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.
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.
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
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>
added in a467d068 but never used.
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
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>
* refactor: replace deprecated API base::GetProcId() in web_frame_main
Co-authored-by: Charles Kerr <charles@charleskerr.com>
* refactor: replace deprecated API base::GetProcId() in web_contents
Co-authored-by: Charles Kerr <charles@charleskerr.com>
* refactor: replace deprecated API base::GetProcId() in a11y ui
Co-authored-by: Charles Kerr <charles@charleskerr.com>
* refactor: frame.osProcessId now returns 0 instead of -1 for invalid processes.
This is consistent with WebContents.getOSProcessId
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>
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>
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>
* chore: do not expose v8Util.getObjectHash() to JS
Not used, documented, or typed. Added in ddad3e4846.
Co-authored-by: Charles Kerr <charles@charleskerr.com>
* chore: do not expose DownloadItem.isDone() to JS
Not used, documented, or typed. Added in dcad25c98c.
Co-authored-by: Charles Kerr <charles@charleskerr.com>
* chore: do not expose BrowserWindow.isWebViewFocused() to JS
Not used, documented, or typed. Added in a949e9542d.
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>
* 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.
Co-authored-by: Bohdan Tkachenko <bohdan@tkachenko.dev>
* 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.
Co-authored-by: Bohdan Tkachenko <bohdan@tkachenko.dev>
---------
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Bohdan Tkachenko <bohdan@tkachenko.dev>
* chore: remove unused undocumented API `menu.worksWhenHiddenAt()`.
Not used, documented, or typed. Added by 544d8a423c.
Co-authored-by: Charles Kerr <charles@charleskerr.com>
* chore: remove unused undocumented API `menu.getCommandIdAt()
Not used, documented, or typed. Added by dae98fa43f.
Co-authored-by: Charles Kerr <charles@charleskerr.com>
* 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.
Co-authored-by: Charles Kerr <charles@charleskerr.com>
* chore: remove unused undocumented API `menu.getLabelAt()`
Not used, documented, or typed. Added by dae98fa43f.
Co-authored-by: Charles Kerr <charles@charleskerr.com>
* chore: remove unused undocumented API `menu.getToolTipAt()`
Not used, documented, or typed. Added by 06d48514c6.
Co-authored-by: Charles Kerr <charles@charleskerr.com>
* chore: remove unused undocumented API `menu.getSubLabelAt()`
Not used, documented, or typed. Added by dae98fa43f.
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>
refactor: remove unused internal method WebContents.equal()
last use removed in Feb 2021 @ 51bb0ad36d
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
* fix: extension service worker not starting beyond first app launch
Co-authored-by: Niklas Wenzel <dev@nikwen.de>
* fix: set preference only for extensions with service workers
Co-authored-by: Niklas Wenzel <dev@nikwen.de>
---------
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Niklas Wenzel <dev@nikwen.de>
refactor: remove unused internal method contents.canGoToIndex()
refactor: make WebContents::CanGoToIndex() private
The JS binding has been unused since 2021-04-27 #288390a1b26b1
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
The `OnTraceBufferUsageAvailable` callback creates V8 handles via
`Dictionary::CreateEmpty()` before `promise.Resolve()` enters its
`SettleScope` (which provides a `HandleScope`). When the callback
fires asynchronously from a Mojo response (i.e. when a trace session
is active), there is no `HandleScope` on the stack, causing a fatal
V8 error: "Cannot create a handle without a HandleScope".
Add an explicit `v8::HandleScope` at the top of the callback, matching
the pattern used by the other contentTracing APIs which resolve their
promises through `SettleScope` or the static `ResolvePromise` helper.
Made-with: Cursor
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Alexey Kozy <alexey@anysphere.co>
* fix: hex-encode Windows notification icon temp filenames
NotificationPresenterWin was using SHA1HashString(origin.spec()) directly
as the basename for the temporary PNG written for toast icons.
SHA1HashString returns raw digest bytes, so the generated filename could
contain invalid path characters on Windows. That caused WriteFile to fail
when saving notification icons, which left toast XML without the expected
icon path.
Hex-encode the digest before appending .png so the temporary filename is
filesystem-safe while keeping deterministic naming for a given origin.
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
* Update shell/browser/notifications/win/notification_presenter_win.cc
Co-authored-by: Robo <hop2deep@gmail.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
---------
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
fix: register PrintDialogLinuxFactory on Linux
Chromium 145 refactored Linux print dialog creation to use a factory
pattern instead of directly calling LinuxUi::CreatePrintDialog().
Chrome registers this factory in
ChromeBrowserMainExtraPartsViewsLinux::ToolkitInitialized(), but
Electron did not, causing PrintingContextLinux::EnsurePrintDialog()
to leave print_dialog_ null on every call.
Without a dialog, UseDefaultSettings() and UpdatePrinterSettings()
return success but with empty/unprocessed settings, causing
PrintMsgPrintParamsIsValid() to fail. This broke both window.print()
(no dialog appears) and webContents.print() (callback stuck until
app close with "Invalid printer settings").
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
GetDefaultPrinterDPI() creates a blank GtkPrintSettings and reads
its resolution, which returns 0 for uninitialized settings. With
DPI=0, SetPrintableAreaIfValid() computes a zero scale factor,
producing empty page dimensions that fail PrintMsgPrintParamsIsValid().
Fall back to kDefaultPdfDpi (72) when GTK returns 0, matching the
existing Windows fallback pattern when CreateDC fails.
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
feat: add nativeTheme.shouldDifferentiateWithoutColor on macOS
Adds nativeTheme.shouldDifferentiateWithoutColor on macOS that maps to
NSWorkspace.accessibilityDisplayShouldDifferentiateWithoutColor. If true,
the user has indicated that they prefer UI that differentiates items with
something other than color alone. This is useful for users with color
vision deficiency.
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Robert Böhnke <robb@robb.is>
* feat: support notification priority on Windows
Add Windows notifications support urgency/priority levels.
This maps the existing `urgency` option (previously Linux-only) to
Windows toast notification priorities:
- 'critical' maps to ToastNotificationPriority_High, which sorts the
notification above default-priority items in Action Center.
- 'normal' and 'low' both map to ToastNotificationPriority_Default.
Note that on Windows, 'critical' priority does not prevent the toast
from being auto-dismissed. Users should additionally set `timeoutType`
to 'never' for that behavior.
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
* chore: make linter happy
Co-authored-by: Charles Kerr <charles@charleskerr.com>
---------
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
- export_gin_v8platform_pageallocator_for_usage_outside_of_the_gin.patch:
gin::V8Platform::GetPageAllocator() is now exported upstream via the
public v8::Platform interface, so we no longer need to patch gin to
expose a custom accessor. Update javascript_environment.cc to use the
upstream API instead.
- fix_getcursorscreenpoint_wrongly_returns_0_0.patch: this fix has
landed upstream in Chromium and is no longer needed as a local patch.
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Sam Attard <sattard@anthropic.com>
* fix: correct utility process exit code on Windows
On Windows, process exit codes are 32-bit unsigned integers (DWORD).
When passed from Chromium to Electron as a signed int and then
implicitly converted to uint64_t, values with the high bit set
(e.g., NTSTATUS codes) undergo sign extension, producing incorrect
values.
Cast the exit code to uint32_t before widening to uint64_t to
prevent sign extension and preserve the original Windows exit code.
Fixes#49455
Co-authored-by: João Silva <joaomrsilva@tecnico.ulisboa.pt>
* fix: narrow HandleTermination and Shutdown to uint32_t, add tests
Co-authored-by: João Silva <joaomrsilva@tecnico.ulisboa.pt>
---------
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: João Silva <joaomrsilva@tecnico.ulisboa.pt>
build: remove macos hittest workaround patch
CL:6574464 changed BridgedContentView::hitTest: to use GetHitTestResult(), which
returns kRootView for any non-null, non-NativeViewHost view — causing
BridgedContentView to absorb all web content mouse events. In BrowserWindow,
content_view_ sits in front of the sibling WebContentsView and covers the full
client area, so it was always found first, breaking all loadURL page interaction.
Fix this by installing a ContentViewTargeterDelegate on content_view_ in
NativeWindowMac::SetContentView that returns nullptr (instead of the view itself)
when no children cover the target point. This makes GetHitTestResult return kOther,
allowing hitTest: to fall through to [super hitTest:] and find
RenderWidgetHostViewCocoa. This also removes the now-unnecessary chromium
partial-revert patch that worked around the same issue.
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Avoids a freeze when failing to enter fullscreen on macOS.
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Beutner <beutner.john@gmail.com>
fix: correctly set IsActive() in BaseWindow on MacOS
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Kyle Cutler <kycutler@microsoft.com>
refactor: replace CHILD_PLUGIN with CHILD_EMBEDDER_FIRST on macOS
Chromium removed upstream support for child plugin processes without
library validation in https://crbug.com/461717105, which we patched
back via feat_restore_macos_child_plugin_process.patch.
Chromium's CHILD_EMBEDDER_FIRST mechanism already provides the right
extensibility point for this: values > CHILD_EMBEDDER_FIRST are reserved
for embedders and resolved via ContentBrowserClient::GetChildProcessSuffix().
Chrome itself uses this pattern for its Alerts helper process.
This commit replaces the Chromium patch with an Electron-native
implementation.
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
* remove painting from linux frame layout
* use chromium csd strategy for frameless windows
* Apply suggestions from code review
Remove unneeded virtual methods
Co-authored-by: Charles Kerr <charles@charleskerr.com>
* removed inline destructors
---------
Co-authored-by: Charles Kerr <charles@charleskerr.com>
* refactor: migrate electron::api::tray to cppgc
* chore: add Tray to wrappable_pointer_tags.h patch
* fixup! refactor: migrate electron::api::tray to cppgc
clear keep_alive_ if error is thrown in constructor
* refactor: make Tray::menu_ a cppgc::Member<Menu>
* fix: prevent traffic light buttons flashing on deminiaturize
When a window with a custom `trafficLightPosition` is minimized and
restored, macOS re-layouts the title bar container during the
deminiaturize animation, causing the traffic light buttons to briefly
appear at their default position before being repositioned.
Fix this by hiding the buttons container in `windowWillMiniaturize` and
restoring them (with a redraw to the correct position) in
`windowDidDeminiaturize`.
* chore: address feedback from review
* fix: continue to run ProxyingURLLoaderFactory for intercepted protocols
* test: webRequest handlers when loading browser windows
* fix: wrap special URL loaders factories with ProxyingURLLoaderFactory
* test: webRequest handlers when using net.fetch
* refactor: remove redundant intercepted protocol handling
AsarURLLoaderFactory is now intercepted by ProxyingURLLoaderFactory, which already handles when the file:// scheme is intercepted.
* fix: check before using saved headers in OnReceiveResponse
* fix: run webRequest handlers when loading file service workers
* test: handlers when loading file service workers
* refactor: add shared CreateURLLoaderFactoryBuilder method
---------
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
* Feat: support getDevToolsId() on WebContents
* Rename to `getOrCreateDevToolsTargetId`
* build: use spawn instead of spawnSync for build (#49774)
* Fix build
* formatting
---------
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
fix: validate protocol scheme names in setAsDefaultProtocolClient
On Windows, `app.setAsDefaultProtocolClient(protocol)` directly
concatenates the protocol string into the registry key path with no
validation. A protocol name containing `\` could write to an arbitrary
subkey under `HKCU\Software\Classes\`, potentially hijacking existing
protocol handlers.
To fix this, add `Browser::IsValidProtocolScheme()` which validates that a protocol
name conforms to the RFC 3986 scheme grammar:
scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
This rejects backslashes, forward slashes, whitespace, and any other
characters not permitted in URI schemes.
* fix: use requesting frame origin instead of top-level URL for permissions
`WebContentsPermissionHelper::RequestPermission` passes
`web_contents_->GetLastCommittedURL()` as the origin to the permission
manager instead of the actual requesting frame's origin. This enables
origin confusion when granting permissions to embedded third-party iframes,
since app permission handlers see the top-level origin instead of the
iframe's. The same pattern exists in the HID, USB, and Serial device
choosers, where grants are keyed to the primary main frame's origin rather
than the requesting frame's.
Fix this by using `requesting_frame->GetLastCommittedOrigin()` in all
affected code paths, renaming `details.requestingUrl` to
`details.requestingOrigin`, and populating it with the serialized
origin only.
* chore: keep requestingUrl name in permission handler details
The previous commit changed the details.requestingUrl field to
details.requestingOrigin in permission request/check handlers. That
field was already populated from the requesting frame's RFH, so the
rename was unnecessary and would break apps that read the existing
property. Revert to requestingUrl to preserve the existing API shape.
The functional changes to use the requesting frame in
WebContentsPermissionHelper and the HID/USB/Serial choosers remain.
---------
Co-authored-by: Samuel Attard <sattard@anthropic.com>
Previously the renderer checked a process-wide command-line switch to
decide whether to create a Node.js environment for dedicated workers.
When a renderer process hosted multiple WebContents with different
nodeIntegrationInWorker values (e.g. via window.open with overridden
webPreferences in setWindowOpenHandler), all workers in the process
used whichever value the first WebContents set on the command line.
Instead, plumb the flag through blink's WorkerSettings at worker
creation time, copying it from the initiating frame's WebPreferences.
The check on the worker thread then reads the per-worker value. Nested
workers inherit the flag from their parent worker via
WorkerSettings::Copy.
The --node-integration-in-worker command-line switch is removed as it
is no longer consumed.