Commit Graph

4212 Commits

Author SHA1 Message Date
Samuel Attard
c9a1cff273 fix: dispatch toast action and reply events from WinRT activation path (#51397)
fix: dispatch toast action and reply events from WinRT activation path (#51286)

* fix: dispatch toast action and reply events from WinRT activation path

ToastEventHandler::Invoke previously returned S_OK without dispatching
whenever the activation arguments looked structured (type=action,
type=reply, or contained &tag=), on the assumption that the COM
INotificationActivationCallback::Activate path would deliver the event
instead. That assumption only holds when Windows actually invokes the
COM activator — which it does for MSIX-packaged apps launched cold, and
for unpackaged apps with a properly-registered CLSID when the app is
not already running. For non-MSIX apps with activationType="foreground"
while the app is running (the common case), Windows raises only the
in-process WinRT Activated event, so action and reply were silently
dropped.

Dispatch structured activations through the same HandleToastActivation
the COM path uses. User input (reply text, selection values) is pulled
from IToastActivatedEventArgs2::UserInput, which carries the data the
COM callback would otherwise have received via
NOTIFICATION_USER_INPUT_DATA.

Also drop the &tag= term from the structured-args check. Plain clicks
in Electron-generated XML don't carry tag=, and a custom toast_xml that
puts tag= on a click argument should now dispatch as a click rather
than being silently dropped.

* fix: release HSTRING out-params from toast activation

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-04-29 23:58:36 -05:00
Niklas Wenzel
7e0499d55d feat: support heap profiling in contentTracing (#51178)
* feat: support heap profiling in `contentTracing`

* chore: backport crrev.com/c/7603976 to fix DCHECK failure

* fix: heap profiling test flakes (#51224)
2026-04-29 11:29:46 -07:00
trop[bot]
86b483af5b fix: use no-op header client for Fetch-intercepted requests (#51371)
fix: use no-op header client for Fetch-intercepted requests (#50744)

* fix: use the non-pass-through path for Fetch-intercepted requests

* Revert "fix: use the non-pass-through path for Fetch-intercepted requests"

This reverts commit 395fb8bb8c.

* fix: use no-op header client for Fetch-intercepted requests

* fix: bring back `DCHECK` that was prematurely removed

* style: reformat code

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Noah Gregory <noahmgregory@gmail.com>
2026-04-29 18:42:45 +02:00
trop[bot]
6fd63cdba8 fix: prevent crash when calling contentTracing APIs before app is ready (#51352)
* fix: prevent crash when calling contentTracing APIs before app is ready

Added Browser::Get()->is_ready() guards to all contentTracing API functions (startRecording, stopRecording, getCategories, getTraceBufferUsage) so they reject their returned Promises with a clear error message instead of crashing when called before app.whenReady().

Added a crash-case fixture test that validates all four APIs reject properly before readiness and work normally after.

Co-authored-by: om-ghante <mr.omghante1@gmail.com>

* chore: fix linter error in `spec/fixtures/crash-cases/content-tracing-before-ready/` (#51356)

chore: fix linter error in spec/fixtures/crash-cases/content-tracing-before-ready/

introduced earlier today in 6f2e5cd4

* chore: make linter happy

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: om-ghante <mr.omghante1@gmail.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2026-04-28 11:08:11 -05:00
trop[bot]
a629331619 fix: validate header name and value in webRequest.onBeforeSendHeaders (#51365)
* fix: validate header name and value in webRequest.onBeforeSendHeaders

Chromium's net::HttpRequestHeaders::SetHeader() uses CHECK() to enforce
valid header names and values, which causes a fatal crash if the caller
passes invalid strings. When users modify requestHeaders in the
onBeforeSendHeaders callback with invalid header names (e.g. containing
spaces) or invalid header values (e.g. containing CRLF), the
gin::Converter<net::HttpRequestHeaders>::FromV8() calls SetHeader()
directly, triggering the CHECK and crashing the process.

This change adds pre-validation using net::HttpUtil::IsValidHeaderName()
and net::HttpUtil::IsValidHeaderValue() before calling SetHeader(),
silently skipping invalid headers instead of crashing.

Co-authored-by: loufulton <loufulton.cz@gmail.com>

* Update shell/common/gin_converters/net_converter.cc

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

Co-authored-by: loufultoncz-coder <loufulton.cz@gmail.com>

* Update spec/api-web-request-spec.ts

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

Co-authored-by: loufultoncz-coder <loufulton.cz@gmail.com>

* fix: lint

Co-authored-by: loufulton <loufulton.cz@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: loufulton <loufulton.cz@gmail.com>
2026-04-28 11:07:36 -05:00
trop[bot]
248ccef775 fix: add MicrotasksScope for worker exit emit in ContextWillDestroy (#51348)
a39108c5a4 (#47244) replaced gin_helper::EmitEvent with a direct
`v8::Function::Call()` in `WebWorkerObserver::ContextWillDestroy`
to avoid re-entering the microtask checkpoint during worker teardown.

V8 `DCHECK()`s that a policy is set. Under the old code path, this
happened with a node::CallbackScope. Under the new code path, it's
possible for a policy to not be set, causing that `DCHECK()` to fail.

This PR copies a39108c5a4's changes in `ShareEnvironmentWithContext()`:
it explicitly adds a `kDoNotRunMicrotasks` scope.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2026-04-27 16:52:26 -07:00
trop[bot]
dd74ff3451 fix: honor webContents.print dpi horizontal/vertical options (#51355)
* fix: honor webContents.print dpi horizontal/vertical options

Co-authored-by: Kunal Dubey <xakep8@protonmail.com>

* style: fix clang-format in print dpi parsing

Co-authored-by: Kunal Dubey <xakep8@protonmail.com>

* style: extract print dpi key constants

Co-authored-by: Kunal Dubey <xakep8@protonmail.com>

* fix: use local dpi constants in print options parser

Co-authored-by: Kunal Dubey <xakep8@protonmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Kunal Dubey <xakep8@protonmail.com>
2026-04-27 18:36:54 -05:00
Charles Kerr
dea65bddd4 fix: crash in AutofillPopup teardown (#51321)
fix: crash in AutofillPopup teardown (#51302)

Fix a crash in AutofillPopupView::Show() when the popup
tried to show itself after the parent's native view had
already gone away during teardown.

2026-04-23T20:44:32.7015810Z Received signal 11 SEGV_ACCERR 000000000160
2026-04-23T20:44:32.9322010Z 4   Electron Framework  ... views::Widget::IsVisible() const + 28
2026-04-23T20:44:32.9528810Z 6   Electron Framework  ... electron::AutofillPopupView::Show() + 200
2026-04-23T20:44:32.9632090Z 7   Electron Framework  ... electron::AutofillPopup::CreateView(...) + 1380
2026-04-23T20:44:32.9749770Z 8   Electron Framework  ... electron::AutofillDriver::ShowAutofillPopup(...) + 736
2026-04-23T20:44:33.0015220Z ✗ Electron tests failed with kill signal SIGSEGV.
2026-04-27 10:49:00 +02:00
trop[bot]
57fee9f2c1 fix: remove insets on fullscreen windows on Windows (#51332)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Mitchell Cohen <mitch.cohen@me.com>
2026-04-26 19:13:13 -05:00
reito
93cc936a94 fix: offscreen rendering with correct screen info. (#50375)
* fix: osr use correct screen info.

Co-authored-by: reito <reito@chromium.org>

* chore: e patches all (trivial only)

* 更新 breaking-changes.md

* chore: fixup .patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2026-04-24 12:36:54 -04:00
Samuel Attard
ce0739ad4f fix: ensure corsEnabled: false protocol handlers do not work across protocols (41-x-y) (#51270)
fix: ensure corsEnabled: false protocol handlers do not work across protocols (#51152)

* fix: ensure corsEnabled: false protocol handlers do not work across protocols

Subresource requests for registered custom protocols are routed to
ElectronURLLoaderFactory via the renderer's per-scheme URLLoaderFactoryBundle
entry, which bypasses the network service's CorsURLLoaderFactory. This meant a
cross-origin page could fetch() a scheme registered with {supportFetchAPI: true}
and read the response body even when {corsEnabled: true} was not set.

Replicate CorsURLLoader::StartRequest's kCorsDisabledScheme gate in
ElectronURLLoaderFactory::CreateLoaderAndStart so cross-origin mode=cors
requests to such schemes fail before the JS handler runs, and tag cross-origin
mode=no-cors responses as opaque so the body is not script-readable while <img>
and similar subresource loads continue to work.

Re-enable the long-disabled "disallows CORS and fetch requests when only
supportFetchAPI is specified" test, add coverage for the opaque/no-cors,
same-origin, handler-not-invoked, corsEnabled-unaffected and net.fetch-unaffected
cases, and migrate spec helpers that were exercising a {supportFetchAPI: true}
scheme cross-origin to a corsEnabled scheme.

* chore: oxfmt

(cherry picked from commit 92f0993d94)
2026-04-23 09:49:23 +02:00
electron-roller[bot]
12410f16ba chore: bump node to v24.15.0 (41-x-y) (#51088)
* chore: bump node in DEPS to v24.15.0

* fix(patch): adapt V8 sandboxed pointers for buffer kMaxLength

Upstream replaced the hardcoded buffer length limit with a runtime
kMaxLength variable, making the patch's regex workaround for sandbox
vs non-sandbox limits unnecessary. Dropped the test-buffer-concat.js
hunk.

Ref: https://github.com/nodejs/node/pull/61721

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(patch): adapt deprecated GetIsolate for upstream refactors

Upstream removed Uint32ToName from node_contextify.cc and
node_webstorage.cc, and renamed LookupAndCompile to
LookupAndCompileFunction in node_builtins.cc. Updated the
GetIsolate deprecation patch to match.

Ref: https://github.com/nodejs/node/pull/60846
Ref: https://github.com/nodejs/node/pull/60518

* chore: remove upstreamed patch

The fix_generate_config_gypi_needs_to_generate_valid_json patch
applied with "No changes -- Patch already applied", confirming
the fix has been incorporated upstream.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* node#60518: src: build v8 tick processor as built-in source text modules

Upstream restructured BuiltinLoader to auto-detect parameters by
source type, removing the custom parameters overload. Added a new
LookupAndCompileFunction overload for embedder scripts and updated
node_util.cc to use it. Also suppressed exit-time-destructors
warning from builtin_info.h in node_includes.h.

Ref: https://github.com/nodejs/node/pull/60518

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(patch): add LookupAndCompileFunction overload for embedder scripts

Ref: https://github.com/nodejs/node/pull/60518

* fix(patch): stop using v8::PropertyCallbackInfo<T>::This() in sqlite

Ref: https://github.com/nodejs/node/issues/60616

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(patch): correct thenable snapshot for Chromium V8

The snapshot used `*` wildcards which don't match the actual output.
Regenerated with NODE_REGENERATE_SNAPSHOTS=1 to capture the correct
concrete frame + <node-internal-frames> output.

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

* fix(patch): GN build files for new merve dep

Ref: https://github.com/nodejs/node/pull/61984

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(patch): adapt fileExists patch to resolve.js module reorg

Ref: https://github.com/nodejs/node/pull/61769

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(patch): adapt new crypto tests for BoringSSL

Guard aes-128-ccm test in test-crypto-authenticated.js behind cipher
availability check. Skip Ed448/X448/DSA tests in
test-crypto-key-objects-raw.js. Skip AES-KW tests in
test-webcrypto-promise-prototype-pollution.mjs.

Ref: https://github.com/nodejs/node/pull/62240
Ref: https://github.com/nodejs/node/pull/62455

* fix(patch): guard DH key test for BoringSSL

BoringSSL does not support loading DH private keys from PEM, causing
createPrivateKey to throw UNSUPPORTED_ALGORITHM.

Ref: https://github.com/nodejs/node/pull/62240

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(patch): adapt cppgc_heap patch to upstream CppHeap handling

Upstream Node moved CppHeap creation to run unconditionally before
Isolate::Initialize via settings.cpp_heap. The patch's embedder-set
params->cpp_heap was being overwritten by the new upstream default.
Fold the patch into the upstream block so settings.cpp_heap still
wins, an embedder-set params->cpp_heap is preserved, and a default
is only created when neither is provided.

Ref: https://github.com/nodejs/node/pull/58070

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: update patches (trivial only)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(patch): normalize brotli decoder error codes for Chromium's brotli

Electron uses Chromium's brotli (via the unbundling patch), which
returns just the NAME from BrotliDecoderErrorString() instead of the
full "_ERROR_..." prefix Node's bundled brotli emits. Upstream's
web-compression spec-compliance fix (nodejs/node#62107) classifies
brotli failures as TypeError via the "ERR__ERROR_" prefix, which
doesn't match Chromium's output — so DecompressionStream surfaced a
plain Error and the WPT decompression-bad-chunks suite failed for
brotli. Normalize the emitted error code on the C++ side so the JS
layer works against either brotli build.

Ref: https://github.com/nodejs/node/pull/62107

---------

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: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 21:52:17 +02:00
trop[bot]
e105d66074 fix: ignore draggable regions in hidden WebContentsView (#51246)
fix: ignore draggable regions in hidden WebContentsView

Hidden child WebContentsViews were still contributing their draggable
regions to the parent window's non-client hit test, so clicks in the
area where a hidden view's draggable element would render still dragged
the window. Early-return HTNOWHERE when the view is not visible.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-04-22 10:34:59 -05:00
trop[bot]
57b26459d4 build: FTBFS when pdf is disabled (#51248)
fix: FTBFS when pdf is disabled

pdf_features.h has a static_assert that pdf is enabled

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2026-04-22 16:05:18 +02:00
trop[bot]
2c05608a76 fix: preserve transparency across setResizable toggles on Windows (#51217)
After #49428 made `NativeWindowViews::CanResize()` return `resizable_`
for frameless windows (instead of `resizable_ && thick_frame_`),
`HWNDMessageHandler::SizeConstraintsChanged()` started adding
`WS_THICKFRAME` to the window style whenever `CanResize()` reported true.
`WS_THICKFRAME` is incompatible with layered (translucent) windows and
destroys their transparency.

`SetContentSizeConstraints` already guards against this by skipping
`OnSizeConstraintsChanged()` when `!thick_frame_`. `SetResizable` did
not, so toggling resizability on a transparent window (e.g.
`setResizable(false)` then `setResizable(true)`) caused the Chromium
path to add `WS_THICKFRAME` and strip transparency.

Apply the same guard in `SetResizable`. Min/max constraints are still
enforced — Chromium reads them from the widget delegate on every
`WM_GETMINMAXINFO`, independent of `SizeConstraintsChanged()`.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-04-22 12:33:06 +02:00
trop[bot]
f258998fcb fix: intermittent CI failure is-not-alwaysOnTop (#51135)
* fix: intermittent CI failure is-not-alwaysOnTop

Ensure that the `always-on-top-changed` event always fires with the
right 'alwaysOnTop' boolean, regardless of interaction between
SetZOrderLevel() and MoveBehindTaskBarIfNeeded(). We know what the
value will be when all of the HWND events settle, so use that value.

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

* test: temporary commit to torture-test the new change with 1000 iterations

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

* test: keep eventually-becomes-consistent test but do not loop 1000 times

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2026-04-20 15:25:00 -07:00
trop[bot]
b977376c5d fix: allow PDF viewer to show save file picker (#51073)
The PDF viewer's "save with changes" feature uses
`window.showSaveFilePicker()`, but the PDF extension runs in a
cross-origin iframe (chrome-extension:// inside the app's origin).
Chromium's File System Access API blocks cross-origin subframes from
showing file pickers unless the embedder explicitly allows them via
`ContentClient::IsFilePickerAllowedForCrossOriginSubframe()`.

Chrome overrides this in `ChromeContentClient` to allowlist the PDF
extension origin, but Electron never did — so the picker was always
blocked with a SecurityError.

This adds the same override to `ElectronContentClient`, allowing the
built-in PDF extension origin to bypass the cross-origin check.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-04-20 14:21:01 -07:00
trop[bot]
82ed28e817 fix: nodeIntegrationInWorker not working in AudioWorklet (#51006)
* fix: nodeIntegrationInWorker not working in AudioWorklet

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* fix: deadlock on Windows when destroying non-AudioWorklet worker contexts

The previous change kept the WebWorkerObserver alive across
ContextWillDestroy so the worker thread could be reused for the next
context (AudioWorklet thread pooling, Chromium CL:5270028). This is
correct for AudioWorklet but wrong for PaintWorklet and other worker
types, which Blink does not pool — each teardown destroys the thread.

For those worker types, ~NodeBindings was deferred to the thread-exit
TLS callback. By that point set_uv_env(nullptr) had already run, so on
Windows the embed thread was parked in GetQueuedCompletionStatus with a
stale async_sent latch that swallowed the eventual WakeupEmbedThread()
from ~NodeBindings. uv_thread_join then blocked forever, deadlocking
renderer navigation. The worker-multiple-destroy crash case timed out
on win-x64/x86/arm64 as a result. macOS/Linux (epoll/kqueue) don't have
the latch and were unaffected.

Plumb is_audio_worklet from WillDestroyWorkerContextOnWorkerThread into
ContextWillDestroy. For non-AudioWorklet contexts, restore the
pre-existing behavior of calling lazy_tls->Set(nullptr) at the end of
the last-context cleanup so ~NodeBindings runs while the worker thread
is still healthy. AudioWorklet continues to keep the observer alive so
the next pooled context can share NodeBindings.

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* chore: address review feedback

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* fix: stop embed thread before destroying environments in worker teardown

FreeEnvironment (called via environments_.clear()) runs uv_run to drain
handle close callbacks. On Windows, both that uv_run and the embed
thread's PollEvents call GetQueuedCompletionStatus on the same IOCP
handle. IOCP completions are consumed by exactly one waiter, so the
embed thread can steal completions that FreeEnvironment needs, causing
uv_run to block indefinitely. On Linux/Mac epoll_wait/kevent can wake
multiple waiters for the same event so the race doesn't manifest.

Add NodeBindings::StopPolling() which cleanly joins the embed thread
without destroying handles or the loop, and allows PrepareEmbedThread +
StartPolling to restart it later. Call StopPolling() in
WebWorkerObserver::ContextWillDestroy before environments_.clear() so
FreeEnvironment's uv_run is the only thread touching the IOCP.

Split PrepareEmbedThread's handle initialization (uv_async_init,
uv_sem_init) from thread creation via a new embed_thread_prepared_ flag
so the handles survive across stop/restart cycles for pooled worklets
while the embed thread itself can be recreated.

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* chore: address outstanding feedback

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[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>
2026-04-20 12:01:52 +02:00
Samuel Attard
c2420b9f44 refactor: attach translator holder via v8::Function data slot (#51120)
refactor: attach translator holder via v8::Function data slot (#50867)

(cherry picked from commit bfa5c93332)
2026-04-17 16:49:56 -05:00
trop[bot]
c33d43bd67 fix: prevent uaf when destroying guest WebContents during event emission (#51081)
fix: prevent use-after-free when destroying guest WebContents during event emission

Multiple event emission sites in WebContents destroy the underlying C++
object via a JavaScript event handler calling webContents.destroy(), then
continue to dereference the freed `this` pointer. This is exploitable
through <webview> guest WebContents because Destroy() calls `delete this`
synchronously for guests, unlike non-guests which safely defer deletion.

The fix has two layers:

1. A new `is_emitting_event_` flag is checked in Destroy() — when true,
   guest deletion is deferred to a posted task instead of executing
   synchronously. This is separate from `is_safe_to_delete_` (which
   gates LoadURL re-entrancy) to avoid rejecting legitimate loadURL
   calls from event handlers.

2. AutoReset<bool> guards on `is_emitting_event_` are added to
   CloseContents, RenderViewDeleted, DidFinishNavigation, and
   SetContentsBounds, preventing synchronous destruction while their
   Emit() calls are on the stack.

Destroy() now requires both `is_safe_to_delete_` (navigation re-entrancy)
and `!is_emitting_event_` (event emission) to allow synchronous guest
deletion. The existing AutoReset guards on `is_safe_to_delete_` in
DidStartNavigation, DidRedirectNavigation, and ReadyToCommitNavigation
are also now effective for guests.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-04-16 15:27:08 -04:00
trop[bot]
17d5d26499 fix: use CreateDataProperty when copying objects across contextBridge (#51084)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Sam Attard <sattard@anthropic.com>
2026-04-16 10:57:27 -07:00
trop[bot]
8ee008ad48 fix: simpleFullScreen exits when web content calls requestFullscreen (#50985)
fix: simpleFullScreen exits when web content calls requestFullscreen

SetHtmlApiFullscreen only checked IsFullscreen() to detect that the
window was already fullscreen, missing the simple-fullscreen case on
macOS. When web content triggered requestFullscreen the code fell
through to SetFullScreen(true) which toggled simple fullscreen off.

Include IsSimpleFullScreen() in the guard so the HTML-API fullscreen
state is updated without touching the window's fullscreen mode.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-04-15 16:10:25 +02:00
Robo
04f4d4b0e6 chore: backport cppgc cleanups (#50915)
* chore: backport cppgc cleanups

Key fixes:
- Replace `base::WeakPtrFactory` with `gin::WeakCellFactory` in
  MenuMac, MenuViews, and NetLog, since weak pointers to cppgc-managed
  objects must go through weak cells
- Replace `v8::Global<v8::Value>` with `cppgc::Persistent<Menu>` for
  the menu reference in BaseWindow
- Stop using `gin_helper::Handle<T>` with cppgc types; use raw `T*`
  and add a `static_assert` to prevent future misuse
- Add proper `Trace()` overrides for Menu, MenuMac, MenuViews, and
  NetLog to ensure cppgc members are visited during garbage collection
- Replace `SelfKeepAlive` prevent-GC mechanism in Menu with a
  `cppgc::Persistent` prevent-GC captured in `BindSelfToClosure`
- Introduce `GC_PLUGIN_IGNORE` macro to suppress
  known-safe violations: mojo::Remote fields, ObjC bridging pointers,
  and intentional persistent self-references
- Mark `ArgumentHolder` as `CPPGC_STACK_ALLOCATED()` in both Electron's
  and gin's function_template.h to silence raw-pointer-to-GC-type
  warnings

* chore: fix build
2026-04-15 16:39:44 +09:00
trop[bot]
ec9b4dc1b8 fix: crash when closing devtools after focus (#51037)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-04-14 17:45:31 -04:00
Niklas Wenzel
0d4172035d fix: include missing metadata in trace files (#51021) 2026-04-13 17:09:46 -04:00
Niklas Wenzel
e30ba680c9 fix: preference initialization with app.setPath('sessionData') (#50958) 2026-04-13 11:13:21 -07:00
David Sanders
bd778011c0 chore: clean up clang-tidy warnings (#50921)
chore: clean up clang-tidy warnings (#50862)

* chore: use emplace and use it correctly

* chore: redundant cast to the same type [google-readability-casting]

* chore: do not create objects with +new [google-objc-avoid-nsobject-new]

* chore: default arguments on virtual or override methods are prohibited [google-default-arguments]

* chore: warning: C-style casts are discouraged; use static_cast [google-readability-casting]

CFLocaleGetValue already returns CFTypeRef so that redundant static_cast was removed

* chore: refactor block to avoid use after move warning from clang-tidy

Looks like clang-tidy couldn't tell these were two mutually exclusive
branches so there was no actual issue, but refactoring is cleaner
anyway since it makes it more DRY.

* chore: C-style casts are discouraged; use static_cast [google-readability-casting]

No cast needed here, everything is already the correct type

* chore: C-style casts are discouraged; use static_cast/const_cast/reinterpret_cast [google-readability-casting]

* chore: use '= default' to define a trivial destructor [modernize-use-equals-default]

* chore: use range-based for loop instead [modernize-loop-convert]

* chore: redundant void argument list [modernize-redundant-void-arg]

* chore: address code review feedback

* chore: use auto



---------

Co-authored-by: Charles Kerr <charles@charleskerr.com>
2026-04-12 10:15:22 -05:00
trop[bot]
598f3b13a7 fix: apply IsSafeRedirectTarget to net module redirects (#50929)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Sam Attard <sattard@anthropic.com>
2026-04-11 19:07:02 -07:00
trop[bot]
120be8544d fix: use audit token instead of PID for parent code-signature check (#50934)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Sam Attard <sattard@anthropic.com>
2026-04-11 19:05:43 -07:00
trop[bot]
1b8a298d62 fix: use ShowItemInFolder for devtools showItemInFolder embedder message (#50937)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Sam Attard <sattard@anthropic.com>
2026-04-11 19:05:29 -07:00
trop[bot]
aa6835662a fix: clamp autofill popup bounds to the requesting frame viewport (#50944)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Sam Attard <sattard@anthropic.com>
2026-04-11 19:05:11 -07:00
trop[bot]
08b9d0a220 fix: respect iframe sandbox flags for external protocol navigation (#50964)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Sam Attard <sattard@anthropic.com>
2026-04-11 19:04:01 -07:00
trop[bot]
b239f27d53 fix: validate OSR frame geometry against shared-memory mapping size (#50940)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Sam Attard <sattard@anthropic.com>
2026-04-11 13:42:22 -07:00
trop[bot]
a2567d6e24 fix: scope extension tab-ID resolution to the calling BrowserContext (#50926)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Sam Attard <sattard@anthropic.com>
2026-04-11 07:35:25 -05:00
trop[bot]
45232e2ce7 fix: PDF support when site isolation trials disabled (#50845)
* fix: use proper OOPIF PDF check in `StreamsPrivateAPI`

* fix: add `ShouldEnableSubframeZoom` override to `ElectronBrowserClient` for upstream parity

* fix: add `MaybeOverrideLocalURLCrossOriginEmbedderPolicy` override to `ElectronBrowserClient` for upstream parity

* fix: add `DoesSiteRequireDedicatedProcess` override to `ElectronBrowserClient` for upstream parity

* style: move `DoesSiteRequireDedicatedProcess` to correct override section

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Noah Gregory <noahmgregory@gmail.com>
2026-04-10 12:10:35 +02:00
trop[bot]
ef2562a59a fix: external resize hit targets for frameless windows on Windows (#50863)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Mitchell Cohen <mitch.cohen@me.com>
2026-04-10 12:07:28 +02:00
trop[bot]
f39d7d8b37 fix: restore std::deque for dynamic crash key storage (#50837)
#47171 migrated `std::deque` to `base::circular_deque` in
`shell/common/crash_keys.cc`. However, `CrashKeyString` wraps a
`crashpad::Annotation` that holds self-referential pointers and
registers itself in a process-global linked list. `circular_deque`
relocates elements on growth (via `VectorBuffer::MoveConstructRange`),
leaving those pointers dangling — causing missing crash keys or a hung
crashpad handler (especially on macOS). The `base/containers/README.md`
warns: "Since `base::deque` does not have stable iterators and it will
move the objects it contains, it may not be appropriate for all uses."

Reverts to `std::deque`, whose block-based layout never relocates
existing elements. Adds a regression test that registers 50 dynamic
crash keys and verifies they all survive a renderer crash.

Notes: Fixed crash keys being lost and the crash reporter hanging on
macOS when many dynamic crash keys were registered.

Made-with: Cursor

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Alexey Kozy <alexey@anysphere.co>
2026-04-10 10:18:48 +02:00
trop[bot]
93387921c0 fix: webContents.print() ignoring mediaSize when silent (#50856)
fix: webContents.print() ignoring mediaSize when silent

PR #49523 moved the default media size fallback into OnGetDeviceNameToUse,
but the new code unconditionally writes kSettingMediaSize — clobbering
any mediaSize the caller had already set in WebContents::Print() from
options.mediaSize / pageSize. As a result, silent prints with an
explicit pageSize (e.g. "Letter") fell back to A4 with tiny content.

Only populate the default/printer media size when the caller hasn't
already supplied one, preserving the precedence:
  1. user-supplied mediaSize / pageSize
  2. printer default (when usePrinterDefaultPageSize is true)
  3. A4 fallback

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-04-09 21:02:25 -05:00
trop[bot]
9042667690 fix: account for extraSize in aspect ratio min/max clamping on macOS (#50835)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: clavin <clavin@electronjs.org>
2026-04-09 15:31:09 +02:00
trop[bot]
1ad20e5ba4 fix: menu items not cleaned up after rebuild (#50830)
Menu was holding a SelfKeepAlive to itself from construction, so any
Menu that was never opened (e.g. an application menu replaced before
being shown) stayed pinned in cppgc forever. Repeated calls to
Menu.setApplicationMenu leaked every prior Menu along with its model
and items.

Restore the original Pin/Unpin lifecycle: start keep_alive_ empty and
only assign `this` in OnMenuWillShow. OnMenuWillClose already clears
it.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-04-09 11:56:38 +02:00
trop[bot]
a26aee5a6d fix: devtools re-attaches on open when previously detached (#50816)
PR #50646 added a dock state allowlist in SetDockState() that collapsed any
non-matching value to "right". WebContents::OpenDevTools passes an empty
string when no `mode` option is given, which is the sentinel LoadCompleted()
uses to restore `currentDockState` from prefs. The allowlist clobbered that
sentinel to "right", so previously-undocked devtools would flash detached
and then snap back to the right dock.

Preserve the empty string through SetDockState() so the pref-restore path
runs; still reject any non-empty invalid value to keep the JS-injection
guard from #50646 intact.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-04-08 13:06:40 -07:00
trop[bot]
d37b4f5d9f fix: enforce size constraints on window creation on Windows and Linux (#50753)
fix: enforce size constraints on window creation on Windows and Linux (#49906)

* enforce size constraints on window creation

* set constraints after resizing on init

* restore conditional centering

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Mitchell Cohen <mitch.cohen@me.com>
2026-04-06 18:40:05 -05:00
Samuel Attard
3fa5280fde fix: re-enable MacWebContentsOcclusion with embedder window fix (#50715)
fix: re-enable MacWebContentsOcclusion with embedder window fix (#50579)

* fix: re-enable MacWebContentsOcclusion with embedder window fix

Replace the full revert of Chromium's MacWebContentsOcclusion cleanup
with a targeted patch that handles embedder windows shown after
WebContentsViewCocoa attachment. This lets us drop the feature flag
disable in feature_list.cc and re-enable upstream occlusion tracking.

Adds tests for show/hide event counts on macOS and visibility tracking
across multiple child WebContentsViews.

* test: drop show/hide event count assertion

The assertion that 'show' fires exactly once per w.show() call is not
an API guarantee - macOS can send multiple occlusion state
notifications during a single show() when other windows are on screen
(common on CI after hundreds of prior tests). The
visibilitychange-count test in api-web-contents-view-spec.ts covers
the actual invariant we care about.

* fix: ignore WebContentsOcclusionCheckerMac synthetic notifications in window delegate

On macOS 13.3-25.x, Chromium's occlusion checker enables manual
frame-intersection detection and posts synthetic
NSWindowDidChangeOcclusionStateNotification tagged with its class name
in userInfo. These fire when the checker's NSContainsRect heuristic
decides a window is covered by another window's frame, but the real
-[NSWindow occlusionState] hasn't changed.

Our delegate was treating these the same as real macOS notifications
and emitting show/hide events based on occlusionState, which was
unchanged - resulting in spurious duplicate show events when e.g.
Quick Look opened and its frame intersected the BrowserWindow.
2026-04-06 16:01:41 -04:00
trop[bot]
e1bb3e7165 fix: defer Wrappable destruction in SecondWeakCallback to a posted task (#50694)
V8's second-pass weak callbacks run inside a
DisallowJavascriptExecutionScope: they may touch the V8 API but must
not invoke JS, directly or indirectly. Several Electron Wrappables
(WebContents in particular) emit JS events from their destructors,
so deleting synchronously inside SecondWeakCallback can crash with
"Invoke in DisallowJavascriptExecutionScope" when GC happens to
collect the JS wrapper during a foreground GC task — typically during
shutdown's uv_run drain after a leaked WebContentsView.

This was previously latent and timing-dependent (electron/electron#47420,
electron/electron#45416, podman-desktop/podman-desktop#12409). The
esbuild migration's keepNames option (which wraps every function/class
with an Object.defineProperty call) shifted heap layout enough to make
the spec/fixtures/crash-cases/webcontentsview-create-leak-exit case
reliably reproduce it on every run, giving a clean signal for the fix.

Both WrappableBase and DeprecatedWrappableBase SecondWeakCallback now
post the deletion via base::SequencedTaskRunner::GetCurrentDefault()
so the destructor (and any Emit it does) runs once V8 has left the GC
scope. Falls back to synchronous deletion if no task runner is
available (early/late process lifetime).

Fixes electron/electron#47420.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Sam Attard <sattard@anthropic.com>
2026-04-05 09:49:43 +00:00
trop[bot]
dbc7cbd000 fix: propagate requesting frame through sync permission checks (#50687)
WebContentsPermissionHelper::CheckPermission was hardcoding
GetPrimaryMainFrame() and deriving the requesting origin from
web_contents_->GetLastCommittedURL(), so the setPermissionCheckHandler
callback always received the top frame's origin and
details.isMainFrame/details.requestingUrl always reflected the main
frame, even when a cross-origin subframe with allow="serial" or
allow="camera; microphone" triggered the check.

Thread the requesting RenderFrameHost through CheckPermission,
CheckSerialAccessPermission, and CheckMediaAccessPermission so the
permission manager receives the real requesting frame. Update the
serial delegate and WebContents::CheckMediaAccessPermission callers to
pass the frame they already have.

Adds a regression test that loads a cross-origin iframe with
allow="camera; microphone", calls enumerateDevices() from within the
iframe, and asserts the permission check handler receives the iframe
origin for requestingOrigin, isMainFrame, and requestingUrl.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Sam Attard <sattard@anthropic.com>
2026-04-05 00:32:03 +00:00
trop[bot]
821b738db0 fix: resolve getFileHandle concurrent stalling by queuing callbacks (#50670)
fix: resolve getFileHandle concurrent stalling by queuing callbacks (#50597)

Previously, concurrent calls to FileSystemAccessPermissionContext::ConfirmSensitiveEntryAccess
for the same file path would silently discard the subsequent callbacks because
the internal callback map used a single callback per file path and std::map::try_emplace
would drop the callback if the key already existed. This caused Promises in JS
(e.g., dirHandle.getFileHandle()) to stall indefinitely.

This commit updates the callback map to hold a vector of callbacks, so all
concurrent requesters for the same filepath are grouped together and resolved
once the asynchronous blocklist check completes.

Notes: Fixed an issue where concurrent `getFileHandle` requests on the same path could stall indefinitely.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Kunal Dubey <21157775+xakep8@users.noreply.github.com>
2026-04-04 11:18:30 -05:00
trop[bot]
969741f9f8 fix: validate dock_state_ against allowlist before JS execution (#50666)
fix: validate dock_state_ against allowlist before JS execution

The dock_state_ member was concatenated directly into a JavaScript
string and executed via ExecuteJavaScript() in the DevTools context.

We should validate against the four known dock states and fall back
to "right" for any unrecognized value for safety

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-04-03 15:45:45 -05:00
trop[bot]
476a864388 feat: make Chrome extensions work on custom protocols (#50529)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Niklas Wenzel <dev@nikwen.de>
2026-04-02 20:09:56 -07:00
trop[bot]
81333d7c79 fix: glitchy rendering and maximize behavior with different GTK themes (#50645)
fix: glitchy rendering and maximize behavior with different GTK themes (#50550)

* fix glitchy rendering with different gtk themes especially when maximizing

* use actual insets, not restored insets

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Mitchell Cohen <mitch.cohen@me.com>
2026-04-02 22:42:40 +02:00
trop[bot]
fd56128f46 fix: remove menu update debug log (#50613)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: clavin <clavin@electronjs.org>
2026-04-01 22:52:31 +02:00