Commit Graph
31269 Commits
Author SHA1 Message Date
claude[bot]andClaude Opus 5.5 dc580b6529 docs: note that beta.1 waits for the Chromium roll (#54649)
* docs: note beta.1 waits for the Chromium roll

The Releases WG moved alpha-to-beta promotion to release automation,
gated on the release branch's Chromium reaching the version in Chrome's
Beta channel. beta.1 is no longer a fixed date, so stop listing it as one
of our solid release dates and note it can land a few days late.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmPhpNhEFuPd7juZ3fc781

* docs: explain beta.1 delay without roll jargon

Say plainly that beta.1 can be late when the release branch has not yet
been updated to the Chromium Beta-channel version, instead of referring
to "our Chromium roll" without explaining it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmPhpNhEFuPd7juZ3fc781

* docs: link Chrome's Beta channel in release timeline

Link to Chromium's release channel page and briefly explain that the
Beta channel is where each Chrome version is tested for about four weeks
before stable.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmPhpNhEFuPd7juZ3fc781

* docs: clarify which release dates are fixed

Replace "our solid release dates" with plain wording: alpha.1 and stable
ship on the scheduled dates, while the prereleases in between, including
beta.1, don't have fixed dates.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmPhpNhEFuPd7juZ3fc781

* docs: tighten beta.1 timing note

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmPhpNhEFuPd7juZ3fc781

* docs: use canonical Chrome release channels URL

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmPhpNhEFuPd7juZ3fc781

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-06 17:46:30 +01:00
claude[bot]andClaude cba5248898 docs: document preload code cache threat model (#54654)
Explain why SetFromRenderer stores the renderer-produced blob unverified and that the (BrowserContext, ProcessLock, id) scope is the security boundary.


Claude-Session: https://claude.ai/code/session_018A4Mt59Nr4h4WSFjyNNkxb

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-07 00:47:31 +09:00
Robo 6b48d9813b refactor: give WebContentsView a native view of its own (#54558)
* refactor: give WebContentsView a native view of its own

A WebContentsView used its webContents InspectableWebContentsView as its
native view. The webContents owns that view and deletes it along with
itself, so a WebContentsView could outlive its native view and every View
method had to check for a null view.

WebContentsViewHost now owns a container view for the whole life of the
WebContentsView and presents the inspectable view in it, filling it, as
its last child. Child views added from JavaScript stay before it and so
beneath the page, as they were when added to the inspectable view. With
that, View::Host always owns its view, and the unowned mode goes away.

Ownership of the webContents no longer needs a user-data claim. The host
whose container presents the inspectable view owns it. Adopting a
webContents in a new WebContentsView moves the inspectable view into the
new container, so only that view acts on the webContents and destroys it
when collected. Two WebContentsViews that share a webContents are now
separate children, rather than one native view tracked twice.

* fix: update the overlay when a WebContentsView moves

Since a WebContentsView has its own container view, moving it without
resizing leaves the page view's bounds unchanged, so the window controls
overlay was never re-sent to the page.
2026-10-06 08:21:33 +09:00
electron-pgo-updater[bot] e91b6a0ab5 build: update PGO profiles (#54642)
* build: update linux-arm64 PGO profile

* build: update linux-x64 PGO profile

* build: update macos-arm64 PGO profile

* build: update macos-x64 PGO profile

* build: update v8-builtins PGO profile

* build: update win-arm64 PGO profile

* build: update win-x64 PGO profile

---------

Co-authored-by: electron-pgo-updater[bot] <290827142+electron-pgo-updater[bot]@users.noreply.github.com>
v46.0.0-nightly.20261005
2026-10-05 20:39:31 +09:00
Shelley Vohr 9d431c2a5d feat: add app.canDeElevate() and a deElevate option to app.relaunch() on Windows (#54383)
* feat: add app.isUnnecessarilyElevated() and a deElevate option to app.relaunch() on Windows

An Electron app started with a full administrator token while UAC is
enabled cannot always launch its sandboxed child processes (the sandbox
broker's CreateProcessAsUser fails under some enterprise policies,
surfacing as render-process-gone launch-failed with exit code 18 or a
blank window), and app code that was never meant to run elevated does.
Chrome handles this by relaunching itself de-elevated at startup.

Give apps the same option: app.isUnnecessarilyElevated() reports whether
the process holds an elevated split token, and app.relaunch({ deElevate:
true }) makes the relauncher start the new instance through
base::win::RunDeElevated() with the user's normal token.

* fix: carry the RunDeElevated working directory fix so a de-elevated relaunch keeps its cwd

* refactor: rename to app.canDeElevate()

* fix: launch the de-elevated relaunch through RunDeElevatedNoWait so it keeps the working directory without a base patch
2026-10-05 11:58:57 +02:00
Shelley Vohr 0477d717d1 refactor: use upstream's color scheme override for nativeTheme.themeSource (#54595)
https://chromium-review.googlesource.com/c/chromium/src/+/8401888 added
ui::NativeTheme::SetPreferredColorSchemeOverride(), which does what the
set_theme_source() patch did, for every theme instance at once. Use it and
drop the patch. themeSource keeps its own stored value, and "system"
restores the override the process started with, so that --force-dark-mode
behaves as before.
2026-10-05 11:58:24 +02:00
Robo 4e18d6c24c refactor: migrate View, ImageView and WebContentsView to cppgc (#54555)
* refactor: migrate View, ImageView and WebContentsView to cppgc

The View wrappers were gin_helper::EventEmitter objects, and every edge
between them was a strong V8 root. A parent held each child in a
v8::Global, BaseWindow and BrowserWindow held their content view in a
v8::Global, and WebContentsView held its WebContents in a
cppgc::Persistent. A view reachable only through such a cycle, such as
a layout callback that closes over its own view, was never collected.

The wrappers are now cppgc managed gin::Wrappables, and those edges are
traced:

- Children are kept in a traced list of child entries, matched by their
  native views::View so that two WebContentsViews sharing a webContents
  stay distinct.
- The layout callback is a v8::TracedReference; the layout manager only
  holds a WeakPtr to the native side.
- WebContentsView holds its WebContents with a Member.
- BaseWindow and BrowserWindow root their views with cppgc::Persistent
  while the native window uses them.

Native state moves to View::Host, a NativePeer that owns or observes the
views::View and is torn down through Release(), never from a GC
destructor. WebContentsViewHost additionally holds the WebContents,
window and draggable-region observers and the overlay update. A
user-data claim on content::WebContents records which host owns the
webContents, so a view that adopts the webContents of a collected but
not yet released view is not destroyed with it. The claim is checked and
the webContents disposed in the same task through the new
WebContents::DestroyNow(). At shutdown, hosts leave disposal to the
WebContents itself.

ImageView and WebContentsView keep their own WrapperInfos and share one
kElectronView pointer tag, and Converter<View*> accepts all three.
gin_helper::Constructible gains ConstructibleParent, so a subclass
constructor template inherits View's, and BindToConstructCall, so
`class extends` and Reflect.construct keep the subclass prototype.

* chore: fix lint
2026-10-05 11:07:55 +09:00
Robo 07a3f54605 build: enable dangling raw_ptr checks (#54619)
* fix: clear vibrancy view before destruction

Keep the removed NativeViewHost alive until vibrant_native_view_host_ has been cleared.

Memory was freed at:

0 Electron Framework 0x000000012b8e4940 base::debug::CollectStackTrace(base::span<void const*, 18446744073709551615ul, void const**>) + 24
1 Electron Framework 0x000000012b8cfa00 base::debug::StackTrace::StackTrace(unsigned long) + 128
2 Electron Framework 0x000000012b8ea86c base::allocator::(anonymous namespace)::DanglingRawPtrDetected(unsigned long) + 764
3 Electron Framework 0x000000012b996bcc void partition_alloc::PartitionRoot::FreeInline<(partition_alloc::internal::FreeFlags)8>(void*) + 5392
4 Electron Framework 0x00000001335fe8f4 views::NativeViewHost::~NativeViewHost() + 16
5 Electron Framework 0x0000000124916004 ___ZN8electron15NativeWindowMac11SetVibrancyERKNSt4__Cr12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEi_block_invoke + 140
6 Electron Framework 0x0000000124915a74 electron::NativeWindowMac::SetVibrancy(std::__Cr::basic_string<char, std::__Cr::char_traits<char>, std::__Cr::allocator<char>> const&, int) + 1048

The dangling raw_ptr was released at:

0 Electron Framework 0x000000012b8e4940 base::debug::CollectStackTrace(base::span<void const*, 18446744073709551615ul, void const**>) + 24
1 Electron Framework 0x000000012b8cfa00 base::debug::StackTrace::StackTrace(unsigned long) + 128
2 Electron Framework 0x000000012b8eb158 void base::allocator::(anonymous namespace)::DanglingRawPtrReleased<(base::features::DanglingPtrMode)1, (base::features::DanglingPtrType)0>(unsigned long) + 92
3 Electron Framework 0x000000012b93c3b4 base::internal::RawPtrBackupRefImpl<false>::ReleaseInternal(unsigned long) + 480
4 Electron Framework 0x0000000124916058 ___ZN8electron15NativeWindowMac11SetVibrancyERKNSt4__Cr12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEi_block_invoke + 224
5 Electron Framework 0x0000000124915a74 electron::NativeWindowMac::SetVibrancy(std::__Cr::basic_string<char, std::__Cr::char_traits<char>, std::__Cr::allocator<char>> const&, int) + 1048

* fix: clear notification delegate before callback

Release delegate_ before NotificationDestroyed() can synchronously delete the delegate.

Memory was freed at:

0 Electron Framework 0x000000012b8e4940 base::debug::CollectStackTrace(base::span<void const*, 18446744073709551615ul, void const**>) + 24
1 Electron Framework 0x000000012b8cfa00 base::debug::StackTrace::StackTrace(unsigned long) + 128
2 Electron Framework 0x000000012b8ea86c base::allocator::(anonymous namespace)::DanglingRawPtrDetected(unsigned long) + 764
3 Electron Framework 0x000000012b9aa080 void partition_alloc::PartitionRoot::FreeInline<(partition_alloc::internal::FreeFlags)22>(void*, partition_alloc::FreeHint<partition_alloc::internal::FreeFlags partition_alloc::internal::FreeHintFlags<partition_alloc::internal::FreeFlags>(partition_alloc::internal::FreeFlags)((partition_alloc::internal::FreeFlags)22)>::Type) + 5928
4 Electron Framework 0x000000012b99f940 void partition_alloc::PartitionRoot::FreeInUnknownRoot<(partition_alloc::internal::FreeFlags)22>(void*, partition_alloc::FreeHint<partition_alloc::internal::FreeFlags partition_alloc::internal::FreeHintFlags<partition_alloc::internal::FreeFlags>(partition_alloc::internal::FreeFlags)((partition_alloc::internal::FreeFlags)22)>::Type) + 1324
5 Electron Framework 0x000000012b9c3a50 allocator_shim::internal::PartitionAllocFunctionsInternal<(partition_alloc::internal::AllocFlags)16, (partition_alloc::internal::FreeFlags)6>::FreeWithSize(void*, unsigned long, void*) + 200
6 Electron Framework 0x00000001247f797c electron::Notification::~Notification() + 72
7 Electron Framework 0x0000000124919fbc electron::CocoaNotification::~CocoaNotification() + 220
8 Electron Framework 0x000000012491a014 electron::CocoaNotification::~CocoaNotification() + 12
9 Electron Framework 0x00000001247f81cc electron::NotificationPresenter::RemoveNotification(electron::Notification*) + 200

The dangling raw_ptr was released at:

0 Electron Framework 0x000000012b8e4940 base::debug::CollectStackTrace(base::span<void const*, 18446744073709551615ul, void const**>) + 24
1 Electron Framework 0x000000012b8cfa00 base::debug::StackTrace::StackTrace(unsigned long) + 128
2 Electron Framework 0x000000012b8eb158 void base::allocator::(anonymous namespace)::DanglingRawPtrReleased<(base::features::DanglingPtrMode)1, (base::features::DanglingPtrType)0>(unsigned long) + 92
3 Electron Framework 0x000000012b93c3b4 base::internal::RawPtrBackupRefImpl<false>::ReleaseInternal(unsigned long) + 480
4 Electron Framework 0x00000001247f7a50 electron::Notification::~Notification() + 284
5 Electron Framework 0x0000000124919fbc electron::CocoaNotification::~CocoaNotification() + 220
6 Electron Framework 0x000000012491a014 electron::CocoaNotification::~CocoaNotification() + 12
7 Electron Framework 0x00000001247f81cc electron::NotificationPresenter::RemoveNotification(electron::Notification*) + 200

* fix: erase notifications before destruction

Remove each raw_ptr from notifications_ before deleting the Notification it references.

Memory was freed at:

0 Electron Framework 0x000000012cacd6e0 base::debug::CollectStackTrace(base::span<void const*, 18446744073709551615ul, void const**>) + 24
1 Electron Framework 0x000000012cab6968 base::debug::StackTrace::StackTrace(unsigned long) + 168
2 Electron Framework 0x000000012cad3a24 base::allocator::(anonymous namespace)::DanglingRawPtrDetected(unsigned long) + 764
3 Electron Framework 0x000000012cbbb9ac void partition_alloc::PartitionRoot::FreeInline<(partition_alloc::internal::FreeFlags)22>(void*, partition_alloc::FreeHint<partition_alloc::internal::FreeFlags partition_alloc::internal::FreeHintFlags<partition_alloc::internal::FreeFlags>(partition_alloc::internal::FreeFlags)((partition_alloc::internal::FreeFlags)22)>::Type) + 5868
4 Electron Framework 0x000000012cbb1264 void partition_alloc::PartitionRoot::FreeInUnknownRoot<(partition_alloc::internal::FreeFlags)22>(void*, partition_alloc::FreeHint<partition_alloc::internal::FreeFlags partition_alloc::internal::FreeHintFlags<partition_alloc::internal::FreeFlags>(partition_alloc::internal::FreeFlags)((partition_alloc::internal::FreeFlags)22)>::Type) + 1324
5 Electron Framework 0x000000012cbd522c allocator_shim::internal::PartitionAllocFunctionsInternal<(partition_alloc::internal::AllocFlags)16, (partition_alloc::internal::FreeFlags)6>::FreeWithSize(void*, unsigned long, void*) + 200
6 Electron Framework 0x00000001258ed394 electron::NotificationPresenter::~NotificationPresenter() + 72
7 Electron Framework 0x0000000125a0ee60 electron::NotificationPresenterMac::~NotificationPresenterMac() + 356
8 Electron Framework 0x0000000125a0ef00 electron::NotificationPresenterMac::~NotificationPresenterMac() + 12
9 Electron Framework 0x0000000125868dfc electron::ElectronBrowserClient::~ElectronBrowserClient() + 500

The dangling raw_ptr was released at:

0 Electron Framework 0x000000012cacd6e0 base::debug::CollectStackTrace(base::span<void const*, 18446744073709551615ul, void const**>) + 24
1 Electron Framework 0x000000012cab6968 base::debug::StackTrace::StackTrace(unsigned long) + 168
2 Electron Framework 0x000000012cad3aec void base::allocator::(anonymous namespace)::DanglingRawPtrReleased<(base::features::DanglingPtrMode)0, (base::features::DanglingPtrType)0>(unsigned long) + 84
3 Electron Framework 0x000000012cb27fc8 base::internal::RawPtrBackupRefImpl<false>::ReleaseInternal(unsigned long) + 480
4 Electron Framework 0x00000001258b87c8 void std::__Cr::__destroy_at[abi:sqn240000]<base::raw_ptr<DraggableRegionProvider, (partition_alloc::internal::RawPtrTraits)0>>(base::raw_ptr<DraggableRegionProvider, (partition_alloc::internal::RawPtrTraits)0>*) + 136
5 Electron Framework 0x00000001258eda14 std::__Cr::__tree<base::raw_ptr<electron::Notification, (partition_alloc::internal::RawPtrTraits)0>, std::__Cr::less<base::raw_ptr<electron::Notification, (partition_alloc::internal::RawPtrTraits)0>>, std::__Cr::allocator<base::raw_ptr<electron::Notification, (partition_alloc::internal::RawPtrTraits)0>>>::__tree_deleter::operator()[abi:sqn240000](std::__Cr::__tree_node<base::raw_ptr<electron::Notification, (partition_alloc::internal::RawPtrTraits)0>, void*>*) + 52
6 Electron Framework 0x00000001258ed3d4 electron::NotificationPresenter::~NotificationPresenter() + 136
7 Electron Framework 0x0000000125a0ee60 electron::NotificationPresenterMac::~NotificationPresenterMac() + 356
8 Electron Framework 0x0000000125a0ef00 electron::NotificationPresenterMac::~NotificationPresenterMac() + 12
9 Electron Framework 0x0000000125868dfc electron::ElectronBrowserClient::~ElectronBrowserClient() + 500

* fix: clear Node environment before teardown

Clear NodeBindings::uv_env_ before NodeService releases the node::Environment.

Memory was freed at:

0 Electron Framework 0x0000000129b78940 base::debug::CollectStackTrace(base::span<void const*, 18446744073709551615ul, void const**>) + 24
1 Electron Framework 0x0000000129b63a00 base::debug::StackTrace::StackTrace(unsigned long) + 128
2 Electron Framework 0x0000000129b7e86c base::allocator::(anonymous namespace)::DanglingRawPtrDetected(unsigned long) + 764
3 Electron Framework 0x0000000129c3c93c void partition_alloc::PartitionRoot::FreeInline<(partition_alloc::internal::FreeFlags)18>(void*, partition_alloc::FreeHint<partition_alloc::internal::FreeFlags partition_alloc::internal::FreeHintFlags<partition_alloc::internal::FreeFlags>(partition_alloc::internal::FreeFlags)((partition_alloc::internal::FreeFlags)18)>::Type) + 8480
4 Electron Framework 0x0000000129c33390 void partition_alloc::PartitionRoot::FreeInUnknownRoot<(partition_alloc::internal::FreeFlags)18>(void*, partition_alloc::FreeHint<partition_alloc::internal::FreeFlags partition_alloc::internal::FreeHintFlags<partition_alloc::internal::FreeFlags>(partition_alloc::internal::FreeFlags)((partition_alloc::internal::FreeFlags)18)>::Type) + 1324
5 Electron Framework 0x0000000129c56ce8 allocator_shim::internal::PartitionAllocFunctionsInternal<(partition_alloc::internal::AllocFlags)16, (partition_alloc::internal::FreeFlags)2>::FreeWithSize(void*, unsigned long, void*) + 200
6 Electron Framework 0x0000000122c4bd24 node::FreeEnvironment(node::Environment*) + 248
7 Electron Framework 0x0000000122b3a74c _ZNSt4__Cr20__shared_ptr_pointerB9sqn240000IPN4node11EnvironmentEZN8electron12NodeBindings17CreateEnvironmentEPN2v87IsolateENS6_5LocalINS6_7ContextEEEPNS1_20MultiIsolatePlatformEmNS_6vectorINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENSI_ISK_EEEESM_NS_8optionalIN4base17RepeatingCallbackIFvvEEEEEE3$_0NSI_IS2_EEE16__on_zero_sharedEv + 188
8 Electron Framework 0x0000000122b7ee40 electron::NodeService::~NodeService() + 416
9 Electron Framework 0x0000000122b7ef2c electron::NodeService::~NodeService() + 12

The dangling raw_ptr was released at:

0 Electron Framework 0x0000000129b78940 base::debug::CollectStackTrace(base::span<void const*, 18446744073709551615ul, void const**>) + 24
1 Electron Framework 0x0000000129b63a00 base::debug::StackTrace::StackTrace(unsigned long) + 128
2 Electron Framework 0x0000000129b7e934 void base::allocator::(anonymous namespace)::DanglingRawPtrReleased<(base::features::DanglingPtrMode)0, (base::features::DanglingPtrType)0>(unsigned long) + 84
3 Electron Framework 0x0000000129bd03b4 base::internal::RawPtrBackupRefImpl<false>::ReleaseInternal(unsigned long) + 480
4 Electron Framework 0x0000000122b34b94 electron::NodeBindings::~NodeBindings() + 372
5 Electron Framework 0x0000000122bde08c electron::NodeBindingsMac::~NodeBindingsMac() + 12
6 Electron Framework 0x0000000122b7edf8 electron::NodeService::~NodeService() + 344
7 Electron Framework 0x0000000122b7ef2c electron::NodeService::~NodeService() + 12

* fix: enable dangling raw_ptr checks

* fix: avoid retaining isolate in PromiseBase

Resolve PromiseHandle traced references with the currently entered
isolate instead of retaining a raw pointer that can outlive
IsolateHolder. Promise operations already require execution on their
creation thread with the isolate entered.

```
gin::IsolateHolder::~IsolateHolder -> JavascriptEnvironment::~JavascriptEnvironment -> isolate free

static Promise<void> destruction -> PromiseBase::~PromiseBase -> isolate_ raw_ptr release
```

* fix: annotate additional dangling raw pointers

* fix(win): annotate additional dangling raw_ptr
2026-10-04 14:30:39 -05:00
Shelley Vohr df79406cec fix: crash on navigator.usb.requestDevice() in in-memory sessions (#54608)
UsbChooserContextFactory did not override GetBrowserContextToUse(), so
off-the-record contexts got no UsbChooserContext and the chooser
controller dereferenced null. Give in-memory sessions their own context,
as the HID and serial factories do.
v46.0.0-nightly.20261001
2026-10-01 09:42:11 +02:00
George Xu 49992b1674 fix: filter non-shareable windows from PiP capture filter updates (#51267)
Refactors the non-shareable window filtering in the Chromium
ScreenCaptureKit patch:

1. Extracts inline NSWindowSharingNone filtering into a reusable
   GetNonShareableWindows() helper function.

2. Fixes a bug where content-protected windows (via
   win.setContentProtection(true)) could temporarily appear in screen
   captures during picture-in-picture state changes — the PiP filter
   update handler was only excluding PiP windows, not non-shareable
   ones.

Notes: Fixed a bug where content-protected windows could temporarily appear in screen captures during picture-in-picture state changes.
2026-09-30 21:05:26 -04:00
dependabot[bot] ae5405dbe9 build(deps): bump github/codeql-action/upload-sarif from 4.38.0 to 4.38.1 (#54570)
build(deps): bump github/codeql-action/upload-sarif

Bumps [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) from 4.38.0 to 4.38.1.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/b96794f015dfd88f77b49b1c93e0fa7110f94c63...1c5b675653bb5c22dbe9b12b556ec555138e09fd)

---
updated-dependencies:
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.38.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-30 15:36:50 -04:00
claude[bot]andClaude Opus 5.5 78d8f05222 test: add mouse-input addon for setIgnoreMouseEvents specs (#54535)
* test: add Windows mouse-input addon for setIgnoreMouseEvents specs

Adds @electron-ci/mouse-input, a Windows-only native test addon that
injects real mouse input with SendInput(). Unlike
webContents.sendInputEvent() these events go through the WH_MOUSE_LL
hook that setIgnoreMouseEvents(true, { forward: true }) relies on.

Uses it for serial specs covering click-through, forwarding of moves,
mouseenter/mouseleave stability inside an element and :hover being
cleared when the cursor moves off an element. On CI the suite fails
instead of skipping when SendInput cannot inject input.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y5cq8qhU8xUitP6SzyT2FV

* test: extend mouse-input addon to macOS and Linux X11

Adds CGEventPost (macOS) and XTEST (Linux X11, dlopen()ed so no dev
headers are needed) backends behind the existing JS API and generalizes
the setIgnoreMouseEvents real-input spec: hit testing on Windows and X11,
click-through on all three, forwarding cases on macOS and Windows only.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y5cq8qhU8xUitP6SzyT2FV

* ci: install libXtst in Linux test jobs that lack it

The mouse-input spec addon loads libXtst.so.6 at runtime for XTEST. The
x64 build image ships it but the arm64 test image does not, so install
the runtime package there before running the specs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y5cq8qhU8xUitP6SzyT2FV

* ci: dismiss the first sign-in privacy window on Windows test runners

The windows-11-arm image shows Windows' "Choose privacy settings for
your device" window full screen above even topmost windows, so real
mouse input clicked it instead of the windows under test and the OS hit
tested it at the test point (seen in the mouse-input spike's
screenshots). Stop UserOOBEBroker/WWAHost and set the policies that keep
it from coming back, logging the windows on screen before and after.

Add describeWindowAtPoint() to the Windows addon backend and report it
when the hit test or click-through cases time out, so a covering window
is named in the failure.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y5cq8qhU8xUitP6SzyT2FV

* ci: also close the Start menu on Windows test runners

With the first sign-in privacy window gone, windows-11-arm had the Start
menu open over the test area: describeWindowAtPoint() reported its
CoreWindow at the hit test point, and the click-through case's click then
launched Calculator from it, which covered the point for the retries.
Stop StartMenuExperienceHost (it restarts with the menu closed) and log
what the OS hit tests on screen afterwards.

Before clicking, the click-through case now waits for the window below to
be what the OS hit tests at the point, where the platform can say, so a
covering window fails the case with its name instead of taking the click.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y5cq8qhU8xUitP6SzyT2FV

* test: keep ordinary windows from covering the click-through case

On windows-11-arm the runner's terminal (a Windows Terminal window
running wsl.exe) came up over the non-topmost window below after the
cleanup step ran, so the case's hit test check found it there. Make the
window below topmost too; the ignoring window is shown after it and
stays above it.

The cleanup step also found a System Properties dialog left at the
centre of the screen, so it now minimizes (dialogs: closes) every
visible, uncloaked top level window besides the desktop and taskbar
and logs each one, rather than stopping known processes only.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y5cq8qhU8xUitP6SzyT2FV

* ci: close the Start menu with Escape instead of stopping its host

Stopping StartMenuExperienceHost on the Windows test runners was followed
by WebContentsView visibilityState specs reading 'hidden' on
windows-11-arm in both runs that did it, and in none before. Only press
Escape when the Start menu's CoreWindow is actually showing (uncloaked),
and log its state.

Clearing the desktop now repeats until nothing is left: closing the
leftover System Properties dialog left its Performance Options dialog
over the test area.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y5cq8qhU8xUitP6SzyT2FV

* ci: sample window occlusion inputs during Windows specs (diagnostic)

With the Start menu closed on windows-11-arm, api-web-contents-view.spec.ts
sees freshly shown windows as hidden for a while (3 of 3 runs). Log the
display, screen saver and power request settings and the WSL/terminal
processes, then run a background sampler that records, whenever it changes,
the foreground window and any window able to occlude Electron's that sits
above the topmost Electron window, plus display on/off and session lock
changes. Its log is printed after the specs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y5cq8qhU8xUitP6SzyT2FV

* ci: stop the windows-11-arm WSL update from covering the specs

The occlusion sampler showed what hides api-web-contents-view.spec.ts's
windows on windows-11-arm: the image runs
`wsl.exe --update --confirm --prompt-before-exit` and relaunches it about
every 90 seconds, each time in a new Windows Terminal window that takes the
foreground over most of the 1024x768 desktop for about a minute, so
Chromium's native occlusion tracking reports Electron windows beneath it as
hidden. The display never turned off (no display timeout on AC, display
status stayed on), so that is ruled out.

Log what launches the update, stop it (and its launcher when that is a
script host outside the step's own ancestry), and have the sampler minimize
any such window that still shows up.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y5cq8qhU8xUitP6SzyT2FV

* ci: trim the Windows occlusion sampler down to a WSL terminal minimizer

The sampler found what hid api-web-contents-view.spec.ts's windows on
windows-11-arm; drop its diagnostic sampling and the power and screen saver
dumps, and keep only what fixes it: a background minimizer, now
script/actions/minimize-wsl-terminals.ps1, that minimizes each
`wsl.exe --update` terminal as it appears and logs its title, pid and
parent process, printed after the specs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y5cq8qhU8xUitP6SzyT2FV

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-30 14:57:53 -04:00
claude[bot]andClaude Opus 5.5 4c10d222cf ci: capture macOS memory-pressure diagnostics on build failure (#54006)
* build: bound devtools-frontend esbuild bundle concurrency on macOS

macOS x64 release builds have been failing in Build Electron when
devtools-frontend esbuild bundle actions die with "The service was
stopped": the esbuild service process is killed externally with no
crash trace, consistent with memory pressure on the 14 GB
macos-15-xlarge runners while siso runs five minify+sourcemap bundles
at once through the generic action pool.

Float a devtools-frontend patch that gives esbuild bundle actions their
own GN pool (depth 2 on macOS hosts), and dump vm_stat, swap usage and
the kernel memorystatus/jetsam log when a macOS build fails so the kill
is observable.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H2pb2QXCU6xBfNMLmjgrLU

* chore: update patches

Refresh the devtools-frontend BUILD.gn blob ids in the esbuild pool patch
after the Chromium roll on main moved the devtools-frontend pin. No change
to the patch content.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H2pb2QXCU6xBfNMLmjgrLU

* ci: drop esbuild pool patch, keep macOS memory diagnostics only

Scope this change down to the failure-only macOS memory-pressure
diagnostics step so we can confirm or rule out memory pressure as the
cause of the intermittent devtools esbuild failures before patching
devtools-frontend.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U8eWCdgZ42Hdi8CMcrcrNb

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-30 14:06:39 -04:00
claude[bot]andClaude Opus 5.5 338a350f7e test: listen for both singleton exits before either can happen (#54593)
* test: listen for both singleton exits before either can happen

'prevents the second launch of app' only started listening for the first
instance's 'exit' after the second instance's exit had been handled. The
two copies quit within milliseconds of each other, so when the spec
process's event loop is busy and sees both exits in the same pass, the
first copy's 'exit' is emitted with no listener, and the test then waits
for it until the 120s test timeout.

Register both exit listeners as each process is spawned, as the other
requestSingleInstanceLock tests already do, kill both copies on the way
out, and fail within 30s naming which copy stalled instead of waiting
out the test timeout.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XT1kpjmqsAdPLBVZMV1pVX

* test: use waitUntil for the singleton launch waits

Record each copy's exit code from an 'exit' listener attached at spawn
and wait on it with the existing waitUntil helper instead of a local
within() helper. Only kill a copy that is still running.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XT1kpjmqsAdPLBVZMV1pVX

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-30 14:06:21 -04:00
Shelley Vohr bc8e748ec8 docs: document denying a display media request and fix a webview spec (#54587)
* docs: document how to deny a display media request

* test: make the webview printToPDF() bad parameter spec reach the type checks

The spec loaded another <webview id="webview"> on every pass of its loop, so
from the second pass on `webview` named a collection of elements and the call
was rejected with "webview.printToPDF is not a function". Only the first of
the ten parameters was checked. Load the webview once, and require the
rejection to name the parameter.
v46.0.0-nightly.20260930
2026-09-30 14:32:56 +02:00
Shelley Vohr 7af89da308 fix: webview findInPage() hang when the embedder page has an iframe (#54508) 2026-09-30 08:28:29 +02:00
claude[bot]andClaude 03703aea6a test: run pointer lock permission spec serially (#54546)
The helper waits for the webContents 'focus' event before requesting
pointer lock (#54529). In the parallel phase another spec's window can
hold focus, so the event never arrives and the first attempt times out
on macOS. Tag the block 'serial', like the clipboard and paste blocks
that use the same focus wait.


Claude-Session: https://claude.ai/code/session_011wzReGh8dFocAi8ujeiTsA

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-29 16:50:57 -07:00
claude[bot]andClaude efbc851383 test: run fullscreen specs serially (#54549)
The `iframe using HTML fullscreen API while window is OS-fullscreened`
block in chromium.spec.ts and the macOS `fullscreen state` block in
api-browser-window.spec.ts move windows in and out of OS fullscreen.
Under the parallel runner two of these transitions can overlap on
macOS and one never finishes, timing out the test. Tag both blocks
serial.


Claude-Session: https://claude.ai/code/session_01XUFN2KBqhJMviaCibjxNUU

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-29 16:50:44 -07:00
claude[bot]andClaude 1d0cc3e705 test: wait for PageState sync before navigating in restore spec (#54504)
The previous fix waited for the edited form state after navigating away,
where it can only arrive via the old frame's unload-time update. The
browser only waits briefly for that frame to unload, so a slow hidden
renderer could still miss it. Wait for the renderer's delayed state sync
while the form page is still current instead.


Claude-Session: https://claude.ai/code/session_01VEsRtPpi9c1f38o3GaZskj

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-29 16:49:28 -07:00
37338b5cc1 chore: bump chromium to 156.0.8078.3 (main) (#54551)
* chore: bump chromium in DEPS to 156.0.8078.0

* chore: update patches

* 8383239: Introduce a new FindInPage domain (with commands) in DevTools

Upstream moved find request id allocation into FindRequestManager and
now delivers the id through a synchronous callback on WebContents::Find.
Capture that id in FindInPage instead of maintaining Electron's own
counter, so the value returned from findInPage matches the requestId
reported by found-in-page.

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* chore: bump chromium in DEPS to 156.0.8078.3

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: electron-claude[bot] <279139701+electron-claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-29 16:45:48 -07:00
claude[bot]andClaude d23dd9df44 ci: enable faraday hold-for-review gate (#54202)
Adds the hold-for-review block to .github/faraday.yml so that a pull request carrying the hold-for-review label is held for 24 business hours (Pacific time) before faraday lets it merge; pull requests carrying fast-track are exempt. The gate is implemented in electron/faraday#24.


Claude-Session: https://claude.ai/code/session_01DpVCp5zarjEPP2s4MQwLXo

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-29 19:29:29 -04:00
claude[bot]andClaude e128184820 fix: avoid NoDestructor on trivially destructible QueueState in release builds (#54554)
With DCHECKs off, SEQUENCE_CHECKER expands to nothing, leaving QueueState
trivially destructible and tripping base::NoDestructor's static_assert.
Give it a user-provided destructor so it is non-trivial in every config.


Claude-Session: https://claude.ai/code/session_01FsSQW86CrHuBNQNRMyPCex

Co-authored-by: Claude <noreply@anthropic.com>
v46.0.0-nightly.20260929
2026-09-29 11:02:05 -07:00
claude[bot]andClaude 2454be571a test: parse all custom page size PDFs in one pdf.js process (#54491)
`printToPDF() with custom page sizes` printed 11 page sizes and called
readPDF() on each one. Every readPDF() call starts a full Electron
process to run pdf.js. On macOS x64 CI, with the parallel vitest
workers, that is about 2-5s per call, so the loop often went over the
30s test timeout.

Add readPDFs(), which parses several PDFs in one pdf-reader process.
The test now prints every size first and then parses them all with a
single launch. readPDF() is now a wrapper around readPDFs().


Claude-Session: https://claude.ai/code/session_01TVWNFK7iBS3en5muZhanuM

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-28 21:51:37 -07:00
Charles KerrandCopilot dfcdfb14e5 fix: clear detached DevTools backlinks before widget destruction (#54524)
Clear the retained view and delegate pointers before resetting their owning widget so neither raw_ptr outlives its pointee during CloseDevTools.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-29 12:20:41 +09:00
claude[bot]andClaude 6b6c3023ed test: wait for focus before requesting pointer lock in spec (#54529)
content rejects requestPointerLock() with WrongDocumentError, without
ever consulting the permission request handler, when the widget does not
have focus. On macOS webContents.focus() takes effect asynchronously, so
the request could race ahead of focus and the helper found no recorded
permission request. Wait for the focus event first, and assert the
request was rejected by the handler (SecurityError).


Claude-Session: https://claude.ai/code/session_011wzReGh8dFocAi8ujeiTsA

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-28 23:42:38 +00:00
c33abcb2da chore: bump chromium to 156.0.8077.0 (main) (#54527)
* chore: bump chromium in DEPS to 156.0.8077.0

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>

* chore: update siso revision

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: electron-claude[bot] <279139701+electron-claude[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2026-09-28 18:27:31 -05:00
Samuel Attard b0b9fcdc5a perf: prefetch the framework on cold launches on macOS (#54515)
On a cold launch the framework and its resources are paged in with
thousands of small reads that stall the main thread and child processes.
Read them sequentially on a background thread at the start of the browser
process instead, so those faults hit the page cache.

Skipped when the framework is already resident or memory is short, reads
only the running architecture's slice of a universal binary, and runs at
utility disk priority.
2026-09-28 14:48:35 -07:00
069b0a9fe3 chore: bump chromium to 156.0.8076.0 (main) (#54318)
* chore: bump chromium in DEPS to 156.0.8073.0

* 8409748: Update RenderWidgetHostViewBase::host_ lifetime

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8410048: [dcheck-to-check] Convert DCHECKs in content/browser/ [34/n]

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8401889: [Win] Read GetLastError() right after CreateFile() in ProcessSingleton

Upstream now reads GetLastError() inside the TRACE_EVENT0 scope, which is
the same fix this patch carried, so drop that hunk.

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8293899: Android: Enable ThemeService for WebUI NTP

Upstream moved the //chrome/browser/themes dependency from a per-platform
conditional into the unconditional deps of the mixers target, so the patch
now removes it from that list instead.

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8412026: [mac] Support video capture lock on macOS

Keep the compositor unsuspended when the window is headless, visible, or
has an active video capture lock.

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8404074: [posix] Don't call SetNonBlocking() inside DCHECK() in ProcessSingleton

Upstream made the same change, so drop the hunk from this patch.

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8421647: media: Move GPU/graphics client utilities to media/gfx/

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8361191: [api] Add MicrotaskQueue::SetMicrotasksPolicy()/GetMicrotasksPolicy()

V8 now exposes the per-queue microtasks policy on v8::MicrotaskQueue, so
remove the patch that added it and switch node_util.cc to the upstream
SetMicrotasksPolicy()/GetMicrotasksPolicy() names.

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* chore: remove upstreamed patches

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8455783
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8455325
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8431509
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8402403
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8402402

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* chore: update patches

* chore: update siso revision

* 8426326: Linux: Rename DarkModeManagerLinux to PortalSettingsLinux

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8278613: Plumb navigation IDs to MIME handler streams

Pass the navigation ID through StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent
to the MIME handler stream manager, and only create the plugin response
interceptor throttle for navigation requests, matching the upstream
ChromeContentBrowserClient change.

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8403343: Bump clang revision

The new clang package ships the raw_ptr plugin change from
crrev.com/c/8358382, after which [chromium-containers] rejects T*
template arguments in std::list, std::set and std::vector fields. Store
raw_ptr<T> in those Electron containers instead.

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8362297: viz: Add `is_secure` flag to CopyOutputRequest and friends

The new is_secure member brings VideoCaptureParams, together with the
use_native_picker field this patch adds, over the chromium-style
complexity threshold, so the implicit inline copy constructor is now
rejected. Declare out-of-line copy and move constructors and assignment
operators for the struct in the patch.

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8442576: Remove id from ChildProcessData

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8421383: [RWS] Remove unused RWS cookie exclusion reason

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8240331: Support targeting a network in NetworkService's WebSockets

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8426064: Remove flag for restrict frame destinations to navigate

The frame-destination check is now unconditional upstream, so drop the
feature flag check in net.request.

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8292633: [atmemory] Add `blink::mojom::ScrollType` to the Autofill scroll callstack

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8405125: FSA: rename UserAction to AccessTrigger and add programmatic triggers

The former UserAction::kNone case is now split into
AccessTrigger::kProgrammaticRead and kProgrammaticWrite; both keep the
previous behavior of not granting access automatically and of replying to
sensitive entry checks without prompting.

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8399046: Add chrome:// host and path mapping for component extensions

ExtensionConfigMap::GetConfigProvider() now takes an Extension; use the
new GetConfigProviderByExtensionId() for the id-based lookup.

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8445301: [Linux] Decouple //components/dbus from //ui/base and //net

The //components/dbus component no longer depends on //components/dbus/menu,
so depend on it directly for status_icon_linux_dbus.cc.

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8360557: [Extensions] Make generated features immutable

FeatureProvider::AddFeature() no longer replaces an existing feature, so
the entries Electron's feature files used to override core ones now fail
a CHECK at startup. Drop the ones that duplicate the core definitions, or
differ only in ChromeOS-only branches. Keep chrome.webstorePrivate
unavailable by moving its delegated availability check into the core
definition with a patch.

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* 8427384: Generate CDP TypeScript definitions directly from in-tree PDL files

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fixup! 8403343: Bump clang revision

* chore: update patches

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* 8397345: Move titlebar_config.h to chrome/browser/win

The move switched the color mixers' Windows dependency from the narrow
titlebar_config target to all of //chrome/browser/win, although the
mixer uses nothing from it. On Windows that pulls
//chrome/browser/profiles into Electron's link, where its
ProfileKeyedServiceFactory collides with the one Electron provides for
the spellchecker. Patch the unused dependency out.

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* 8403320: [WebUI] Disallow devtools:// scheme for WebUI data sources by default

URL data sources are no longer served to devtools:// unless they opt in,
so DevTools failed to load its frontend. Opt Electron's bundle data
source in, and let its theme data source serve colors.css to devtools://
as Chrome's ThemeSource does.

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* 8394377: Migrate RefCountedDeleteOnSequence to start-from-one ref counting (4/4)

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore: bump chromium in DEPS to 156.0.8075.0

* chore: update patches

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>

* 8467669: [zoom] Key host-less zoom levels on the URL without its fragment

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore: update patches

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore: bump chromium in DEPS to 156.0.8076.0

* 8468407: [gtk] Don't leave GDK_BACKEND set in the environment after GTK init

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8457646: [snapshot] Include embedder string in version hash

Upstream moved Version::Hash() out of line and now builds it with
base::Hasher over the version number and embedder string. Fold the
v8_version_hash_salt into that hasher the same way instead of carrying
a separate FNV-1a helper and hash_combine() call.

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* chore: update patches

* 8459447: gin: Mark the stack-only helper classes STACK_ALLOCATED()

gin::Dictionary is now STACK_ALLOCATED(), and the find-bad-constructs
plugin conservatively treats any template instantiated with a
stack-allocated type argument as stack-allocated too. Mark the two
gin_helper::Promise<gin_helper::Dictionary> fields with
STACK_ALLOCATED_IGNORE, since Promise<T> only names T as its resolve
type and never stores one.

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* 8424587: mojo: Remove unused WrapPlatformFile and UnwrapPlatformFile helpers

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

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fixup! 8403343: Bump clang revision

notifications_ is now a std::set<raw_ptr<Notification>>, and libc++ has
no heterogeneous set::erase, so erasing by key after Dismiss() built a
temporary raw_ptr from the notification. On macOS Dismiss() has already
destroyed it by then, so that took a BackupRefPtr reference on freed
memory. Find it with the transparent comparator, which compares
addresses without constructing a raw_ptr, and erase by iterator.

Also drop NotifyIconHost::NotifyIcons, unused since notify_icons_ became
a std::vector<raw_ptr<NotifyIcon>>.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fixup! 8426064: Remove flag for restrict frame destinations to navigate

Drop the network features include; its only use was the
kRestrictFrameDestinationsToNavigate check this CL removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: electron-claude[bot] <279139701+electron-claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: clavin <clavin@electronjs.org>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2026-09-28 16:01:00 -05:00
Charles KerrandCopilot 8b85bb4d1c fix: detach interned string cache before isolate disposal (#54520)
Release cached strings and isolate references in OnBeforeDispose rather than after the isolate has been freed. Add a subprocess regression covering clean shutdown after nativeImage.getSize populates the cache.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-28 14:52:46 -05:00
Shelley Vohr 013d90fb56 fix: crashReporter.setUploadToServer() having no effect after start (#54506) 2026-09-28 10:36:11 -07:00
Robo 411dd99148 test: wait for child output before asserting on it (#54507) 2026-09-28 10:35:49 -07:00
Charles KerrandCopilot a586a72271 fix: clear DownloadItem backlink before native removal (#54513)
Keep a stack-local native pointer and clear the raw_ptr member before Remove() synchronously deletes the native item. Preserve observer removal and download cancellation behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-28 10:35:35 -07:00
RoboandSamuel Attard 1e1ddcc3d9 refactor: add a native peer helper for cppgc wrappers (#54410)
* refactor: add a native peer helper for cppgc wrappers

cppgc wrapper destructors run during sweeping, where they must not touch
other GC objects, run JavaScript, or tear down native registrations.
Debugger, Notification and WebContents each hand rolled an off-heap peer
for this.

Add NativePeer<Wrapper>, which owns native registrations, resources, and
independent V8 roots for a wrapper. The wrapper's deleter only queues the
peer. Queued peers are released and deleted from a posted task. At
shutdown they are released while V8 can still run and deleted after the
isolate is disposed, so peer teardown never runs inside a cppgc finalizer
and nothing leaks.

* chore: apply review feedback

Co-authored-by: Samuel Attard <sam@electronjs.org>

* chore: apply review feedback

Co-authored-by: Samuel Attard <sam@electronjs.org>

---------

Co-authored-by: Samuel Attard <sam@electronjs.org>
2026-09-28 16:58:43 +00:00
Shelley Vohr 7e61137a70 feat: add protocol.registerSource() (#53220)
* feat: add protocol.registerSource()

A protocol.handle() handler runs on the main thread, so requests to an
app's own scheme wait whenever the main process is busy there, most
visibly at startup when the first window's HTML, scripts and styles are
served by that handler. For the common case of serving bundled files
there is nothing for JavaScript to decide, so let the app declare it:

  protocol.registerSource('app', {
    routes: [
      { match: { host: 'bundle', path: '/assets/' },
        source: { type: 'directory', root: assetsDir } },
      { match: { host: 'bundle' },
        source: { type: 'directory', root: distDir } }
    ]
  })

The routes are compiled into an immutable ProtocolSource held by the
session's ProtocolRegistry. The URLLoaderFactory the registry hands out
for the scheme (to renderers for subresources, to navigations, and to
net.fetch through ProtocolRegistry::CreateRegisteredFactory) is bound on
the IO thread; it picks the most specific route (a host match over a
wildcard, then the longest path prefix), resolves the rest of the path
inside that route's root, refusing anything that would leave it, and
hands the file to AsarURLLoader, which reads it on a blocking sequence
the way file: URLs are read, asar archives included, with Content-Type
from the extension and any headers the route adds. AsarURLLoader reads
plain files itself for this (read_plain_files) rather than delegating to
Chromium's file loader, whose Last-Modified formatting costs more than
the read for small files. A scheme has either a handler or a source;
unhandle() removes either and isProtocolHandled() reports both.

Linux x64, page with 60 stylesheets, median of 3 warm loads:
protocol.handle on the main thread 22 ms idle / 120 ms with the main
process busy for 100 ms after navigation; registerSource 13 ms / 14 ms.
Renderer fetch() round trip 0.33 -> 0.20 ms; browser-process CPU per
request 234 -> 200 us with no main-thread time at all.

* test: protocol.registerSource

* fix: address review of protocol.registerSource

- HEAD requests get the response head with Content-Type/Content-Length
  and an empty body, without opening or reading the file.
- A satisfiable Range is answered 206 with Content-Range and
  Content-Length; an unsatisfiable one 416 with `bytes */size`.
- Route roots are canonicalized at registration and each requested file
  is resolved (symlinks included) before it is opened; a file that is not
  under the root is not served.
- Plain-file sizes no longer pass through Archive::FileInfo's 32-bit
  size, so files over 4 GiB are served whole.
- registerSource rejects the full set of built-in schemes
  (ProtocolRegistry::IsBuiltinScheme), not just the legacy list.
- Reduce a few variable scopes, drop Route's out-of-line special members.

* fix: address second review of protocol.registerSource

* chore: oxfmt

* docs: mark protocol.registerSource() and getSource() as experimental

* fix: tighten registerSource() route validation and root containment

* docs: note that loader-computed headers override route headers
2026-09-28 16:53:39 +00:00
claude[bot]andClaude c21fc2dd24 test: wait for earlier Electron workers to exit before serial specs (#54489)
vitest starts stopping a finished file's worker without waiting for it, so a
worker in the 'serial' project could launch while earlier Electron workers
were still quitting and be handed activation by them. From that state
app.hide() was ignored, and the macOS app.isActive and app.isHidden specs
timed out on every attempt. Serial workers now wait for all earlier workers
to exit, and the specs take activation through a window of their own before
hiding.


Claude-Session: https://claude.ai/code/session_01JBP7gbUymggpz1TCjF51Q1

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-28 17:05:15 +02:00
Shelley Vohr d58cb24d78 fix: throw instead of crashing when nativeImage cannot create a Buffer (#54488)
toPNG(), toJPEG(), toBitmap(), getBitmap() and getNativeHandle() called
ToLocalChecked() on the Buffer they created. Node.js throws and returns an
empty handle when the current context has no Node.js environment, as in
sandboxed and service worker preload scripts, so the renderer aborted.
Return the empty handle and let the pending exception reach the caller.

toBitmap() now allocates its Buffer before reading pixels, so it throws
before doing the work and a failed allocation throws as well.
v46.0.0-nightly.20260928
2026-09-28 10:02:39 +02:00
Shelley Vohr 8af22fd094 fix: apply setContentProtection() in Windows remote sessions again (#54492)
* fix: apply setContentProtection() in Windows remote sessions again

Chromium stopped excluding windows from capture in remote sessions so that
its own Picture-in-Picture windows stay visible to the remote user
(https://chromium-review.googlesource.com/c/chromium/src/+/7918332). The
same code path backs setContentProtection(), so since Electron 44 the call
has silently done nothing over Remote Desktop while isContentProtected()
kept returning true. Enable the feature that lifts the restriction by
default, and document the effect on remote users and how to opt out.

* docs: note when setContentProtection() takes effect on Windows

SetWindowDisplayAffinity is applied by the next DWM composition. Measured on
Windows 11 24H2, the first frame without the window was presented 9-42ms after
the call, and a capture started within about 11ms could still contain it.
2026-09-28 10:02:25 +02:00
Shelley Vohr 4205b3641d fix: apply the X11 input shape before setIgnoreMouseEvents() returns (#54487)
The XShape request that setIgnoreMouseEvents() issues on X11 stayed in the
client-side output buffer until the UI thread next returned to its message
loop, so the window kept receiving (or kept ignoring) mouse events for as
long as the caller stayed busy. Round-trip to the server after updating the
region. A flush alone only writes the request to the socket; the server
gives no ordering guarantee between clients, so only a reply shows that the
shape is in place before another client's next request is processed.
2026-09-28 08:01:59 +02:00
Shelley Vohr d1e8dad911 fix: report install folders that the sandbox cannot read on Windows instead of crash-looping the GPU process (#54382)
* fix: let sandboxed processes read per-user install directories with stray AppContainer ACEs on Windows

Sandboxed children run with a restricted token, and Windows evaluates a
restricted token against a DACL that contains any AppContainer package
SID as if it were an AppContainer: only an ALL APPLICATION PACKAGES (or
ALL RESTRICTED APPLICATION PACKAGES) entry can grant access. Per-user
install locations under %LOCALAPPDATA% inherit package ACEs left by
other software and carry neither, so every sandboxed child was denied
its own install directory, died opening icudtl.dat, and the app exited
with "GPU process isn't usable". Program Files installs are unaffected
because they inherit ALL APPLICATION PACKAGES read access.

Probe the install directory with the sandbox's initial token before the
first child is launched and, when the probe is denied, add an inheritable
read/execute ACE for ALL APPLICATION PACKAGES, the same access Program
Files grants by default.

* fix: check sandbox access to the install dir with AccessCheck instead of impersonating

Same probe, but ask the kernel with AccessCheck() against the restricted
token and the file's security descriptor rather than putting the token on
the browser's main thread.

* fix: abort with a descriptive error instead of granting access at runtime

Leave the ACL to installers: check whether the sandbox token can read
the install directory and, if not, stop startup with a message that names
the directory and the icacls command that fixes it.
2026-09-27 09:50:43 +02:00
claude[bot]andClaude 5213c824cb build: label main PGO profile update PRs with no-backport (#54482)
Each supported release branch gets its own profile update PR from its own
pgo-generation run, so the PR opened against main should never be
backported.


Claude-Session: https://claude.ai/code/session_01VbNpxpzqzEsUwcAgW6xiW8

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-27 07:49:45 +00:00
claude[bot]andClaude 24b40f68b9 test: fix flaky navigationHistory.restore PageState spec (#54468)
The test read the restored input value once on dom-ready and then polled
that constant, so any early read turned into a guaranteed 10s timeout.
The saved PageState could also be snapshotted before the old
cross-process form page sent its final state on unload, leaving the
entry without the edited value.

Wait until the saved entry's PageState actually contains the typed value,
then await restore() and assert the input value directly.


Claude-Session: https://claude.ai/code/session_01VEsRtPpi9c1f38o3GaZskj

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-27 06:06:32 +00:00
claude[bot]andClaude f4f4e8a0da test: fix chrome.tabs reload spec race with the reload commit (#54467)
chrome.tabs.reload() resolves after the reload has started, so the
reply to the 'reload' message is addressed to the document being
replaced. When the new document commits first the reply is dropped,
console-message never fires and the test times out.

Keep the reload result in the service worker, wait for did-finish-load,
then ask the reloaded page for it with a new getReloadStatus message.


Claude-Session: https://claude.ai/code/session_01KgNfjEYpFmXyDvfN11dqJM

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-27 06:06:18 +00:00
electron-pgo-updater[bot] c828823ba1 build: update PGO profiles (#54471)
* build: update linux-arm64 PGO profile

* build: update linux-x64 PGO profile

* build: update macos-arm64 PGO profile

* build: update macos-x64 PGO profile

* build: update v8-builtins PGO profile

* build: update win-arm64 PGO profile

* build: update win-x64 PGO profile

---------

Co-authored-by: electron-pgo-updater[bot] <290827142+electron-pgo-updater[bot]@users.noreply.github.com>
2026-09-27 05:10:47 +00:00
santichausis 690ccdd890 docs: fix offline installation cache key description (#53824) 2026-09-26 14:34:40 -07:00
Shelley Vohr 2dc5757130 fix: keep focus in a child WebContentsView when its window regains focus (#54378)
When a BrowserWindow was reactivated, the views focus manager restored
focus to the view the user last clicked into, and BrowserWindow's focus
handler then moved it to the window's own webContents unconditionally. A
child WebContentsView therefore lost focus on every Alt+Tab round trip on
Windows and Linux. Leave focus alone when another view in the window
already holds it.
2026-09-26 14:43:25 +02:00
Shelley Vohr 3722f4bcec fix: restore keyboard input after a JavaScript dialog on Windows and Linux (#54380)
While alert(), confirm() or a beforeunload prompt blocks the renderer,
Chromium ignores focus gains on the page's view. Electron shows these as
native dialogs owned by the window, and closing one hands activation back
to the window before the dialog result is delivered, so the view ended up
focused in aura but blurred in Blink: no caret, and typed characters were
dropped until the window was deactivated and activated again. After the
dialog result unblocks the renderer, replay the focus when the two sides
disagree.
2026-09-26 14:41:05 +02:00
Shelley Vohr ff6681b1ff fix: honor win.setEnabled(false) and modal parents under Wayland (#54427)
On Linux, disabling a window (setEnabled(false), or opening a modal child)
only took effect under X11; under Wayland the window kept receiving input
and isEnabled() always returned true.

Replace the X11-only EventDisabler rewriter with the window tree host's
DisableEventListening(), which blocks event dispatch the same way on both
X11 and Wayland, and run the disabling specs on Wayland too.
2026-09-26 20:17:17 +09:00
claude[bot]andClaude Opus 5.5 783bf56ab7 fix: abort on wrong-typed optional string CDP param (#54418)
* test: add crash case for wrong-typed optional string CDP param

Sending a number for Input.dispatchKeyEvent's optional `text` param via
webContents.debugger aborts the browser process instead of rejecting.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TvtfDf4VmRTDrn2oZYYK6Q

* test: add in-process debugger case for wrong-typed string param

Mirrors the crash-case fixture inside api-debugger.spec.ts.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TvtfDf4VmRTDrn2oZYYK6Q

* fix: use Chromium's crdtp std::string traits in Node

Drop Node's crdtp::ProtocolTypeTraits<std::string> definitions so the
specialization has one definition, Chromium's, which reports a protocol
error on wrong-typed values instead of CHECKing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TvtfDf4VmRTDrn2oZYYK6Q

* chore: attribute crdtp traits patch to Claude

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TvtfDf4VmRTDrn2oZYYK6Q

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-26 20:15:16 +09:00
Shelley Vohr b947435d1d fix: keep the zoom level of file: and other host-less pages across fragment navigations (#54381)
HostZoomMap keys zoom levels for URLs without a host by their full spec,
including the fragment, so on a file: page a location.hash change moved
the page to a new key: getZoomLevel() dropped to the default while the
page kept its zoom, and the next zoom in/out was computed from the
default. Carry the upstream fix
(https://chromium-review.googlesource.com/c/chromium/src/+/8467669),
which strips the fragment from the keying URL.
2026-09-26 12:48:57 +02:00
Shelley Vohr 25689bdd46 fix: keep visual zoom level limits across navigations and for webview guests (#54373)
setVisualZoomLevelLimits() only reached the current renderer, and the
cached WebPreferences that every new render view receives carry the
default 1/1 page scale limits, so the limits were lost on the next
navigation. For <webview> guests they never applied at all because
pinch-zoom is handled by the embedder's compositor. Store the limits in
WebContentsPreferences, recompute WebPreferences when they change, and
forward them to the embedder for guests.
2026-09-26 12:17:10 +02:00