Compare commits

...

65 Commits

Author SHA1 Message Date
Sudowoodo Release Bot
92f20955bd Bump v16.0.0-beta.3 2021-10-25 06:33:46 -07:00
trop[bot]
762ecfef24 fix: vibrant window should have transparent background (#31537)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-10-25 09:48:13 +09:00
trop[bot]
ea96f4c176 fix: MediaMetadata not working properly (#31535)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-10-22 21:17:24 +09:00
Erick Zhao
d085de4787 docs: add window customization guide (#31054) (#31508)
* docs: add window customization guide

* fixes

* Update docs/api/browser-window.md

Co-authored-by: Mark Lee <malept@users.noreply.github.com>

* Update docs/api/browser-window.md

Co-authored-by: Mark Lee <malept@users.noreply.github.com>

* Update docs/fiddles/windows/manage-windows/frameless-window/index.html

Co-authored-by: Mark Lee <malept@users.noreply.github.com>

* Update docs/tutorial/window-customization.md

Co-authored-by: Mark Lee <malept@users.noreply.github.com>

* Update docs/tutorial/window-customization.md

Co-authored-by: Mark Lee <malept@users.noreply.github.com>

* Update docs/tutorial/window-customization.md

Co-authored-by: Mark Lee <malept@users.noreply.github.com>

* Update docs/tutorial/window-customization.md

Co-authored-by: Mark Lee <malept@users.noreply.github.com>

* Update docs/tutorial/window-customization.md

Co-authored-by: Mark Lee <malept@users.noreply.github.com>

* Update docs/tutorial/window-customization.md

Co-authored-by: Mark Lee <malept@users.noreply.github.com>

* Update docs/tutorial/window-customization.md

Co-authored-by: Mark Lee <malept@users.noreply.github.com>

* Update docs/tutorial/window-customization.md

Co-authored-by: Mark Lee <malept@users.noreply.github.com>

* Update docs/tutorial/window-customization.md

Co-authored-by: Mark Lee <malept@users.noreply.github.com>

* Update docs/tutorial/window-customization.md

Co-authored-by: Mark Lee <malept@users.noreply.github.com>

* Update docs/tutorial/window-customization.md

Co-authored-by: Mark Lee <malept@users.noreply.github.com>

* fix code fence

Co-authored-by: Mark Lee <malept@users.noreply.github.com>

Co-authored-by: Mark Lee <malept@users.noreply.github.com>
2021-10-22 21:15:57 +09:00
trop[bot]
dd7a8da6be fix: event with invalid timestamp in trace log (#31423)
* fix: event with invalid timestamp in trace log

When node is started within Electron's environment it doesn't
initialize v8 and time of v8's start is never set. As a result
we log v8's start time as 0 and it breaks timestamps in the
trace log. With this change we log v8's start time only when
it was initialized by node.

* update patches for 16-x-y

Co-authored-by: Cezary Kulakowski <cezary@openfin.co>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-10-21 13:55:02 -04:00
Sudowoodo Release Bot
a4ded39e61 Bump v16.0.0-beta.2 2021-10-21 06:33:22 -07:00
trop[bot]
d3ff2033ed feat: Add data parameter to app.requestSingleInstanceLock() (#31444)
* WIP

* Use serialization

* Rebase windows impl of new app requestSingleInstanceLock parameter

* Fix test

* Implement posix side

* Add backwards compatibility test

* Apply PR feedback Windows

* Fix posix impl

* Switch mac impl back to vector

* Refactor Windows impl

* Use vectors, inline make_span

* Use blink converter

* fix: ownership across sequences

* Fix upstream merge from Chromium

Co-authored-by: Raymond Zhao <raymondzhao@microsoft.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-10-21 21:52:15 +09:00
trop[bot]
005b193307 feat: warn when ipcRenderer.sendSync() called with no listeners for channel (#31435)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2021-10-21 09:08:47 +09:00
trop[bot]
369269c475 fix: remove 'NOTREACHED()' from 'GetWindowResizeEdge' (#31479)
Co-authored-by: mlaurencin <mlaurencin@electronjs.org>
2021-10-21 09:05:33 +09:00
Sudowoodo Release Bot
339eccfc42 Bump v16.0.0-beta.1 2021-10-20 07:57:25 -07:00
trop[bot]
65c8415bac fix: don't use private enterprise APIs in MAS build (#31488)
* fix: don't use private enterprise APIs in MAS build

* Update .patches

Co-authored-by: VerteDinde <khammond@slack-corp.com>
Co-authored-by: Samuel Attard <sam@electronjs.org>
2021-10-20 07:50:32 -07:00
trop[bot]
30be3150ff fix: ensure TracingAgent in place for SWs (#31477)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-10-19 11:43:23 -04:00
trop[bot]
7d9ce1379f fix: link to image windows progress bar image was linked with square brackets [] insted of parenthesis () and to github asset storage instead of local image directory. (#31473)
Co-authored-by: Daniel Ramp <12480131+DanielRamp@users.noreply.github.com>
2021-10-19 20:39:45 +09:00
trop[bot]
27d1f6a360 Avoid Undefined Variable In printToPdf Example (#31466)
Co-authored-by: universalstrapping <90921972+universalstrapping@users.noreply.github.com>
2021-10-19 17:41:05 +09:00
trop[bot]
be46387f22 fix: add isDestroyed check (#31469)
* Added isDestroyed check

fix: https://github.com/electron/electron/issues/31196

* fix: unregister frame name

Unregister the frame name so that we do not accidentally unregister the wrong window later on in case there is a timing issue with the events

* fix; check if webContents is destroyed

* fix: check if window/webContents is destroyed

Co-authored-by: Cheng Zhao <github@zcbenz.com>

Co-authored-by: t57ser <seve@live.at>
Co-authored-by: Cheng Zhao <github@zcbenz.com>
2021-10-19 17:39:33 +09:00
Cheng Zhao
fe160165b6 fix: generate valid config.gypi (#31441) 2021-10-18 10:35:07 -05:00
Sudowoodo Release Bot
be1c18096b Bump v16.0.0-alpha.9 2021-10-18 08:30:43 -07:00
trop[bot]
2e3b05bcad fix: also pass securityOrigin to media permissions request handler (#31416)
Co-authored-by: Maxime Serrano <mserrano@alumni.cmu.edu>
2021-10-15 13:32:01 +09:00
trop[bot]
54657fb667 fix: mac window crash native theme update (#31430)
Co-authored-by: Samuel Maddock <samuel.maddock@gmail.com>
2021-10-15 09:05:53 +09:00
Sudowoodo Release Bot
c83d65eab0 Bump v16.0.0-alpha.8 2021-10-14 11:22:30 -07:00
trop[bot]
3daad4fd40 fix: reset render_frame_disposed_ after render frame host change (#31427)
* fix: reset render_frame_disposed_ after hang

* fix: handle exception in webContents.send

Co-authored-by: VerteDinde <keeleymhammond@gmail.com>
Co-authored-by: VerteDinde <khammond@slack-corp.com>
2021-10-14 11:21:31 -07:00
trop[bot]
b4a79672cf test: fix flaky contentTracing.startRecording spec (#31411)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-10-13 16:52:19 -04:00
trop[bot]
a71c610747 docs: update Versioning doc (#31389)
* fix information

* move historical section to bottom

* Update docs/tutorial/electron-versioning.md

Co-authored-by: Charles Kerr <charles@charleskerr.com>

Co-authored-by: Erick Zhao <erick@hotmail.ca>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2021-10-13 11:24:30 +09:00
trop[bot]
b1366421d1 chore: bump chromium to 96.0.4647.0 (main) (#31302)
* chore: bump chromium in DEPS to 95.0.4630.0

* 3133701: Fix chrome root store codegen for cross-compile builds.

https://chromium-review.googlesource.com/c/chromium/src/+/3133701

* 49125: Include SHA512-256 in EVP_get_digestbyname and EVP_MD_do_all.

https://boringssl-review.googlesource.com/c/boringssl/+/49125

* chore: fixup patch indices

* 3131662: [Code Health] Remove ListValue::Append(Integer|Boolean)

https://chromium-review.googlesource.com/c/chromium/src/+/3131662

* chore: bump chromium in DEPS to 95.0.4631.0

* chore: update patches

* chore: bump chromium in DEPS to 95.0.4635.0

* chore: update patches

* chore: bump chromium in DEPS to 95.0.4636.0

* chore: bump chromium in DEPS to 95.0.4637.0

* chore: update patches

* refactor: move PlatformNotificationService into BrowserContext

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/3137256

* refactor: ListValue::GetSize and ListValue::AppendString were removed

Refs: https://chromium-review.googlesource.com/c/chromium/src/+/3144540

* chore: bump chromium in DEPS to 95.0.4638.0

* chore: bump chromium in DEPS to 95.0.4638.4

* chore: bump chromium in DEPS to 96.0.4640.0

* chore: bump chromium in DEPS to 96.0.4641.0

* chore: bump chromium in DEPS to 96.0.4642.0

* chore: update patches

Co-authored-by: Michaela Laurencin <mlaurencin@electronjs.org>

* 3134756: Move extensions/browser/value_store to components/value_store.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/3134756

* 3150092: [Autofill] Allow aligning Autofill suggestions to the field's center

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/3150092

* chore: bump chromium in DEPS to 96.0.4643.0

* chore: update patches

* chore: bump chromium in DEPS to 96.0.4644.0

* chore: update patches

* chore: bump chromium in DEPS to 96.0.4645.0

* chore: update patches

* chore: bump chromium in DEPS to 96.0.4646.0

* chore: bump chromium in DEPS to 96.0.4647.0

* chore: update patches

Ref (for chromium): https://chromium-review.googlesource.com/c/chromium/src/+/3165772

* 3162087: Reland "Ensure Branch Target Identification is enabled for executable pages."

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/3162087

* chore: update evert_add_inline_and_inline_origin_records_to_symbol_file.patch

Xref: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/3166678

Xref: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/3166674

* chore: update Allocator construction

Xref: https://chromium-review.googlesource.com/c/chromium/src/+/3135195

Change RefCount::kAllowed/Disallowed semantics into BackupRefPtr::kEnabled/Disabled

* chore: add UseConfigurablePool to v8::ArrayBuffer::Allocator invocation

Xref: https://chromium-review.googlesource.com/c/chromium/src/+/3090845

* chore: do not set network_context_params.context_name

Xref: https://chromium-review.googlesource.com/c/chromium/src/+/3155743

Remove name field from mojom::NetworkContext

* fix: use ForEachRenderFrameHost to iterate frames.

Xref: https://chromium-review.googlesource.com/c/chromium/src/+/3163336

New implementation partially cribbed from
https://source.chromium.org/chromium/chromium/src/+/main:extensions/browser/script_executor.cc;drc=f894f106c6d5fac8e0b75158f622256e0f34f593;l=109

* Remove WebLocalFrame::RequestExecuteScriptAndReturnValue()

Xref: https://chromium-review.googlesource.com/c/chromium/src/+/3149699

ExecuteJavaScript's RequestExecuteScript() new params are cribbed from
https://chromium-review.googlesource.com/c/chromium/src/+/3149699/4/third_party/blink/renderer/core/frame/web_local_frame_impl.cc

* Remove IsDescendantOf API on RenderFrameHost.

Xref: https://chromium-review.googlesource.com/c/chromium/src/+/3165357

function is trivial to implement, so make a local copy in anon namespace

* Rewrite IsDescendantOf check to check GetParentOrOuterDocument.

https://chromium-review.googlesource.com/c/chromium/src/+/3160061

* Remove GetFramesInSubtree from RenderFrameHost

https://chromium-review.googlesource.com/c/chromium/src/+/3163336

* fix: dump_syms for macOS

* chore: update patches

* Remove ListValue::AppendString and ListValue::GetSize

https://chromium-review.googlesource.com/c/chromium/src/+/3144540

* fix: gn check

https://chromium-review.googlesource.com/c/chromium/src/+/3163890

* fix: crash with Isolate::GetHeapCodeAndMetadataStatistics

https://chromium-review.googlesource.com/c/v8/v8/+/3175820

* chore: update patches

* chore: fix windows build

* Add kPrintWithPostScriptType42Fonts feature.

https://chromium-review.googlesource.com/c/chromium/src/+/3150776

* chore: update patches

* chore: fix tests

* ozone/x11: fix VA-API.

https://chromium-review.googlesource.com/c/chromium/src/+/3141878

* Revert "ozone/x11: fix VA-API."

This reverts commit 23e742acb1.

* Reland "Make Ozone/X11 default."

https://chromium-review.googlesource.com/c/chromium/src/+/3114071

* fixup Reland "Make Ozone/X11 default."

* fixup Reland "Make Ozone/X11 default." for clipboard

* test: unflake contentTracing test

* Revert "test: unflake contentTracing test"

This reverts commit 62a6525235.

* chore: debug large contentTracing file

* fixup debug patch

* Revert "fixup debug patch"

* Roll Perfetto Trace Processor Linux from b852166f90d5 to e90b9fb93385

https://chromium-review.googlesource.com/c/chromium/src/+/3212306

* update patch after merge

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: VerteDinde <khammond@slack-corp.com>
Co-authored-by: Michaela Laurencin <mlaurencin@electronjs.org>
Co-authored-by: VerteDinde <keeleymhammond@gmail.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
2021-10-12 13:56:37 -04:00
trop[bot]
f2696fb431 chore: refactor persisting permission granted to serial ports (#31324)
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-10-12 09:19:07 +09:00
trop[bot]
25c536d355 fix: black window on screen capture when content protection is enabled (#31386)
Co-authored-by: Micha Hanselmann <mhanselmann@microsoft.com>
2021-10-12 09:07:27 +09:00
trop[bot]
6530067b85 feat: add commandLine.removeSwitch (#31327)
* feat: add commandLine.removeSwitch

In some cases apps may want to remove Chromium command line switches to avoid certain Chromium behaviors being used, E.g. remote-debugging-port or gpu-launcher

* fix: add missing removeSwitch to app.ts

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2021-10-12 09:06:16 +09:00
Sudowoodo Release Bot
8626aa29d1 Bump v16.0.0-alpha.7 2021-10-11 07:57:39 -07:00
Keeley Hammond
9e0a182821 chore: cherry-pick ec42dfd3545f from chromium (#31331)
* chore: cherry-pick ec42dfd3545f from chromium

* chore: cherry-pick 39090918efac from chromium

* chore: reconcile FPS patch differences

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2021-10-11 13:03:53 +02:00
trop[bot]
2d8fa4d225 fix: correctly notify WebViewGuestDelegate when webview is detached (#31375)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-10-11 14:35:56 +09:00
trop[bot]
5a7ba8ba8c chore: add logging for print_backend failures (#31288)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-10-11 14:32:46 +09:00
trop[bot]
ede6b45bc1 test: add missing context-menu event spec for <webview> (#31307)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2021-10-11 14:29:40 +09:00
trop[bot]
1000ddfcab docs: add missing 'context-menu' event to webview-tag.md (#31311)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2021-10-11 14:28:17 +09:00
trop[bot]
63110a7159 fix: crash on missing render frame (#31336)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-10-11 09:33:59 +09:00
trop[bot]
308ef699e6 docs: nativeWindowOpen default was changed in Electron 15 (#31356)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2021-10-10 15:50:20 -07:00
Sudowoodo Release Bot
764b2a6041 Bump v16.0.0-alpha.6 2021-10-07 08:16:39 -07:00
trop[bot]
5009694dc9 refactor: only access memory coordinator interface from browser process (#31301)
Refs https://chromium-review.googlesource.com/c/chromium/src/+/3174305

Co-authored-by: deepak1556 <hop2deep@gmail.com>
2021-10-05 19:19:11 -07:00
trop[bot]
c07016e1d1 fix: return HTNOWHERE in resize hit test to allow draggable regions to kick in when required (#31300)
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2021-10-06 09:22:06 +09:00
Sudowoodo Release Bot
7c5a346464 Bump v16.0.0-alpha.5 2021-10-04 12:44:25 -07:00
trop[bot]
4f54cc0d18 fix: "Failed to serialize arguments" when emitting 'context-menu' for webview (#31278)
* fix: sanitize params for 'context-menu' event sent over IPC for webview

* Revert "fix: sanitize params for 'context-menu' event sent over IPC for webview"

This reverts commit 7fee455138.

* fix: make frame property non-enumerable in params for 'context-menu' event

Co-authored-by: Milan Burda <milan.burda@gmail.com>
2021-10-04 15:43:11 -04:00
Sudowoodo Release Bot
520e7077d4 Bump v16.0.0-alpha.4 2021-10-04 04:48:37 -07:00
trop[bot]
eb41f5b70e fix: dialog is not defined (#31270)
Corrects the following error in Electron Fiddle:

```
Uncaught Exception:
ReferenceError: dialog is not defined
...
```

Co-authored-by: Ryan Johnson <CITguy@users.noreply.github.com>
2021-10-04 12:14:36 +09:00
trop[bot]
23afedcea8 fix: fix typo in description of secureDnsMode (#31268)
Co-authored-by: Tobias Nießen <tniessen@users.noreply.github.com>
2021-10-04 12:13:45 +09:00
Alexey Kuzmin
9bc6e1a584 chore: fix pylint (#31201)
* chore: fix pylint

* chore: fix linter errors
2021-09-30 17:19:54 -04:00
Sudowoodo Release Bot
89b08817a9 Bump v16.0.0-alpha.3 2021-09-30 13:55:43 -07:00
trop[bot]
cb6a22a7a4 fix: Enable X509_V_FLAG_TRUSTED_FIRST flag in BoringSSL (#31217)
Fixes: https://github.com/electron/electron/issues/31212
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>

Co-authored-by: Juan Cruz Viotti <jv@jviotti.com>
2021-09-30 16:30:32 -04:00
trop[bot]
74c53ad0c3 fix: draggable regions in BrowserViews are independent (#31199)
* fix: draggable regions in BrowserViews are independent

* Trigger Build

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2021-09-30 11:14:40 -04:00
trop[bot]
88235cb2bc fix: crash creating private key with unsupported algorithm (#31136)
* fix: crash creating private key with unsupported algorithm

* test: add regression test

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-09-30 10:11:32 -04:00
Sudowoodo Release Bot
f8b4dc98b9 Bump v16.0.0-alpha.2 2021-09-30 07:08:25 -07:00
trop[bot]
79108c7acd fix: running tests with release build (#31141)
* fix: running tests with release build

* Update electron_api_v8_util.cc

Co-authored-by: Milan Burda <milan.burda@gmail.com>
2021-09-29 15:31:54 -04:00
trop[bot]
b0273b96c1 feat: add support for WebHID (#30213) (#31090)
* feat: add support for WebHID

* Apply suggestions from code review

Co-authored-by: Jeremy Rose <jeremya@chromium.org>

* Address review feedback

* Address review feedback

* chore: clear granted_devices on navigation

Also added test to verify devices get cleared

* fixup testing for device clear

* make sure navigator.hid.getDevices is run on correct frame

* clear granted devices on RenderFrameHost deletion/change

* manage device permissions per RenderFrameHost

This change makes sure we don't clear device permission prematurely due to child frame navigation

* Update shell/browser/api/electron_api_web_contents.cc

Co-authored-by: Jeremy Rose <jeremya@chromium.org>

* apply review feedback from @zcbenz

* Match upstream ObjectMap

This change matches what ObjectPermissionContextBase uses to cache object permissions: https://source.chromium.org/chromium/chromium/src/+/main:components/permissions/object_permission_context_base.h;l=52;drc=8f95b5eab2797a3e26bba299f3b0df85bfc98bf5;bpv=1;bpt=0

The main reason for this was to resolve this crash on Win x64:
ok 2 WebContentsView doesn't crash when GCed during allocation
Received fatal exception EXCEPTION_ACCESS_VIOLATION
Backtrace:
        gin::WrappableBase::SecondWeakCallback [0x00007FF6F2AFA005+133] (o:\gin\wrappable.cc:53)
        v8::internal::GlobalHandles::InvokeSecondPassPhantomCallbacks [0x00007FF6F028F9AB+171] (o:\v8\src\handles\global-handles.cc:1400)
        v8::internal::GlobalHandles::InvokeSecondPassPhantomCallbacksFromTask [0x00007FF6F028F867+391] (o:\v8\src\handles\global-handles.cc:1387)
        node::PerIsolatePlatformData::RunForegroundTask [0x00007FF6F3B4D065+317] (o:\third_party\electron_node\src\node_platform.cc:415)
        node::PerIsolatePlatformData::FlushForegroundTasksInternal [0x00007FF6F3B4C424+776] (o:\third_party\electron_node\src\node_platform.cc:479)
        uv_run [0x00007FF6F2DDD07C+492] (o:\third_party\electron_node\deps\uv\src\win\core.c:609)
        electron::NodeBindings::UvRunOnce [0x00007FF6EEE1E036+294] (o:\electron\shell\common\node_bindings.cc:631)
        base::TaskAnnotator::RunTask [0x00007FF6F2318A19+457] (o:\base\task\common\task_annotator.cc:178)
        base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl [0x00007FF6F2E6F553+963] (o:\base\task\sequence_manager\thread_controller_with_message_pump_impl.cc:361)
        base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork [0x00007FF6F2E6EC69+137] (o:\base\task\sequence_manager\thread_controller_with_message_pump_impl.cc:266)
        base::MessagePumpForUI::DoRunLoop [0x00007FF6F235AA58+216] (o:\base\message_loop\message_pump_win.cc:221)
        base::MessagePumpWin::Run [0x00007FF6F235A01A+106] (o:\base\message_loop\message_pump_win.cc:79)
        base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run [0x00007FF6F2E702DA+682] (o:\base\task\sequence_manager\thread_controller_with_message_pump_impl.cc:470)
        base::RunLoop::Run [0x00007FF6F22F95BA+842] (o:\base\run_loop.cc:136)
        content::BrowserMainLoop::RunMainMessageLoop [0x00007FF6F14423CC+208] (o:\content\browser\browser_main_loop.cc:990)
        content::BrowserMainRunnerImpl::Run [0x00007FF6F144402F+143] (o:\content\browser\browser_main_runner_impl.cc:153)
        content::BrowserMain [0x00007FF6F143F911+257] (o:\content\browser\browser_main.cc:49)
        content::RunBrowserProcessMain [0x00007FF6EFFA7D18+112] (o:\content\app\content_main_runner_impl.cc:608)
        content::ContentMainRunnerImpl::RunBrowser [0x00007FF6EFFA8CF4+1220] (o:\content\app\content_main_runner_impl.cc:1104)
        content::ContentMainRunnerImpl::Run [0x00007FF6EFFA87C9+393] (o:\content\app\content_main_runner_impl.cc:971)
        content::RunContentProcess [0x00007FF6EFFA73BD+733] (o:\content\app\content_main.cc:394)
        content::ContentMain [0x00007FF6EFFA79E1+54] (o:\content\app\content_main.cc:422)
        wWinMain [0x00007FF6EECA1535+889] (o:\electron\shell\app\electron_main.cc:291)
        __scrt_common_main_seh [0x00007FF6F6F88482+262] (d:\A01\_work\6\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288)
        BaseThreadInitThunk [0x00007FFEC0087034+20]
        RtlUserThreadStart [0x00007FFEC1F02651+33]
✗ Electron tests failed with code 0xc0000005.

Co-authored-by: Jeremy Rose <jeremya@chromium.org>

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: Jeremy Rose <jeremya@chromium.org>
2021-09-29 13:05:46 -04:00
trop[bot]
f7dd18466b fix: BrowserView drag now delegates to the OS when possible (#31178)
Co-authored-by: @anulman <@anulman>
2021-09-29 12:24:01 +02:00
trop[bot]
80175c5828 refactor: use native WeakRef instead of v8util.weaklyTrackValue() (#31166)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2021-09-28 10:16:01 +02:00
trop[bot]
2a36199b35 fix: .lldbinit config stale (unavailable) (#31161)
Co-authored-by: Black-Hole1 <158blackhole@gmail.com>
2021-09-28 09:54:25 +02:00
trop[bot]
f5c2bab02b docs: update branch name (#31150) 2021-09-28 09:52:19 +02:00
trop[bot]
acca212814 fix: avoid double free when destroying WebContents (#31132)
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2021-09-28 09:48:33 +02:00
trop[bot]
ebbaa3b352 fix: crash in v8 due to regexp reentrancy (#31145)
* fix: crash in v8 due to regexp reentrancy

Check failed: !regexp_stack_->is_in_use()

Refs https://bugs.chromium.org/p/chromium/issues/detail?id=1250646
Refs https://bugs.chromium.org/p/v8/issues/detail?id=11382

* chore: update patches

Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2021-09-27 16:53:39 -07:00
trop[bot]
c42ed97535 fix: first mouse not dragging BrowserView (#31101)
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-09-27 09:38:57 +02:00
trop[bot]
cec707ce67 chore: remove gin::Wrappable crash keys (#31105)
* chore: remove gin wrappable crash keys

* chore: remove class headers from crash keys

Co-authored-by: VerteDinde <khammond@slack-corp.com>
2021-09-24 10:15:59 -07:00
trop[bot]
0080a61c1d feat: add width option to dialog.showMessageBox() (#31089)
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2021-09-23 17:34:51 -04:00
trop[bot]
2f543c3fd4 fix: startDrag params type incorrect (#31084)
Co-authored-by: Black-Hole1 <158blackhole@gmail.com>
2021-09-23 19:49:49 +09:00
trop[bot]
f6da3b43c2 fix: update Windows' cache after changing window's style (#31080)
To enable/disable window resizing we set/unset WS_THICKFRAME style
flag on the window. Window's frame styles are cached so we need to
call SetWindowPos with the SWP_FRAMECHANGED flag set to update
cache properly.

Co-authored-by: Cezary Kulakowski <cezary@openfin.co>
2021-09-23 19:48:42 +09:00
trop[bot]
6029315e1a chore: clarify new-window fix comment (#31072)
Co-authored-by: VerteDinde <khammond@slack-corp.com>
2021-09-22 17:26:22 -07:00
Sudowoodo Release Bot
f6748f9795 Bump v16.0.0-alpha.1 2021-09-22 12:49:14 -07:00
trop[bot]
6500bcbb32 fix: proper localization when using GtkFileChooserNative (#31067)
* fix: proper localization when using GtkFileChooserNative

* fix: iwyu

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2021-09-22 15:48:19 -04:00
248 changed files with 7849 additions and 3074 deletions

View File

@@ -8,9 +8,9 @@ body:
label: Preflight Checklist
description: Please ensure you've completed all of the following.
options:
- label: I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md) for this project.
- label: I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/main/CONTRIBUTING.md) for this project.
required: true
- label: I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md) that this project adheres to.
- label: I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md) that this project adheres to.
required: true
- label: I have searched the [issue tracker](https://www.github.com/electron/electron/issues) for a feature request that matches the one I want to file, without success.
required: true

View File

@@ -8,9 +8,9 @@ body:
label: Preflight Checklist
description: Please ensure you've completed all of the following.
options:
- label: I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md) for this project.
- label: I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/main/CONTRIBUTING.md) for this project.
required: true
- label: I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md) that this project adheres to.
- label: I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md) that this project adheres to.
required: true
- label: I have searched the [issue tracker](https://www.github.com/electron/electron/issues) for a feature request that matches the one I want to file, without success.
required: true

View File

@@ -7,9 +7,9 @@ body:
label: Preflight Checklist
description: Please ensure you've completed all of the following.
options:
- label: I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/master/CONTRIBUTING.md) for this project.
- label: I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/main/CONTRIBUTING.md) for this project.
required: true
- label: I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md) that this project adheres to.
- label: I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md) that this project adheres to.
required: true
- type: input
attributes:

View File

@@ -3,7 +3,7 @@
Thank you for your Pull Request. Please provide a description above and review
the requirements below.
Contributors guide: https://github.com/electron/electron/blob/master/CONTRIBUTING.md
Contributors guide: https://github.com/electron/electron/blob/main/CONTRIBUTING.md
-->
#### Checklist
@@ -11,7 +11,7 @@ Contributors guide: https://github.com/electron/electron/blob/master/CONTRIBUTIN
- [ ] PR description included and stakeholders cc'd
- [ ] `npm test` passes
- [ ] tests are [changed or added](https://github.com/electron/electron/blob/master/docs/development/testing.md)
- [ ] tests are [changed or added](https://github.com/electron/electron/blob/main/docs/development/testing.md)
- [ ] relevant documentation is changed or added
- [ ] [PR release notes](https://github.com/electron/clerk/blob/master/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/master/README.md#examples).

6
.github/config.yml vendored
View File

@@ -2,7 +2,7 @@
newPRWelcomeComment: |
💖 Thanks for opening this pull request! 💖
We use [semantic commit messages](https://github.com/electron/electron/blob/master/docs/development/pull-requests.md#commit-message-guidelines) to streamline the release process. Before your pull request can be merged, you should **update your pull request title** to start with a semantic prefix.
We use [semantic commit messages](https://github.com/electron/electron/blob/main/docs/development/pull-requests.md#commit-message-guidelines) to streamline the release process. Before your pull request can be merged, you should **update your pull request title** to start with a semantic prefix.
Examples of commit messages with semantic prefixes:
@@ -12,9 +12,9 @@ newPRWelcomeComment: |
Things that will help get your PR across the finish line:
- Follow the JavaScript, C++, and Python [coding style](https://github.com/electron/electron/blob/master/docs/development/coding-style.md).
- Follow the JavaScript, C++, and Python [coding style](https://github.com/electron/electron/blob/main/docs/development/coding-style.md).
- Run `npm run lint` locally to catch formatting errors earlier.
- Document any user-facing changes you've made following the [documentation styleguide](https://github.com/electron/electron/blob/master/docs/styleguide.md).
- Document any user-facing changes you've made following the [documentation styleguide](https://github.com/electron/electron/blob/main/docs/styleguide.md).
- Include tests when adding/changing behavior.
- Include screenshots and animated GIFs whenever possible.

View File

@@ -187,6 +187,12 @@ action("electron_js2c") {
rebase_path(sources, root_build_dir)
}
action("generate_config_gypi") {
outputs = [ "$root_gen_dir/config.gypi" ]
script = "script/generate-config-gypi.py"
args = rebase_path(outputs) + [ target_cpu ]
}
target_gen_default_app_js = "$target_gen_dir/js/default_app"
typescript_build("default_app_js") {
@@ -347,6 +353,7 @@ source_set("electron_lib") {
"//base/allocator:buildflags",
"//chrome/app:command_ids",
"//chrome/app/resources:platform_locale_settings",
"//components/autofill/core/common:features",
"//components/certificate_transparency",
"//components/language/core/browser",
"//components/net_log",
@@ -379,6 +386,7 @@ source_set("electron_lib") {
"//ppapi/shared_impl",
"//printing/buildflags",
"//services/device/public/cpp/geolocation",
"//services/device/public/cpp/hid",
"//services/device/public/mojom",
"//services/proxy_resolver:lib",
"//services/video_capture/public/mojom:constants",

View File

@@ -36,7 +36,7 @@ Having the original text _as well as_ the translation can help mitigate translat
Responses to posted issues may or may not be in the original language.
**Please note** that using non-English as an attempt to circumvent our [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md) will be an immediate, and possibly indefinite, ban from the project.
**Please note** that using non-English as an attempt to circumvent our [Code of Conduct](https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md) will be an immediate, and possibly indefinite, ban from the project.
## [Pull Requests](https://electronjs.org/docs/development/pull-requests)

2
DEPS
View File

@@ -15,7 +15,7 @@ gclient_gn_args = [
vars = {
'chromium_version':
'95.0.4629.0',
'96.0.4647.0',
'node_version':
'v16.9.1',
'nan_version':

View File

@@ -1 +1 @@
16.0.0-nightly.20210922
16.0.0-beta.3

View File

@@ -1,7 +1,7 @@
[![Electron Logo](https://electronjs.org/images/electron-logo.svg)](https://electronjs.org)
[![CircleCI Build Status](https://circleci.com/gh/electron/electron/tree/master.svg?style=shield)](https://circleci.com/gh/electron/electron/tree/master)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/4lggi9dpjc1qob7k/branch/master?svg=true)](https://ci.appveyor.com/project/electron-bot/electron-ljo26/branch/master)
[![CircleCI Build Status](https://circleci.com/gh/electron/electron/tree/main.svg?style=shield)](https://circleci.com/gh/electron/electron/tree/main)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/4lggi9dpjc1qob7k/branch/main?svg=true)](https://ci.appveyor.com/project/electron-bot/electron-ljo26/branch/main)
[![Electron Discord Invite](https://img.shields.io/discord/745037351163527189?color=%237289DA&label=chat&logo=discord&logoColor=white)](https://discord.com/invite/electron)
:memo: Available Translations: 🇨🇳 🇧🇷 🇪🇸 🇯🇵 🇷🇺 🇫🇷 🇺🇸 🇩🇪.
@@ -16,7 +16,7 @@ Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important
announcements.
This project adheres to the Contributor Covenant
[code of conduct](https://github.com/electron/electron/tree/master/CODE_OF_CONDUCT.md).
[code of conduct](https://github.com/electron/electron/tree/main/CODE_OF_CONDUCT.md).
By participating, you are expected to uphold this code. Please report unacceptable
behavior to [coc@electronjs.org](mailto:coc@electronjs.org).
@@ -97,6 +97,6 @@ and more can be found in the [support document](docs/tutorial/support.md#finding
## License
[MIT](https://github.com/electron/electron/blob/master/LICENSE)
[MIT](https://github.com/electron/electron/blob/main/LICENSE)
When using the Electron or other GitHub logos, be sure to follow the [GitHub logo guidelines](https://github.com/logos).

View File

@@ -10,7 +10,7 @@ Report security bugs in third-party modules to the person or team maintaining th
## The Electron Security Notification Process
For context on Electron's security notification process, please see the [Notifications](https://github.com/electron/governance/blob/master/wg-security/membership-and-notifications.md#notifications) section of the Security WG's [Membership and Notifications](https://github.com/electron/governance/blob/master/wg-security/membership-and-notifications.md) Governance document.
For context on Electron's security notification process, please see the [Notifications](https://github.com/electron/governance/blob/main/wg-security/membership-and-notifications.md#notifications) section of the Security WG's [Membership and Notifications](https://github.com/electron/governance/blob/main/wg-security/membership-and-notifications.md) Governance document.
## Learning More About Security

View File

@@ -212,6 +212,7 @@ static_library("chrome") {
"//components/services/print_compositor",
"//components/services/print_compositor/public/cpp",
"//components/services/print_compositor/public/mojom",
"//printing/backend",
]
deps += [

View File

@@ -483,6 +483,7 @@ Returns:
* `event` Event
* `argv` String[] - An array of the second instance's command line arguments
* `workingDirectory` String - The second instance's working directory
* `additionalData` unknown - A JSON object of additional data passed from the second instance
This event will be emitted inside the primary instance of your application
when a second instance has been executed and calls `app.requestSingleInstanceLock()`.
@@ -941,6 +942,8 @@ app.setJumpList([
### `app.requestSingleInstanceLock()`
* `additionalData` unknown (optional) - A JSON object containing additional data to send to the first instance.
Returns `Boolean`
The return value of this method indicates whether or not this instance of your
@@ -966,12 +969,16 @@ starts:
const { app } = require('electron')
let myWindow = null
const gotTheLock = app.requestSingleInstanceLock()
const additionalData = { myKey: 'myValue' }
const gotTheLock = app.requestSingleInstanceLock(additionalData)
if (!gotTheLock) {
app.quit()
} else {
app.on('second-instance', (event, commandLine, workingDirectory) => {
app.on('second-instance', (event, commandLine, workingDirectory, additionalData) => {
// Print out data received from the second instance.
console.log(additionalData)
// Someone tried to run a second instance, we should focus our window.
if (myWindow) {
if (myWindow.isMinimized()) myWindow.restore()
@@ -1072,7 +1079,7 @@ indicates success while any other value indicates failure according to Chromium
Linux.
* `secureDnsMode` String (optional) - Can be "off", "automatic" or "secure".
Configures the DNS-over-HTTP mode. When "off", no DoH lookups will be
performed. When "automatic", DoH lookups will be peformed first if DoH is
performed. When "automatic", DoH lookups will be performed first if DoH is
available, and insecure DNS lookups will be performed as a fallback. When
"secure", only DoH lookups will be performed. Defaults to "automatic".
* `secureDnsServers` String[]&#32;(optional) - A list of DNS-over-HTTP

View File

@@ -17,10 +17,11 @@ win.loadURL('https://github.com')
win.loadFile('index.html')
```
## Frameless window
## Window customization
To create a window without chrome, or a transparent window in arbitrary shape,
you can use the [Frameless Window](frameless-window.md) API.
The `BrowserWindow` class exposes various ways to modify the look and behavior of
your app's windows. For more details, see the [Window Customization](../tutorial/window-customization.md)
tutorial.
## Showing the window gracefully
@@ -184,7 +185,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
`true`.
* `paintWhenInitiallyHidden` Boolean (optional) - Whether the renderer should be active when `show` is `false` and it has just been created. In order for `document.visibilityState` to work correctly on first load with `show: false` you should set this to `false`. Setting this to `false` will cause the `ready-to-show` event to not fire. Default is `true`.
* `frame` Boolean (optional) - Specify `false` to create a
[Frameless Window](frameless-window.md). Default is `true`.
[frameless window](../tutorial/window-customization.md#create-frameless-windows). Default is `true`.
* `parent` BrowserWindow (optional) - Specify parent window. Default is `null`.
* `modal` Boolean (optional) - Whether this is a modal window. This only works when the
window is a child window. Default is `false`.
@@ -206,7 +207,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
transparent) and 1.0 (fully opaque). This is only implemented on Windows and macOS.
* `darkTheme` Boolean (optional) - Forces using dark theme for the window, only works on
some GTK+3 desktop environments. Default is `false`.
* `transparent` Boolean (optional) - Makes the window [transparent](frameless-window.md#transparent-window).
* `transparent` Boolean (optional) - Makes the window [transparent](../tutorial/window-customization.md#create-transparent-windows).
Default is `false`. On Windows, does not work unless the window is frameless.
* `type` String (optional) - The type of window, default is normal window. See more about
this below.

View File

@@ -53,3 +53,12 @@ Returns `Boolean` - Whether the command-line switch is present.
Returns `String` - The command-line switch value.
**Note:** When the switch is not present or has no value, it returns empty string.
#### `commandLine.removeSwitch(switch)`
* `switch` String - A command-line switch
Removes the specified switch from Chromium's command line.
**Note:** This will not affect `process.argv`. The intended usage of this function is to
control Chromium's behavior.

View File

@@ -234,6 +234,7 @@ expanding and collapsing the dialog.
* `title` String (optional) - Title of the message box, some platforms will not show it.
* `detail` String (optional) - Extra information of the message.
* `icon` ([NativeImage](native-image.md) | String) (optional)
* `textWidth` Integer (optional) _macOS_ - Custom width of the text in the message box.
* `cancelId` Integer (optional) - The index of the button to be used to cancel the dialog, via
the `Esc` key. By default this is assigned to the first button with "cancel" or "no" as the
label. If no such labeled buttons exist and this option is not set, `0` will be used as the
@@ -285,6 +286,7 @@ If `browserWindow` is not shown dialog will not be attached to it. In such case
* `checkboxChecked` Boolean (optional) - Initial checked state of the
checkbox. `false` by default.
* `icon` [NativeImage](native-image.md) (optional)
* `textWidth` Integer (optional) _macOS_ - Custom width of the text in the message box.
* `cancelId` Integer (optional) - The index of the button to be used to cancel the dialog, via
the `Esc` key. By default this is assigned to the first button with "cancel" or "no" as the
label. If no such labeled buttons exist and this option is not set, `0` will be used as the

View File

@@ -1,221 +0,0 @@
# Frameless Window
> Open a window without toolbars, borders, or other graphical "chrome".
A frameless window is a window that has no
[chrome](https://developer.mozilla.org/en-US/docs/Glossary/Chrome), the parts of
the window, like toolbars, that are not a part of the web page. These are
options on the [`BrowserWindow`](browser-window.md) class.
## Create a frameless window
To create a frameless window, you need to set `frame` to `false` in
[BrowserWindow](browser-window.md)'s `options`:
```javascript
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ width: 800, height: 600, frame: false })
win.show()
```
### Alternatives
There's an alternative way to specify a chromeless window on macOS and Windows.
Instead of setting `frame` to `false` which disables both the titlebar and window controls,
you may want to have the title bar hidden and your content extend to the full window size,
yet still preserve the window controls ("traffic lights" on macOS) for standard window actions.
You can do so by specifying the `titleBarStyle` option:
#### `hidden`
Results in a hidden title bar and a full size content window. On macOS, the title bar still has the standard window controls (“traffic lights”) in the top left.
```javascript
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hidden' })
win.show()
```
### Alternatives on macOS
#### `hiddenInset`
Results in a hidden title bar with an alternative look where the traffic light buttons are slightly more inset from the window edge.
```javascript
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hiddenInset' })
win.show()
```
#### `customButtonsOnHover`
Uses custom drawn close, and miniaturize buttons that display
when hovering in the top left of the window. The fullscreen button
is not available due to restrictions of frameless windows as they
interface with Apple's macOS window masks. These custom buttons prevent
issues with mouse events that occur with the standard window toolbar buttons.
This option is only applicable for frameless windows.
```javascript
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'customButtonsOnHover', frame: false })
win.show()
```
## Windows Control Overlay
When using a frameless window in conjuction with `win.setWindowButtonVisibility(true)` on macOS, using one of the `titleBarStyle`s as described above so
that the traffic lights are visible, or using `titleBarStyle: hidden` on Windows, you can access the Window Controls Overlay [JavaScript APIs][overlay-javascript-apis] and
[CSS Environment Variables][overlay-css-env-vars] by setting the `titleBarOverlay` option to true. Specifying `true` will result in an overlay with default system colors.
On Windows, you can also specify the color of the overlay and its symbols by setting `titleBarOverlay` to an object with the options `color` and `symbolColor`. If an option is not specified, the color will default to its system color for the window control buttons:
```javascript
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: true
})
win.show()
```
```javascript
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: {
color: '#2f3241',
symbolColor: '#74b1be'
}
})
win.show()
```
## Transparent window
By setting the `transparent` option to `true`, you can also make the frameless
window transparent:
```javascript
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ transparent: true, frame: false })
win.show()
```
### Limitations
* You can not click through the transparent area. We are going to introduce an
API to set window shape to solve this, see
[our issue](https://github.com/electron/electron/issues/1335) for details.
* Transparent windows are not resizable. Setting `resizable` to `true` may make
a transparent window stop working on some platforms.
* The `blur` filter only applies to the web page, so there is no way to apply
blur effect to the content below the window (i.e. other applications open on
the user's system).
* The window will not be transparent when DevTools is opened.
* On Windows operating systems,
* transparent windows will not work when DWM is
disabled.
* transparent windows can not be maximized using the Windows system menu or by double clicking the title bar. The reasoning behind this can be seen on [this pull request](https://github.com/electron/electron/pull/28207).
* On Linux, users have to put `--enable-transparent-visuals --disable-gpu` in
the command line to disable GPU and allow ARGB to make transparent window,
this is caused by an upstream bug that [alpha channel doesn't work on some
NVidia drivers](https://bugs.chromium.org/p/chromium/issues/detail?id=369209) on
Linux.
* On Mac, the native window shadow will not be shown on a transparent window.
## Click-through window
To create a click-through window, i.e. making the window ignore all mouse
events, you can call the [win.setIgnoreMouseEvents(ignore)][ignore-mouse-events]
API:
```javascript
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.setIgnoreMouseEvents(true)
```
### Forwarding
Ignoring mouse messages makes the web page oblivious to mouse movement, meaning
that mouse movement events will not be emitted. On Windows operating systems an
optional parameter can be used to forward mouse move messages to the web page,
allowing events such as `mouseleave` to be emitted:
```javascript
const { ipcRenderer } = require('electron')
const el = document.getElementById('clickThroughElement')
el.addEventListener('mouseenter', () => {
ipcRenderer.send('set-ignore-mouse-events', true, { forward: true })
})
el.addEventListener('mouseleave', () => {
ipcRenderer.send('set-ignore-mouse-events', false)
})
// Main process
const { ipcMain } = require('electron')
ipcMain.on('set-ignore-mouse-events', (event, ...args) => {
BrowserWindow.fromWebContents(event.sender).setIgnoreMouseEvents(...args)
})
```
This makes the web page click-through when over `el`, and returns to normal
outside it.
## Draggable region
By default, the frameless window is non-draggable. Apps need to specify
`-webkit-app-region: drag` in CSS to tell Electron which regions are draggable
(like the OS's standard titlebar), and apps can also use
`-webkit-app-region: no-drag` to exclude the non-draggable area from the
draggable region. Note that only rectangular shapes are currently supported.
Note: `-webkit-app-region: drag` is known to have problems while the developer tools are open. See this [GitHub issue](https://github.com/electron/electron/issues/3647) for more information including a workaround.
To make the whole window draggable, you can add `-webkit-app-region: drag` as
`body`'s style:
```html
<body style="-webkit-app-region: drag">
</body>
```
And note that if you have made the whole window draggable, you must also mark
buttons as non-draggable, otherwise it would be impossible for users to click on
them:
```css
button {
-webkit-app-region: no-drag;
}
```
If you're only setting a custom titlebar as draggable, you also need to make all
buttons in titlebar non-draggable.
## Text selection
In a frameless window the dragging behavior may conflict with selecting text.
For example, when you drag the titlebar you may accidentally select the text on
the titlebar. To prevent this, you need to disable text selection within a
draggable area like this:
```css
.titlebar {
-webkit-user-select: none;
-webkit-app-region: drag;
}
```
## Context menu
On some platforms, the draggable area will be treated as a non-client frame, so
when you right click on it a system menu will pop up. To make the context menu
behave correctly on all platforms you should never use a custom context menu on
draggable areas.
[ignore-mouse-events]: browser-window.md#winsetignoremouseeventsignore-options
[overlay-javascript-apis]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#javascript-apis
[overlay-css-env-vars]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#css-environment-variables

View File

@@ -180,6 +180,96 @@ Emitted when a hunspell dictionary file download fails. For details
on the failure you should collect a netlog and inspect the download
request.
#### Event: 'select-hid-device'
Returns:
* `event` Event
* `details` Object
* `deviceList` [HIDDevice[]](structures/hid-device.md)
* `frame` [WebFrameMain](web-frame-main.md)
* `callback` Function
* `deviceId` String | null (optional)
Emitted when a HID device needs to be selected when a call to
`navigator.hid.requestDevice` is made. `callback` should be called with
`deviceId` to be selected; passing no arguments to `callback` will
cancel the request. Additionally, permissioning on `navigator.hid` can
be further managed by using [ses.setPermissionCheckHandler(handler)](#sessetpermissioncheckhandlerhandler)
and [ses.setDevicePermissionHandler(handler)`](#sessetdevicepermissionhandlerhandler).
```javascript
const { app, BrowserWindow } = require('electron')
let win = null
app.whenReady().then(() => {
win = new BrowserWindow()
win.webContents.session.setPermissionCheckHandler((webContents, permission, requestingOrigin, details) => {
if (permission === 'hid') {
// Add logic here to determine if permission should be given to allow HID selection
return true
}
return false
})
// Optionally, retrieve previously persisted devices from a persistent store
const grantedDevices = fetchGrantedDevices()
win.webContents.session.setDevicePermissionHandler((details) => {
if (new URL(details.origin).hostname === 'some-host' && details.deviceType === 'hid') {
if (details.device.vendorId === 123 && details.device.productId === 345) {
// Always allow this type of device (this allows skipping the call to `navigator.hid.requestDevice` first)
return true
}
// Search through the list of devices that have previously been granted permission
return grantedDevices.some((grantedDevice) => {
return grantedDevice.vendorId === details.device.vendorId &&
grantedDevice.productId === details.device.productId &&
grantedDevice.serialNumber && grantedDevice.serialNumber === details.device.serialNumber
})
}
return false
})
win.webContents.session.on('select-hid-device', (event, details, callback) => {
event.preventDefault()
const selectedDevice = details.deviceList.find((device) => {
return device.vendorId === '9025' && device.productId === '67'
})
callback(selectedPort?.deviceId)
})
})
```
#### Event: 'hid-device-added'
Returns:
* `event` Event
* `details` Object
* `device` [HIDDevice[]](structures/hid-device.md)
* `frame` [WebFrameMain](web-frame-main.md)
Emitted when a new HID device becomes available. For example, when a new USB device is plugged in.
This event will only be emitted after `navigator.hid.requestDevice` has been called and `select-hid-device` has fired.
#### Event: 'hid-device-removed'
Returns:
* `event` Event
* `details` Object
* `device` [HIDDevice[]](structures/hid-device.md)
* `frame` [WebFrameMain](web-frame-main.md)
Emitted when a HID device has been removed. For example, this event will fire when a USB device is unplugged.
This event will only be emitted after `navigator.hid.requestDevice` has been called and `select-hid-device` has fired.
#### Event: 'select-serial-port'
Returns:
@@ -207,6 +297,35 @@ app.whenReady().then(() => {
width: 800,
height: 600
})
win.webContents.session.setPermissionCheckHandler((webContents, permission, requestingOrigin, details) => {
if (permission === 'serial') {
// Add logic here to determine if permission should be given to allow serial selection
return true
}
return false
})
// Optionally, retrieve previously persisted devices from a persistent store
const grantedDevices = fetchGrantedDevices()
win.webContents.session.setDevicePermissionHandler((details) => {
if (new URL(details.origin).hostname === 'some-host' && details.deviceType === 'serial') {
if (details.device.vendorId === 123 && details.device.productId === 345) {
// Always allow this type of device (this allows skipping the call to `navigator.serial.requestPort` first)
return true
}
// Search through the list of devices that have previously been granted permission
return grantedDevices.some((grantedDevice) => {
return grantedDevice.vendorId === details.device.vendorId &&
grantedDevice.productId === details.device.productId &&
grantedDevice.serialNumber && grantedDevice.serialNumber === details.device.serialNumber
})
}
return false
})
win.webContents.session.on('select-serial-port', (event, portList, webContents, callback) => {
event.preventDefault()
const selectedPort = portList.find((device) => {
@@ -499,6 +618,7 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
* `permissionGranted` Boolean - Allow or deny the permission.
* `details` Object - Some properties are only available on certain permission types.
* `externalURL` String (optional) - The url of the `openExternal` request.
* `securityOrigin` String (optional) - The security origin of the `media` request.
* `mediaTypes` String[] (optional) - The types of media access being requested, elements can be `video`
or `audio`
* `requestingUrl` String - The last URL the requesting frame loaded
@@ -525,7 +645,7 @@ session.fromPartition('some-partition').setPermissionRequestHandler((webContents
* `handler` Function\<Boolean> | null
* `webContents` ([WebContents](web-contents.md) | null) - WebContents checking the permission. Please note that if the request comes from a subframe you should use `requestingUrl` to check the request origin. All cross origin sub frames making permission checks will pass a `null` webContents to this handler, while certain other permission checks such as `notifications` checks will always pass `null`. You should use `embeddingOrigin` and `requestingOrigin` to determine what origin the owning frame and the requesting frame are on respectively.
* `permission` String - Type of permission check. Valid values are `midiSysex`, `notifications`, `geolocation`, `media`,`mediaKeySystem`,`midi`, `pointerLock`, `fullscreen`, `openExternal`, or `serial`.
* `permission` String - Type of permission check. Valid values are `midiSysex`, `notifications`, `geolocation`, `media`,`mediaKeySystem`,`midi`, `pointerLock`, `fullscreen`, `openExternal`, `hid`, or `serial`.
* `requestingOrigin` String - The origin URL of the permission check
* `details` Object - Some properties are only available on certain permission types.
* `embeddingOrigin` String (optional) - The origin of the frame embedding the frame that made the permission check. Only set for cross-origin sub frames making permission checks.
@@ -553,6 +673,78 @@ session.fromPartition('some-partition').setPermissionCheckHandler((webContents,
})
```
#### `ses.setDevicePermissionHandler(handler)`
* `handler` Function\<Boolean> | null
* `details` Object
* `deviceType` String - The type of device that permission is being requested on, can be `hid` or `serial`.
* `origin` String - The origin URL of the device permission check.
* `device` [HIDDevice](structures/hid-device.md) | [SerialPort](structures/serial-port.md)- the device that permission is being requested for.
* `frame` [WebFrameMain](web-frame-main.md) - WebFrameMain checking the device permission.
Sets the handler which can be used to respond to device permission checks for the `session`.
Returning `true` will allow the device to be permitted and `false` will reject it.
To clear the handler, call `setDevicePermissionHandler(null)`.
This handler can be used to provide default permissioning to devices without first calling for permission
to devices (eg via `navigator.hid.requestDevice`). If this handler is not defined, the default device
permissions as granted through device selection (eg via `navigator.hid.requestDevice`) will be used.
Additionally, the default behavior of Electron is to store granted device permision through the lifetime
of the corresponding WebContents. If longer term storage is needed, a developer can store granted device
permissions (eg when handling the `select-hid-device` event) and then read from that storage with `setDevicePermissionHandler`.
```javascript
const { app, BrowserWindow } = require('electron')
let win = null
app.whenReady().then(() => {
win = new BrowserWindow()
win.webContents.session.setPermissionCheckHandler((webContents, permission, requestingOrigin, details) => {
if (permission === 'hid') {
// Add logic here to determine if permission should be given to allow HID selection
return true
} else if (permission === 'serial') {
// Add logic here to determine if permission should be given to allow serial port selection
}
return false
})
// Optionally, retrieve previously persisted devices from a persistent store
const grantedDevices = fetchGrantedDevices()
win.webContents.session.setDevicePermissionHandler((details) => {
if (new URL(details.origin).hostname === 'some-host' && details.deviceType === 'hid') {
if (details.device.vendorId === 123 && details.device.productId === 345) {
// Always allow this type of device (this allows skipping the call to `navigator.hid.requestDevice` first)
return true
}
// Search through the list of devices that have previously been granted permission
return grantedDevices.some((grantedDevice) => {
return grantedDevice.vendorId === details.device.vendorId &&
grantedDevice.productId === details.device.productId &&
grantedDevice.serialNumber && grantedDevice.serialNumber === details.device.serialNumber
})
} else if (details.deviceType === 'serial') {
if (details.device.vendorId === 123 && details.device.productId === 345) {
// Always allow this type of device (this allows skipping the call to `navigator.hid.requestDevice` first)
return true
}
}
return false
})
win.webContents.session.on('select-hid-device', (event, details, callback) => {
event.preventDefault()
const selectedDevice = details.deviceList.find((device) => {
return device.vendorId === '9025' && device.productId === '67'
})
callback(selectedPort?.deviceId)
})
})
```
#### `ses.clearHostResolverCache()`
Returns `Promise<void>` - Resolves when the operation is complete.

View File

@@ -0,0 +1,8 @@
# HIDDevice Object
* `deviceId` String - Unique identifier for the device.
* `name` String - Name of the device.
* `vendorId` Integer - The USB vendor ID.
* `productId` Integer - The USB product ID.
* `serialNumber` String (optional) - The USB device serial number.
* `guid` String (optional) - Unique identifier for the HID interface. A device may have multiple HID interfaces.

View File

@@ -1494,8 +1494,8 @@ win.loadURL('http://github.com')
win.webContents.on('did-finish-load', () => {
// Use default printing options
const pdfPath = path.join(os.homedir(), 'Desktop', 'temp.pdf')
win.webContents.printToPDF({}).then(data => {
const pdfPath = path.join(os.homedir(), 'Desktop', 'temp.pdf')
fs.writeFile(pdfPath, data, (error) => {
if (error) throw error
console.log(`Wrote PDF successfully to ${pdfPath}`)
@@ -1827,7 +1827,8 @@ End subscribing for frame presentation events.
#### `contents.startDrag(item)`
* `item` Object
* `file` String[] | String - The path(s) to the file(s) being dragged.
* `file` String - The path to the file being dragged.
* `files` String[] (optional) - The paths to the files being dragged. (`files` will override `file` field)
* `icon` [NativeImage](native-image.md) | String - The image must be
non-empty on macOS.

View File

@@ -1025,3 +1025,78 @@ Emitted when DevTools is focused / opened.
[runtime-enabled-features]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5?l=70
[chrome-webview]: https://developer.chrome.com/docs/extensions/reference/webviewTag/
### Event: 'context-menu'
Returns:
* `params` Object
* `x` Integer - x coordinate.
* `y` Integer - y coordinate.
* `linkURL` String - URL of the link that encloses the node the context menu
was invoked on.
* `linkText` String - Text associated with the link. May be an empty
string if the contents of the link are an image.
* `pageURL` String - URL of the top level page that the context menu was
invoked on.
* `frameURL` String - URL of the subframe that the context menu was invoked
on.
* `srcURL` String - Source URL for the element that the context menu
was invoked on. Elements with source URLs are images, audio and video.
* `mediaType` String - Type of the node the context menu was invoked on. Can
be `none`, `image`, `audio`, `video`, `canvas`, `file` or `plugin`.
* `hasImageContents` Boolean - Whether the context menu was invoked on an image
which has non-empty contents.
* `isEditable` Boolean - Whether the context is editable.
* `selectionText` String - Text of the selection that the context menu was
invoked on.
* `titleText` String - Title text of the selection that the context menu was
invoked on.
* `altText` String - Alt text of the selection that the context menu was
invoked on.
* `suggestedFilename` String - Suggested filename to be used when saving file through 'Save
Link As' option of context menu.
* `selectionRect` [Rectangle](structures/rectangle.md) - Rect representing the coordinates in the document space of the selection.
* `selectionStartOffset` Number - Start position of the selection text.
* `referrerPolicy` [Referrer](structures/referrer.md) - The referrer policy of the frame on which the menu is invoked.
* `misspelledWord` String - The misspelled word under the cursor, if any.
* `dictionarySuggestions` String[] - An array of suggested words to show the
user to replace the `misspelledWord`. Only available if there is a misspelled
word and spellchecker is enabled.
* `frameCharset` String - The character encoding of the frame on which the
menu was invoked.
* `inputFieldType` String - If the context menu was invoked on an input
field, the type of that field. Possible values are `none`, `plainText`,
`password`, `other`.
* `spellcheckEnabled` Boolean - If the context is editable, whether or not spellchecking is enabled.
* `menuSourceType` String - Input source that invoked the context menu.
Can be `none`, `mouse`, `keyboard`, `touch`, `touchMenu`, `longPress`, `longTap`, `touchHandle`, `stylus`, `adjustSelection`, or `adjustSelectionReset`.
* `mediaFlags` Object - The flags for the media element the context menu was
invoked on.
* `inError` Boolean - Whether the media element has crashed.
* `isPaused` Boolean - Whether the media element is paused.
* `isMuted` Boolean - Whether the media element is muted.
* `hasAudio` Boolean - Whether the media element has audio.
* `isLooping` Boolean - Whether the media element is looping.
* `isControlsVisible` Boolean - Whether the media element's controls are
visible.
* `canToggleControls` Boolean - Whether the media element's controls are
toggleable.
* `canPrint` Boolean - Whether the media element can be printed.
* `canSave` Boolean - Whether or not the media element can be downloaded.
* `canShowPictureInPicture` Boolean - Whether the media element can show picture-in-picture.
* `isShowingPictureInPicture` Boolean - Whether the media element is currently showing picture-in-picture.
* `canRotate` Boolean - Whether the media element can be rotated.
* `canLoop` Boolean - Whether the media element can be looped.
* `editFlags` Object - These flags indicate whether the renderer believes it
is able to perform the corresponding action.
* `canUndo` Boolean - Whether the renderer believes it can undo.
* `canRedo` Boolean - Whether the renderer believes it can redo.
* `canCut` Boolean - Whether the renderer believes it can cut.
* `canCopy` Boolean - Whether the renderer believes it can copy.
* `canPaste` Boolean - Whether the renderer believes it can paste.
* `canDelete` Boolean - Whether the renderer believes it can delete.
* `canSelectAll` Boolean - Whether the renderer believes it can select all.
* `canEditRichly` Boolean - Whether the renderer believes it can edit text richly.
Emitted when there is a new context menu that needs to be handled.

View File

@@ -69,6 +69,18 @@ Electron apps.
See [here](#removed-desktopcapturergetsources-in-the-renderer) for details on
how to replace this API in your app.
## Planned Breaking API Changes (15.0)
### Default Changed: `nativeWindowOpen` defaults to `true`
Prior to Electron 15, `window.open` was by default shimmed to use
`BrowserWindowProxy`. This meant that `window.open('about:blank')` did not work
to open synchronously scriptable child windows, among other incompatibilities.
`nativeWindowOpen` is no longer experimental, and is now the default.
See the documentation for [window.open in Electron](api/window-open.md)
for more details.
## Planned Breaking API Changes (14.0)
### Removed: `remote` module
@@ -119,16 +131,6 @@ ensure your code works with this property enabled. It has been enabled by defau
You will be affected by this change if you use either `webFrame.executeJavaScript` or `webFrame.executeJavaScriptInIsolatedWorld`. You will need to ensure that values returned by either of those methods are supported by the [Context Bridge API](api/context-bridge.md#parameter--error--return-type-support) as these methods use the same value passing semantics.
### Default Changed: `nativeWindowOpen` defaults to `true`
Prior to Electron 14, `window.open` was by default shimmed to use
`BrowserWindowProxy`. This meant that `window.open('about:blank')` did not work
to open synchronously scriptable child windows, among other incompatibilities.
`nativeWindowOpen` is no longer experimental, and is now the default.
See the documentation for [window.open in Electron](api/window-open.md)
for more details.
### Removed: BrowserWindowConstructorOptions inheriting from parent windows
Prior to Electron 14, windows opened with `window.open` would inherit
@@ -632,7 +634,7 @@ error.
### API Changed: `shell.openItem` is now `shell.openPath`
The `shell.openItem` API has been replaced with an asynchronous `shell.openPath` API.
You can see the original API proposal and reasoning [here](https://github.com/electron/governance/blob/master/wg-api/spec-documents/shell-openitem.md).
You can see the original API proposal and reasoning [here](https://github.com/electron/governance/blob/main/wg-api/spec-documents/shell-openitem.md).
## Planned Breaking API Changes (8.0)

View File

@@ -4,8 +4,8 @@ These guides are intended for people working on the Electron project itself.
For guides on Electron app development, see
[/docs/README.md](../README.md#guides-and-tutorials).
* [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md)
* [Contributing to Electron](https://github.com/electron/electron/blob/master/CONTRIBUTING.md)
* [Code of Conduct](https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md)
* [Contributing to Electron](https://github.com/electron/electron/blob/main/CONTRIBUTING.md)
* [Issues](issues.md)
* [Pull Requests](pull-requests.md)
* [Documentation Styleguide](coding-style.md#documentation)

View File

@@ -8,7 +8,7 @@ Example Use Case:
* We need `VS15.9` and we have `VS15.7` installed; this would require us to update an Azure image.
1. Identify the image you wish to modify.
* In [appveyor.yml](https://github.com/electron/electron/blob/master/appveyor.yml), the image is identified by the property *image*.
* In [appveyor.yml](https://github.com/electron/electron/blob/main/appveyor.yml), the image is identified by the property *image*.
* The names used correspond to the *"images"* defined for a build cloud, eg the [libcc-20 cloud](https://windows-ci.electronjs.org/build-clouds/8).
* Find the image you wish to modify in the build cloud and make note of the **VHD Blob Path** for that image, which is the value for that corresponding key.
* You will need this URI path to copy into a new image.

View File

@@ -65,8 +65,8 @@ origin URLs.
$ cd src/electron
$ git remote remove origin
$ git remote add origin https://github.com/electron/electron
$ git checkout master
$ git branch --set-upstream-to=origin/master
$ git checkout main
$ git branch --set-upstream-to=origin/main
$ cd -
```

View File

@@ -26,7 +26,9 @@ you prefer a graphical interface.
* **.lldbinit**: Create or edit `~/.lldbinit` to allow Chromium code to be properly source-mapped.
```text
command script import ~/electron/src/tools/lldb/lldbinit.py
# e.g: ['~/electron/src/tools/lldb']
script sys.path[:0] = ['<...path/to/electron/src/tools/lldb>']
script import lldbinit
```
## Attaching to and Debugging Electron

View File

@@ -72,4 +72,4 @@ to try NW.js.
[nwjs]: https://nwjs.io/
[electron-modules]: https://www.npmjs.com/search?q=electron
[node-bindings]: https://github.com/electron/electron/tree/master/lib/common
[node-bindings]: https://github.com/electron/electron/tree/main/lib/common

View File

@@ -45,10 +45,10 @@ Once you've built the project locally, you're ready to start making changes!
### Step 3: Branch
To keep your development environment organized, create local branches to
hold your work. These should be branched directly off of the `master` branch.
hold your work. These should be branched directly off of the `main` branch.
```sh
$ git checkout -b my-branch -t upstream/master
$ git checkout -b my-branch -t upstream/main
```
## Making Changes
@@ -134,11 +134,11 @@ Once you have committed your changes, it is a good idea to use `git rebase`
```sh
$ git fetch upstream
$ git rebase upstream/master
$ git rebase upstream/main
```
This ensures that your working branch has the latest changes from `electron/electron`
master.
main.
### Step 7: Test
@@ -189,7 +189,7 @@ the requirements below.
Bug fixes and new features should include tests and possibly benchmarks.
Contributors guide: https://github.com/electron/electron/blob/master/CONTRIBUTING.md
Contributors guide: https://github.com/electron/electron/blob/main/CONTRIBUTING.md
-->
```
@@ -222,7 +222,7 @@ seem unfamiliar, refer to this
#### Approval and Request Changes Workflow
All pull requests require approval from a
[Code Owner](https://github.com/electron/electron/blob/master/.github/CODEOWNERS)
[Code Owner](https://github.com/electron/electron/blob/main/.github/CODEOWNERS)
of the area you modified in order to land. Whenever a maintainer reviews a pull
request they may request changes. These may be small, such as fixing a typo, or
may involve substantive changes. Such requests are intended to be helpful, but

View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Web Bluetooth API</title>
</head>
<body>
<h1>Web Bluetooth API</h1>
<button id="clickme">Test Bluetooth</button>
<p>Currently selected bluetooth device: <strong id="device-name""></strong></p>
<script src="./renderer.js"></script>
</body>
</html>

View File

@@ -0,0 +1,30 @@
const {app, BrowserWindow} = require('electron')
const path = require('path')
function createWindow () {
const mainWindow = new BrowserWindow({
width: 800,
height: 600
})
mainWindow.webContents.on('select-bluetooth-device', (event, deviceList, callback) => {
event.preventDefault()
if (deviceList && deviceList.length > 0) {
callback(deviceList[0].deviceId)
}
})
mainWindow.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})

View File

@@ -0,0 +1,8 @@
async function testIt() {
const device = await navigator.bluetooth.requestDevice({
acceptAllDevices: true
})
document.getElementById('device-name').innerHTML = device.name || `ID: ${device.id}`
}
document.getElementById('clickme').addEventListener('click',testIt)

View File

@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>WebHID API</title>
</head>
<body>
<h1>WebHID API</h1>
<button id="clickme">Test WebHID</button>
<h3>HID devices automatically granted access via <i>setDevicePermissionHandler</i></h3>
<div id="granted-devices"></div>
<h3>HID devices automatically granted access via <i>select-hid-device</i></h3>
<div id="granted-devices2"></div>
<script src="./renderer.js"></script>
</body>
</html>

View File

@@ -0,0 +1,50 @@
const {app, BrowserWindow} = require('electron')
const path = require('path')
function createWindow () {
const mainWindow = new BrowserWindow({
width: 800,
height: 600
})
mainWindow.webContents.session.on('select-hid-device', (event, details, callback) => {
event.preventDefault()
if (details.deviceList && details.deviceList.length > 0) {
callback(details.deviceList[0].deviceId)
}
})
mainWindow.webContents.session.on('hid-device-added', (event, device) => {
console.log('hid-device-added FIRED WITH', device)
})
mainWindow.webContents.session.on('hid-device-removed', (event, device) => {
console.log('hid-device-removed FIRED WITH', device)
})
mainWindow.webContents.session.setPermissionCheckHandler((webContents, permission, requestingOrigin, details) => {
if (permission === 'hid' && details.securityOrigin === 'file:///') {
return true
}
})
mainWindow.webContents.session.setDevicePermissionHandler((details) => {
if (details.deviceType === 'hid' && details.origin === 'file://') {
return true
}
})
mainWindow.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})

View File

@@ -0,0 +1,19 @@
async function testIt() {
const grantedDevices = await navigator.hid.getDevices()
let grantedDeviceList = ''
grantedDevices.forEach(device => {
grantedDeviceList += `<hr>${device.productName}</hr>`
})
document.getElementById('granted-devices').innerHTML = grantedDeviceList
const grantedDevices2 = await navigator.hid.requestDevice({
filters: []
})
grantedDeviceList = ''
grantedDevices2.forEach(device => {
grantedDeviceList += `<hr>${device.productName}</hr>`
})
document.getElementById('granted-devices2').innerHTML = grantedDeviceList
}
document.getElementById('clickme').addEventListener('click',testIt)

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Web Serial API</title>
<body>
<h1>Web Serial API</h1>
<button id="clickme">Test Web Serial API</button>
<p>Matching Arduino Uno device: <strong id="device-name""></strong></p>
<script src="./renderer.js"></script>
</body>
</html>

View File

@@ -0,0 +1,54 @@
const {app, BrowserWindow} = require('electron')
const path = require('path')
function createWindow () {
const mainWindow = new BrowserWindow({
width: 800,
height: 600
})
mainWindow.webContents.session.on('select-serial-port', (event, portList, webContents, callback) => {
event.preventDefault()
if (portList && portList.length > 0) {
callback(portList[0].portId)
} else {
callback('') //Could not find any matching devices
}
})
mainWindow.webContents.session.on('serial-port-added', (event, port) => {
console.log('serial-port-added FIRED WITH', port)
})
mainWindow.webContents.session.on('serial-port-removed', (event, port) => {
console.log('serial-port-removed FIRED WITH', port)
})
mainWindow.webContents.session.setPermissionCheckHandler((webContents, permission, requestingOrigin, details) => {
if (permission === 'serial' && details.securityOrigin === 'file:///') {
return true
}
})
mainWindow.webContents.session.setDevicePermissionHandler((details) => {
if (details.deviceType === 'serial' && details.origin === 'file://') {
return true
}
})
mainWindow.loadFile('index.html')
mainWindow.webContents.openDevTools()
}
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})

View File

@@ -0,0 +1,19 @@
async function testIt() {
const filters = [
{ usbVendorId: 0x2341, usbProductId: 0x0043 },
{ usbVendorId: 0x2341, usbProductId: 0x0001 }
];
try {
const port = await navigator.serial.requestPort({filters});
const portInfo = port.getInfo();
document.getElementById('device-name').innerHTML = `vendorId: ${portInfo.usbVendorId} | productId: ${portInfo.usbProductId} `
} catch (ex) {
if (ex.name === 'NotFoundError') {
document.getElementById('device-name').innerHTML = 'Device NOT found'
} else {
document.getElementById('device-name').innerHTML = ex
}
}
}
document.getElementById('clickme').addEventListener('click',testIt)

View File

@@ -1,5 +1,5 @@
// Modules to control application life and create native browser window
const { app, BrowserWindow, ipcMain, shell } = require('electron')
const { app, BrowserWindow, ipcMain, shell, dialog } = require('electron')
const path = require('path')
let mainWindow;

View File

@@ -59,8 +59,9 @@
<p>
For more details, see the
<a href="https://electronjs.org/docs/api/frameless-window/">
Frameless Window
<a href="https://electronjs.org/docs/tutorial/window-customization/">
Window Customization
</a>
documentation.
</p>

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

108
docs/tutorial/devices.md Normal file
View File

@@ -0,0 +1,108 @@
# Device Access
Like Chromium based browsers, Electron provides access to device hardware
through web APIs. For the most part these APIs work like they do in a browser,
but there are some differences that need to be taken into account. The primary
difference between Electron and browsers is what happens when device access is
requested. In a browser, users are presented with a popup where they can grant
access to an individual device. In Electron APIs are provided which can be
used by a developer to either automatically pick a device or prompt users to
pick a device via a developer created interface.
## Web Bluetooth API
The [Web Bluetooth API](https://web.dev/bluetooth/) can be used to communicate
with bluetooth devices. In order to use this API in Electron, developers will
need to handle the [`select-bluetooth-device` event on the webContents](../api/web-contents.md#event-select-bluetooth-device)
associated with the device request.
### Example
This example demonstrates an Electron application that automatically selects
the first available bluetooth device when the `Test Bluetooth` button is
clicked.
```javascript fiddle='docs/fiddles/features/web-bluetooth'
```
## WebHID API
The [WebHID API](https://web.dev/hid/) can be used to access HID devices such
as keyboards and gamepads. Electron provides several APIs for working with
the WebHID API:
* The [`select-hid-device` event on the Session](../api/session.md#event-select-hid-device)
can be used to select a HID device when a call to
`navigator.hid.requestDevice` is made. Additionally the [`hid-device-added`](../api/session.md#event-hid-device-added)
and [`hid-device-removed`](../api/session.md#event-hid-device-removed) events
on the Session can be used to handle devices being plugged in or unplugged during the
`navigator.hid.requestDevice` process.
* [`ses.setDevicePermissionHandler(handler)`](../api/session.md#sessetdevicepermissionhandlerhandler)
can be used to provide default permissioning to devices without first calling
for permission to devices via `navigator.hid.requestDevice`. Additionally,
the default behavior of Electron is to store granted device permision through
the lifetime of the corresponding WebContents. If longer term storage is
needed, a developer can store granted device permissions (eg when handling
the `select-hid-device` event) and then read from that storage with
`setDevicePermissionHandler`.
* [`ses.setPermissionCheckHandler(handler)`](../api/session.md#sessetpermissioncheckhandlerhandler)
can be used to disable HID access for specific origins.
### Blocklist
By default Electron employs the same [blocklist](https://github.com/WICG/webhid/blob/main/blocklist.txt)
used by Chromium. If you wish to override this behavior, you can do so by
setting the `disable-hid-blocklist` flag:
```javascript
app.commandLine.appendSwitch('disable-hid-blocklist')
```
### Example
This example demonstrates an Electron application that automatically selects
HID devices through [`ses.setDevicePermissionHandler(handler)`](../api/session.md#sessetdevicepermissionhandlerhandler)
and through [`select-hid-device` event on the Session](../api/session.md#event-select-hid-device)
when the `Test WebHID` button is clicked.
```javascript fiddle='docs/fiddles/features/web-hid'
```
## Web Serial API
The [Web Serial API](https://web.dev/serial/) can be used to access serial
devices that are connected via serial port, USB, or Bluetooth. In order to use
this API in Electron, developers will need to handle the
[`select-serial-port` event on the Session](../api/session.md#event-select-serial-port)
associated with the serial port request.
There are several additional APIs for working with the Web Serial API:
* The [`serial-port-added`](../api/session.md#event-serial-port-added)
and [`serial-port-removed`](../api/session.md#event-serial-port-removed) events
on the Session can be used to handle devices being plugged in or unplugged during the
`navigator.serial.requestPort` process.
* [`ses.setDevicePermissionHandler(handler)`](../api/session.md#sessetdevicepermissionhandlerhandler)
can be used to provide default permissioning to devices without first calling
for permission to devices via `navigator.serial.requestPort`. Additionally,
the default behavior of Electron is to store granted device permision through
the lifetime of the corresponding WebContents. If longer term storage is
needed, a developer can store granted device permissions (eg when handling
the `select-serial-port` event) and then read from that storage with
`setDevicePermissionHandler`.
* [`ses.setPermissionCheckHandler(handler)`](../api/session.md#sessetpermissioncheckhandlerhandler)
can be used to disable serial access for specific origins.
### Example
This example demonstrates an Electron application that automatically selects
serial devices through [`ses.setDevicePermissionHandler(handler)`](../api/session.md#sessetdevicepermissionhandlerhandler)
as well as demonstrating selecting the first available Arduino Uno serial device (if connected) through
[`select-serial-port` event on the Session](../api/session.md#event-select-serial-port)
when the `Test Web Serial` button is clicked.
```javascript fiddle='docs/fiddles/features/web-serial'
```

View File

@@ -2,43 +2,31 @@
> A detailed look at our versioning policy and implementation.
As of version 2.0.0, Electron follows [SemVer](#semver). The following command will install the most recent stable build of Electron:
As of version 2.0.0, Electron follows the [SemVer](#semver) spec. The following command will install the most recent stable build of Electron:
```sh
```sh npm2yarn
npm install --save-dev electron
```
To update an existing project to use the latest stable version:
```sh
```sh npm2yarn
npm install --save-dev electron@latest
```
## Version 1.x
Electron versions *< 2.0* did not conform to the [SemVer](https://semver.org) spec: major versions corresponded to end-user API changes, minor versions corresponded to Chromium major releases, and patch versions corresponded to new features and bug fixes. While convenient for developers merging features, it creates problems for developers of client-facing applications. The QA testing cycles of major apps like Slack, Stride, Teams, Skype, VS Code, Atom, and Desktop can be lengthy and stability is a highly desired outcome. There is a high risk in adopting new features while trying to absorb bug fixes.
Here is an example of the 1.x strategy:
![1.x Versioning](../images/versioning-sketch-0.png)
An app developed with `1.8.1` cannot take the `1.8.3` bug fix without either absorbing the `1.8.2` feature, or by backporting the fix and maintaining a new release line.
## Version 2.0 and Beyond
## Versioning scheme
There are several major changes from our 1.x strategy outlined below. Each change is intended to satisfy the needs and priorities of developers/maintainers and app developers.
1. Strict use of SemVer
1. Strict use of the the [SemVer](#semver) spec
2. Introduction of semver-compliant `-beta` tags
3. Introduction of [conventional commit messages](https://conventionalcommits.org/)
4. Well-defined stabilization branches
5. The `master` branch is versionless; only stabilization branches contain version information
5. The `main` branch is versionless; only stabilization branches contain version information
We will cover in detail how git branching works, how npm tagging works, what developers should expect to see, and how one can backport changes.
# SemVer
From 2.0 onward, Electron will follow SemVer.
## SemVer
Below is a table explicitly mapping types of changes to their corresponding category of SemVer (e.g. Major, Minor, Patch).
@@ -48,22 +36,25 @@ Below is a table explicitly mapping types of changes to their corresponding cate
| Node.js major version updates | Node.js minor version updates | Node.js patch version updates |
| Chromium version updates | | fix-related chromium patches |
For more information, see the [Semantic Versioning 2.0.0](https://semver.org/) spec.
Note that most Chromium updates will be considered breaking. Fixes that can be backported will likely be cherry-picked as patches.
# Stabilization Branches
## Stabilization branches
Stabilization branches are branches that run parallel to master, taking in only cherry-picked commits that are related to security or stability. These branches are never merged back to master.
Stabilization branches are branches that run parallel to `main`, taking in only cherry-picked commits that are related to security or stability. These branches are never merged back to `main`.
![Stabilization Branches](../images/versioning-sketch-1.png)
Since Electron 8, stabilization branches are always **major** version lines, and named against the following template `$MAJOR-x-y` e.g. `8-x-y`. Prior to that we used **minor** version lines and named them as `$MAJOR-$MINOR-x` e.g. `2-0-x`
Since Electron 8, stabilization branches are always **major** version lines, and named against the following template `$MAJOR-x-y` e.g. `8-x-y`. Prior to that we used **minor** version lines and named them as `$MAJOR-$MINOR-x` e.g. `2-0-x`.
We allow for multiple stabilization branches to exist simultaneously, one for each supported version. For more details on which versions are supported, see our [Electron Release Timelines](./electron-timelines.md) doc.
We allow for multiple stabilization branches to exist simultaneously, and intend to support at least two in parallel at all times, backporting security fixes as necessary.
![Multiple Stability Branches](../images/versioning-sketch-2.png)
Older lines will not be supported by GitHub, but other groups can take ownership and backport stability and security fixes on their own. We discourage this, but recognize that it makes life easier for many app developers.
Older lines will not be supported by the Electron project, but other groups can take ownership and backport stability and security fixes on their own. We discourage this, but recognize that it makes life easier for many app developers.
# Beta Releases and Bug Fixes
## Beta releases and bug fixes
Developers want to know which releases are _safe_ to use. Even seemingly innocent features can introduce regressions in complex applications. At the same time, locking to a fixed version is dangerous because youre ignoring security patches and bug fixes that may have come out since your version. Our goal is to allow the following standard semver ranges in `package.json` :
@@ -116,15 +107,7 @@ A few examples of how various SemVer ranges will pick up new releases:
![Semvers and Releases](../images/versioning-sketch-7.png)
# Missing Features: Alphas
Our strategy has a few tradeoffs, which for now we feel are appropriate. Most importantly that new features in master may take a while before reaching a stable release line. If you want to try a new feature immediately, you will have to build Electron yourself.
As a future consideration, we may introduce one or both of the following:
* alpha releases that have looser stability constraints to betas; for example it would be allowable to admit new features while a stability channel is in _alpha_
# Feature Flags
## Feature flags
Feature flags are a common practice in Chromium, and are well-established in the web-development ecosystem. In the context of Electron, a feature flag or **soft branch** must have the following properties:
@@ -132,20 +115,29 @@ Feature flags are a common practice in Chromium, and are well-established in the
* it completely segments new and old code paths; refactoring old code to support a new feature _violates_ the feature-flag contract
* feature flags are eventually removed after the feature is released
# Semantic Commits
## Semantic commits
We seek to increase clarity at all levels of the update and releases process. Starting with `2.0.0` we will require pull requests adhere to the [Conventional Commits](https://conventionalcommits.org/) spec, which can be summarized as follows:
All pull requests must adhere to the [Conventional Commits](https://conventionalcommits.org/) spec, which can be summarized as follows:
* Commits that would result in a SemVer **major** bump must start their body with `BREAKING CHANGE:`.
* Commits that would result in a SemVer **minor** bump must start with `feat:`.
* Commits that would result in a SemVer **patch** bump must start with `fix:`.
* We allow squashing of commits, provided that the squashed message adheres to the above message format.
* It is acceptable for some commits in a pull request to not include a semantic prefix, as long as the pull request title contains a meaningful encompassing semantic message.
The `electron/electron` repository also enforces squash merging, so you only need to make sure that your pull request has the correct title prefix.
# Versioned `master`
## Versioned `main` branch
* The `master` branch will always contain the next major version `X.0.0-nightly.DATE` in its `package.json`
* Release branches are never merged back to master
* Release branches _do_ contain the correct version in their `package.json`
* As soon as a release branch is cut for a major, master must be bumped to the next major. I.e. `master` is always versioned as the next theoretical release branch
* The `main` branch will always contain the next major version `X.0.0-nightly.DATE` in its `package.json`.
* Release branches are never merged back to `main`.
* Release branches _do_ contain the correct version in their `package.json`.
* As soon as a release branch is cut for a major, `main` must be bumped to the next major (i.e. `main` is always versioned as the next theoretical release branch).
## Historical versioning (Electron 1.X)
Electron versions *< 2.0* did not conform to the [SemVer](https://semver.org) spec: major versions corresponded to end-user API changes, minor versions corresponded to Chromium major releases, and patch versions corresponded to new features and bug fixes. While convenient for developers merging features, it creates problems for developers of client-facing applications. The QA testing cycles of major apps like Slack, Teams, Skype, VS Code, and GitHub Desktop can be lengthy and stability is a highly desired outcome. There is a high risk in adopting new features while trying to absorb bug fixes.
Here is an example of the 1.x strategy:
![1.x Versioning](../images/versioning-sketch-0.png)
An app developed with `1.8.1` cannot take the `1.8.3` bug fix without either absorbing the `1.8.2` feature, or by backporting the fix and maintaining a new release line.

View File

@@ -51,4 +51,4 @@ Somewhere in the Electron binary there will be a sequence of bytes that look lik
To flip a fuse you find its position in the fuse wire and change it to "0" or "1" depending on the state you'd like.
You can view the current schema [here](https://github.com/electron/electron/blob/master/build/fuses/fuses.json5).
You can view the current schema [here](https://github.com/electron/electron/blob/main/build/fuses/fuses.json5).

View File

@@ -17,7 +17,7 @@ the dirty area is passed to the `paint` event to be more efficient.
losses with no benefits.
* When nothing is happening on a webpage, no frames are generated.
* An offscreen window is always created as a
[Frameless Window](../api/frameless-window.md).
[Frameless Window](../tutorial/window-customization.md)..
### Rendering Modes

View File

@@ -7,7 +7,7 @@ without the need of switching to the window itself.
On Windows, you can use a taskbar button to display a progress bar.
![Windows Progress Bar][https://cloud.githubusercontent.com/assets/639601/5081682/16691fda-6f0e-11e4-9676-49b6418f1264.png]
![Windows Progress Bar](../images/windows-progress-bar.png)
On macOS, the progress bar will be displayed as a part of the dock icon.

View File

@@ -23,7 +23,7 @@ your responsibility to ensure that the code is not malicious.
## Reporting Security Issues
For information on how to properly disclose an Electron vulnerability,
see [SECURITY.md](https://github.com/electron/electron/tree/master/SECURITY.md)
see [SECURITY.md](https://github.com/electron/electron/tree/main/SECURITY.md)
## Chromium Security Issues and Upgrades

View File

@@ -3,7 +3,7 @@
## Finding Support
If you have a security concern,
please see the [security document](https://github.com/electron/electron/tree/master/SECURITY.md).
please see the [security document](https://github.com/electron/electron/tree/main/SECURITY.md).
If you're looking for programming help,
for answers to questions,
@@ -26,7 +26,7 @@ you can interact with the community in these locations:
* [`electron-pl`](https://electronpl.github.io) *(Poland)*
If you'd like to contribute to Electron,
see the [contributing document](https://github.com/electron/electron/blob/master/CONTRIBUTING.md).
see the [contributing document](https://github.com/electron/electron/blob/main/CONTRIBUTING.md).
If you've found a bug in a [supported version](#supported-versions) of Electron,
please report it with the [issue tracker](../development/issues.md).
@@ -50,15 +50,15 @@ as the 4.2.x series are supported. We only support the latest minor release
for each stable release series. This means that in the case of a security fix
6.1.x will receive the fix, but we will not release a new version of 6.0.x.
The latest stable release unilaterally receives all fixes from `master`,
The latest stable release unilaterally receives all fixes from `main`,
and the version prior to that receives the vast majority of those fixes
as time and bandwidth warrants. The oldest supported release line will receive
only security fixes directly.
All supported release lines will accept external pull requests to backport
fixes previously merged to `master`, though this may be on a case-by-case
fixes previously merged to `main`, though this may be on a case-by-case
basis for some older supported lines. All contested decisions around release
line backports will be resolved by the [Releases Working Group](https://github.com/electron/governance/tree/master/wg-releases) as an agenda item at their weekly meeting the week the backport PR is raised.
line backports will be resolved by the [Releases Working Group](https://github.com/electron/governance/tree/main/wg-releases) as an agenda item at their weekly meeting the week the backport PR is raised.
When an API is changed or removed in a way that breaks existing functionality, the
previous functionality will be supported for a minimum of two major versions when

View File

@@ -0,0 +1,271 @@
# Window Customization
The `BrowserWindow` module is the foundation of your Electron application, and it exposes
many APIs that can change the look and behavior of your browser windows. In this
tutorial, we will be going over the various use-cases for window customization on
macOS, Windows, and Linux.
## Create frameless windows
A frameless window is a window that has no [chrome]. Not to be confused with the Google
Chrome browser, window _chrome_ refers to the parts of the window (e.g. toolbars, controls)
that are not a part of the web page.
To create a frameless window, you need to set `frame` to `false` in the `BrowserWindow`
constructor.
```javascript title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ frame: false })
```
## Apply custom title bar styles _macOS_ _Windows_
Title bar styles allow you to hide most of a BrowserWindow's chrome while keeping the
system's native window controls intact and can be configured with the `titleBarStyle`
option in the `BrowserWindow` constructor.
Applying the `hidden` title bar style results in a hidden title bar and a full-size
content window.
```javascript title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hidden' })
```
### Control the traffic lights _macOS_
On macOS, applying the `hidden` title bar style will still expose the standard window
controls (“traffic lights”) in the top left.
#### Customize the look of your traffic lights _macOS_
The `customButtonsOnHover` title bar style will hide the traffic lights until you hover
over them. This is useful if you want to create custom traffic lights in your HTML but still
use the native UI to control the window.
```javascript
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'customButtonsOnHover' })
```
#### Customize the traffic light position _macOS_
To modify the position of the traffic light window controls, there are two configuration
options available.
Applying `hiddenInset` title bar style will shift the vertical inset of the traffic lights
by a fixed amount.
```javascript title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hiddenInset' })
```
If you need more granular control over the positioning of the traffic lights, you can pass
a set of coordinates to the `trafficLightPosition` option in the `BrowserWindow`
constructor.
```javascript title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
trafficLightPosition: { x: 10, y: 10 }
})
```
#### Show and hide the traffic lights programmatically _macOS_
You can also show and hide the traffic lights programmatically from the main process.
The `win.setWindowButtonVisibility` forces traffic lights to be show or hidden depending
on the value of its boolean parameter.
```javascript title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
// hides the traffic lights
win.setWindowButtonVisibility(false)
```
> Note: Given the number of APIs available, there are many ways of achieving this. For instance,
> combining `frame: false` with `win.setWindowButtonVisibility(true)` will yield the same
> layout outcome as setting `titleBarStyle: 'hidden'`.
## Window Controls Overlay _macOS_ _Windows_
The [Window Controls Overlay API] is a web standard that gives web apps the ability to
customize their title bar region when installed on desktop. Electron exposes this API
through the `BrowserWindow` constructor option `titleBarOverlay`.
This option only works whenever a custom `titlebarStyle` is applied on macOS or Windows.
When `titleBarOverlay` is enabled, the window controls become exposed in their default
position, and DOM elements cannot use the area underneath this region.
The `titleBarOverlay` option accepts two different value formats.
Specifying `true` on either platform will result in an overlay region with default
system colors:
```javascript title='main.js'
// on macOS or Windows
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: true
})
```
On Windows, you can also specify the color of the overlay and its symbols by setting
`titleBarOverlay` to an object with the `color` and `symbolColor` properties. If an option
is not specified, the color will default to its system color for the window control buttons:
```javascript title='main.js'
// on Windows
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: {
color: '#2f3241',
symbolColor: '#74b1be'
}
})
```
> Note: Once your title bar overlay is enabled from the main process, you can access the overlay's
> color and dimension values from a renderer using a set of readonly
> [JavaScript APIs][overlay-javascript-apis] and [CSS Environment Variables][overlay-css-env-vars].
## Create transparent windows
By setting the `transparent` option to `true`, you can make a fully transparent window.
```javascript title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ transparent: true })
```
### Limitations
* You cannot click through the transparent area. See
[#1335](https://github.com/electron/electron/issues/1335) for details.
* Transparent windows are not resizable. Setting `resizable` to `true` may make
a transparent window stop working on some platforms.
* The CSS [`blur()`] filter only applies to the window's web contents, so there is no way to apply
blur effect to the content below the window (i.e. other applications open on
the user's system).
* The window will not be transparent when DevTools is opened.
* On _Windows_:
* Transparent windows will not work when DWM is disabled.
* Transparent windows can not be maximized using the Windows system menu or by double
clicking the title bar. The reasoning behind this can be seen on
PR [#28207](https://github.com/electron/electron/pull/28207).
* On _macOS_:
* The native window shadow will not be shown on a transparent window.
## Create click-through windows
To create a click-through window, i.e. making the window ignore all mouse
events, you can call the [win.setIgnoreMouseEvents(ignore)][ignore-mouse-events]
API:
```javascript title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.setIgnoreMouseEvents(true)
```
### Forward mouse events _macOS_ _Windows_
Ignoring mouse messages makes the web contents oblivious to mouse movement,
meaning that mouse movement events will not be emitted. On Windows and macOS, an
optional parameter can be used to forward mouse move messages to the web page,
allowing events such as `mouseleave` to be emitted:
```javascript title='main.js'
const { BrowserWindow, ipcMain } = require('electron')
const path = require('path')
const win = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
ipcMain.on('set-ignore-mouse-events', (event, ...args) => {
const win = BrowserWindow.fromWebContents(event.sender)
win.setIgnoreMouseEvents(...args)
})
```
```javascript title='preload.js'
window.addEventListener('DOMContentLoaded', () => {
const el = document.getElementById('clickThroughElement')
el.addEventListener('mouseenter', () => {
ipcRenderer.send('set-ignore-mouse-events', true, { forward: true })
})
el.addEventListener('mouseleave', () => {
ipcRenderer.send('set-ignore-mouse-events', false)
})
})
```
This makes the web page click-through when over the `#clickThroughElement` element,
and returns to normal outside it.
## Set custom draggable region
By default, the frameless window is non-draggable. Apps need to specify
`-webkit-app-region: drag` in CSS to tell Electron which regions are draggable
(like the OS's standard titlebar), and apps can also use
`-webkit-app-region: no-drag` to exclude the non-draggable area from the
draggable region. Note that only rectangular shapes are currently supported.
To make the whole window draggable, you can add `-webkit-app-region: drag` as
`body`'s style:
```css title='styles.css'
body {
-webkit-app-region: drag;
}
```
And note that if you have made the whole window draggable, you must also mark
buttons as non-draggable, otherwise it would be impossible for users to click on
them:
```css title='styles.css'
button {
-webkit-app-region: no-drag;
}
```
If you're only setting a custom titlebar as draggable, you also need to make all
buttons in titlebar non-draggable.
### Tip: disable text selection
When creating a draggable region, the dragging behavior may conflict with text selection.
For example, when you drag the titlebar, you may accidentally select its text contents.
To prevent this, you need to disable text selection within a draggable area like this:
```css
.titlebar {
-webkit-user-select: none;
-webkit-app-region: drag;
}
```
### Tip: disable context menus
On some platforms, the draggable area will be treated as a non-client frame, so
when you right click on it, a system menu will pop up. To make the context menu
behave correctly on all platforms, you should never use a custom context menu on
draggable areas.
[`blur()`]: https://developer.mozilla.org/en-US/docs/Web/CSS/filter-function/blur()
[`BrowserWindow`]: ../api/browser-window.md
[chrome]: https://developer.mozilla.org/en-US/docs/Glossary/Chrome
[ignore-mouse-events]: ../api/browser-window.md#winsetignoremouseeventsignore-options
[overlay-css-env-vars]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#css-environment-variables
[overlay-javascript-apis]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#javascript-apis
[Window Controls Overlay API]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md

View File

@@ -125,5 +125,7 @@
</message>
<message name="IDS_BADGE_UNREAD_NOTIFICATIONS" desc="The accessibility text which will be read by a screen reader when there are notifcatications">
{UNREAD_NOTIFICATIONS, plural, =1 {1 Unread Notification} other {# Unread Notifications}}
</message>
</message>
<message name="IDS_HID_CHOOSER_ITEM_WITHOUT_NAME" desc="User option displaying the device IDs for a Human Interface Device (HID) without a device name.">
Unknown Device (<ph name="DEVICE_ID">$1<ex>1234:abcd</ex></ph>) </message>
</grit-part>

View File

@@ -23,7 +23,6 @@ auto_filenames = {
"docs/api/environment-variables.md",
"docs/api/extensions.md",
"docs/api/file-object.md",
"docs/api/frameless-window.md",
"docs/api/global-shortcut.md",
"docs/api/in-app-purchase.md",
"docs/api/incoming-message.md",
@@ -84,6 +83,7 @@ auto_filenames = {
"docs/api/structures/file-filter.md",
"docs/api/structures/file-path-with-headers.md",
"docs/api/structures/gpu-feature-status.md",
"docs/api/structures/hid-device.md",
"docs/api/structures/input-event.md",
"docs/api/structures/io-counters.md",
"docs/api/structures/ipc-main-event.md",

View File

@@ -387,6 +387,14 @@ filenames = {
"shell/browser/font/electron_font_access_delegate.h",
"shell/browser/font_defaults.cc",
"shell/browser/font_defaults.h",
"shell/browser/hid/electron_hid_delegate.cc",
"shell/browser/hid/electron_hid_delegate.h",
"shell/browser/hid/hid_chooser_context.cc",
"shell/browser/hid/hid_chooser_context.h",
"shell/browser/hid/hid_chooser_context_factory.cc",
"shell/browser/hid/hid_chooser_context_factory.h",
"shell/browser/hid/hid_chooser_controller.cc",
"shell/browser/hid/hid_chooser_controller.h",
"shell/browser/javascript_environment.cc",
"shell/browser/javascript_environment.h",
"shell/browser/lib/bluetooth_chooser.cc",

View File

@@ -39,7 +39,8 @@ Object.assign(app, {
hasSwitch: (theSwitch: string) => commandLine.hasSwitch(String(theSwitch)),
getSwitchValue: (theSwitch: string) => commandLine.getSwitchValue(String(theSwitch)),
appendSwitch: (theSwitch: string, value?: string) => commandLine.appendSwitch(String(theSwitch), typeof value === 'undefined' ? value : String(value)),
appendArgument: (arg: string) => commandLine.appendArgument(String(arg))
appendArgument: (arg: string) => commandLine.appendArgument(String(arg)),
removeSwitch: (theSwitch: string) => commandLine.removeSwitch(String(theSwitch))
} as Electron.CommandLine
});

View File

@@ -168,6 +168,7 @@ const messageBox = (sync: boolean, window: BrowserWindow | null, options?: Messa
defaultId = -1,
detail = '',
icon = null,
textWidth = 0,
noLink = false,
message = '',
title = '',
@@ -225,7 +226,8 @@ const messageBox = (sync: boolean, window: BrowserWindow | null, options?: Messa
detail,
checkboxLabel,
checkboxChecked,
icon
icon,
textWidth
};
if (sync) {

View File

@@ -593,6 +593,9 @@ WebContents.prototype._init = function () {
ipcMainInternal.emit(channel, event, ...args);
} else {
addReplyToEvent(event);
if (this.listenerCount('ipc-message-sync') === 0 && ipcMain.listenerCount(channel) === 0) {
console.warn(`WebContents #${this.id} called ipcRenderer.sendSync() with '${channel}' channel without listeners.`);
}
this.emit('ipc-message-sync', event, channel, ...args);
ipcMain.emit(channel, event, ...args);
}
@@ -666,9 +669,9 @@ WebContents.prototype._init = function () {
postBody
};
windowOpenOverriddenOptions = this._callWindowOpenHandler(event, details);
// if attempting to use this API with the deprecated window.open event,
// if attempting to use this API with the deprecated new-window event,
// windowOpenOverriddenOptions will always return null. This ensures
// short-term backwards compatibility until window.open is removed.
// short-term backwards compatibility until new-window is removed.
const parsedFeatures = parseFeatures(rawFeatures);
const overriddenFeatures: BrowserWindowConstructorOptions = {
...parsedFeatures.options,

View File

@@ -7,7 +7,11 @@ WebFrameMain.prototype.send = function (channel, ...args) {
throw new Error('Missing required channel argument');
}
return this._send(false /* internal */, channel, args);
try {
return this._send(false /* internal */, channel, args);
} catch (e) {
console.error('Error sending from webFrameMain: ', e);
}
};
WebFrameMain.prototype._sendInternal = function (channel, ...args) {
@@ -15,7 +19,11 @@ WebFrameMain.prototype._sendInternal = function (channel, ...args) {
throw new Error('Missing required channel argument');
}
return this._send(true /* internal */, channel, args);
try {
return this._send(true /* internal */, channel, args);
} catch (e) {
console.error('Error sending from webFrameMain: ', e);
}
};
WebFrameMain.prototype.postMessage = function (...args) {

View File

@@ -65,8 +65,13 @@ export function openGuestWindow ({ event, embedder, guest, referrer, disposition
// https://html.spec.whatwg.org/multipage/window-object.html#apis-for-creating-and-navigating-browsing-contexts-by-name
const existingWindow = getGuestWindowByFrameName(frameName);
if (existingWindow) {
existingWindow.loadURL(url);
return existingWindow;
if (existingWindow.isDestroyed() || existingWindow.webContents.isDestroyed()) {
// FIXME(t57ser): The webContents is destroyed for some reason, unregister the frame name
unregisterFrameName(frameName);
} else {
existingWindow.loadURL(url);
return existingWindow;
}
}
const window = new BrowserWindow({

View File

@@ -38,6 +38,10 @@ ipcMainInternal.handle(IPC_MESSAGES.BROWSER_GET_LAST_WEB_PREFERENCES, function (
return event.sender.getLastWebPreferences();
});
ipcMainInternal.handle(IPC_MESSAGES.BROWSER_GET_PROCESS_MEMORY_INFO, function (event) {
return event.sender._getProcessMemoryInfo();
});
// Methods not listed in this set are called directly in the renderer process.
const allowedClipboardMethods = (() => {
switch (process.platform) {

View File

@@ -4,6 +4,7 @@ export const enum IPC_MESSAGES {
BROWSER_PRELOAD_ERROR = 'BROWSER_PRELOAD_ERROR',
BROWSER_SANDBOX_LOAD = 'BROWSER_SANDBOX_LOAD',
BROWSER_WINDOW_CLOSE = 'BROWSER_WINDOW_CLOSE',
BROWSER_GET_PROCESS_MEMORY_INFO = 'BROWSER_GET_PROCESS_MEMORY_INFO',
GUEST_INSTANCE_VISIBILITY_CHANGE = 'GUEST_INSTANCE_VISIBILITY_CHANGE',

View File

@@ -59,6 +59,10 @@ v8Util.setHiddenValue(global, 'ipcNative', {
}
});
process.getProcessMemoryInfo = () => {
return ipcRendererInternal.invoke<Electron.ProcessMemoryInfo>(IPC_MESSAGES.BROWSER_GET_PROCESS_MEMORY_INFO);
};
// Use electron module after everything is ready.
const { webFrameInit } = require('@electron/internal/renderer/web-frame-init') as typeof webFrameInitModule;
webFrameInit();

View File

@@ -86,6 +86,10 @@ Object.assign(preloadProcess, processProps);
Object.assign(process, binding.process);
Object.assign(process, processProps);
process.getProcessMemoryInfo = preloadProcess.getProcessMemoryInfo = () => {
return ipcRendererInternal.invoke<Electron.ProcessMemoryInfo>(IPC_MESSAGES.BROWSER_GET_PROCESS_MEMORY_INFO);
};
Object.defineProperty(preloadProcess, 'noDeprecation', {
get () {
return process.noDeprecation;

View File

@@ -1,6 +1,6 @@
{
"name": "electron",
"version": "16.0.0-nightly.20210922",
"version": "16.0.0-beta.3",
"repository": "https://github.com/electron/electron",
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {

View File

@@ -2,4 +2,4 @@ expose_ripemd160.patch
expose_aes-cfb.patch
expose_des-ede3.patch
fix_sync_evp_get_cipherbynid_and_evp_get_cipherbyname.patch
add_maskhash_to_rsa_pss_params_st_for_compat.patch
enable_x509_v_flag_trusted_first_flag.patch

View File

@@ -1,26 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Wed, 8 Sep 2021 10:59:51 +0200
Subject: Add maskHash to rsa_pss_params_st for compat
This CL adds a maskHash member to the rsa_pss_params_st struct for
increased compatibility with OpenSSL.
Node.js recently began to make use of this member in
https://github.com/nodejs/node/pull/39851
and without this member Electron sees compilation errors.
Upstreamed at https://boringssl-review.googlesource.com/c/boringssl/+/49365
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index fa333ca057dd8e90a3e38c51db6269815de7b85f..0f4a6d79514739fb4c719f9e5b41db364e775417 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -1949,6 +1949,7 @@ typedef struct rsa_pss_params_st {
X509_ALGOR *maskGenAlgorithm;
ASN1_INTEGER *saltLength;
ASN1_INTEGER *trailerField;
+ X509_ALGOR *maskHash;
} RSA_PSS_PARAMS;
DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS)

View File

@@ -0,0 +1,20 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Juan Cruz Viotti <jv@jviotti.com>
Date: Thu, 30 Sep 2021 13:39:23 -0400
Subject: Enable X509_V_FLAG_TRUSTED_FIRST flag
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c
index 5a881d64c30076404cc800fff9e943bb0b30d2ac..29d5341efc8eb7ae6f90bdde5a8032e99f75c98e 100644
--- a/crypto/x509/x509_vpm.c
+++ b/crypto/x509/x509_vpm.c
@@ -528,7 +528,7 @@ static const X509_VERIFY_PARAM default_table[] = {
(char *)"default", /* X509 default parameters */
0, /* Check time */
0, /* internal flags */
- 0, /* flags */
+ X509_V_FLAG_TRUSTED_FIRST, /* flags */
0, /* purpose */
0, /* trust */
100, /* depth */

View File

@@ -31,7 +31,7 @@ index 786a5d5fb13d7ceafc9b7d58c0aaccb88552506d..5ede89f9f0761d1da1baa899e9a02b77
return EVP_aes_128_ctr();
} else if (OPENSSL_strcasecmp(name, "aes-192-ctr") == 0) {
diff --git a/decrepit/evp/evp_do_all.c b/decrepit/evp/evp_do_all.c
index 5a41a7b7dc9afee65d9004c497da735073715bd3..c6c901eaff474eaa3f06128ea825b8203d064a52 100644
index 852b76bea69988e0b3ac76a17b603128f239dde0..d443f4dc2daea0b7aa86ae75d31d995fae667ba9 100644
--- a/decrepit/evp/evp_do_all.c
+++ b/decrepit/evp/evp_do_all.c
@@ -20,8 +20,10 @@ void EVP_CIPHER_do_all_sorted(void (*callback)(const EVP_CIPHER *cipher,

View File

@@ -19,7 +19,7 @@ index 5ede89f9f0761d1da1baa899e9a02b77ffcffe93..8205e121c152fe4e2d8df34a1ac2fe04
// This is not a name used by OpenSSL, but tcpdump registers it
// with |EVP_add_cipher_alias|. Our |EVP_add_cipher_alias| is a
diff --git a/decrepit/evp/evp_do_all.c b/decrepit/evp/evp_do_all.c
index c6c901eaff474eaa3f06128ea825b8203d064a52..f577cd23bf72b94b2651fe5eeb757106f5adaea2 100644
index d443f4dc2daea0b7aa86ae75d31d995fae667ba9..5e71420b765019edea82a33884ace539cd91bda5 100644
--- a/decrepit/evp/evp_do_all.c
+++ b/decrepit/evp/evp_do_all.c
@@ -39,6 +39,7 @@ void EVP_CIPHER_do_all_sorted(void (*callback)(const EVP_CIPHER *cipher,

View File

@@ -10,12 +10,12 @@ this patch is required to provide ripemd160 support in the nodejs crypto
module.
diff --git a/crypto/digest_extra/digest_extra.c b/crypto/digest_extra/digest_extra.c
index a93601c170dc407f7d6d628fb7e2d2f0788467f3..00911ee69bb99a34b938ea6a62cd10bc930ec95c 100644
index 8cbb28e3afde3dbae3887b22e8b607fa7303e89f..32caba196eb9f0823f774dac9e91314035b3ff7f 100644
--- a/crypto/digest_extra/digest_extra.c
+++ b/crypto/digest_extra/digest_extra.c
@@ -84,6 +84,7 @@ static const struct nid_to_digest nid_to_digest_mapping[] = {
{NID_sha384, EVP_sha384, SN_sha384, LN_sha384},
@@ -85,6 +85,7 @@ static const struct nid_to_digest nid_to_digest_mapping[] = {
{NID_sha512, EVP_sha512, SN_sha512, LN_sha512},
{NID_sha512_256, EVP_sha512_256, SN_sha512_256, LN_sha512_256},
{NID_md5_sha1, EVP_md5_sha1, SN_md5_sha1, LN_md5_sha1},
+ {NID_ripemd160, EVP_ripemd160, SN_ripemd160, LN_ripemd160},
// As a remnant of signing |EVP_MD|s, OpenSSL returned the corresponding
@@ -62,21 +62,21 @@ index f006ebbc53eea78ce0337a076a05285f22da7a18..7b9309f39a2e5dc6e61bb89e5d32b176
+
#undef CHECK
diff --git a/decrepit/evp/evp_do_all.c b/decrepit/evp/evp_do_all.c
index d8023e08f70a060aed083212fefd1de3ecc142e4..5a41a7b7dc9afee65d9004c497da735073715bd3 100644
index a3fb077b9b9e66d1bc524fd7987622e73aa4776a..852b76bea69988e0b3ac76a17b603128f239dde0 100644
--- a/decrepit/evp/evp_do_all.c
+++ b/decrepit/evp/evp_do_all.c
@@ -78,6 +78,7 @@ void EVP_MD_do_all_sorted(void (*callback)(const EVP_MD *cipher,
callback(EVP_sha256(), "SHA256", NULL, arg);
@@ -79,6 +79,7 @@ void EVP_MD_do_all_sorted(void (*callback)(const EVP_MD *cipher,
callback(EVP_sha384(), "SHA384", NULL, arg);
callback(EVP_sha512(), "SHA512", NULL, arg);
+ callback(EVP_ripemd160(), "RIPEMD160", NULL, arg);
callback(EVP_sha512_256(), "SHA512-256", NULL, arg);
+ callback(EVP_ripemd160(), "ripemd160", NULL, arg);
callback(EVP_md4(), "md4", NULL, arg);
callback(EVP_md5(), "md5", NULL, arg);
@@ -86,6 +87,7 @@ void EVP_MD_do_all_sorted(void (*callback)(const EVP_MD *cipher,
callback(EVP_sha256(), "sha256", NULL, arg);
@@ -88,6 +89,7 @@ void EVP_MD_do_all_sorted(void (*callback)(const EVP_MD *cipher,
callback(EVP_sha384(), "sha384", NULL, arg);
callback(EVP_sha512(), "sha512", NULL, arg);
callback(EVP_sha512_256(), "sha512-256", NULL, arg);
+ callback(EVP_ripemd160(), "ripemd160", NULL, arg);
}

View File

@@ -1,2 +0,0 @@
revert_remove_warning_about_unknown_abstract_origin.patch
revert_add_inline_and_inline_origin_records_to_symbol_file.patch

View File

@@ -1,47 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Attard <samuel.r.attard@gmail.com>
Date: Thu, 2 Sep 2021 22:55:25 +0000
Subject: Revert "Remove warning about unknown abstract origin"
This reverts commit 7933ec0a69bac134b7cee4b60a5dc80743b2b1a9.
diff --git a/src/common/dwarf_cu_to_module.cc b/src/common/dwarf_cu_to_module.cc
index dacc9cbe4b0e13d19b5969fe91ba7a867e64a36c..c51514b7575c2e961aaae3ff883be00d80e3ec15 100644
--- a/src/common/dwarf_cu_to_module.cc
+++ b/src/common/dwarf_cu_to_module.cc
@@ -504,6 +504,8 @@ void DwarfCUToModule::GenericDIEHandler::ProcessAttributeReference(
abstract_origin_ = &(origin->second);
} else if (data > offset_) {
forward_ref_die_offset_ = data;
+ } else {
+ cu_context_->reporter->UnknownAbstractOrigin(offset_, data);
}
specification_offset_ = data;
break;
@@ -748,6 +750,14 @@ void DwarfCUToModule::InlineHandler::Finish() {
}
}
+ // Malformed DWARF may omit the name, but all Module::Functions must
+ // have names.
+ // If we have a forward reference to a DW_AT_specification or
+ // DW_AT_abstract_origin, then don't warn, the name will be fixed up
+ // later
+ if (name_.empty() && forward_ref_die_offset_ == 0)
+ cu_context_->reporter->UnnamedFunction(offset_);
+
// Every DW_TAG_inlined_subroutine should have a DW_AT_abstract_origin.
assert(specification_offset_ != 0);
@@ -919,6 +929,11 @@ void DwarfCUToModule::FuncHandler::Finish() {
if (!name_.empty()) {
name = name_;
} else {
+ // If we have a forward reference to a DW_AT_specification or
+ // DW_AT_abstract_origin, then don't warn, the name will be fixed up
+ // later
+ if (forward_ref_die_offset_ == 0)
+ cu_context_->reporter->UnnamedFunction(offset_);
name = "<name omitted>";
}

View File

@@ -100,11 +100,14 @@ build_do_not_depend_on_packed_resource_integrity.patch
refactor_restore_base_adaptcallbackforrepeating.patch
hack_to_allow_gclient_sync_with_host_os_mac_on_linux_in_ci.patch
don_t_run_pcscan_notifythreadcreated_if_pcscan_is_disabled.patch
add_gin_wrappable_crash_key.patch
logging_win32_only_create_a_console_if_logging_to_stderr.patch
fix_media_key_usage_with_globalshortcuts.patch
feat_expose_raw_response_headers_from_urlloader.patch
chore_do_not_use_chrome_windows_in_cryptotoken_webrequestsender.patch
fix_chrome_root_store_codegen_for_cross-compile_builds.patch
process_singleton.patch
fix_expose_decrementcapturercount_in_web_contents_impl.patch
cherry-pick-ec42dfd3545f.patch
cherry-pick-39090918efac.patch
roll_perfetto_trace_processor_linux_from_b852166f90d5_to_e90b9fb93385.patch
feat_add_data_parameter_to_processsingleton.patch
mas_gate_private_enterprise_APIs

View File

@@ -10,7 +10,7 @@ DidCreateScriptContext is called, not all JS APIs are available in the
context, which can cause some preload scripts to trip.
diff --git a/content/public/renderer/render_frame_observer.h b/content/public/renderer/render_frame_observer.h
index 794a89ded73c415403d0d590780869c8d8b4ae38..5eb76debe9804a5195747cb6b90707fd0a242ec6 100644
index 808bbcb0a13bbf069b2354bf39aabcd6d316d514..20e4cbe56bdb8dca3883778b16b9c127aca34793 100644
--- a/content/public/renderer/render_frame_observer.h
+++ b/content/public/renderer/render_frame_observer.h
@@ -127,6 +127,8 @@ class CONTENT_EXPORT RenderFrameObserver : public IPC::Listener,
@@ -23,10 +23,10 @@ index 794a89ded73c415403d0d590780869c8d8b4ae38..5eb76debe9804a5195747cb6b90707fd
int32_t world_id) {}
virtual void DidClearWindowObject() {}
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 173952d4545d59ecb1b99aa07b6c8f8bcd1b2e86..395bb615c0a2d5a49cfbc6d8a9e9f3d9a809b595 100644
index 4560b2e363e7392467ff623691d3bd0302b5a502..ebf2d997f03c36e5242405002c7dce583aec31dc 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -4461,6 +4461,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
@@ -4460,6 +4460,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
observer.DidCreateScriptContext(context, world_id);
}
@@ -40,10 +40,10 @@ index 173952d4545d59ecb1b99aa07b6c8f8bcd1b2e86..395bb615c0a2d5a49cfbc6d8a9e9f3d9
int world_id) {
for (auto& observer : observers_)
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 4cd3901203e5399fb5a2855fca98e083fe0973d1..b11cb66d157023d36113f28399d57ff2b2f10abb 100644
index 100e382cc73c1f107cd1b7e618b93e009a1f6c65..afebce99ebbcb28aff27d2d7044bb080ce9fd40e 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -593,6 +593,8 @@ class CONTENT_EXPORT RenderFrameImpl
@@ -594,6 +594,8 @@ class CONTENT_EXPORT RenderFrameImpl
blink::WebLocalFrameClient::LazyLoadBehavior lazy_load_behavior) override;
void DidCreateScriptContext(v8::Local<v8::Context> context,
int world_id) override;
@@ -123,10 +123,10 @@ index 57c9b6b733ebf5b9483d31959fbdccad8b72031c..13c7e6924a19717473379045ae1c1f0e
int32_t world_id) override;
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h
index 65356d0acdc5868cce8401ed88b90d75c6306f28..338ebba74360e09bfc93c5be943ab828d22b500b 100644
index 0a4a0b8a4dc871dc86887774a6c81282ea98cda6..ab6ada68a78aa22e723080925d20cf14e8fe822a 100644
--- a/third_party/blink/renderer/core/loader/empty_clients.h
+++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -359,6 +359,8 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
@@ -360,6 +360,8 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
void DidCreateScriptContext(v8::Local<v8::Context>,
int32_t world_id) override {}

View File

@@ -1,63 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: VerteDinde <khammond@slack-corp.com>
Date: Thu, 15 Jul 2021 12:16:50 -0700
Subject: chore: add gin::wrappable wrapperinfo crash key
This patch adds an additional crash key for gin::Wrappable, to help
debug a crash that is occurring during garbage collection in SecondWeakCallback.
The crash seems to be due to a class that is holding a reference to
gin::Wrappable even after being deleted. This added crash key compares
the soon-to-be-deleted WrapperInfo with known WrapperInfo components to
help determine where the crash originated from.
This patch should not be upstreamed, and can be removed in Electron 15 and
beyond once we identify the cause of the crash.
diff --git a/gin/BUILD.gn b/gin/BUILD.gn
index c6059fdb0e0f74ee3ef78c5517634ed5a36f1b10..e16b2ec43b98c3b8724fd85085a33fe52a1e1979 100644
--- a/gin/BUILD.gn
+++ b/gin/BUILD.gn
@@ -88,6 +88,10 @@ component("gin") {
frameworks = [ "CoreFoundation.framework" ]
}
+ if (!is_mas_build) {
+ public_deps += [ "//components/crash/core/common:crash_key" ]
+ }
+
configs += [
"//tools/v8_context_snapshot:use_v8_context_snapshot",
"//v8:external_startup_data",
diff --git a/gin/wrappable.cc b/gin/wrappable.cc
index fe07eb94a8e679859bba6d76ff0d6ee86bd0c67e..ecb0aa2c4ec57e1814f4c94194e775440f4e35ee 100644
--- a/gin/wrappable.cc
+++ b/gin/wrappable.cc
@@ -8,6 +8,11 @@
#include "gin/object_template_builder.h"
#include "gin/per_isolate_data.h"
+#if !defined(MAS_BUILD)
+#include "components/crash/core/common/crash_key.h"
+#include "electron/shell/common/crash_keys.h"
+#endif
+
namespace gin {
WrappableBase::WrappableBase() = default;
@@ -36,6 +41,15 @@ void WrappableBase::FirstWeakCallback(
void WrappableBase::SecondWeakCallback(
const v8::WeakCallbackInfo<WrappableBase>& data) {
WrappableBase* wrappable = data.GetParameter();
+
+#if !defined(MAS_BUILD)
+ WrapperInfo* wrapperInfo = static_cast<WrapperInfo*>(data.GetInternalField(0));
+ std::string location = electron::crash_keys::GetCrashValueForGinWrappable(wrapperInfo);
+
+ static crash_reporter::CrashKeyString<32> crash_key("gin-wrappable-fatal.location");
+ crash_reporter::ScopedCrashKeyString auto_clear(&crash_key, location);
+#endif
+
delete wrappable;
}

View File

@@ -6,10 +6,10 @@ Subject: allow disabling blink scheduler throttling per RenderView
This allows us to disable throttling for hidden windows.
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index e4f71e2ce9cf7cce68c0b2c336d6a7329a7cd564..30bd888e778d27c738eb67df2316db191a3c3066 100644
index af75828e89e8cb1cca20c8acd64c9f864c0ffab7..182a6ebdf1ccad6b6ef7a2d45791bc0f5dc456f2 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -616,6 +616,11 @@ void RenderViewHostImpl::SetBackgroundOpaque(bool opaque) {
@@ -627,6 +627,11 @@ void RenderViewHostImpl::SetBackgroundOpaque(bool opaque) {
GetWidget()->GetAssociatedFrameWidget()->SetBackgroundOpaque(opaque);
}
@@ -22,10 +22,10 @@ index e4f71e2ce9cf7cce68c0b2c336d6a7329a7cd564..30bd888e778d27c738eb67df2316db19
return is_active();
}
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h
index b9a91d4cf22379408c296742f8ec66eb20c34f7e..f110151e555fc90f9ad863a43b6185c7481cf3b3 100644
index b51bd8160bf63a75066d23514b727eb365a3918c..48413119621f6b118b80d681f777e74af8dc8ab7 100644
--- a/content/browser/renderer_host/render_view_host_impl.h
+++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -137,6 +137,7 @@ class CONTENT_EXPORT RenderViewHostImpl
@@ -135,6 +135,7 @@ class CONTENT_EXPORT RenderViewHostImpl
bool IsRenderViewLive() override;
void WriteIntoTrace(perfetto::TracedValue context) override;
@@ -34,10 +34,10 @@ index b9a91d4cf22379408c296742f8ec66eb20c34f7e..f110151e555fc90f9ad863a43b6185c7
void SendRendererPreferencesToRenderer(
const blink::RendererPreferences& preferences);
diff --git a/content/public/browser/render_view_host.h b/content/public/browser/render_view_host.h
index 740d1c322b740d374dd0287d99daebc1fe39ceda..f6ed1402120c0d8b30356c87a52d88fe39ed08d9 100644
index 8bb06dec16fbf205230a10e0e52daa787338bc23..9ebc42788391e838e78af75e2449dde4f1107f22 100644
--- a/content/public/browser/render_view_host.h
+++ b/content/public/browser/render_view_host.h
@@ -90,6 +90,9 @@ class CONTENT_EXPORT RenderViewHost {
@@ -84,6 +84,9 @@ class CONTENT_EXPORT RenderViewHost {
// Write a representation of this object into a trace.
virtual void WriteIntoTrace(perfetto::TracedValue context) = 0;

View File

@@ -49,7 +49,7 @@ index 8bf6b4bc077cc41da5e0e6b13302bc343537c68f..01bddc0bcb7476408023c4cfc042a088
// its owning reference back to our owning LocalFrame.
client_->Detached(type);
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index cf505929c9f6eac724a22e5abcd362ed70aed710..b49500d62fb29f179ae802366108c84e2f891836 100644
index be646cf80c0d3490979e3500821c5fc4351af2a7..dca161475f9e0cd86db8675faec3d375d94c490f 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -553,10 +553,6 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {

View File

@@ -8,7 +8,7 @@ categories in use are known / declared. This patch is required for us
to introduce a new Electron category for Electron-specific tracing.
diff --git a/base/trace_event/builtin_categories.h b/base/trace_event/builtin_categories.h
index efa8e6578dbdda31a9cfafe680d03c809617f84c..46affd2c438a5108440848943fb20efe070e6ed0 100644
index 702ac1a5464635acb1064ca31f7ef211cc0b4a66..6adcf56ca83237d93cd289744b4eb29d7f9e39d6 100644
--- a/base/trace_event/builtin_categories.h
+++ b/base/trace_event/builtin_categories.h
@@ -77,6 +77,7 @@

View File

@@ -11,7 +11,7 @@ if we ever align our .pak file generation with Chrome we can remove this
patch.
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index 897e473cbb4c3e8b244210706e4e1549b1e71a0c..cde17f7fee3851e96afc181c92121867c97a0f95 100644
index abab9c8e8c60a6d1690acca5133b3c54d0ccc793..f4378acd7c92193c6e6ac2785cd8a670bd9c650c 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -165,11 +165,16 @@ if (!is_android && !is_mac) {
@@ -33,10 +33,10 @@ index 897e473cbb4c3e8b244210706e4e1549b1e71a0c..cde17f7fee3851e96afc181c92121867
"//base",
"//build:branding_buildflags",
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 3acfeb5e5bf721fabe2339e389193cd9e154e293..9cdea4ca822f74cf7398d3f474bcc5ccfd43f829 100644
index 27f4f83da31dbd3a1e754279e760dddf00224e1b..5cdcad53c32d7f25fe041344cb7441bdd6c524a5 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -4398,7 +4398,7 @@ static_library("browser") {
@@ -4415,7 +4415,7 @@ static_library("browser") {
# On Windows, the hashes are embedded in //chrome:chrome_initial rather
# than here in :chrome_dll.
@@ -46,10 +46,10 @@ index 3acfeb5e5bf721fabe2339e389193cd9e154e293..9cdea4ca822f74cf7398d3f474bcc5cc
}
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index f8eeccc044eebd0c7f1a845ff29c7e46acf83252..d81d15061a88a7e38d7ee46ca7b0f6fcbe994961 100644
index a7e09cea9b71e810e08790d109e805a8119c0825..52f9f2b0d4e3ee7d3221f04f122f41e1429f6016 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -5353,7 +5353,6 @@ test("unit_tests") {
@@ -5482,7 +5482,6 @@ test("unit_tests") {
assert(toolkit_views)
sources += [ "../browser/ui/startup/credential_provider_signin_info_fetcher_win_unittest.cc" ]
deps += [
@@ -57,7 +57,7 @@ index f8eeccc044eebd0c7f1a845ff29c7e46acf83252..d81d15061a88a7e38d7ee46ca7b0f6fc
"//chrome/browser:chrome_process_finder",
"//chrome/browser/safe_browsing/chrome_cleaner",
"//chrome/browser/safe_browsing/chrome_cleaner:public",
@@ -5366,6 +5365,12 @@ test("unit_tests") {
@@ -5495,6 +5494,12 @@ test("unit_tests") {
"//components/chrome_cleaner/public/proto",
"//ui/events/devices:test_support",
]
@@ -70,7 +70,7 @@ index f8eeccc044eebd0c7f1a845ff29c7e46acf83252..d81d15061a88a7e38d7ee46ca7b0f6fc
}
# TODO(crbug.com/931218): Ninja cannot handle certain characters appearing
@@ -5953,7 +5958,6 @@ test("unit_tests") {
@@ -6088,7 +6093,6 @@ test("unit_tests") {
}
deps += [
@@ -78,7 +78,7 @@ index f8eeccc044eebd0c7f1a845ff29c7e46acf83252..d81d15061a88a7e38d7ee46ca7b0f6fc
"//chrome/browser:cart_db_content_proto",
"//chrome/browser/media/router:test_support",
"//chrome/browser/resource_coordinator:intervention_policy_database_proto",
@@ -5989,6 +5993,9 @@ test("unit_tests") {
@@ -6124,6 +6128,9 @@ test("unit_tests") {
"//ui/native_theme:test_support",
"//ui/webui/resources/js/browser_command:mojo_bindings",
]

View File

@@ -14,7 +14,7 @@ tradeoff is that switching from MAS_BUILD to !MAS_BUILD or vice-versa will
rebuild the entire tree.
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn
index 725894d05274355be4ad5d6ac3388a489220a50c..e568780d699a9ac977e509165b2e9b0516cde779 100644
index 62e7e4bcd3e6c1ef49e3c929af7ac4634a1e6e2b..4edb4b27d985f6cd836832cde49346089ebe579e 100644
--- a/build/config/BUILDCONFIG.gn
+++ b/build/config/BUILDCONFIG.gn
@@ -123,6 +123,9 @@ if (current_os == "") {

View File

@@ -9,10 +9,10 @@ potentially prevent a window from being created.
TODO(loc): this patch is currently broken.
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index befd11fbac2068e6ac303989528ee609263ae9b2..ea22c655ae4e5c1e023d68fbedb2a684edabe1fe 100644
index 78eb422f2ac9c56f7a601f2e82a759817be23f82..1a62a9669484980a69d658ca6729e7caf3db96fb 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -6406,6 +6406,7 @@ void RenderFrameHostImpl::CreateNewWindow(
@@ -6533,6 +6533,7 @@ void RenderFrameHostImpl::CreateNewWindow(
last_committed_origin_, params->window_container_type,
params->target_url, params->referrer.To<Referrer>(),
params->frame_name, params->disposition, *params->features,
@@ -21,10 +21,10 @@ index befd11fbac2068e6ac303989528ee609263ae9b2..ea22c655ae4e5c1e023d68fbedb2a684
&no_javascript_access);
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index afee3ed1f21aa9b95e2dc48191445d0f18049bbb..0ba0990cf02624cc7cf1b304a0d9b63692cd464d 100644
index b9aa5d69242727e1a01df7a0d00d592c58e3815a..5a86229bf1fc52e6cccbf609ed029fe88d35cd8f 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3739,6 +3739,14 @@ FrameTree* WebContentsImpl::CreateNewWindow(
@@ -3734,6 +3734,14 @@ FrameTree* WebContentsImpl::CreateNewWindow(
}
auto* new_contents_impl = new_contents.get();
@@ -39,7 +39,7 @@ index afee3ed1f21aa9b95e2dc48191445d0f18049bbb..0ba0990cf02624cc7cf1b304a0d9b636
new_contents_impl->GetController().SetSessionStorageNamespace(
partition_id, session_storage_namespace);
@@ -3781,12 +3789,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
@@ -3776,12 +3784,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
AddWebContentsDestructionObserver(new_contents_impl);
}
@@ -68,10 +68,10 @@ index 74ed9ae0eae10e77dace6905b5108a834b07f8b4..924d6b43d444ccb919d6985c975eb886
// Operation result when the renderer asks the browser to create a new window.
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 9f8dbbc7a63cf8a1a8166dd67efd452eab791426..8a45f8c39fe160829de316c513e73327dabfc391 100644
index 0cf1f777dc5ffbca606fff558ef6a41e8ed60a99..40bd443cb3c82d9671c4716900a1f19b3c26de69 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -557,6 +557,8 @@ bool ContentBrowserClient::CanCreateWindow(
@@ -555,6 +555,8 @@ bool ContentBrowserClient::CanCreateWindow(
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
@@ -81,10 +81,10 @@ index 9f8dbbc7a63cf8a1a8166dd67efd452eab791426..8a45f8c39fe160829de316c513e73327
bool opener_suppressed,
bool* no_javascript_access) {
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 4db050cb8e5e328f84d4a5fc92aee7d743ee16c4..bb30bb3604a793cbe37d20a3a18b21d5abfd6530 100644
index b6dae0082a297a6dbafd63bd56729b77ffb832fc..66ff9593b8f3d62c486ef83c4c682edf73081d88 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -166,6 +166,7 @@ class NetworkService;
@@ -167,6 +167,7 @@ class NetworkService;
class TrustedURLLoaderHeaderClient;
} // namespace mojom
struct ResourceRequest;
@@ -92,7 +92,7 @@ index 4db050cb8e5e328f84d4a5fc92aee7d743ee16c4..bb30bb3604a793cbe37d20a3a18b21d5
} // namespace network
namespace sandbox {
@@ -924,6 +925,8 @@ class CONTENT_EXPORT ContentBrowserClient {
@@ -922,6 +923,8 @@ class CONTENT_EXPORT ContentBrowserClient {
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
@@ -173,10 +173,10 @@ index ea22a86dc1a6e5cdb3e3dfa31a929a3dd14b9e61..215b059bb2dfcead6c709c99b39578f8
/*is_opener_navigation=*/false, request.HasUserGesture(),
// `openee_can_access_opener_origin` only matters for opener navigations,
diff --git a/content/web_test/browser/web_test_content_browser_client.cc b/content/web_test/browser/web_test_content_browser_client.cc
index c6872573086e628a894f482877db2d417552c6a1..5e67b6a59c3e3d6881f738985ab947a2d7902f0a 100644
index 520b6f8146361cf8c00079c1cc0f5394f747d405..77f58cc157229eb01ce9a35aa5814f64d6e8f2f2 100644
--- a/content/web_test/browser/web_test_content_browser_client.cc
+++ b/content/web_test/browser/web_test_content_browser_client.cc
@@ -450,6 +450,8 @@ bool WebTestContentBrowserClient::CanCreateWindow(
@@ -438,6 +438,8 @@ bool WebTestContentBrowserClient::CanCreateWindow(
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
@@ -186,10 +186,10 @@ index c6872573086e628a894f482877db2d417552c6a1..5e67b6a59c3e3d6881f738985ab947a2
bool opener_suppressed,
bool* no_javascript_access) {
diff --git a/content/web_test/browser/web_test_content_browser_client.h b/content/web_test/browser/web_test_content_browser_client.h
index 427656a1a01a9305459a8f1d6616fd0666413b39..c8e296286cdd148348932d2bdfa4d064f8cbe36d 100644
index 1580bd13ea123740dc7a8813680a8d2448d49969..5c0809733b366ecff02c5a4b77dac9530eb15fbf 100644
--- a/content/web_test/browser/web_test_content_browser_client.h
+++ b/content/web_test/browser/web_test_content_browser_client.h
@@ -83,6 +83,8 @@ class WebTestContentBrowserClient : public ShellContentBrowserClient {
@@ -80,6 +80,8 @@ class WebTestContentBrowserClient : public ShellContentBrowserClient {
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
@@ -220,10 +220,10 @@ index 84d32491a56528a84b4395fba1d54cdbb38d522b..09998a83c449ef8cd9f360fbcdcf7edc
} // namespace blink
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index 10e40d408bb0b1526534918add49906e65d17368..b6a0473ad93f8ef1adc53536411e8fd62c106b5d 100644
index 3915f0df47d5a2ae1a5f2909d2aa59192c0cc44b..ada26f26f2ac0fab4a2dc02a5b64c72614c06965 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -2022,6 +2022,7 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
@@ -2027,6 +2027,7 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
WebWindowFeatures window_features =
GetWindowFeaturesFromString(features, incumbent_window);

View File

@@ -0,0 +1,455 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: cfredric <cfredric@chromium.org>
Date: Mon, 27 Sep 2021 22:14:18 +0000
Subject: Consider HTTPS and WSS schemes identically for FPS.
This modifies the FPS implementation to normalize wss:// URLs into
https:// URLs when determining the same-partiness of a request.
This allows SameParty cookies to be sent on same-party WSS connection
requests. A browsertest is included to verify this.
Bug: 1251688
Change-Id: Id277288982805e0d29c6683e0c13d4b7c7cfe359
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3182786
Reviewed-by: Maksim Orlovich <morlovich@chromium.org>
Reviewed-by: Shuran Huang <shuuran@chromium.org>
Commit-Queue: Chris Fredrickson <cfredric@chromium.org>
Cr-Commit-Position: refs/heads/main@{#925457}
diff --git a/chrome/browser/net/websocket_browsertest.cc b/chrome/browser/net/websocket_browsertest.cc
index 8a9fe6db3b0030496d00cf57d96a90ee899babaf..de48b97b96c22eeae5fe680868c48381d9a13cc2 100644
--- a/chrome/browser/net/websocket_browsertest.cc
+++ b/chrome/browser/net/websocket_browsertest.cc
@@ -21,6 +21,7 @@
#include "base/test/bind.h"
#include "build/build_config.h"
#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/login/login_handler.h"
#include "chrome/browser/ui/login/login_handler_test_utils.h"
@@ -45,25 +46,31 @@
#include "mojo/public/cpp/system/data_pipe.h"
#include "net/base/network_isolation_key.h"
#include "net/cookies/site_for_cookies.h"
+#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
#include "net/test/test_data_directory.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
+#include "services/network/public/cpp/network_switches.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "services/network/public/mojom/websocket.mojom.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"
namespace {
+using SSLOptions = net::SpawnedTestServer::SSLOptions;
+
class WebSocketBrowserTest : public InProcessBrowserTest {
public:
- WebSocketBrowserTest()
+ explicit WebSocketBrowserTest(
+ SSLOptions::ServerCertificate cert = SSLOptions::CERT_OK)
: ws_server_(net::SpawnedTestServer::TYPE_WS,
net::GetWebSocketTestDataDirectory()),
wss_server_(net::SpawnedTestServer::TYPE_WSS,
- SSLOptions(SSLOptions::CERT_OK),
+ SSLOptions(cert),
net::GetWebSocketTestDataDirectory()) {}
protected:
@@ -145,7 +152,6 @@ class WebSocketBrowserTest : public InProcessBrowserTest {
net::SpawnedTestServer wss_server_;
private:
- typedef net::SpawnedTestServer::SSLOptions SSLOptions;
std::unique_ptr<content::TitleWatcher> watcher_;
DISALLOW_COPY_AND_ASSIGN(WebSocketBrowserTest);
@@ -162,37 +168,72 @@ class WebSocketBrowserTestWithAllowFileAccessFromFiles
};
// Framework for tests using the connect_to.html page served by a separate HTTP
-// server.
+// or HTTPS server.
class WebSocketBrowserConnectToTest : public WebSocketBrowserTest {
protected:
- WebSocketBrowserConnectToTest() {
- http_server_.ServeFilesFromSourceDirectory(
- net::GetWebSocketTestDataDirectory());
- }
+ explicit WebSocketBrowserConnectToTest(
+ SSLOptions::ServerCertificate cert = SSLOptions::CERT_OK)
+ : WebSocketBrowserTest(cert) {}
// The title watcher and HTTP server are set up automatically by the test
// framework. Each test case still needs to configure and start the
// WebSocket server(s) it needs.
void SetUpOnMainThread() override {
+ server().ServeFilesFromSourceDirectory(
+ net::GetWebSocketTestDataDirectory());
WebSocketBrowserTest::SetUpOnMainThread();
- ASSERT_TRUE(http_server_.Start());
+ ASSERT_TRUE(server().Start());
}
- // Supply a ws: or wss: URL to connect to.
- void ConnectTo(GURL url) {
- ASSERT_TRUE(http_server_.Started());
+ // Supply a ws: or wss: URL to connect to. Serves connect_to.html from the
+ // server's default host.
+ void ConnectTo(const GURL& url) {
+ ConnectTo(server().base_url().host(), url);
+ }
+
+ // Supply a ws: or wss: URL to connect to via loading `host`/connect_to.html.
+ void ConnectTo(const std::string& host, const GURL& url) {
+ ASSERT_TRUE(server().Started());
std::string query("url=" + url.spec());
GURL::Replacements replacements;
replacements.SetQueryStr(query);
ASSERT_TRUE(ui_test_utils::NavigateToURL(
- browser(), http_server_.GetURL("/connect_to.html")
+ browser(), server()
+ .GetURL(host, "/connect_to.html")
.ReplaceComponents(replacements)));
}
- private:
+ virtual net::EmbeddedTestServer& server() = 0;
+};
+
+// Concrete impl for tests that use connect_to.html over HTTP.
+class WebSocketBrowserHTTPConnectToTest : public WebSocketBrowserConnectToTest {
+ protected:
+ net::EmbeddedTestServer& server() override { return http_server_; }
+
net::EmbeddedTestServer http_server_;
};
+// Concrete impl for tests that use connect_to.html over HTTPS.
+class WebSocketBrowserHTTPSConnectToTest
+ : public WebSocketBrowserConnectToTest {
+ protected:
+ explicit WebSocketBrowserHTTPSConnectToTest(
+ SSLOptions::ServerCertificate cert = SSLOptions::CERT_OK)
+ : WebSocketBrowserConnectToTest(cert),
+ https_server_(net::test_server::EmbeddedTestServer::TYPE_HTTPS) {}
+
+ void SetUpOnMainThread() override {
+ host_resolver()->AddRule("*", "127.0.0.1");
+ server().SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
+ WebSocketBrowserConnectToTest::SetUpOnMainThread();
+ }
+
+ net::EmbeddedTestServer& server() override { return https_server_; }
+
+ net::EmbeddedTestServer https_server_;
+};
+
// Automatically fill in any login prompts that appear with the supplied
// credentials.
class AutoLogin : public content::NotificationObserver {
@@ -352,7 +393,7 @@ IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest,
EXPECT_EQ("PASS", WaitAndGetTitle());
}
-IN_PROC_BROWSER_TEST_F(WebSocketBrowserConnectToTest,
+IN_PROC_BROWSER_TEST_F(WebSocketBrowserHTTPConnectToTest,
WebSocketBasicAuthInWSURL) {
// Launch a basic-auth-protected WebSocket server.
ws_server_.set_websocket_basic_auth(true);
@@ -364,7 +405,7 @@ IN_PROC_BROWSER_TEST_F(WebSocketBrowserConnectToTest,
EXPECT_EQ("PASS", WaitAndGetTitle());
}
-IN_PROC_BROWSER_TEST_F(WebSocketBrowserConnectToTest,
+IN_PROC_BROWSER_TEST_F(WebSocketBrowserHTTPConnectToTest,
WebSocketBasicAuthInWSURLBadCreds) {
// Launch a basic-auth-protected WebSocket server.
ws_server_.set_websocket_basic_auth(true);
@@ -376,7 +417,7 @@ IN_PROC_BROWSER_TEST_F(WebSocketBrowserConnectToTest,
EXPECT_EQ("FAIL", WaitAndGetTitle());
}
-IN_PROC_BROWSER_TEST_F(WebSocketBrowserConnectToTest,
+IN_PROC_BROWSER_TEST_F(WebSocketBrowserHTTPConnectToTest,
WebSocketBasicAuthNoCreds) {
// Launch a basic-auth-protected WebSocket server.
ws_server_.set_websocket_basic_auth(true);
@@ -420,8 +461,7 @@ IN_PROC_BROWSER_TEST_F(WebSocketBrowserTest, MAYBE_WebSocketAppliesHSTS) {
https_server.ServeFilesFromSourceDirectory(GetChromeTestDataDir());
net::SpawnedTestServer wss_server(
net::SpawnedTestServer::TYPE_WSS,
- net::SpawnedTestServer::SSLOptions(
- net::SpawnedTestServer::SSLOptions::CERT_COMMON_NAME_IS_DOMAIN),
+ SSLOptions(SSLOptions::CERT_COMMON_NAME_IS_DOMAIN),
net::GetWebSocketTestDataDirectory());
// This test sets HSTS on localhost. To avoid being redirected to https, start
// the http server on 127.0.0.1 instead.
@@ -711,4 +751,43 @@ IN_PROC_BROWSER_TEST_F(WebSocketBrowserTestWithAllowFileAccessFromFiles,
EXPECT_EQ("FILE", WaitAndGetTitle());
}
+// A test fixture that enables First-Party Sets.
+class FirstPartySetsWebSocketBrowserTest
+ : public WebSocketBrowserHTTPSConnectToTest {
+ public:
+ FirstPartySetsWebSocketBrowserTest()
+ : WebSocketBrowserHTTPSConnectToTest(SSLOptions::CERT_TEST_NAMES) {}
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ WebSocketBrowserTest::SetUpCommandLine(command_line);
+ command_line->AppendSwitchASCII(
+ network::switches::kUseFirstPartySet,
+ "https://a.test,https://b.test,https://c.test");
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(FirstPartySetsWebSocketBrowserTest,
+ SendsSamePartyCookies) {
+ ASSERT_TRUE(wss_server_.Start());
+
+ ASSERT_TRUE(content::SetCookie(browser()->profile(),
+ server().GetURL("a.test", "/"),
+ "same-party-cookie=1; SameParty; Secure"));
+ ASSERT_TRUE(content::SetCookie(browser()->profile(),
+ server().GetURL("a.test", "/"),
+ "same-site-cookie=1; SameSite=Lax; Secure"));
+
+ content::DOMMessageQueue message_queue;
+ ConnectTo("b.test", wss_server_.GetURL("a.test", "echo-request-headers"));
+
+ std::string message;
+ EXPECT_TRUE(message_queue.WaitForMessage(&message));
+ // Only the SameParty cookie should have been sent, since it was a cross-site
+ // but same-party connection.
+ EXPECT_THAT(message, testing::HasSubstr("same-party-cookie=1"));
+ EXPECT_THAT(message, testing::Not(testing::HasSubstr("same-site-cookie=1")));
+
+ EXPECT_EQ("PASS", WaitAndGetTitle());
+}
+
} // namespace
diff --git a/net/data/websocket/connect_to.html b/net/data/websocket/connect_to.html
index 05c653fc5d2ab9a333efea5b4c5eee83a03bbe07..8a6d78214fe5974cbb0ec62b61f4d7fdcdf42c3b 100644
--- a/net/data/websocket/connect_to.html
+++ b/net/data/websocket/connect_to.html
@@ -29,6 +29,17 @@ ws.onclose = function()
document.title = 'FAIL';
}
+ws.onmessage = function(evt)
+{
+ domAutomationController.send(evt.data);
+}
+
+ws.onerror = function(evt)
+{
+ console.error(`WebSocket error: '${evt.message}'`);
+}
+
+
</script>
</head>
</html>
diff --git a/net/test/spawned_test_server/base_test_server.cc b/net/test/spawned_test_server/base_test_server.cc
index 71199ca12a6b805f288349b0d702b834d4e51df7..90626857ea6452a04e872d13f4474c67a905353c 100644
--- a/net/test/spawned_test_server/base_test_server.cc
+++ b/net/test/spawned_test_server/base_test_server.cc
@@ -137,6 +137,8 @@ base::FilePath BaseTestServer::SSLOptions::GetCertificateFile() const {
case CERT_KEY_USAGE_RSA_DIGITAL_SIGNATURE:
return base::FilePath(
FILE_PATH_LITERAL("key_usage_rsa_digitalsignature.pem"));
+ case CERT_TEST_NAMES:
+ return base::FilePath(FILE_PATH_LITERAL("test_names.pem"));
default:
NOTREACHED();
}
@@ -228,6 +230,14 @@ GURL BaseTestServer::GetURL(const std::string& path) const {
return GURL(GetScheme() + "://" + host_port_pair_.ToString() + "/" + path);
}
+GURL BaseTestServer::GetURL(const std::string& hostname,
+ const std::string& relative_url) const {
+ GURL local_url = GetURL(relative_url);
+ GURL::Replacements replace_host;
+ replace_host.SetHostStr(hostname);
+ return local_url.ReplaceComponents(replace_host);
+}
+
GURL BaseTestServer::GetURLWithUser(const std::string& path,
const std::string& user) const {
return GURL(GetScheme() + "://" + user + "@" + host_port_pair_.ToString() +
diff --git a/net/test/spawned_test_server/base_test_server.h b/net/test/spawned_test_server/base_test_server.h
index e16c548686fd00517493a33ad390dfd2a4ead380..091c5b3ea3f910bfe188c82bc1be85f75dd7dc78 100644
--- a/net/test/spawned_test_server/base_test_server.h
+++ b/net/test/spawned_test_server/base_test_server.h
@@ -77,6 +77,11 @@ class BaseTestServer {
// A certificate with invalid notBefore and notAfter times. Windows'
// certificate library will not parse this certificate.
CERT_BAD_VALIDITY,
+
+ // A certificate that covers a number of test names. See [test_names] in
+ // net/data/ssl/scripts/ee.cnf. More may be added by editing this list and
+ // and rerunning net/data/ssl/scripts/generate-test-certs.sh.
+ CERT_TEST_NAMES,
};
// NOTE: the values of these enumerators are passed to the the Python test
@@ -206,6 +211,8 @@ class BaseTestServer {
bool GetAddressList(AddressList* address_list) const WARN_UNUSED_RESULT;
GURL GetURL(const std::string& path) const;
+ GURL GetURL(const std::string& hostname,
+ const std::string& relative_url) const;
GURL GetURLWithUser(const std::string& path,
const std::string& user) const;
diff --git a/services/network/first_party_sets/first_party_sets.cc b/services/network/first_party_sets/first_party_sets.cc
index 1650c28d8b6c61b30531e1e2ef3e2869d8450360..826b403a2a9702c255ee9b7ea38dc74b9e18791d 100644
--- a/services/network/first_party_sets/first_party_sets.cc
+++ b/services/network/first_party_sets/first_party_sets.cc
@@ -91,16 +91,17 @@ bool FirstPartySets::IsContextSamePartyWithSite(
const net::SchemefulSite* top_frame_site,
const std::set<net::SchemefulSite>& party_context,
bool infer_singleton_sets) const {
- const net::SchemefulSite* site_owner = FindOwner(site, infer_singleton_sets);
- if (!site_owner)
+ const absl::optional<net::SchemefulSite> site_owner =
+ FindOwner(site, infer_singleton_sets);
+ if (!site_owner.has_value())
return false;
const auto is_owned_by_site_owner =
- [this, site_owner,
+ [this, &site_owner,
infer_singleton_sets](const net::SchemefulSite& context_site) -> bool {
- const net::SchemefulSite* context_owner =
+ const absl::optional<net::SchemefulSite> context_owner =
FindOwner(context_site, infer_singleton_sets);
- return context_owner && *context_owner == *site_owner;
+ return context_owner.has_value() && *context_owner == *site_owner;
};
if (top_frame_site && !is_owned_by_site_owner(*top_frame_site))
@@ -131,7 +132,8 @@ net::FirstPartySetsContextType FirstPartySets::ComputeContextType(
const absl::optional<net::SchemefulSite>& top_frame_site,
const std::set<net::SchemefulSite>& party_context) const {
constexpr bool infer_singleton_sets = true;
- const net::SchemefulSite* site_owner = FindOwner(site, infer_singleton_sets);
+ const absl::optional<net::SchemefulSite> site_owner =
+ FindOwner(site, infer_singleton_sets);
// Note: the `party_context` consists of the intermediate frames (for frame
// requests) or intermediate frames and current frame for subresource
// requests.
@@ -152,18 +154,22 @@ net::FirstPartySetsContextType FirstPartySets::ComputeContextType(
: net::FirstPartySetsContextType::kTopResourceMatchMixed;
}
-const net::SchemefulSite* FirstPartySets::FindOwner(
+const absl::optional<net::SchemefulSite> FirstPartySets::FindOwner(
const net::SchemefulSite& site,
bool infer_singleton_sets) const {
- const auto it = sets_.find(site);
- if (it == sets_.end())
- return infer_singleton_sets ? &site : nullptr;
- return &it->second;
+ net::SchemefulSite normalized_site = site;
+ normalized_site.ConvertWebSocketToHttp();
+ const auto it = sets_.find(normalized_site);
+ if (it != sets_.end())
+ return it->second;
+ if (infer_singleton_sets)
+ return normalized_site;
+ return absl::nullopt;
}
bool FirstPartySets::IsInNontrivialFirstPartySet(
const net::SchemefulSite& site) const {
- return base::Contains(sets_, site);
+ return FindOwner(site, /*infer_singleton_sets=*/false).has_value();
}
base::flat_map<net::SchemefulSite, std::set<net::SchemefulSite>>
@@ -244,7 +250,8 @@ base::flat_set<net::SchemefulSite> FirstPartySets::ComputeSetsDiff(
for (const auto& old_pair : old_sets) {
const net::SchemefulSite& old_member = old_pair.first;
const net::SchemefulSite& old_owner = old_pair.second;
- const net::SchemefulSite* current_owner = FindOwner(old_member, false);
+ const absl::optional<net::SchemefulSite> current_owner =
+ FindOwner(old_member, false);
// Look for the removed sites and the ones have owner changed.
if (!current_owner || *current_owner != old_owner) {
result.emplace(old_member);
diff --git a/services/network/first_party_sets/first_party_sets.h b/services/network/first_party_sets/first_party_sets.h
index 8158b555856526170051cba72a08312a5528de51..fc87e5155667befc5a94bbe539ca71dc47d5f7d1 100644
--- a/services/network/first_party_sets/first_party_sets.h
+++ b/services/network/first_party_sets/first_party_sets.h
@@ -97,11 +97,12 @@ class FirstPartySets {
base::OnceCallback<void(const std::string&)> callback);
private:
- // Returns a pointer to `site`'s owner (optionally inferring a singleton set
- // if necessary), or `nullptr` if `site` has no owner. Must not return
- // `nullptr` if `infer_singleton_sets` is true.
- const net::SchemefulSite* FindOwner(const net::SchemefulSite& site,
- bool infer_singleton_sets) const;
+ // Returns `site`'s owner (optionally inferring a singleton set if necessary),
+ // or `nullopt` if `site` has no owner. Must not return `nullopt` if
+ // `infer_singleton_sets` is true.
+ const absl::optional<net::SchemefulSite> FindOwner(
+ const net::SchemefulSite& site,
+ bool infer_singleton_sets) const;
// We must ensure there's no intersection between the manually-specified set
// and the sets that came from Component Updater. (When reconciling the
diff --git a/services/network/first_party_sets/first_party_sets_unittest.cc b/services/network/first_party_sets/first_party_sets_unittest.cc
index 2055619f4c999cbfd5a5ee4780e2eb5c1dad5816..52eb8e8a3d87172353c64bba972311db2889c693 100644
--- a/services/network/first_party_sets/first_party_sets_unittest.cc
+++ b/services/network/first_party_sets/first_party_sets_unittest.cc
@@ -1167,6 +1167,8 @@ TEST_F(FirstPartySetsTest, ComputeContext) {
net::SchemefulSite nonmember1(GURL("https://nonmember1.test"));
net::SchemefulSite member(GURL("https://member1.test"));
net::SchemefulSite owner(GURL("https://example.test"));
+ net::SchemefulSite wss_member(GURL("wss://member1.test"));
+ net::SchemefulSite wss_nonmember(GURL("wss://nonmember.test"));
// Works as usual for sites that are in First-Party sets.
EXPECT_THAT(sets().ComputeContext(member, &member, {member}),
@@ -1180,10 +1182,17 @@ TEST_F(FirstPartySetsTest, ComputeContext) {
EXPECT_THAT(sets().ComputeContext(member, &member, {member, owner}),
net::SamePartyContext(SamePartyContextType::kSameParty));
+ // Works if the site is provided with WSS scheme instead of HTTPS.
+ EXPECT_THAT(sets().ComputeContext(wss_member, &member, {member, owner}),
+ net::SamePartyContext(SamePartyContextType::kSameParty));
+
EXPECT_THAT(sets().ComputeContext(nonmember, &member, {member}),
net::SamePartyContext(SamePartyContextType::kCrossParty));
EXPECT_THAT(sets().ComputeContext(member, &nonmember, {member}),
net::SamePartyContext(SamePartyContextType::kCrossParty));
+ EXPECT_THAT(
+ sets().ComputeContext(wss_nonmember, &wss_member, {member, owner}),
+ net::SamePartyContext(SamePartyContextType::kCrossParty));
// Top&resource differs from Ancestors.
EXPECT_THAT(sets().ComputeContext(member, &member, {nonmember}),
@@ -1225,6 +1234,12 @@ TEST_F(FirstPartySetsTest, IsInNontrivialFirstPartySet) {
EXPECT_TRUE(sets().IsInNontrivialFirstPartySet(
net::SchemefulSite(GURL("https://member1.test"))));
+ EXPECT_TRUE(sets().IsInNontrivialFirstPartySet(
+ net::SchemefulSite(GURL("wss://member1.test"))));
+
+ EXPECT_FALSE(sets().IsInNontrivialFirstPartySet(
+ net::SchemefulSite(GURL("ws://member1.test"))));
+
EXPECT_FALSE(sets().IsInNontrivialFirstPartySet(
net::SchemefulSite(GURL("https://nonmember.test"))));
}

View File

@@ -0,0 +1,626 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shuran Huang <shuuran@chromium.org>
Date: Fri, 24 Sep 2021 00:47:47 +0000
Subject: Add functions to pass in persisted FPSs and compute diffs.
Pass the persisted FPSs and a callback that takes a FPSs into Network
Service. The persisted FPSs is parsed and compared to the current FPSs
in the FirstPartySets class, then call the callback with the current
FPSs. The function that passes in the persisted FPSs and the callback
has not been called anywhere yet.
Bug: 1219656
Change-Id: I08c531aa08d3aeeb772c1eb9a3a453a07b0349d3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3103693
Commit-Queue: Shuran Huang <shuuran@chromium.org>
Reviewed-by: Will Harris <wfh@chromium.org>
Reviewed-by: Matt Menke <mmenke@chromium.org>
Reviewed-by: Chris Fredrickson <cfredric@chromium.org>
Cr-Commit-Position: refs/heads/main@{#924570}
diff --git a/services/network/first_party_sets/first_party_sets.cc b/services/network/first_party_sets/first_party_sets.cc
index f7e732e88d6e6ebc5daed9169d5eee336a9de8c1..1650c28d8b6c61b30531e1e2ef3e2869d8450360 100644
--- a/services/network/first_party_sets/first_party_sets.cc
+++ b/services/network/first_party_sets/first_party_sets.cc
@@ -13,6 +13,7 @@
#include "base/logging.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_split.h"
+#include "base/task/post_task.h"
#include "net/base/schemeful_site.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/same_party_context.h"
@@ -72,12 +73,16 @@ void FirstPartySets::SetManuallySpecifiedSet(const std::string& flag_value) {
flag_value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY));
ApplyManuallySpecifiedSet();
+ manual_sets_ready_ = true;
+ ClearSiteDataOnChangedSetsIfReady();
}
base::flat_map<net::SchemefulSite, net::SchemefulSite>*
FirstPartySets::ParseAndSet(base::StringPiece raw_sets) {
sets_ = FirstPartySetParser::ParseSetsFromComponentUpdater(raw_sets);
ApplyManuallySpecifiedSet();
+ component_sets_ready_ = true;
+ ClearSiteDataOnChangedSetsIfReady();
return &sets_;
}
@@ -218,4 +223,48 @@ void FirstPartySets::ApplyManuallySpecifiedSet() {
sets_.emplace(manual_owner, manual_owner);
}
+void FirstPartySets::SetPersistedSets(base::StringPiece raw_sets) {
+ raw_persisted_sets_ = std::string(raw_sets);
+ persisted_sets_ready_ = true;
+ ClearSiteDataOnChangedSetsIfReady();
+}
+
+void FirstPartySets::SetOnSiteDataCleared(
+ base::OnceCallback<void(const std::string&)> callback) {
+ on_site_data_cleared_ = std::move(callback);
+ ClearSiteDataOnChangedSetsIfReady();
+}
+
+base::flat_set<net::SchemefulSite> FirstPartySets::ComputeSetsDiff(
+ const base::flat_map<net::SchemefulSite, net::SchemefulSite>& old_sets) {
+ if (old_sets.empty())
+ return {};
+
+ base::flat_set<net::SchemefulSite> result;
+ for (const auto& old_pair : old_sets) {
+ const net::SchemefulSite& old_member = old_pair.first;
+ const net::SchemefulSite& old_owner = old_pair.second;
+ const net::SchemefulSite* current_owner = FindOwner(old_member, false);
+ // Look for the removed sites and the ones have owner changed.
+ if (!current_owner || *current_owner != old_owner) {
+ result.emplace(old_member);
+ }
+ }
+ return result;
+}
+
+void FirstPartySets::ClearSiteDataOnChangedSetsIfReady() {
+ if (!persisted_sets_ready_ || !component_sets_ready_ || !manual_sets_ready_ ||
+ on_site_data_cleared_.is_null())
+ return;
+
+ base::flat_set<net::SchemefulSite> diff = ComputeSetsDiff(
+ FirstPartySetParser::DeserializeFirstPartySets(raw_persisted_sets_));
+
+ // TODO(shuuran@chromium.org): Implement site state clearing.
+
+ std::move(on_site_data_cleared_)
+ .Run(FirstPartySetParser::SerializeFirstPartySets(sets_));
+}
+
} // namespace network
diff --git a/services/network/first_party_sets/first_party_sets.h b/services/network/first_party_sets/first_party_sets.h
index 81e0e1080d965947a2ebc1635638c25ad75a1bf7..8158b555856526170051cba72a08312a5528de51 100644
--- a/services/network/first_party_sets/first_party_sets.h
+++ b/services/network/first_party_sets/first_party_sets.h
@@ -9,6 +9,7 @@
#include <memory>
#include <set>
+#include "base/callback.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "net/base/schemeful_site.h"
@@ -87,6 +88,14 @@ class FirstPartySets {
// the members of the set includes the owner.
base::flat_map<net::SchemefulSite, std::set<net::SchemefulSite>> Sets() const;
+ // Sets the `raw_persisted_sets_`, which is a JSON-encoded
+ // string representation of a map of site -> site.
+ void SetPersistedSets(base::StringPiece persisted_sets);
+ // Sets the `on_site_data_cleared_` callback, which takes input of a
+ // JSON-encoded string representation of a map of site -> site.
+ void SetOnSiteDataCleared(
+ base::OnceCallback<void(const std::string&)> callback);
+
private:
// Returns a pointer to `site`'s owner (optionally inferring a singleton set
// if necessary), or `nullptr` if `site` has no owner. Must not return
@@ -101,6 +110,19 @@ class FirstPartySets {
// `manually_specified_set_`.
void ApplyManuallySpecifiedSet();
+ // Compares the map `old_sets` to `sets_` and returns the set of sites that:
+ // 1) were in `old_sets` but are no longer in `sets_`, i.e. leave the FPSs;
+ // or, 2) mapped to a different owner site.
+ base::flat_set<net::SchemefulSite> ComputeSetsDiff(
+ const base::flat_map<net::SchemefulSite, net::SchemefulSite>& old_sets);
+
+ // Checks the required inputs have been received, and if so, computes the diff
+ // between the `sets_` and the parsed `raw_persisted_sets_`, and clears the
+ // site data of the set of sites based on the diff.
+ //
+ // TODO(shuuran@chromium.org): Implement the code to clear site state.
+ void ClearSiteDataOnChangedSetsIfReady();
+
// Represents the mapping of site -> site, where keys are members of sets, and
// values are owners of the sets. Owners are explicitly represented as members
// of the set.
@@ -108,6 +130,22 @@ class FirstPartySets {
absl::optional<
std::pair<net::SchemefulSite, base::flat_set<net::SchemefulSite>>>
manually_specified_set_;
+
+ std::string raw_persisted_sets_;
+
+ bool persisted_sets_ready_ = false;
+ bool component_sets_ready_ = false;
+ bool manual_sets_ready_ = false;
+
+ // The callback runs after the site state clearing is completed.
+ base::OnceCallback<void(const std::string&)> on_site_data_cleared_;
+
+ FRIEND_TEST_ALL_PREFIXES(FirstPartySets, ComputeSetsDiff_SitesJoined);
+ FRIEND_TEST_ALL_PREFIXES(FirstPartySets, ComputeSetsDiff_SitesLeft);
+ FRIEND_TEST_ALL_PREFIXES(FirstPartySets, ComputeSetsDiff_OwnerChanged);
+ FRIEND_TEST_ALL_PREFIXES(FirstPartySets, ComputeSetsDiff_OwnerLeft);
+ FRIEND_TEST_ALL_PREFIXES(FirstPartySets, ComputeSetsDiff_OwnerMemberRotate);
+ FRIEND_TEST_ALL_PREFIXES(FirstPartySets, ComputeSetsDiff_EmptySets);
};
} // namespace network
diff --git a/services/network/first_party_sets/first_party_sets_unittest.cc b/services/network/first_party_sets/first_party_sets_unittest.cc
index b929315d9b857e0f86d1d726f7cefefb7ad8e54c..2055619f4c999cbfd5a5ee4780e2eb5c1dad5816 100644
--- a/services/network/first_party_sets/first_party_sets_unittest.cc
+++ b/services/network/first_party_sets/first_party_sets_unittest.cc
@@ -7,6 +7,7 @@
#include <initializer_list>
#include "base/json/json_reader.h"
+#include "base/test/bind.h"
#include "net/base/schemeful_site.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/same_party_context.h"
@@ -204,6 +205,30 @@ TEST(FirstPartySets, SetsManuallySpecified_Invalid_RegisteredDomain_Member) {
EXPECT_THAT(sets.ParseAndSet("[]"), Pointee(IsEmpty()));
}
+TEST(FirstPartySets, SetsManuallySpecified_Valid_EmptyValue) {
+ FirstPartySets sets;
+ sets.SetManuallySpecifiedSet("");
+
+ // Set non-empty existing sets to distinguish the failure case from the no-op
+ // case when processing the manually-specified sets.
+ const std::string existing_sets = R"(
+ [
+ {
+ "owner": "https://example.test",
+ "members": ["https://member.test"]
+ }
+ ]
+ )";
+ ASSERT_TRUE(base::JSONReader::Read(existing_sets));
+
+ EXPECT_THAT(sets.ParseAndSet(existing_sets),
+ Pointee(UnorderedElementsAre(
+ Pair(SerializesTo("https://example.test"),
+ SerializesTo("https://example.test")),
+ Pair(SerializesTo("https://member.test"),
+ SerializesTo("https://example.test")))));
+}
+
TEST(FirstPartySets, SetsManuallySpecified_Valid_SingleMember) {
FirstPartySets sets;
sets.SetManuallySpecifiedSet("https://example.test,https://member.test");
@@ -469,6 +494,311 @@ TEST(FirstPartySets, SetsManuallySpecified_PrunesInducedSingletons) {
SerializesTo("https://example.test")))));
}
+TEST(FirstPartySets, ComputeSetsDiff_SitesJoined) {
+ auto old_sets = base::flat_map<net::SchemefulSite, net::SchemefulSite>{
+ {net::SchemefulSite(GURL("https://example.test")),
+ net::SchemefulSite(GURL("https://example.test"))},
+ {net::SchemefulSite(GURL("https://member1.test")),
+ net::SchemefulSite(GURL("https://example.test"))},
+ {net::SchemefulSite(GURL("https://member3.test")),
+ net::SchemefulSite(GURL("https://example.test"))}};
+
+ // Consistency check the reviewer-friendly JSON format matches the input.
+ ASSERT_THAT(FirstPartySets().ParseAndSet(R"(
+ [
+ {
+ "owner": "https://example.test",
+ "members": ["https://member1.test", "https://member3.test"]
+ }
+ ]
+ )"),
+ Pointee(old_sets));
+
+ FirstPartySets sets;
+ sets.ParseAndSet(R"(
+ [
+ {
+ "owner": "https://example.test",
+ "members": ["https://member1.test", "https://member3.test"]
+ },
+ {
+ "owner": "https://foo.test",
+ "members": ["https://member2.test"]
+ }
+ ]
+ )");
+ // "https://foo.test" and "https://member2.test" joined FPSs. We don't clear
+ // site data upon joining, so the computed diff should be empty set.
+ EXPECT_THAT(sets.ComputeSetsDiff(old_sets), IsEmpty());
+}
+
+TEST(FirstPartySets, ComputeSetsDiff_SitesLeft) {
+ auto old_sets = base::flat_map<net::SchemefulSite, net::SchemefulSite>{
+ {net::SchemefulSite(GURL("https://example.test")),
+ net::SchemefulSite(GURL("https://example.test"))},
+ {net::SchemefulSite(GURL("https://member1.test")),
+ net::SchemefulSite(GURL("https://example.test"))},
+ {net::SchemefulSite(GURL("https://member3.test")),
+ net::SchemefulSite(GURL("https://example.test"))},
+ {net::SchemefulSite(GURL("https://foo.test")),
+ net::SchemefulSite(GURL("https://foo.test"))},
+ {net::SchemefulSite(GURL("https://member2.test")),
+ net::SchemefulSite(GURL("https://foo.test"))}};
+
+ // Consistency check the reviewer-friendly JSON format matches the input.
+ ASSERT_THAT(FirstPartySets().ParseAndSet(R"(
+ [
+ {
+ "owner": "https://example.test",
+ "members": ["https://member1.test", "https://member3.test"]
+ },
+ {
+ "owner": "https://foo.test",
+ "members": ["https://member2.test"]
+ },
+ ]
+ )"),
+ Pointee(old_sets));
+
+ FirstPartySets sets;
+ sets.ParseAndSet(R"(
+ [
+ {
+ "owner": "https://example.test",
+ "members": ["https://member1.test"]
+ },
+ ]
+ )");
+ // Expected diff: "https://foo.test", "https://member2.test" and
+ // "https://member3.test" left FPSs.
+ EXPECT_THAT(sets.ComputeSetsDiff(old_sets),
+ UnorderedElementsAre(SerializesTo("https://foo.test"),
+ SerializesTo("https://member2.test"),
+ SerializesTo("https://member3.test")));
+}
+
+TEST(FirstPartySets, ComputeSetsDiff_OwnerChanged) {
+ auto old_sets = base::flat_map<net::SchemefulSite, net::SchemefulSite>{
+ {net::SchemefulSite(GURL("https://example.test")),
+ net::SchemefulSite(GURL("https://example.test"))},
+ {net::SchemefulSite(GURL("https://member1.test")),
+ net::SchemefulSite(GURL("https://example.test"))},
+ {net::SchemefulSite(GURL("https://foo.test")),
+ net::SchemefulSite(GURL("https://foo.test"))},
+ {net::SchemefulSite(GURL("https://member2.test")),
+ net::SchemefulSite(GURL("https://foo.test"))},
+ {net::SchemefulSite(GURL("https://member3.test")),
+ net::SchemefulSite(GURL("https://foo.test"))}};
+
+ // Consistency check the reviewer-friendly JSON format matches the input.
+ ASSERT_THAT(FirstPartySets().ParseAndSet(R"(
+ [
+ {
+ "owner": "https://example.test",
+ "members": ["https://member1.test"]
+ },
+ {
+ "owner": "https://foo.test",
+ "members": ["https://member2.test", "https://member3.test"]
+ },
+ ]
+ )"),
+ Pointee(old_sets));
+
+ FirstPartySets sets;
+ sets.ParseAndSet(R"(
+ [
+ {
+ "owner": "https://example.test",
+ "members": ["https://member1.test", "https://member3.test"]
+ },
+ {
+ "owner": "https://foo.test",
+ "members": ["https://member2.test"]
+ }
+ ]
+ )");
+ // Expected diff: "https://member3.test" changed owner.
+ EXPECT_THAT(sets.ComputeSetsDiff(old_sets),
+ UnorderedElementsAre(SerializesTo("https://member3.test")));
+}
+
+TEST(FirstPartySets, ComputeSetsDiff_OwnerLeft) {
+ auto old_sets = base::flat_map<net::SchemefulSite, net::SchemefulSite>{
+ {net::SchemefulSite(GURL("https://example.test")),
+ net::SchemefulSite(GURL("https://example.test"))},
+ {net::SchemefulSite(GURL("https://foo.test")),
+ net::SchemefulSite(GURL("https://example.test"))},
+ {net::SchemefulSite(GURL("https://bar.test")),
+ net::SchemefulSite(GURL("https://example.test"))}};
+
+ // Consistency check the reviewer-friendly JSON format matches the input.
+ ASSERT_THAT(FirstPartySets().ParseAndSet(R"(
+ [
+ {
+ "owner": "https://example.test",
+ "members": ["https://foo.test", "https://bar.test"]
+ }
+ ]
+ )"),
+ Pointee(old_sets));
+
+ FirstPartySets sets;
+ sets.ParseAndSet(R"(
+ [
+ {
+ "owner": "https://foo.test",
+ "members": ["https://bar.test"]
+ }
+ ]
+ )");
+ // Expected diff: "https://example.test" left FPSs, "https://foo.test" and
+ // "https://bar.test" changed owner.
+ // It would be valid to only have example.test in the diff, but our logic
+ // isn't sophisticated enough yet to know that foo.test and bar.test don't
+ // need to be included in the result.
+ EXPECT_THAT(sets.ComputeSetsDiff(old_sets),
+ UnorderedElementsAre(SerializesTo("https://example.test"),
+ SerializesTo("https://foo.test"),
+ SerializesTo("https://bar.test")));
+}
+
+TEST(FirstPartySets, ComputeSetsDiff_OwnerMemberRotate) {
+ auto old_sets = base::flat_map<net::SchemefulSite, net::SchemefulSite>{
+ {net::SchemefulSite(GURL("https://example.test")),
+ net::SchemefulSite(GURL("https://example.test"))},
+ {net::SchemefulSite(GURL("https://foo.test")),
+ net::SchemefulSite(GURL("https://example.test"))}};
+
+ // Consistency check the reviewer-friendly JSON format matches the input.
+ ASSERT_THAT(FirstPartySets().ParseAndSet(R"(
+ [
+ {
+ "owner": "https://example.test",
+ "members": ["https://foo.test"]
+ }
+ ]
+ )"),
+ Pointee(old_sets));
+
+ FirstPartySets sets;
+ sets.ParseAndSet(R"(
+ [
+ {
+ "owner": "https://foo.test",
+ "members": ["https://example.test"]
+ }
+ ]
+ )");
+ // Expected diff: "https://example.test" and "https://foo.test" changed owner.
+ // It would be valid to not include example.test and foo.test in the result,
+ // but our logic isn't sophisticated enough yet to know that.ß
+ EXPECT_THAT(sets.ComputeSetsDiff(old_sets),
+ UnorderedElementsAre(SerializesTo("https://example.test"),
+ SerializesTo("https://foo.test")));
+}
+
+TEST(FirstPartySets, ComputeSetsDiff_EmptySets) {
+ // Empty old_sets.
+ FirstPartySets sets;
+ sets.ParseAndSet(R"(
+ [
+ {
+ "owner": "https://example.test",
+ "members": ["https://member1.test"]
+ },
+ ]
+ )");
+ EXPECT_THAT(sets.ComputeSetsDiff({}), IsEmpty());
+
+ // Empty current sets.
+ auto old_sets = base::flat_map<net::SchemefulSite, net::SchemefulSite>{
+ {net::SchemefulSite(GURL("https://example.test")),
+ net::SchemefulSite(GURL("https://example.test"))},
+ {net::SchemefulSite(GURL("https://member1.test")),
+ net::SchemefulSite(GURL("https://example.test"))}};
+ // Consistency check the reviewer-friendly JSON format matches the input.
+ ASSERT_THAT(FirstPartySets().ParseAndSet(R"(
+ [
+ {
+ "owner": "https://example.test",
+ "members": ["https://member1.test"]
+ }
+ ]
+ )"),
+ Pointee(old_sets));
+ EXPECT_THAT(FirstPartySets().ComputeSetsDiff(old_sets),
+ UnorderedElementsAre(SerializesTo("https://example.test"),
+ SerializesTo("https://member1.test")));
+}
+
+TEST(FirstPartySets, ClearSiteDataOnChangedSetsIfReady_NotReady) {
+ int callback_calls = 0;
+ auto callback = base::BindLambdaForTesting(
+ [&](const std::string& got) { callback_calls++; });
+ // component sets not ready.
+ {
+ FirstPartySets sets;
+ callback_calls = 0;
+ sets.SetPersistedSets("{}");
+ sets.SetManuallySpecifiedSet("");
+ sets.SetOnSiteDataCleared(callback);
+ EXPECT_EQ(callback_calls, 0);
+ }
+ // manual sets not ready.
+ {
+ FirstPartySets sets;
+ callback_calls = 0;
+ sets.ParseAndSet("[]");
+ sets.SetPersistedSets("{}");
+ sets.SetOnSiteDataCleared(callback);
+ EXPECT_EQ(callback_calls, 0);
+ }
+ // persisted sets not ready.
+ {
+ FirstPartySets sets;
+ callback_calls = 0;
+ sets.ParseAndSet("[]");
+ sets.SetManuallySpecifiedSet("");
+ sets.SetOnSiteDataCleared(callback);
+ EXPECT_EQ(callback_calls, 0);
+ }
+ // callback not set.
+ {
+ FirstPartySets sets;
+ callback_calls = 0;
+ sets.ParseAndSet("[]");
+ sets.SetManuallySpecifiedSet("");
+ sets.SetPersistedSets("{}");
+ EXPECT_EQ(callback_calls, 0);
+ }
+}
+
+// The callback only runs when `old_sets` is generated and `sets` has merged the
+// inputs from Component Updater and command line flag.
+TEST(FirstPartySets, ClearSiteDataOnChangedSetsIfReady_Ready) {
+ FirstPartySets sets;
+ int callback_calls = 0;
+ sets.ParseAndSet(R"([
+ {
+ "owner": "https://example.test",
+ "members": ["https://member1.test"]
+ }
+ ])");
+ sets.SetManuallySpecifiedSet("https://example2.test,https://member2.test");
+ sets.SetPersistedSets(
+ R"({"https://example.test":"https://example.test",
+ "https://member1.test":"https://example.test"})");
+ sets.SetOnSiteDataCleared(base::BindLambdaForTesting([&](const std::string&
+ got) {
+ EXPECT_EQ(
+ got,
+ R"({"https://member1.test":"https://example.test","https://member2.test":"https://example2.test"})");
+ callback_calls++;
+ }));
+ EXPECT_EQ(callback_calls, 1);
+}
+
class FirstPartySetsTest : public ::testing::Test {
public:
FirstPartySetsTest() {
diff --git a/services/network/network_service.cc b/services/network/network_service.cc
index 5d598ff6c626510bf1da00d35bc9ba4179bac93e..c850d6950aa7777cdc5c2056d4b80c9dd44d3af9 100644
--- a/services/network/network_service.cc
+++ b/services/network/network_service.cc
@@ -343,8 +343,7 @@ void NetworkService::Initialize(mojom::NetworkServiceParamsPtr params,
}
first_party_sets_ = std::make_unique<FirstPartySets>();
- if (net::cookie_util::IsFirstPartySetsEnabled() &&
- command_line->HasSwitch(switches::kUseFirstPartySet)) {
+ if (net::cookie_util::IsFirstPartySetsEnabled()) {
first_party_sets_->SetManuallySpecifiedSet(
command_line->GetSwitchValueASCII(switches::kUseFirstPartySet));
}
@@ -785,6 +784,14 @@ void NetworkService::SetFirstPartySets(const std::string& raw_sets) {
first_party_sets_->ParseAndSet(raw_sets);
}
+void NetworkService::SetPersistedFirstPartySetsAndGetCurrentSets(
+ const std::string& persisted_sets,
+ mojom::NetworkService::SetPersistedFirstPartySetsAndGetCurrentSetsCallback
+ callback) {
+ first_party_sets_->SetPersistedSets(persisted_sets);
+ first_party_sets_->SetOnSiteDataCleared(std::move(callback));
+}
+
void NetworkService::SetExplicitlyAllowedPorts(
const std::vector<uint16_t>& ports) {
net::SetExplicitlyAllowedPorts(ports);
diff --git a/services/network/network_service.h b/services/network/network_service.h
index 1da4505fc9fe478e00353cd55e615878ea875aa0..963e22f6d5e957684dc56dd6e3ae31fa430a355e 100644
--- a/services/network/network_service.h
+++ b/services/network/network_service.h
@@ -204,6 +204,10 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkService
void BindTestInterface(
mojo::PendingReceiver<mojom::NetworkServiceTest> receiver) override;
void SetFirstPartySets(const std::string& raw_sets) override;
+ void SetPersistedFirstPartySetsAndGetCurrentSets(
+ const std::string& persisted_sets,
+ mojom::NetworkService::SetPersistedFirstPartySetsAndGetCurrentSetsCallback
+ callback) override;
void SetExplicitlyAllowedPorts(const std::vector<uint16_t>& ports) override;
// Returns an HttpAuthHandlerFactory for the given NetworkContext.
diff --git a/services/network/network_service_unittest.cc b/services/network/network_service_unittest.cc
index bd8ed7abe5870d23e3b0430f29f0448cf425fabc..dffa318ab85d6851c54d0f3c38ab6bb72f274f40 100644
--- a/services/network/network_service_unittest.cc
+++ b/services/network/network_service_unittest.cc
@@ -925,6 +925,7 @@ class NetworkServiceTestWithService : public testing::Test {
void SetUp() override {
test_server_.AddDefaultHandlers(base::FilePath(kServicesTestData));
ASSERT_TRUE(test_server_.Start());
+ scoped_features_.InitAndEnableFeature(net::features::kFirstPartySets);
service_ = NetworkService::CreateForTesting();
service_->Bind(network_service_.BindNewPipeAndPassReceiver());
}
@@ -989,7 +990,7 @@ class NetworkServiceTestWithService : public testing::Test {
mojo::Remote<mojom::NetworkContext> network_context_;
mojo::Remote<mojom::URLLoader> loader_;
- DISALLOW_COPY_AND_ASSIGN(NetworkServiceTestWithService);
+ base::test::ScopedFeatureList scoped_features_;
};
// Verifies that loading a URL through the network service's mojo interface
@@ -1169,6 +1170,18 @@ TEST_F(NetworkServiceTestWithService, GetNetworkList) {
run_loop.Run();
}
+TEST_F(NetworkServiceTestWithService,
+ SetPersistedFirstPartySetsAndGetCurrentSets) {
+ base::RunLoop run_loop;
+ network_service_->SetPersistedFirstPartySetsAndGetCurrentSets(
+ "", base::BindLambdaForTesting([&](const std::string& got) {
+ EXPECT_EQ(got, "{}");
+ run_loop.Quit();
+ }));
+ network_service_->SetFirstPartySets("");
+ run_loop.Run();
+}
+
class TestNetworkChangeManagerClient
: public mojom::NetworkChangeManagerClient {
public:
diff --git a/services/network/public/mojom/network_service.mojom b/services/network/public/mojom/network_service.mojom
index fe5450b20b3c4a8490e853dd236bf6baefa90b81..59fbbde6ffc30d51304a72f402eee7c664ea111b 100644
--- a/services/network/public/mojom/network_service.mojom
+++ b/services/network/public/mojom/network_service.mojom
@@ -373,6 +373,14 @@ interface NetworkService {
// cleared (except for the manually-specified set, if one exists).
SetFirstPartySets(string raw_sets);
+ // Sets the First-Party Sets data that was persisted to compare it with the
+ // current First-Party Sets data set by `SetFirstPartySets()`, which is
+ // considered more up-to-date, and returns a serialized version of the current
+ // one. Both input and output are in format of the JSON-encoded string
+ // representation of a map of site -> site.
+ SetPersistedFirstPartySetsAndGetCurrentSets(string persisted_sets)
+ => (string up_to_date_sets);
+
// Sets the list of ports which will be permitted even if they normally would
// be restricted.
SetExplicitlyAllowedPorts(array<uint16> ports);

View File

@@ -35,10 +35,10 @@ index 5b4d70991e19edcdfee731c56251932bf43e535f..fe1977c5e6ce0f5b30e8be529b9efa51
#endif // CHROME_BROWSER_ANDROID_DOCUMENT_DOCUMENT_WEB_CONTENTS_DELEGATE_H_
diff --git a/chrome/browser/media/offscreen_tab.cc b/chrome/browser/media/offscreen_tab.cc
index d6295d809381f4f4a86a9948762079232ba6c93c..ad429250984cf367e1194bda67bc56a886f650ae 100644
index c0823105ecc86ce2e60ede44be29a14889dad887..bb0f2672c6e565657500e617b4eb416c0575dac7 100644
--- a/chrome/browser/media/offscreen_tab.cc
+++ b/chrome/browser/media/offscreen_tab.cc
@@ -283,8 +283,7 @@ bool OffscreenTab::IsWebContentsCreationOverridden(
@@ -284,8 +284,7 @@ bool OffscreenTab::IsWebContentsCreationOverridden(
content::SiteInstance* source_site_instance,
content::mojom::WindowContainerType window_container_type,
const GURL& opener_url,
@@ -49,10 +49,10 @@ index d6295d809381f4f4a86a9948762079232ba6c93c..ad429250984cf367e1194bda67bc56a8
// uses this to spawn new windows/tabs, which is also not allowed for
// offscreen tabs.
diff --git a/chrome/browser/media/offscreen_tab.h b/chrome/browser/media/offscreen_tab.h
index 3fd38bcb861174f99369d0e53b9946c632baf21a..de1a4df623538cc2857f8bb85b05e17d411c45a0 100644
index c80128b816cc77b95af215384fdc36b2150f95ea..3fe773e671d1c087eaf1303ca60883597c0c3907 100644
--- a/chrome/browser/media/offscreen_tab.h
+++ b/chrome/browser/media/offscreen_tab.h
@@ -103,8 +103,7 @@ class OffscreenTab final : public ProfileObserver,
@@ -107,8 +107,7 @@ class OffscreenTab final : public ProfileObserver,
content::SiteInstance* source_site_instance,
content::mojom::WindowContainerType window_container_type,
const GURL& opener_url,
@@ -94,10 +94,10 @@ index 07014765f33bdddebcc5bc32a2713d6523faf394..f866f69f9c810d89f1a0e9e4952293f6
content::WebContents* source,
const content::OpenURLParams& params) override;
diff --git a/chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents.cc b/chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents.cc
index ef84e04d628fb5cdbaf8fbbf84af3bf23e00c522..f1ee0bee5bfd08227a29498f8410d5d3582e02c3 100644
index ba376cca99e6b8b367c6a4cfc9925b940728b9fc..f1b831507d628d35cc65f697ffc832568fc28193 100644
--- a/chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents.cc
+++ b/chrome/browser/ui/ash/keyboard/chrome_keyboard_web_contents.cc
@@ -66,8 +66,7 @@ class ChromeKeyboardContentsDelegate : public content::WebContentsDelegate,
@@ -72,8 +72,7 @@ class ChromeKeyboardContentsDelegate : public content::WebContentsDelegate,
content::SiteInstance* source_site_instance,
content::mojom::WindowContainerType window_container_type,
const GURL& opener_url,
@@ -108,10 +108,10 @@ index ef84e04d628fb5cdbaf8fbbf84af3bf23e00c522..f1ee0bee5bfd08227a29498f8410d5d3
}
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 61724ab53609f80cf5a0139c8bdb2ad1fb0413b2..b8647710bf9a16e8ffc3ca3b25aa4f6c584fa9be 100644
index c8d3c04475fe3ee60ec4671ee47c18aa78840dd1..e5d95132b4f20f17f328e41cf6d0cf839787222a 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -1789,12 +1789,11 @@ bool Browser::IsWebContentsCreationOverridden(
@@ -1790,12 +1790,11 @@ bool Browser::IsWebContentsCreationOverridden(
content::SiteInstance* source_site_instance,
content::mojom::WindowContainerType window_container_type,
const GURL& opener_url,
@@ -155,10 +155,10 @@ index ff97ac6e97c688d677053a5f01546a4c2d91ff1d..1da6a9c32b883a17975e61d603639182
// uses this to spawn new windows/tabs, which is also not allowed for
// local presentations.
diff --git a/chrome/browser/ui/media_router/presentation_receiver_window_controller.h b/chrome/browser/ui/media_router/presentation_receiver_window_controller.h
index 058ec72442d59989c4d6df4a7c791ecfeff0ef99..f7c8c2139382cb2e290c561624291afe647383cf 100644
index 45cd02ecf7b7acb107f95656b3fa07a5fca2ea95..b06ca2dbdd0c21554802ab3b99576b381d0e4ddb 100644
--- a/chrome/browser/ui/media_router/presentation_receiver_window_controller.h
+++ b/chrome/browser/ui/media_router/presentation_receiver_window_controller.h
@@ -99,8 +99,7 @@ class PresentationReceiverWindowController final
@@ -104,8 +104,7 @@ class PresentationReceiverWindowController final
content::SiteInstance* source_site_instance,
content::mojom::WindowContainerType window_container_type,
const GURL& opener_url,
@@ -232,10 +232,10 @@ index c5c5a7b63b5b3b62a9517cbef3ae23ce57a3c89c..4f1b7e88d6d2ae89a60311c8aeb1fcee
void AddNewContents(content::WebContents* source,
std::unique_ptr<content::WebContents> new_contents,
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index bc84aa5826d4ca8aef8f496acd3569152007b7a8..b6524566b96a141ba710441ab70d17f46e5b1b9a 100644
index ad1b4abe0390215e007ad2db8d972661470e94ed..d3593a6f3e9f6cba5823169d36fd93a6f97608ae 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3687,8 +3687,7 @@ FrameTree* WebContentsImpl::CreateNewWindow(
@@ -3682,8 +3682,7 @@ FrameTree* WebContentsImpl::CreateNewWindow(
if (delegate_ && delegate_->IsWebContentsCreationOverridden(
source_site_instance, params.window_container_type,
@@ -316,10 +316,10 @@ index b794ee4204fb8eaf90084e762f80988af13609b4..ac4e00f2ef1d2a722851d88531c28e65
}
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
index bb90319f768ed2f3a3e530d64bf622de585ce163..d84de1d218267887f6b8624f913438ebc4aa7a79 100644
index 647a9bdf39c60f61cf3c9520bc7e57e206678cd0..59860dc143467168e2ce596f26c84ed8a26be6ed 100644
--- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
+++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h
@@ -158,8 +158,7 @@ class MimeHandlerViewGuest
@@ -167,8 +167,7 @@ class MimeHandlerViewGuest
content::SiteInstance* source_site_instance,
content::mojom::WindowContainerType window_container_type,
const GURL& opener_url,

View File

@@ -7,10 +7,10 @@ spellchecker uses a few IDS_ resources. We need to load these from
Electrons grit header instead of Chromes
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 8847ed67e305d746c671afb49b445afaf24b85b3..3acfeb5e5bf721fabe2339e389193cd9e154e293 100644
index 7f050d074a057b9226444432625e3df856c5d1d8..27f4f83da31dbd3a1e754279e760dddf00224e1b 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -6689,6 +6689,7 @@ static_library("browser") {
@@ -6736,6 +6736,7 @@ static_library("browser") {
deps += [
"//components/spellcheck/browser",
"//components/spellcheck/common",
@@ -32,7 +32,7 @@ index 2b7aa1add57dccbcbf8202cead5b7d2d5a174270..2ba03fc045f2e4bb12f173aacb6581cc
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"
diff --git a/components/language/core/browser/BUILD.gn b/components/language/core/browser/BUILD.gn
index 1ece01a38683e81fdf07ec475c2bf1bf19fab891..668789ca5c0b3b6381313dbb4cccf119b80e9b66 100644
index e2f54334ed199b0cb4658c1b1c956dd8bc8b2bf0..0241849170f6d589d011c28127abfd9bc830e5e5 100644
--- a/components/language/core/browser/BUILD.gn
+++ b/components/language/core/browser/BUILD.gn
@@ -28,6 +28,7 @@ static_library("browser") {

View File

@@ -52,10 +52,10 @@ index d6d896b87bb327bd7387335bd5bbac4616316f1e..ec0293ba8b66df5c9a34435cb2a0c9a3
NotifyKeyPressed(ui::Accelerator(key_code, modifiers));
}
diff --git a/chrome/browser/extensions/global_shortcut_listener_ozone.h b/chrome/browser/extensions/global_shortcut_listener_ozone.h
index 27655641551afe9763cd76afe366f04e56efbbc6..14ff891a057464a1bd570cb14e127ce865d9ba91 100644
index 866c4e6c1ff8c1a2399d943837fce1753c8ea1a5..ecde46fe5f8c5f250a7cb505c86ae59cfa1bd623 100644
--- a/chrome/browser/extensions/global_shortcut_listener_ozone.h
+++ b/chrome/browser/extensions/global_shortcut_listener_ozone.h
@@ -41,7 +41,8 @@ class GlobalShortcutListenerOzone
@@ -46,7 +46,8 @@ class GlobalShortcutListenerOzone
void OnKeyPressed(ui::KeyboardCode key_code,
bool is_alt_down,
bool is_ctrl_down,

View File

@@ -75,10 +75,10 @@ index 39557cce474439238255ecd28030215085db0c81..5b3f980837911c710686ab91a2a81c31
// Used by WebView to sample crashes without generating the unwanted dumps. If
// the returned value is less than 100, crash dumping will be sampled to that
diff --git a/components/crash/core/app/crashpad_linux.cc b/components/crash/core/app/crashpad_linux.cc
index 1abde7faf44a4526d7c622e6ce2d6fafe957a4c8..68d745567c1a0e37fa4ebc9e7e705d2a24f3e1fe 100644
index 99e5ee6eeadb9ff12b7b027ceba4c838a8fedc6d..838ccd82b5828c1c58b3089064b7baeb35982f7e 100644
--- a/components/crash/core/app/crashpad_linux.cc
+++ b/components/crash/core/app/crashpad_linux.cc
@@ -165,6 +165,7 @@ base::FilePath PlatformCrashpadInitialization(
@@ -178,6 +178,7 @@ base::FilePath PlatformCrashpadInitialization(
// where crash_reporter provides it's own values for lsb-release.
annotations["lsb-release"] = base::GetLinuxDistro();
#endif
@@ -86,7 +86,7 @@ index 1abde7faf44a4526d7c622e6ce2d6fafe957a4c8..68d745567c1a0e37fa4ebc9e7e705d2a
std::vector<std::string> arguments;
if (crash_reporter_client->ShouldMonitorCrashHandlerExpensively()) {
@@ -186,6 +187,13 @@ base::FilePath PlatformCrashpadInitialization(
@@ -199,6 +200,13 @@ base::FilePath PlatformCrashpadInitialization(
}
#endif

View File

@@ -19,10 +19,10 @@ https://chromium-review.googlesource.com/c/chromium/src/+/1901591, we should try
re-submitting the patch.
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc
index 7e7a16e6f9cb187a834ecc44b27f288c9146b6a6..a2aca80f9a95c345e6d394b78d3341534fd0450f 100644
index 29fd158813a0d4ecd5f7cb41cd2c9a6bf8a29f6c..b3f2e64cb729f43faeb0e3af39ca5469d77fb503 100644
--- a/content/app/content_main_runner_impl.cc
+++ b/content/app/content_main_runner_impl.cc
@@ -751,7 +751,7 @@ int ContentMainRunnerImpl::Initialize(const ContentMainParams& params) {
@@ -752,7 +752,7 @@ int ContentMainRunnerImpl::Initialize(const ContentMainParams& params) {
}
#endif

View File

@@ -38,10 +38,10 @@ index a3e1de40e843b5450f417a0455e0e7d7dee1d1bd..63befdc162a4b4a16e8c5099abb0f5af
int DesktopMediaListBase::GetSourceCount() const {
diff --git a/chrome/browser/media/webrtc/desktop_media_list_base.h b/chrome/browser/media/webrtc/desktop_media_list_base.h
index a1038183d5b44ca760576bff55534b5841e2e9d2..e9cc308271c561b249ace7dc9e703b549fcfbbd2 100644
index c87535950fdc6cf1c5641835a69971d0e1654025..a6151407ae3ac3456d0af07330db3d1ae82bd6a9 100644
--- a/chrome/browser/media/webrtc/desktop_media_list_base.h
+++ b/chrome/browser/media/webrtc/desktop_media_list_base.h
@@ -31,7 +31,7 @@ class DesktopMediaListBase : public DesktopMediaList {
@@ -35,7 +35,7 @@ class DesktopMediaListBase : public DesktopMediaList {
void SetThumbnailSize(const gfx::Size& thumbnail_size) override;
void SetViewDialogWindowId(content::DesktopMediaID dialog_id) override;
void StartUpdating(DesktopMediaListObserver* observer) override;
@@ -51,7 +51,7 @@ index a1038183d5b44ca760576bff55534b5841e2e9d2..e9cc308271c561b249ace7dc9e703b54
const Source& GetSource(int index) const override;
DesktopMediaList::Type GetMediaListType() const override;
diff --git a/chrome/browser/media/webrtc/native_desktop_media_list.cc b/chrome/browser/media/webrtc/native_desktop_media_list.cc
index 5a851f4c89b4ed2b41640bf8bad47b7d8eba8ca1..2dc65acfc355180dc966aab76b39fc1956325b84 100644
index 4c822ebcca602ecbd30fbc79d72a1ecabc273229..d9f45c280ce4f5771c379033d8034e68681e42f8 100644
--- a/chrome/browser/media/webrtc/native_desktop_media_list.cc
+++ b/chrome/browser/media/webrtc/native_desktop_media_list.cc
@@ -16,7 +16,7 @@
@@ -74,7 +74,7 @@ index 5a851f4c89b4ed2b41640bf8bad47b7d8eba8ca1..2dc65acfc355180dc966aab76b39fc19
#endif
} // namespace
@@ -425,6 +426,8 @@ void NativeDesktopMediaList::RefreshForVizFrameSinkWindows(
@@ -427,6 +428,8 @@ void NativeDesktopMediaList::RefreshForVizFrameSinkWindows(
FROM_HERE, base::BindOnce(&Worker::RefreshThumbnails,
base::Unretained(worker_.get()),
std::move(native_ids), thumbnail_size_));

View File

@@ -15,10 +15,10 @@ the redraw locking mechanism, which fixes these issues. The electron issue
can be found at https://github.com/electron/electron/issues/1821
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
index 21e96caaa87538f962b7446dc889bd0ece3ca986..21d64ed9c116088fb5f4becad8a5e827ff47f1c4 100644
index 81132959080d21a341fcc418fcd7c73cf62b78c4..9cac7284aeacda2d877502f97d9e442ae4fdadd3 100644
--- a/ui/views/win/hwnd_message_handler.cc
+++ b/ui/views/win/hwnd_message_handler.cc
@@ -307,6 +307,10 @@ constexpr int kSynthesizedMouseMessagesTimeDifference = 500;
@@ -309,6 +309,10 @@ constexpr int kSynthesizedMouseMessagesTimeDifference = 500;
} // namespace
@@ -29,7 +29,7 @@ index 21e96caaa87538f962b7446dc889bd0ece3ca986..21d64ed9c116088fb5f4becad8a5e827
// A scoping class that prevents a window from being able to redraw in response
// to invalidations that may occur within it for the lifetime of the object.
//
@@ -358,6 +362,7 @@ class HWNDMessageHandler::ScopedRedrawLock {
@@ -360,6 +364,7 @@ class HWNDMessageHandler::ScopedRedrawLock {
cancel_unlock_(false),
should_lock_(owner_->IsVisible() && !owner->HasChildRenderingWindow() &&
::IsWindow(hwnd_) &&
@@ -37,7 +37,7 @@ index 21e96caaa87538f962b7446dc889bd0ece3ca986..21d64ed9c116088fb5f4becad8a5e827
(!(GetWindowLong(hwnd_, GWL_STYLE) & WS_CAPTION) ||
!ui::win::IsAeroGlassEnabled())) {
if (should_lock_)
@@ -976,6 +981,10 @@ HWNDMessageHandler::RegisterUnadjustedMouseEvent() {
@@ -979,6 +984,10 @@ HWNDMessageHandler::RegisterUnadjustedMouseEvent() {
return scoped_enable;
}
@@ -49,10 +49,10 @@ index 21e96caaa87538f962b7446dc889bd0ece3ca986..21d64ed9c116088fb5f4becad8a5e827
// HWNDMessageHandler, gfx::WindowImpl overrides:
diff --git a/ui/views/win/hwnd_message_handler.h b/ui/views/win/hwnd_message_handler.h
index a338ec40a4052a40304d7cf8c4e222f539412e68..6c109dde127bb04b33d18f030ffe4ec2a2e044c6 100644
index fd402c3d6b0130dc91d6d369bc3337f9955ccf6d..36caa4704af99a6769cf359582a11b025a2b24a0 100644
--- a/ui/views/win/hwnd_message_handler.h
+++ b/ui/views/win/hwnd_message_handler.h
@@ -202,6 +202,8 @@ class VIEWS_EXPORT HWNDMessageHandler : public gfx::WindowImpl,
@@ -206,6 +206,8 @@ class VIEWS_EXPORT HWNDMessageHandler : public gfx::WindowImpl,
using TouchIDs = std::set<DWORD>;
enum class DwmFrameState { kOff, kOn };

View File

@@ -20,10 +20,10 @@ to deal with color spaces. That is being tracked at
https://crbug.com/634542 and https://crbug.com/711107.
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 3be9e62159ad6ac98e1cd0790c7c06921effe5e3..356a8f451061b0bddeb1fcc1b64d7e48b7e8c8a6 100644
index c841d7f51ea7a99fe2e806e4102bf91d75853ed0..ed983081afb0f4ead01da32cd56d61ecb63d33dd 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -1802,6 +1802,10 @@ void LayerTreeHostImpl::SetIsLikelyToRequireADraw(
@@ -1789,6 +1789,10 @@ void LayerTreeHostImpl::SetIsLikelyToRequireADraw(
gfx::ColorSpace LayerTreeHostImpl::GetRasterColorSpace(
gfx::ContentColorUsage content_color_usage) const {
@@ -60,7 +60,7 @@ index e58b4023652785fa8ea47236a5ad7237c7ea6ed2..4ec673ea93410ee00b1af4330fdc8b52
bool force_antialiasing = false;
bool force_blending_with_shaders = false;
diff --git a/components/viz/host/renderer_settings_creation.cc b/components/viz/host/renderer_settings_creation.cc
index f919df4d79a1168269c1538ac13a2a944586cf4e..fc34cf5d7dab95e7b6fc0576674b3e2be1792c65 100644
index aab0c5d1dbdfce9b56ada8861a0a7ffb42704a96..430ad6cfc7bba31bc097e654765fb94d42bcdfe5 100644
--- a/components/viz/host/renderer_settings_creation.cc
+++ b/components/viz/host/renderer_settings_creation.cc
@@ -17,6 +17,7 @@
@@ -229,7 +229,7 @@ index 1e2ad6423a5e316a9a1713abab7579ea0d2a82f9..22df5e1728e5dc2879c9b96911f6e734
+
+#undef PATCH_CS
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index cc90e0aae77c0ca80eeab84eee8ff89a1295dbd2..fa96e7fa8c4f5d14da548398e533b10f153723ed 100644
index 49d6d4107c0e4e0c37471394c5b7bdf84b3c823a..f0773c8fe1ccf0a3f920c840719ad7ee07d5d0db 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -224,6 +224,7 @@ GpuTerminationStatus ConvertToGpuTerminationStatus(
@@ -241,10 +241,10 @@ index cc90e0aae77c0ca80eeab84eee8ff89a1295dbd2..fa96e7fa8c4f5d14da548398e533b10f
sandbox::policy::switches::kGpuSandboxAllowSysVShm,
sandbox::policy::switches::kGpuSandboxFailuresFatal,
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 0a53d80feb2cdaa599da3ea87a8a6a8f8327ae92..532e82ca5145853b218c1e835d0b71bc1b158564 100644
index 3555928a29b3c6022621c4e9b65531edbefa7797..9b36af8cd02f56810b6b8ed86d1c8ba544567233 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -183,6 +183,7 @@
@@ -182,6 +182,7 @@
#include "ui/accessibility/accessibility_switches.h"
#include "ui/base/ui_base_switches.h"
#include "ui/display/display_switches.h"
@@ -252,7 +252,7 @@ index 0a53d80feb2cdaa599da3ea87a8a6a8f8327ae92..532e82ca5145853b218c1e835d0b71bc
#include "ui/gl/gl_switches.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -3375,6 +3376,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
@@ -3416,6 +3417,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
// Propagate the following switches to the renderer command line (along
// with any associated values) if present in the browser command line.
static const char* const kSwitchNames[] = {
@@ -293,7 +293,7 @@ index 94ca8fd75212fa5c7b90823a112309dd7961353b..566393827ef739eb8fc0e24e6ee505e1
}
diff --git a/third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.cc b/third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.cc
index 083e7c6d49574ae5d1beeba02b334ae864d60afb..85626cd2354b0c13caceb8a1b4f7d585f400cb2c 100644
index 62ff201dae894250b84ad3c32f477ff9324e1906..e53116a55c234f1cbc2d8f05cc8090e931095f1a 100644
--- a/third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.cc
+++ b/third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.cc
@@ -25,6 +25,7 @@

View File

@@ -6,10 +6,10 @@ Subject: fix: disabling compositor recycling
Compositor recycling is useful for Chrome because there can be many tabs and spinning up a compositor for each one would be costly. In practice, Chrome uses the parent compositor code path of browser_compositor_view_mac.mm; the NSView of each tab is detached when it's hidden and attached when it's shown. For Electron, there is no parent compositor, so we're forced into the "own compositor" code path, which seems to be non-optimal and pretty ruthless in terms of the release of resources. Electron has no real concept of multiple tabs per window, so it should be okay to disable this ruthless recycling altogether in Electron.
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index 515d1588c0de8daa503df91338dc3a5c072c5690..b524f3125f955ba065c2d87e992606ec88b95b55 100644
index 5aac5fcfe781e282b748630c07341d1b465d99ac..987b0e85ead3a33c8d0a93ac9a6c95782b22af96 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -483,7 +483,11 @@
@@ -491,7 +491,11 @@
return;
host()->WasHidden();

View File

@@ -6,10 +6,10 @@ Subject: disable_hidden.patch
Electron uses this to disable background throttling for hidden windows.
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 095ae394b95b07f17295611dc1ade9ae7b4f2c1c..b72e3f6ab2a43e8a7f707e9634fb3a4abb87e993 100644
index 3ec7188cc015df085e46d3dac1374af1d92ae4d3..a1632e19959d163eecafef484204aa0dba919897 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -773,6 +773,9 @@ void RenderWidgetHostImpl::WasHidden() {
@@ -776,6 +776,9 @@ void RenderWidgetHostImpl::WasHidden() {
if (is_hidden_)
return;
@@ -20,12 +20,12 @@ index 095ae394b95b07f17295611dc1ade9ae7b4f2c1c..b72e3f6ab2a43e8a7f707e9634fb3a4a
blink::mojom::PointerLockResult::kWrongDocument);
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index 59b0439a6ba6959b5c37c316fcb955a1486c343d..2b93a57863f4e0e5e41fbf4a640510d70b794830 100644
index b7a3b2bc9032934a8537a49b8e1fd895eae721dd..aa864537cf2c3002623427ecd10ff62c88e75aba 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -856,6 +856,9 @@ class CONTENT_EXPORT RenderWidgetHostImpl
mojom::CreateFrameWidgetParamsPtr
BindAndGenerateCreateFrameWidgetParamsForNewWindow();
@@ -864,6 +864,9 @@ class CONTENT_EXPORT RenderWidgetHostImpl
void OnLocalSurfaceIdChanged(
const cc::RenderFrameMetadata& metadata) override;
+ // Electron: Prevents the widget from getting hidden.
+ bool disable_hidden_ = false;
@@ -34,7 +34,7 @@ index 59b0439a6ba6959b5c37c316fcb955a1486c343d..2b93a57863f4e0e5e41fbf4a640510d7
// |routing_id| must not be MSG_ROUTING_NONE.
// If this object outlives |delegate|, DetachDelegate() must be called when
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index 2f508cbb53a9d5734c1be40827b5b4794b639056..555937e97250f62d68860ec86026efafe6a5d616 100644
index afdd5aa89be899a1176a770c7a4c06f7fa2579ef..0ea6f2ee5bfd41bfb36db6de19a42128b4894dd8 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -605,7 +605,7 @@ void RenderWidgetHostViewAura::HideImpl() {

View File

@@ -24,10 +24,10 @@ This patch temporarily disables the metrics so we can have green CI, and we
should continue seeking for a real fix.
diff --git a/content/browser/renderer_host/navigator.cc b/content/browser/renderer_host/navigator.cc
index cd3055cb99e117868d6b1d2d7a4faedca0a3981f..5f5bf984b28c5f708db632f1771601b08f23a3b1 100644
index cb2bde331db92cd29a3af5ca2c065bbf02b39208..46ba89e09cf228bc022142e040763b5a9332764c 100644
--- a/content/browser/renderer_host/navigator.cc
+++ b/content/browser/renderer_host/navigator.cc
@@ -1098,6 +1098,7 @@ void Navigator::RecordNavigationMetrics(
@@ -1105,6 +1105,7 @@ void Navigator::RecordNavigationMetrics(
.InMilliseconds());
}
@@ -35,7 +35,7 @@ index cd3055cb99e117868d6b1d2d7a4faedca0a3981f..5f5bf984b28c5f708db632f1771601b0
// If this is a same-process navigation and we have timestamps for unload
// durations, fill those metrics out as well.
if (params.unload_start && params.unload_end &&
@@ -1144,6 +1145,7 @@ void Navigator::RecordNavigationMetrics(
@@ -1151,6 +1152,7 @@ void Navigator::RecordNavigationMetrics(
first_before_unload_start_time)
.InMilliseconds());
}

View File

@@ -11,10 +11,10 @@ This regressed in https://chromium-review.googlesource.com/c/chromium/src/+/2572
Upstream: https://chromium-review.googlesource.com/c/chromium/src/+/2598393
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 395bb615c0a2d5a49cfbc6d8a9e9f3d9a809b595..dcf47a194713764d0ccb588ff07de7fc43e30bdc 100644
index ebf2d997f03c36e5242405002c7dce583aec31dc..2cf1ac25f3c4ca0348502a37dbf84111842ced93 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -2357,7 +2357,7 @@ const blink::WebView* RenderFrameImpl::GetWebView() const {
@@ -2347,7 +2347,7 @@ const blink::WebView* RenderFrameImpl::GetWebView() const {
}
const blink::web_pref::WebPreferences& RenderFrameImpl::GetBlinkPreferences() {

View File

@@ -6,10 +6,10 @@ Subject: feat: enable setting aspect ratio to 0
Make SetAspectRatio accept 0 as valid input, which would reset to null.
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
index 17668789847d1a7f7037b9507adb824c02f1cb31..6401d9b00d6c7071c16ca44866a3d53116ddfb89 100644
index d8411ddc4fd88a1416181cce366b112df3f48d63..a33ec53b96fec67feacc92e71fa6ed17c5e47d7d 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -527,7 +527,7 @@ void DesktopWindowTreeHostWin::SetOpacity(float opacity) {
@@ -525,7 +525,7 @@ void DesktopWindowTreeHostWin::SetOpacity(float opacity) {
}
void DesktopWindowTreeHostWin::SetAspectRatio(const gfx::SizeF& aspect_ratio) {
@@ -19,10 +19,10 @@ index 17668789847d1a7f7037b9507adb824c02f1cb31..6401d9b00d6c7071c16ca44866a3d531
aspect_ratio.height());
}
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
index 21d64ed9c116088fb5f4becad8a5e827ff47f1c4..7f6ab51b2d83a8c555de1d1e19a40b93b438fbd4 100644
index 9cac7284aeacda2d877502f97d9e442ae4fdadd3..33c533665589f78425488547b550876c5161f010 100644
--- a/ui/views/win/hwnd_message_handler.cc
+++ b/ui/views/win/hwnd_message_handler.cc
@@ -926,8 +926,11 @@ void HWNDMessageHandler::SetFullscreen(bool fullscreen) {
@@ -929,8 +929,11 @@ void HWNDMessageHandler::SetFullscreen(bool fullscreen) {
}
void HWNDMessageHandler::SetAspectRatio(float aspect_ratio) {

View File

@@ -9,26 +9,26 @@ correctly tagged with MAP_JIT we need to use gins page allocator instead
of the default V8 allocator. This probably can't be usptreamed.
diff --git a/gin/public/v8_platform.h b/gin/public/v8_platform.h
index fa0e7faad9296b9be8d662324c52f40e502f2e38..a579b359c684ccd72dcbe43f40b4aa7b4779c36b 100644
index e5da06566ffef8d0b394c0d7fde3916ce49da06e..76bbdf35f4751c87a6d25cc5e8db7aebf43bc821 100644
--- a/gin/public/v8_platform.h
+++ b/gin/public/v8_platform.h
@@ -25,6 +25,7 @@ class GIN_EXPORT V8Platform : public v8::Platform {
// Some configurations do not use page_allocator.
#if BUILDFLAG(USE_PARTITION_ALLOC)
v8::PageAllocator* GetPageAllocator() override;
+ static v8::PageAllocator* PageAllocator();
@@ -30,6 +30,7 @@ class GIN_EXPORT V8Platform : public v8::Platform {
// enabling Arm's Branch Target Instructions for executable pages. This is
// verified in the tests for gin::PageAllocator.
PageAllocator* GetPageAllocator() override;
+ static PageAllocator* PageAllocator();
void OnCriticalMemoryPressure() override;
#endif
std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner(
diff --git a/gin/v8_platform.cc b/gin/v8_platform.cc
index 6acf18c405774774fa9074f1b3d5daeefbda120e..9147b28b0f7f016a26e3d9e346f1eeb72d719a79 100644
index 44f8ffeda27cbfebcfc57e1312e9e9f4ca3ab576..356b5a7c8f39fab97ff434850038f8f6cee750c8 100644
--- a/gin/v8_platform.cc
+++ b/gin/v8_platform.cc
@@ -472,6 +472,10 @@ v8::PageAllocator* V8Platform::GetPageAllocator() {
@@ -368,6 +368,10 @@ PageAllocator* V8Platform::GetPageAllocator() {
return g_page_allocator.Pointer();
}
+v8::PageAllocator* V8Platform::PageAllocator() {
+PageAllocator* V8Platform::PageAllocator() {
+ return g_page_allocator.Pointer();
+}
+

View File

@@ -33,10 +33,10 @@ index 0ccfe130f00ec3b6c75cd8ee04d5a2777e1fd00c..653829457d58bf92057cc36aa8a28970
DISALLOW_COPY_AND_ASSIGN(StaticHttpUserAgentSettings);
};
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index 3896a834cbb17bfe6ecfc602886ea7d77d7d5167..4f752b1e961e23cf2f0e07a93dfe3867bbd56737 100644
index 7bd73dae3a77cb16cf282d2df7f4ff7a8f412805..3d3795cd1911647f026addf0d6e6bcc18325f641 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -1285,6 +1285,13 @@ void NetworkContext::SetNetworkConditions(
@@ -1292,6 +1292,13 @@ void NetworkContext::SetNetworkConditions(
std::move(network_conditions));
}
@@ -51,10 +51,10 @@ index 3896a834cbb17bfe6ecfc602886ea7d77d7d5167..4f752b1e961e23cf2f0e07a93dfe3867
// This may only be called on NetworkContexts created with the constructor
// that calls MakeURLRequestContext().
diff --git a/services/network/network_context.h b/services/network/network_context.h
index 00bcb6e3b31b7e61a36c6df96d39cd0d5cc5e28a..aacda36b0a14beb415592a1f0e478dc1964d82eb 100644
index 049c8e5e0e34454f03a823b31a5f7755d67cfb07..d928b8c314f8c3384215a87aacd01a7f570316c9 100644
--- a/services/network/network_context.h
+++ b/services/network/network_context.h
@@ -270,6 +270,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
@@ -271,6 +271,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
void CloseIdleConnections(CloseIdleConnectionsCallback callback) override;
void SetNetworkConditions(const base::UnguessableToken& throttling_profile_id,
mojom::NetworkConditionsPtr conditions) override;
@@ -63,10 +63,10 @@ index 00bcb6e3b31b7e61a36c6df96d39cd0d5cc5e28a..aacda36b0a14beb415592a1f0e478dc1
void SetEnableReferrers(bool enable_referrers) override;
#if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
index 9a4ab0a7493688e31acd119b816de69bfb47d9d7..751769a979c0fc8d3cdcded177ee23c227fcd103 100644
index d8e7d0d35317fe1124bf81f60faf2b35ae19a3d7..eed5109002dd99a6e65c8882530a5fd2a69ce28c 100644
--- a/services/network/public/mojom/network_context.mojom
+++ b/services/network/public/mojom/network_context.mojom
@@ -998,6 +998,9 @@ interface NetworkContext {
@@ -1029,6 +1029,9 @@ interface NetworkContext {
SetNetworkConditions(mojo_base.mojom.UnguessableToken throttling_profile_id,
NetworkConditions? conditions);
@@ -77,7 +77,7 @@ index 9a4ab0a7493688e31acd119b816de69bfb47d9d7..751769a979c0fc8d3cdcded177ee23c2
SetAcceptLanguage(string new_accept_language);
diff --git a/services/network/test/test_network_context.h b/services/network/test/test_network_context.h
index 6bf98a5e9028cc162aa5493a5dc6910f59aa10d7..48d1f1414894c3ca71de74a7cb5e49eb98a1bf30 100644
index f1fbbf10df01876e8ae3418b72cd0f4fcbda542b..780ccbe1a9ff8ab91b39fdcef74cd5805ba8583d 100644
--- a/services/network/test/test_network_context.h
+++ b/services/network/test/test_network_context.h
@@ -134,6 +134,7 @@ class TestNetworkContext : public mojom::NetworkContext {

View File

@@ -0,0 +1,343 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Raymond Zhao <raymondzhao@microsoft.com>
Date: Tue, 7 Sep 2021 14:54:25 -0700
Subject: feat: Add data parameter to ProcessSingleton
This patch adds an additional_data parameter to the constructor of
ProcessSingleton, so that the second instance can send additional
data over to the first instance while requesting the ProcessSingleton
lock.
On the Electron side, we then expose an extra parameter to the
app.requestSingleInstanceLock API so that users can pass in a JSON
object for the second instance to send to the first instance.
diff --git a/chrome/browser/process_singleton.h b/chrome/browser/process_singleton.h
index eec994c4252f17d9c9c41e66d5dae6509ed98a18..e538c9b76da4d4435e10cd3848438446c2cc2cc8 100644
--- a/chrome/browser/process_singleton.h
+++ b/chrome/browser/process_singleton.h
@@ -19,6 +19,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/process/process.h"
+#include "base/containers/span.h"
#include "ui/gfx/native_widget_types.h"
#if defined(OS_POSIX) && !defined(OS_ANDROID)
@@ -101,21 +102,24 @@ class ProcessSingleton {
// should handle it (i.e., because the current process is shutting down).
using NotificationCallback =
base::RepeatingCallback<bool(const base::CommandLine& command_line,
- const base::FilePath& current_directory)>;
+ const base::FilePath& current_directory,
+ const std::vector<const uint8_t> additional_data)>;
#if defined(OS_WIN)
ProcessSingleton(const std::string& program_name,
const base::FilePath& user_data_dir,
+ const base::span<const uint8_t> additional_data,
bool is_sandboxed,
const NotificationCallback& notification_callback);
#else
ProcessSingleton(const base::FilePath& user_data_dir,
+ const base::span<const uint8_t> additional_data,
const NotificationCallback& notification_callback);
+#endif
ProcessSingleton(const ProcessSingleton&) = delete;
ProcessSingleton& operator=(const ProcessSingleton&) = delete;
-#endif
~ProcessSingleton();
// Notify another process, if available. Otherwise sets ourselves as the
@@ -179,6 +183,8 @@ class ProcessSingleton {
private:
NotificationCallback notification_callback_; // Handler for notifications.
+ // Custom data to pass to the other instance during notify.
+ base::span<const uint8_t> additional_data_;
#if defined(OS_WIN)
bool EscapeVirtualization(const base::FilePath& user_data_dir);
diff --git a/chrome/browser/process_singleton_posix.cc b/chrome/browser/process_singleton_posix.cc
index 05c86df6c871ca7d0926836edc2f6137fcf229cb..01627f6b46c64a24870fa05b9efeaf949203c2ac 100644
--- a/chrome/browser/process_singleton_posix.cc
+++ b/chrome/browser/process_singleton_posix.cc
@@ -564,6 +564,7 @@ class ProcessSingleton::LinuxWatcher
// |reader| is for sending back ACK message.
void HandleMessage(const std::string& current_dir,
const std::vector<std::string>& argv,
+ const std::vector<const uint8_t> additional_data,
SocketReader* reader);
private:
@@ -620,13 +621,16 @@ void ProcessSingleton::LinuxWatcher::StartListening(int socket) {
}
void ProcessSingleton::LinuxWatcher::HandleMessage(
- const std::string& current_dir, const std::vector<std::string>& argv,
+ const std::string& current_dir,
+ const std::vector<std::string>& argv,
+ const std::vector<const uint8_t> additional_data,
SocketReader* reader) {
DCHECK(ui_task_runner_->BelongsToCurrentThread());
DCHECK(reader);
if (parent_->notification_callback_.Run(base::CommandLine(argv),
- base::FilePath(current_dir))) {
+ base::FilePath(current_dir),
+ std::move(additional_data))) {
// Send back "ACK" message to prevent the client process from starting up.
reader->FinishWithACK(kACKToken, base::size(kACKToken) - 1);
} else {
@@ -674,7 +678,8 @@ void ProcessSingleton::LinuxWatcher::SocketReader::
}
}
- // Validate the message. The shortest message is kStartToken\0x\0x
+ // Validate the message. The shortest message kStartToken\0\00
+ // The shortest message with additional data is kStartToken\0\00\00\0.
const size_t kMinMessageLength = base::size(kStartToken) + 4;
if (bytes_read_ < kMinMessageLength) {
buf_[bytes_read_] = 0;
@@ -704,10 +709,25 @@ void ProcessSingleton::LinuxWatcher::SocketReader::
tokens.erase(tokens.begin());
tokens.erase(tokens.begin());
+ size_t num_args;
+ base::StringToSizeT(tokens[0], &num_args);
+ std::vector<std::string> command_line(tokens.begin() + 1, tokens.begin() + 1 + num_args);
+
+ std::vector<const uint8_t> additional_data;
+ if (tokens.size() == 3 + num_args) {
+ size_t additional_data_size;
+ base::StringToSizeT(tokens[1 + num_args], &additional_data_size);
+ const uint8_t* additional_data_bits =
+ reinterpret_cast<const uint8_t*>(tokens[2 + num_args].c_str());
+ additional_data = std::vector<const uint8_t>(additional_data_bits,
+ additional_data_bits + additional_data_size);
+ }
+
// Return to the UI thread to handle opening a new browser tab.
ui_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&ProcessSingleton::LinuxWatcher::HandleMessage,
- parent_, current_dir, tokens, this));
+ parent_, current_dir, command_line,
+ std::move(additional_data), this));
fd_watch_controller_.reset();
// LinuxWatcher::HandleMessage() is in charge of destroying this SocketReader
@@ -736,8 +756,10 @@ void ProcessSingleton::LinuxWatcher::SocketReader::FinishWithACK(
//
ProcessSingleton::ProcessSingleton(
const base::FilePath& user_data_dir,
+ const base::span<const uint8_t> additional_data,
const NotificationCallback& notification_callback)
: notification_callback_(notification_callback),
+ additional_data_(additional_data),
current_pid_(base::GetCurrentProcId()),
watcher_(new LinuxWatcher(this)) {
socket_path_ = user_data_dir.Append(chrome::kSingletonSocketFilename);
@@ -854,7 +876,8 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
sizeof(socket_timeout));
// Found another process, prepare our command line
- // format is "START\0<current dir>\0<argv[0]>\0...\0<argv[n]>".
+ // format is "START\0<current-dir>\0<n-args>\0<argv[0]>\0...\0<argv[n]>
+ // \0<additional-data-length>\0<additional-data>".
std::string to_send(kStartToken);
to_send.push_back(kTokenDelimiter);
@@ -864,11 +887,21 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
to_send.append(current_dir.value());
const std::vector<std::string>& argv = cmd_line.argv();
+ to_send.push_back(kTokenDelimiter);
+ to_send.append(base::NumberToString(argv.size()));
for (auto it = argv.begin(); it != argv.end(); ++it) {
to_send.push_back(kTokenDelimiter);
to_send.append(*it);
}
+ size_t data_to_send_size = additional_data_.size_bytes();
+ if (data_to_send_size) {
+ to_send.push_back(kTokenDelimiter);
+ to_send.append(base::NumberToString(data_to_send_size));
+ to_send.push_back(kTokenDelimiter);
+ to_send.append(reinterpret_cast<const char*>(additional_data_.data()), data_to_send_size);
+ }
+
// Send the message
if (!WriteToSocket(socket.fd(), to_send.data(), to_send.length())) {
// Try to kill the other process, because it might have been dead.
diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc
index 19d5659d665321da54e05cee01be7da02e0c283b..600ff701b025ba190d05bc30994e3d3e8847df55 100644
--- a/chrome/browser/process_singleton_win.cc
+++ b/chrome/browser/process_singleton_win.cc
@@ -99,10 +99,12 @@ BOOL CALLBACK BrowserWindowEnumeration(HWND window, LPARAM param) {
bool ParseCommandLine(const COPYDATASTRUCT* cds,
base::CommandLine* parsed_command_line,
- base::FilePath* current_directory) {
+ base::FilePath* current_directory,
+ std::vector<const uint8_t>* parsed_additional_data) {
// We should have enough room for the shortest command (min_message_size)
// and also be a multiple of wchar_t bytes. The shortest command
- // possible is L"START\0\0" (empty current directory and command line).
+ // possible is L"START\0\0" (empty command line, current directory,
+ // and additional data).
static const int min_message_size = 7;
if (cds->cbData < min_message_size * sizeof(wchar_t) ||
cds->cbData % sizeof(wchar_t) != 0) {
@@ -152,6 +154,37 @@ bool ParseCommandLine(const COPYDATASTRUCT* cds,
const std::wstring cmd_line =
msg.substr(second_null + 1, third_null - second_null);
*parsed_command_line = base::CommandLine::FromString(cmd_line);
+
+ const std::wstring::size_type fourth_null =
+ msg.find_first_of(L'\0', third_null + 1);
+ if (fourth_null == std::wstring::npos ||
+ fourth_null == msg.length()) {
+ // No additional data was provided.
+ return true;
+ }
+
+ // Get length of the additional data.
+ const std::wstring additional_data_length_string =
+ msg.substr(third_null + 1, fourth_null - third_null);
+ size_t additional_data_length;
+ base::StringToSizeT(additional_data_length_string, &additional_data_length);
+
+ const std::wstring::size_type fifth_null =
+ msg.find_first_of(L'\0', fourth_null + 1);
+ if (fifth_null == std::wstring::npos ||
+ fifth_null == msg.length()) {
+ LOG(WARNING) << "Invalid format for start command, we need a string in 6 "
+ "parts separated by NULLs";
+ }
+
+ // Get the actual additional data.
+ const std::wstring additional_data =
+ msg.substr(fourth_null + 1, fifth_null - fourth_null);
+ const uint8_t* additional_data_bytes =
+ reinterpret_cast<const uint8_t*>(additional_data.c_str());
+ *parsed_additional_data = std::vector<const uint8_t>(additional_data_bytes,
+ additional_data_bytes + additional_data_length);
+
return true;
}
return false;
@@ -168,16 +201,16 @@ bool ProcessLaunchNotification(
// Handle the WM_COPYDATA message from another process.
const COPYDATASTRUCT* cds = reinterpret_cast<COPYDATASTRUCT*>(lparam);
-
base::CommandLine parsed_command_line(base::CommandLine::NO_PROGRAM);
base::FilePath current_directory;
- if (!ParseCommandLine(cds, &parsed_command_line, &current_directory)) {
+ std::vector<const uint8_t> additional_data;
+ if (!ParseCommandLine(cds, &parsed_command_line, &current_directory, &additional_data)) {
*result = TRUE;
return true;
}
- *result = notification_callback.Run(parsed_command_line, current_directory) ?
- TRUE : FALSE;
+ *result = notification_callback.Run(parsed_command_line,
+ current_directory, std::move(additional_data)) ? TRUE : FALSE;
return true;
}
@@ -274,9 +307,11 @@ bool ProcessSingleton::EscapeVirtualization(
ProcessSingleton::ProcessSingleton(
const std::string& program_name,
const base::FilePath& user_data_dir,
+ const base::span<const uint8_t> additional_data,
bool is_app_sandboxed,
const NotificationCallback& notification_callback)
: notification_callback_(notification_callback),
+ additional_data_(additional_data),
program_name_(program_name),
is_app_sandboxed_(is_app_sandboxed),
is_virtualized_(false),
@@ -301,7 +336,7 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
return PROCESS_NONE;
}
- switch (chrome::AttemptToNotifyRunningChrome(remote_window_)) {
+ switch (chrome::AttemptToNotifyRunningChrome(remote_window_, additional_data_)) {
case chrome::NOTIFY_SUCCESS:
return PROCESS_NOTIFIED;
case chrome::NOTIFY_FAILED:
diff --git a/chrome/browser/win/chrome_process_finder.cc b/chrome/browser/win/chrome_process_finder.cc
index 788abf9a04f2a3725d67f7f8d84615016b241c8e..6ae6d97708e18c25c59a0b1e3d2d58f27d980ffb 100644
--- a/chrome/browser/win/chrome_process_finder.cc
+++ b/chrome/browser/win/chrome_process_finder.cc
@@ -34,7 +34,9 @@ HWND FindRunningChromeWindow(const base::FilePath& user_data_dir) {
return base::win::MessageWindow::FindWindow(user_data_dir.value());
}
-NotifyChromeResult AttemptToNotifyRunningChrome(HWND remote_window) {
+NotifyChromeResult AttemptToNotifyRunningChrome(
+ HWND remote_window,
+ const base::span<const uint8_t> additional_data) {
DCHECK(remote_window);
DWORD process_id = 0;
DWORD thread_id = GetWindowThreadProcessId(remote_window, &process_id);
@@ -42,7 +44,8 @@ NotifyChromeResult AttemptToNotifyRunningChrome(HWND remote_window) {
return NOTIFY_FAILED;
// Send the command line to the remote chrome window.
- // Format is "START\0<<<current directory>>>\0<<<commandline>>>".
+ // Format is
+ // "START\0<current-directory>\0<command-line>\0<additional-data-length>\0<additional-data>".
std::wstring to_send(L"START\0", 6); // want the NULL in the string.
base::FilePath cur_dir;
if (!base::GetCurrentDirectory(&cur_dir))
@@ -53,6 +56,22 @@ NotifyChromeResult AttemptToNotifyRunningChrome(HWND remote_window) {
base::CommandLine::ForCurrentProcess()->GetCommandLineString());
to_send.append(L"\0", 1); // Null separator.
+ size_t additional_data_size = additional_data.size_bytes();
+ if (additional_data_size) {
+ // Send over the size, because the reinterpret cast to wchar_t could
+ // add padding.
+ to_send.append(base::UTF8ToWide(base::NumberToString(additional_data_size)));
+ to_send.append(L"\0", 1); // Null separator.
+
+ size_t padded_size = additional_data_size / sizeof(wchar_t);
+ if (additional_data_size % sizeof(wchar_t) != 0) {
+ padded_size++;
+ }
+ to_send.append(reinterpret_cast<const wchar_t*>(additional_data.data()),
+ padded_size);
+ to_send.append(L"\0", 1); // Null separator.
+ }
+
// Allow the current running browser window to make itself the foreground
// window (otherwise it will just flash in the taskbar).
::AllowSetForegroundWindow(process_id);
diff --git a/chrome/browser/win/chrome_process_finder.h b/chrome/browser/win/chrome_process_finder.h
index 5516673cee019f6060077091e59498bf9038cd6e..8edea5079b46c2cba67833114eb9c21d85cfc22d 100644
--- a/chrome/browser/win/chrome_process_finder.h
+++ b/chrome/browser/win/chrome_process_finder.h
@@ -7,6 +7,7 @@
#include <windows.h>
+#include "base/containers/span.h"
#include "base/time/time.h"
namespace base {
@@ -27,7 +28,9 @@ HWND FindRunningChromeWindow(const base::FilePath& user_data_dir);
// Attempts to send the current command line to an already running instance of
// Chrome via a WM_COPYDATA message.
// Returns true if a running Chrome is found and successfully notified.
-NotifyChromeResult AttemptToNotifyRunningChrome(HWND remote_window);
+NotifyChromeResult AttemptToNotifyRunningChrome(
+ HWND remote_window,
+ const base::span<const uint8_t> additional_data);
// Changes the notification timeout to |new_timeout|, returns the old timeout.
base::TimeDelta SetNotificationTimeoutForTesting(base::TimeDelta new_timeout);

View File

@@ -44,10 +44,10 @@ index 182721f9238683321ef5645d5506d2e88816f45f..31958788b8b2f110ecedcd9f0ba3b8ec
"https://redirector.gvt1.com/edgedl/chrome/dict/";
diff --git a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
index a8acd00dc449812d336364229fade2a16e21ccbc..8d8eca3c7de3080111043dc465ed4316af026c0b 100644
index f2eb0abec4d5fb05dee09b51e02619ba47336025..77667a70584c5a102bddbc46cb71aa616b672384 100644
--- a/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
+++ b/chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h
@@ -88,6 +88,8 @@ class SpellcheckHunspellDictionary
@@ -93,6 +93,8 @@ class SpellcheckHunspellDictionary
// Tests use this method to set a custom URL for downloading dictionaries.
static void SetDownloadURLForTesting(const GURL url);

View File

@@ -7,10 +7,10 @@ Subject: feat: allow embedders to add observers on created hunspell
This patch is used by Electron to implement spellchecker events.
diff --git a/chrome/browser/spellchecker/spellcheck_service.cc b/chrome/browser/spellchecker/spellcheck_service.cc
index 23980dfd5e35ac9160b82bd0d29bd98762897d1f..aece7fe0a4d45a40afbc0339073ffffb2c0d4f5e 100644
index 7e6846c8bbb2d773c0b0ec97da928871d828bcbf..7a5f0d5034270dcfb287d9c46b2cd0431098d37e 100644
--- a/chrome/browser/spellchecker/spellcheck_service.cc
+++ b/chrome/browser/spellchecker/spellcheck_service.cc
@@ -466,6 +466,9 @@ void SpellcheckService::LoadDictionaries() {
@@ -467,6 +467,9 @@ void SpellcheckService::LoadDictionaries() {
std::make_unique<SpellcheckHunspellDictionary>(
dictionary, platform_spellcheck_language, context_, this));
hunspell_dictionaries_.back()->AddObserver(this);
@@ -20,7 +20,7 @@ index 23980dfd5e35ac9160b82bd0d29bd98762897d1f..aece7fe0a4d45a40afbc0339073ffffb
hunspell_dictionaries_.back()->Load();
}
@@ -518,6 +521,20 @@ bool SpellcheckService::IsSpellcheckEnabled() const {
@@ -519,6 +522,20 @@ bool SpellcheckService::IsSpellcheckEnabled() const {
(!hunspell_dictionaries_.empty() || enable_if_uninitialized);
}
@@ -42,10 +42,10 @@ index 23980dfd5e35ac9160b82bd0d29bd98762897d1f..aece7fe0a4d45a40afbc0339073ffffb
const content::NotificationSource& source,
const content::NotificationDetails& details) {
diff --git a/chrome/browser/spellchecker/spellcheck_service.h b/chrome/browser/spellchecker/spellcheck_service.h
index a810ed516cce5f491ea75ae2d0bbda65e066ad3e..fcfd3f5801a967fdd7b3e99094a35eddb1a31789 100644
index b417b23feb1f53c949d8d8c677ff36431cee2a62..bdc67f1de727983a67ea360b502d791af8b22479 100644
--- a/chrome/browser/spellchecker/spellcheck_service.h
+++ b/chrome/browser/spellchecker/spellcheck_service.h
@@ -134,6 +134,8 @@ class SpellcheckService : public KeyedService,
@@ -138,6 +138,8 @@ class SpellcheckService : public KeyedService,
// dictionaries available.
bool IsSpellcheckEnabled() const;
@@ -54,7 +54,7 @@ index a810ed516cce5f491ea75ae2d0bbda65e066ad3e..fcfd3f5801a967fdd7b3e99094a35edd
// NotificationProfile implementation.
void Observe(int type,
const content::NotificationSource& source,
@@ -301,6 +303,8 @@ class SpellcheckService : public KeyedService,
@@ -305,6 +307,8 @@ class SpellcheckService : public KeyedService,
// A pointer to the BrowserContext which this service refers to.
content::BrowserContext* context_;

View File

@@ -81,7 +81,7 @@ index 1026b739d283f0fc252fa2af83a6d4cf51bc8553..fe562ab60ce98b8bb0c5080a6428deb3
private:
const HWND hwnd_;
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
index f0eb025056501c5d87a0ef814ec4070a3df29bcc..148adf8b17209eeb142c02674a2a24312e588e80 100644
index 34dad16dac56631dae62e2c38b8ed7bf6ca2eb41..25f114ceb4c18a88bd23975c85fab67a6311f808 100644
--- a/components/viz/service/BUILD.gn
+++ b/components/viz/service/BUILD.gn
@@ -137,6 +137,8 @@ viz_component("service") {

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