Compare commits

..

170 Commits

Author SHA1 Message Date
Electron Bot
97df834c1c Bump v5.0.9 2019-08-06 10:23:09 -07:00
Shelley Vohr
d98735cff7 fix: ensure the webContents is not destroyed before communicating (#18467) (#19627) 2019-08-06 08:56:07 -07:00
Shelley Vohr
9e0eb96141 docs: explanation on using protocols with partitions (#19628) 2019-08-06 08:54:12 -07:00
Erick Zhao
753501442f fix: handle edge behavior for about panel on Linux (#19634) 2019-08-06 08:50:13 -07:00
Shelley Vohr
303559e2f1 fix: clearRecentDocuments role on Windows (#19599) (#19640)
* fix: clear recent documents on windows

* chore: don't check for version < win 7
2019-08-06 08:37:32 -07:00
Cheng Zhao
5a8bdb2380 fix: the callback of beginFrameSubscription should pass NativeImage instead of Buffer (#17548) (#19647)
* Revert "revert: frame subscriber deprecation and re-enable tests"

This reverts commit f643ce4f66.

* fix: make sure SkBitmap's pixels are copied
2019-08-06 08:37:13 -07:00
Mark Lee
21aaf670ce docs: clean up the native module tutorial (#19629)
This is a backport of #17624 for 5-0-x.
2019-08-05 15:10:41 -07:00
trop[bot]
fa2b3a3767 fix: throw on invalid webRequest filters (#19580)
* fix: throw on invalid webRequest filters (#19337)

Closes #11371.

Previously, we didn't consider the return value of the webRequest URLPattern mate converter, which meant that when the pattern wasn't correctly parsed owing to invalid filter specification users would not be made aware of that fact and would just think that the filtering itself had failed. This corrects that error by moving the business logic of url pattern parsing out of the converter and into the function itself so that granular and specific errors can be thrown.

There's also no real reason that i'm aware of not to allow wider breadth of filters by letting users use a wildcard for effective TLD, so I also overrode that (default for the 1-arg Parse is not to allow that).

Finally, I added some examples of url filter types for users to reference.

* fix expect call test failure
2019-08-05 16:14:46 +09:00
Shelley Vohr
fc94fb4480 fix: destroy tray on current tick (#18196) (#19619)
This code was originally added in #6448 to handle an edge case crash in 10.9, and we no longer support 10.9 and therefore no longer need to account for this case.

It addressed the crash, but also created a race condition whereby when a new tray is created the old tray's destroy wouldn't have been fully completed and therefore a new one would be spawned. This fixes that by destroying the tray on the current tick once more.
2019-08-05 09:46:23 +09:00
trop[bot]
f5d936d52c fix: set size of GTK about panel icon (#18957) (#19581) 2019-08-02 19:07:16 -07:00
Micha Hanselmann
b4f5c4ba4a fix: make process.uptime() return the correct time (#19436) (#19566) 2019-08-01 14:02:00 -07:00
John Kleinschmidt
3af498e17c fix: use WeakPtr to detect deletion (#19561)
(cherry picked from commit 4bcf99dc20)
2019-08-01 14:01:40 -07:00
trop[bot]
670291b0ab fix: tray.displayBalloon() does not work with custom icon on Windows (#19530) 2019-07-30 09:22:32 -07:00
trop[bot]
7b6a14b667 fix: remove .pdb from symbol file names (#19503)
* fix: remove .pdb from symbol file names

* Update dump_syms.py
2019-07-30 09:21:42 -07:00
Shelley Vohr
4fa89a1fbc fix: correctly emit BrowserWindow alwaysOnTop status (#19506) 2019-07-30 08:46:29 -07:00
trop[bot]
6b0eaa4832 fix: clearing of the backgroundColor property on TouchBarButton (#19473) 2019-07-29 17:17:13 -07:00
trop[bot]
bc30aeac7c add desc (#19509) 2019-07-29 17:15:31 -07:00
trop[bot]
c5573d2b6c chore: omit superceded Chromium updates from notes (#19407)
* feat: omit superceded Chromium updates from notes

* chore: simplify changed code
2019-07-23 21:32:28 -07:00
Electron Bot
7e80f3fb19 Bump v5.0.8 2019-07-23 11:38:39 -07:00
trop[bot]
e64d407bfd fix: emit swipe event on macOS (#19353) 2019-07-22 09:29:24 -07:00
trop[bot]
7771886073 fix zoom button when alwaysOnTop set (#19350) 2019-07-19 18:50:50 -07:00
John Kleinschmidt
9b1147c7c9 fix: delay handling occlusion events to avoid flicker on macOS (#19315)
* fix: delay handling occlusion events to avoid flicker on macOS (#18661)

* chore: add debounce on the updateWebContentsVisibility method to ensure quick changes in occlusion do not result in flickering

* chore: update old patch headers

(cherry picked from commit 0146cc0eb5)

* Update patch for 5-0-x

* Fix compilation errors
2019-07-18 10:11:23 -07:00
Milan Burda
69ff736ace fix: don't execute preload scripts for internal <iframe> in <webview> (#19260) (#19299) 2019-07-18 15:58:09 +09:00
Micha Hanselmann
04c7453074 refactor: use NativeTheme dark mode detection on macOS 10.14+ (#19310) 2019-07-17 14:31:57 -07:00
Samuel Attard
46c0859c49 build: move our node fork to our patch system (#19292)
This points our node repo at upstream (nodejs/node) and uses the base node tag as the target ref.  We then use our existing patch system and patch files to apply our changes on top of node.  This unifies how we patch upstream repos and makes our node patches easier to reason, view, understand and most importantly reduce.
2019-07-16 16:50:26 -07:00
Electron Bot
31e43f54d0 Bump v5.0.7 2019-07-16 07:51:04 -07:00
trop[bot]
d545757191 fix: don't try to dump swiftshader symbols on mac (#19261)
* fix: don't try to dump swiftshader symbols on mac

* fix: don't try to generate swiftshader symbols on arm
2019-07-15 20:53:57 -07:00
Milan Burda
ddc85869de fix: <webview> not working in scriptable popups (#19206) 2019-07-16 11:44:04 +09:00
Shelley Vohr
65faec8659 fix: silent printing (#19038) 2019-07-15 14:38:25 -07:00
trop[bot]
9b72734f7c fix: exit non-silently when running as root on Linux (#19254)
* check for sandbox param on root

* add IsSandboxEnabled
2019-07-15 14:28:04 -05:00
Erick Zhao
29a6dd079c chore: revert key -> main change in window delegate listener (#19238) 2019-07-14 10:54:20 +09:00
Milan Burda
dd58f2a6ac ci: add check for dist zip file changes (#19173) 2019-07-11 11:51:35 -05:00
Samuel Attard
8e68e6eb75 feat: provide the frame URL with permission requests and checks (#18757) (#18773)
* feat: provide the frame URL with permission requests and checks

Also provides a handy isMainFrame property to determine if it is an
iframe making the request

* chore: refactor to use base::Value

* chore: use Set<Type>Key over SetPath
2019-07-11 18:00:12 +09:00
trop[bot]
0a3ec23967 fix: check parent-child relationship in canAccessWindow (#19117) 2019-07-11 17:57:14 +09:00
trop[bot]
6f85e4de57 remove non-existent event (#19170) 2019-07-11 17:33:55 +09:00
trop[bot]
b8f3325a04 fix: don't package mojom{,-lite}.js files in dist.zip (#19192) 2019-07-11 17:19:50 +09:00
Milan Burda
3e6cd062a7 fix: don't package resources/inspector in dist.zip (#19193) 2019-07-11 17:19:00 +09:00
Jeremy Apthorp
a2f68c1e57 fix: dump correct breakpad symbols on macOS (#19157) 2019-07-09 09:47:36 +09:00
trop[bot]
bff8573646 fix: only check darkMode effectiveAppearance in 10.15 (#19082) 2019-07-02 14:15:33 -07:00
trop[bot]
32ad5be74e fix: Correct modal focus behavior on macOS (#19063)
* wip: wish i could hack the main window focus away

* main -> key

* remove useless code

* test: Add focus event spec

* test: more robust spec

* test: simplify test

* duplicate non-firing macOS event listener 😳

* destroy 🚨

* chore: remove unused variable
2019-07-02 09:20:15 -07:00
Juliette Rapala
3d60f82d03 docs: fix typo in breaking-changes.md (#19040) 2019-07-01 10:42:21 -07:00
Samuel Attard
3aa16f5632 docs: fix heading level for power-monitor docs (#19018) 2019-07-01 09:55:43 -07:00
trop[bot]
d0f7f9f894 ci: run lint on CircleCI (#19058)
* ci: run lint on CircleCI

* Fix linting errors
2019-07-01 08:47:59 -07:00
trop[bot]
7865fa37fa fix: make tray not block main process (#18880) (#19036)
* fix: make tray not block main process

* make AtomMenuModel refcounted
2019-06-28 14:00:01 -07:00
trop[bot]
714fa6f3c0 fix: delay emitting screen events by a tick to avoid re-entrancy crash (#19023) 2019-06-28 16:23:43 +09:00
Alexandre Lacheze
61d9d7c657 fix: webview crash on iframe removal (#18976)
* Remove disable detach webview frame patch

* Backport Chromium fix crash when detaching OOPIF

Backport of 7464a6b4e3%5E%21

* Move portals_fix_crash_when_detaching_oopif_from_portal.patch as first patch

* Revert disable_detach_webview_frame.patch
2019-06-28 11:16:38 +09:00
Electron Bot
558bb52847 Bump v5.0.6 2019-06-26 13:05:00 -07:00
Samuel Attard
c979c90f46 fix: override the timers module impls to activate the uv loop (#18965) 2019-06-24 19:14:30 -07:00
Micha Hanselmann
a9ada36097 fix: sanitize invalid custom protocol headers (#18928)
* fix: sanitize invalid custom protocol headers (#18854)

* lint fix

* wild guess
2019-06-24 13:28:45 -07:00
trop[bot]
0c4b2e99ec fix: make isDarkMode correctly detect dark mode in the auto setting on catalina (#18960) 2019-06-24 13:27:58 -07:00
trop[bot]
f35b166844 chore: use manual invocation of npx yarn (#18920)
* chore: Revert "build: use yarn to install arm modules (#18802)"

This reverts commit 97bec607fe.
script/yarn.js doesn't exist in 5-0-x or 6-0-x

* chore: use manual invocation of npx yarn

* Revert "chore: use manual invocation of npx yarn"

This reverts commit 8ae77f5f5b.
2019-06-24 07:54:32 -07:00
Electron Bot
ff54817a92 Bump very far --> this is electron bot fixing the release 2019-06-21 13:34:55 -07:00
Electron Bot
25e5432863 Bump very far --> this is electron bot doing nothing 2019-06-21 12:58:36 -07:00
Electron Bot
4b9ae99f34 chore: this is electron bot doing nothing 2019-06-21 12:50:31 -07:00
Samuel Attard
e2e7a82ebc chore: this is electron bot doing nothing 2019-06-21 12:45:20 -07:00
Shelley Vohr
385e548073 refactor: session.{clearCache,getCacheSize} nws13n (#18898) 2019-06-21 09:47:39 -07:00
Milan Burda
938b3440ef fix: app.getAppPath() returning default-app path for files or directories without package.json (#18763) (#18894) 2019-06-21 08:54:32 -07:00
trop[bot]
eb821a3c7f chore: fix branch trimming for blast-off releases (#18908) 2019-06-21 01:06:59 -07:00
Milan Burda
4318ad8f3a fix: set nativeWindowOpen when sandboxed (#18273) (#18798) 2019-06-20 08:25:51 -07:00
Alexey Kuzmin
b3c44d1fe6 Revert "chore: reformat code C++ to make the linter happy (#18687)" (#18881)
This reverts commit 38cca77346.
2019-06-20 07:54:11 -07:00
Samuel Attard
401f6641c8 chore: roll node to fix http2 memory leak (#18883) 2019-06-19 12:32:59 -07:00
trop[bot]
18e31da478 docs: add example on handling the webPrefs change (#17971) (#18864)
* docs: add example on handling the webPrefs change

Fixes #17967

* Update breaking-changes.md
2019-06-19 09:54:48 -07:00
Electron Bot
ae5d556845 Bump v5.0.5 2019-06-18 15:09:37 -07:00
trop[bot]
ebc937cfd5 chore: fix current branch fetch on master (#18861) 2019-06-18 08:34:23 -07:00
trop[bot]
f09f926cba fix: use effectiveAppearance to check dark mode on mojave and above (#18666) (#18852)
* fix: use effectiveAppearance to check dark mode on mojave and above

* chore: add forward declarations for dark appearance
2019-06-17 18:12:31 -07:00
Shelley Vohr
4964a09677 chore: update codeowners in 5 (#18835) 2019-06-17 14:06:43 -07:00
Milan Burda
a7c4d21427 fix: Uncaught TypeError: Cannot set property 'innerText' of null in default-app (#18819) 2019-06-17 10:24:43 -07:00
trop[bot]
07cd1e6b4d build: get current release branch from commit (#18834)
* chore: get current release branch from commit

* love too lint
2019-06-17 07:54:13 -07:00
Shelley Vohr
7a135c736b docs: better explain supported release line levels (#18800) (#18839) 2019-06-17 07:53:30 -07:00
Milan Burda
183c687f49 fix: [Liftoff] Correctly unuse Labels (#18545) 2019-06-15 19:42:31 +09:00
Milan Burda
b04eaabf4e fix: crash in BrowserWindow destructor after win.webContents.destroy() (#18686) (#18794) 2019-06-15 16:22:13 +09:00
trop[bot]
aae58ffcae build: use yarn to install arm modules (#18801) 2019-06-15 16:16:31 +09:00
Shelley Vohr
226dd755f8 fix: callback values for printing cancellation and success (#18804) 2019-06-15 16:13:49 +09:00
trop[bot]
2e6814c4b0 docs: add specific options for MenuItem.role (#18806) 2019-06-14 23:29:28 -07:00
Electron Bot
d4319badce Bump v5.0.4 2019-06-14 14:14:47 -07:00
Erick Zhao
b034bf9ae6 fix: throw error on invalid URLs when setting cookie (#18756)
With this PR, invalid inputs to the url parameter will throw an error when using cookie.set(). This is done by checking if the URL is parseable using GURL rather than checking if the URL string being passed in is empty.

Previously, invalid URLs would be able to be added as a cookie, but you would not be able to filter for them or remove them.
2019-06-14 10:54:32 -07:00
trop[bot]
c0e688ff35 docs: fully document MenuItem instance properties (#18785)
* document menuItem instance properties

* correct some types

* add correct click documentation
2019-06-13 18:45:13 -07:00
Shelley Vohr
bf9b001989 fix: HTML fullscreen request for sub frames (#18736) (#18781)
Don't re-enter fullscreen if there is a pending operation,
for subframe fullscreen request `EnterFullScreenModeForTab`
will be called for both the frame in question as well as
the outer webContents hosting it.
2019-06-13 17:59:51 -07:00
Shelley Vohr
0e0c3da49a fix: correct isDownloadable docs to match impl (#18748) 2019-06-13 16:17:23 -07:00
Shelley Vohr
63d994808c docs: fix editMenu menu role etc types (#18759) 2019-06-13 08:30:55 -07:00
Jeremy Spiegel
e0d566a7e7 fix: properly pass openExternal activate option (#18721)
A reference to an OpenExternalOptions structure was being captured by an Objective-C block that
outlived the object that was being referenced.
2019-06-12 20:56:39 -07:00
trop[bot]
eaa22b4aa8 fix: remove lingering data when notifications autodismiss on Windows 7 (#18741) 2019-06-12 21:43:48 +09:00
Alexandre Lacheze
99c3ff60bb fix: lost window.opener after cross-origin navigation (#18614)
* SiteInstance::CreateRelatedSiteInstance and use it

* Some relies on preloads in opened window

The fact that, now, we always have an opener for opened windows diables note integration in opened windows, except if `nodeIntegrationInSubFrames` is enabled.

* Add a test on window.opener after cross-orgin navigation

* Make sure to unregisterProtocol in tests

* Introduc and use a NetworkSandbox for tests

* Modify tests about zoom persistence to properly simulate cross-origin navigation

* Revert "Modify tests about zoom persistence to properly simulate cross-origin navigation"

This reverts commit 0a7537f2eb7f183ddec16637e8a2e92a0d600321.
2019-06-11 17:37:52 -07:00
Alexey Kuzmin
38cca77346 chore: reformat code C++ to make the linter happy (#18687) 2019-06-10 09:49:16 +09:00
Maya Wolf
a0872b2314 fix: contractions handling in spellchecker (#18548) 2019-06-07 19:12:17 -07:00
trop[bot]
8517c499e9 fix: use isEqual instead of pointer equality to convert NSAppearance (#18689) 2019-06-07 11:31:39 -07:00
trop[bot]
3f23f8b2a3 ci: fix issues downloading from CircleCI (#18655)
Make sure we pass along token to download from CircleCI
Also, add back off period for retries on downloads.
2019-06-05 10:54:22 -07:00
Electron Bot
45ab468ce1 Bump v5.0.3 2019-06-04 12:13:27 -07:00
Milan Burda
be458b547a build: remove Vulkan mock ICD (#18595) 2019-06-04 10:08:40 -05:00
trop[bot]
050bbfb211 build: move Windows release builds to AppVeyor cloud (#18604)
* build: move Windows release builds to AppVeyor cloud

* Use new env variable for AppVeyor cloud server
2019-06-04 10:29:37 -04:00
Milan Burda
0a4d90d41f fix: don't export private V8 symbols that can cause native node modules to crash (#18281) (#18620) 2019-06-04 10:13:29 -04:00
trop[bot]
0e56578e11 build: install python-dbusmock via pip for a Docker container (#18599)
* build: use python-dbusmock v0.18.1 on Linux

To prevent timeout errors with some other python-dbusmock versions.

* Don't use a fixed version of python-dbusmock

Co-Authored-By: John Kleinschmidt <jkleinsc@github.com>
2019-06-04 09:41:55 -04:00
trop[bot]
7a2777cc00 doc: change pyobjc link in macos build instruction (#18617) 2019-06-03 22:02:50 -07:00
trop[bot]
fc6b98766c build: strip swiftshader binaries (#18601) 2019-06-03 14:32:39 -07:00
trop[bot]
7d06861a6d ci: add retries to downloads for arm testing (#18533) 2019-05-30 21:08:57 -07:00
trop[bot]
851a84d301 docs: specify use case for the 'services' role (#18527)
* docs: specify use case for the 'services' role

* update based on @caesar's recommendation

Co-Authored-By: Caesar Schinas <caesar@caesarschinas.com>
2019-05-30 15:15:02 -07:00
trop[bot]
91bc35fbfc fix: populate phase of WebMouseWheelEvents generated in webContents.sendInputEvent. (#18495) 2019-05-30 15:11:37 -07:00
trop[bot]
76414e58d4 fix: respect minimizable/closable for customButtonsOnHover (#18485) 2019-05-29 13:00:36 -07:00
trop[bot]
d6ad3e6a17 docs: clarify that 'second-instance' is only emitted when the second instance calls app.requestSingleInstanceLock() (#18384) 2019-05-28 14:21:17 -07:00
Milan Burda
49d6f5cc14 chore: remove leftovers from memory property removal from app.getAppMetrics() (#18423) 2019-05-28 14:20:24 -07:00
Charles Kerr
610f61603d Rename 'API Contract' as 'Breaking Changes' in 5-0-x (#18400)
Backport of https://github.com/electron/electron/pull/18326 to the stable branch for visibility on electronjs.org
2019-05-23 15:03:24 -04:00
Electron Bot
6b371a5ef9 Bump v5.0.2 2019-05-22 11:33:35 -07:00
trop[bot]
7ee06c354e fix: 'page-title-updated' event forwarding + documentation (#18318) 2019-05-21 16:22:45 +09:00
trop[bot]
a60ad6aeed fix: default enable_negotiate_port to false (#18284) 2019-05-15 10:28:21 -07:00
trop[bot]
693d840202 build: linux needs java on GN (#18216) 2019-05-08 16:33:26 -07:00
trop[bot]
7a759ea0b6 fix: crash on systemPreferences.getAccentColor() (#18194) 2019-05-07 09:51:41 -07:00
trop[bot]
83a4b7371b docs: clarify clipboard type options (#18174) 2019-05-06 09:29:31 -07:00
trop[bot]
82bb6d4ccf fix: do not mark navigations interupted with same-document navigations as aborted (#18142)
* fix: do not mark navigations interupted with same-document navigations as aborted

* spec: add tests for the loadURL promise
2019-05-03 23:09:03 -07:00
Electron Bot
2de54a3dbc Bump v5.0.1 2019-05-03 13:33:57 -07:00
trop[bot]
7eac676fa7 fix: fs.promises does not work with asar paths (#18115) 2019-05-02 22:34:25 -07:00
Electron Bot
54199d21c3 chore: bump chromium in DEPS to 73.0.3683.121 (#18001) 2019-05-02 12:50:37 -07:00
trop[bot]
2483dcc09c docs: fix webContents 'new-window' event handler sample (#18097) 2019-05-01 13:43:48 -07:00
trop[bot]
1154f3c585 fix: ensure the inspector agent is shutdown before cleaning up the node env (#18076)
* fix: ensure the inspector agent is shutdown before cleaning up the node env

* spec: add tests to ensure clean shutdown with connected inspector agent

* Update node_debugger.cc
2019-05-01 12:43:54 -07:00
trop[bot]
232d9fe808 fix: explicitly focus window on win.show() (#18080) 2019-05-01 10:44:34 -07:00
trop[bot]
5693b7f3a1 chore: disable Vulkan validation layers (#18061) 2019-04-30 10:17:19 -07:00
Milan Burda
d4e631f1b9 Revert "build: disable Vulkan support by default (#17788)" (#17986)
This reverts commit 82f91b7efa.
2019-04-30 06:48:36 -07:00
Milan Burda
2252ac060e docs: update nodeIntegration section for new defaults (#18051) 2019-04-30 06:44:05 -07:00
trop[bot]
bb28195b74 docs: Correct doc for registerFileProtocol (#18049)
In the registerFileProtocol docs the "headers" argument of the callback was described as being a list.
In fact is has to be an Object mapping header-entries to values. This can be seen in Line 326 of `/spec/api-protocol-spec.js` [fe618631f1/spec/api-protocol-spec.js (L326)].
2019-04-29 15:30:25 -07:00
Milan Burda
2f426a031a fix: remove non-existent gpu-crashed event on <webview> (#17317) (#18004) 2019-04-29 15:21:52 -07:00
trop[bot]
761b14316f docs: add azure vm spinup tutorial (#17974) 2019-04-25 15:49:24 -07:00
trop[bot]
f3a05c30ae fix: crash when run from SMB network share (#17908) 2019-04-24 11:26:40 -07:00
Electron Bot
7514372e79 Bump v5.0.0 2019-04-23 14:04:26 -07:00
Samuel Attard
151a338956 Revert "Bump v5.0.0"
This reverts commit d57293503d.
2019-04-23 14:03:18 -07:00
Electron Bot
d57293503d Bump v5.0.0 2019-04-23 11:34:11 -07:00
Samuel Attard
c4009760c7 build: fix bump-version script for stable releases 2019-04-23 11:30:19 -07:00
Samuel Attard
3408997289 Revert "Bump v5.0.0"
This reverts commit 9ca2b31b7c.
2019-04-23 11:25:23 -07:00
Electron Bot
9ca2b31b7c Bump v5.0.0 2019-04-23 09:36:13 -07:00
Samuel Attard
5aa0a1a77a build: fix release notes generation 2019-04-23 09:34:35 -07:00
Jeremy Apthorp
3825bf0b6d fix: enable autofill popups on mac (backport: 5-0-x) (#17888)
* feat: enable autofill popups on mac

* fix: make popup positioning better

* fix: don't try to show popup when widget is closing or not visible

* fix: unify conditions

* refactor: use PopupViewCommon from chrome directly

* lint: mark constructor explicit

* fix: use a patch instead of dummy functions to make things compile on Windows

* chore: address review suggestions

* Update atom/browser/ui/cocoa/views_delegate_mac.mm

Co-Authored-By: brenca <benecene@gmail.com>
2019-04-22 14:55:38 -07:00
Samuel Attard
d15bcfb1ed refactor: allow embedder overriding of internal FS calls (#17906) 2019-04-22 14:54:19 -07:00
Samuel Attard
ccb051caf7 fix: remove duplicate function deprecator 2019-04-22 13:28:39 -07:00
Electron Bot
3284aabd48 chore: bump chromium in DEPS to 73.0.3683.119 (#17853) 2019-04-19 13:56:24 -07:00
Electron Bot
6d575f80fa Bump v5.0.0-beta.9 2019-04-19 11:04:37 -07:00
Cheng Zhao
b91dcfb314 fix: drain tasks before shutting down isolate (#17877) 2019-04-19 11:03:04 -07:00
Milan Burda
321e66d0cc fix: copy pixels in AddImageSkiaRepFromBuffer (#17843) (#17863) 2019-04-18 08:53:56 -07:00
trop[bot]
81eedb6efa doc: document occasional mismatch between NSImageName and string (#17849) 2019-04-17 21:01:24 -04:00
Roller Bot
b08dc0f7e6 chore: bump chromium in DEPS to 73.0.3683.117 (#17839) 2019-04-17 17:29:35 -07:00
Samuel Attard
11c1c255bf fix: ensure the sandboxed preloads globals do not leak (#17712) (#17830) 2019-04-17 17:05:24 -04:00
Samuel Attard
c89bab9730 build: override the NMV for Electron 5 (#17828)
* build: override the NMV for Electron 5

* chore: add ref to the NMV registry

* chore: update DEPS for new node revision

* chore: update node ref

* chore: update node ref in DEPS

* Update build/args/all.gn
2019-04-17 17:04:12 -04:00
trop[bot]
5ffe634824 refactor: remove superfluous ScopedAllowBaseSync in desktopCapturer (#17846) 2019-04-17 13:12:21 -07:00
Jeremy Apthorp
3ad9fb1473 fix: skip zygote for unsandboxed ppapi processes (#17829) 2019-04-17 13:13:16 -04:00
Milan Burda
b0298cca2e fix: emit process 'loaded' event in sandboxed renderers (#17808) 2019-04-16 16:24:31 -07:00
trop[bot]
ed8ab7e9ad fix: reset the NSUserNotication handle on dismiss (#17822) 2019-04-16 16:20:26 -07:00
Samuel Attard
c75726f9ef fix: maintain a ref count for objects sent over remote (#17464) (#17825)
* spec: clean up after a failed window count assertion

Previously when this assertion failed all tests that ran after the
failed assertion also failed.  This ensure that the assertion fails for
the test that actually caused the issue but cleans up the left-over
windows so that future tests do not fail.

* fix: maintain a ref count for objects sent over remote

Previously there was a race condition where a GC could occur in the
renderer process between the main process sending a meta.id and the
renderer pulling the proxy out its weakmap to stop it being GC'ed.

This fixes that race condition by maintaining a "sent" ref count in the
object registry and a "received" ref count in the object cache on the
renderer side.  The deref request now sends the number of refs the
renderer thinks it owns, if the number does not match the value in the
object registry it is assumed that there is an IPC message containing a
new reference in flight and this race condition was hit.

The browser side ref count is then reduced and we wait for the new deref
message.  This guaruntees that an object will only be removed from the
registry if every reference we sent has been guarunteed to be unreffed.
2019-04-16 17:57:25 -04:00
trop[bot]
ff7e22c675 docs: note desktop audio limitation on macOS (backport: 5-0-x) (#17814)
* docs: note desktop audio limitation on macOS

* link to signed kernel info

* Update docs/api/desktop-capturer.md

Co-Authored-By: codebytere <codebytere@github.com>
2019-04-16 13:13:17 -07:00
trop[bot]
946c11145c docs: reference the webviewTag option in the webview docs (#17812)
Closes #16773

Notes: Add a reference to the "webviewTag" option in the webview docs
2019-04-16 15:51:48 -04:00
Nitish Sakhawalkar
ffd2224bbe Node 12 Upgrade (5-0-x) (#17752)
* fix: backport boringssl patches for node compat

* refactor: prevent node macros from overriding base (#17178)

* fix: backport boring ssl patch OPENSSL_clear_free

* refactor: load electron builtin modules with process._linkedBinding (#17247)

* refactor: load electron builtin modules with process._linkedBinding

NODE_BUILTING_MODULE_CONTEXT_AWARE and process.binding are
removed in https://github.com/nodejs/node/pull/25829. This changes
uses the alternative available without any functionality change.

* chore: roll node

* fix: add boringssl backport to support node upgrade

* fix: Update node_includes.h, add DCHECK macros

* fix: Update node Debug Options parser usage

* fix: Fix asar setup

* fix: using v8Util in isolated context

* fix: make "process" available in preload scripts

* fix: use proper options parser and remove setting of _breakFirstLine

_breakFirstLine was being set on the process, but that has changed in node 12 and so is no longer needed. Node will handle it properly when --inspect-brk is provided

* fix: process.binding => _linkedBinding in sandboxed isolated preload

* chore: update node dep sha

* fix: make original-fs work with streams
2019-04-16 15:51:08 -04:00
Samuel Attard
c326de860d fix: handle remote-debugging-port=0 correctly (#17800) (#17817)
By default the Chromedriver will send remote-debugging-port=0 to let the
browser choose a free port to listen on.  The chosen port is written to
a known file in the user data dir that is passed to the app through the
CLI.

This PR does two things.

1. Correctly passes the USER_DATA_DIR to the remote debugging server so
it knows where to write the file
2. Adds support for --user-data-dir as we did not support that CLI
argument and Chromedriver relies on being able to tell the "browser"
where to write this file.

Fixes #17354
2019-04-16 15:46:27 -04:00
Roller Bot
145aa919ca chore: bump chromium in DEPS to 73.0.3683.116 (#17805) 2019-04-16 12:02:02 -04:00
trop[bot]
2cc55fee5e test: remove non-applicable processMemoryInfo specs (#17709) 2019-04-15 20:00:43 -04:00
trop[bot]
119e8bec93 fix: crash when alt key pressed with falsy menu bar visiblity (#17795) 2019-04-15 15:26:35 -04:00
Alexey Kuzmin
82f91b7efa build: disable Vulkan support by default (#17788)
Is was enabled in
327326656f
which landed in 69.0.3460.0

Vulkan support would require a command line parameter "--enable-vulkan"
to be passes to a binary to be enabled anyway,
so this change doesn't actual alter the current behaviour of Electron.

(cherry picked from commit e05e45d62d)
2019-04-15 15:26:02 -04:00
trop[bot]
900feef89f fix: incorrect default path setting for dl items (#17797) 2019-04-15 15:20:41 -04:00
trop[bot]
c58d39e71b fix crash when passing empty string to recording (#17711) 2019-04-15 14:15:31 -04:00
trop[bot]
48f190690e fix: correct crash reporter for Windows on Arm (#17792)
ARM64 cleans up and moves around RUNTIME_FUNCTION structure fields.
With this patch applied, electron should build cleanly for Windows on Arm.
2019-04-15 13:56:23 -04:00
Roller Bot
faa308c88c chore: bump chromium in DEPS to 73.0.3683.112 (#17770) 2019-04-12 14:18:19 -04:00
Milan Burda
9619688706 fix: report module name when require fails in sandboxed renderers (#17705) 2019-04-12 13:40:15 -04:00
Roller Bot
a724aced43 chore: bump chromium in DEPS to 73.0.3683.105 (#17707) 2019-04-05 10:48:30 -07:00
Electron Bot
9a9f7af971 Bump v5.0.0-beta.8 2019-04-04 09:09:31 -07:00
trop[bot]
0184ccd019 build: optionally exclude some parts of patches from being applied (#17685) 2019-04-04 09:07:32 -07:00
Roller Bot
cdd8021509 chore: bump chromium in DEPS to 73.0.3683.104 (#17692) 2019-04-04 09:06:57 -07:00
Heilig Benedek
1e31bfe287 fix: port OSR code to new viz compositor codepath (backport: 5-0-x) (#17572)
* fix: make OSR work with viz compositor

* fix: update OSR patch

* fix: update patch again

* fix: update viz_osr.patch for macOS

* fix: gn check warnings

* chore: no need to change SoftwareOutputDeviceWinProxy

* chore: add check in case we missed something

* fix: consider scale factor when compare size

* fix: make GPU OSR work

* fix: autofill popups with OSR

* chore: use UNIX line ending for osr_video_consumer

* chore: code is already in defined(OS_MACOSX)

* fix: share same OSR implementation on macOS

This should also fix the crash when there is navigation on macOS.

* test: osr window should not crash after navigation

* fix: make osr work on Mac properly

* fix: software osr on windows

* fix: software osr on Linux

* fix: split local surface id allocation into two

* fix: update patch for 5-0-x

* fix: patch and update VideoConsumer to report proper damage_rect

* fix: update patch to resolve compilation error on Linux

* fix: compilation error on mac

* Update osr_host_display_client_mac.mm

* chore: update copyright year
2019-04-03 18:08:22 -05:00
trop[bot]
7304af93ed docs: clarify cookie domain normalization (#17663) 2019-04-02 18:26:28 -07:00
Roller Bot
69f6a44e81 chore: bump chromium in DEPS to 73.0.3683.101 (#17656) 2019-04-02 15:44:33 -07:00
Samuel Attard
354b32a9fc fix: make devtools extensions load correctly (#17616) 2019-04-02 13:24:40 -07:00
Samuel Attard
d5bb0e968f fix: ensure dots in content script patterns aren't used as wildcards (#17594)
* fix: ensure dots in content script patterns aren't used as wildcards

* chore: santize all regex chars

* chore: extract to helper

* chore: fixup helper
2019-03-28 14:04:30 -07:00
trop[bot]
9e12e8c63f fix: handle a race condition between preload scripts executing and navigations (#17597)
There is a race condition between DidCreateScriptContext and another
navigation occuring in the main process. If the navigation occurs while
the preload script is running, the same process is re-used.  This
ensures that any pending navigations are completely removed / ignored
when we trigger a new navigation.

Fixes #17576
2019-03-28 12:56:29 -07:00
Heilig Benedek
ebcd094222 fix: update patch to make Windows key work with global shortcuts (#17566) 2019-03-28 11:17:39 -07:00
trop[bot]
5dd735f5b3 fix: correctly return properties on the netLog module (#17545) 2019-03-27 15:38:10 -07:00
trop[bot]
46841d7373 fix: set default_id and cancel_id correctly on confirm dialogs (#17578) 2019-03-27 15:30:21 -07:00
328 changed files with 11288 additions and 2402 deletions

View File

@@ -35,6 +35,7 @@ env-debug-build: &env-debug-build
env-testing-build: &env-testing-build
GN_CONFIG: //electron/build/args/testing.gn
CHECK_DIST_MANIFEST: '1'
env-release-build: &env-release-build
GN_CONFIG: //electron/build/args/release.gn
@@ -254,6 +255,28 @@ step-electron-dist-build: &step-electron-dist-build
command: |
cd src
ninja -C out/Default electron:electron_dist_zip
if [ "$CHECK_DIST_MANIFEST" == "1" ]; then
if [ "`uname`" == "Darwin" ]; then
target_os=mac
target_cpu=x64
if [ x"$MAS_BUILD" == x"true" ]; then
target_os=mac_mas
fi
elif [ "`uname`" == "Linux" ]; then
target_os=linux
if [ x"$TARGET_ARCH" == x ]; then
target_cpu=x64
elif [ "$TARGET_ARCH" == "ia32" ]; then
target_cpu=x86
else
target_cpu="$TARGET_ARCH"
fi
else
echo "Unknown system: `uname`"
exit 1
fi
electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.$target_os.$target_cpu.manifest
fi
step-electron-dist-store: &step-electron-dist-store
store_artifacts:
@@ -402,25 +425,13 @@ step-mksnapshot-store: &step-mksnapshot-store
path: src/out/Default/mksnapshot.zip
destination: mksnapshot.zip
step-maybe-build-dump-syms: &step-maybe-build-dump-syms
run:
name: Build dump_syms binary
command: |
if [ "$GENERATE_SYMBOLS" == "true" ]; then
cd src
# Build needed dump_syms executable
ninja -C out/Default third_party/breakpad:dump_syms
fi
step-maybe-generate-breakpad-symbols: &step-maybe-generate-breakpad-symbols
run:
name: Generate breakpad symbols
command: |
if [ "$GENERATE_SYMBOLS" == "true" ]; then
cd src
export BUILD_PATH="$PWD/out/Default"
export DEST_PATH="$BUILD_PATH/breakpad_symbols"
electron/script/dump-symbols.py -b $BUILD_PATH -d $DEST_PATH -v
ninja -C out/Default electron:electron_symbols
fi
step-maybe-zip-symbols: &step-maybe-zip-symbols
@@ -492,6 +503,39 @@ step-maybe-generate-typescript-defs: &step-maybe-generate-typescript-defs
fi
# Lists of steps.
steps-lint: &steps-lint
steps:
- *step-checkout-electron
- run:
name: Setup third_party Depot Tools
command: |
# "depot_tools" has to be checkout into "//third_party/depot_tools" so pylint.py can a "pylintrc" file.
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git src/third_party/depot_tools
echo 'export PATH="$PATH:'"$PWD"'/src/third_party/depot_tools"' >> $BASH_ENV
- run:
name: Download GN Binary
command: |
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
buildtools_revision="$(curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/DEPS?format=TEXT" | base64 -d | grep buildtools_revision -A1 | tr -d '\n' | cut -d\' -f4)"
git clone https://chromium.googlesource.com/chromium/buildtools "buildtools"
(cd "buildtools" && git checkout "$buildtools_revision")
echo 'export CHROMIUM_BUILDTOOLS_PATH="'"$PWD"'/buildtools"' >> $BASH_ENV
download_from_google_storage --bucket chromium-gn -s "buildtools/linux64/gn.sha1"
- run:
name: Run Lint
command: |
# gn.py tries to find a gclient root folder starting from the current dir.
# When it fails and returns "None" path, the whole script fails. Let's "fix" it.
touch .gclient
# Another option would be to checkout "buildtools" inside the Electron checkout,
# but then we would lint its contents (at least gn format), and it doesn't pass it.
cd src/electron
npm install
npm run lint
steps-checkout: &steps-checkout
steps:
- *step-checkout-electron
@@ -596,7 +640,6 @@ steps-electron-build-for-tests: &steps-electron-build-for-tests
# Save all data needed for a further tests run.
- *step-persist-data-for-tests
- *step-maybe-build-dump-syms
- *step-maybe-generate-breakpad-symbols
- *step-maybe-zip-symbols
@@ -621,7 +664,6 @@ steps-electron-build-for-publish: &steps-electron-build-for-publish
- *step-maybe-electron-dist-strip
- *step-electron-dist-build
- *step-electron-dist-store
- *step-maybe-build-dump-syms
- *step-maybe-generate-breakpad-symbols
- *step-maybe-zip-symbols
@@ -779,6 +821,13 @@ chromium-upgrade-branches: &chromium-upgrade-branches
# List of all jobs.
version: 2
jobs:
# Layer 0: Lint. Standalone.
lint:
<<: *machine-linux-medium
environment:
<<: *env-linux-medium
<<: *steps-lint
# Layer 1: Checkout.
linux-checkout:
<<: *machine-linux-2xlarge
@@ -1302,6 +1351,10 @@ jobs:
workflows:
version: 2
lint:
jobs:
- lint
build-linux:
jobs:
- linux-checkout

View File

@@ -1,7 +1,7 @@
# These env vars are only necessary for creating Electron releases.
# See docs/development/releasing.md
APPVEYOR_TOKEN=
APPVEYOR_CLOUD_TOKEN=
CIRCLE_TOKEN=
ELECTRON_GITHUB_TOKEN=
VSTS_TOKEN=

33
.github/CODEOWNERS vendored
View File

@@ -3,19 +3,24 @@
# https://help.github.com/articles/about-codeowners
# https://git-scm.com/docs/gitignore
# Everything that falls through the cracks:
* @electron/reviewers
# Most stuff in here is owned by the Community & Safety WG...
/.github/* @electron/wg-community
# filename patterns
*browser_view* @electron/browserview
*notification* @electron/notifications
*pdf* @electron/printing
*printing* @electron/printing
*updater* @electron/updater
# ...except the Admin WG maintains this file.
/.github/CODEOWNERS @electron/wg-admin
# directories
/.github/ @electron/electrocats
/default_app/ @electron/docs
/docs/ @electron/docs
/docs-translations/ @electron/i18n
/npm/ @electron/electrocats
# Upgrades WG
/patches/ @electron/wg-upgrades
# Releases WG
/npm/ @electron/wg-releases
/script/release-notes @electron/wg-releases
/script/prepare-release.js @electron/wg-releases
/script/bump-version.js @electron/wg-releases
/script/ci-release-build.js @electron/wg-releases
/script/release.js @electron/wg-releases
/script/upload-to-github.js @electron/wg-releases
/script/release-artifact-cleanup.js @electron/wg-releases
/script/get-last-major-for-master.js @electron/wg-releases
/script/find-release.js @electron/wg-releases
/script/download-circleci-artifacts.js @electron/wg-releases

View File

@@ -1,31 +0,0 @@
pool:
vmImage: 'Ubuntu 16.04'
steps:
- bash: |
# "depot_tools" has to be checkout into "//third_party/depot_tools" so pylint.py can a "pylintrc" file.
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git "${AGENT_BUILDDIRECTORY}/third_party/depot_tools"
echo "##vso[task.setvariable variable=PATH]$PATH:${AGENT_BUILDDIRECTORY}/third_party/depot_tools"
displayName: Setup Depot Tools
- bash: |
chromium_revision="$(grep -A1 chromium_version DEPS | tr -d '\n' | cut -d\' -f4)"
buildtools_revision="$(curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/DEPS?format=TEXT" | base64 -d | grep buildtools_revision -A1 | tr -d '\n' | cut -d\' -f4)"
git clone https://chromium.googlesource.com/chromium/buildtools "${AGENT_TEMPDIRECTORY}/buildtools"
(cd "${AGENT_TEMPDIRECTORY}/buildtools" && git checkout "$buildtools_revision")
echo "##vso[task.setvariable variable=CHROMIUM_BUILDTOOLS_PATH]$AGENT_TEMPDIRECTORY/buildtools"
download_from_google_storage --bucket chromium-gn -s "${AGENT_TEMPDIRECTORY}/buildtools/linux64/gn.sha1"
displayName: Download gn binary
- bash: |
# gn.py tries to find a gclient root folder starting from the current dir.
# When it fails and returns "None" path, the whole script fails. Let's "fix" it.
touch .gclient
# Another option would be to checkout "buildtools" inside the Electron checkout,
# but then we would lint its contents (at least gn format), and it doesn't pass it.
npm install
npm run lint
displayName: Run Lint

160
BUILD.gn
View File

@@ -9,6 +9,8 @@ import("//tools/grit/repack.gni")
import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
import("//v8/snapshot_toolchain.gni")
import("build/asar.gni")
import("build/extract_symbols.gni")
import("build/js_wrap.gni")
import("build/npm.gni")
import("buildflags/buildflags.gni")
import("electron_paks.gni")
@@ -52,7 +54,7 @@ config("branding") {
]
}
npm_action("atom_browserify_sandbox") {
npm_action("atom_browserify_sandbox_unwrapped") {
script = "browserify"
inputs = [
@@ -64,7 +66,7 @@ npm_action("atom_browserify_sandbox") {
]
outputs = [
"$target_gen_dir/js2c/preload_bundle.js",
"$target_gen_dir/js2c/preload_bundle_unwrapped.js",
]
args = [
@@ -73,12 +75,14 @@ npm_action("atom_browserify_sandbox") {
"./lib/sandboxed_renderer/api/exports/electron.js:electron",
"-t",
"aliasify",
"--standalone",
"sandboxed_preload",
"-o",
rebase_path(outputs[0]),
]
}
npm_action("atom_browserify_isolated") {
npm_action("atom_browserify_isolated_unwrapped") {
script = "browserify"
inputs = [
@@ -86,18 +90,48 @@ npm_action("atom_browserify_isolated") {
]
outputs = [
"$target_gen_dir/js2c/isolated_bundle.js",
"$target_gen_dir/js2c/isolated_bundle_unwrapped.js",
]
args = [
"lib/isolated_renderer/init.js",
"-t",
"aliasify",
"--standalone",
"isolated_preload",
"-o",
rebase_path(outputs[0]),
]
}
js_wrap("atom_browserify_isolated") {
deps = [
":atom_browserify_isolated_unwrapped",
]
inputs = [
"$target_gen_dir/js2c/isolated_bundle_unwrapped.js",
]
outputs = [
"$target_gen_dir/js2c/isolated_bundle.js",
]
}
js_wrap("atom_browserify_sandbox") {
deps = [
":atom_browserify_sandbox_unwrapped",
]
inputs = [
"$target_gen_dir/js2c/preload_bundle_unwrapped.js",
]
outputs = [
"$target_gen_dir/js2c/preload_bundle.js",
]
}
copy("atom_js2c_copy") {
sources = [
"lib/common/asar.js",
@@ -324,8 +358,6 @@ static_library("electron_lib") {
"*_views.cc",
"*_views.h",
"*\bviews/*",
"*/autofill_popup.cc",
"*/autofill_popup.h",
]
}
@@ -350,6 +382,10 @@ static_library("electron_lib") {
"//third_party/crashpad/crashpad/client",
"//ui/accelerated_widget_mac",
]
sources += [
"atom/browser/ui/views/autofill_popup_view.cc",
"atom/browser/ui/views/autofill_popup_view.h",
]
include_dirs += [
# NOTE(nornagon): other chromium files use the full path to include
# crashpad; this is just here for compatibility between GN and GYP, so that
@@ -422,11 +458,13 @@ static_library("electron_lib") {
if (enable_osr) {
sources += [
"atom/browser/osr/osr_output_device.cc",
"atom/browser/osr/osr_output_device.h",
"atom/browser/osr/osr_host_display_client.cc",
"atom/browser/osr/osr_host_display_client.h",
"atom/browser/osr/osr_host_display_client_mac.mm",
"atom/browser/osr/osr_render_widget_host_view.cc",
"atom/browser/osr/osr_render_widget_host_view.h",
"atom/browser/osr/osr_render_widget_host_view_mac.mm",
"atom/browser/osr/osr_video_consumer.cc",
"atom/browser/osr/osr_video_consumer.h",
"atom/browser/osr/osr_view_proxy.cc",
"atom/browser/osr/osr_view_proxy.h",
"atom/browser/osr/osr_web_contents_view.cc",
@@ -499,6 +537,7 @@ if (is_mac) {
electron_helper_name = "$electron_product_name Helper"
electron_login_helper_name = "$electron_product_name Login Helper"
electron_framework_version = "A"
electron_version = read_file("ELECTRON_VERSION", "trim string")
mac_xib_bundle_data("electron_xibs") {
sources = [
@@ -581,7 +620,6 @@ if (is_mac) {
}
info_plist = "atom/common/resources/mac/Info.plist"
electron_version = read_file("ELECTRON_VERSION", "trim string")
extra_substitutions = [
"ATOM_BUNDLE_ID=$electron_mac_bundle_id.framework",
"ELECTRON_VERSION=$electron_version",
@@ -600,6 +638,11 @@ if (is_mac) {
"ServiceManagement.framework",
"StoreKit.framework",
]
if (enable_osr) {
libs += [ "IOSurface.framework" ]
}
ldflags = [
"-F",
rebase_path("external_binaries", root_build_dir),
@@ -747,6 +790,56 @@ if (is_mac) {
"@executable_path/../Frameworks",
]
}
if (enable_dsyms) {
extract_symbols("electron_framework_syms") {
binary = "$root_out_dir/$electron_framework_name.framework/Versions/$electron_framework_version/$electron_framework_name"
symbol_dir = "$root_out_dir/breakpad_symbols"
dsym_file = "$root_out_dir/$electron_framework_name.dSYM/Contents/Resources/DWARF/$electron_framework_name"
deps = [
":electron_framework",
]
}
extract_symbols("electron_helper_syms") {
binary = "$root_out_dir/$electron_helper_name.app/Contents/MacOS/$electron_helper_name"
symbol_dir = "$root_out_dir/breakpad_symbols"
dsym_file = "$root_out_dir/$electron_helper_name.dSYM/Contents/Resources/DWARF/$electron_helper_name"
deps = [
":electron_helper_app",
]
}
extract_symbols("electron_app_syms") {
binary = "$root_out_dir/$electron_product_name.app/Contents/MacOS/$electron_product_name"
symbol_dir = "$root_out_dir/breakpad_symbols"
dsym_file = "$root_out_dir/$electron_product_name.dSYM/Contents/Resources/DWARF/$electron_product_name"
deps = [
":electron_app",
]
}
extract_symbols("crashpad_handler_syms") {
binary = "$root_out_dir/crashpad_handler"
symbol_dir = "$root_out_dir/breakpad_symbols"
dsym_file = "$root_out_dir/crashpad_handler.dSYM/Contents/Resources/DWARF/crashpad_handler"
deps = [
"//third_party/crashpad/crashpad/handler:crashpad_handler",
]
}
group("electron_symbols") {
deps = [
":crashpad_handler_syms",
":electron_app_syms",
":electron_framework_syms",
":electron_helper_syms",
]
}
} else {
group("electron_symbols") {
}
}
} else {
windows_manifest("electron_app_manifest") {
sources = [
@@ -844,6 +937,53 @@ if (is_mac) {
}
}
}
if (is_official_build) {
if (is_linux) {
_target_executable_suffix = ""
_target_shared_library_suffix = ".so"
} else if (is_win) {
_target_executable_suffix = ".exe"
_target_shared_library_suffix = ".dll"
}
extract_symbols("electron_app_symbols") {
binary = "$root_out_dir/$electron_project_name$_target_executable_suffix"
symbol_dir = "$root_out_dir/breakpad_symbols"
deps = [
":electron_app",
]
}
extract_symbols("swiftshader_egl_symbols") {
binary = "$root_out_dir/swiftshader/libEGL$_target_shared_library_suffix"
symbol_dir = "$root_out_dir/breakpad_symbols"
deps = [
"//third_party/swiftshader/src/OpenGL/libEGL:swiftshader_libEGL",
]
}
extract_symbols("swiftshader_gles_symbols") {
binary =
"$root_out_dir/swiftshader/libGLESv2$_target_shared_library_suffix"
symbol_dir = "$root_out_dir/breakpad_symbols"
deps = [
"//third_party/swiftshader/src/OpenGL/libGLESv2:swiftshader_libGLESv2",
]
}
group("electron_symbols") {
deps = [
":electron_app_symbols",
]
if (target_cpu == "x86" || target_cpu == "x64") {
deps += [
":swiftshader_egl_symbols",
":swiftshader_gles_symbols",
]
}
}
}
}
template("dist_zip") {

7
DEPS
View File

@@ -10,9 +10,9 @@ gclient_gn_args = [
vars = {
'chromium_version':
'73.0.3683.94',
'73.0.3683.121',
'node_version':
'f807d72614d4b8973d71548328be213532b46b1b',
'666c67e078bddc32f25409f4a929c1e9b5f47373',
'boto_version': 'f7574aa6cc2c819430c1f05e9a1a1a666ef8169b',
'pyyaml_version': '3.12',
@@ -21,6 +21,7 @@ vars = {
'boto_git': 'https://github.com/boto',
'chromium_git': 'https://chromium.googlesource.com',
'electron_git': 'https://github.com/electron',
'nodejs_git': 'https://github.com/nodejs',
'requests_git': 'https://github.com/kennethreitz',
'yaml_git': 'https://github.com/yaml',
@@ -64,7 +65,7 @@ deps = {
'condition': 'checkout_chromium',
},
'src/third_party/electron_node': {
'url': (Var("electron_git")) + '/node.git@' + (Var("node_version")),
'url': (Var("nodejs_git")) + '/node.git@' + (Var("node_version")),
'condition': 'checkout_node',
},
'src/electron/vendor/pyyaml': {

View File

@@ -16,7 +16,7 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
locales \
lsb-release \
nano \
python-dbusmock \
python-dbus \
python-pip \
python-setuptools \
sudo \
@@ -33,6 +33,9 @@ RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
# crcmod is required by gsutil, which is used for filling the gclient git cache
RUN pip install -U crcmod
# dbusmock is needed for Electron tests
RUN pip install python-dbusmock
RUN mkdir /tmp/workspace
RUN chown builduser:builduser /tmp/workspace

View File

@@ -1 +1 @@
5.0.0-beta.7
5.0.9

View File

@@ -68,14 +68,16 @@ build_script:
- appveyor PushArtifact out/ffmpeg/ffmpeg.zip
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
ninja -C out/Default third_party/breakpad:dump_syms
# Needed for msdia140.dll on 64-bit windows
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
ninja -C out/Default electron:electron_symbols
}
- if "%GN_CONFIG%"=="release" ( python electron\script\dump-symbols.py -d %cd%\out\Default\breakpad_symbols -v)
- ps: >-
if ($env:GN_CONFIG -eq 'release') {
python electron\script\zip-symbols.py
appveyor PushArtifact out/Default/symbols.zip
}
- python electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
test_script:
- ps: >-
if ((-Not (Test-Path Env:\ELECTRON_RELEASE)) -And ($env:GN_CONFIG -in "testing", "release")) {

View File

@@ -58,6 +58,11 @@ bool IsBrowserProcess(base::CommandLine* cmd) {
return process_type.empty();
}
bool IsSandboxEnabled(base::CommandLine* command_line) {
return command_line->HasSwitch(switches::kEnableSandbox) ||
!command_line->HasSwitch(service_manager::switches::kNoSandbox);
}
// Returns true if this subprocess type needs the ResourceBundle initialized
// and resources loaded.
bool SubprocessNeedsResourceBundle(const std::string& process_type) {
@@ -183,6 +188,14 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
base::win::DisableHandleVerifier();
#endif
#if defined(OS_LINUX)
// Check for --no-sandbox parameter when running as root.
if (getuid() == 0 && IsSandboxEnabled(command_line))
LOG(FATAL) << "Running as root without --"
<< service_manager::switches::kNoSandbox
<< " is not supported. See https://crbug.com/638180.";
#endif
content_client_ = std::make_unique<AtomContentClient>();
SetContentClient(content_client_.get());
@@ -259,10 +272,9 @@ content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() {
content::ContentRendererClient*
AtomMainDelegate::CreateContentRendererClient() {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableSandbox) ||
!base::CommandLine::ForCurrentProcess()->HasSwitch(
service_manager::switches::kNoSandbox)) {
auto* command_line = base::CommandLine::ForCurrentProcess();
if (IsSandboxEnabled(command_line)) {
renderer_client_.reset(new AtomSandboxedRendererClient);
} else {
renderer_client_.reset(new AtomRendererClient);

View File

@@ -96,6 +96,7 @@ int NodeMain(int argc, char* argv[]) {
}
} while (more == true);
node_debugger.Stop();
exit_code = node::EmitExit(env);
node::RunAtExit(env);
gin_env.platform()->DrainTasks(env->isolate());

View File

@@ -1413,4 +1413,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_app, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_app, Initialize)

View File

@@ -154,4 +154,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_auto_updater, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_auto_updater, Initialize)

View File

@@ -172,4 +172,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_browser_view, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_browser_view, Initialize)

View File

@@ -68,7 +68,7 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate,
}
web_contents_.Reset(isolate, web_contents.ToV8());
api_web_contents_ = web_contents.get();
api_web_contents_ = web_contents->GetWeakPtr();
api_web_contents_->AddObserver(this);
Observe(api_web_contents_->web_contents());
@@ -86,8 +86,7 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate,
InitWith(isolate, wrapper);
#if defined(OS_MACOSX)
if (!window()->has_frame())
OverrideNSWindowContentView(web_contents->managed_web_contents());
OverrideNSWindowContentView(web_contents->managed_web_contents());
#endif
// Init window after everything has been setup.
@@ -95,7 +94,9 @@ BrowserWindow::BrowserWindow(v8::Isolate* isolate,
}
BrowserWindow::~BrowserWindow() {
api_web_contents_->RemoveObserver(this);
// FIXME This is a hack rather than a proper fix preventing shutdown crashes.
if (api_web_contents_)
api_web_contents_->RemoveObserver(this);
// Note that the OnWindowClosed will not be called after the destructor runs,
// since the window object is managed by the TopLevelWindow class.
if (web_contents())
@@ -481,4 +482,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_window, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_window, Initialize)

View File

@@ -116,7 +116,7 @@ class BrowserWindow : public TopLevelWindow,
#endif
v8::Global<v8::Value> web_contents_;
api::WebContents* api_web_contents_;
base::WeakPtr<api::WebContents> api_web_contents_;
base::WeakPtrFactory<BrowserWindow> weak_factory_;

View File

@@ -11,6 +11,7 @@
#include "atom/common/promise_util.h"
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/threading/thread_restrictions.h"
#include "content/public/browser/tracing_controller.h"
#include "native_mate/dictionary.h"
@@ -59,6 +60,11 @@ scoped_refptr<TracingController::TraceDataEndpoint> GetTraceDataEndpoint(
const base::FilePath& path,
const CompletionCallback& callback) {
base::FilePath result_file_path = path;
// base::CreateTemporaryFile prevents blocking so we need to allow it
// for now since offloading this to a different sequence would require
// changing the api shape
base::ThreadRestrictions::ScopedAllowIO allow_io;
if (result_file_path.empty() && !base::CreateTemporaryFile(&result_file_path))
LOG(ERROR) << "Creating temporary file failed";
@@ -134,4 +140,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_content_tracing, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_content_tracing, Initialize)

View File

@@ -226,13 +226,13 @@ void FlushCookieStoreOnIOThread(
void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
std::unique_ptr<base::DictionaryValue> details,
util::Promise promise) {
std::string url, name, value, domain, path;
std::string url_string, name, value, domain, path;
bool secure = false;
bool http_only = false;
double creation_date;
double expiration_date;
double last_access_date;
details->GetString("url", &url);
details->GetString("url", &url_string);
details->GetString("name", &name);
details->GetString("value", &value);
details->GetString("domain", &domain);
@@ -261,24 +261,27 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
: base::Time::FromDoubleT(last_access_date);
}
auto completion_callback = base::BindOnce(OnSetCookie, std::move(promise));
GURL url(url_string);
if (!url.is_valid()) {
std::move(completion_callback).Run(false);
return;
}
if (name.empty()) {
std::move(completion_callback).Run(false);
return;
}
std::unique_ptr<net::CanonicalCookie> canonical_cookie(
net::CanonicalCookie::CreateSanitizedCookie(
GURL(url), name, value, domain, path, creation_time, expiration_time,
url, name, value, domain, path, creation_time, expiration_time,
last_access_time, secure, http_only,
net::CookieSameSite::DEFAULT_MODE, net::COOKIE_PRIORITY_DEFAULT));
auto completion_callback = base::BindOnce(OnSetCookie, std::move(promise));
if (!canonical_cookie || !canonical_cookie->IsCanonical()) {
std::move(completion_callback).Run(false);
return;
}
if (url.empty()) {
std::move(completion_callback).Run(false);
return;
}
if (name.empty()) {
std::move(completion_callback).Run(false);
return;
}
GetCookieStore(getter)->SetCanonicalCookieAsync(
std::move(canonical_cookie), secure, http_only,
std::move(completion_callback));

View File

@@ -205,4 +205,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_debugger, Initialize);
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_debugger, Initialize);

View File

@@ -88,10 +88,6 @@ void DesktopCapturer::StartHandling(bool capture_window,
capture_screen_ = capture_screen;
{
// Remove this once
// https://bugs.chromium.org/p/chromium/issues/detail?id=795340 is fixed.
base::ScopedAllowBaseSyncPrimitivesForTesting
scoped_allow_base_sync_primitives;
// Initialize the source list.
// Apply the new thumbnail size and restart capture.
if (capture_window) {
@@ -230,4 +226,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_desktop_capturer, Initialize);
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_desktop_capturer, Initialize);

View File

@@ -96,4 +96,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_dialog, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_dialog, Initialize)

View File

@@ -251,4 +251,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_download_item, Initialize);
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_download_item, Initialize);

View File

@@ -23,4 +23,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_event, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_event, Initialize)

View File

@@ -166,4 +166,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_global_shortcut, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_global_shortcut, Initialize)

View File

@@ -62,7 +62,7 @@ struct Converter<in_app_purchase::Product> {
dict.Set("formattedPrice", val.formattedPrice);
// Downloadable Content Information
dict.Set("isDownloadable", val.downloadable);
dict.Set("isDownloadable", val.isDownloadable);
return dict.GetHandle();
}
@@ -140,4 +140,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_in_app_purchase, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_in_app_purchase, Initialize)

View File

@@ -245,4 +245,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_menu, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_menu, Initialize)

View File

@@ -61,4 +61,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_net, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_net, Initialize)

View File

@@ -272,4 +272,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_common_notification, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_common_notification, Initialize)

View File

@@ -148,4 +148,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_power_monitor, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_power_monitor, Initialize)

View File

@@ -151,4 +151,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_power_save_blocker, Initialize);
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_power_save_blocker, Initialize);

View File

@@ -317,4 +317,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_protocol, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_protocol, Initialize)

View File

@@ -87,5 +87,5 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_render_process_preferences,
Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_render_process_preferences,
Initialize)

View File

@@ -52,6 +52,19 @@ std::vector<std::string> MetricsToArray(uint32_t metrics) {
return array;
}
void DelayEmit(Screen* screen,
const base::StringPiece& name,
const display::Display& display) {
screen->Emit(name, display);
}
void DelayEmitWithMetrics(Screen* screen,
const base::StringPiece& name,
const display::Display& display,
const std::vector<std::string>& metrics) {
screen->Emit(name, display, metrics);
}
} // namespace
Screen::Screen(v8::Isolate* isolate, display::Screen* screen)
@@ -101,16 +114,23 @@ static gfx::Rect DIPToScreenRect(atom::NativeWindow* window,
#endif
void Screen::OnDisplayAdded(const display::Display& new_display) {
Emit("display-added", new_display);
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
FROM_HERE, base::Bind(&DelayEmit, base::Unretained(this), "display-added",
new_display));
}
void Screen::OnDisplayRemoved(const display::Display& old_display) {
Emit("display-removed", old_display);
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
FROM_HERE, base::Bind(&DelayEmit, base::Unretained(this),
"display-removed", old_display));
}
void Screen::OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) {
Emit("display-metrics-changed", display, MetricsToArray(changed_metrics));
base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
FROM_HERE, base::Bind(&DelayEmitWithMetrics, base::Unretained(this),
"display-metrics-changed", display,
MetricsToArray(changed_metrics)));
}
// static
@@ -171,4 +191,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_common_screen, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_common_screen, Initialize)

View File

@@ -420,6 +420,17 @@ void Session::ResolveProxy(
browser_context_->GetResolveProxyHelper()->ResolveProxy(url, callback);
}
void Session::GetCacheSize(const net::CompletionCallback& callback) {
content::BrowserContext::GetDefaultStoragePartition(browser_context_.get())
->GetNetworkContext()
->ComputeHttpCacheSize(
base::Time(), base::Time::Max(),
base::BindOnce(
[](const net::CompletionCallback& cb, bool is_upper_bound,
int64_t size_or_error) { cb.Run(size_or_error); },
callback));
}
template <Session::CacheAction action>
void Session::DoCacheAction(const net::CompletionCallback& callback) {
base::PostTaskWithTraits(
@@ -748,7 +759,7 @@ void Session::BuildPrototype(v8::Isolate* isolate,
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
.MakeDestroyable()
.SetMethod("resolveProxy", &Session::ResolveProxy)
.SetMethod("getCacheSize", &Session::DoCacheAction<CacheAction::STATS>)
.SetMethod("getCacheSize", &Session::GetCacheSize)
.SetMethod("clearCache", &Session::DoCacheAction<CacheAction::CLEAR>)
.SetMethod("clearStorageData", &Session::ClearStorageData)
.SetMethod("flushStorageData", &Session::FlushStorageData)
@@ -819,4 +830,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_session, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_session, Initialize)

View File

@@ -66,6 +66,7 @@ class Session : public mate::TrackableObject<Session>,
const ResolveProxyHelper::ResolveProxyCallback& callback);
template <CacheAction action>
void DoCacheAction(const net::CompletionCallback& callback);
void GetCacheSize(const net::CompletionCallback& callback);
void ClearStorageData(mate::Arguments* args);
void FlushStorageData();
void SetProxy(const mate::Dictionary& options, const base::Closure& callback);

View File

@@ -128,4 +128,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_system_preferences, Initialize);
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_system_preferences, Initialize);

View File

@@ -11,6 +11,7 @@
#include "atom/browser/mac/atom_application.h"
#include "atom/browser/mac/dict_util.h"
#include "atom/browser/ui/cocoa/NSColor+Hex.h"
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/value_converter.h"
#include "base/mac/sdk_forward_declarations.h"
@@ -19,6 +20,7 @@
#include "base/values.h"
#include "native_mate/object_template_builder.h"
#include "net/base/mac/url_conversions.h"
#include "ui/native_theme/native_theme.h"
namespace mate {
template <>
@@ -56,11 +58,11 @@ struct Converter<NSAppearance*> {
return v8::Null(isolate);
}
if (val.name == NSAppearanceNameAqua) {
if ([val.name isEqualToString:NSAppearanceNameAqua]) {
return mate::ConvertToV8(isolate, "light");
}
if (@available(macOS 10.14, *)) {
if (val.name == NSAppearanceNameDarkAqua) {
if ([val.name isEqualToString:NSAppearanceNameDarkAqua]) {
return mate::ConvertToV8(isolate, "dark");
}
}
@@ -106,21 +108,6 @@ std::string ConvertAuthorizationStatus(AVAuthorizationStatusMac status) {
}
}
// Convert color to RGBA value like "aabbccdd"
std::string ToRGBA(NSColor* color) {
return base::StringPrintf(
"%02X%02X%02X%02X", (int)(color.redComponent * 0xFF),
(int)(color.greenComponent * 0xFF), (int)(color.blueComponent * 0xFF),
(int)(color.alphaComponent * 0xFF));
}
// Convert color to RGB hex value like "#ABCDEF"
std::string ToRGBHex(NSColor* color) {
return base::StringPrintf("#%02X%02X%02X", (int)(color.redComponent * 0xFF),
(int)(color.greenComponent * 0xFF),
(int)(color.blueComponent * 0xFF));
}
} // namespace
void SystemPreferences::PostNotification(const std::string& name,
@@ -400,7 +387,7 @@ std::string SystemPreferences::GetAccentColor() {
if (@available(macOS 10.14, *))
sysColor = [NSColor controlAccentColor];
return ToRGBA(sysColor);
return base::SysNSStringToUTF8([sysColor RGBAValue]);
}
std::string SystemPreferences::GetSystemColor(const std::string& color,
@@ -429,7 +416,7 @@ std::string SystemPreferences::GetSystemColor(const std::string& color,
return "";
}
return ToRGBHex(sysColor);
return base::SysNSStringToUTF8([sysColor hexadecimalValue]);
}
// static
@@ -519,7 +506,7 @@ std::string SystemPreferences::GetColor(const std::string& color,
return "";
}
return ToRGBHex(sysColor);
return base::SysNSStringToUTF8([sysColor hexadecimalValue]);
}
std::string SystemPreferences::GetMediaAccessStatus(
@@ -571,6 +558,9 @@ void SystemPreferences::RemoveUserDefault(const std::string& name) {
}
bool SystemPreferences::IsDarkMode() {
if (@available(macOS 10.15, *)) {
return ui::NativeTheme::GetInstanceForNativeUi()->SystemDarkModeEnabled();
}
NSString* mode = [[NSUserDefaults standardUserDefaults]
stringForKey:@"AppleInterfaceStyle"];
return [mode isEqualToString:@"Dark"];

View File

@@ -1199,4 +1199,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_top_level_window, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_top_level_window, Initialize)

View File

@@ -59,11 +59,7 @@ Tray::Tray(v8::Isolate* isolate,
InitWith(isolate, wrapper);
}
Tray::~Tray() {
// Destroy the native tray in next tick.
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
tray_icon_.release());
}
Tray::~Tray() = default;
// static
mate::WrappableBase* Tray::New(mate::Handle<NativeImage> image,
@@ -192,7 +188,7 @@ void Tray::DisplayBalloon(mate::Arguments* args,
#if defined(OS_WIN)
tray_icon_->DisplayBalloon(
icon.IsEmpty() ? NULL : icon->GetHICON(GetSystemMetrics(SM_CXSMICON)),
icon.IsEmpty() ? NULL : icon->GetHICON(GetSystemMetrics(SM_CXICON)),
title, content);
#else
tray_icon_->DisplayBalloon(icon.IsEmpty() ? gfx::Image() : icon->image(),
@@ -261,4 +257,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_tray, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_tray, Initialize)

View File

@@ -86,4 +86,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_view, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_view, Initialize)

View File

@@ -87,7 +87,6 @@
#include "ui/events/base_event_utils.h"
#if BUILDFLAG(ENABLE_OSR)
#include "atom/browser/osr/osr_output_device.h"
#include "atom/browser/osr/osr_render_widget_host_view.h"
#include "atom/browser/osr/osr_web_contents_view.h"
#endif
@@ -288,7 +287,9 @@ struct WebContents::FrameDispatchHelper {
WebContents::WebContents(v8::Isolate* isolate,
content::WebContents* web_contents)
: content::WebContentsObserver(web_contents), type_(REMOTE) {
: content::WebContentsObserver(web_contents),
type_(REMOTE),
weak_factory_(this) {
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent(),
false);
Init(isolate);
@@ -299,7 +300,9 @@ WebContents::WebContents(v8::Isolate* isolate,
WebContents::WebContents(v8::Isolate* isolate,
std::unique_ptr<content::WebContents> web_contents,
Type type)
: content::WebContentsObserver(web_contents.get()), type_(type) {
: content::WebContentsObserver(web_contents.get()),
type_(type),
weak_factory_(this) {
DCHECK(type != REMOTE) << "Can't take ownership of a remote WebContents";
auto session = Session::CreateFrom(isolate, GetBrowserContext());
session_.Reset(isolate, session.ToV8());
@@ -307,8 +310,8 @@ WebContents::WebContents(v8::Isolate* isolate,
mate::Dictionary::CreateEmpty(isolate));
}
WebContents::WebContents(v8::Isolate* isolate,
const mate::Dictionary& options) {
WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options)
: weak_factory_(this) {
// Read options.
options.Get("backgroundThrottling", &background_throttling_);
@@ -598,7 +601,7 @@ void WebContents::SetContentsBounds(content::WebContents* source,
void WebContents::CloseContents(content::WebContents* source) {
Emit("close");
#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
#if defined(TOOLKIT_VIEWS)
HideAutofillPopup();
#endif
if (managed_web_contents())
@@ -838,6 +841,10 @@ void WebContents::DidChangeThemeColor(SkColor theme_color) {
}
}
void WebContents::DidAcquireFullscreen(content::RenderFrameHost* rfh) {
set_fullscreen_frame(rfh);
}
void WebContents::DocumentLoadedInFrame(
content::RenderFrameHost* render_frame_host) {
if (!render_frame_host->GetParent())
@@ -1026,7 +1033,7 @@ void WebContents::DevToolsClosed() {
Emit("devtools-closed");
}
#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
#if defined(TOOLKIT_VIEWS)
void WebContents::ShowAutofillPopup(content::RenderFrameHost* frame_host,
const gfx::RectF& bounds,
const std::vector<base::string16>& values,
@@ -1073,7 +1080,7 @@ bool WebContents::OnMessageReceived(const IPC::Message& message,
FrameDispatchHelper::OnSetTemporaryZoomLevel)
IPC_MESSAGE_FORWARD_DELAY_REPLY(AtomFrameHostMsg_GetZoomLevel, &helper,
FrameDispatchHelper::OnGetZoomLevel)
#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
#if defined(TOOLKIT_VIEWS)
IPC_MESSAGE_HANDLER(AtomAutofillFrameHostMsg_ShowPopup, ShowAutofillPopup)
IPC_MESSAGE_HANDLER(AtomAutofillFrameHostMsg_HidePopup, HideAutofillPopup)
#endif
@@ -1214,6 +1221,9 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
params.transition_type = ui::PAGE_TRANSITION_TYPED;
params.should_clear_history_list = true;
params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
// Discord non-committed entries to ensure that we don't re-use a pending
// entry
web_contents()->GetController().DiscardNonCommittedEntries();
web_contents()->GetController().LoadURLWithParams(params);
// Set the background color of RenderWidgetHostView.
@@ -1670,13 +1680,24 @@ bool WebContents::SendIPCMessageWithSender(bool internal,
const std::string& channel,
const base::ListValue& args,
int32_t sender_id) {
auto* frame_host = web_contents()->GetMainFrame();
if (frame_host) {
return frame_host->Send(new AtomFrameMsg_Message(frame_host->GetRoutingID(),
internal, send_to_all,
channel, args, sender_id));
std::vector<content::RenderFrameHost*> target_hosts;
if (!send_to_all) {
auto* frame_host = web_contents()->GetMainFrame();
if (frame_host) {
target_hosts.push_back(frame_host);
}
} else {
target_hosts = web_contents()->GetAllFrames();
}
return false;
bool handled = false;
for (auto* frame_host : target_hosts) {
handled = frame_host->Send(
new AtomFrameMsg_Message(frame_host->GetRoutingID(), internal,
false, channel, args, sender_id)) ||
handled;
}
return handled;
}
bool WebContents::SendIPCMessageToFrame(bool internal,
@@ -1735,6 +1756,19 @@ void WebContents::SendInputEvent(v8::Isolate* isolate,
mouse_wheel_event);
#endif
} else {
// Chromium expects phase info in wheel events (and applies a
// DCHECK to verify it). See: https://crbug.com/756524.
mouse_wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
mouse_wheel_event.dispatch_type = blink::WebInputEvent::kBlocking;
rwh->ForwardWheelEvent(mouse_wheel_event);
// Send a synthetic wheel event with phaseEnded to finish scrolling.
mouse_wheel_event.has_synthetic_phase = true;
mouse_wheel_event.delta_x = 0;
mouse_wheel_event.delta_y = 0;
mouse_wheel_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
mouse_wheel_event.dispatch_type =
blink::WebInputEvent::kEventNonBlocking;
rwh->ForwardWheelEvent(mouse_wheel_event);
}
return;
@@ -1756,7 +1790,7 @@ void WebContents::BeginFrameSubscription(mate::Arguments* args) {
}
frame_subscriber_.reset(
new FrameSubscriber(isolate(), web_contents(), callback, only_dirty));
new FrameSubscriber(web_contents(), callback, only_dirty));
}
void WebContents::EndFrameSubscription() {
@@ -2296,4 +2330,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_web_contents, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_web_contents, Initialize)

View File

@@ -111,6 +111,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
static void BuildPrototype(v8::Isolate* isolate,
v8::Local<v8::FunctionTemplate> prototype);
base::WeakPtr<WebContents> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
// Destroy the managed content::WebContents instance.
//
// Note: The |async| should only be |true| when users are expecting to use the
@@ -448,6 +450,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
const MediaPlayerId& id,
content::WebContentsObserver::MediaStoppedReason reason) override;
void DidChangeThemeColor(SkColor theme_color) override;
void DidAcquireFullscreen(content::RenderFrameHost* rfh) override;
// InspectableWebContentsDelegate:
void DevToolsReloadPage() override;
@@ -544,6 +547,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
// -1 means no speculative RVH has been committed yet.
int currently_committed_process_id_ = -1;
base::WeakPtrFactory<WebContents> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(WebContents);
};

View File

@@ -131,4 +131,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_web_contents_view, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_web_contents_view, Initialize)

View File

@@ -4,6 +4,7 @@
#include "atom/browser/api/atom_api_web_request.h"
#include <set>
#include <string>
#include <utility>
@@ -20,23 +21,6 @@
using content::BrowserThread;
namespace mate {
template <>
struct Converter<URLPattern> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
URLPattern* out) {
std::string pattern;
if (!ConvertFromV8(isolate, val, &pattern))
return false;
*out = URLPattern(URLPattern::SCHEME_ALL);
return out->Parse(pattern) == URLPattern::ParseResult::kSuccess;
}
};
} // namespace mate
namespace atom {
namespace api {
@@ -84,7 +68,25 @@ void WebRequest::SetListener(Method method, Event type, mate::Arguments* args) {
// { urls }.
URLPatterns patterns;
mate::Dictionary dict;
args->GetNext(&dict) && dict.Get("urls", &patterns);
std::set<std::string> filter_patterns;
if (args->GetNext(&dict) && !dict.Get("urls", &filter_patterns)) {
args->ThrowError(
"onBeforeRequest parameter 'filter' must have property 'urls'.");
return;
}
URLPattern pattern(URLPattern::SCHEME_ALL);
for (const std::string& filter_pattern : filter_patterns) {
const URLPattern::ParseResult result = pattern.Parse(filter_pattern);
if (result == URLPattern::ParseResult::kSuccess) {
patterns.insert(pattern);
} else {
const char* error_type = URLPattern::GetParseResultString(result);
args->ThrowError("Invalid url pattern " + filter_pattern + ": " +
error_type);
}
}
// Function or null.
v8::Local<v8::Value> value;

View File

@@ -55,4 +55,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_web_view_manager, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_web_view_manager, Initialize)

View File

@@ -10,6 +10,7 @@
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/skbitmap_operations.h"
#include "atom/common/node_includes.h"
@@ -20,12 +21,10 @@ namespace api {
constexpr static int kMaxFrameRate = 30;
FrameSubscriber::FrameSubscriber(v8::Isolate* isolate,
content::WebContents* web_contents,
FrameSubscriber::FrameSubscriber(content::WebContents* web_contents,
const FrameCaptureCallback& callback,
bool only_dirty)
: content::WebContentsObserver(web_contents),
isolate_(isolate),
callback_(callback),
only_dirty_(only_dirty),
weak_ptr_factory_(this) {
@@ -149,26 +148,23 @@ void FrameSubscriber::Done(const gfx::Rect& damage, const SkBitmap& frame) {
if (frame.drawsNothing())
return;
v8::Locker locker(isolate_);
v8::HandleScope handle_scope(isolate_);
const_cast<SkBitmap&>(frame).setAlphaType(kPremul_SkAlphaType);
const SkBitmap& bitmap = only_dirty_ ? SkBitmapOperations::CreateTiledBitmap(
frame, damage.x(), damage.y(),
damage.width(), damage.height())
: frame;
size_t rgb_row_size = bitmap.width() * bitmap.bytesPerPixel();
auto* source = static_cast<const char*>(bitmap.getPixels());
// Copying SkBitmap does not copy the internal pixels, we have to manually
// allocate and write pixels otherwise crash may happen when the original
// frame is modified.
SkBitmap copy;
copy.allocPixels(SkImageInfo::Make(bitmap.width(), bitmap.height(),
kRGBA_8888_SkColorType,
kPremul_SkAlphaType));
SkPixmap pixmap;
bool success = bitmap.peekPixels(&pixmap) && copy.writePixels(pixmap, 0, 0);
CHECK(success);
v8::MaybeLocal<v8::Object> buffer =
node::Buffer::Copy(isolate_, source, rgb_row_size * bitmap.height());
auto local_buffer = buffer.ToLocalChecked();
v8::Local<v8::Value> damage_rect =
mate::Converter<gfx::Rect>::ToV8(isolate_, damage);
callback_.Run(local_buffer, damage_rect);
callback_.Run(gfx::Image::CreateFrom1xBitmap(copy), damage);
}
} // namespace api

View File

@@ -14,6 +14,10 @@
#include "content/public/browser/web_contents_observer.h"
#include "v8/include/v8.h"
namespace gfx {
class Image;
}
namespace atom {
namespace api {
@@ -24,10 +28,9 @@ class FrameSubscriber : public content::WebContentsObserver,
public viz::mojom::FrameSinkVideoConsumer {
public:
using FrameCaptureCallback =
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)>;
base::Callback<void(const gfx::Image&, const gfx::Rect&)>;
FrameSubscriber(v8::Isolate* isolate,
content::WebContents* web_contents,
FrameSubscriber(content::WebContents* web_contents,
const FrameCaptureCallback& callback,
bool only_dirty);
~FrameSubscriber() override;
@@ -52,7 +55,6 @@ class FrameSubscriber : public content::WebContentsObserver,
void Done(const gfx::Rect& damage, const SkBitmap& frame);
v8::Isolate* isolate_;
FrameCaptureCallback callback_;
bool only_dirty_;

View File

@@ -84,4 +84,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_box_layout, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_box_layout, Initialize)

View File

@@ -57,4 +57,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_button, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_button, Initialize)

View File

@@ -77,4 +77,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_label_button, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_label_button, Initialize)

View File

@@ -60,4 +60,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_layout_manager, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_layout_manager, Initialize)

View File

@@ -54,4 +54,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_md_text_button, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_md_text_button, Initialize)

View File

@@ -57,4 +57,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_resize_area, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_resize_area, Initialize)

View File

@@ -64,4 +64,4 @@ void Initialize(v8::Local<v8::Object> exports,
} // namespace
NODE_BUILTIN_MODULE_CONTEXT_AWARE(atom_browser_text_field, Initialize)
NODE_LINKED_MODULE_CONTEXT_AWARE(atom_browser_text_field, Initialize)

View File

@@ -611,11 +611,6 @@ bool AtomBrowserClient::CanCreateWindow(
int opener_render_process_id = opener->GetProcess()->GetID();
if (IsRendererSandboxed(opener_render_process_id)) {
*no_javascript_access = false;
return true;
}
if (RendererUsesNativeWindowOpen(opener_render_process_id)) {
if (RendererDisablesPopups(opener_render_process_id)) {
// <webview> without allowpopups attribute should return

View File

@@ -481,6 +481,7 @@ void AtomBrowserMainParts::PostMainMessageLoopRun() {
ui::SetX11ErrorHandlers(X11EmptyErrorHandler, X11EmptyIOErrorHandler);
#endif
node_debugger_->Stop();
js_env_->OnMessageLoopDestroying();
#if defined(OS_MACOSX)

View File

@@ -54,8 +54,26 @@ void AtomBrowserMainParts::InitializeMainNib() {
auto application = [principalClass sharedApplication];
NSString* mainNibName = [infoDictionary objectForKey:@"NSMainNibFile"];
auto mainNib = [[NSNib alloc] initWithNibNamed:mainNibName
bundle:base::mac::FrameworkBundle()];
NSNib* mainNib;
@try {
mainNib = [[NSNib alloc] initWithNibNamed:mainNibName
bundle:base::mac::FrameworkBundle()];
// Handle failure of initWithNibNamed on SMB shares
// TODO(codebytere): Remove when
// https://bugs.chromium.org/p/chromium/issues/detail?id=932935 is fixed
} @catch (NSException* exception) {
NSString* nibPath =
[NSString stringWithFormat:@"Resources/%@.nib", mainNibName];
nibPath = [base::mac::FrameworkBundle().bundlePath
stringByAppendingPathComponent:nibPath];
NSData* data = [NSData dataWithContentsOfFile:nibPath];
mainNib = [[NSNib alloc] initWithNibData:data
bundle:base::mac::FrameworkBundle()];
}
[mainNib instantiateWithOwner:application topLevelObjects:nil];
[mainNib release];
}

View File

@@ -111,7 +111,7 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
settings.parent_window = window;
if (settings.title.size() == 0)
settings.title = item->GetURL().spec();
if (!settings.default_path.empty())
if (settings.default_path.empty())
settings.default_path = default_path;
auto* web_preferences = WebContentsPreferences::From(web_contents);

View File

@@ -61,9 +61,16 @@ void AtomJavaScriptDialogManager::RunJavaScriptDialog(
return;
}
// No default button
int default_id = -1;
int cancel_id = 0;
std::vector<std::string> buttons = {"OK"};
if (dialog_type == JavaScriptDialogType::JAVASCRIPT_DIALOG_TYPE_CONFIRM) {
buttons.push_back("Cancel");
// First button is default, second button is cancel
default_id = 0;
cancel_id = 1;
}
origin_counts_[origin]++;
@@ -85,8 +92,8 @@ void AtomJavaScriptDialogManager::RunJavaScriptDialog(
}
atom::ShowMessageBox(
window, atom::MessageBoxType::MESSAGE_BOX_TYPE_NONE, buttons, -1, 0,
atom::MessageBoxOptions::MESSAGE_BOX_NONE, "",
window, atom::MessageBoxType::MESSAGE_BOX_TYPE_NONE, buttons, default_id,
cancel_id, atom::MessageBoxOptions::MESSAGE_BOX_NONE, "",
base::UTF16ToUTF8(message_text), "", checkbox, false, gfx::ImageSkia(),
base::Bind(&AtomJavaScriptDialogManager::OnMessageBoxCallback,
base::Unretained(this), base::Passed(std::move(callback)),

View File

@@ -183,12 +183,14 @@ int AtomPermissionManager::RequestPermissionsWithDetails(
const auto callback =
base::Bind(&AtomPermissionManager::OnPermissionResponse,
base::Unretained(this), request_id, i);
if (details == nullptr) {
request_handler_.Run(web_contents, permission, callback,
base::DictionaryValue());
} else {
request_handler_.Run(web_contents, permission, callback, *details);
}
auto mutable_details =
details == nullptr ? base::DictionaryValue() : details->Clone();
mutable_details.SetKey(
"requestingUrl",
base::Value(render_frame_host->GetLastCommittedURL().spec()));
mutable_details.SetKey(
"isMainFrame", base::Value(render_frame_host->GetParent() == nullptr));
request_handler_.Run(web_contents, permission, callback, mutable_details);
}
return request_id;
@@ -241,8 +243,15 @@ bool AtomPermissionManager::CheckPermissionWithDetails(
}
auto* web_contents =
content::WebContents::FromRenderFrameHost(render_frame_host);
auto mutable_details =
details == nullptr ? base::DictionaryValue() : details->Clone();
mutable_details.SetKey(
"requestingUrl",
base::Value(render_frame_host->GetLastCommittedURL().spec()));
mutable_details.SetKey(
"isMainFrame", base::Value(render_frame_host->GetParent() == nullptr));
return check_handler_.Run(web_contents, permission, requesting_origin,
*details);
mutable_details);
}
blink::mojom::PermissionStatus

View File

@@ -31,11 +31,11 @@ class AtomPermissionManager : public content::PermissionControllerDelegate {
using RequestHandler = base::Callback<void(content::WebContents*,
content::PermissionType,
const StatusCallback&,
const base::DictionaryValue&)>;
const base::Value&)>;
using CheckHandler = base::Callback<bool(content::WebContents*,
content::PermissionType,
const GURL& requesting_origin,
const base::DictionaryValue&)>;
const base::Value&)>;
// Handler to dispatch permission requests in JS.
void SetPermissionRequestHandler(const RequestHandler& handler);

View File

@@ -145,7 +145,8 @@ bool Browser::IsUnityRunning() {
void Browser::ShowAboutPanel() {
std::string app_name, version, copyright, icon_path, website;
GtkAboutDialog* dialog = GTK_ABOUT_DIALOG(gtk_about_dialog_new());
GtkWidget* dialogWidget = gtk_about_dialog_new();
GtkAboutDialog* dialog = GTK_ABOUT_DIALOG(dialogWidget);
if (about_panel_options_.GetString("applicationName", &app_name))
gtk_about_dialog_set_program_name(dialog, app_name.c_str());
@@ -157,7 +158,12 @@ void Browser::ShowAboutPanel() {
gtk_about_dialog_set_website(dialog, website.c_str());
if (about_panel_options_.GetString("iconPath", &icon_path)) {
GError* error = nullptr;
GdkPixbuf* icon = gdk_pixbuf_new_from_file(icon_path.c_str(), &error);
constexpr int width = 64; // width of about panel icon in pixels
constexpr int height = 64; // height of about panel icon in pixels
// set preserve_aspect_ratio to true
GdkPixbuf* icon = gdk_pixbuf_new_from_file_at_size(icon_path.c_str(), width,
height, &error);
if (error != nullptr) {
g_warning("%s", error->message);
g_clear_error(&error);
@@ -168,7 +174,7 @@ void Browser::ShowAboutPanel() {
}
gtk_dialog_run(GTK_DIALOG(dialog));
g_clear_object(&dialog);
gtk_widget_destroy(dialogWidget);
}
void Browser::SetAboutPanelOptions(const base::DictionaryValue& options) {

View File

@@ -95,9 +95,6 @@ void Browser::Focus() {
}
void Browser::AddRecentDocument(const base::FilePath& path) {
if (base::win::GetVersion() < base::win::VERSION_WIN7)
return;
CComPtr<IShellItem> item;
HRESULT hr = SHCreateItemFromParsingName(path.value().c_str(), NULL,
IID_PPV_ARGS(&item));
@@ -110,13 +107,7 @@ void Browser::AddRecentDocument(const base::FilePath& path) {
}
void Browser::ClearRecentDocuments() {
CComPtr<IApplicationDestinations> destinations;
if (FAILED(destinations.CoCreateInstance(CLSID_ApplicationDestinations, NULL,
CLSCTX_INPROC_SERVER)))
return;
if (FAILED(destinations->SetAppID(GetAppUserModelID())))
return;
destinations->RemoveAllDestinations();
SHAddToRecentDocs(SHARD_APPIDINFO, nullptr);
}
void Browser::SetAppUserModelID(const base::string16& name) {

View File

@@ -208,7 +208,7 @@ void CommonWebContentsDelegate::SetOwnerWindow(
NativeWindow* owner_window) {
if (owner_window) {
owner_window_ = owner_window->GetWeakPtr();
#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
#if defined(TOOLKIT_VIEWS)
autofill_popup_.reset(new AutofillPopup());
#endif
NativeWindowRelay::CreateForWebContents(web_contents,
@@ -322,9 +322,12 @@ void CommonWebContentsDelegate::EnterFullscreenModeForTab(
const blink::WebFullscreenOptions& options) {
if (!owner_window_)
return;
if (IsFullscreenForTabOrPending(source)) {
DCHECK_EQ(fullscreen_frame_, source->GetFocusedFrame());
return;
}
SetHtmlApiFullscreen(true);
owner_window_->NotifyWindowEnterHtmlFullScreen();
source->GetRenderViewHost()->GetWidget()->SynchronizeVisualProperties();
}
void CommonWebContentsDelegate::ExitFullscreenModeForTab(
@@ -333,7 +336,6 @@ void CommonWebContentsDelegate::ExitFullscreenModeForTab(
return;
SetHtmlApiFullscreen(false);
owner_window_->NotifyWindowLeaveHtmlFullScreen();
source->GetRenderViewHost()->GetWidget()->SynchronizeVisualProperties();
}
bool CommonWebContentsDelegate::IsFullscreenForTabOrPending(
@@ -621,4 +623,24 @@ void CommonWebContentsDelegate::SetHtmlApiFullscreen(bool enter_fullscreen) {
native_fullscreen_ = false;
}
void CommonWebContentsDelegate::ShowAutofillPopup(
content::RenderFrameHost* frame_host,
content::RenderFrameHost* embedder_frame_host,
bool offscreen,
const gfx::RectF& bounds,
const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) {
if (!owner_window())
return;
autofill_popup_->CreateView(frame_host, embedder_frame_host, offscreen,
owner_window()->content_view(), bounds);
autofill_popup_->SetItems(values, labels);
}
void CommonWebContentsDelegate::HideAutofillPopup() {
if (autofill_popup_)
autofill_popup_->Hide();
}
} // namespace atom

View File

@@ -18,7 +18,7 @@
#include "content/public/browser/web_contents_delegate.h"
#include "electron/buildflags/buildflags.h"
#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
#if defined(TOOLKIT_VIEWS)
#include "atom/browser/ui/autofill_popup.h"
#endif
@@ -68,6 +68,10 @@ class CommonWebContentsDelegate : public content::WebContentsDelegate,
bool is_html_fullscreen() const { return html_fullscreen_; }
void set_fullscreen_frame(content::RenderFrameHost* rfh) {
fullscreen_frame_ = rfh;
}
protected:
#if BUILDFLAG(ENABLE_OSR)
virtual OffScreenWebContentsView* GetOffScreenWebContentsView() const;
@@ -105,7 +109,7 @@ class CommonWebContentsDelegate : public content::WebContentsDelegate,
const content::NativeWebKeyboardEvent& event) override;
// Autofill related events.
#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
#if defined(TOOLKIT_VIEWS)
void ShowAutofillPopup(content::RenderFrameHost* frame_host,
content::RenderFrameHost* embedder_frame_host,
bool offscreen,
@@ -175,7 +179,7 @@ class CommonWebContentsDelegate : public content::WebContentsDelegate,
bool native_fullscreen_ = false;
// UI related helper classes.
#if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX)
#if defined(TOOLKIT_VIEWS)
std::unique_ptr<AutofillPopup> autofill_popup_;
#endif
std::unique_ptr<WebDialogHelper> web_dialog_helper_;
@@ -203,6 +207,9 @@ class CommonWebContentsDelegate : public content::WebContentsDelegate,
scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
// Stores the frame thats currently in fullscreen, nullptr if there is none.
content::RenderFrameHost* fullscreen_frame_ = nullptr;
base::WeakPtrFactory<CommonWebContentsDelegate> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(CommonWebContentsDelegate);

View File

@@ -41,27 +41,6 @@ bool CommonWebContentsDelegate::HandleKeyboardEvent(
return false;
}
void CommonWebContentsDelegate::ShowAutofillPopup(
content::RenderFrameHost* frame_host,
content::RenderFrameHost* embedder_frame_host,
bool offscreen,
const gfx::RectF& bounds,
const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) {
if (!owner_window())
return;
auto* window = static_cast<NativeWindowViews*>(owner_window());
autofill_popup_->CreateView(frame_host, embedder_frame_host, offscreen,
window->content_view(), bounds);
autofill_popup_->SetItems(values, labels);
}
void CommonWebContentsDelegate::HideAutofillPopup() {
if (autofill_popup_)
autofill_popup_->Hide();
}
gfx::ImageSkia CommonWebContentsDelegate::GetDevToolsWindowIcon() {
if (!owner_window())
return gfx::ImageSkia();

View File

@@ -74,6 +74,7 @@ void JavascriptEnvironment::OnMessageLoopCreated() {
void JavascriptEnvironment::OnMessageLoopDestroying() {
DCHECK(microtasks_runner_);
base::MessageLoopCurrent::Get()->RemoveTaskObserver(microtasks_runner_.get());
platform_->DrainTasks(isolate_);
platform_->UnregisterIsolate(isolate_);
}

View File

@@ -29,7 +29,7 @@ struct Product {
std::string formattedPrice;
// Downloadable Content Information
bool downloadable = false;
bool isDownloadable = false;
Product(const Product&);
Product();

View File

@@ -141,15 +141,13 @@
if (product.priceLocale != nil) {
productStruct.formattedPrice =
[[self formatPrice:product.price withLocal:product.priceLocale]
UTF8String];
[[self formatPrice:product.price
withLocal:product.priceLocale] UTF8String];
}
}
// Downloadable Content Information
if (product.downloadable == true) {
productStruct.downloadable = true;
}
productStruct.isDownloadable = [product downloadable];
return productStruct;
}

View File

@@ -165,7 +165,7 @@ class NativeWindowMac : public NativeWindow {
private:
// Add custom layers to the content view.
void AddContentViewLayers();
void AddContentViewLayers(bool minimizable, bool closable);
void InternalSetParentWindow(NativeWindow* parent, bool attach);
void SetForwardMouseMessages(bool forward);

View File

@@ -73,9 +73,11 @@
NSButton* close_button =
[NSWindow standardWindowButton:NSWindowCloseButton
forStyleMask:NSWindowStyleMaskTitled];
[close_button setTag:1];
NSButton* miniaturize_button =
[NSWindow standardWindowButton:NSWindowMiniaturizeButton
forStyleMask:NSWindowStyleMaskTitled];
[miniaturize_button setTag:2];
CGFloat x = 0;
const CGFloat space_between = 20;
@@ -233,7 +235,10 @@ namespace atom {
namespace {
bool IsFramelessWindow(NSView* view) {
NativeWindow* window = [static_cast<AtomNSWindow*>([view window]) shell];
NSWindow* nswindow = [view window];
if (![nswindow respondsToSelector:@selector(shell)])
return false;
NativeWindow* window = [static_cast<AtomNSWindow*>(nswindow) shell];
return window && !window->has_frame();
}
@@ -456,7 +461,7 @@ NativeWindowMac::NativeWindowMac(const mate::Dictionary& options,
// Default content view.
SetContentView(new views::View());
AddContentViewLayers();
AddContentViewLayers(minimizable, closable);
original_frame_ = [window_ frame];
original_level_ = [window_ level];
@@ -820,6 +825,7 @@ void NativeWindowMac::SetAlwaysOnTop(bool top,
int relativeLevel,
std::string* error) {
int windowLevel = NSNormalWindowLevel;
bool level_changed = top != widget()->IsAlwaysOnTop();
CGWindowLevel maxWindowLevel = CGWindowLevelForKey(kCGMaximumWindowLevelKey);
CGWindowLevel minWindowLevel = CGWindowLevelForKey(kCGMinimumWindowLevelKey);
@@ -846,12 +852,22 @@ void NativeWindowMac::SetAlwaysOnTop(bool top,
NSInteger newLevel = windowLevel + relativeLevel;
if (newLevel >= minWindowLevel && newLevel <= maxWindowLevel) {
was_maximizable_ = IsMaximizable();
[window_ setLevel:newLevel];
// Set level will make the zoom button revert to default, probably
// a bug of Cocoa or macOS.
[[window_ standardWindowButton:NSWindowZoomButton]
setEnabled:was_maximizable_];
} else {
*error = std::string([
[NSString stringWithFormat:@"relativeLevel must be between %d and %d",
minWindowLevel, maxWindowLevel] UTF8String]);
*error = std::string([[NSString
stringWithFormat:@"relativeLevel must be between %d and %d",
minWindowLevel, maxWindowLevel] UTF8String]);
}
// This must be notified at the very end or IsAlwaysOnTop
// will not yet have been updated to reflect the new status
if (level_changed)
NativeWindow::NotifyWindowAlwaysOnTopChanged();
}
bool NativeWindowMac::IsAlwaysOnTop() {
@@ -1089,7 +1105,7 @@ void NativeWindowMac::RemoveBrowserView(NativeBrowserView* view) {
}
[view->GetInspectableWebContentsView()->GetNativeView().GetNativeNSView()
removeFromSuperview];
removeFromSuperview];
remove_browser_view(view);
[CATransaction commit];
@@ -1371,7 +1387,7 @@ views::View* NativeWindowMac::GetContentsView() {
return root_view_.get();
}
void NativeWindowMac::AddContentViewLayers() {
void NativeWindowMac::AddContentViewLayers(bool minimizable, bool closable) {
// Make sure the bottom corner is rounded for non-modal windows:
// http://crbug.com/396264.
if (!is_modal()) {
@@ -1411,6 +1427,12 @@ void NativeWindowMac::AddContentViewLayers() {
[[CustomWindowButtonView alloc] initWithFrame:NSZeroRect]);
// NSWindowStyleMaskFullSizeContentView does not work with zoom button
SetFullScreenable(false);
if (!minimizable)
[[buttons_view_ viewWithTag:2] removeFromSuperview];
if (!closable)
[[buttons_view_ viewWithTag:1] removeFromSuperview];
[[window_ contentView] addSubview:buttons_view_];
} else {
if (title_bar_style_ != NORMAL)
@@ -1467,7 +1489,7 @@ void NativeWindowMac::OverrideNSWindowContentView() {
setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[container_view_ setFrame:[[[window_ contentView] superview] bounds]];
[window_ setContentView:container_view_];
AddContentViewLayers();
AddContentViewLayers(IsMinimizable(), IsClosable());
}
void NativeWindowMac::SetStyleMask(bool on, NSUInteger flag) {

View File

@@ -358,6 +358,9 @@ void NativeWindowViews::Show() {
widget()->native_widget_private()->Show(GetRestoredState(), gfx::Rect());
// explicitly focus the window
widget()->Activate();
NotifyWindowShow();
#if defined(USE_X11)
@@ -734,10 +737,14 @@ void NativeWindowViews::SetAlwaysOnTop(bool top,
const std::string& level,
int relativeLevel,
std::string* error) {
if (top != widget()->IsAlwaysOnTop())
NativeWindow::NotifyWindowAlwaysOnTopChanged();
bool level_changed = top != widget()->IsAlwaysOnTop();
widget()->SetAlwaysOnTop(top);
// This must be notified at the very end or IsAlwaysOnTop
// will not yet have been updated to reflect the new status
if (level_changed)
NativeWindow::NotifyWindowAlwaysOnTopChanged();
}
bool NativeWindowViews::IsAlwaysOnTop() {

View File

@@ -51,6 +51,8 @@ network::mojom::HttpAuthDynamicParamsPtr CreateHttpAuthDynamicParams() {
command_line->GetSwitchValueASCII(atom::switches::kAuthServerWhitelist);
auth_dynamic_params->delegate_whitelist = command_line->GetSwitchValueASCII(
atom::switches::kAuthNegotiateDelegateWhitelist);
auth_dynamic_params->enable_negotiate_port =
command_line->HasSwitch(atom::switches::kEnableAuthNegotiatePort);
return auth_dynamic_params;
}

View File

@@ -38,6 +38,21 @@ void BeforeStartInUI(base::WeakPtr<URLRequestAsyncAsarJob> job,
error = net::ERR_NOT_IMPLEMENTED;
}
// sanitize custom headers
if (request_options && request_options->is_dict()) {
const base::Value* headersDict = request_options->FindKeyOfType(
"headers", base::Value::Type::DICTIONARY);
if (headersDict) {
for (const auto& iter : headersDict->DictItems()) {
if (!iter.second.is_string()) {
args->ThrowError("Value of '" + iter.first +
"' header has to be a string");
return;
}
}
}
}
base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(&URLRequestAsyncAsarJob::StartAsync, job,

View File

@@ -38,13 +38,13 @@ void NodeDebugger::Start() {
}
node::DebugOptions options;
node::options_parser::DebugOptionsParser options_parser;
std::vector<std::string> exec_args;
std::vector<std::string> v8_args;
std::vector<std::string> errors;
node::options_parser::DebugOptionsParser::instance.Parse(
&args, &exec_args, &v8_args, &options,
node::options_parser::kDisallowedInEnvironment, &errors);
options_parser.Parse(&args, &exec_args, &v8_args, &options,
node::options_parser::kDisallowedInEnvironment, &errors);
if (!errors.empty()) {
// TODO(jeremy): what's the appropriate behaviour here?
@@ -52,13 +52,6 @@ void NodeDebugger::Start() {
<< base::JoinString(errors, " ");
}
// Set process._debugWaitConnect if --inspect-brk was specified to stop
// the debugger on the first line
if (options.wait_for_connect()) {
mate::Dictionary process(env_->isolate(), env_->process_object());
process.Set("_breakFirstLine", true);
}
const char* path = "";
if (inspector->Start(path, options,
std::make_shared<node::HostPort>(options.host_port),
@@ -66,4 +59,10 @@ void NodeDebugger::Start() {
DCHECK(env_->inspector_agent()->IsListening());
}
void NodeDebugger::Stop() {
auto* inspector = env_->inspector_agent();
if (inspector && inspector->IsListening())
inspector->Stop();
}
} // namespace atom

View File

@@ -20,6 +20,7 @@ class NodeDebugger {
~NodeDebugger();
void Start();
void Stop();
private:
node::Environment* env_;

View File

@@ -109,6 +109,8 @@ void CocoaNotification::Dismiss() {
NotificationDismissed();
this->LogAction("dismissed");
notification_.reset(nil);
}
void CocoaNotification::NotificationDisplayed() {

View File

@@ -269,10 +269,16 @@ LRESULT DesktopNotificationController::Toast::WndProc(HWND hwnd,
case WM_MOUSEACTIVATE:
return MA_NOACTIVATE;
case WM_TIMER:
case WM_TIMER: {
if (wparam == TimerID_AutoDismiss) {
Get(hwnd)->AutoDismiss();
auto* inst = Get(hwnd);
Notification notification(inst->data_);
inst->data_->controller->OnNotificationDismissed(notification);
inst->AutoDismiss();
}
}
return 0;
case WM_LBUTTONDOWN: {

View File

@@ -47,8 +47,12 @@ void Win32Notification::Show(const NotificationOptions& options) {
if (existing) {
existing->tag_.clear();
this->notification_ref_ = std::move(existing->notification_ref_);
this->notification_ref_.Set(options.title, options.msg, image);
// Need to remove the entry in the notifications set that
// NotificationPresenter is holding
existing->Destroy();
} else {
this->notification_ref_ =
presenter->AddNotification(options.title, options.msg, image);

View File

@@ -0,0 +1,121 @@
// Copyright (c) 2019 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/osr/osr_host_display_client.h"
#include <utility>
#include "components/viz/common/resources/resource_format.h"
#include "components/viz/common/resources/resource_sizes.h"
#include "mojo/public/cpp/system/platform_handle.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/src/core/SkDevice.h"
#include "ui/gfx/skia_util.h"
#if defined(OS_WIN)
#include "skia/ext/skia_utils_win.h"
#endif
namespace atom {
LayeredWindowUpdater::LayeredWindowUpdater(
viz::mojom::LayeredWindowUpdaterRequest request,
OnPaintCallback callback)
: callback_(callback), binding_(this, std::move(request)) {}
LayeredWindowUpdater::~LayeredWindowUpdater() = default;
void LayeredWindowUpdater::SetActive(bool active) {
active_ = active;
}
void LayeredWindowUpdater::OnAllocatedSharedMemory(
const gfx::Size& pixel_size,
mojo::ScopedSharedBufferHandle scoped_buffer_handle) {
canvas_.reset();
// Make sure |pixel_size| is sane.
size_t expected_bytes;
bool size_result = viz::ResourceSizes::MaybeSizeInBytes(
pixel_size, viz::ResourceFormat::RGBA_8888, &expected_bytes);
if (!size_result)
return;
#if defined(WIN32)
base::SharedMemoryHandle shm_handle;
size_t required_bytes;
MojoResult unwrap_result = mojo::UnwrapSharedMemoryHandle(
std::move(scoped_buffer_handle), &shm_handle, &required_bytes, nullptr);
if (unwrap_result != MOJO_RESULT_OK)
return;
base::SharedMemory shm(shm_handle, false);
if (!shm.Map(required_bytes)) {
DLOG(ERROR) << "Failed to map " << required_bytes << " bytes";
return;
}
canvas_ = skia::CreatePlatformCanvasWithSharedSection(
pixel_size.width(), pixel_size.height(), false, shm.handle().GetHandle(),
skia::CRASH_ON_FAILURE);
#else
auto shm =
mojo::UnwrapWritableSharedMemoryRegion(std::move(scoped_buffer_handle));
if (!shm.IsValid()) {
DLOG(ERROR) << "Failed to unwrap shared memory region";
return;
}
shm_mapping_ = shm.Map();
if (!shm_mapping_.IsValid()) {
DLOG(ERROR) << "Failed to map shared memory region";
return;
}
canvas_ = skia::CreatePlatformCanvasWithPixels(
pixel_size.width(), pixel_size.height(), false,
static_cast<uint8_t*>(shm_mapping_.memory()), skia::CRASH_ON_FAILURE);
#endif
}
void LayeredWindowUpdater::Draw(const gfx::Rect& damage_rect,
DrawCallback draw_callback) {
SkPixmap pixmap;
SkBitmap bitmap;
if (active_ && canvas_->peekPixels(&pixmap)) {
bitmap.installPixels(pixmap);
callback_.Run(damage_rect, bitmap);
}
std::move(draw_callback).Run();
}
OffScreenHostDisplayClient::OffScreenHostDisplayClient(
gfx::AcceleratedWidget widget,
OnPaintCallback callback)
: viz::HostDisplayClient(widget), callback_(callback) {}
OffScreenHostDisplayClient::~OffScreenHostDisplayClient() {}
void OffScreenHostDisplayClient::SetActive(bool active) {
active_ = active;
if (layered_window_updater_) {
layered_window_updater_->SetActive(active_);
}
}
void OffScreenHostDisplayClient::IsOffscreen(IsOffscreenCallback callback) {
std::move(callback).Run(true);
}
void OffScreenHostDisplayClient::CreateLayeredWindowUpdater(
viz::mojom::LayeredWindowUpdaterRequest request) {
layered_window_updater_ =
std::make_unique<LayeredWindowUpdater>(std::move(request), callback_);
layered_window_updater_->SetActive(active_);
}
} // namespace atom

View File

@@ -0,0 +1,77 @@
// Copyright (c) 2019 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_OSR_OSR_HOST_DISPLAY_CLIENT_H_
#define ATOM_BROWSER_OSR_OSR_HOST_DISPLAY_CLIENT_H_
#include <memory>
#include "base/callback.h"
#include "base/memory/shared_memory.h"
#include "components/viz/host/host_display_client.h"
#include "services/viz/privileged/interfaces/compositing/layered_window_updater.mojom.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/gfx/native_widget_types.h"
namespace atom {
typedef base::Callback<void(const gfx::Rect&, const SkBitmap&)> OnPaintCallback;
class LayeredWindowUpdater : public viz::mojom::LayeredWindowUpdater {
public:
explicit LayeredWindowUpdater(viz::mojom::LayeredWindowUpdaterRequest request,
OnPaintCallback callback);
~LayeredWindowUpdater() override;
void SetActive(bool active);
// viz::mojom::LayeredWindowUpdater implementation.
void OnAllocatedSharedMemory(
const gfx::Size& pixel_size,
mojo::ScopedSharedBufferHandle scoped_buffer_handle) override;
void Draw(const gfx::Rect& damage_rect, DrawCallback draw_callback) override;
private:
OnPaintCallback callback_;
mojo::Binding<viz::mojom::LayeredWindowUpdater> binding_;
std::unique_ptr<SkCanvas> canvas_;
bool active_ = false;
#if !defined(WIN32)
base::WritableSharedMemoryMapping shm_mapping_;
#endif
DISALLOW_COPY_AND_ASSIGN(LayeredWindowUpdater);
};
class OffScreenHostDisplayClient : public viz::HostDisplayClient {
public:
explicit OffScreenHostDisplayClient(gfx::AcceleratedWidget widget,
OnPaintCallback callback);
~OffScreenHostDisplayClient() override;
void SetActive(bool active);
private:
void IsOffscreen(IsOffscreenCallback callback) override;
#if defined(OS_MACOSX)
void OnDisplayReceivedCALayerParams(
const gfx::CALayerParams& ca_layer_params) override;
#endif
void CreateLayeredWindowUpdater(
viz::mojom::LayeredWindowUpdaterRequest request) override;
std::unique_ptr<LayeredWindowUpdater> layered_window_updater_;
OnPaintCallback callback_;
bool active_ = false;
DISALLOW_COPY_AND_ASSIGN(OffScreenHostDisplayClient);
};
} // namespace atom
#endif // ATOM_BROWSER_OSR_OSR_HOST_DISPLAY_CLIENT_H_

View File

@@ -0,0 +1,35 @@
// Copyright (c) 2019 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/osr/osr_host_display_client.h"
#include <IOSurface/IOSurface.h>
namespace atom {
void OffScreenHostDisplayClient::OnDisplayReceivedCALayerParams(
const gfx::CALayerParams& ca_layer_params) {
if (!ca_layer_params.is_empty) {
base::ScopedCFTypeRef<IOSurfaceRef> io_surface(
IOSurfaceLookupFromMachPort(ca_layer_params.io_surface_mach_port));
gfx::Size pixel_size_ = ca_layer_params.pixel_size;
void* pixels = static_cast<void*>(IOSurfaceGetBaseAddress(io_surface));
size_t stride = IOSurfaceGetBytesPerRow(io_surface);
struct IOSurfacePinner {
base::ScopedCFTypeRef<IOSurfaceRef> io_surface;
};
SkBitmap bitmap;
bitmap.installPixels(
SkImageInfo::MakeN32(pixel_size_.width(), pixel_size_.height(),
kPremul_SkAlphaType),
pixels, stride);
bitmap.setImmutable();
callback_.Run(ca_layer_params.damage, bitmap);
}
}
} // namespace atom

View File

@@ -1,101 +0,0 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/osr/osr_output_device.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/src/core/SkDevice.h"
#include "ui/gfx/skia_util.h"
namespace atom {
OffScreenOutputDevice::OffScreenOutputDevice(bool transparent,
const OnPaintCallback& callback)
: transparent_(transparent), callback_(callback) {
DCHECK(!callback_.is_null());
}
OffScreenOutputDevice::~OffScreenOutputDevice() {}
void OffScreenOutputDevice::Resize(const gfx::Size& pixel_size,
float scale_factor) {
if (viewport_pixel_size_ == pixel_size)
return;
viewport_pixel_size_ = pixel_size;
canvas_.reset();
bitmap_.reset(new SkBitmap);
bitmap_->allocN32Pixels(viewport_pixel_size_.width(),
viewport_pixel_size_.height(), !transparent_);
if (bitmap_->drawsNothing()) {
NOTREACHED();
bitmap_.reset();
return;
}
if (transparent_) {
bitmap_->eraseColor(SK_ColorTRANSPARENT);
} else {
bitmap_->eraseColor(SK_ColorWHITE);
}
canvas_.reset(new SkCanvas(*bitmap_));
}
SkCanvas* OffScreenOutputDevice::BeginPaint(const gfx::Rect& damage_rect) {
DCHECK(canvas_.get());
DCHECK(bitmap_.get());
damage_rect_ = damage_rect;
SkIRect damage =
SkIRect::MakeXYWH(damage_rect_.x(), damage_rect_.y(),
damage_rect_.width(), damage_rect_.height());
if (transparent_) {
bitmap_->erase(SK_ColorTRANSPARENT, damage);
} else {
bitmap_->erase(SK_ColorWHITE, damage);
}
return canvas_.get();
}
void OffScreenOutputDevice::EndPaint() {
DCHECK(canvas_.get());
DCHECK(bitmap_.get());
if (!bitmap_.get())
return;
viz::SoftwareOutputDevice::EndPaint();
if (active_)
OnPaint(damage_rect_);
}
void OffScreenOutputDevice::SetActive(bool active, bool paint) {
if (active == active_)
return;
active_ = active;
if (!active_ && !pending_damage_rect_.IsEmpty() && paint)
OnPaint(gfx::Rect(viewport_pixel_size_));
}
void OffScreenOutputDevice::OnPaint(const gfx::Rect& damage_rect) {
gfx::Rect rect = damage_rect;
if (!pending_damage_rect_.IsEmpty()) {
rect.Union(pending_damage_rect_);
pending_damage_rect_.SetRect(0, 0, 0, 0);
}
rect.Intersect(gfx::Rect(viewport_pixel_size_));
if (rect.IsEmpty())
return;
callback_.Run(rect, *bitmap_);
}
} // namespace atom

View File

@@ -1,47 +0,0 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_OSR_OSR_OUTPUT_DEVICE_H_
#define ATOM_BROWSER_OSR_OSR_OUTPUT_DEVICE_H_
#include <memory>
#include "base/callback.h"
#include "components/viz/service/display/software_output_device.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
namespace atom {
typedef base::Callback<void(const gfx::Rect&, const SkBitmap&)> OnPaintCallback;
class OffScreenOutputDevice : public viz::SoftwareOutputDevice {
public:
OffScreenOutputDevice(bool transparent, const OnPaintCallback& callback);
~OffScreenOutputDevice() override;
// viz::SoftwareOutputDevice:
void Resize(const gfx::Size& pixel_size, float scale_factor) override;
SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override;
void EndPaint() override;
void SetActive(bool active, bool paint);
void OnPaint(const gfx::Rect& damage_rect);
private:
const bool transparent_;
OnPaintCallback callback_;
bool active_ = false;
std::unique_ptr<SkCanvas> canvas_;
std::unique_ptr<SkBitmap> bitmap_;
gfx::Rect pending_damage_rect_;
DISALLOW_COPY_AND_ASSIGN(OffScreenOutputDevice);
};
} // namespace atom
#endif // ATOM_BROWSER_OSR_OSR_OUTPUT_DEVICE_H_

View File

@@ -20,14 +20,15 @@
#include "components/viz/common/frame_sinks/delay_based_time_source.h"
#include "components/viz/common/gl_helper.h"
#include "components/viz/common/quads/render_pass.h"
#include "content/browser/renderer_host/cursor_manager.h"
#include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_owner_delegate.h"
#include "content/browser/renderer_host/cursor_manager.h" // nogncheck
#include "content/browser/renderer_host/input/synthetic_gesture_target.h" // nogncheck
#include "content/browser/renderer_host/render_widget_host_delegate.h" // nogncheck
#include "content/browser/renderer_host/render_widget_host_owner_delegate.h" // nogncheck
#include "content/common/view_messages.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/context_factory.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/render_process_host.h"
#include "media/base/video_frame.h"
#include "third_party/blink/public/platform/web_input_event.h"
@@ -50,7 +51,6 @@ namespace atom {
namespace {
const float kDefaultScaleFactor = 1.0;
const int kFrameRetryLimit = 2;
ui::MouseEvent UiMouseEventFromWebMouseEvent(blink::WebMouseEvent event) {
ui::EventType type = ui::EventType::ET_UNKNOWN;
@@ -120,105 +120,6 @@ ui::MouseWheelEvent UiMouseWheelEventFromWebMouseEvent(
} // namespace
class AtomCopyFrameGenerator {
public:
AtomCopyFrameGenerator(OffScreenRenderWidgetHostView* view,
int frame_rate_threshold_us)
: view_(view),
frame_duration_(
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us)),
weak_ptr_factory_(this) {
last_time_ = base::Time::Now();
}
void GenerateCopyFrame(const gfx::Rect& damage_rect) {
if (!view_->render_widget_host() || !view_->IsPainting())
return;
auto request = std::make_unique<viz::CopyOutputRequest>(
viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
base::BindOnce(
&AtomCopyFrameGenerator::CopyFromCompositingSurfaceHasResult,
weak_ptr_factory_.GetWeakPtr(), damage_rect));
request->set_area(gfx::Rect(view_->GetCompositorViewportPixelSize()));
view_->GetRootLayer()->RequestCopyOfOutput(std::move(request));
}
void set_frame_rate_threshold_us(int frame_rate_threshold_us) {
frame_duration_ =
base::TimeDelta::FromMicroseconds(frame_rate_threshold_us);
}
private:
void CopyFromCompositingSurfaceHasResult(
const gfx::Rect& damage_rect,
std::unique_ptr<viz::CopyOutputResult> result) {
if (result->IsEmpty() || result->size().IsEmpty() ||
!view_->render_widget_host()) {
OnCopyFrameCaptureFailure(damage_rect);
return;
}
DCHECK(!result->IsEmpty());
auto source = std::make_unique<SkBitmap>(result->AsSkBitmap());
DCHECK(source->readyToDraw());
if (source) {
base::AutoLock autolock(lock_);
std::shared_ptr<SkBitmap> bitmap(source.release());
base::TimeTicks now = base::TimeTicks::Now();
base::TimeDelta next_frame_in = next_frame_time_ - now;
if (next_frame_in > frame_duration_ / 4) {
next_frame_time_ += frame_duration_;
base::PostDelayedTaskWithTraits(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&AtomCopyFrameGenerator::OnCopyFrameCaptureSuccess,
weak_ptr_factory_.GetWeakPtr(), damage_rect, bitmap),
next_frame_in);
} else {
next_frame_time_ = now + frame_duration_;
OnCopyFrameCaptureSuccess(damage_rect, bitmap);
}
frame_retry_count_ = 0;
} else {
OnCopyFrameCaptureFailure(damage_rect);
}
}
void OnCopyFrameCaptureFailure(const gfx::Rect& damage_rect) {
const bool force_frame = (++frame_retry_count_ <= kFrameRetryLimit);
if (force_frame) {
// Retry with the same |damage_rect|.
base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&AtomCopyFrameGenerator::GenerateCopyFrame,
weak_ptr_factory_.GetWeakPtr(), damage_rect));
}
}
void OnCopyFrameCaptureSuccess(const gfx::Rect& damage_rect,
const std::shared_ptr<SkBitmap>& bitmap) {
base::AutoLock lock(onPaintLock_);
view_->OnPaint(damage_rect, *bitmap);
}
base::Lock lock_;
base::Lock onPaintLock_;
OffScreenRenderWidgetHostView* view_;
base::Time last_time_;
int frame_retry_count_ = 0;
base::TimeTicks next_frame_time_ = base::TimeTicks::Now();
base::TimeDelta frame_duration_;
base::WeakPtrFactory<AtomCopyFrameGenerator> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(AtomCopyFrameGenerator);
};
class AtomBeginFrameTimer : public viz::DelayBasedTimeSourceClient {
public:
AtomBeginFrameTimer(int frame_rate_threshold_us,
@@ -253,7 +154,6 @@ class AtomBeginFrameTimer : public viz::DelayBasedTimeSourceClient {
DISALLOW_COPY_AND_ASSIGN(AtomBeginFrameTimer);
};
#if !defined(OS_MACOSX)
class AtomDelegatedFrameHostClient : public content::DelegatedFrameHostClient {
public:
explicit AtomDelegatedFrameHostClient(OffScreenRenderWidgetHostView* view)
@@ -297,7 +197,6 @@ class AtomDelegatedFrameHostClient : public content::DelegatedFrameHostClient {
DISALLOW_COPY_AND_ASSIGN(AtomDelegatedFrameHostClient);
};
#endif // !defined(OS_MACOSX)
OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
bool transparent,
@@ -315,19 +214,23 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
frame_rate_(frame_rate),
size_(initial_size),
painting_(painting),
is_showing_(!render_widget_host_->is_hidden()),
is_showing_(false),
cursor_manager_(new content::CursorManager(this)),
mouse_wheel_phase_handler_(this),
backing_(new SkBitmap),
weak_ptr_factory_(this) {
DCHECK(render_widget_host_);
bool is_guest_view_hack = parent_host_view_ != nullptr;
current_device_scale_factor_ = kDefaultScaleFactor;
#if !defined(OS_MACOSX)
local_surface_id_allocator_.GenerateId();
local_surface_id_allocation_ =
local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation();
delegated_frame_host_allocator_.GenerateId();
delegated_frame_host_allocation_ =
delegated_frame_host_allocator_.GetCurrentLocalSurfaceIdAllocation();
compositor_allocator_.GenerateId();
compositor_allocation_ =
compositor_allocator_.GetCurrentLocalSurfaceIdAllocation();
delegated_frame_host_client_.reset(new AtomDelegatedFrameHostClient(this));
delegated_frame_host_ = std::make_unique<content::DelegatedFrameHost>(
AllocateFrameSinkId(is_guest_view_hack),
@@ -335,59 +238,49 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
true /* should_register_frame_sink_id */);
root_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR));
#endif
#if defined(OS_MACOSX)
last_frame_root_background_color_ = SK_ColorTRANSPARENT;
CreatePlatformWidget(is_guest_view_hack);
#endif
bool opaque = SkColorGetA(background_color_) == SK_AlphaOPAQUE;
GetRootLayer()->SetFillsBoundsOpaquely(opaque);
GetRootLayer()->SetColor(background_color_);
#if !defined(OS_MACOSX)
// On macOS the ui::Compositor is created/owned by the platform view.
content::ImageTransportFactory* factory =
content::ImageTransportFactory::GetInstance();
ui::ContextFactoryPrivate* context_factory_private =
factory->GetContextFactoryPrivate();
compositor_.reset(new ui::Compositor(
context_factory_private->AllocateFrameSinkId(),
content::GetContextFactory(), context_factory_private,
base::ThreadTaskRunnerHandle::Get(), false /* enable_pixel_canvas */));
compositor_.reset(
new ui::Compositor(context_factory_private->AllocateFrameSinkId(),
content::GetContextFactory(), context_factory_private,
base::ThreadTaskRunnerHandle::Get(),
false /* enable_pixel_canvas */, this));
compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
compositor_->SetRootLayer(root_layer_.get());
#endif
GetCompositor()->SetDelegate(this);
ResizeRootLayer(false);
render_widget_host_->SetView(this);
InstallTransparency();
if (content::GpuDataManager::GetInstance()->HardwareAccelerationEnabled()) {
video_consumer_.reset(new OffScreenVideoConsumer(
this, base::Bind(&OffScreenRenderWidgetHostView::OnPaint,
weak_ptr_factory_.GetWeakPtr())));
video_consumer_->SetActive(IsPainting());
video_consumer_->SetFrameRate(GetFrameRate());
}
}
OffScreenRenderWidgetHostView::~OffScreenRenderWidgetHostView() {
#if defined(OS_MACOSX)
if (is_showing_)
browser_compositor_->SetRenderWidgetHostIsHidden(true);
#else
// Marking the DelegatedFrameHost as removed from the window hierarchy is
// necessary to remove all connections to its old ui::Compositor.
if (is_showing_)
delegated_frame_host_->WasHidden();
delegated_frame_host_->DetachFromCompositor();
#endif
if (copy_frame_generator_.get())
copy_frame_generator_.reset(NULL);
#if defined(OS_MACOSX)
DestroyPlatformWidget();
#else
delegated_frame_host_.reset(NULL);
compositor_.reset(NULL);
root_layer_.reset(NULL);
#endif
}
content::BrowserAccessibilityManager*
@@ -422,8 +315,17 @@ void OffScreenRenderWidgetHostView::SendBeginFrame(
DCHECK(begin_frame_args.IsValid());
begin_frame_number_++;
if (renderer_compositor_frame_sink_)
renderer_compositor_frame_sink_->OnBeginFrame(begin_frame_args, {});
compositor_->context_factory_private()->IssueExternalBeginFrame(
compositor_.get(), begin_frame_args);
}
void OffScreenRenderWidgetHostView::OnDisplayDidFinishFrame(
const viz::BeginFrameAck& ack) {}
void OffScreenRenderWidgetHostView::OnNeedsExternalBeginFrames(
bool needs_begin_frames) {
SetupFrameRate(true);
begin_frame_timer_->SetActive(needs_begin_frames);
}
void OffScreenRenderWidgetHostView::InitAsChild(gfx::NativeView) {
@@ -437,7 +339,7 @@ void OffScreenRenderWidgetHostView::InitAsChild(gfx::NativeView) {
parent_host_view_->Hide();
ResizeRootLayer(false);
Show();
SetPainting(parent_host_view_->IsPainting());
}
void OffScreenRenderWidgetHostView::SetSize(const gfx::Size& size) {
@@ -478,14 +380,10 @@ void OffScreenRenderWidgetHostView::Show() {
is_showing_ = true;
#if defined(OS_MACOSX)
browser_compositor_->SetRenderWidgetHostIsHidden(false);
#else
delegated_frame_host_->AttachToCompositor(compositor_.get());
delegated_frame_host_->WasShown(
GetLocalSurfaceIdAllocation().local_surface_id(),
GetRootLayer()->bounds().size(), false);
#endif
if (render_widget_host_)
render_widget_host_->WasShown(false);
@@ -498,12 +396,8 @@ void OffScreenRenderWidgetHostView::Hide() {
if (render_widget_host_)
render_widget_host_->WasHidden();
#if defined(OS_MACOSX)
browser_compositor_->SetRenderWidgetHostIsHidden(true);
#else
GetDelegatedFrameHost()->WasHidden();
GetDelegatedFrameHost()->DetachFromCompositor();
#endif
is_showing_ = false;
}
@@ -576,67 +470,17 @@ void OffScreenRenderWidgetHostView::DidCreateNewRendererCompositorFrameSink(
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink) {
renderer_compositor_frame_sink_ = renderer_compositor_frame_sink;
#if defined(OS_MACOSX)
browser_compositor_->DidCreateNewRendererCompositorFrameSink(
renderer_compositor_frame_sink_);
#else
if (GetDelegatedFrameHost()) {
GetDelegatedFrameHost()->DidCreateNewRendererCompositorFrameSink(
renderer_compositor_frame_sink_);
}
#endif
}
void OffScreenRenderWidgetHostView::SubmitCompositorFrame(
const viz::LocalSurfaceId& local_surface_id,
viz::CompositorFrame frame,
base::Optional<viz::HitTestRegionList> hit_test_region_list) {
#if defined(OS_MACOSX)
last_frame_root_background_color_ = frame.metadata.root_background_color;
#endif
if (frame.metadata.root_scroll_offset != last_scroll_offset_) {
last_scroll_offset_ = frame.metadata.root_scroll_offset;
}
if (!frame.render_pass_list.empty()) {
if (software_output_device_) {
if (!begin_frame_timer_.get() || IsPopupWidget()) {
software_output_device_->SetActive(painting_, false);
}
// The compositor will draw directly to the SoftwareOutputDevice which
// then calls OnPaint.
// We would normally call BrowserCompositorMac::SubmitCompositorFrame on
// macOS, however it contains compositor resize logic that we don't want.
// Consequently we instead call the SubmitCompositorFrame method directly.
GetDelegatedFrameHost()->SubmitCompositorFrame(
local_surface_id, std::move(frame), std::move(hit_test_region_list));
} else {
if (!copy_frame_generator_.get()) {
copy_frame_generator_.reset(
new AtomCopyFrameGenerator(this, frame_rate_threshold_us_));
}
// Determine the damage rectangle for the current frame. This is the same
// calculation that SwapDelegatedFrame uses.
viz::RenderPass* root_pass = frame.render_pass_list.back().get();
gfx::Size frame_size = root_pass->output_rect.size();
gfx::Rect damage_rect =
gfx::ToEnclosingRect(gfx::RectF(root_pass->damage_rect));
damage_rect.Intersect(gfx::Rect(frame_size));
// We would normally call BrowserCompositorMac::SubmitCompositorFrame on
// macOS, however it contains compositor resize logic that we don't want.
// Consequently we instead call the SubmitCompositorFrame method directly.
GetDelegatedFrameHost()->SubmitCompositorFrame(
local_surface_id, std::move(frame), std::move(hit_test_region_list));
// Request a copy of the last compositor frame which will eventually call
// OnPaint asynchronously.
copy_frame_generator_->GenerateCopyFrame(damage_rect);
}
}
NOTREACHED();
}
void OffScreenRenderWidgetHostView::ClearCompositorFrame() {
@@ -651,13 +495,13 @@ void OffScreenRenderWidgetHostView::InitAsPopup(
content::RenderWidgetHostView* parent_host_view,
const gfx::Rect& pos) {
DCHECK_EQ(parent_host_view_, parent_host_view);
DCHECK_EQ(widget_type_, content::WidgetType::kPopup);
if (parent_host_view_->popup_host_view_) {
parent_host_view_->popup_host_view_->CancelWidget();
}
parent_host_view_->set_popup_host_view(this);
parent_host_view_->popup_bitmap_.reset(new SkBitmap);
parent_callback_ =
base::Bind(&OffScreenRenderWidgetHostView::OnPopupPaint,
parent_host_view_->weak_ptr_factory_.GetWeakPtr());
@@ -665,6 +509,10 @@ void OffScreenRenderWidgetHostView::InitAsPopup(
popup_position_ = pos;
ResizeRootLayer(false);
SetPainting(parent_host_view_->IsPainting());
if (video_consumer_) {
video_consumer_->SizeChanged();
}
Show();
}
@@ -698,7 +546,6 @@ void OffScreenRenderWidgetHostView::Destroy() {
} else {
if (popup_host_view_)
popup_host_view_->CancelWidget();
popup_bitmap_.reset();
if (child_host_view_)
child_host_view_->CancelWidget();
if (!guest_host_views_.empty()) {
@@ -748,6 +595,7 @@ void OffScreenRenderWidgetHostView::InitAsGuest(
content::RenderWidgetHostView* parent_host_view,
content::RenderWidgetHostViewGuest* guest_view) {
parent_host_view_->AddGuestHostView(this);
SetPainting(parent_host_view_->IsPainting());
}
void OffScreenRenderWidgetHostView::TransformPointToRootSurface(
@@ -763,6 +611,12 @@ viz::SurfaceId OffScreenRenderWidgetHostView::GetCurrentSurfaceId() const {
: viz::SurfaceId();
}
std::unique_ptr<content::SyntheticGestureTarget>
OffScreenRenderWidgetHostView::CreateSyntheticGestureTarget() {
NOTIMPLEMENTED();
return nullptr;
}
void OffScreenRenderWidgetHostView::ImeCompositionRangeChanged(
const gfx::Range&,
const std::vector<gfx::Rect>&) {}
@@ -800,12 +654,8 @@ const viz::FrameSinkId& OffScreenRenderWidgetHostView::GetFrameSinkId() const {
void OffScreenRenderWidgetHostView::DidNavigate() {
ResizeRootLayer(true);
#if defined(OS_MACOSX)
browser_compositor_->DidNavigate();
#else
if (delegated_frame_host_)
delegated_frame_host_->DidNavigate();
#endif
}
bool OffScreenRenderWidgetHostView::TransformPointToLocalCoordSpaceLegacy(
@@ -847,7 +697,6 @@ void OffScreenRenderWidgetHostView::CancelWidget() {
if (parent_host_view_) {
if (parent_host_view_->popup_host_view_ == this) {
parent_host_view_->set_popup_host_view(NULL);
parent_host_view_->popup_bitmap_.reset();
} else if (parent_host_view_->child_host_view_ == this) {
parent_host_view_->set_child_host_view(NULL);
parent_host_view_->Show();
@@ -890,29 +739,21 @@ void OffScreenRenderWidgetHostView::ProxyViewDestroyed(
Invalidate();
}
std::unique_ptr<viz::SoftwareOutputDevice>
OffScreenRenderWidgetHostView::CreateSoftwareOutputDevice(
std::unique_ptr<viz::HostDisplayClient>
OffScreenRenderWidgetHostView::CreateHostDisplayClient(
ui::Compositor* compositor) {
DCHECK_EQ(GetCompositor(), compositor);
DCHECK(!copy_frame_generator_);
DCHECK(!software_output_device_);
ResizeRootLayer(false);
software_output_device_ = new OffScreenOutputDevice(
transparent_, base::Bind(&OffScreenRenderWidgetHostView::OnPaint,
weak_ptr_factory_.GetWeakPtr()));
return base::WrapUnique(software_output_device_);
host_display_client_ = new OffScreenHostDisplayClient(
gfx::kNullAcceleratedWidget,
base::Bind(&OffScreenRenderWidgetHostView::OnPaint,
weak_ptr_factory_.GetWeakPtr()));
host_display_client_->SetActive(IsPainting());
return base::WrapUnique(host_display_client_);
}
bool OffScreenRenderWidgetHostView::InstallTransparency() {
if (transparent_) {
SetBackgroundColor(SkColor());
#if defined(OS_MACOSX)
browser_compositor_->SetBackgroundColor(SK_ColorTRANSPARENT);
#else
compositor_->SetBackgroundColor(SK_ColorTRANSPARENT);
#endif
return true;
}
return false;
@@ -921,76 +762,99 @@ bool OffScreenRenderWidgetHostView::InstallTransparency() {
void OffScreenRenderWidgetHostView::SetNeedsBeginFrames(
bool needs_begin_frames) {
SetupFrameRate(true);
begin_frame_timer_->SetActive(needs_begin_frames);
if (software_output_device_) {
software_output_device_->SetActive(painting_, false);
}
}
void OffScreenRenderWidgetHostView::SetWantsAnimateOnlyBeginFrames() {
if (GetDelegatedFrameHost()) {
GetDelegatedFrameHost()->SetWantsAnimateOnlyBeginFrames();
}
void OffScreenRenderWidgetHostView::SetWantsAnimateOnlyBeginFrames() {}
#if defined(OS_MACOSX)
void OffScreenRenderWidgetHostView::SetActive(bool active) {}
void OffScreenRenderWidgetHostView::ShowDefinitionForSelection() {}
void OffScreenRenderWidgetHostView::SpeakSelection() {}
bool OffScreenRenderWidgetHostView::UpdateNSViewAndDisplay() {
return false;
}
#endif
void OffScreenRenderWidgetHostView::OnPaint(const gfx::Rect& damage_rect,
const SkBitmap& bitmap) {
backing_.reset(new SkBitmap());
backing_->allocN32Pixels(bitmap.width(), bitmap.height(), !transparent_);
bitmap.readPixels(backing_->pixmap());
if (IsPopupWidget() && parent_callback_) {
parent_callback_.Run(this->popup_position_);
} else {
CompositeFrame(damage_rect);
}
}
gfx::Size OffScreenRenderWidgetHostView::SizeInPixels() {
if (IsPopupWidget()) {
return gfx::ConvertSizeToPixel(current_device_scale_factor_,
popup_position_.size());
} else {
return gfx::ConvertSizeToPixel(current_device_scale_factor_,
GetViewBounds().size());
}
}
void OffScreenRenderWidgetHostView::CompositeFrame(
const gfx::Rect& damage_rect) {
HoldResize();
if (parent_callback_) {
parent_callback_.Run(damage_rect, bitmap);
gfx::Size size_in_pixels = SizeInPixels();
SkBitmap frame;
// Optimize for the case when there is no popup
if (proxy_views_.size() == 0 && !popup_host_view_) {
frame = GetBacking();
} else {
gfx::Rect damage(damage_rect);
frame.allocN32Pixels(size_in_pixels.width(), size_in_pixels.height(),
false);
if (!GetBacking().drawsNothing()) {
SkCanvas canvas(frame);
canvas.writePixels(GetBacking(), 0, 0);
gfx::Size size_in_pixels = gfx::ConvertSizeToPixel(
current_device_scale_factor_, GetViewBounds().size());
if (popup_host_view_ && !popup_host_view_->GetBacking().drawsNothing()) {
gfx::Rect rect = popup_host_view_->popup_position_;
gfx::Point origin_in_pixels = gfx::ConvertPointToPixel(
current_device_scale_factor_, rect.origin());
canvas.writePixels(popup_host_view_->GetBacking(), origin_in_pixels.x(),
origin_in_pixels.y());
}
SkBitmap backing;
backing.allocN32Pixels(size_in_pixels.width(), size_in_pixels.height(),
false);
SkCanvas canvas(backing);
canvas.writePixels(bitmap, 0, 0);
if (popup_host_view_ && popup_bitmap_.get()) {
gfx::Rect rect = popup_host_view_->popup_position_;
gfx::Point origin_in_pixels =
gfx::ConvertPointToPixel(current_device_scale_factor_, rect.origin());
damage.Union(rect);
canvas.writePixels(*popup_bitmap_.get(), origin_in_pixels.x(),
origin_in_pixels.y());
for (auto* proxy_view : proxy_views_) {
gfx::Rect rect = proxy_view->GetBounds();
gfx::Point origin_in_pixels = gfx::ConvertPointToPixel(
current_device_scale_factor_, rect.origin());
canvas.writePixels(*proxy_view->GetBitmap(), origin_in_pixels.x(),
origin_in_pixels.y());
}
}
for (auto* proxy_view : proxy_views_) {
gfx::Rect rect = proxy_view->GetBounds();
gfx::Point origin_in_pixels =
gfx::ConvertPointToPixel(current_device_scale_factor_, rect.origin());
damage.Union(rect);
canvas.writePixels(*proxy_view->GetBitmap(), origin_in_pixels.x(),
origin_in_pixels.y());
}
damage.Intersect(GetViewBounds());
paint_callback_running_ = true;
callback_.Run(damage, backing);
paint_callback_running_ = false;
}
paint_callback_running_ = true;
callback_.Run(gfx::IntersectRects(gfx::Rect(size_in_pixels), damage_rect),
frame);
paint_callback_running_ = false;
ReleaseResize();
}
void OffScreenRenderWidgetHostView::OnPopupPaint(const gfx::Rect& damage_rect,
const SkBitmap& bitmap) {
if (popup_host_view_ && popup_bitmap_.get())
popup_bitmap_.reset(new SkBitmap(bitmap));
InvalidateBounds(popup_host_view_->popup_position_);
void OffScreenRenderWidgetHostView::OnPopupPaint(const gfx::Rect& damage_rect) {
InvalidateBounds(
gfx::ConvertRectToPixel(current_device_scale_factor_, damage_rect));
}
void OffScreenRenderWidgetHostView::OnProxyViewPaint(
const gfx::Rect& damage_rect) {
InvalidateBounds(damage_rect);
InvalidateBounds(
gfx::ConvertRectToPixel(current_device_scale_factor_, damage_rect));
}
void OffScreenRenderWidgetHostView::HoldResize() {
@@ -1020,7 +884,7 @@ void OffScreenRenderWidgetHostView::SynchronizeVisualProperties() {
return;
}
ResizeRootLayer(false);
ResizeRootLayer(true);
}
void OffScreenRenderWidgetHostView::SendMouseEvent(
@@ -1147,8 +1011,17 @@ void OffScreenRenderWidgetHostView::SendMouseWheelEvent(
void OffScreenRenderWidgetHostView::SetPainting(bool painting) {
painting_ = painting;
if (software_output_device_) {
software_output_device_->SetActive(painting_, !paint_callback_running_);
if (popup_host_view_) {
popup_host_view_->SetPainting(painting);
}
for (auto* guest_host_view : guest_host_views_)
guest_host_view->SetPainting(painting);
if (video_consumer_) {
video_consumer_->SetActive(IsPainting());
} else if (host_display_client_) {
host_display_client_->SetActive(IsPainting());
}
}
@@ -1173,6 +1046,10 @@ void OffScreenRenderWidgetHostView::SetFrameRate(int frame_rate) {
SetupFrameRate(true);
if (video_consumer_) {
video_consumer_->SetFrameRate(GetFrameRate());
}
for (auto* guest_host_view : guest_host_views_)
guest_host_view->SetFrameRate(frame_rate);
}
@@ -1181,7 +1058,6 @@ int OffScreenRenderWidgetHostView::GetFrameRate() const {
return frame_rate_;
}
#if !defined(OS_MACOSX)
ui::Compositor* OffScreenRenderWidgetHostView::GetCompositor() const {
return compositor_.get();
}
@@ -1190,18 +1066,15 @@ ui::Layer* OffScreenRenderWidgetHostView::GetRootLayer() const {
return root_layer_.get();
}
#if !defined(OS_MACOSX)
const viz::LocalSurfaceIdAllocation&
OffScreenRenderWidgetHostView::GetLocalSurfaceIdAllocation() const {
return local_surface_id_allocation_;
return delegated_frame_host_allocation_;
}
#endif // defined(OS_MACOSX)
content::DelegatedFrameHost*
OffScreenRenderWidgetHostView::GetDelegatedFrameHost() const {
return delegated_frame_host_.get();
}
#endif
void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
if (!force && frame_rate_threshold_us_ != 0)
@@ -1209,11 +1082,6 @@ void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
frame_rate_threshold_us_ = 1000000 / frame_rate_;
if (copy_frame_generator_.get()) {
copy_frame_generator_->set_frame_rate_threshold_us(
frame_rate_threshold_us_);
}
if (begin_frame_timer_.get()) {
begin_frame_timer_->SetFrameRateThresholdUs(frame_rate_threshold_us_);
} else {
@@ -1225,15 +1093,11 @@ void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
}
void OffScreenRenderWidgetHostView::Invalidate() {
InvalidateBounds(GetViewBounds());
InvalidateBounds(gfx::Rect(GetRequestedRendererSize()));
}
void OffScreenRenderWidgetHostView::InvalidateBounds(const gfx::Rect& bounds) {
if (software_output_device_) {
software_output_device_->OnPaint(bounds);
} else if (copy_frame_generator_) {
copy_frame_generator_->GenerateCopyFrame(bounds);
}
CompositeFrame(bounds);
}
void OffScreenRenderWidgetHostView::ResizeRootLayer(bool force) {
@@ -1259,23 +1123,24 @@ void OffScreenRenderWidgetHostView::ResizeRootLayer(bool force) {
GetRootLayer()->SetBounds(gfx::Rect(size));
#if defined(OS_MACOSX)
bool resized = UpdateNSViewAndDisplay();
#else
const gfx::Size& size_in_pixels =
gfx::ConvertSizeToPixel(current_device_scale_factor_, size);
local_surface_id_allocator_.GenerateId();
local_surface_id_allocation_ =
local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation();
compositor_allocator_.GenerateId();
compositor_allocation_ =
compositor_allocator_.GetCurrentLocalSurfaceIdAllocation();
GetCompositor()->SetScaleAndSize(current_device_scale_factor_, size_in_pixels,
local_surface_id_allocation_);
compositor_allocation_);
delegated_frame_host_allocator_.GenerateId();
delegated_frame_host_allocation_ =
delegated_frame_host_allocator_.GetCurrentLocalSurfaceIdAllocation();
bool resized = true;
GetDelegatedFrameHost()->EmbedSurface(
local_surface_id_allocation_.local_surface_id(), size,
delegated_frame_host_allocation_.local_surface_id(), size,
cc::DeadlinePolicy::UseDefaultDeadline());
#endif
// Note that |render_widget_host_| will retrieve resize parameters from the
// DelegatedFrameHost, so it must have SynchronizeVisualProperties called

View File

@@ -14,7 +14,8 @@
#include <windows.h>
#endif
#include "atom/browser/osr/osr_output_device.h"
#include "atom/browser/osr/osr_host_display_client.h"
#include "atom/browser/osr/osr_video_consumer.h"
#include "atom/browser/osr/osr_view_proxy.h"
#include "base/process/kill.h"
#include "base/threading/thread.h"
@@ -23,12 +24,12 @@
#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "content/browser/frame_host/render_widget_host_view_guest.h"
#include "content/browser/renderer_host/delegated_frame_host.h"
#include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/web_contents/web_contents_view.h"
#include "content/browser/frame_host/render_widget_host_view_guest.h" // nogncheck
#include "content/browser/renderer_host/delegated_frame_host.h" // nogncheck
#include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h" // nogncheck
#include "content/browser/renderer_host/render_widget_host_impl.h" // nogncheck
#include "content/browser/renderer_host/render_widget_host_view_base.h" // nogncheck
#include "content/browser/web_contents/web_contents_view.h" // nogncheck
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/ime/text_input_client.h"
@@ -37,24 +38,13 @@
#include "ui/compositor/layer_owner.h"
#include "ui/gfx/geometry/point.h"
#include "components/viz/host/host_display_client.h"
#include "ui/compositor/external_begin_frame_client.h"
#if defined(OS_WIN)
#include "ui/gfx/win/window_impl.h"
#endif
#if defined(OS_MACOSX)
#include "content/browser/renderer_host/browser_compositor_view_mac.h"
#endif
#if defined(OS_MACOSX)
#ifdef __OBJC__
@class CALayer;
@class NSWindow;
#else
class CALayer;
class NSWindow;
#endif
#endif
namespace content {
class CursorManager;
} // namespace content
@@ -64,13 +54,13 @@ namespace atom {
class AtomCopyFrameGenerator;
class AtomBeginFrameTimer;
#if defined(OS_MACOSX)
class MacHelper;
#else
class AtomDelegatedFrameHostClient;
#endif
typedef base::Callback<void(const gfx::Rect&, const SkBitmap&)> OnPaintCallback;
typedef base::Callback<void(const gfx::Rect&)> OnPopupPaintCallback;
class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
public ui::ExternalBeginFrameClient,
public ui::CompositorDelegate,
public OffscreenViewProxyObserver {
public:
@@ -87,6 +77,9 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
content::BrowserAccessibilityDelegate*,
bool) override;
void OnDisplayDidFinishFrame(const viz::BeginFrameAck& ack) override;
void OnNeedsExternalBeginFrames(bool needs_begin_frames) override;
// content::RenderWidgetHostView:
void InitAsChild(gfx::NativeView) override;
void SetSize(const gfx::Size&) override;
@@ -152,15 +145,12 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
void TransformPointToRootSurface(gfx::PointF* point) override;
gfx::Rect GetBoundsInRootWindow(void) override;
viz::SurfaceId GetCurrentSurfaceId() const override;
std::unique_ptr<content::SyntheticGestureTarget>
CreateSyntheticGestureTarget() override;
void ImeCompositionRangeChanged(const gfx::Range&,
const std::vector<gfx::Rect>&) override;
gfx::Size GetCompositorViewportPixelSize() const override;
#if defined(OS_MACOSX)
viz::ScopedSurfaceIdAllocator DidUpdateVisualProperties(
const cc::RenderFrameMetadata& metadata) override;
#endif
content::RenderWidgetHostViewBase* CreateViewForWidget(
content::RenderWidgetHost*,
content::RenderWidgetHost*,
@@ -183,7 +173,7 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
viz::EventSource source = viz::EventSource::ANY) override;
// ui::CompositorDelegate:
std::unique_ptr<viz::SoftwareOutputDevice> CreateSoftwareOutputDevice(
std::unique_ptr<viz::HostDisplayClient> CreateHostDisplayClient(
ui::Compositor* compositor) override;
bool InstallTransparency();
@@ -191,14 +181,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
void OnBeginFrameTimerTick();
void SendBeginFrame(base::TimeTicks frame_time, base::TimeDelta vsync_period);
#if defined(OS_MACOSX)
void CreatePlatformWidget(bool is_guest_view_hack);
void DestroyPlatformWidget();
SkColor last_frame_root_background_color() const {
return last_frame_root_background_color_;
}
#endif
void CancelWidget();
void AddGuestHostView(OffScreenRenderWidgetHostView* guest_host);
void RemoveGuestHostView(OffScreenRenderWidgetHostView* guest_host);
@@ -207,13 +189,19 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
void ProxyViewDestroyed(OffscreenViewProxy* proxy) override;
void OnPaint(const gfx::Rect& damage_rect, const SkBitmap& bitmap);
void OnPopupPaint(const gfx::Rect& damage_rect, const SkBitmap& bitmap);
void OnPopupPaint(const gfx::Rect& damage_rect);
void OnProxyViewPaint(const gfx::Rect& damage_rect) override;
gfx::Size SizeInPixels();
void CompositeFrame(const gfx::Rect& damage_rect);
bool IsPopupWidget() const {
return widget_type_ == content::WidgetType::kPopup;
}
const SkBitmap& GetBacking() { return *backing_.get(); }
void HoldResize();
void ReleaseResize();
void SynchronizeVisualProperties();
@@ -230,12 +218,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
ui::Compositor* GetCompositor() const;
ui::Layer* GetRootLayer() const;
#if defined(OS_MACOSX)
content::BrowserCompositorMac* browser_compositor() const {
return browser_compositor_.get();
}
#endif
content::DelegatedFrameHost* GetDelegatedFrameHost() const;
void Invalidate();
@@ -256,12 +238,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
}
private:
#if defined(OS_MACOSX)
display::Display GetDisplay();
void OnDidUpdateVisualPropertiesComplete(
const cc::RenderFrameMetadata& metadata);
#endif
void SetupFrameRate(bool force);
void ResizeRootLayer(bool force);
@@ -276,16 +252,13 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
OffScreenRenderWidgetHostView* parent_host_view_ = nullptr;
OffScreenRenderWidgetHostView* popup_host_view_ = nullptr;
std::unique_ptr<SkBitmap> popup_bitmap_;
OffScreenRenderWidgetHostView* child_host_view_ = nullptr;
std::set<OffScreenRenderWidgetHostView*> guest_host_views_;
std::set<OffscreenViewProxy*> proxy_views_;
OffScreenOutputDevice* software_output_device_ = nullptr;
const bool transparent_;
OnPaintCallback callback_;
OnPaintCallback parent_callback_;
OnPopupPaintCallback parent_callback_;
int frame_rate_ = 0;
int frame_rate_threshold_us_ = 0;
@@ -305,8 +278,11 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
bool paint_callback_running_ = false;
viz::LocalSurfaceIdAllocation local_surface_id_allocation_;
viz::ParentLocalSurfaceIdAllocator local_surface_id_allocator_;
viz::LocalSurfaceIdAllocation delegated_frame_host_allocation_;
viz::ParentLocalSurfaceIdAllocator delegated_frame_host_allocator_;
viz::LocalSurfaceIdAllocation compositor_allocation_;
viz::ParentLocalSurfaceIdAllocator compositor_allocator_;
std::unique_ptr<ui::Layer> root_layer_;
std::unique_ptr<ui::Compositor> compositor_;
@@ -314,27 +290,15 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
std::unique_ptr<content::CursorManager> cursor_manager_;
std::unique_ptr<AtomCopyFrameGenerator> copy_frame_generator_;
std::unique_ptr<AtomBeginFrameTimer> begin_frame_timer_;
OffScreenHostDisplayClient* host_display_client_;
std::unique_ptr<OffScreenVideoConsumer> video_consumer_;
// Provides |source_id| for BeginFrameArgs that we create.
viz::StubBeginFrameSource begin_frame_source_;
uint64_t begin_frame_number_ = viz::BeginFrameArgs::kStartingFrameNumber;
#if defined(OS_MACOSX)
std::unique_ptr<content::BrowserCompositorMac> browser_compositor_;
SkColor last_frame_root_background_color_;
// Can not be managed by smart pointer because its header can not be included
// in the file that has the destructor.
MacHelper* mac_helper_;
// Selected text on the renderer.
std::string selected_text_;
#else
std::unique_ptr<AtomDelegatedFrameHostClient> delegated_frame_host_client_;
#endif
content::MouseWheelPhaseHandler mouse_wheel_phase_handler_;
@@ -348,6 +312,8 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
SkColor background_color_ = SkColor();
std::unique_ptr<SkBitmap> backing_;
base::WeakPtrFactory<OffScreenRenderWidgetHostView> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(OffScreenRenderWidgetHostView);

View File

@@ -1,150 +0,0 @@
// Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/osr/osr_render_widget_host_view.h"
#import <Cocoa/Cocoa.h>
#include "base/strings/utf_string_conversions.h"
#include "content/common/view_messages.h"
#include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
#include "ui/display/screen.h"
#include "components/viz/common/features.h"
namespace atom {
class MacHelper : public content::BrowserCompositorMacClient,
public ui::AcceleratedWidgetMacNSView {
public:
explicit MacHelper(OffScreenRenderWidgetHostView* view) : view_(view) {
[view_->GetNativeView().GetNativeNSView() setWantsLayer:YES];
}
virtual ~MacHelper() {}
// content::BrowserCompositorMacClient:
SkColor BrowserCompositorMacGetGutterColor() const override {
// When making an element on the page fullscreen the element's background
// may not match the page's, so use black as the gutter color to avoid
// flashes of brighter colors during the transition.
if (view_->render_widget_host()->delegate() &&
view_->render_widget_host()->delegate()->IsFullscreenForCurrentTab()) {
return SK_ColorBLACK;
}
return view_->last_frame_root_background_color();
}
void BrowserCompositorMacOnBeginFrame(base::TimeTicks frame_time) override {}
void OnFrameTokenChanged(uint32_t frame_token) override {
view_->render_widget_host()->DidProcessFrame(frame_token);
}
void AcceleratedWidgetCALayerParamsUpdated() override {}
void DestroyCompositorForShutdown() override {}
bool OnBrowserCompositorSurfaceIdChanged() override {
return view_->render_widget_host()->SynchronizeVisualProperties();
}
std::vector<viz::SurfaceId> CollectSurfaceIdsForEviction() override {
return view_->render_widget_host()->CollectSurfaceIdsForEviction();
}
private:
OffScreenRenderWidgetHostView* view_;
DISALLOW_COPY_AND_ASSIGN(MacHelper);
};
void OffScreenRenderWidgetHostView::SetActive(bool active) {}
void OffScreenRenderWidgetHostView::ShowDefinitionForSelection() {}
void OffScreenRenderWidgetHostView::SpeakSelection() {}
bool OffScreenRenderWidgetHostView::UpdateNSViewAndDisplay() {
return browser_compositor_->UpdateSurfaceFromNSView(
GetRootLayer()->bounds().size(), GetDisplay());
}
void OffScreenRenderWidgetHostView::CreatePlatformWidget(
bool is_guest_view_hack) {
mac_helper_ = new MacHelper(this);
browser_compositor_.reset(new content::BrowserCompositorMac(
mac_helper_, mac_helper_, render_widget_host_->is_hidden(), GetDisplay(),
AllocateFrameSinkId(is_guest_view_hack)));
if (!base::FeatureList::IsEnabled(features::kVizDisplayCompositor)) {
SetNeedsBeginFrames(true);
}
}
void OffScreenRenderWidgetHostView::DestroyPlatformWidget() {
browser_compositor_.reset();
delete mac_helper_;
}
viz::ScopedSurfaceIdAllocator
OffScreenRenderWidgetHostView::DidUpdateVisualProperties(
const cc::RenderFrameMetadata& metadata) {
base::OnceCallback<void()> allocation_task = base::BindOnce(
base::IgnoreResult(
&OffScreenRenderWidgetHostView::OnDidUpdateVisualPropertiesComplete),
weak_ptr_factory_.GetWeakPtr(), metadata);
return browser_compositor_->GetScopedRendererSurfaceIdAllocator(
std::move(allocation_task));
}
display::Display OffScreenRenderWidgetHostView::GetDisplay() {
content::ScreenInfo screen_info;
GetScreenInfo(&screen_info);
// Start with a reasonable display representation.
display::Display display =
display::Screen::GetScreen()->GetDisplayNearestView(nullptr);
// Populate attributes based on |screen_info|.
display.set_bounds(screen_info.rect);
display.set_work_area(screen_info.available_rect);
display.set_device_scale_factor(screen_info.device_scale_factor);
display.set_color_space(screen_info.color_space);
display.set_color_depth(screen_info.depth);
display.set_depth_per_component(screen_info.depth_per_component);
display.set_is_monochrome(screen_info.is_monochrome);
display.SetRotationAsDegree(screen_info.orientation_angle);
return display;
}
void OffScreenRenderWidgetHostView::OnDidUpdateVisualPropertiesComplete(
const cc::RenderFrameMetadata& metadata) {
DCHECK_EQ(current_device_scale_factor_, metadata.device_scale_factor);
browser_compositor_->UpdateSurfaceFromChild(
metadata.device_scale_factor, metadata.viewport_size_in_pixels,
metadata.local_surface_id_allocation.value_or(
viz::LocalSurfaceIdAllocation()));
}
const viz::LocalSurfaceIdAllocation&
OffScreenRenderWidgetHostView::GetLocalSurfaceIdAllocation() const {
return browser_compositor_->GetRendererLocalSurfaceIdAllocation();
}
ui::Compositor* OffScreenRenderWidgetHostView::GetCompositor() const {
return browser_compositor_->GetCompositor();
}
ui::Layer* OffScreenRenderWidgetHostView::GetRootLayer() const {
return browser_compositor_->GetRootLayer();
}
content::DelegatedFrameHost*
OffScreenRenderWidgetHostView::GetDelegatedFrameHost() const {
return browser_compositor_->GetDelegatedFrameHost();
}
} // namespace atom

View File

@@ -0,0 +1,132 @@
// Copyright (c) 2019 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/osr/osr_video_consumer.h"
#include <utility>
#include "atom/browser/osr/osr_render_widget_host_view.h"
#include "media/base/video_frame_metadata.h"
#include "media/capture/mojom/video_capture_types.mojom.h"
#include "ui/gfx/skbitmap_operations.h"
namespace atom {
OffScreenVideoConsumer::OffScreenVideoConsumer(
OffScreenRenderWidgetHostView* view,
OnPaintCallback callback)
: callback_(callback),
view_(view),
video_capturer_(view->CreateVideoCapturer()),
weak_ptr_factory_(this) {
video_capturer_->SetResolutionConstraints(view_->SizeInPixels(),
view_->SizeInPixels(), true);
video_capturer_->SetAutoThrottlingEnabled(false);
video_capturer_->SetMinSizeChangePeriod(base::TimeDelta());
video_capturer_->SetFormat(media::PIXEL_FORMAT_ARGB,
gfx::ColorSpace::CreateREC709());
SetFrameRate(view_->GetFrameRate());
}
OffScreenVideoConsumer::~OffScreenVideoConsumer() = default;
void OffScreenVideoConsumer::SetActive(bool active) {
if (active) {
video_capturer_->Start(this);
} else {
video_capturer_->Stop();
}
}
void OffScreenVideoConsumer::SetFrameRate(int frame_rate) {
video_capturer_->SetMinCapturePeriod(base::TimeDelta::FromSeconds(1) /
frame_rate);
}
void OffScreenVideoConsumer::SizeChanged() {
video_capturer_->SetResolutionConstraints(view_->SizeInPixels(),
view_->SizeInPixels(), true);
video_capturer_->RequestRefreshFrame();
}
void OffScreenVideoConsumer::OnFrameCaptured(
base::ReadOnlySharedMemoryRegion data,
::media::mojom::VideoFrameInfoPtr info,
const gfx::Rect& update_rect,
const gfx::Rect& content_rect,
viz::mojom::FrameSinkVideoConsumerFrameCallbacksPtr callbacks) {
if (!CheckContentRect(content_rect)) {
gfx::Size view_size = view_->SizeInPixels();
video_capturer_->SetResolutionConstraints(view_size, view_size, true);
video_capturer_->RequestRefreshFrame();
return;
}
if (!data.IsValid()) {
callbacks->Done();
return;
}
base::ReadOnlySharedMemoryMapping mapping = data.Map();
if (!mapping.IsValid()) {
DLOG(ERROR) << "Shared memory mapping failed.";
return;
}
if (mapping.size() <
media::VideoFrame::AllocationSize(info->pixel_format, info->coded_size)) {
DLOG(ERROR) << "Shared memory size was less than expected.";
return;
}
// The SkBitmap's pixels will be marked as immutable, but the installPixels()
// API requires a non-const pointer. So, cast away the const.
void* const pixels = const_cast<void*>(mapping.memory());
// Call installPixels() with a |releaseProc| that: 1) notifies the capturer
// that this consumer has finished with the frame, and 2) releases the shared
// memory mapping.
struct FramePinner {
// Keeps the shared memory that backs |frame_| mapped.
base::ReadOnlySharedMemoryMapping mapping;
// Prevents FrameSinkVideoCapturer from recycling the shared memory that
// backs |frame_|.
viz::mojom::FrameSinkVideoConsumerFrameCallbacksPtr releaser;
};
SkBitmap bitmap;
bitmap.installPixels(
SkImageInfo::MakeN32(content_rect.width(), content_rect.height(),
kPremul_SkAlphaType),
pixels,
media::VideoFrame::RowBytes(media::VideoFrame::kARGBPlane,
info->pixel_format, info->coded_size.width()),
[](void* addr, void* context) {
delete static_cast<FramePinner*>(context);
},
new FramePinner{std::move(mapping), std::move(callbacks)});
bitmap.setImmutable();
media::VideoFrameMetadata metadata;
metadata.MergeInternalValuesFrom(info->metadata);
callback_.Run(update_rect, bitmap);
}
void OffScreenVideoConsumer::OnStopped() {}
bool OffScreenVideoConsumer::CheckContentRect(const gfx::Rect& content_rect) {
gfx::Size view_size = view_->SizeInPixels();
gfx::Size content_size = content_rect.size();
if (std::abs(view_size.width() - content_size.width()) > 2) {
return false;
}
if (std::abs(view_size.height() - content_size.height()) > 2) {
return false;
}
return true;
}
} // namespace atom

View File

@@ -0,0 +1,54 @@
// Copyright (c) 2019 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_OSR_OSR_VIDEO_CONSUMER_H_
#define ATOM_BROWSER_OSR_OSR_VIDEO_CONSUMER_H_
#include <memory>
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "components/viz/host/client_frame_sink_video_capturer.h"
namespace atom {
class OffScreenRenderWidgetHostView;
typedef base::Callback<void(const gfx::Rect&, const SkBitmap&)> OnPaintCallback;
class OffScreenVideoConsumer : public viz::mojom::FrameSinkVideoConsumer {
public:
OffScreenVideoConsumer(OffScreenRenderWidgetHostView* view,
OnPaintCallback callback);
~OffScreenVideoConsumer() override;
void SetActive(bool active);
void SetFrameRate(int frame_rate);
void SizeChanged();
private:
// viz::mojom::FrameSinkVideoConsumer implementation.
void OnFrameCaptured(
base::ReadOnlySharedMemoryRegion data,
::media::mojom::VideoFrameInfoPtr info,
const gfx::Rect& update_rect,
const gfx::Rect& content_rect,
viz::mojom::FrameSinkVideoConsumerFrameCallbacksPtr callbacks) override;
void OnStopped() override;
bool CheckContentRect(const gfx::Rect& content_rect);
OnPaintCallback callback_;
OffScreenRenderWidgetHostView* view_;
std::unique_ptr<viz::ClientFrameSinkVideoCapturer> video_capturer_;
base::WeakPtrFactory<OffScreenVideoConsumer> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(OffScreenVideoConsumer);
};
} // namespace atom
#endif // ATOM_BROWSER_OSR_OSR_VIDEO_CONSUMER_H_

View File

@@ -5,7 +5,7 @@
#include "atom/browser/osr/osr_web_contents_view.h"
#include "atom/common/api/api_messages.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/web_contents/web_contents_impl.h" // nogncheck
#include "content/public/browser/render_view_host.h"
#include "third_party/blink/public/platform/web_screen_info.h"
#include "ui/display/screen.h"
@@ -140,7 +140,7 @@ OffScreenWebContentsView::CreateViewForChildWidget(
->GetRenderWidgetHostView()
: web_contents_impl->GetRenderWidgetHostView());
return new OffScreenRenderWidgetHostView(transparent_, true,
return new OffScreenRenderWidgetHostView(transparent_, painting_,
view->GetFrameRate(), callback_,
render_widget_host, view, GetSize());
}
@@ -189,10 +189,9 @@ void OffScreenWebContentsView::UpdateDragCursor(
void OffScreenWebContentsView::SetPainting(bool painting) {
auto* view = GetView();
painting_ = painting;
if (view != nullptr) {
view->SetPainting(painting);
} else {
painting_ = painting;
}
}
@@ -207,10 +206,9 @@ bool OffScreenWebContentsView::IsPainting() const {
void OffScreenWebContentsView::SetFrameRate(int frame_rate) {
auto* view = GetView();
frame_rate_ = frame_rate;
if (view != nullptr) {
view->SetFrameRate(frame_rate);
} else {
frame_rate_ = frame_rate;
}
}

View File

@@ -9,8 +9,8 @@
#include "atom/browser/native_window_observer.h"
#include "atom/browser/osr/osr_render_widget_host_view.h"
#include "content/browser/renderer_host/render_view_host_delegate_view.h"
#include "content/browser/web_contents/web_contents_view.h"
#include "content/browser/renderer_host/render_view_host_delegate_view.h" // nogncheck
#include "content/browser/web_contents/web_contents_view.h" // nogncheck
#include "content/public/browser/web_contents.h"
#if defined(OS_MACOSX)

View File

@@ -17,9 +17,9 @@
<key>CFBundleIconFile</key>
<string>electron.icns</string>
<key>CFBundleVersion</key>
<string>5.0.0-beta.7</string>
<string>5.0.9</string>
<key>CFBundleShortVersionString</key>
<string>5.0.0-beta.7</string>
<string>5.0.9</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.developer-tools</string>
<key>LSMinimumSystemVersion</key>

View File

@@ -50,8 +50,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 5,0,0,7
PRODUCTVERSION 5,0,0,7
FILEVERSION 5,0,9,0
PRODUCTVERSION 5,0,9,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -68,12 +68,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "GitHub, Inc."
VALUE "FileDescription", "Electron"
VALUE "FileVersion", "5.0.0"
VALUE "FileVersion", "5.0.9"
VALUE "InternalName", "electron.exe"
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
VALUE "OriginalFilename", "electron.exe"
VALUE "ProductName", "Electron"
VALUE "ProductVersion", "5.0.0"
VALUE "ProductVersion", "5.0.9"
VALUE "SquirrelAwareVersion", "1"
END
END

View File

@@ -9,6 +9,8 @@
#include "atom/browser/native_window_views.h"
#include "atom/browser/ui/autofill_popup.h"
#include "atom/common/api/api_messages.h"
#include "base/i18n/rtl.h"
#include "chrome/browser/ui/autofill/popup_view_common.h"
#include "electron/buildflags/buildflags.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
@@ -25,85 +27,18 @@
namespace atom {
namespace {
class PopupViewCommon : public autofill::PopupViewCommon {
public:
explicit PopupViewCommon(const gfx::Rect& window_bounds)
: window_bounds_(window_bounds) {}
std::pair<int, int> CalculatePopupXAndWidth(
const display::Display& left_display,
const display::Display& right_display,
int popup_required_width,
const gfx::Rect& element_bounds,
bool is_rtl) {
int leftmost_display_x = left_display.bounds().x();
int rightmost_display_x =
right_display.GetSizeInPixel().width() + right_display.bounds().x();
// Calculate the start coordinates for the popup if it is growing right or
// the end position if it is growing to the left, capped to screen space.
int right_growth_start = std::max(
leftmost_display_x, std::min(rightmost_display_x, element_bounds.x()));
int left_growth_end =
std::max(leftmost_display_x,
std::min(rightmost_display_x, element_bounds.right()));
int right_available = rightmost_display_x - right_growth_start;
int left_available = left_growth_end - leftmost_display_x;
int popup_width =
std::min(popup_required_width, std::max(right_available, left_available));
std::pair<int, int> grow_right(right_growth_start, popup_width);
std::pair<int, int> grow_left(left_growth_end - popup_width, popup_width);
// Prefer to grow towards the end (right for LTR, left for RTL). But if there
// is not enough space available in the desired direction and more space in
// the other direction, reverse it.
if (is_rtl) {
return left_available >= popup_width || left_available >= right_available
? grow_left
: grow_right;
gfx::Rect GetWindowBounds(gfx::NativeView container_view) override {
return window_bounds_;
}
return right_available >= popup_width || right_available >= left_available
? grow_right
: grow_left;
}
std::pair<int, int> CalculatePopupYAndHeight(
const display::Display& top_display,
const display::Display& bottom_display,
int popup_required_height,
const gfx::Rect& element_bounds) {
int topmost_display_y = top_display.bounds().y();
int bottommost_display_y =
bottom_display.GetSizeInPixel().height() + bottom_display.bounds().y();
// Calculate the start coordinates for the popup if it is growing down or
// the end position if it is growing up, capped to screen space.
int top_growth_end = std::max(
topmost_display_y, std::min(bottommost_display_y, element_bounds.y()));
int bottom_growth_start =
std::max(topmost_display_y,
std::min(bottommost_display_y, element_bounds.bottom()));
int top_available = bottom_growth_start - topmost_display_y;
int bottom_available = bottommost_display_y - top_growth_end;
// TODO(csharp): Restrict the popup height to what is available.
if (bottom_available >= popup_required_height ||
bottom_available >= top_available) {
// The popup can appear below the field.
return std::make_pair(bottom_growth_start, popup_required_height);
} else {
// The popup must appear above the field.
return std::make_pair(top_growth_end - popup_required_height,
popup_required_height);
}
}
display::Display GetDisplayNearestPoint(const gfx::Point& point) {
return display::Screen::GetScreen()->GetDisplayNearestPoint(point);
}
} // namespace
private:
gfx::Rect window_bounds_;
};
AutofillPopup::AutofillPopup() {
bold_font_list_ = gfx::FontList().DeriveWithWeight(gfx::Font::Weight::BOLD);
@@ -134,7 +69,6 @@ void AutofillPopup::CreateView(content::RenderFrameHost* frame_host,
parent_->AddObserver(this);
view_ = new AutofillPopupView(this, parent->GetWidget());
view_->Show();
#if BUILDFLAG(ENABLE_OSR)
if (offscreen) {
@@ -148,6 +82,9 @@ void AutofillPopup::CreateView(content::RenderFrameHost* frame_host,
osr_rwhv->AddViewProxy(view_->view_proxy_.get());
}
#endif
// Do this after OSR setup, we check for view_proxy_ when showing
view_->Show();
}
void AutofillPopup::Hide() {
@@ -181,34 +118,14 @@ void AutofillPopup::UpdatePopupBounds() {
DCHECK(parent_);
gfx::Point origin(element_bounds_.origin());
views::View::ConvertPointToScreen(parent_, &origin);
gfx::Rect bounds(origin, element_bounds_.size());
gfx::Rect window_bounds = parent_->GetBoundsInScreen();
int desired_width = GetDesiredPopupWidth();
int desired_height = GetDesiredPopupHeight();
bool is_rtl = false;
gfx::Point top_left_corner_of_popup =
origin + gfx::Vector2d(bounds.width() - desired_width, -desired_height);
// This is the bottom right point of the popup if the popup is below the
// element and grows to the right (since the is the lowest and furthest right
// the popup could go).
gfx::Point bottom_right_corner_of_popup =
origin + gfx::Vector2d(desired_width, bounds.height() + desired_height);
display::Display top_left_display =
GetDisplayNearestPoint(top_left_corner_of_popup);
display::Display bottom_right_display =
GetDisplayNearestPoint(bottom_right_corner_of_popup);
std::pair<int, int> popup_x_and_width = CalculatePopupXAndWidth(
top_left_display, bottom_right_display, desired_width, bounds, is_rtl);
std::pair<int, int> popup_y_and_height = CalculatePopupYAndHeight(
top_left_display, bottom_right_display, desired_height, bounds);
popup_bounds_ =
gfx::Rect(popup_x_and_width.first, popup_y_and_height.first,
popup_x_and_width.second, popup_y_and_height.second);
PopupViewCommon popup_view_common(window_bounds);
popup_bounds_ = popup_view_common.CalculatePopupBounds(
GetDesiredPopupWidth(), GetDesiredPopupHeight(), bounds,
gfx::NativeView(), base::i18n::IsRTL());
}
gfx::Rect AutofillPopup::popup_bounds_in_view() {

View File

@@ -10,6 +10,8 @@
#import <Cocoa/Cocoa.h>
@interface NSColor (Hex)
- (NSString*)hexadecimalValue;
- (NSString*)RGBAValue;
+ (NSColor*)colorWithHexColorString:(NSString*)hex;
@end

View File

@@ -8,17 +8,65 @@
@implementation NSColor (Hex)
- (NSString*)RGBAValue {
double redFloatValue, greenFloatValue, blueFloatValue, alphaFloatValue;
NSColor* convertedColor =
[self colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
if (convertedColor) {
[convertedColor getRed:&redFloatValue
green:&greenFloatValue
blue:&blueFloatValue
alpha:&alphaFloatValue];
int redIntValue = redFloatValue * 255.99999f;
int greenIntValue = greenFloatValue * 255.99999f;
int blueIntValue = blueFloatValue * 255.99999f;
int alphaIntValue = alphaFloatValue * 255.99999f;
return
[NSString stringWithFormat:@"%02x%02x%02x%02x", redIntValue,
greenIntValue, blueIntValue, alphaIntValue];
}
return nil;
}
- (NSString*)hexadecimalValue {
double redFloatValue, greenFloatValue, blueFloatValue;
NSColor* convertedColor =
[self colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
if (convertedColor) {
[convertedColor getRed:&redFloatValue
green:&greenFloatValue
blue:&blueFloatValue
alpha:NULL];
int redIntValue = redFloatValue * 255.99999f;
int greenIntValue = greenFloatValue * 255.99999f;
int blueIntValue = blueFloatValue * 255.99999f;
return [NSString stringWithFormat:@"#%02x%02x%02x", redIntValue,
greenIntValue, blueIntValue];
}
return nil;
}
+ (NSColor*)colorWithHexColorString:(NSString*)inColorString {
unsigned colorCode = 0;
unsigned char redByte, greenByte, blueByte;
if (inColorString) {
NSScanner* scanner = [NSScanner scannerWithString:inColorString];
(void)[scanner scanHexInt:&colorCode]; // ignore error
}
redByte = (unsigned char)(colorCode >> 16);
greenByte = (unsigned char)(colorCode >> 8);
blueByte = (unsigned char)(colorCode); // masks off high bits
unsigned char redByte = (unsigned char)(colorCode >> 16);
unsigned char greenByte = (unsigned char)(colorCode >> 8);
unsigned char blueByte = (unsigned char)(colorCode); // masks off high bits
return [NSColor colorWithCalibratedRed:(CGFloat)redByte / 0xff
green:(CGFloat)greenByte / 0xff

View File

@@ -353,8 +353,11 @@ static NSString* const ImageScrubberItemIdentifier = @"scrubber.image.item";
NSButton* button = (NSButton*)item.view;
std::string backgroundColor;
if (settings.Get("backgroundColor", &backgroundColor)) {
if (settings.Get("backgroundColor", &backgroundColor) &&
!backgroundColor.empty()) {
button.bezelColor = [self colorFromHexColorString:backgroundColor];
} else {
button.bezelColor = nil;
}
std::string label;

View File

@@ -16,7 +16,19 @@ ViewsDelegateMac::~ViewsDelegateMac() {}
void ViewsDelegateMac::OnBeforeWidgetInit(
views::Widget::InitParams* params,
views::internal::NativeWidgetDelegate* delegate) {
DCHECK(params->native_widget);
// If we already have a native_widget, we don't have to try to come
// up with one.
if (params->native_widget)
return;
if (!native_widget_factory().is_null()) {
params->native_widget = native_widget_factory().Run(*params, delegate);
if (params->native_widget)
return;
}
// Setting null here causes Widget to create the default NativeWidget implementation.
params->native_widget = nullptr;
}
ui::ContextFactory* ViewsDelegateMac::GetContextFactory() {

View File

@@ -8,9 +8,11 @@
#include <utility>
#include <vector>
#include "atom/browser/atom_paths.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
@@ -67,7 +69,7 @@ std::unique_ptr<content::DevToolsSocketFactory> CreateSocketFactory() {
int temp_port;
std::string port_str =
command_line.GetSwitchValueASCII(switches::kRemoteDebuggingPort);
if (base::StringToInt(port_str, &temp_port) && temp_port > 0 &&
if (base::StringToInt(port_str, &temp_port) && temp_port >= 0 &&
temp_port < 65535) {
port = temp_port;
} else {
@@ -84,8 +86,10 @@ std::unique_ptr<content::DevToolsSocketFactory> CreateSocketFactory() {
// static
void DevToolsManagerDelegate::StartHttpHandler() {
base::FilePath user_dir;
base::PathService::Get(DIR_USER_DATA, &user_dir);
content::DevToolsAgentHost::StartRemoteDebuggingServer(
CreateSocketFactory(), base::FilePath(), base::FilePath());
CreateSocketFactory(), user_dir, base::FilePath());
}
DevToolsManagerDelegate::DevToolsManagerDelegate() {}

View File

@@ -29,6 +29,7 @@ class TrayIconCocoa : public TrayIcon, public AtomMenuModel::Observer {
void SetHighlightMode(TrayIcon::HighlightMode mode) override;
void SetIgnoreDoubleClickEvents(bool ignore) override;
bool GetIgnoreDoubleClickEvents() override;
void PopUpOnUI(AtomMenuModel* menu_model);
void PopUpContextMenu(const gfx::Point& pos,
AtomMenuModel* menu_model) override;
void SetContextMenu(AtomMenuModel* menu_model) override;
@@ -48,6 +49,8 @@ class TrayIconCocoa : public TrayIcon, public AtomMenuModel::Observer {
// Used for unregistering observer.
AtomMenuModel* menu_model_ = nullptr; // weak ref.
base::WeakPtrFactory<TrayIconCocoa> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(TrayIconCocoa);
};

Some files were not shown because too many files have changed in this diff Show More