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.
* 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>
---------
Co-authored-by: Charles Kerr <charles@charleskerr.com>
chore: address blink gc plugin errors
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
* feat: allow to set id and groupId
* feat: use Id's without hash but check length
* feat: adds visual grouping via groupTitle
* test: tests added for id, groupId and groupTitle
* fix: unused vars on Mac and Linux
* fix: remove redundant parameter
* fix: add doc links for id and group
* fix: throw if groupId is missing
* fix: test
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
* 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
* chore: remove window enlargement revert patch
Chromium removed the `window_enlargement_` system from
DesktopWindowTreeHostWin (1771dbae), which was a workaround for an AMD
driver bug from 2013 (crbug.com/286609) where translucent HWNDs smaller
than 64x64 caused graphical glitches. Chromium confirmed this is no
longer needed and shipped the removal.
This removes the revert patch and all Electron-side code that depended
on the `kEnableTransparentHwndEnlargement` feature flag, including the
`GetExpandedWindowSize` helper and max size constraint expansion in
`NativeWindow::GetContentMaximumSize`.
* test: remove obsolete <64x64 transparent window test
The test was added in 2018 (#12904) to verify the AMD driver
workaround that artificially enlarged translucent HWNDs smaller than
64x64 (crbug.com/286609). The workaround set the real HWND to 64x64
and subtracted a stored window_enlargement_ from every client/window
bounds query, so getContentSize() reported the originally-requested
size even though the actual HWND was larger.
With both the Chromium window_enlargement_ system and Electron's
GetExpandedWindowSize gone, setContentSize on a transparent
thickFrame window calls SetWindowPos directly. WS_THICKFRAME windows
are subject to DefWindowProc's MINMAXINFO.ptMinTrackSize clamp on
programmatic resizes (Chromium's OnGetMinMaxInfo ends with
SetMsgHandled(FALSE), so DefWindowProc overwrites the zeroed
min-track with system defaults), which on Windows Server 2025
floors at 32x39 — hence the failing [32, 39] vs [30, 30].
The removed feature_list.cc comment explicitly flagged this test as
the blocker for retiring kEnableTransparentHwndEnlargement, so
delete it alongside the workaround it was validating.
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.
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.
* chore: iwyu in shell/browser/api/electron_api_web_contents.h
* chore: iwyu in shell/browser/browser.h
* chore: iwyu in shell/browser/javascript_environment.h
* chore: iwyu in shell/common/gin_hhelper/function_template.h
* chore: do not include node_includes.h if we are not using it
* chore: fix transitive include
chore: remove unused FileSystemAccessPermissionContext::Access enum class
chore: remove unused FileSystemAccessPermissionContext::RequestType enum class
declared in 344aba08 but never used
Adds the ability to temporarily suspend and resume global shortcut
handling via `globalShortcut.setSuspended()` and query the current
state via `globalShortcut.isSuspended()`. When suspended, registered
shortcuts stop listening and new registrations are rejected. When
resumed, previously registered shortcuts are automatically restored.
* chore: do not expose menu.isItemCheckedAt() to JS
Not used, documented, or typed. Added in dae98fa43f.
* chore: do not expose menu.isEnabledAt() to JS
Nto used, documented, or typed. Added in dae98fa43f.
* chore: do not expose menu.isVisibleAt() to JS
Not used, documented, or typed. Added in dae98fa43f.
* chore: remove unused undocumented API `getOjectHash`
Not used, documented, or typed. Added in ddad3e4846.
Appears to never have been used.
* chore: bump chromium in DEPS to 148.0.7765.0
* chore: bump chromium in DEPS to 148.0.7766.0
* fix(patch-conflict): update packed_resources dep name after upstream rename
Upstream renamed //chrome:packed_resources_integrity_header to
//chrome:packed_resources. Updated the patch to guard the new dependency
name with !is_electron_build while preserving the same intent.
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7714543
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(patch-conflict): update code_cache_host_impl.cc for upstream includes and TODO
Upstream added #include <stdint.h> and a TODO comment in
code_cache_host_impl.cc which conflicted with the Electron code cache
custom schemes patch. Resolved by keeping both upstream additions and
the Electron ProcessLockURLIsCodeCacheScheme function.
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7615151
Co-Authored-By: Claude <noreply@anthropic.com>
* chore: update patch hunk headers
Co-Authored-By: Claude <noreply@anthropic.com>
* 7700837: update RecordContentToVisibleTimeRequest from mojom to native struct
Upstream typemapped RecordContentToVisibleTimeRequest from a Mojo
struct to a native C++ struct. Updated OSR virtual method signatures
from blink::mojom::RecordContentToVisibleTimeRequestPtr to
std::optional<blink::RecordContentToVisibleTimeRequest> and
blink::RecordContentToVisibleTimeRequest to match.
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7700837
Co-Authored-By: Claude <noreply@anthropic.com>
* 7714579: update WebString::FromASCII to FromUTF8
Upstream renamed blink::WebString::FromASCII to FromAscii. Updated
Electron's usage to FromUTF8 which is equivalent for ASCII scheme
strings and avoids a dependency on the renamed method. Also fixed
blink::String::FromUTF8 to use the String constructor directly.
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7714579
Co-Authored-By: Claude <noreply@anthropic.com>
* 7696480: add stream_info dep after StreamInfo extraction
Upstream extracted extensions::StreamInfo from PdfViewerStreamManager
to a standalone class in extensions/browser/mime_handler/stream_info.h.
Added the new target as a dependency since Electron's streams_private
and pdf_viewer_private APIs use PdfViewerStreamManager which now
depends on the separate StreamInfo target.
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7696480
Co-Authored-By: Claude <noreply@anthropic.com>
* chore: bump chromium in DEPS to 148.0.7768.0
* fix(patch-conflict): update PiP patch for new toggle_mute_button in overlay window
Upstream added a toggle_mute_button to the live caption dialog controls
in VideoOverlayWindowViews::SetLiveCaptionDialogVisibility. Extended the
existing #if 0 guard to include the new button handling since Electron
disables live caption dialog functionality.
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7682308
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(patch-conflict): update packed_resource_integrity patch after upstream dep removal
Upstream removed the deps += [ "//chrome:packed_resources" ] line from
the if (!is_win) block in chrome/browser/BUILD.gn. The Electron patch
no longer needs to guard this dep with !is_electron_build in this
location since the dep was already relocated by an earlier upstream CL.
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7714543
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(patch-conflict): update WebSocket throttling revert for DisconnectWebSocketOnBFCache guard
Upstream added a DisconnectWebSocketOnBFCacheEnabled() runtime feature
check that wraps the WebSocket BFCache feature registration. Updated the
Electron revert patch to place the kAllowAggressiveThrottlingWithWebSocket
ternary inside the new conditional guard.
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7698838
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(patch-conflict): update SCContentSharingPicker patch for upstream native picker refactor
Upstream added is_native_picker and filter_ based native picker session
validation to ScreenCaptureKitDeviceMac. Electron's patch uses its own
native picker approach (active_streams_ counter + direct SCContentSharingPicker
API), so marked the new upstream parameters as [[maybe_unused]] and kept
Electron's implementation.
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7713560
Co-Authored-By: Claude <noreply@anthropic.com>
* chore: update patch hunk headers
Co-Authored-By: Claude <noreply@anthropic.com>
* 7708800: update StartDragging signature to use RenderFrameHost
Upstream refactored StartDragging to take a RenderFrameHost& instead of
separate source_origin and source_rwh parameters. Updated
OffScreenWebContentsView to match the new signature and derive the
RenderWidgetHostImpl from the RenderFrameHost internally.
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7708800
Co-Authored-By: Claude <noreply@anthropic.com>
* 7682308: add toggle_mute_button to chromium_src build sources
Upstream added a ToggleMuteButton to the PiP overlay window controls.
Added the new toggle_mute_button.cc/h source files to Electron's
chromium_src/BUILD.gn to resolve linker errors.
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7682308
Co-Authored-By: Claude <noreply@anthropic.com>
* chore: update patches after main rebase
* fixup! 7708800: update StartDragging signature to use RenderFrameHost
fix linting
* 7705541: [trap-handler] Track individual Wasm memories | https://chromium-review.googlesource.com/c/v8/v8/+/7705541
Moved the SetUpWebAssemblyTrapHandler() call to before the V8 isolate is created
* fixup! fix utility process tests
---------
Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
This removes two `raw_ptr<context::StoragePartition>` instances.
These pointers were used to build a ServiceWorkerMain* lookup key.
The key was built from [version_id, raw_ptr<StoragePartition>].
Unfortunately these keys could be dangling on shutdown.
This PR now uses stable, immutable fields for building the key:
[version_id, BrowserContext::UniqueId(), context::StoragePartitionConfig].
context::StoragePartitionConfig is a unique lookup key for StoragePartition
within a BrowserContext.
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.
* refactor: replace deprecated API base::GetProcId() in web_frame_main
* refactor: replace deprecated API base::GetProcId() in web_contents
* refactor: replace deprecated API base::GetProcId() in a11y ui
* refactor: frame.osProcessId now returns 0 instead of -1 for invalid processes.
This is consistent with WebContents.getOSProcessId
* chore: do not expose v8Util.getObjectHash() to JS
Not used, documented, or typed. Added in ddad3e4846.
* chore: do not expose DownloadItem.isDone() to JS
Not used, documented, or typed. Added in dcad25c98c.
* chore: do not expose BrowserWindow.isWebViewFocused() to JS
Not used, documented, or typed. Added in a949e9542d.
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.
* feat: forward activation token from libnotify notification clicks
When a notification action is clicked on Linux, retrieve the activation
token from libnotify (if available) via dlsym and set it using
`base::nix::SetActivationToken()`. This enables proper window focus
handling under Wayland, where the compositor requires a valid activation
token to grant focus to the application.
The `notify_notification_get_activation_token` symbol is resolved at
runtime to maintain compatibility with older libnotify versions that
do not expose this API.
* refactor: simplify libnotify soname loading and activation token lookup
Replace the chained Load() calls with a loop over a constexpr array of
sonames, and inline the lazy EnsureActivationTokenFunc() into
Initialize() since it is only called once and the library handle is
already known at that point.
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
* chore: remove unused undocumented API `menu.worksWhenHiddenAt()`.
Not used, documented, or typed. Added by 544d8a423c.
* chore: remove unused undocumented API `menu.getCommandIdAt()
Not used, documented, or typed. Added by dae98fa43f.
* chore: do not expose `menu.getIndexOfCommandId()` to JS
Added by dae98fa43f but not documented, typed, or used by JS code.
The C++ method is used by other shell code, but not in JS.
* chore: remove unused undocumented API `menu.getLabelAt()`
Not used, documented, or typed. Added by dae98fa43f.
* chore: remove unused undocumented API `menu.getToolTipAt()`
Not used, documented, or typed. Added by 06d48514c6.
* chore: remove unused undocumented API `menu.getSubLabelAt()`
Not used, documented, or typed. Added by dae98fa43f.
refactor: remove unused internal method contents.canGoToIndex()
refactor: make WebContents::CanGoToIndex() private
The JS binding has been unused since 2021-04-27 #288390a1b26b1