Compare commits

...

103 Commits

Author SHA1 Message Date
trop[bot]
e094b3939e fix: user resizable transparent windows on win32 (#50301)
test: revert win32 frameless and transparent resizable expectations

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Justin Mayfield <tooker@gmail.com>
2026-03-17 09:46:36 +01:00
trop[bot]
339d44c723 fix: add ASAR support to additional copy methods (#50287)
* fix: add ASAR support for additional copy methods

Co-authored-by: Noah Gregory <noahmgregory@gmail.com>

* test: add tests for ASAR support for additional copy messages

Co-authored-by: Noah Gregory <noahmgregory@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Noah Gregory <noahmgregory@gmail.com>
2026-03-16 16:23:38 -04:00
trop[bot]
ee2d3db030 test: fix esm issue in node-spec-runner (#50294)
Chromium added a top-level package.json in CL:7485999 that sets
the type to module and breaks commonjs tests run via
node-spec-runner.js. This commit temporarily changes the type to
commonjs while running the tests, then changes it back to module when done.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-03-16 21:13:30 +01:00
trop[bot]
139e238d07 build: remove redundant bits of ncrypto node patch (#50280)
build: remove redundant ncrypto node patch

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-03-16 16:03:26 +01:00
trop[bot]
a1550f5102 fix: prefer browser runtime over node in DevTools HostRuntime detection (#50275)
Upstream DevTools' HostRuntime checks `IS_NODE` before `IS_BROWSER` when
selecting the platform runtime. In Electron, `process` is available in
renderer processes, so `IS_NODE` evaluates to `true` in the DevTools
context. This causes DevTools to dynamically import the Node.js platform
runtime, which uses `node:worker_threads`. DevTools Web Workers running
under the `devtools://` protocol cannot load Node.js built-in modules,
so the import fails and breaks features like the formatter worker.

Fix by swapping the check order to prefer `IS_BROWSER` when both are
true. This is safe because in pure Node.js environments (the only case
where the node runtime is needed), `window` and `self` are both
undefined, so `IS_BROWSER` is always `false` regardless of check order.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-03-16 12:57:53 +01:00
trop[bot]
3dd04c2725 ci: update actions/cache to 5.0.3 (#50236)
chore: update actions/cache to 5.0.3

Needed due to https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
2026-03-13 10:04:57 +01:00
Keeley Hammond
d32b8a64d0 chore: cherry-pick 7911bee5d90e from skia (#50229)
* chore: cherry-pick 7911bee5d90e from skia

* chore: update patch
2026-03-13 02:48:07 +00:00
Keeley Hammond
425fe98c14 chore: cherry-pick d5b0cb2acffe from v8 (#50231)
* chore: cherry-pick d5b0cb2acffe from v8

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2026-03-13 01:48:31 +00:00
Kanishk Ranjan
6b4b7df937 chore: backport running mac app icons from chromium (crrev.com/c/7239386) (#50188)
chore: backport running mac app icons from chromium
2026-03-12 15:15:46 +01:00
John Kleinschmidt
cc81658f40 ci: add timeout to test step (#50211)
ci: add timeout to test step (#50186)

Additionally, take a screenshot on timeout so that we can debug why there is a hang
2026-03-12 14:40:24 +01:00
trop[bot]
9be5389e77 fix: preserve staged update dir when pruning orphaned updates on macOS (#50216)
* fix: preserve staged update dir when pruning orphaned update dirs on macOS

The previous squirrel.mac patch cleaned up all staged update directories
before starting a new download. This kept disk usage bounded but broke
quitAndInstall() if called while a subsequent checkForUpdates() was in
flight — the already-staged bundle would be deleted out from under it.

This reworks the patch to read ShipItState.plist and preserve the
directory it references, deleting only truly orphaned update.XXXXXXX
directories. Disk footprint stays bounded (at most 2 dirs: staged +
in-progress) and quitAndInstall() remains safe mid-check.

Also adds test coverage for the quitAndInstall/checkForUpdates race and
a triple-stack scenario where 3 updates arrive without a restart.

Refs https://github.com/electron/electron/issues/50200

Co-authored-by: Samuel Attard <sattard@anthropic.com>

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <sattard@anthropic.com>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
2026-03-12 01:57:22 +00:00
trop[bot]
8264495aff fix: prevent traffic light buttons flashing on deminiaturize (#50207)
* 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`.

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

* chore: address feedback from review

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>
2026-03-11 15:36:30 -04:00
trop[bot]
ed9ec1a535 fix: don't call TaskDialogIndirect with disabled parent windows (#50189)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Noah Gregory <noahmgregory@gmail.com>
2026-03-10 18:06:15 -07:00
Keeley Hammond
b8362fe96f chore: cherry-pick 12f932985275 from chromium (#50173)
* chore: cherry-pick 12f932985275 from chromium

* chore: update patches
2026-03-10 10:11:13 +01:00
Samuel Attard
4480c3545d fix: correct parsing of second-instance additionalData (#50162)
- POSIX: validate StringToSizeT result and token count when splitting
  the socket message into argv and additionalData; previously a
  malformed message could produce incorrect slicing.
- Windows: base64-encode additionalData before embedding in the
  null-delimited wchar_t buffer. The prior reinterpret_cast approach
  dropped everything after the first aligned 0x0000 in the serialized
  payload, so complex objects could arrive truncated.

Manually backported from #50119
2026-03-10 09:42:27 +01:00
trop[bot]
de5d94bc49 fix: validate protocol scheme names in setAsDefaultProtocolClient (#50158)
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.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-03-10 00:04:27 -05:00
trop[bot]
4fe62718b9 fix: use requesting frame origin in permission helper and device choosers (#50149)
* 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.

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

* 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>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: Samuel Attard <sattard@anthropic.com>
2026-03-09 23:03:45 -05:00
Keeley Hammond
1c9e1cd141 chore: cherry-pick a08731cf6d70 from angle (#50168) 2026-03-09 19:15:10 -07:00
trop[bot]
04e39e24e6 refactor: use WHATWG URL instead of url.parse (#50142)
refactor: use WHATWG URL instead of url.parse

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-03-09 17:36:12 -04:00
trop[bot]
e0c8b9b168 fix: InspectorFrontendHost override in embedded windows (#50138)
fix: InspectorFrontendHost override in embedded windows

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-03-09 11:26:55 -04:00
trop[bot]
77f3f5f2b2 fix: screen.getCursorScreenPoint() crash on Wayland (#50104)
* docs: document that getCursorScreenPoint() needs a Window on Wayland

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

* feat: add IsWayland() helper

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

* fix: Wayland crash in GetCursorScreenPoint()

fix: support Screen::GetCursorScreenPoint() on X11

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-03-09 12:33:49 +01:00
trop[bot]
a349e616d4 fix: strictly validate sender for internal IPC reply channels (#50125)
The sender-mismatch check in invokeInWebContents and invokeInWebFrameMain
used a negative condition (`type === 'frame' && sender !== expected`),
which only rejected mismatched frame senders and accepted anything else.

Invert to a positive check so only the exact expected frame can resolve
the reply — matches the guard style used elsewhere in lib/browser/.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <sattard@anthropic.com>
2026-03-09 11:36:47 +01:00
trop[bot]
8c1b38d443 build: pin diff.renames for deterministic patch export (#50127)
git format-patch honors diff.renames, which defaults to 'true' (rename
detection only). If a user has diff.renames=copies configured at the
system or global level, exported patches may encode new files as copies
of similar existing files, causing spurious diffs against patches
exported on other machines. Pin diff.renames=true to match git's
default.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <sattard@anthropic.com>
2026-03-09 11:36:45 +01:00
trop[bot]
06278ba3b3 fix: validate response header names and values before AddHeader (#50131)
Matches the existing validation applied to request headers in
electron_api_url_loader.cc.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <sattard@anthropic.com>
2026-03-09 11:36:34 +01:00
trop[bot]
15b95fcd52 fix: Revert "updated Alt detection to explicitly exclude AltGraph/AltGr (#49778)" (#50110)
Revert "fix: updated Alt detection to explicitly exclude AltGraph/AltGr (#49778)"

This reverts commit 90c9de70ac.

Ref: https://github.com/electron/electron/issues/50050

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: clavin <clavin@electronjs.org>
2026-03-06 21:05:45 -08:00
trop[bot]
d574f99c9e docs: cleanup desktop-capturer doc after chromium audio capture additions (#50113)
* docs: cleanup desktop-capturer doc after chromium audio capture additions

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

* Apply suggestions from code review

Co-authored-by: Erick Zhao <erick@hotmail.ca>

Co-authored-by: Michaela Laurencin <35157522+mlaurencin@users.noreply.github.com>

* disable linter for list in note

Co-authored-by: Michaela Laurencin <35157522+mlaurencin@users.noreply.github.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Michaela Laurencin <mlaurencin@electronjs.org>
Co-authored-by: Michaela Laurencin <35157522+mlaurencin@users.noreply.github.com>
2026-03-06 16:06:03 -05:00
trop[bot]
cbc6959269 docs: remove release schedule in favor of https://releases.electronjs.org/schedule (#50107)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
2026-03-06 15:47:54 -05:00
trop[bot]
f4c7a3ff66 fix: prevent use-after-free in PowerMonitor via dangling OS callbacks (#50088)
PowerMonitor registered OS-level callbacks (HWND UserData and
WTS/suspend notifications on Windows, shutdown handler and lock-screen
observer on macOS) but never cleaned them up in its destructor. The JS
layer also only held the native object in a closure-local variable,
allowing GC to reclaim it while those registrations still referenced
freed memory.

Retain the native PowerMonitor at module level in power-monitor.ts so
it cannot be garbage-collected. Add DestroyPlatformSpecificMonitors()
to properly tear down OS registrations on destruction: on Windows,
unregister WTS and suspend notifications, clear GWLP_USERDATA, and
destroy the HWND; on macOS, remove the emitter from the global
MacLockMonitor and reset the Browser shutdown handler.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-03-05 17:21:22 -05:00
trop[bot]
66ce2439cc fix: avoid redundant page-favicon-updated events on setBounds (#50084)
* fix: avoid duplicate calls in electron_api_web_contents

Co-authored-by: ANANYA542 <ananyashrma6512@gmail.com>

* Style: fix lint errors

Co-authored-by: ANANYA542 <ananyashrma6512@gmail.com>

* fix: prevent duplicate page-favicon-updated events and add regression test

Co-authored-by: Ananya542 <ananyashrma6512@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: ANANYA542 <ananyashrma6512@gmail.com>
2026-03-05 12:47:58 -05:00
trop[bot]
de61f6c5e8 feat: show toast dismissal reason on Windows (#50030)
* feat: show toast dismissal reason on Windows

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

* Update docs/api/notification.md

Co-authored-by: David Sanders <dsanders11@ucsbalum.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>
2026-03-05 11:29:21 +01:00
electron-roller[bot]
90f85f2bf4 chore: bump chromium to 144.0.7559.236 (40-x-y) (#50060)
* chore: bump chromium in DEPS to 144.0.7559.236

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
2026-03-05 10:30:45 +01:00
trop[bot]
60951cdca9 fix: use proper quoting for exe paths and args on Windows (#50075)
Previously, GetProtocolLaunchPath and FormatCommandLineString in
browser_win.cc used naive quoting which could break when paths or
arguments contained backslashes, spaces, or embedded quotes.

Fix by extracting the CommandLineToArgvW-compatible quoting logic from
relauncher_win.cc into a shared utility and use it in both browser_win.cc
and relauncher_win.cc to properly quote the exe path and each argument
individually.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-03-05 10:27:40 +01:00
trop[bot]
a3022df30f build: fix code-signing for MacOS x64 tests (#50072)
* fix: code-sign binaries for notification tests

Co-authored-by: Keeley Hammond <khammond@slack-corp.com>

* test: remove redundent feedURL test

Co-authored-by: Keeley Hammond <khammond@slack-corp.com>

* test: move squirrel feed tests to api-autoupdater

Co-authored-by: Keeley Hammond <khammond@slack-corp.com>

* fix: fix SQRLShipItRequest.JSONKeyPathsByPropertyKey mappings

Co-authored-by: Keeley Hammond <khammond@slack-corp.com>

* Revert "fix: fix SQRLShipItRequest.JSONKeyPathsByPropertyKey mappings"

This reverts commit 5ad9892a67.

Co-authored-by: Keeley Hammond <khammond@slack-corp.com>

* test: unsign tests requiring no signed app

Co-authored-by: Keeley Hammond <khammond@slack-corp.com>

* fixup! fix: fix SQRLShipItRequest.JSONKeyPathsByPropertyKey mappings

chore: fix patch shear

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2026-03-05 10:27:29 +01:00
trop[bot]
996fbfd6bc chore: remove applescript from trash (#50065)
Previously, when trashItemAtURL: failed (e.g. on network shares or
under app translocation), the code fell back to constructing an
AppleScript that interpolated the bundle path directly into a string
literal via %@ with no escaping. This was fragile and unnecessary —
trashItemAtURL: has been the standard API since 10.8 and covers the
relevant cases. The fix simply removes the AppleScript fallback
entirely, so Trash() now returns the result of trashItemAtURL: directly.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-03-04 16:14:15 +01:00
trop[bot]
79d1e32281 fix: uaf in non-client hittest during view teardown (#50053)
* fix: uaf in non-client hittest during view teardown

Co-authored-by: deepak1556 <hop2deep@gmail.com>

* chore: update crash spec

Co-authored-by: deepak1556 <hop2deep@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2026-03-03 14:16:05 -05:00
trop[bot]
1598b9116d fix: validate USB device selection against filtered device list (#50048)
Previously, UsbChooserController::OnDeviceChosen looked up the chosen
device_id via chooser_context_->GetDeviceInfo(), which searches all
known USB devices on the system rather than the filtered list shown to
the select-usb-device handler. This meant a device excluded by the
renderer's filters or exclusion_filters could still be granted
permission if the handler returned its GUID.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-03-03 09:08:03 -05:00
trop[bot]
68cd11118d fix: use setter's creation context when proxying setter in OverrideGlobalPropertyFromIsolatedWorld (#50018)
The setter branch was deriving source_context from getter-> instead of
setter->. Currently latent since the only call site passes both from
the same preload context, but this would crash or mis-resolve if a
future call site passed a setter without a getter or from a different
context.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <sattard@anthropic.com>
2026-03-03 10:45:57 +01:00
trop[bot]
1e2d5902a5 fix: bind offscreen paint callback to child WebContents (#50024)
fix: bind offscreen paint callback to child WebContents

Previously, MaybeOverrideCreateParamsForNewWindow bound the
OffScreenWebContentsView's paint callback to the parent WebContents
using base::Unretained(this). This was both unsafe (dangling pointer
risk if the parent is destroyed before the child) and semantically
incorrect — paint events belong to the child window, not the opener.

Replace the callback in MaybeOverrideCreateParamsForNewWindow with
base::DoNothing(), then rebind it to the child WebContents in
AddNewContents via a new SetCallback method on OffScreenWebContentsView.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-03-03 10:43:08 +01:00
trop[bot]
1bbe8c9610 fix: use destination context when wrapping VideoFrame in contextBridge (#50022)
Enter the destination context scope before creating the VideoFrame V8
wrapper, matching the sibling Element and Blob branches. Without this,
ScriptState::ForCurrentRealm resolved to the calling context instead of
the target context, producing an incorrect wrapper.

Also switch to ScriptState::From with an explicit context argument to
make the intent clearer.

Adds spec coverage for VideoFrame crossing the bridge in both
directions and adds VideoFrame to the existing prototype checks.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <sattard@anthropic.com>
2026-03-02 23:30:16 -08:00
trop[bot]
4bfc2a83fc chore: remove unused commandLineSwitches flag (#50012)
chore: remove unused commandLineSwitches flag

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-03-02 20:48:33 -08:00
trop[bot]
d80adf4aed fix: prevent use-after-free in permission request callbacks (#50036)
EnterFullscreenModeForTab, RequestPointerLock, and RequestKeyboardLock
bind callbacks with base::Unretained(this); fullscreen also captures a
raw RenderFrameHost*. These callbacks may be invoked by the app's JS
permission handler after the WebContents or RenderFrameHost is destroyed.

Use GetWeakPtr() in all three call sites, and capture a
GlobalRenderFrameHostToken instead of the raw RenderFrameHost* for
fullscreen so the pointer is resolved and null-checked only when the
callback fires. Cancel in-flight permission requests from ~WebContents()
via a new ElectronPermissionManager::CancelPendingRequests()` so stale
callbacks are never handed back to JS.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-03-02 20:44:50 -08:00
trop[bot]
b39f8e3e1c fix: deliver Universal Links when NSUserActivity.userInfo is nil (#50005)
* fix(mac): deliver Universal Links when NSUserActivity.userInfo is nil

Co-authored-by: Dante Issaias <dante@issaias.com>

* chore: format

Co-authored-by: Dante Issaias <dante@issaias.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Dante Issaias <dante@issaias.com>
2026-03-02 19:12:08 -05:00
trop[bot]
9c3f76f617 build: authenticate curl requests to googlesource in lint workflow (#50027)
fix: authenticate curl requests to googlesource in lint workflow

The "Download GN Binary" and "Download clang-format Binary" steps
fetch files from chromium.googlesource.com without passing
authentication cookies. When googlesource rate-limits or returns a
transient error (502), the HTML error page is piped into `base64 -d`,
causing `base64: invalid input`.

The `set-chromium-cookie` action already configures `~/.gitcookies`
in a prior step. Pass `-b ~/.gitcookies` to both `curl` calls so
they authenticate, matching what the cookie verification step itself
does.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-03-02 18:38:48 -05:00
trop[bot]
3925b82a07 fix: potential UAF in OnDownloadPathGenerated (#50011)
fix: potential UAF in OnDownloadPathGenerated

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-03-02 18:35:40 -05:00
trop[bot]
e2b4cbfff3 fix: delete temporary blink* globals after restoring Blink implementations (#49999)
ElectronRendererClient::DidCreateScriptContext (and the worker
equivalent) save Blink's fetch/Response/FormData/Request/Headers/
EventSource as temporary globalThis.blink* properties before Node
initialization may overwrite them. node/init.ts and worker/init.ts
restore the originals but previously never deleted the temporary
blink* globals.

They persisted as non-standard global pollution visible to page
content when contextIsolation is disabled -- a minor fingerprinting
signal and a bypass for any preload that wraps window.fetch (page
could call blinkfetch() instead).

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <sattard@anthropic.com>
2026-03-02 13:13:11 -05:00
trop[bot]
29216464dc fix: update label/sublabel/icon in MenuItems on open (#49973)
fix: update label/sublabel/icon in macOS item on open

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-03-02 11:37:53 -05:00
trop[bot]
649c19c877 fix: menu bar hiding on two setFullscreen(false) (#49994)
* test: add failing test for `setFullscreen(false)`

`setFullscreen(false)` should do nothing
when not already in fullscreen, but it hides the menu bar
on Linux.

Co-authored-by: WofWca <wofwca@protonmail.com>

* fix: menu bar hiding on two setFullScreen(false)

This fixes the following bug on Linux (and maybe macOS):
1. Create a window with a menu bar.
2. Call `win.setFullScreen(false)`.

The menu bar will hide.

See the original bug in our project:
https://github.com/deltachat/deltachat-desktop/issues/4752.

Co-authored-by: WofWca <wofwca@protonmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: WofWca <wofwca@protonmail.com>
2026-03-02 16:01:22 +01:00
electron-roller[bot]
603bcb73e3 chore: bump node to v24.14.0 (40-x-y) (#49939)
* chore: bump node in DEPS to v24.14.0

* lib: prefer call() over apply() if argument list is not array

https://github.com/nodejs/node/pull/60796

* build,deps: replace cjs-module-lexer with merve

https://github.com/nodejs/node/pull/61456

* test: use fixture directories for sea tests

https://github.com/nodejs/node/pull/61167

* src: throw RangeError on failed ArrayBuffer BackingStore allocation

* chore: fixup patch indices

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-03-02 14:37:11 +01:00
trop[bot]
488af02eaa fix: menu close event missing after opening a submenu (#49963)
* fix: menu close event missing after opening a submenu

Co-authored-by: Jarek Radosz <jarek@cvx.dev>

* add a unit-like test

Co-authored-by: Jarek Radosz <jarek@cvx.dev>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jarek Radosz <jarek@cvx.dev>
2026-02-26 17:29:31 -05:00
reito
589e08af80 fix: offscreen rendering with correct screen info. (#49681)
* fix: osr use correct screen info.

* fix: 40-x-y types

* Update breaking changes documentation

Removed details about planned breaking API changes for versions 41.0 and 42.0.
2026-02-26 11:08:34 -05:00
trop[bot]
06521fad4c build: exit upload with error code if github upload fails (#49945)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
2026-02-25 23:58:28 -08:00
trop[bot]
771cbce43b fix: potential std::stoi crash in Windows Toasts (#49952)
fix: potential std::stoi crash in Windows Toasts

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-02-25 23:58:04 -08:00
Samuel Attard
b5cfc5dd91 fix: implement keychain item deletion in MAS safeStorage migration (#49817)
The MAS safeStorage patch had three bugs:

1. `AddRandomPasswordToKeychain` was called with the unsuffixed account
   name, so first launches always created the wrong keychain entry,
   triggering an unnecessary migration on the next launch.

2. `FindGenericPassword` never populated the `SecKeychainItemRef` output
   parameter — the SecItem API doesn't return that deprecated type.

3. `ItemDelete` was a no-op stub that always returned `noErr` without
   actually deleting anything.

Fixes all three by using `suffixed_account_name` for new entries,
removing the unused `SecKeychainItemRef` parameter, and implementing
`ItemDelete` with `SecItemDelete` using the modern SecItem API.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 22:19:56 -08:00
trop[bot]
d6e6fcea86 feat: add support for --experimental-transform-types (#49883)
* feat: add support for `--experimental-transform-types`

Co-authored-by: Niklas Wenzel <dev@nikwen.de>

* chore: add tests

Co-authored-by: Niklas Wenzel <dev@nikwen.de>

* docs: add `--experimental-transform-types` to docs

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>
2026-02-25 12:54:38 -05:00
trop[bot]
cc64a5e8d9 fix: crash after win.showAllTabs() new tab (#49934)
fix: crash after win.showAllTabs new tab

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-02-25 08:39:27 -05:00
electron-roller[bot]
2d12f059b4 chore: bump chromium to 144.0.7559.225 (40-x-y) (#49928)
chore: bump chromium in DEPS to 144.0.7559.225

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
2026-02-24 11:20:35 -05:00
trop[bot]
f715930d49 docs: fix some string enum typings (#49931)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2026-02-24 11:19:28 -05:00
trop[bot]
477fe8566e ci: fix checking latest release for website docs update (#49921)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2026-02-23 18:09:51 -08:00
trop[bot]
a9837ed476 fix: updated Alt detection to explicitly exclude AltGraph/AltGr (#49915)
fix: updated Alt detection to explicitly exclude AltGraph/AltGr (#49778)

Updated Alt detection to explicitly exclude AltGraph/AltGr

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shashwat Raj <65155843+darthvader58@users.noreply.github.com>
2026-02-23 15:29:25 -08:00
trop[bot]
1f7269f482 fix: apply zoomFactor from setWindowOpenHandler to window.open() windows (#49909)
fix: apply zoomFactor from setWindowOpenHandler to window.open() windows

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-02-23 11:36:55 +01:00
trop[bot]
2813b89824 fix: prevent GBytes leak in GdkPixbufFromSkBitmap on Linux/GTK (#49898)
Inside gtk_util::GdkPixbufFromSkBitmap, g_bytes_new() was called
inline as an argument to gdk_pixbuf_new_from_bytes(), which per
GTK docs does not take ownership of the GBytes - it adds its own
internal reference. The caller's GBytes* was never stored or
unreffed, leaking 4 x width x height bytes of pixel data on every
call.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: redeemer <marcin.probola@gmail.com>
2026-02-20 16:10:34 -08:00
trop[bot]
a4560db9f0 fix: refresh menu item state on key equivalent dispatch (#49889)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-02-20 14:58:52 -05:00
trop[bot]
adfc062313 fix: fullscreen restoration on Windows (#49892)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-02-20 14:29:48 -05:00
trop[bot]
8dc34b4b25 fix: update DBus signal signature for XDG GlobalShortcuts portal (#49870)
* fix: update DBus signal signature for XDG GlobalShortcuts portal

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

* fixup! fix: update DBus signal signature for XDG GlobalShortcuts portal

chore: fix .patches file

* 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: Charles Kerr <charles@charleskerr.com>
2026-02-19 19:07:56 -06:00
trop[bot]
6cc5ad763d fix: avoid startup crash when V8 sandbox is disabled (#49884)
* fix: avoid startup crash when V8 sandbox is disabled

Co-authored-by: David Franco <davidfrsan@gmail.com>

* chore: update patch

Co-authored-by: David Franco <david@metrica-sports.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Franco <davidfrsan@gmail.com>
Co-authored-by: David Franco <david@metrica-sports.com>
2026-02-19 18:41:30 -06:00
trop[bot]
4c5637c687 ci: log mocha retries in spec runner (#49877)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Nilay Arya <84241885+nilayarya@users.noreply.github.com>
2026-02-19 16:22:21 -06:00
electron-roller[bot]
0d71ed0f29 chore: bump chromium to 144.0.7559.220 (40-x-y) (#49869)
chore: bump chromium in DEPS to 144.0.7559.220

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
2026-02-19 11:27:01 -05:00
trop[bot]
fc63000ee7 refactor: initialize libgdk stubs before use in platform_util:Beep (#49864)
* refactor: initialize libgdk stubs before use in `platform_util:Beep`

Co-authored-by: Noah Gregory <noahmgregory@gmail.com>

* feat: add upstream function to get libgdk handle

Co-authored-by: Noah Gregory <noahmgregory@gmail.com>

* fix: add missing include for libgdk support

Co-authored-by: Noah Gregory <noahmgregory@gmail.com>

* style: adjust comment wording and make linter happy

Co-authored-by: Noah Gregory <noahmgregory@gmail.com>

* style: make linter actually happy

Co-authored-by: Noah Gregory <noahmgregory@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Noah Gregory <noahmgregory@gmail.com>
2026-02-19 14:24:12 +01:00
trop[bot]
8d41dbe65f chore: use relative links from docs/ to files outside of docs/ (#49867)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2026-02-19 14:23:34 +01:00
trop[bot]
f3b90cc91c fix: draggable region position with docked DevTools (#49847)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-02-19 09:55:01 +01:00
trop[bot]
a78a8cd30c ci: fixup build stats upload on Windows (#49849)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
2026-02-19 09:54:36 +01:00
Sam Maddock
2511f78120 fix: frameless window resize in MAS builds (#49856)
backport: fix: frameless window resize in MAS builds
2026-02-19 14:24:38 +09:00
trop[bot]
f711af1080 docs: note required windows in 'new-window-for-tab' event (#49860)
docs: note required windows in new-window-for-tab

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-02-18 20:37:10 -08:00
trop[bot]
616026ce1c docs: clarify ASAR integrity is supported in MAS builds (#49853)
* docs: clarify ASAR integrity is supported in MAS builds

Add a note to the ASAR integrity documentation explicitly stating
that this feature is fully supported and recommended in Mac App
Store builds. While MAS-installed apps have system-level protections,
ASAR integrity provides an additional security layer and is important
for MAS builds distributed outside the Mac App Store.

Slack thread: https://electronhq.slack.com/archives/CB6CG54DB/p1771449093872419?thread_ts=1771446183.473289&cid=CB6CG54DB

https://claude.ai/code/session_01A97nfiqHUVxLNaQyHVXS7j

Co-authored-by: Claude <noreply@anthropic.com>

* docs: clarify ASAR integrity support for MAS builds

Updates the ASAR integrity documentation to explicitly mention that
it is supported and recommended in Mac App Store builds. Clarifies
that while MAS-installed apps have system-level protections (Resources
folder owned by root), ASAR integrity is especially important when
distributing MAS builds through other channels like direct download,
since those installations won't have the read-only protections.

https://claude.ai/code/session_012mBNZQW34h91NRcdFaLxNh

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-18 22:24:13 +00:00
trop[bot]
ada2c4e072 feat: add focusOnNavigation flag to WebPreferences (#49512)
* feat: add focusOnNavigation webPreference

Co-authored-by: Kyle Cutler <kycutler@microsoft.com>

* WebContentsView tests

Co-authored-by: Kyle Cutler <kycutler@microsoft.com>

* fix

Co-authored-by: Kyle Cutler <kycutler@microsoft.com>

* fix

Co-authored-by: Kyle Cutler <kycutler@microsoft.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Kyle Cutler <kycutler@microsoft.com>
2026-02-18 15:51:20 -05:00
trop[bot]
1a76e35971 feat: add support for long-animation-frame script attribution (#49772)
* feat: add support for `long-animation-frame` script attribution

Co-authored-by: Niklas Wenzel <dev@nikwen.de>

* docs: document `AlwaysLogLOAFURL`

Co-authored-by: Niklas Wenzel <dev@nikwen.de>

* chore: add test

Co-authored-by: Niklas Wenzel <dev@nikwen.de>

* docs: adjust docs as per PR comment

Co-authored-by: Niklas Wenzel <dev@nikwen.de>

* fix: test failures

Co-authored-by: Niklas Wenzel <dev@nikwen.de>

* chore: simplify test

Co-authored-by: Niklas Wenzel <dev@nikwen.de>

* fix: tests on Windows and Linux

Co-authored-by: Niklas Wenzel <dev@nikwen.de>

* chore: fixup patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Niklas Wenzel <dev@nikwen.de>
2026-02-18 14:22:00 -05:00
trop[bot]
3d475716f4 feat: improve Windows Toast actions support (#49786)
* feat: improve Windows Toast actions support

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

* fix: ensure MSIX compatibility

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

* test: add bad clsid format test

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>
2026-02-18 13:22:10 -05:00
electron-roller[bot]
c7a033dd06 chore: bump chromium to 144.0.7559.177 (40-x-y) (#49800)
* chore: bump chromium in DEPS to 144.0.7559.177

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
2026-02-18 16:34:57 +01:00
trop[bot]
2ff6e7e042 build: use spawn instead of spawnSync for build (#49826)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
2026-02-17 16:22:33 -05:00
Väinö Mäkelä
3302c4dbd8 fix: make pointer lock work on Wayland (#49283)
Chromium used to only implement pointer lock on Wayland in
Chrome-specific code, and this prevented Electron from making use of it.
This has been fixed on chromium main, so backport this as a patch to
Electron.
2026-02-17 15:45:38 -05:00
trop[bot]
76ce7a7ca0 docs: fix typos across tutorial documentation (#49832)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: ron <ronald_eddy@yahoo.com>
2026-02-17 15:04:38 -05:00
trop[bot]
4237bcbc4c chore: add Copilot CLI instructions (#49824)
chore: add copilot-instructions

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
2026-02-17 13:26:29 -05:00
trop[bot]
c81c505fea fix: missing shared texture docs (#49810)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: reito <reito@chromium.org>
2026-02-16 22:18:43 -08:00
trop[bot]
638dd2221a build(dev-deps): update micromark-core-commonmark to 2.0.3 (#49761)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2026-02-13 15:30:58 -08:00
electron-roller[bot]
8ec629e871 chore: bump node to v24.13.1 (40-x-y) (#49742)
* chore: bump node in DEPS to v24.13.1

* chore: fixup patches

refs:
* https://github.com/nodejs/node/pull/60425
* https://github.com/nodejs/node/pull/61270
* https://github.com/nodejs/node/pull/61044

* fix: generate_config_gypi needs to generate valid JSON

https://github.com/nodejs/node/pull/60794

* doc: align Buffer.concat documentation with behavior

https://github.com/nodejs/node/pull/60405

* src: fix off-thread cert loading in bundled cert mode

https://github.com/nodejs/node/pull/60764

* chore: fixup patch indices

* build: fix extraneous includes

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-02-13 16:35:43 +01:00
trop[bot]
ba487e914d fix: address upstream Chromium shift to enable CoreAudio Tap API for audio capture used in electron's desktopCapturer (🍏 macOS). (#49741)
* fix: Enable CoreAudio Tap API for Audio Capture (🍏 macOS)

Co-authored-by: Bug-Reaper <llama@soundsafari.io>

* fix: addressed markdown issue which caused pre-commit hook failure

🧑‍🔧 : Ref : https://github.com/electron/electron/pull/49717#issuecomment-3874660013

Co-authored-by: Bug-Reaper <llama@soundsafari.io>

* fix: updated docs to cover `desktopCapturer` nuances with macOS

📝 : PR https://github.com/electron/electron/pull/49717

Co-authored-by: Bug-Reaper <llama@soundsafari.io>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Bug-Reaper <llama@soundsafari.io>
2026-02-13 16:27:51 +01:00
trop[bot]
4cd269a752 fix: revoke Read access after removing file via FileSystemAccess API (#49746)
Refs https://chromium-review.googlesource.com/6677249

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-02-13 10:40:22 +01:00
Keeley Hammond
201be32e0f chore: cherry-pick e045399a1ecb from chromium (#49790)
* chore: cherry-pick e045399a1ecb from chromium

* chore: update patch
2026-02-12 18:06:08 -08:00
trop[bot]
11f60f3520 ci: add markdownlint problem matcher (#49764)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2026-02-12 10:56:13 -05:00
electron-roller[bot]
530c16aab5 chore: bump chromium to 144.0.7559.173 (40-x-y) (#49766)
chore: bump chromium in DEPS to 144.0.7559.173

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
2026-02-12 10:15:09 -05:00
trop[bot]
e0a61a58ef build: generate artifact attestions for released assets (#49767)
* build: generate artifact attestions for released assets

Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>

* chore: address review feedback

Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>

* build: fixup attestation for release assets (#49732)

* build: fixup attestation for release assets

* Generate artifact attestation for generated artifacts

* set id-token for attestation

* Add artifact-metadata permission for attestation

* add permissions for testing attestations

* Revert "add permissions for testing attestations"

This reverts commit 0284bed175.

* Revert "set id-token for attestation"

This reverts commit 69a1b13a18.

* Revert "Generate artifact attestation for generated artifacts"

This reverts commit ee0536eceb.

* chore: update publish workflow

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2026-02-11 15:34:26 -05:00
Keeley Hammond
fdd31a7aa4 feat: add support for disclaiming utility processes (#49695)
feat: add support for disclaiming utility processes (#49128)

* feat: add support for disclaiming utility processes

* chore: update patches

---------
2026-02-11 16:51:03 +01:00
trop[bot]
cb0727f88c docs: fix typos across documentation (#49758)
Fix 40 typos across 25 documentation files including misspellings,
missing words, doubled words, wrong words, and grammatical errors.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: ron <ronald_eddy@yahoo.com>
2026-02-11 16:48:48 +01:00
electron-roller[bot]
21c6e4e8a0 chore: bump node to v24.13.0 (40-x-y) (#49188)
* chore: bump node in DEPS to v24.12.0

* chore: bump node in DEPS to v24.13.0

* src: use CP_UTF8 for wide file names on win32

https://github.com/nodejs/node/pull/60575

* test,crypto: handle a few more BoringSSL tests

https://github.com/nodejs/node/pull/59030

* chore: re-add accidentally removed sslv23 test

* test: make buffer sizes 32bit-aware in test-internal-util-construct-sab

https://github.com/nodejs/node/pull/61026

* chore: fixup patch indices

* chore: fixup crypto patch rebase

(cherry picked from commit 0b3baf0167)

* chore: fixup sandboxed pointers patch

(cherry picked from commit f52fbdbe51)

* build: try removing zero-fill sandbox patch component (#49452)

(cherry picked from commit 73377af79e)

* tls: route callback exceptions through error handlers

https://github.com/nodejs-private/node-private/pull/782
(cherry picked from commit 87bc8ebd34)

* src: add internal binding for constructing SharedArrayBuffers

https://github.com/nodejs/node/pull/60497
(cherry picked from commit ae90076267)

* chore: fixup after rebase

---------

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: John Kleinschmidt <kleinschmidtorama@gmail.com>
2026-02-10 15:29:51 +01:00
trop[bot]
bf4746c7c9 fix: default accelerator for role-based menu items (#49669)
fix: apply default accelerator for role-based menu items

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-02-09 10:09:18 -05:00
trop[bot]
091c5db763 docs: fix framerate limit when osr with shared texture (#49729)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: reito <reito@chromium.org>
2026-02-09 15:37:31 +01:00
electron-roller[bot]
ee64692287 chore: bump chromium to 144.0.7559.134 (40-x-y) (#49656)
* chore: bump chromium in DEPS to 144.0.7559.133

* chore: update patches

* chore: bump chromium in DEPS to 144.0.7559.134

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
2026-02-09 09:17:14 -05:00
trop[bot]
0bc0553af7 fix: restore macos 12 support in Node 24 (#49702)
* fix: restore macos 12 support in Node 24

Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>

* chore: fix rebased patch list

* chore: fixup patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
Co-authored-by: Niklas Wenzel <dev@nikwen.de>
2026-02-07 07:59:25 -08:00
trop[bot]
51beb04c10 ci: fix patches changes detected in apply patches workflow (#49710)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2026-02-06 21:29:52 -08:00
Keeley Hammond
45a6bfbae9 chore: cherry-pick 4508b5dfb26e from v8 (#49699)
* chore: cherry-pick 4508b5dfb26e from v8

* chore: update patch
2026-02-06 07:49:31 -08:00
trop[bot]
53982a2c3a refactor: use ComPtr pattern for MSIX to avoid exception handling (#49687)
* Revert "fix: fix Windows MSIX release build errors (#49613)"

This reverts commit 4b5d5f9dd5.

Co-authored-by: Keeley Hammond <khammond@slack-corp.com>

* refactor: use WRL ComPtr pattern for MSIX to avoid exception handling

The MSIX auto-updater code was using C++/WinRT (winrt::* namespace), which requires exception handling (/EHsc). Mixing exception and non-exception handling code in the same binary is problematic at runtime. This commit refactors electron_api_msix_updater.cc to use an upstream Chromium pattern and eliminates the need for special exception handling build flags

Co-authored-by: Keeley Hammond <khammond@slack-corp.com>

* build: import correct packages

Co-authored-by: Keeley Hammond <khammond@slack-corp.com>

* build: consolidate IPackage declarations

Co-authored-by: Keeley Hammond <khammond@slack-corp.com>

* refactor: use IPackageManager/IPackageManager5/IPackageManager9 and IPackage/IPackage2/IPackage4/IPackage6 interfaces as needed for different API methods.

Also consolidates duplicate completion handler logic, fixes a bug in
RegisterRestartOnUpdate where the command line string could go out of
scope, and removes unused includes.

Co-authored-by: Keeley Hammond <khammond@slack-corp.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
2026-02-05 13:48:23 -08:00
trop[bot]
713b24db80 refactor: don't log error just for unsigned code (#49677)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Noah Gregory <noahmgregory@gmail.com>
2026-02-05 22:01:09 +01:00
trop[bot]
f63f875ee0 ci: use squash merge for apply patches workflow (#49672)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2026-02-04 18:49:57 -08:00
281 changed files with 7091 additions and 2395 deletions

View File

@@ -95,7 +95,7 @@ runs:
# Upload build stats to Datadog
if ($env:DD_API_KEY) {
try {
npx node electron\script\build-stats.mjs out\Default\siso.exe.INFO --upload-stats
npx node electron\script\build-stats.mjs out\Default\siso.exe.INFO --upload-stats ; $LASTEXITCODE = 0
} catch {
Write-Host "Build stats upload failed, continuing..."
}
@@ -216,6 +216,7 @@ runs:
- name: Publish Electron Dist ${{ inputs.step-suffix }}
if: ${{ inputs.is-release == 'true' }}
shell: bash
id: github-upload
run: |
rm -rf src/out/Default/obj
cd src/electron
@@ -226,6 +227,11 @@ runs:
echo 'Uploading Electron release distribution to GitHub releases'
script/release/uploaders/upload.py --verbose
fi
- name: Generate artifact attestation
if: ${{ inputs.is-release == 'true' }}
uses: actions/attest-build-provenance@96278af6caaf10aea03fd8d33a09a777ca52d62f # v3.2.0
with:
subject-path: ${{ steps.github-upload.outputs.UPLOADED_PATHS }}
- name: Generate siso report
if: ${{ inputs.target-platform != 'win' && !cancelled() }}
shell: bash

View File

@@ -43,7 +43,7 @@ runs:
curl --unix-socket /var/run/sas/sas.sock --fail "http://foo/$CACHE_FILE?platform=${{ inputs.target-platform }}&getAccountName=true" > sas-token
- name: Save SAS Key
if: ${{ inputs.generate-sas-token == 'true' }}
uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
uses: actions/cache/save@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
with:
path: sas-token
key: sas-key-${{ inputs.target-platform }}-${{ github.run_number }}-${{ github.run_attempt }}

View File

@@ -15,7 +15,7 @@ runs:
git config --global core.preloadindex true
git config --global core.longpaths true
fi
export BUILD_TOOLS_SHA=4430e4a505e0f4fa2a41b707a10a36f780bbdd26
export BUILD_TOOLS_SHA=a0cc95a1884a631559bcca0c948465b725d9295a
npm i -g @electron/build-tools
# Update depot_tools to ensure python
e d update_depot_tools

View File

@@ -7,7 +7,7 @@ runs:
shell: bash
id: yarn-cache-dir-path
run: echo "dir=$(node src/electron/script/yarn.js config get cacheFolder)" >> $GITHUB_OUTPUT
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
- uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}

122
.github/copilot-instructions.md vendored Normal file
View File

@@ -0,0 +1,122 @@
# Copilot Instructions for Electron
## Build System
Electron uses `@electron/build-tools` (`e` CLI). Install with `npm i -g @electron/build-tools`.
```bash
e sync # Fetch sources and apply patches
e build # Build Electron (GN + Ninja)
e build -k 999 # Build, continuing through errors
e start # Run built Electron
e start --version # Verify Electron launches
e test # Run full test suite
e debug # Run in debugger (lldb on macOS, gdb on Linux)
```
### Linting
```bash
npm run lint # Run all linters (JS, C++, Python, GN, docs)
npm run lint:js # JavaScript/TypeScript only
npm run lint:clang-format # C++ formatting only
npm run lint:cpp # C++ linting only
npm run lint:docs # Documentation only
```
### Running a Single Test
```bash
npm run test -- -g "pattern" # Run tests matching a regex pattern
# Example: npm run test -- -g "ipc"
```
### Running a Single Node.js Test
```bash
node script/node-spec-runner.js parallel/test-crypto-keygen
```
## Architecture
Electron embeds Chromium (rendering) and Node.js (backend) to enable desktop apps with web technologies. The parent directory (`../`) is the Chromium source tree.
### Process Model
Electron has two primary process types, mirroring Chromium:
- **Main process** (`shell/browser/` + `lib/browser/`): Controls app lifecycle, creates windows, system APIs
- **Renderer process** (`shell/renderer/` + `lib/renderer/`): Runs web content in BrowserWindows
### Native ↔ JavaScript Bridge
Each API is implemented as a C++/JS pair:
- C++ side: `shell/browser/api/electron_api_{name}.cc/.h` — uses `gin::Wrappable` and `ObjectTemplateBuilder`
- JS side: `lib/browser/api/{name}.ts` — exports the module, registered in `lib/browser/api/module-list.ts`
- Binding: `NODE_LINKED_BINDING_CONTEXT_AWARE(electron_browser_{name}, Initialize)` in C++ and registered in `shell/common/node_bindings.cc`
- Type declaration: `typings/internal-ambient.d.ts` maps `process._linkedBinding('electron_browser_{name}')`
### Patches System
Electron patches upstream dependencies (Chromium, Node.js, V8, etc.) rather than forking them. Patches live in `patches/` organized by target, with `patches/config.json` mapping directories to repos.
```text
patches/{target}/*.patch → [e sync] → target repo commits
← [e patches] ←
```
Key rules:
- Fix existing patches rather than creating new ones
- Preserve original authorship in TODO comments — never change `TODO(name)` assignees
- Each patch commit message must explain why the patch exists
- After modifying patches, run `e patches {target}` to export
When working on the `roller/chromium/main` branch for Chromium upgrades, use `e sync --3` for 3-way merge conflict resolution.
## Conventions
### File Naming
- JS/TS files: kebab-case (`file-name.ts`)
- C++ files: snake_case with `electron_api_` prefix (`electron_api_safe_storage.cc`)
- Test files: `api-{module-name}-spec.ts` in `spec/`
- Source file lists are maintained in `filenames.gni` (with platform-specific sections)
### JavaScript/TypeScript
- Semicolons required (`"semi": ["error", "always"]`)
- `const` and `let` only (no `var`)
- Arrow functions preferred
- Import order enforced: `@electron/internal``@electron``electron` → external → builtin → relative
- API naming: `PascalCase` for classes (`BrowserWindow`), `camelCase` for module APIs (`globalShortcut`)
- Prefer getters/setters over jQuery-style `.text([text])` patterns
### C++
- Follows Chromium coding style, enforced by `clang-format` and `clang-tidy`
- Uses Chromium abstractions (`base::`, `content::`, etc.)
- Header guards: `#ifndef ELECTRON_SHELL_BROWSER_API_ELECTRON_API_{NAME}_H_`
- Platform-specific files: `_mac.mm`, `_win.cc`, `_linux.cc`
### Testing
- Framework: Mocha + Chai + Sinon
- Test helpers in `spec/lib/` (e.g., `spec-helpers.ts`, `window-helpers.ts`)
- Use `defer()` from spec-helpers for cleanup, `closeAllWindows()` for window teardown
- Tests import from `electron/main` or `electron/renderer`
### Documentation
- API docs in `docs/api/` as Markdown, parsed by `@electron/docs-parser` to generate `electron.d.ts`
- API history tracked via YAML blocks in HTML comments within doc files
- Docs must pass `npm run lint:docs`
### Build Configuration
- `BUILD.gn`: Main GN build config
- `buildflags/buildflags.gni`: Feature flags (PDF viewer, extensions, spellchecker)
- `build/args/`: Build argument profiles (`testing.gn`, `release.gn`, `all.gn`)
- `DEPS`: Dependency versions and checkout paths
- `chromium_src/`: Chromium source file overrides (compiled instead of originals)

View File

@@ -0,0 +1,16 @@
{
"problemMatcher": [
{
"owner": "markdownlint",
"pattern": [
{
"regexp": "^(.+):(\\d+):(\\d+)\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"message": 4
}
]
}
]
}

View File

@@ -56,16 +56,17 @@ jobs:
path: src/electron
fetch-depth: 0
persist-credentials: false
ref: ${{ github.event.pull_request.head.sha }}
- name: Rebase onto Base Branch
ref: ${{ github.event.pull_request.base.ref }}
- name: Merge PR HEAD
working-directory: src/electron
env:
BASE_REF: ${{ github.event.pull_request.base.ref }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
git config user.email "electron@github.com"
git config user.name "Electron Bot"
git fetch origin ${BASE_REF}
git rebase origin/${BASE_REF}
git fetch origin refs/pull/${PR_NUMBER}/head
git merge --squash FETCH_HEAD
git commit -n -m "Squashed commits"
- name: Checkout & Sync & Save
uses: ./src/electron/.github/actions/checkout
with:

View File

@@ -43,9 +43,12 @@ jobs:
uses: ./src/electron/.github/actions/checkout
publish-x64:
uses: ./.github/workflows/pipeline-segment-electron-build.yml
uses: ./.github/workflows/pipeline-segment-electron-publish.yml
permissions:
artifact-metadata: write
attestations: write
contents: read
id-token: write
needs: checkout-linux
with:
environment: production-release
@@ -60,9 +63,12 @@ jobs:
secrets: inherit
publish-arm:
uses: ./.github/workflows/pipeline-segment-electron-build.yml
uses: ./.github/workflows/pipeline-segment-electron-publish.yml
permissions:
artifact-metadata: write
attestations: write
contents: read
id-token: write
needs: checkout-linux
with:
environment: production-release
@@ -77,9 +83,12 @@ jobs:
secrets: inherit
publish-arm64:
uses: ./.github/workflows/pipeline-segment-electron-build.yml
uses: ./.github/workflows/pipeline-segment-electron-publish.yml
permissions:
artifact-metadata: write
attestations: write
contents: read
id-token: write
needs: checkout-linux
with:
environment: production-release

View File

@@ -47,9 +47,12 @@ jobs:
target-platform: macos
publish-x64-darwin:
uses: ./.github/workflows/pipeline-segment-electron-build.yml
uses: ./.github/workflows/pipeline-segment-electron-publish.yml
permissions:
artifact-metadata: write
attestations: write
contents: read
id-token: write
needs: checkout-macos
with:
environment: production-release
@@ -64,9 +67,12 @@ jobs:
secrets: inherit
publish-x64-mas:
uses: ./.github/workflows/pipeline-segment-electron-build.yml
uses: ./.github/workflows/pipeline-segment-electron-publish.yml
permissions:
artifact-metadata: write
attestations: write
contents: read
id-token: write
needs: checkout-macos
with:
environment: production-release
@@ -81,9 +87,12 @@ jobs:
secrets: inherit
publish-arm64-darwin:
uses: ./.github/workflows/pipeline-segment-electron-build.yml
uses: ./.github/workflows/pipeline-segment-electron-publish.yml
permissions:
artifact-metadata: write
attestations: write
contents: read
id-token: write
needs: checkout-macos
with:
environment: production-release
@@ -98,9 +107,12 @@ jobs:
secrets: inherit
publish-arm64-mas:
uses: ./.github/workflows/pipeline-segment-electron-build.yml
uses: ./.github/workflows/pipeline-segment-electron-publish.yml
permissions:
artifact-metadata: write
attestations: write
contents: read
id-token: write
needs: checkout-macos
with:
environment: production-release

View File

@@ -46,7 +46,7 @@ jobs:
shell: bash
run: |
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
gn_version="$(curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/DEPS?format=TEXT" | base64 -d | grep gn_version | head -n1 | cut -d\' -f4)"
gn_version="$(curl -sL -b ~/.gitcookies "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/DEPS?format=TEXT" | base64 -d | grep gn_version | head -n1 | cut -d\' -f4)"
cipd ensure -ensure-file - -root . <<-CIPD
\$ServiceURL https://chrome-infra-packages.appspot.com/
@@ -62,12 +62,14 @@ jobs:
chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
mkdir -p src/buildtools
curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/buildtools/DEPS?format=TEXT" | base64 -d > src/buildtools/DEPS
curl -sL -b ~/.gitcookies "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/buildtools/DEPS?format=TEXT" | base64 -d > src/buildtools/DEPS
gclient sync --spec="solutions=[{'name':'src/buildtools','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':True},'managed':False}]"
- name: Add ESLint problem matcher
- name: Add problem matchers
shell: bash
run: echo "::add-matcher::src/electron/.github/problem-matchers/eslint-stylish.json"
run: |
echo "::add-matcher::src/electron/.github/problem-matchers/eslint-stylish.json"
echo "::add-matcher::src/electron/.github/problem-matchers/markdownlint.json"
- name: Run Lint
shell: bash
run: |
@@ -85,4 +87,8 @@ jobs:
run: |
cd src/electron
node script/yarn.js tsc -p tsconfig.script.json
- name: Check GHA Workflows
shell: bash
run: |
cd src/electron
node script/copy-pipeline-segment-publish.js --check

View File

@@ -0,0 +1,237 @@
# AUTOGENERATED FILE - DO NOT EDIT MANUALLY
# ONLY EDIT .github/workflows/pipeline-segment-electron-build.yml
name: Pipeline Segment - Electron Build
on:
workflow_call:
inputs:
environment:
description: using the production or testing environment
required: false
type: string
target-platform:
type: string
description: Platform to run on, can be macos, win or linux
required: true
target-arch:
type: string
description: Arch to build for, can be x64, arm64, ia32 or arm
required: true
target-variant:
type: string
description: Variant to build for, no effect on non-macOS target platforms. Can
be darwin, mas or all.
default: all
build-runs-on:
type: string
description: What host to run the build
required: true
build-container:
type: string
description: JSON container information for aks runs-on
required: false
default: '{"image":null}'
is-release:
description: Whether this build job is a release job
required: true
type: boolean
default: false
gn-build-type:
description: The gn build type - testing or release
required: true
type: string
default: testing
generate-symbols:
description: Whether or not to generate symbols
required: true
type: boolean
default: false
upload-to-storage:
description: Whether or not to upload build artifacts to external storage
required: true
type: string
default: "0"
is-asan:
description: Building the Address Sanitizer (ASan) Linux build
required: false
type: boolean
default: false
enable-ssh:
description: Enable SSH debugging
required: false
type: boolean
default: false
permissions: {}
concurrency:
group: electron-build-${{ inputs.target-platform }}-${{ inputs.target-arch
}}-${{ inputs.target-variant }}-${{ inputs.is-asan }}-${{
github.ref_protected == true && github.run_id || github.ref }}
cancel-in-progress: ${{ github.ref_protected != true }}
env:
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
CHROMIUM_GIT_COOKIE_WINDOWS_STRING: ${{ secrets.CHROMIUM_GIT_COOKIE_WINDOWS_STRING }}
DD_API_KEY: ${{ secrets.DD_API_KEY }}
ELECTRON_ARTIFACTS_BLOB_STORAGE: ${{ secrets.ELECTRON_ARTIFACTS_BLOB_STORAGE }}
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
SUDOWOODO_EXCHANGE_URL: ${{ secrets.SUDOWOODO_EXCHANGE_URL }}
SUDOWOODO_EXCHANGE_TOKEN: ${{ secrets.SUDOWOODO_EXCHANGE_TOKEN }}
GCLIENT_EXTRA_ARGS: ${{ inputs.target-platform == 'macos' &&
'--custom-var=checkout_mac=True --custom-var=host_os=mac' ||
inputs.target-platform == 'win' && '--custom-var=checkout_win=True' ||
'--custom-var=checkout_arm=True --custom-var=checkout_arm64=True' }}
ELECTRON_OUT_DIR: Default
ACTIONS_STEP_DEBUG: ${{ secrets.ACTIONS_STEP_DEBUG }}
jobs:
build:
defaults:
run:
shell: bash
runs-on: ${{ inputs.build-runs-on }}
permissions:
artifact-metadata: write
attestations: write
contents: read
id-token: write
container: ${{ fromJSON(inputs.build-container) }}
environment: ${{ inputs.environment }}
env:
TARGET_ARCH: ${{ inputs.target-arch }}
TARGET_PLATFORM: ${{ inputs.target-platform }}
steps:
- name: Create src dir
run: |
mkdir src
- name: Checkout Electron
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
with:
path: src/electron
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Setup SSH Debugging
if: ${{ inputs.target-platform == 'macos' && (inputs.enable-ssh ||
env.ACTIONS_STEP_DEBUG == 'true') }}
uses: ./src/electron/.github/actions/ssh-debug
with:
tunnel: "true"
env:
CLOUDFLARE_TUNNEL_CERT: ${{ secrets.CLOUDFLARE_TUNNEL_CERT }}
CLOUDFLARE_TUNNEL_HOSTNAME: ${{ vars.CLOUDFLARE_TUNNEL_HOSTNAME }}
CLOUDFLARE_USER_CA_CERT: ${{ secrets.CLOUDFLARE_USER_CA_CERT }}
AUTHORIZED_USERS: ${{ secrets.SSH_DEBUG_AUTHORIZED_USERS }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Free up space (macOS)
if: ${{ inputs.target-platform == 'macos' }}
uses: ./src/electron/.github/actions/free-space-macos
- name: Check disk space after freeing up space
if: ${{ inputs.target-platform == 'macos' }}
run: df -h
- name: Setup Node.js/npm
if: ${{ inputs.target-platform == 'macos' }}
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903
with:
node-version: 20.19.x
cache: yarn
cache-dependency-path: src/electron/yarn.lock
- name: Install Dependencies
uses: ./src/electron/.github/actions/install-dependencies
- name: Install AZCopy
if: ${{ inputs.target-platform == 'macos' }}
run: brew install azcopy
- name: Set GN_EXTRA_ARGS for Linux
if: ${{ inputs.target-platform == 'linux' }}
run: >
if [ "${{ inputs.target-arch }}" = "arm" ]; then
if [ "${{ inputs.is-release }}" = true ]; then
GN_EXTRA_ARGS='target_cpu="arm" build_tflite_with_xnnpack=false symbol_level=1'
else
GN_EXTRA_ARGS='target_cpu="arm" build_tflite_with_xnnpack=false'
fi
elif [ "${{ inputs.target-arch }}" = "arm64" ]; then
GN_EXTRA_ARGS='target_cpu="arm64" fatal_linker_warnings=false enable_linux_installer=false'
elif [ "${{ inputs.is-asan }}" = true ]; then
GN_EXTRA_ARGS='is_asan=true'
fi
echo "GN_EXTRA_ARGS=$GN_EXTRA_ARGS" >> $GITHUB_ENV
- name: Set Chromium Git Cookie
uses: ./src/electron/.github/actions/set-chromium-cookie
- name: Install Build Tools
uses: ./src/electron/.github/actions/install-build-tools
- name: Generate DEPS Hash
run: |
node src/electron/script/generate-deps-hash.js
DEPSHASH=v1-src-cache-$(cat src/electron/.depshash)
echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
echo "CACHE_PATH=$DEPSHASH.tar" >> $GITHUB_ENV
- name: Restore src cache via AZCopy
if: ${{ inputs.target-platform != 'linux' }}
uses: ./src/electron/.github/actions/restore-cache-azcopy
with:
target-platform: ${{ inputs.target-platform }}
- name: Restore src cache via AKS
if: ${{ inputs.target-platform == 'linux' }}
uses: ./src/electron/.github/actions/restore-cache-aks
- name: Checkout Electron
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
with:
path: src/electron
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Fix Sync
if: ${{ inputs.target-platform != 'linux' }}
uses: ./src/electron/.github/actions/fix-sync
with:
target-platform: ${{ inputs.target-platform }}
env:
ELECTRON_DEPOT_TOOLS_DISABLE_LOG: true
- name: Init Build Tools
run: >
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }}
--import ${{ inputs.gn-build-type }} --target-cpu ${{
inputs.target-arch }} --remote-build siso
- name: Run Electron Only Hooks
run: |
e d gclient runhooks --spec="solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]"
- name: Regenerate DEPS Hash
run: >
(cd src/electron && git checkout .) && node
src/electron/script/generate-deps-hash.js
echo "DEPSHASH=$(cat src/electron/.depshash)" >> $GITHUB_ENV
- name: Add CHROMIUM_BUILDTOOLS_PATH to env
run: echo "CHROMIUM_BUILDTOOLS_PATH=$(pwd)/src/buildtools" >> $GITHUB_ENV
- name: Free up space (macOS)
if: ${{ inputs.target-platform == 'macos' }}
uses: ./src/electron/.github/actions/free-space-macos
- name: Build Electron
if: ${{ inputs.target-platform != 'macos' || (inputs.target-variant == 'all' ||
inputs.target-variant == 'darwin') }}
uses: ./src/electron/.github/actions/build-electron
with:
target-arch: ${{ inputs.target-arch }}
target-platform: ${{ inputs.target-platform }}
artifact-platform: ${{ inputs.target-platform == 'macos' && 'darwin' ||
inputs.target-platform }}
is-release: ${{ inputs.is-release }}
generate-symbols: ${{ inputs.generate-symbols }}
upload-to-storage: ${{ inputs.upload-to-storage }}
is-asan: ${{ inputs.is-asan }}
- name: Set GN_EXTRA_ARGS for MAS Build
if: ${{ inputs.target-platform == 'macos' && (inputs.target-variant == 'all' ||
inputs.target-variant == 'mas') }}
run: |
echo "MAS_BUILD=true" >> $GITHUB_ENV
GN_EXTRA_ARGS='is_mas_build=true'
echo "GN_EXTRA_ARGS=$GN_EXTRA_ARGS" >> $GITHUB_ENV
- name: Build Electron (MAS)
if: ${{ inputs.target-platform == 'macos' && (inputs.target-variant == 'all' ||
inputs.target-variant == 'mas') }}
uses: ./src/electron/.github/actions/build-electron
with:
target-arch: ${{ inputs.target-arch }}
target-platform: ${{ inputs.target-platform }}
artifact-platform: mas
is-release: ${{ inputs.is-release }}
generate-symbols: ${{ inputs.generate-symbols }}
upload-to-storage: ${{ inputs.upload-to-storage }}
step-suffix: (mas)

View File

@@ -191,15 +191,25 @@ jobs:
run: |
cd src/out/Default
unzip -:o dist.zip
#- name: Import & Trust Self-Signed Codesigning Cert on MacOS
# if: ${{ inputs.target-platform == 'macos' && inputs.target-arch == 'x64' }}
# run: |
# sudo security authorizationdb write com.apple.trust-settings.admin allow
# cd src/electron
# ./script/codesign/generate-identity.sh
- name: Import & Trust Self-Signed Codesigning Cert on MacOS
if: ${{ inputs.target-platform == 'macos' }}
run: |
cd src/electron
./script/codesign/generate-identity.sh
# Only sign on x64 — arm64 builds are already ad-hoc signed, and re-signing
# with an untrusted cert breaks macOS system integrations (e.g. dock bounce).
# Autoupdater tests sign their own fixture copies via signApp().
- name: Sign Electron.app for macOS tests
if: ${{ inputs.target-platform == 'macos' && inputs.target-arch == 'x64' }}
run: |
identity=$(src/electron/script/codesign/get-trusted-identity.sh)
if [ -n "$identity" ]; then
codesign -s "$identity" --deep --force src/out/Default/Electron.app
fi
- name: Run Electron Tests
shell: bash
timeout-minutes: 40
env:
MOCHA_REPORTER: mocha-multi-reporters
MOCHA_MULTI_REPORTERS: mocha-junit-reporter, tap
@@ -250,6 +260,19 @@ jobs:
fi
fi
- name: Take screenshot on timeout or cancellation
if: ${{ inputs.target-platform != 'linux' && (cancelled() || failure()) }}
shell: bash
run: |
screenshot_dir="src/electron/spec/artifacts"
mkdir -p "$screenshot_dir"
screenshot_file="$screenshot_dir/screenshot-timeout-$(date +%Y%m%d%H%M%S).png"
if [ "${{ inputs.target-platform }}" = "macos" ]; then
screencapture -x "$screenshot_file" || true
elif [ "${{ inputs.target-platform }}" = "win" ]; then
powershell -command "Add-Type -AssemblyName System.Windows.Forms; \$screen = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds; \$bitmap = New-Object System.Drawing.Bitmap(\$screen.Width, \$screen.Height); \$graphics = [System.Drawing.Graphics]::FromImage(\$bitmap); \$graphics.CopyFromScreen(\$screen.Location, [System.Drawing.Point]::Empty, \$screen.Size); \$bitmap.Save('$screenshot_file')" || true
fi
- name: Upload Test results to Datadog
env:
DD_ENV: ci
@@ -265,7 +288,7 @@ jobs:
fi
if: always() && !cancelled()
- name: Upload Test Artifacts
if: always() && !cancelled()
if: always()
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4
with:
name: test_artifacts_${{ env.ARTIFACT_KEY }}_${{ matrix.shard }}

View File

@@ -31,7 +31,7 @@ jobs:
echo "isLatestRelease=false" >> $GITHUB_OUTPUT
fi
- name: Trigger website docs update
if: ${{ steps.check-if-latest-release.outputs.isLatestRelease }}
if: ${{ steps.check-if-latest-release.outputs.isLatestRelease == 'true' }}
env:
GH_REPO: electron/website
GH_TOKEN: ${{ fromJSON(steps.secret-service.outputs.secrets).WEBSITE_DOCS_UPDATER_APP_TOKEN }}

View File

@@ -51,9 +51,12 @@ jobs:
target-platform: win
publish-x64-win:
uses: ./.github/workflows/pipeline-segment-electron-build.yml
uses: ./.github/workflows/pipeline-segment-electron-publish.yml
permissions:
artifact-metadata: write
attestations: write
contents: read
id-token: write
needs: checkout-windows
with:
environment: production-release
@@ -67,9 +70,12 @@ jobs:
secrets: inherit
publish-arm64-win:
uses: ./.github/workflows/pipeline-segment-electron-build.yml
uses: ./.github/workflows/pipeline-segment-electron-publish.yml
permissions:
artifact-metadata: write
attestations: write
contents: read
id-token: write
needs: checkout-windows
with:
environment: production-release
@@ -83,9 +89,12 @@ jobs:
secrets: inherit
publish-x86-win:
uses: ./.github/workflows/pipeline-segment-electron-build.yml
uses: ./.github/workflows/pipeline-segment-electron-publish.yml
permissions:
artifact-metadata: write
attestations: write
contents: read
id-token: write
needs: checkout-windows
with:
environment: production-release

View File

@@ -420,37 +420,6 @@ action("electron_generate_node_defines") {
args = [ rebase_path(target_gen_dir) ] + rebase_path(inputs)
}
# MSIX updater needs to be in a separate source_set because it uses C++/WinRT
# headers that require exceptions to be enabled.
source_set("electron_msix_updater") {
sources = [
"shell/browser/api/electron_api_msix_updater.cc",
"shell/browser/api/electron_api_msix_updater.h",
]
configs += [ "//third_party/electron_node:node_external_config" ]
public_configs = [ ":electron_lib_config" ]
if (is_win) {
cflags_cc = [
"/EHsc", # Enable C++ exceptions for C++/WinRT
"-Wno-c++98-compat-extra-semi", #Suppress C++98 compatibility warnings
]
include_dirs = [ "//third_party/nearby/src/internal/platform/implementation/windows/generated" ]
}
deps = [
"//base",
"//content/public/browser",
"//gin",
"//third_party/electron_node/deps/simdjson",
"//third_party/electron_node/deps/uv",
"//v8",
]
}
source_set("electron_lib") {
configs += [
"//v8:external_startup_data",
@@ -466,7 +435,6 @@ source_set("electron_lib") {
":electron_fuses",
":electron_generate_node_defines",
":electron_js2c",
":electron_msix_updater",
":electron_version_header",
":resources",
"buildflags",

4
DEPS
View File

@@ -2,9 +2,9 @@ gclient_gn_args_from = 'src'
vars = {
'chromium_version':
'144.0.7559.111',
'144.0.7559.236',
'node_version':
'v24.11.1',
'v24.14.0',
'nan_version':
'675cefebca42410733da8a454c8d9391fcebfbc2',
'squirrel.mac_version':

View File

@@ -255,7 +255,7 @@ async function startRepl () {
if (option.file && !option.webdriver) {
const file = option.file;
// eslint-disable-next-line n/no-deprecated-api
const protocol = url.parse(file).protocol;
const protocol = URL.canParse(file) ? new URL(file).protocol : null;
const extension = path.extname(file);
if (protocol === 'http:' || protocol === 'https:' || protocol === 'file:' || protocol === 'chrome:') {
await loadApplicationByURL(file);

View File

@@ -250,7 +250,9 @@ Returns:
Emitted when the user clicks the native macOS new tab button. The new
tab button is only visible if the current `BrowserWindow` has a
`tabbingIdentifier`
`tabbingIdentifier`.
You must create a window in this handler in order for macOS tabbing to work as expected.
### Event: 'browser-window-blur'
@@ -632,7 +634,7 @@ Returns `string` - The current application directory.
Returns `string` - A path to a special directory or file associated with `name`. On
failure, an `Error` is thrown.
If `app.getPath('logs')` is called without called `app.setAppLogsPath()` being called first, a default log directory will be created equivalent to calling `app.setAppLogsPath()` without a `path` parameter.
If `app.getPath('logs')` is called without calling `app.setAppLogsPath()` being called first, a default log directory will be created equivalent to calling `app.setAppLogsPath()` without a `path` parameter.
### `app.getFileIcon(path[, options])`
@@ -647,7 +649,7 @@ Returns `Promise<NativeImage>` - fulfilled with the app's icon, which is a [Nati
Fetches a path's associated icon.
On _Windows_, there a 2 kinds of icons:
On _Windows_, there are 2 kinds of icons:
* Icons associated with certain file extensions, like `.mp3`, `.png`, etc.
* Icons inside the file itself, like `.exe`, `.dll`, `.ico`.
@@ -763,7 +765,7 @@ app.getPreferredSystemLanguages() // ['fr-CA', 'en-US', 'zh-Hans-FI', 'es-419']
Both the available languages and regions and the possible return values differ between the two operating systems.
As can be seen with the example above, on Windows, it is possible that a preferred system language has no country code, and that one of the preferred system languages corresponds with the language used for the regional format. On macOS, the region serves more as a default country code: the user doesn't need to have Finnish as a preferred language to use Finland as the region,and the country code `FI` is used as the country code for preferred system languages that do not have associated countries in the language name.
As can be seen with the example above, on Windows, it is possible that a preferred system language has no country code, and that one of the preferred system languages corresponds with the language used for the regional format. On macOS, the region serves more as a default country code: the user doesn't need to have Finnish as a preferred language to use Finland as the region, and the country code `FI` is used as the country code for preferred system languages that do not have associated countries in the language name.
### `app.addRecentDocument(path)` _macOS_ _Windows_
@@ -1121,6 +1123,19 @@ Updates the current activity if its type matches `type`, merging the entries fro
Changes the [Application User Model ID][app-user-model-id] to `id`.
### `app.setToastActivatorCLSID(id)` _Windows_
* `id` string
Changes the [Toast Activator CLSID][toast-activator-clsid] to `id`. If one is not set via this method, it will be randomly generated for the app.
* The value must be a valid GUID/CLSID in one of the following forms:
* Canonical brace-wrapped: `{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}` (preferred)
* Canonical without braces: `XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX` (braces will be added automatically)
* Hex digits are case-insensitive.
This method should be called early (before showing notifications) so the value is baked into the registration/shortcut. Supplying an empty string or an unparsable value throws and leaves the existing (or generated) CLSID unchanged. If this method is never called, a random CLSID is generated once per run and exposed via `app.toastActivatorCLSID`.
### `app.setActivationPolicy(policy)` _macOS_
* `policy` string - Can be 'regular', 'accessory', or 'prohibited'.
@@ -1225,7 +1240,7 @@ Returns `boolean` - whether hardware acceleration is currently enabled.
### `app.disableDomainBlockingFor3DAPIs()`
By default, Chromium disables 3D APIs (e.g. WebGL) until restart on a per
domain basis if the GPU processes crashes too frequently. This function
domain basis if the GPU process crashes too frequently. This function
disables that behavior.
This method can only be called before app is ready.
@@ -1316,7 +1331,7 @@ Returns `boolean` - Whether the current desktop environment is Unity launcher.
### `app.getLoginItemSettings([options])` _macOS_ _Windows_
* `options` Object (optional)
* `type` string (optional) _macOS_ - Can be one of `mainAppService`, `agentService`, `daemonService`, or `loginItemService`. Defaults to `mainAppService`. Only available on macOS 13 and up. See [app.setLoginItemSettings](app.md#appsetloginitemsettingssettings-macos-windows) for more information about each type.
* `type` string (optional) _macOS_ - Can be `mainAppService`, `agentService`, `daemonService`, or `loginItemService`. Defaults to `mainAppService`. Only available on macOS 13 and up. See [app.setLoginItemSettings](app.md#appsetloginitemsettingssettings-macos-windows) for more information about each type.
* `serviceName` string (optional) _macOS_ - The name of the service. Required if `type` is non-default. Only available on macOS 13 and up.
* `path` string (optional) _Windows_ - The executable path to compare against. Defaults to `process.execPath`.
* `args` string[] (optional) _Windows_ - The command-line arguments to compare against. Defaults to an empty array.
@@ -1331,13 +1346,13 @@ Returns `Object`:
* `wasOpenedAtLogin` boolean _macOS_ - `true` if the app was opened at login automatically.
* `wasOpenedAsHidden` boolean _macOS_ _Deprecated_ - `true` if the app was opened as a hidden login item. This indicates that the app should not open any windows at startup. This setting is not available on [MAS builds][mas-builds] or on macOS 13 and up.
* `restoreState` boolean _macOS_ _Deprecated_ - `true` if the app was opened as a login item that should restore the state from the previous session. This indicates that the app should restore the windows that were open the last time the app was closed. This setting is not available on [MAS builds][mas-builds] or on macOS 13 and up.
* `status` string _macOS_ - can be one of `not-registered`, `enabled`, `requires-approval`, or `not-found`.
* `status` string _macOS_ - can be `not-registered`, `enabled`, `requires-approval`, or `not-found`.
* `executableWillLaunchAtLogin` boolean _Windows_ - `true` if app is set to open at login and its run key is not deactivated. This differs from `openAtLogin` as it ignores the `args` option, this property will be true if the given executable would be launched at login with **any** arguments.
* `launchItems` Object[] _Windows_
* `name` string _Windows_ - name value of a registry entry.
* `path` string _Windows_ - The executable to an app that corresponds to a registry entry.
* `args` string[] _Windows_ - the command-line arguments to pass to the executable.
* `scope` string _Windows_ - one of `user` or `machine`. Indicates whether the registry entry is under `HKEY_CURRENT USER` or `HKEY_LOCAL_MACHINE`.
* `scope` string _Windows_ - can be `user` or `machine`. Indicates whether the registry entry is under `HKEY_CURRENT USER` or `HKEY_LOCAL_MACHINE`.
* `enabled` boolean _Windows_ - `true` if the app registry key is startup approved and therefore shows as `enabled` in Task Manager and Windows settings.
### `app.setLoginItemSettings(settings)` _macOS_ _Windows_
@@ -1703,8 +1718,13 @@ platforms) that allows you to perform actions on your app icon in the user's doc
A `boolean` property that returns `true` if the app is packaged, `false` otherwise. For many apps, this property can be used to distinguish development and production environments.
### `app.toastActivatorCLSID` _Windows_ _Readonly_
A `string` property that returns the app's [Toast Activator CLSID][toast-activator-clsid].
[tasks]:https://learn.microsoft.com/en-us/windows/win32/shell/taskbar-extensions#tasks
[app-user-model-id]: https://learn.microsoft.com/en-us/windows/win32/shell/appids
[toast-activator-clsid]: https://learn.microsoft.com/en-us/windows/win32/properties/props-system-appusermodel-toastactivatorclsid
[electron-forge]: https://www.electronforge.io/
[electron-packager]: https://github.com/electron/packager
[CFBundleURLTypes]: https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/TP40009249-102207-TPXREF115

View File

@@ -351,7 +351,11 @@ Emitted when the window has closed a sheet.
#### Event: 'new-window-for-tab' _macOS_
Emitted when the native new tab button is clicked.
Emitted when the user clicks the native macOS new tab button. The new
tab button is only visible if the current `BrowserWindow` has a
`tabbingIdentifier`.
You must create a window in this handler in order for macOS tabbing to work as expected.
#### Event: 'system-context-menu' _Windows_ _Linux_
@@ -1049,7 +1053,7 @@ under this mode apps can choose to optimize their UI for tablets, such as
enlarging the titlebar and hiding titlebar buttons.
This API returns whether the window is in tablet mode, and the `resize` event
can be be used to listen to changes to tablet mode.
can be used to listen to changes to tablet mode.
#### `win.getMediaSourceId()`

View File

@@ -431,7 +431,11 @@ Emitted when the window has closed a sheet.
#### Event: 'new-window-for-tab' _macOS_
Emitted when the native new tab button is clicked.
Emitted when the user clicks the native macOS new tab button. The new
tab button is only visible if the current `BrowserWindow` has a
`tabbingIdentifier`.
You must create a window in this handler in order for macOS tabbing to work as expected.
#### Event: 'system-context-menu' _Windows_ _Linux_
@@ -1140,7 +1144,7 @@ under this mode apps can choose to optimize their UI for tablets, such as
enlarging the titlebar and hiding titlebar buttons.
This API returns whether the window is in tablet mode, and the `resize` event
can be be used to listen to changes to tablet mode.
can be used to listen to changes to tablet mode.
#### `win.getMediaSourceId()`

View File

@@ -264,7 +264,7 @@ will not be allowed. The `finish` event is emitted just after the end operation.
Cancels an ongoing HTTP transaction. If the request has already emitted the
`close` event, the abort operation will have no effect. Otherwise an ongoing
event will emit `abort` and `close` events. Additionally, if there is an ongoing
response object,it will emit the `aborted` event.
response object, it will emit the `aborted` event.
#### `request.followRedirect()`

View File

@@ -5,7 +5,7 @@
Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process) _Deprecated_ (non-sandboxed only)
> [!NOTE]
> Using the `clipoard` API from the renderer process is deprecated.
> Using the `clipboard` API from the renderer process is deprecated.
> [!IMPORTANT]
> If you want to call this API from a renderer process,

View File

@@ -168,7 +168,7 @@ Enables net log events to be saved and writes them to `path`.
Sets the verbosity of logging when used together with `--enable-logging`.
`N` should be one of [Chrome's LogSeverities][severities].
Note that two complimentary logging mechanisms in Chromium -- `LOG()`
Note that two complementary logging mechanisms in Chromium -- `LOG()`
and `VLOG()` -- are controlled by different switches. `--log-level`
controls `LOG()` messages, while `--v` and `--vmodule` control `VLOG()`
messages. So you may want to use a combination of these three switches
@@ -350,6 +350,11 @@ Affects the default output directory of [v8.setHeapSnapshotNearHeapLimit](https:
Disable exposition of [Navigator API][] on the global scope from Node.js.
### `--experimental-transform-types`
Enables the [transformation](https://nodejs.org/api/typescript.html#type-stripping)
of TypeScript-only syntax into JavaScript code.
## Chromium Flags
There isn't a documented list of all Chromium switches, but there are a few ways to find them.
@@ -366,6 +371,13 @@ Keep in mind that standalone switches can sometimes be split into individual fea
Finally, you'll need to ensure that the version of Chromium in Electron matches the version of the browser you're using to cross-reference the switches.
### Chromium features relevant to Electron apps
* `AlwaysLogLOAFURL`: enables script attribution for
[`long-animation-frame`](https://developer.mozilla.org/en-US/docs/Web/API/Performance_API/Long_animation_frame_timing)
`PerformanceObserver` events for non-http(s), non-data, non-blob URLs (such as `file:` or custom
protocol URLs).
[app]: app.md
[append-switch]: command-line.md#commandlineappendswitchswitch-value
[debugging-main-process]: ../tutorial/debugging-main-process.md

View File

@@ -49,7 +49,7 @@ Use the `system-ui` keyword to match the smoothness to the OS design language.
| Value: | `60%` | `0%` |
| Example: | ![A rectangle with round corners whose smoothness matches macOS](../images/corner-smoothing-example-60.svg) | ![A rectangle with round corners whose smoothness matches Windows and Linux](../images/corner-smoothing-example-0.svg) |
### Controlling availibility
### Controlling availability
This CSS rule can be disabled using the Blink feature flag `ElectronCSSCornerSmoothing`.

View File

@@ -94,18 +94,56 @@ The `desktopCapturer` module has the following methods:
Returns `Promise<DesktopCapturerSource[]>` - Resolves with an array of [`DesktopCapturerSource`](structures/desktop-capturer-source.md) objects, each `DesktopCapturerSource` represents a screen or an individual window that can be captured.
> [!NOTE]
> Capturing the screen contents requires user consent on macOS 10.15 Catalina or higher,
> which can detected by [`systemPreferences.getMediaAccessStatus`][].
<!-- markdownlint-disable-next-line MD032 -->
> * Capturing audio requires `NSAudioCaptureUsageDescription` Info.plist key on macOS 14.2 Sonoma and higher - [read more](#macos-versions-142-or-higher).
> * Capturing the screen contents requires user consent on macOS 10.15 Catalina or higher, which can detected by [`systemPreferences.getMediaAccessStatus`][].
[`navigator.mediaDevices.getUserMedia`]: https://developer.mozilla.org/en/docs/Web/API/MediaDevices/getUserMedia
[`systemPreferences.getMediaAccessStatus`]: system-preferences.md#systempreferencesgetmediaaccessstatusmediatype-windows-macos
## Caveats
### Linux
`desktopCapturer.getSources(options)` only returns a single source on Linux when using Pipewire.
PipeWire supports a single capture for both screens and windows. If you request the window and screen type, the selected source will be returned as a window capture.
`navigator.mediaDevices.getUserMedia` does not work on macOS for audio capture due to a fundamental limitation whereby apps that want to access the system's audio require a [signed kernel extension](https://developer.apple.com/library/archive/documentation/Security/Conceptual/System_Integrity_Protection_Guide/KernelExtensions/KernelExtensions.html). Chromium, and by extension Electron, does not provide this.
### macOS versions 14.2 or higher
It is possible to circumvent this limitation by capturing system audio with another macOS app like Soundflower and passing it through a virtual audio input device. This virtual device can then be queried with `navigator.mediaDevices.getUserMedia`.
`NSAudioCaptureUsageDescription` Info.plist key must be added in order for audio to be captured by
`desktopCapturer`. If instead you are running Electron from another program like a terminal or IDE
then that parent program must contain the Info.plist key.
This is in order to facillitate use of Apple's new [CoreAudio Tap API](https://developer.apple.com/documentation/CoreAudio/capturing-system-audio-with-core-audio-taps#Configure-the-sample-code-project) by Chromium.
> [!WARNING]
> Failure of `desktopCapturer` to start an audio stream due to `NSAudioCaptureUsageDescription`
> permission not present will still create a dead audio stream however no warnings or errors are
> displayed.
As of Electron `v39.0.0-beta.4`, Chromium [made Apple's new `CoreAudio Tap API` the default](https://source.chromium.org/chromium/chromium/src/+/ad17e8f8b93d5f34891b06085d373a668918255e)
for desktop audio capture. There is no fallback to the older `Screen & System Audio Recording`
permissions system even if [CoreAudio Tap API](https://developer.apple.com/documentation/CoreAudio/capturing-system-audio-with-core-audio-taps) stream creation fails.
If you need to continue using `Screen & System Audio Recording` permissions for `desktopCapturer`
on macOS versions 14.2 and later, you can apply a Chromium feature flag to force use of that older
permissions system:
```js
// main.js (right beneath your require/import statments)
app.commandLine.appendSwitch('disable-features', 'MacCatapLoopbackAudioForScreenShare')
```
### macOS versions 12.7.6 or lower
`navigator.mediaDevices.getUserMedia` does not work on macOS versions 12.7.6 and prior for audio
capture due to a fundamental limitation whereby apps that want to access the system's audio require
a [signed kernel extension](https://developer.apple.com/library/archive/documentation/Security/Conceptual/System_Integrity_Protection_Guide/KernelExtensions/KernelExtensions.html).
Chromium, and by extension Electron, does not provide this. Only in macOS 13 and onwards does Apple
provide APIs to capture desktop audio without the need for a signed kernel extension.
It is possible to circumvent this limitation by capturing system audio with another macOS app like
[BlackHole](https://existential.audio/blackhole/) or [Soundflower](https://rogueamoeba.com/freebies/soundflower/)
and passing it through a virtual audio input device. This virtual device can then be queried
with `navigator.mediaDevices.getUserMedia`.

View File

@@ -344,7 +344,7 @@ Displays a modal dialog that shows an error message.
This API can be called safely before the `ready` event the `app` module emits,
it is usually used to report errors in early stage of startup. If called
before the app `ready`event on Linux, the message will be emitted to stderr,
before the app `ready` event on Linux, the message will be emitted to stderr,
and no GUI dialog will appear.
### `dialog.showCertificateTrustDialog([window, ]options)` _macOS_ _Windows_

View File

@@ -34,7 +34,7 @@ Returns:
* `error` Error - Typically holds an error string identifying failure root cause.
Emitted when an error was encountered while streaming response data events. For
instance, if the server closes the underlying while the response is still
instance, if the server closes the underlying connection while the response is still
streaming, an `error` event will be emitted on the response object and a `close`
event will subsequently follow on the request object.

View File

@@ -73,13 +73,16 @@ The following properties are available on instances of `MenuItem`:
#### `menuItem.id`
A `string` indicating the item's unique id. This property can be
dynamically changed.
A `string` indicating the item's unique id.
This property can be dynamically changed.
#### `menuItem.label`
A `string` indicating the item's visible label.
This property can be dynamically changed.
#### `menuItem.click`
A `Function` that is fired when the MenuItem receives a click event.
@@ -107,7 +110,7 @@ A `string` (optional) indicating the item's role, if set. Can be `undo`, `redo`,
#### `menuItem.accelerator`
An `Accelerator` (optional) indicating the item's accelerator, if set.
An `Accelerator | null` indicating the item's accelerator, if set.
#### `menuItem.userAccelerator` _Readonly_ _macOS_
@@ -118,31 +121,37 @@ An `Accelerator | null` indicating the item's [user-assigned accelerator](https:
#### `menuItem.icon`
A `NativeImage | string` (optional) indicating the
item's icon, if set.
A `NativeImage | string` (optional) indicating the item's icon, if set.
This property can be dynamically changed.
#### `menuItem.sublabel`
A `string` indicating the item's sublabel.
This property can be dynamically changed.
#### `menuItem.toolTip` _macOS_
A `string` indicating the item's hover text.
#### `menuItem.enabled`
A `boolean` indicating whether the item is enabled. This property can be
dynamically changed.
A `boolean` indicating whether the item is enabled.
This property can be dynamically changed.
#### `menuItem.visible`
A `boolean` indicating whether the item is visible. This property can be
dynamically changed.
A `boolean` indicating whether the item is visible.
This property can be dynamically changed.
#### `menuItem.checked`
A `boolean` indicating whether the item is checked. This property can be
dynamically changed.
A `boolean` indicating whether the item is checked.
This property can be dynamically changed.
A `checkbox` menu item will toggle the `checked` property on and off when
selected.

View File

@@ -34,7 +34,7 @@ indicate which letter should get a generated accelerator. For example, using
opens the associated menu. The indicated character in the button label then gets an
underline, and the `&` character is not displayed on the button label.
In order to escape the `&` character in an item name, add a proceeding `&`. For example, `&&File` would result in `&File` displayed on the button label.
In order to escape the `&` character in an item name, add a preceding `&`. For example, `&&File` would result in `&File` displayed on the button label.
Passing `null` will suppress the default menu. On Windows and Linux,
this has the additional effect of removing the menu bar from the window.

View File

@@ -83,4 +83,4 @@ Currently, Windows high contrast is the only system setting that triggers forced
### `nativeTheme.prefersReducedTransparency` _Readonly_
A `boolean` that indicates the whether the user has chosen via system accessibility settings to reduce transparency at the OS level.
A `boolean` that indicates whether the user has chosen via system accessibility settings to reduce transparency at the OS level.

View File

@@ -67,6 +67,22 @@ Emitted when the notification is shown to the user. Note that this event can be
multiple times as a notification can be shown multiple times through the
`show()` method.
```js
const { Notification, app } = require('electron')
app.whenReady().then(() => {
const n = new Notification({
title: 'Title!',
subtitle: 'Subtitle!',
body: 'Body!'
})
n.on('show', () => console.log('Notification shown!'))
n.show()
})
```
#### Event: 'click'
Returns:
@@ -75,11 +91,28 @@ Returns:
Emitted when the notification is clicked by the user.
```js
const { Notification, app } = require('electron')
app.whenReady().then(() => {
const n = new Notification({
title: 'Title!',
subtitle: 'Subtitle!',
body: 'Body!'
})
n.on('click', () => console.log('Notification clicked!'))
n.show()
})
```
#### Event: 'close'
Returns:
* `event` Event
* `details` Event\<\>
* `reason` _Windows_ string (optional) - The reason the notification was closed. This can be 'userCanceled', 'applicationHidden', or 'timedOut'.
Emitted when the notification is closed by manual intervention from the user.
@@ -88,21 +121,85 @@ is closed.
On Windows, the `close` event can be emitted in one of three ways: programmatic dismissal with `notification.close()`, by the user closing the notification, or via system timeout. If a notification is in the Action Center after the initial `close` event is emitted, a call to `notification.close()` will remove the notification from the action center but the `close` event will not be emitted again.
#### Event: 'reply' _macOS_
```js
const { Notification, app } = require('electron')
app.whenReady().then(() => {
const n = new Notification({
title: 'Title!',
subtitle: 'Subtitle!',
body: 'Body!'
})
n.on('close', () => console.log('Notification closed!'))
n.show()
})
```
#### Event: 'reply' _macOS_ _Windows_
Returns:
* `event` Event
* `reply` string - The string the user entered into the inline reply field.
* `details` Event\<\>
* `reply` string - The string the user entered into the inline reply field.
* `reply` string _Deprecated_
Emitted when the user clicks the "Reply" button on a notification with `hasReply: true`.
#### Event: 'action' _macOS_
```js
const { Notification, app } = require('electron')
app.whenReady().then(() => {
const n = new Notification({
title: 'Send a Message',
body: 'Body Text',
hasReply: true,
replyPlaceholder: 'Message text...'
})
n.on('reply', (e, reply) => console.log(`User replied: ${reply}`))
n.on('click', () => console.log('Notification clicked'))
n.show()
})
```
#### Event: 'action' _macOS_ _Windows_
Returns:
* `event` Event
* `index` number - The index of the action that was activated.
* `details` Event\<\>
* `actionIndex` number - The index of the action that was activated.
* `selectionIndex` number _Windows_ - The index of the selected item, if one was chosen. -1 if none was chosen.
* `actionIndex` number _Deprecated_
* `selectionIndex` number _Windows_ _Deprecated_
```js
const { Notification, app } = require('electron')
app.whenReady().then(() => {
const items = ['One', 'Two', 'Three']
const n = new Notification({
title: 'Choose an Action!',
actions: [
{ type: 'button', text: 'Action 1' },
{ type: 'button', text: 'Action 2' },
{ type: 'selection', text: 'Apply', items }
]
})
n.on('click', () => console.log('Notification clicked'))
n.on('action', (e) => {
console.log(`User triggered action at index: ${e.actionIndex}`)
if (e.selectionIndex > -1) {
console.log(`User chose selection item '${items[e.selectionIndex]}'`)
}
})
n.show()
})
```
#### Event: 'failed' _Windows_
@@ -113,6 +210,22 @@ Returns:
Emitted when an error is encountered while creating and showing the native notification.
```js
const { Notification, app } = require('electron')
app.whenReady().then(() => {
const n = new Notification({
title: 'Bad Action'
})
n.on('failed', (e, err) => {
console.log('Notification failed: ', err)
})
n.show()
})
```
### Instance Methods
Objects created with the `new Notification()` constructor have the following instance methods:
@@ -126,12 +239,42 @@ call this method before the OS will display it.
If the notification has been shown before, this method will dismiss the previously
shown notification and create a new one with identical properties.
```js
const { Notification, app } = require('electron')
app.whenReady().then(() => {
const n = new Notification({
title: 'Title!',
subtitle: 'Subtitle!',
body: 'Body!'
})
n.show()
})
```
#### `notification.close()`
Dismisses the notification.
On Windows, calling `notification.close()` while the notification is visible on screen will dismiss the notification and remove it from the Action Center. If `notification.close()` is called after the notification is no longer visible on screen, calling `notification.close()` will try remove it from the Action Center.
```js
const { Notification, app } = require('electron')
app.whenReady().then(() => {
const n = new Notification({
title: 'Title!',
subtitle: 'Subtitle!',
body: 'Body!'
})
n.show()
setTimeout(() => n.close(), 5000)
})
```
### Instance Properties
#### `notification.title`

View File

@@ -99,13 +99,13 @@ property is used instead of the `--throw-deprecation` command line flag.
A `boolean` that controls whether or not deprecations printed to `stderr` include
their stack trace. Setting this to `true` will print stack traces for deprecations.
This property is instead of the `--trace-deprecation` command line flag.
This property is used instead of the `--trace-deprecation` command line flag.
### `process.traceProcessWarnings`
A `boolean` that controls whether or not process warnings printed to `stderr` include
their stack trace. Setting this to `true` will print stack traces for process warnings
(including deprecations). This property is instead of the `--trace-warnings` command
(including deprecations). This property is used instead of the `--trace-warnings` command
line flag.
### `process.type` _Readonly_

View File

@@ -110,6 +110,8 @@ Returns [`Point`](structures/point.md)
The current absolute position of the mouse pointer.
Not supported on Wayland (Linux).
> [!NOTE]
> The return value is a DIP point, not a screen physical point.

View File

@@ -1216,7 +1216,7 @@ function createWindow () {
mainWindow.webContents.session.setBluetoothPairingHandler((details, callback) => {
bluetoothPinCallback = callback
// Send a IPC message to the renderer to prompt the user to confirm the pairing.
// Send an IPC message to the renderer to prompt the user to confirm the pairing.
// Note that this will require logic in the renderer to handle this message and
// display a prompt to the user.
mainWindow.webContents.send('bluetooth-pairing-request', details)
@@ -1264,7 +1264,7 @@ session.defaultSession.allowNTLMCredentialsForDomains('*')
Overrides the `userAgent` and `acceptLanguages` for this session.
The `acceptLanguages` must a comma separated ordered list of language codes, for
The `acceptLanguages` must be a comma separated ordered list of language codes, for
example `"en-US,fr,de,ko,zh-CN,ja"`.
This doesn't affect existing `WebContents`, and each `WebContents` can use

View File

@@ -1,6 +1,6 @@
# sharedTexture
> Import shared textures into Electron and converts platform specific handles into [`VideoFrame`](https://developer.mozilla.org/en-US/docs/Web/API/VideoFrame). Supports all Web rendering systems, and can be transferred across Electron processes. Read [here](https://github.com/electron/electron/blob/main/shell/common/api/shared_texture/README.md) for more information.
> Import shared textures into Electron and converts platform specific handles into [`VideoFrame`](https://developer.mozilla.org/en-US/docs/Web/API/VideoFrame). Supports all Web rendering systems, and can be transferred across Electron processes. Read [here](../../shell/common/api/shared_texture/README.md) for more information.
Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process)

View File

@@ -7,7 +7,7 @@
* `depthPerComponent` number - The number of bits per color component.
* `detected` boolean - `true` if the display is detected by the system.
* `displayFrequency` number - The display refresh rate.
* `id` number - Unique identifier associated with the display. A value of of -1 means the display is invalid or the correct `id` is not yet known, and a value of -10 means the display is a virtual display assigned to a unified desktop.
* `id` number - Unique identifier associated with the display. A value of -1 means the display is invalid or the correct `id` is not yet known, and a value of -10 means the display is a virtual display assigned to a unified desktop.
* `internal` boolean - `true` for an internal display and `false` for an external display.
* `label` string - User-friendly label, determined by the platform.
* `maximumCursorSize` [Size](size.md) - Maximum cursor size in native pixels.

View File

@@ -1,13 +1,15 @@
# NotificationAction Object
* `type` string - The type of action, can be `button`.
* `type` string - The type of action, can be `button` or `selection`. `selection` is only supported on Windows.
* `text` string (optional) - The label for the given action.
* `items` string[] (optional) _Windows_ - The list of items for the `selection` action `type`.
## Platform / Action Support
| Action Type | Platform Support | Usage of `text` | Default `text` | Limitations |
|-------------|------------------|-----------------|----------------|-------------|
| `button` | macOS | Used as the label for the button | "Show" (or a localized string by system default if first of such `button`, otherwise empty) | Only the first one is used. If multiple are provided, those beyond the first will be listed as additional actions (displayed when mouse active over the action button). Any such action also is incompatible with `hasReply` and will be ignored if `hasReply` is `true`. |
| `button` | macOS, Windows | Used as the label for the button | "Show" on macOS (localized) if first `button`, otherwise empty; Windows uses provided `text` | macOS: Only the first one is used as primary; others shown as additional actions (hover). Incompatible with `hasReply` (beyond first ignored). |
| `selection` | Windows | Used as the label for the submit button for the selection menu | "Select" | Requires an `items` array property specifying option labels. Emits the `action` event with `(index, selectedIndex)` where `selectedIndex` is the chosen option (>= 0). Ignored on platforms that do not support selection actions. |
### Button support on macOS
@@ -15,6 +17,37 @@ In order for extra notification buttons to work on macOS your app must meet the
following criteria.
* App is signed
* App has it's `NSUserNotificationAlertStyle` set to `alert` in the `Info.plist`.
* App has its `NSUserNotificationAlertStyle` set to `alert` in the `Info.plist`.
If either of these requirements are not met the button won't appear.
### Selection support on Windows
To add a selection (combo box) style action, include an action with `type: 'selection'`, a `text` label for the submit button, and an `items` array of strings:
```js
const { Notification, app } = require('electron')
app.whenReady().then(() => {
const items = ['One', 'Two', 'Three']
const n = new Notification({
title: 'Choose an option',
actions: [{
type: 'selection',
text: 'Apply',
items
}]
})
n.on('action', (e) => {
console.log(`User triggered action at index: ${e.actionIndex}`)
if (e.selectionIndex > 0) {
console.log(`User chose selection item '${items[e.selectionIndex]}'`)
}
})
n.show()
})
```
When the user activates the selection action, the notification's `action` event will be emitted with two parameters: `actionIndex` (the action's index in the `actions` array) and `selectedIndex` (the zero-based index of the chosen item, or `-1` if unavailable). On non-Windows platforms selection actions are ignored.

View File

@@ -40,7 +40,7 @@
* `javascript` boolean (optional) - Enables JavaScript support. Default is `true`.
* `webSecurity` boolean (optional) - When `false`, it will disable the
same-origin policy (usually using testing websites by people), and set
`allowRunningInsecureContent` to `true` if this options has not been set
`allowRunningInsecureContent` to `true` if this option has not been set
by user. Default is `true`.
* `allowRunningInsecureContent` boolean (optional) - Allow an https page to run
JavaScript, CSS or plugins from http URLs. Default is `false`.
@@ -94,6 +94,7 @@
The actual output pixel format and color space of the texture should refer to [`OffscreenSharedTexture`](../structures/offscreen-shared-texture.md) object in the `paint` event.
* `argb` - The requested output texture format is 8-bit unorm RGBA, with SRGB SDR color space.
* `rgbaf16` - The requested output texture format is 16-bit float RGBA, with scRGB HDR color space.
* `deviceScaleFactor` number (optional) _Experimental_ - The device scale factor of the offscreen rendering output. If not set, will use primary display's scale factor as default.
* `contextIsolation` boolean (optional) - Whether to run Electron APIs and
the specified `preload` script in a separate JavaScript context. Defaults
to `true`. The context that the `preload` script runs in will only have
@@ -156,6 +157,8 @@
`WebContents` when the preferred size changes. Default is `false`.
* `transparent` boolean (optional) - Whether to enable background transparency for the guest page. Default is `true`. **Note:** The guest page's text and background colors are derived from the [color scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/color-scheme) of its root element. When transparency is enabled, the text color will still change accordingly but the background will remain transparent.
* `enableDeprecatedPaste` boolean (optional) _Deprecated_ - Whether to enable the `paste` [execCommand](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand). Default is `false`.
* `focusOnNavigation` boolean (optional) - Whether to focus the WebContents
when navigating. Default is `true`.
[chrome-content-scripts]: https://developer.chrome.com/extensions/content_scripts#execution-environment
[runtime-enabled-features]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/runtime_enabled_features.json5

View File

@@ -36,6 +36,12 @@ Process: [Main](../glossary.md#main-process)<br />
`com.apple.security.cs.allow-unsigned-executable-memory` entitlements. This will allow the utility process
to load unsigned libraries. Unless you specifically need this capability, it is best to leave this disabled.
Default is `false`.
* `disclaim` boolean (optional) _macOS_ - With this flag, the utility process will disclaim
responsibility for the child process. This causes the operating system to consider the child
process as a separate entity for purposes of security policies like Transparency, Consent, and
Control (TCC). When responsibility is disclaimed, the parent process will not be attributed
for any TCC requests initiated by the child process. This is useful when launching processes
that run third-party or otherwise untrusted code. Default is `false`.
* `respondToAuthRequestsFromMainProcess` boolean (optional) - With this flag, all HTTP 401 and 407 network
requests created via the [net module](net.md) will allow responding to them via the
[`app#login`](app.md#event-login) event in the main process instead of the default

View File

@@ -383,7 +383,7 @@ Emitted after a server side redirect occurs during navigation. For example a 30
redirect.
This event cannot be prevented, if you want to prevent redirects you should
checkout out the `will-redirect` event above.
check out the `will-redirect` event above.
#### Event: 'did-navigate'
@@ -933,7 +933,7 @@ copying data between CPU and GPU memory, with Chromium's hardware acceleration s
Only a limited number of textures can exist at the same time, so it's important that you call `texture.release()` as soon as you're done with the texture.
By managing the texture lifecycle by yourself, you can safely pass the `texture.textureInfo` to other processes through IPC.
More details can be found in the [offscreen rendering tutorial](../tutorial/offscreen-rendering.md). To learn about how to handle the texture in native code, refer to [offscreen rendering's code documentation.](https://github.com/electron/electron/blob/main/shell/browser/osr/README.md).
More details can be found in the [offscreen rendering tutorial](../tutorial/offscreen-rendering.md). To learn about how to handle the texture in native code, refer to [offscreen rendering's code documentation.](../../shell/browser/osr/README.md).
```js
const { BrowserWindow } = require('electron')
@@ -1465,7 +1465,7 @@ Ignore application menu shortcuts while this web contents is focused.
without a recognized 'action' value will result in a console error and have
the same effect as returning `{action: 'deny'}`.
Called before creating a window a new window is requested by the renderer, e.g.
Called before creating a window when a new window is requested by the renderer, e.g.
by `window.open()`, a link with `target="_blank"`, shift+clicking on a link, or
submitting a form with `<form target="_blank">`. See
[`window.open()`](window-open.md) for more details and how to use this in
@@ -2168,7 +2168,7 @@ Returns `boolean` - If _offscreen rendering_ is enabled returns whether it is cu
* `fps` Integer
If _offscreen rendering_ is enabled sets the frame rate to the specified number.
Only values between 1 and 240 are accepted.
When `webPreferences.offscreen.useSharedTexture` is `false` only values between 1 and 240 are accepted.
#### `contents.getFrameRate()`
@@ -2369,7 +2369,7 @@ instance that might own this `WebContents`.
#### `contents.devToolsWebContents` _Readonly_
A `WebContents | null` property that represents the of DevTools `WebContents` associated with a given `WebContents`.
A `WebContents | null` property that represents the DevTools `WebContents` associated with a given `WebContents`.
> [!NOTE]
> Users should never store this object because it may become `null`

View File

@@ -50,6 +50,22 @@ webContents.setWindowOpenHandler((details) => {
})
```
### Behavior Changed: `NSAudioCaptureUsageDescription` should be included in your app's Info.plist file to use `desktopCapturer` (🍏 macOS ≥14.2)
Per [Chromium update](https://source.chromium.org/chromium/chromium/src/+/ad17e8f8b93d5f34891b06085d373a668918255e) which enables Apple's newer [CoreAudio Tap API](https://developer.apple.com/documentation/CoreAudio/capturing-system-audio-with-core-audio-taps#Configure-the-sample-code-project) by default, you now must have `NSAudioCaptureUsageDescription` defined in your `Info.plist` to use `desktopCapturer`.
Electron's `desktopCapturer` will create a dead audio stream if the new permission is absent however no errors or warnings will occur. This is partially a side-effect of Chromium not falling back to the older `Screen & System Audio Recording` permissions system if the new system fails.
To restore previous behavior:
```js
// main.js (right beneath your require/import statments)
app.commandLine.appendSwitch(
'disable-features',
'MacCatapLoopbackAudioForScreenShare'
)
```
### Behavior Changed: shared texture OSR `paint` event data structure
When using shared texture offscreen rendering feature, the `paint` event now emits a more structured object.
@@ -68,7 +84,7 @@ Users can force XWayland by passing `--ozone-platform=x11`.
### Removed: `ORIGINAL_XDG_CURRENT_DESKTOP` environment variable
Previously, Electron changed the value of `XDG_CURRENT_DESKTOP` internally to `Unity`, and stored the original name of the desktop session
in a separate variable. `XDG_CURRENT_DESKTOP` is no longer overriden and now reflects the actual desktop environment.
in a separate variable. `XDG_CURRENT_DESKTOP` is no longer overridden and now reflects the actual desktop environment.
### Removed: macOS 11 support
@@ -149,7 +165,7 @@ window is not currently visible.
`app.commandLine` was only meant to handle chromium switches (which aren't case-sensitive) and switches passed via `app.commandLine` will not be passed down to any of the child processes.
If you were using `app.commandLine` to control the behavior of the main process, you should do this via `process.argv`.
If you were using `app.commandLine` to control the behavior of the main process, you should do this via `process.argv`.
### Deprecated: `NativeImage.getBitmap()`
@@ -179,7 +195,7 @@ from upstream Chromium.
### Deprecated: `null` value for `session` property in `ProtocolResponse`
Previously, setting the ProtocolResponse.session property to `null`
Would create a random independent session. This is no longer supported.
would create a random independent session. This is no longer supported.
Using single-purpose sessions here is discouraged due to overhead costs;
however, old code that needs to preserve this behavior can emulate it by
@@ -190,7 +206,7 @@ and then using it in `ProtocolResponse.session`.
When calling `Session.clearStorageData(options)`, the `options.quota`
property is deprecated. Since the `syncable` type was removed, there
is only type left -- `'temporary'` -- so specifying it is unnecessary.
is only one type left -- `'temporary'` -- so specifying it is unnecessary.
### Deprecated: Extension methods and events on `session`
@@ -519,7 +535,7 @@ more information.
### Removed: The `--disable-color-correct-rendering` switch
This switch was never formally documented but it's removal is being noted here regardless. Chromium itself now has better support for color spaces so this flag should not be needed.
This switch was never formally documented but its removal is being noted here regardless. Chromium itself now has better support for color spaces so this flag should not be needed.
### Behavior Changed: `BrowserView.setAutoResize` behavior on macOS
@@ -1210,7 +1226,7 @@ more details.
### API Changed: `webContents.printToPDF()`
`webContents.printToPDF()` has been modified to conform to [`Page.printToPDF`](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-printToPDF) in the Chrome DevTools Protocol. This has been changes in order to
`webContents.printToPDF()` has been modified to conform to [`Page.printToPDF`](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-printToPDF) in the Chrome DevTools Protocol. This has been changed in order to
address changes upstream that made our previous implementation untenable and rife with bugs.
**Arguments Changed**

View File

@@ -41,7 +41,7 @@ e init --root=~/electron --bootstrap testing
```
The `--bootstrap` flag also runs `e sync` (synchronizes source code branches from
[`DEPS`](https://github.com/electron/electron/blob/main/DEPS) using
[`DEPS`](../../DEPS) using
[`gclient`](https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/HEAD/README.gclient.md))
and `e build` (compiles the Electron binary into the `${root}/src/out` folder).
@@ -63,7 +63,7 @@ Some quick tips on building once your checkout is set up:
* **Updating your checkout:** Run git commands such as `git checkout <branch>` and `git pull` from `${root}/src/electron`.
Whenever you update your commit `HEAD`, make sure to `e sync` before `e build` to sync dependencies
such as Chromium and Node.js. This is especially relevant because the Chromium version in
[`DEPS`](https://github.com/electron/electron/blob/main/DEPS) changes frequently.
[`DEPS`](../../DEPS) changes frequently.
* **Rebuilding:** When making changes to code in `${root}/src/electron/` in a local branch, you only need to re-run `e build`.
* **Adding patches:** When contributing changes in `${root}/src/` outside of `${root}/src/electron/`, you need to do so
via Electron's [patch system](./patches.md). The `e patches` command can export all relevant patches to
@@ -98,7 +98,7 @@ Project configurations can be found in the `.gn` and `.gni` files in the `electr
The following `gn` files contain the main rules for building Electron:
* [`BUILD.gn`](https://github.com/electron/electron/blob/main/BUILD.gn) defines how Electron itself
* [`BUILD.gn`](../../BUILD.gn) defines how Electron itself
is built and includes the default configurations for linking with Chromium.
* [`build/args/{testing,release,all}.gn`](https://github.com/electron/electron/tree/main/build/args)
contain the default build arguments for building Electron.

View File

@@ -40,7 +40,7 @@ If you are on arm64 architecture, the build script may be pointing to the wrong
### Certificates fail to verify
installing [`certifi`](https://pypi.org/project/certifi/) will fix the following error:
Installing [`certifi`](https://pypi.org/project/certifi/) will fix the following error:
```sh
________ running 'python3 src/tools/clang/scripts/update.py' in '/Users/<user>/electron'

View File

@@ -6,7 +6,7 @@ This is not a comprehensive end-all guide to creating an Electron Browser API, r
## Add your files to Electron's project configuration
Electron uses [GN](https://gn.googlesource.com/gn) as a meta build system to generate files for its compiler, [Ninja](https://ninja-build.org/). This means that in order to tell Electron to compile your code, we have to add your API's code and header file names into [`filenames.gni`](https://github.com/electron/electron/blob/main/filenames.gni).
Electron uses [GN](https://gn.googlesource.com/gn) as a meta build system to generate files for its compiler, [Ninja](https://ninja-build.org/). This means that in order to tell Electron to compile your code, we have to add your API's code and header file names into [`filenames.gni`](../../filenames.gni).
You will need to append your API file names alphabetically into the appropriate files like so:
@@ -127,7 +127,7 @@ void Initialize(v8::Local<v8::Object> exports,
## Link your Electron API with Node
In the [`typings/internal-ambient.d.ts`](https://github.com/electron/electron/blob/main/typings/internal-ambient.d.ts) file, we need to append a new property onto the `Process` interface like so:
In the [`typings/internal-ambient.d.ts`](../../typings/internal-ambient.d.ts) file, we need to append a new property onto the `Process` interface like so:
```ts title='typings/internal-ambient.d.ts' @ts-nocheck
interface Process {
@@ -141,7 +141,7 @@ At the very bottom of your `api_name.cc` file:
NODE_LINKED_BINDING_CONTEXT_AWARE(electron_browser_{api_name},Initialize)
```
In your [`shell/common/node_bindings.cc`](https://github.com/electron/electron/blob/main/shell/common/node_bindings.cc) file, add your node binding name to Electron's built-in modules.
In your [`shell/common/node_bindings.cc`](../../shell/common/node_bindings.cc) file, add your node binding name to Electron's built-in modules.
```cpp title='shell/common/node_bindings.cc'
#define ELECTRON_BROWSER_MODULES(V) \
@@ -159,7 +159,7 @@ We will need to create a new TypeScript file in the path that follows:
`"lib/browser/api/{electron_browser_{api_name}}.ts"`
An example of the contents of this file can be found [here](https://github.com/electron/electron/blob/main/lib/browser/api/native-theme.ts).
An example of the contents of this file can be found [here](../../lib/browser/api/native-theme.ts).
### Expose your module to TypeScript

View File

@@ -28,7 +28,7 @@ with breakpoints inside Electron's source code.
format.
* **ProcMon**: The [free SysInternals tool][sys-internals] allows you to inspect
a processes parameters, file handles, and registry operations.
a process's parameters, file handles, and registry operations.
## Attaching to and Debugging Electron

View File

@@ -185,7 +185,7 @@ $ git push origin my-branch
### Step 9: Opening the Pull Request
From within GitHub, opening a new pull request will present you with a template
that should be filled out. It can be found [here](https://github.com/electron/electron/blob/main/.github/PULL_REQUEST_TEMPLATE.md).
that should be filled out. It can be found [here](../../.github/PULL_REQUEST_TEMPLATE.md).
If you do not adequately complete this template, your PR may be delayed in being merged as maintainers
seek more information or clarify ambiguities.
@@ -218,8 +218,7 @@ seem unfamiliar, refer to this
#### Approval and Request Changes Workflow
All pull requests require approval from a
[Code Owner](https://github.com/electron/electron/blob/main/.github/CODEOWNERS)
All pull requests require approval from a [Code Owner](../../.github/CODEOWNERS)
of the area you modified in order to land. Whenever a maintainer reviews a pull
request they may request changes. These may be small, such as fixing a typo, or
may involve substantive changes. Such requests are intended to be helpful, but

View File

@@ -10,11 +10,11 @@ to understand the source code better.
## Project structure
Electron is a complex project containing multiple upstream dependencies, which are tracked in source
control via the [`DEPS`](https://github.com/electron/electron/blob/main/DEPS) file. When
control via the [`DEPS`](../../DEPS) file. When
[initializing a local Electron checkout](./build-instructions-gn.md), Electron's source code is just one
of many nested folders within the project root.
The project contains a single `src` folder that corresponds a specific git checkout of
The project contains a single `src` folder that corresponds to a specific git checkout of
[Chromium's `src` folder](https://source.chromium.org/chromium/chromium/src). In addition, Electron's
repository code is contained in `src/electron` (with its own nested git repository), and other
Electron-specific third-party dependencies (e.g. [nan](https://github.com/nodejs/nan) or

View File

@@ -17,7 +17,7 @@ style, run `npm run lint`, which will run a variety of linting checks
against your changes depending on which areas of the code they touch.
Many of these checks are included as precommit hooks, so it's likely
you error would be caught at commit time.
your error would be caught at commit time.
## Unit Tests

View File

@@ -14,7 +14,7 @@ dependency tree from `node_modules`).
### ASAR integrity
ASAR integrity is an security feature that validates the contents of your app's
ASAR integrity is a security feature that validates the contents of your app's
ASAR archives at runtime. When enabled, your Electron app will verify the
header hash of its ASAR archive on runtime. If no hash is present or if there is a mismatch in the
hashes, the app will forcefully terminate.
@@ -137,9 +137,9 @@ See also: [code signing](#code-signing)
### OSR
OSR (offscreen rendering) can be used for loading heavy page in
OSR (offscreen rendering) can be used for loading a heavy page in
background and then displaying it after (it will be much faster).
It allows you to render page without showing it on screen.
It allows you to render a page without showing it on screen.
For more information, read the [Offscreen Rendering][] tutorial.

View File

@@ -6,7 +6,7 @@ hide_title: false
---
After creating an [application distribution](application-distribution.md), the
app's source code are usually bundled into an [ASAR archive](https://github.com/electron/asar),
app's source code is usually bundled into an [ASAR archive](https://github.com/electron/asar),
which is a simple extensive archive format designed for Electron apps. By bundling the app
we can mitigate issues around long path names on Windows, speed up `require` and conceal your source
code from cursory inspection.
@@ -134,7 +134,7 @@ underlying system calls, Electron will extract the needed file into a
temporary file and pass the path of the temporary file to the APIs to make them
work. This adds a little overhead for those APIs.
APIs that requires extra unpacking are:
APIs that require extra unpacking are:
* `child_process.execFile`
* `child_process.execFileSync`

View File

@@ -15,6 +15,14 @@ Currently, ASAR integrity checking is supported on:
* macOS as of `electron>=16.0.0`
* Windows as of `electron>=30.0.0`
> [!NOTE]
> ASAR integrity is fully supported in Mac App Store (MAS) builds and is recommended
> as a best practice. While MAS-installed applications have their `Resources/` folder
> protected by the system (owned by root), ASAR integrity still provides an additional
> layer of security. It is especially important if you use Electron's MAS build but
> distribute your app through channels other than the Mac App Store (such as direct
> download), since those installations won't have the system-level read-only protections.
In order to enable ASAR integrity checking, you also need to ensure that your `app.asar` file
was generated by a version of the `@electron/asar` npm package that supports ASAR integrity.
@@ -24,7 +32,7 @@ All versions of `@electron/asar` support ASAR integrity.
## How it works
Each ASAR archive contains a JSON string header. The header format includes an `integrity` object
that contain a hex encoded hash of the entire archive as well as an array of hex encoded hashes for each
that contains a hex encoded hash of the entire archive as well as an array of hex encoded hashes for each
block of `blockSize` bytes.
```json

View File

@@ -203,7 +203,7 @@ test('launch app', async () => {
})
```
After that, you will access to an instance of Playwright's `ElectronApp` class. This
After that, you will have access to an instance of Playwright's `ElectronApp` class. This
is a powerful class that has access to main process modules for example:
```js {5-10} @ts-nocheck
@@ -237,7 +237,7 @@ test('save screenshot', async () => {
})
```
Putting all this together using the Playwright test-runner, let's create a `example.spec.js`
Putting all this together using the Playwright test-runner, let's create an `example.spec.js`
test file with a single test and assertion:
```js title='example.spec.js' @ts-nocheck
@@ -377,7 +377,7 @@ class TestDriver {
module.exports = { TestDriver }
```
In your app code, can then write a simple handler to receive RPC calls:
In your app code, you can then write a simple handler to receive RPC calls:
```js title='main.js'
const METHODS = {

View File

@@ -17,7 +17,7 @@ run them, users need to go through multiple advanced and manual steps.
If you are building an Electron app that you intend to package and distribute,
it should be code signed. The Electron ecosystem tooling makes codesigning your
apps straightforward - this documentation explains how sign your apps on both
apps straightforward - this documentation explains how to sign your apps on both
Windows and macOS.
## Signing & notarizing macOS builds
@@ -210,7 +210,7 @@ const msiCreator = new MSICreator({
const supportBinaries = await msiCreator.create()
// 🆕 Step 2a: optionally sign support binaries if you
// sign you binaries as part of of your packaging script
// sign your binaries as part of your packaging script
for (const binary of supportBinaries) {
// Binaries are the new stub executable and optionally
// the Squirrel auto updater.

View File

@@ -110,7 +110,7 @@ const win = new BrowserWindow({
#### Show and hide the traffic lights programmatically _macOS_
You can also show and hide the traffic lights programmatically from the main process.
The `win.setWindowButtonVisibility` forces traffic lights to be show or hidden depending
The `win.setWindowButtonVisibility` forces traffic lights to be shown or hidden depending
on the value of its boolean parameter.
```js title='main.js'

View File

@@ -5,12 +5,12 @@
By default, windows are dragged using the title bar provided by the OS chrome. Apps
that remove the default title bar need to use the `app-region` CSS property to define
specific areas that can be used to drag the window. Setting `app-region: drag` marks
a rectagular area as draggable.
a rectangular area as draggable.
It is important to note that draggable areas ignore all pointer events. For example,
a button element that overlaps a draggable region will not emit mouse clicks or mouse
enter/exit events within that overlapping area. Setting `app-region: no-drag` reenables
pointer events by excluding a rectagular area from a draggable region.
pointer events by excluding a rectangular area from a draggable region.
To make the whole window draggable, you can add `app-region: drag` as
`body`'s style:

View File

@@ -29,7 +29,7 @@ be updated accordingly.
In macOS 10.14 Mojave, Apple introduced a new [system-wide dark mode][system-wide-dark-mode]
for all macOS computers. If your Electron app has a dark mode, you can make it
follow the system-wide dark mode setting using
[the `nativeTheme` api](../api/native-theme.md).
[the `nativeTheme` API](../api/native-theme.md).
In macOS 10.15 Catalina, Apple introduced a new "automatic" dark mode option
for all macOS computers. In order for the `nativeTheme.shouldUseDarkColors` and

View File

@@ -7,47 +7,7 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
## Timeline
| Electron | Alpha | Beta | Stable | EOL | Chrome | Node | Supported |
| ------- | ----- | ------- | ------ | ------ | ---- | ---- | ---- |
| 40.0.0 | 2025-Oct-30 | 2025-Dec-03 | 2026-Jan-13 | 2026-Jun-30 | M144 | TBD | ✅ |
| 39.0.0 | 2025-Sep-04 | 2025-Oct-01 | 2025-Oct-28 | 2026-May-05 | M142 | v22.20 | ✅ |
| 38.0.0 | 2025-Jun-26 | 2025-Aug-06 | 2025-Sep-02 | 2026-Mar-10 | M140 | v22.18 | ✅ |
| 37.0.0 | 2025-May-01 | 2025-May-28 | 2025-Jun-24 | 2026-Jan-13 | M138 | v22.16 | ✅ |
| 36.0.0 | 2025-Mar-06 | 2025-Apr-02 | 2025-Apr-29 | 2025-Oct-28 | M136 | v22.14 | 🚫 |
| 35.0.0 | 2025-Jan-16 | 2025-Feb-05 | 2025-Mar-04 | 2025-Sep-02 | M134 | v22.14 | 🚫 |
| 34.0.0 | 2024-Oct-17 | 2024-Nov-13 | 2025-Jan-14 | 2025-Jun-24 | M132 | v20.18 | 🚫 |
| 33.0.0 | 2024-Aug-22 | 2024-Sep-18 | 2024-Oct-15 | 2025-Apr-29 | M130 | v20.18 | 🚫 |
| 32.0.0 | 2024-Jun-14 | 2024-Jul-24 | 2024-Aug-20 | 2025-Mar-04 | M128 | v20.16 | 🚫 |
| 31.0.0 | 2024-Apr-18 | 2024-May-15 | 2024-Jun-11 | 2025-Jan-14 | M126 | v20.14 | 🚫 |
| 30.0.0 | 2024-Feb-22 | 2024-Mar-20 | 2024-Apr-16 | 2024-Oct-15 | M124 | v20.11 | 🚫 |
| 29.0.0 | 2023-Dec-07 | 2024-Jan-24 | 2024-Feb-20 | 2024-Aug-20 | M122 | v20.9 | 🚫 |
| 28.0.0 | 2023-Oct-11 | 2023-Nov-06 | 2023-Dec-05 | 2024-Jun-11 | M120 | v18.18 | 🚫 |
| 27.0.0 | 2023-Aug-17 | 2023-Sep-13 | 2023-Oct-10 | 2024-Apr-16 | M118 | v18.17 | 🚫 |
| 26.0.0 | 2023-Jun-01 | 2023-Jun-27 | 2023-Aug-15 | 2024-Feb-20 | M116 | v18.16 | 🚫 |
| 25.0.0 | 2023-Apr-10 | 2023-May-02 | 2023-May-30 | 2023-Dec-05 | M114 | v18.15 | 🚫 |
| 24.0.0 | 2023-Feb-09 | 2023-Mar-07 | 2023-Apr-04 | 2023-Oct-10 | M112 | v18.14 | 🚫 |
| 23.0.0 | 2022-Dec-01 | 2023-Jan-10 | 2023-Feb-07 | 2023-Aug-15 | M110 | v18.12 | 🚫 |
| 22.0.0 | 2022-Sep-29 | 2022-Oct-25 | 2022-Nov-29 | 2023-Oct-10 | M108 | v16.17 | 🚫 |
| 21.0.0 | 2022-Aug-04 | 2022-Aug-30 | 2022-Sep-27 | 2023-Apr-04 | M106 | v16.16 | 🚫 |
| 20.0.0 | 2022-May-26 | 2022-Jun-21 | 2022-Aug-02 | 2023-Feb-07 | M104 | v16.15 | 🚫 |
| 19.0.0 | 2022-Mar-31 | 2022-Apr-26 | 2022-May-24 | 2022-Nov-29 | M102 | v16.14 | 🚫 |
| 18.0.0 | 2022-Feb-03 | 2022-Mar-03 | 2022-Mar-29 | 2022-Sep-27 | M100 | v16.13 | 🚫 |
| 17.0.0 | 2021-Nov-18 | 2022-Jan-06 | 2022-Feb-01 | 2022-Aug-02 | M98 | v16.13 | 🚫 |
| 16.0.0 | 2021-Sep-23 | 2021-Oct-20 | 2021-Nov-16 | 2022-May-24 | M96 | v16.9 | 🚫 |
| 15.0.0 | 2021-Jul-20 | 2021-Sep-01 | 2021-Sep-21 | 2022-May-24 | M94 | v16.5 | 🚫 |
| 14.0.0 | -- | 2021-May-27 | 2021-Aug-31 | 2022-Mar-29 | M93 | v14.17 | 🚫 |
| 13.0.0 | -- | 2021-Mar-04 | 2021-May-25 | 2022-Feb-01 | M91 | v14.16 | 🚫 |
| 12.0.0 | -- | 2020-Nov-19 | 2021-Mar-02 | 2021-Nov-16 | M89 | v14.16 | 🚫 |
| 11.0.0 | -- | 2020-Aug-27 | 2020-Nov-17 | 2021-Aug-31 | M87 | v12.18 | 🚫 |
| 10.0.0 | -- | 2020-May-21 | 2020-Aug-25 | 2021-May-25 | M85 | v12.16 | 🚫 |
| 9.0.0 | -- | 2020-Feb-06 | 2020-May-19 | 2021-Mar-02 | M83 | v12.14 | 🚫 |
| 8.0.0 | -- | 2019-Oct-24 | 2020-Feb-04 | 2020-Nov-17 | M80 | v12.13 | 🚫 |
| 7.0.0 | -- | 2019-Aug-01 | 2019-Oct-22 | 2020-Aug-25 | M78 | v12.8 | 🚫 |
| 6.0.0 | -- | 2019-Apr-25 | 2019-Jul-30 | 2020-May-19 | M76 | v12.14.0 | 🚫 |
| 5.0.0 | -- | 2019-Jan-22 | 2019-Apr-23 | 2020-Feb-04 | M73 | v12.0 | 🚫 |
| 4.0.0 | -- | 2018-Oct-11 | 2018-Dec-20 | 2019-Oct-22 | M69 | v10.11 | 🚫 |
| 3.0.0 | -- | 2018-Jun-21 | 2018-Sep-18 | 2019-Jul-30 | M66 | v10.2 | 🚫 |
| 2.0.0 | -- | 2018-Feb-21 | 2018-May-01 | 2019-Apr-23 | M61 | v8.9 | 🚫 |
[Electron's Release Schedule](https://releases.electronjs.org/schedule) lists a schedule of Electron major releases showing key milestones including alpha, beta, and stable release dates, as well as end-of-life dates and dependency versions.
:::info Official support dates may change

View File

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

View File

@@ -171,7 +171,7 @@ sections.
In the main process, we'll be creating a `handleFileOpen()` function that calls
`dialog.showOpenDialog` and returns the value of the file path selected by the user. This function
is used as a callback whenever an `ipcRender.invoke` message is sent through the `dialog:openFile`
is used as a callback whenever an `ipcRenderer.invoke` message is sent through the `dialog:openFile`
channel from the renderer process. The return value is then returned as a Promise to the original
`invoke` call.
@@ -446,7 +446,7 @@ After loading the preload script, your renderer process should have access to th
We don't directly expose the whole `ipcRenderer.on` API for [security reasons][]. Make sure to
limit the renderer's access to Electron APIs as much as possible.
Also don't just pass the callback to `ipcRenderer.on` as this will leak `ipcRenderer` via `event.sender`.
Use a custom handler that invoke the `callback` only with the desired arguments.
Use a custom handler that invokes the `callback` only with the desired arguments.
:::
:::info

View File

@@ -10,7 +10,7 @@ hide_title: false
## Accelerators
Accelerators are strings that can be used to represent keyboard shortcuts throughout your Electron.
These strings can contain multiple modifiers keys and a single key code joined by the `+` character.
These strings can contain multiple modifier keys and a single key code joined by the `+` character.
> [!NOTE]
> Accelerators are **case-insensitive**.

View File

@@ -62,9 +62,9 @@ const createWindow = () => {
}
```
In this next step, we will create our `BrowserWindow` and tell our application how to handle an event in which an external protocol is clicked.
In this next step, we will create our `BrowserWindow` and tell our application how to handle an event in which an external protocol is clicked.
This code will be different in Windows and Linux compared to MacOS. This is due to both platforms emitting the `second-instance` event rather than the `open-url` event and Windows requiring additional code in order to open the contents of the protocol link within the same Electron instance. Read more about this [here](../api/app.md#apprequestsingleinstancelockadditionaldata).
This code will be different in Windows and Linux compared to macOS. This is due to both platforms emitting the `second-instance` event rather than the `open-url` event and Windows requiring additional code in order to open the contents of the protocol link within the same Electron instance. Read more about this [here](../api/app.md#apprequestsingleinstancelockadditionaldata).
#### Windows and Linux code:
@@ -91,7 +91,7 @@ if (!gotTheLock) {
}
```
#### MacOS code:
#### macOS code:
```js @ts-type={createWindow:()=>void}
// This method will be called when Electron has finished

View File

@@ -65,7 +65,7 @@ The full list of certificate types can be found
Apps signed with "Apple Development" and "Apple Distribution" certificates can
only run under [App Sandbox][app-sandboxing], so they must use the MAS build of
Electron. However, the "Developer ID Application" certificate does not have this
restrictions, so apps signed with it can use either the normal build or the MAS
restriction, so apps signed with it can use either the normal build or the MAS
build of Electron.
#### Legacy certificate names
@@ -208,7 +208,7 @@ signAsync({
After signing the app with the "Apple Distribution" certificate, you can
continue to submit it to Mac App Store.
However, this guide do not ensure your app will be approved by Apple; you
However, this guide does not ensure your app will be approved by Apple; you
still need to read Apple's [Submitting Your App][submitting-your-app] guide on
how to meet the Mac App Store requirements.

View File

@@ -25,7 +25,7 @@ Electron application, and this property only exists on macOS.
One of the main uses for your app's Dock icon is to expose additional app menus. The Dock menu is
triggered by right-clicking or <kbd>Ctrl</kbd>-clicking the app icon. By default, the app's Dock menu
will come with system-provided window management utilities, including the ability to show all windows,
hide the app, and switch betweeen different open windows.
hide the app, and switch between different open windows.
To set an app-defined custom Dock menu, pass any [Menu](../api/menu.md) instance into the
[`dock.setMenu`](../api/dock.md#docksetmenumenu-macos) API.

View File

@@ -200,7 +200,7 @@ macOS has a number of platform-specific menu roles available. Many of these map
* `recentDocuments` - The submenu is an "Open Recent" menu.
* `clearRecentDocuments` - Map to the [`clearRecentDocuments`](https://developer.apple.com/documentation/appkit/nsdocumentcontroller/clearrecentdocuments(_:)) action.
* `shareMenu` - The submenu is [share menu][ShareMenu]. The `sharingItem` property must also be set to indicate the item to share.
* `shareMenu` - The submenu is [share menu](../api/share-menu.md). The `sharingItem` property must also be set to indicate the item to share.
> [!IMPORTANT]
> When specifying a `role` on macOS, `label` and `accelerator` are the only

View File

@@ -1339,7 +1339,7 @@ For developers wanting to learn more, you can refer to the [official N-API docum
### Putting `cpp_addon.cc` together
We've now finished the bridge part our addon - that is, the code that's most concerned with being the bridge between your JavaScript and C++ code (and by contrast, less so actually interacting with the operating system or GTK). After adding all the sections above, your `src/cpp_addon.cc` should look like this:
We've now finished the bridge part of our addon - that is, the code that's most concerned with being the bridge between your JavaScript and C++ code (and by contrast, less so actually interacting with the operating system or GTK). After adding all the sections above, your `src/cpp_addon.cc` should look like this:
```cpp title='src/cpp_addon.cc'
#include <napi.h>

View File

@@ -4,13 +4,13 @@ This tutorial builds on the [general introduction to Native Code and Electron](.
Specifically, we'll be integrating with two commonly used native Windows libraries:
* `comctl32.lib`, which contains common controls and user interface components. It provides various UI elements like buttons, scrollbars, toolbars, status bars, progress bars, and tree views. As far as GUI development on Windows goes, this library is very low-level and basic - more modern frameworks like WinUI or WPF are advanced and alternatives but require a lot more C++ and Windows version considerations than are useful for this tutorial. This way, we can avoid the many perils of building native interfaces for multiple Windows versions!
* `comctl32.lib`, which contains common controls and user interface components. It provides various UI elements like buttons, scrollbars, toolbars, status bars, progress bars, and tree views. As far as GUI development on Windows goes, this library is very low-level and basic - more modern frameworks like WinUI or WPF are more advanced alternatives but require a lot more C++ and Windows version considerations than are useful for this tutorial. This way, we can avoid the many perils of building native interfaces for multiple Windows versions!
* `shcore.lib`, a library that provides high-DPI awareness functionality and other Shell-related features around managing displays and UI elements.
This tutorial will be most useful to those who already have some familiarity with native C++ GUI development on Windows. You should have experience with basic window classes and procedures, like `WNDCLASSEXW` and `WindowProc` functions. You should also be familiar with the Windows message loop, which is the heart of any native application - our code will be using `GetMessage`, `TranslateMessage`, and `DispatchMessage` to handle messages. Lastly, we'll be using (but not explaining) standard Win32 controls like `WC_EDITW` or `WC_BUTTONW`.
> [!NOTE]
> If you're not familiar with C++ GUI development on Windows, we recommend Microsoft's excellent documentation and guides, particular for beginners. "[Get Started with Win32 and C++](https://learn.microsoft.com/en-us/windows/win32/learnwin32/learn-to-program-for-windows)" is a great introduction.
> If you're not familiar with C++ GUI development on Windows, we recommend Microsoft's excellent documentation and guides, particularly for beginners. "[Get Started with Win32 and C++](https://learn.microsoft.com/en-us/windows/win32/learnwin32/learn-to-program-for-windows)" is a great introduction.
## Requirements
@@ -1333,7 +1333,7 @@ npm run build
## Conclusion
You've now built a complete native Node.js addon for Windows using C++ and the Win32 API. Some of things we've done here are:
You've now built a complete native Node.js addon for Windows using C++ and the Win32 API. Some of the things we've done here are:
1. Creating a native Windows GUI from C++
2. Implementing a Todo list application with Add, Edit, and Delete functionality

View File

@@ -1167,7 +1167,7 @@ The approach demonstrated here allows you to:
* Setting up bidirectional communication using callbacks and events
* Configuring a custom build process to compile Swift code
For more information on developing with Swift and Swift, refer to Apple's developer documentation:
For more information on developing with Swift and SwiftUI, refer to Apple's developer documentation:
* [Swift Programming Language](https://developer.apple.com/swift/)
* [SwiftUI Framework](https://developer.apple.com/documentation/swiftui)

View File

@@ -14,7 +14,7 @@ _Notes_:
* There are two rendering modes that can be used (see the section below) and only
the dirty area is passed to the `paint` event to be more efficient.
* You can stop/continue the rendering as well as set the frame rate.
* When `webPreferences.offscreen.useSharedTexture` is not `true`, the maximum frame rate is 240 because greater values bring only performance
* When `webPreferences.offscreen.useSharedTexture` is `false`, the maximum frame rate is 240 because greater values bring only performance
losses with no benefits.
* When nothing is happening on a webpage, no frames are generated.
* An offscreen window is always created as a
@@ -36,8 +36,8 @@ setting.
This is an advanced feature requiring a native node module to work with your own code.
The frames are directly copied in GPU textures, thus this mode is very fast because
there's no CPU-GPU memory copies overhead, and you can directly import the shared
texture to your own rendering program. You can read more details at
[here](https://github.com/electron/electron/blob/main/shell/browser/osr/README.md).
texture to your own rendering program. You can read more details
[here](../../shell/common/api/shared_texture/README.md).
2. Use CPU shared memory bitmap

View File

@@ -294,7 +294,7 @@ particularly useful if users complain about your app sometimes "stuttering".
Generally speaking, all advice for building performant web apps for modern
browsers apply to Electron's renderers, too. The two primary tools at your
disposal are currently `requestIdleCallback()` for small operations and
disposal are currently `requestIdleCallback()` for small operations and
`Web Workers` for long-running operations.
_`requestIdleCallback()`_ allows developers to queue up a function to be
@@ -360,7 +360,7 @@ turning into a desktop application. As web developers, we are used to loading
resources from a variety of content delivery networks. Now that you are
shipping a proper desktop application, attempt to "cut the cord" where possible
and avoid letting your users wait for resources that never change and could
easily be included in your app.
easily be included in your app.
A typical example is Google Fonts. Many developers make use of Google's
impressive collection of free fonts, which comes with a content delivery

View File

@@ -113,7 +113,7 @@ For a full list of Electron's main process modules, check out our API documentat
Each Electron app spawns a separate renderer process for each open `BrowserWindow`
(and each web embed). As its name implies, a renderer is responsible for
_rendering_ web content. For all intents and purposes, code ran in renderer processes
_rendering_ web content. For all intents and purposes, code run in renderer processes
should behave according to web standards (insofar as Chromium does, at least).
Therefore, all user interfaces and app functionality within a single browser

View File

@@ -9,7 +9,7 @@ toc_max_heading_level: 3
:::info Reporting security issues
For information on how to properly disclose an Electron vulnerability,
see [SECURITY.md](https://github.com/electron/electron/blob/main/SECURITY.md).
see [SECURITY.md](../../SECURITY.md).
For upstream Chromium vulnerabilities: Electron keeps up to date with alternating
Chromium releases. For more information, see the
@@ -771,7 +771,7 @@ ipcMain.handle('get-secrets', (e) => {
})
function validateSender (frame) {
// Value the host of the URL using an actual URL parser and an allowlist
// Validate the host of the URL using an actual URL parser and an allowlist
if ((new URL(frame.url)).host === 'electronjs.org') return true
return false
}

View File

@@ -2,4 +2,4 @@
* For information on supported releases, see the [Electron Releases](./electron-timelines.md) doc.
* For community support on Electron, see the [Community page](https://www.electronjs.org/community).
* For platform support info, see the [README](https://github.com/electron/electron/blob/main/README.md).
* For platform support info, see the [README](../../README.md).

View File

@@ -2,8 +2,8 @@
Being based on Chromium, Electron requires a display driver to function.
If Chromium can't find a display driver, Electron will fail to launch -
and therefore not executing any of your tests, regardless of how you are running
them. Testing Electron-based apps on Travis, CircleCI, Jenkins or similar Systems
and therefore not execute any of your tests, regardless of how you are running
them. Testing Electron-based apps on Travis, CircleCI, Jenkins or similar systems
requires therefore a little bit of configuration. In essence, we need to use
a virtual display driver.

View File

@@ -44,7 +44,7 @@ following JSON format:
"updateTo": {
"version": "1.2.1",
"pub_date": "2023-09-18T12:29:53+01:00",
"notes": "Theses are some release notes innit",
"notes": "These are some release notes innit",
"name": "1.2.1",
"url": "https://mycompany.example.com/myapp/releases/myrelease"
}
@@ -54,7 +54,7 @@ following JSON format:
"updateTo": {
"version": "1.2.3",
"pub_date": "2024-09-18T12:29:53+01:00",
"notes": "Theses are some more release notes innit",
"notes": "These are some more release notes innit",
"name": "1.2.3",
"url": "https://mycompany.example.com/myapp/releases/myrelease3"
}
@@ -307,7 +307,7 @@ app update. All other properties in the object are optional.
{
"url": "https://your-static.storage/your-app-1.2.3-darwin.zip",
"name": "1.2.3",
"notes": "Theses are some release notes innit",
"notes": "These are some release notes innit",
"pub_date": "2024-09-18T12:29:53+01:00"
}
```

View File

@@ -149,7 +149,7 @@ for an example delay-load hook if you're implementing your own.
native Node modules with prebuilt binaries for multiple versions of Node
and Electron.
If the `prebuild`-powered module provide binaries for the usage in Electron,
If the `prebuild`-powered module provides binaries for the usage in Electron,
make sure to omit `--build-from-source` and the `npm_config_build_from_source`
environment variable in order to take full advantage of the prebuilt binaries.

View File

@@ -38,7 +38,7 @@ To test your app, use a Windows on Arm device running Windows 10 (version 1903 o
### Node.js/node-gyp
[Node.js v12.9.0 or later is recommended.](https://nodejs.org/en/) If updating to a new version of Node is undesirable, you can instead [update npm's copy of node-gyp manually](https://github.com/nodejs/node-gyp/wiki/Updating-npm's-bundled-node-gyp) to version 5.0.2 or later, which contains the required changes to compile native modules for Arm.
[Node.js v12.9.0 or later is recommended.](https://nodejs.org/en/) If updating to a new version of Node is undesirable, you can instead [update npm's copy of node-gyp manually](https://github.com/nodejs/node-gyp/wiki/Updating-npm's-bundled-node-gyp) to version 5.0.2 or later, which contains the required changes to compile native modules for Arm.
### Visual Studio 2017

View File

@@ -134,7 +134,7 @@ system.
Before running the CLI for the first time, you will have to setup the "Windows Desktop App
Converter". This will take a few minutes, but don't worry - you only have to do
this once. Download and Desktop App Converter from [here][app-converter].
this once. Download the Desktop App Converter from [here][app-converter].
You will receive two files: `DesktopAppConverter.zip` and `BaseImage-14316.wim`.
1. Unzip `DesktopAppConverter.zip`. From an elevated PowerShell (opened with

View File

@@ -30,7 +30,7 @@ If you want to focus on building a great product without debugging a weird quirk
Whatever provider or customer data you need to interact with, they will have probably thought of an integration path with the web. Depending on your technology choice, embedding a YouTube video either takes 30 seconds or requires you to hire a team devoted to streaming and hardware-accelerated video decoding. In the case of YouTube, using anything other than the provided players is actually against their terms and conditions, so youll likely embed a browser frame before you implement your own video streaming decoder.
There will be virtually no platform where your app cannot run if you build it with web technologies. Virtually all devices with a display—be that an ATM, a car infotainment system, a smart TV, a fridge, or a Nintendo Switch—come with means to display web technologies. The web is safe bet if you want to be cross-platform.
There will be virtually no platform where your app cannot run if you build it with web technologies. Virtually all devices with a display—be that an ATM, a car infotainment system, a smart TV, a fridge, or a Nintendo Switch—come with means to display web technologies. The web is a safe bet if you want to be cross-platform.
### Ubiquity
@@ -59,7 +59,7 @@ What does all of that mean for you, a developer, in practice?
### Stability, security, performance
Electron delivers the best experience on all target platforms (macOS, Windows, Linux) by bundling the latest version of Chromium, V8, and Node.js directly with the application binary. When it comes to running and rendering web content with upmost stability, security, and performance, we currently believe that stack to be “best in class”.
Electron delivers the best experience on all target platforms (macOS, Windows, Linux) by bundling the latest version of Chromium, V8, and Node.js directly with the application binary. When it comes to running and rendering web content with utmost stability, security, and performance, we currently believe that stack to be “best in class”.
#### Why bundle anything at all

View File

@@ -79,6 +79,8 @@ filenames = {
"shell/browser/notifications/win/notification_presenter_win.h",
"shell/browser/notifications/win/windows_toast_notification.cc",
"shell/browser/notifications/win/windows_toast_notification.h",
"shell/browser/notifications/win/windows_toast_activator.cc",
"shell/browser/notifications/win/windows_toast_activator.h",
"shell/browser/relauncher_win.cc",
"shell/browser/ui/certificate_trust_win.cc",
"shell/browser/ui/file_dialog_win.cc",
@@ -113,6 +115,8 @@ filenames = {
"shell/browser/win/scoped_hstring.h",
"shell/common/api/electron_api_native_image_win.cc",
"shell/common/application_info_win.cc",
"shell/common/command_line_util_win.cc",
"shell/common/command_line_util_win.h",
"shell/common/language_util_win.cc",
"shell/common/node_bindings_win.cc",
"shell/common/node_bindings_win.h",
@@ -277,6 +281,8 @@ filenames = {
"shell/browser/api/electron_api_in_app_purchase.h",
"shell/browser/api/electron_api_menu.cc",
"shell/browser/api/electron_api_menu.h",
"shell/browser/api/electron_api_msix_updater.cc",
"shell/browser/api/electron_api_msix_updater.h",
"shell/browser/api/electron_api_native_theme.cc",
"shell/browser/api/electron_api_native_theme.h",
"shell/browser/api/electron_api_net_log.cc",

View File

@@ -353,6 +353,7 @@ export function shouldOverrideCheckStatus (role: RoleId) {
export function getDefaultAccelerator (role: RoleId) {
if (hasRole(role)) return roleList[role].accelerator;
return undefined;
}
export function shouldRegisterAccelerator (role: RoleId) {

View File

@@ -25,10 +25,10 @@ const MenuItem = function (this: any, options: any) {
this.overrideReadOnlyProperty('type', roles.getDefaultType(this.role));
this.overrideReadOnlyProperty('role');
this.overrideReadOnlyProperty('accelerator');
this.overrideReadOnlyProperty('icon');
this.overrideReadOnlyProperty('accelerator', roles.getDefaultAccelerator(this.role));
this.overrideReadOnlyProperty('submenu');
this.overrideProperty('icon');
this.overrideProperty('label', roles.getDefaultLabel(this.role));
this.overrideProperty('sublabel', '');
this.overrideProperty('toolTip', '');

View File

@@ -53,6 +53,18 @@ Menu.prototype._isCommandIdVisible = function (id) {
return this.commandsMap[id]?.visible ?? false;
};
Menu.prototype._getLabelForCommandId = function (id) {
return this.commandsMap[id]?.label ?? '';
};
Menu.prototype._getSecondaryLabelForCommandId = function (id) {
return this.commandsMap[id]?.sublabel ?? '';
};
Menu.prototype._getIconForCommandId = function (id) {
return this.commandsMap[id]?.icon ?? null;
};
Menu.prototype._getAcceleratorForCommandId = function (id, useDefaultAccelerator) {
const command = this.commandsMap[id];
if (!command) return;
@@ -158,7 +170,6 @@ Menu.prototype.insert = function (pos, item) {
insertItemByType.call(this, item, pos);
// set item properties
if (item.sublabel) this.setSublabel(pos, item.sublabel);
if (item.toolTip) this.setToolTip(pos, item.toolTip);
if (item.icon) this.setIcon(pos, item.icon);
if (item.role) this.setRole(pos, item.role);

View File

@@ -8,13 +8,19 @@ const {
isOnBatteryPower
} = process._linkedBinding('electron_browser_power_monitor');
// Hold the native PowerMonitor at module level so it is never garbage-collected
// while this module is alive. The C++ side registers OS-level callbacks (HWND
// user-data on Windows, shutdown handler on macOS, notification observers) that
// prevent safe collection of the C++ wrapper while those registrations exist.
let pm: any;
class PowerMonitor extends EventEmitter implements Electron.PowerMonitor {
constructor () {
super();
// Don't start the event source until both a) the app is ready and b)
// there's a listener registered for a powerMonitor event.
this.once('newListener', () => {
const pm = createPowerMonitor();
pm = createPowerMonitor();
pm.emit = this.emit.bind(this);
if (process.platform === 'linux') {

View File

@@ -19,8 +19,8 @@ export function invokeInWebContents<T> (sender: Electron.WebContents, command: s
const requestId = ++nextId;
const channel = `${command}_RESPONSE_${requestId}`;
ipcMainInternal.on(channel, function handler (event, error: Error, result: any) {
if (event.type === 'frame' && event.sender !== sender) {
console.error(`Reply to ${command} sent by unexpected WebContents (${event.sender.id})`);
if (event.type !== 'frame' || event.sender !== sender) {
console.error(`Reply to ${command} sent by unexpected sender`);
return;
}
@@ -43,8 +43,8 @@ export function invokeInWebFrameMain<T> (sender: Electron.WebFrameMain, command:
const channel = `${command}_RESPONSE_${requestId}`;
const frameTreeNodeId = sender.frameTreeNodeId;
ipcMainInternal.on(channel, function handler (event, error: Error, result: any) {
if (event.type === 'frame' && event.frameTreeNodeId !== frameTreeNodeId) {
console.error(`Reply to ${command} sent by unexpected WebFrameMain (${event.frameTreeNodeId})`);
if (event.type !== 'frame' || event.frameTreeNodeId !== frameTreeNodeId) {
console.error(`Reply to ${command} sent by unexpected sender`);
return;
}

View File

@@ -227,10 +227,9 @@ function validateHeader (name: any, value: any): void {
}
function parseOptions (optionsIn: ClientRequestConstructorOptions | string): NodeJS.CreateURLLoaderOptions & ExtraURLLoaderOptions {
// eslint-disable-next-line n/no-deprecated-api
const options: any = typeof optionsIn === 'string' ? url.parse(optionsIn) : { ...optionsIn };
const options: any = typeof optionsIn === 'string' ? new URL(optionsIn) : { ...optionsIn };
let urlStr: string = options.url;
let urlStr: string = options.url || options.href;
if (!urlStr) {
const urlObj: url.UrlObject = {};
@@ -260,8 +259,8 @@ function parseOptions (optionsIn: ClientRequestConstructorOptions | string): Nod
// an invalid request.
throw new TypeError('Request path contains unescaped characters');
}
// eslint-disable-next-line n/no-deprecated-api
const pathObj = url.parse(options.path || '/');
const pathObj = new URL(options.path || '/', 'http://localhost');
urlObj.pathname = pathObj.pathname;
urlObj.search = pathObj.search;
urlObj.hash = pathObj.hash;

View File

@@ -1232,6 +1232,8 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
// has filesystem caching.
overrideAPI(fs, 'copyFile');
overrideAPISync(fs, 'copyFileSync');
overrideAPI(fs, 'cp');
overrideAPISync(fs, 'cpSync');
overrideAPI(fs, 'open');
overrideAPISync(process, 'dlopen', 1);

View File

@@ -9,6 +9,7 @@ if ((globalThis as any).blinkfetch) {
const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers', 'EventSource'];
for (const key of keys) {
(globalThis as any)[key] = (globalThis as any)[`blink${key}`];
delete (globalThis as any)[`blink${key}`];
}
}

View File

@@ -23,11 +23,14 @@ export default contextBridge;
export const internalContextBridge = {
contextIsolationEnabled: process.contextIsolated,
tryOverrideGlobalValueFromIsolatedWorld: (keys: string[], value: any) => {
return binding._overrideGlobalValueFromIsolatedWorld(keys, value, true, true);
},
overrideGlobalValueFromIsolatedWorld: (keys: string[], value: any) => {
return binding._overrideGlobalValueFromIsolatedWorld(keys, value, false);
return binding._overrideGlobalValueFromIsolatedWorld(keys, value, false, false);
},
overrideGlobalValueWithDynamicPropsFromIsolatedWorld: (keys: string[], value: any) => {
return binding._overrideGlobalValueFromIsolatedWorld(keys, value, true);
return binding._overrideGlobalValueFromIsolatedWorld(keys, value, true, false);
},
overrideGlobalPropertyFromIsolatedWorld: (keys: string[], getter: Function, setter?: Function) => {
return binding._overrideGlobalPropertyFromIsolatedWorld(keys, getter, setter || null);

View File

@@ -11,14 +11,12 @@ const { contextIsolationEnabled } = internalContextBridge;
* 1) Use menu API to show context menu.
*/
window.onload = function () {
if (window.InspectorFrontendHost) {
if (contextIsolationEnabled) {
internalContextBridge.overrideGlobalValueFromIsolatedWorld([
'InspectorFrontendHost', 'showContextMenuAtPoint'
], createMenu);
} else {
window.InspectorFrontendHost.showContextMenuAtPoint = createMenu;
}
if (contextIsolationEnabled) {
internalContextBridge.tryOverrideGlobalValueFromIsolatedWorld([
'InspectorFrontendHost', 'showContextMenuAtPoint'
], createMenu);
} else {
window.InspectorFrontendHost!.showContextMenuAtPoint = createMenu;
}
};

View File

@@ -22,6 +22,7 @@ if ((globalThis as any).blinkfetch) {
const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers', 'EventSource'];
for (const key of keys) {
(globalThis as any)[key] = (globalThis as any)[`blink${key}`];
delete (globalThis as any)[`blink${key}`];
}
}

View File

@@ -57,7 +57,8 @@
"url": "^0.11.4",
"webpack": "^5.95.0",
"webpack-cli": "^6.0.1",
"wrapper-webpack-plugin": "^2.2.0"
"wrapper-webpack-plugin": "^2.2.0",
"yaml": "^2.8.1"
},
"private": true,
"scripts": {
@@ -73,7 +74,7 @@
"lint:gn": "node ./script/lint.js --gn",
"lint:docs": "remark docs -qf && npm run lint:js-in-markdown && npm run create-typescript-definitions && npm run lint:ts-check-js-in-markdown && npm run lint:docs-fiddles && npm run lint:docs-relative-links && npm run lint:markdown && npm run lint:api-history",
"lint:docs-fiddles": "standard \"docs/fiddles/**/*.js\"",
"lint:docs-relative-links": "lint-roller-markdown-links --root docs \"**/*.md\"",
"lint:docs-relative-links": "lint-roller-markdown-links --resource-root . --root docs \"**/*.md\"",
"lint:markdown": "node ./script/lint.js --md",
"lint:ts-check-js-in-markdown": "lint-roller-markdown-ts-check --root docs \"**/*.md\" --ignore \"breaking-changes.md\"",
"lint:js-in-markdown": "lint-roller-markdown-standard --root docs \"**/*.md\"",
@@ -132,6 +133,10 @@
"DEPS": [
"node script/gen-hunspell-filenames.js",
"node script/gen-libc++-filenames.js"
],
".github/workflows/pipeline-segment-electron-build.yml": [
"node script/copy-pipeline-segment-publish.js",
"git add .github/workflows/pipeline-segment-electron-publish.yml"
]
},
"resolutions": {

View File

@@ -0,0 +1 @@
cherry-pick-a08731cf6d70.patch

View File

@@ -0,0 +1,240 @@
From a08731cf6d70c60fd74b1d75f2e8b94c52e18140 Mon Sep 17 00:00:00 2001
From: Shahbaz Youssefi <syoussefi@chromium.org>
Date: Thu, 19 Feb 2026 14:42:08 -0500
Subject: [PATCH] Vulkan: Avoid overflow in texture size calculation
Bug: chromium:485622239
Change-Id: Idf9847afa0aa2e72b6433ac8348ae2820c1ad8c5
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/7595734
Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com>
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
---
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp
index 9e208f9..e2185a4 100644
--- a/src/libANGLE/renderer/vulkan/TextureVk.cpp
+++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp
@@ -3164,8 +3164,17 @@
// invalidate must be called after wait for finish.
ANGLE_TRY(srcBuffer->invalidate(renderer));
- size_t dstBufferSize = sourceBox.width * sourceBox.height * sourceBox.depth *
- dstFormat.pixelBytes * layerCount;
+ // Use size_t calculations to avoid 32-bit overflows. Note that the dimensions are bound by
+ // the maximums specified in Constants.h, and that gl::Box members are signed 32-bit
+ // integers.
+ static_assert(gl::IMPLEMENTATION_MAX_2D_TEXTURE_SIZE *
+ gl::IMPLEMENTATION_MAX_2D_TEXTURE_SIZE <
+ std::numeric_limits<int32_t>::max());
+ size_t dstBufferSize = sourceBox.width * sourceBox.height;
+ static_assert(gl::IMPLEMENTATION_MAX_3D_TEXTURE_SIZE *
+ gl::IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS * 16 <
+ std::numeric_limits<int32_t>::max());
+ dstBufferSize *= sourceBox.depth * dstFormat.pixelBytes * layerCount;
// Allocate memory in the destination texture for the copy/conversion.
uint8_t *dstData = nullptr;
diff --git a/src/tests/gl_tests/FramebufferTest.cpp b/src/tests/gl_tests/FramebufferTest.cpp
index 020a041..f72f1a7 100644
--- a/src/tests/gl_tests/FramebufferTest.cpp
+++ b/src/tests/gl_tests/FramebufferTest.cpp
@@ -8894,6 +8894,62 @@
ASSERT_GL_NO_ERROR();
}
+// Test that 2D array texture size calculation doesn't overflow internally when rendering to it. An
+// RGB format is used which is often emualted with RGBA.
+//
+// Practically we cannot run this test. On most configurations, allocating a 4GB texture fails due
+// to internal driver limitations. On the few configs that the test actually runs, allocating such
+// large memory leads to instability.
+TEST_P(FramebufferTest_ES3, DISABLED_MaxSize2DArrayNoOverflow)
+{
+ GLint maxTexture2DSize;
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexture2DSize);
+
+ maxTexture2DSize = std::min(maxTexture2DSize, 16384);
+
+ // Create a 2D array texture with RGB format. Every layer is going to take 1GB of memory (if
+ // emulated with RGBA), so only create 4 layers of it (for a total of 4GB of memory). If 32-bit
+ // math is involved when calculating sizes related to this texture, they will overflow.
+ constexpr uint32_t kLayers = 4;
+ GLTexture tex;
+ glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
+ glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGB8, maxTexture2DSize, maxTexture2DSize, kLayers);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ // Initialize the texture so its content is considered valid and worth preserving.
+ constexpr int kValidSubsectionWidth = 16;
+ constexpr int kValidSubsectionHeight = 20;
+ std::vector<GLColorRGB> data(kValidSubsectionWidth * kValidSubsectionHeight,
+ GLColorRGB(0, 255, 0));
+ for (uint32_t layer = 0; layer < kLayers; ++layer)
+ {
+ glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layer, kValidSubsectionWidth,
+ kValidSubsectionHeight, 1, GL_RGB, GL_UNSIGNED_BYTE, data.data());
+ }
+
+ // Draw with the texture, making sure it's initialized and data is flushed.
+ ANGLE_GL_PROGRAM(drawTex2DArray, essl3_shaders::vs::Texture2DArray(),
+ essl3_shaders::fs::Texture2DArray());
+ drawQuad(drawTex2DArray, essl3_shaders::PositionAttrib(), 0.5f);
+
+ // Bind a framebuffer to the texture and render into it. In some backends, the texture is
+ // recreated to RGBA to be renderable.
+ GLFramebuffer fbo;
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 1);
+
+ ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
+ glViewport(0, 0, kValidSubsectionWidth / 2, kValidSubsectionHeight);
+ drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.5f);
+
+ EXPECT_PIXEL_RECT_EQ(0, 0, kValidSubsectionWidth / 2, kValidSubsectionHeight, GLColor::red);
+ EXPECT_PIXEL_RECT_EQ(kValidSubsectionWidth / 2, 0,
+ kValidSubsectionWidth - kValidSubsectionWidth / 2, kValidSubsectionHeight,
+ GLColor::green);
+ ASSERT_GL_NO_ERROR();
+}
+
ANGLE_INSTANTIATE_TEST_ES2_AND(AddMockTextureNoRenderTargetTest,
ES2_D3D9().enable(Feature::AddMockTextureNoRenderTarget),
ES2_D3D11().enable(Feature::AddMockTextureNoRenderTarget));
diff --git a/src/tests/gl_tests/VulkanImageTest.cpp b/src/tests/gl_tests/VulkanImageTest.cpp
index 2f06e2d..87e7482 100644
--- a/src/tests/gl_tests/VulkanImageTest.cpp
+++ b/src/tests/gl_tests/VulkanImageTest.cpp
@@ -677,8 +677,8 @@
kTextureHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE, textureColor.data());
}
- ANGLE_GL_PROGRAM(drawTex2DArray, essl1_shaders::vs::Texture2DArray(),
- essl1_shaders::fs::Texture2DArray());
+ ANGLE_GL_PROGRAM(drawTex2DArray, essl3_shaders::vs::Texture2DArray(),
+ essl3_shaders::fs::Texture2DArray());
drawQuad(drawTex2DArray, essl1_shaders::PositionAttrib(), 0.5f);
// Fill up the device memory until we start allocating on the system memory.
diff --git a/util/shader_utils.cpp b/util/shader_utils.cpp
index 275e261..8994612 100644
--- a/util/shader_utils.cpp
+++ b/util/shader_utils.cpp
@@ -580,18 +580,6 @@
})";
}
-const char *Texture2DArray()
-{
- return R"(#version 300 es
-out vec2 v_texCoord;
-in vec4 a_position;
-void main()
-{
- gl_Position = vec4(a_position.xy, 0.0, 1.0);
- v_texCoord = (a_position.xy * 0.5) + 0.5;
-})";
-}
-
} // namespace vs
namespace fs
@@ -689,20 +677,6 @@
})";
}
-const char *Texture2DArray()
-{
- return R"(#version 300 es
-precision highp float;
-uniform highp sampler2DArray tex2DArray;
-uniform int slice;
-in vec2 v_texCoord;
-out vec4 fragColor;
-void main()
-{
- fragColor = texture(tex2DArray, vec3(v_texCoord, float(slice)));
-})";
-}
-
} // namespace fs
} // namespace essl1_shaders
@@ -787,6 +761,18 @@
})";
}
+const char *Texture2DArray()
+{
+ return R"(#version 300 es
+out vec2 v_texCoord;
+in vec4 a_position;
+void main()
+{
+ gl_Position = vec4(a_position.xy, 0.0, 1.0);
+ v_texCoord = (a_position.xy * 0.5) + 0.5;
+})";
+}
+
} // namespace vs
namespace fs
@@ -844,6 +830,20 @@
})";
}
+const char *Texture2DArray()
+{
+ return R"(#version 300 es
+precision highp float;
+uniform highp sampler2DArray tex2DArray;
+uniform int slice;
+in vec2 v_texCoord;
+out vec4 fragColor;
+void main()
+{
+ fragColor = texture(tex2DArray, vec3(v_texCoord, float(slice)));
+})";
+}
+
} // namespace fs
} // namespace essl3_shaders
diff --git a/util/shader_utils.h b/util/shader_utils.h
index 676341e..cf211cf 100644
--- a/util/shader_utils.h
+++ b/util/shader_utils.h
@@ -90,7 +90,6 @@
// A shader that simply passes through attribute a_position, setting it to gl_Position and varying
// texcoord.
ANGLE_UTIL_EXPORT const char *Texture2D();
-ANGLE_UTIL_EXPORT const char *Texture2DArray();
} // namespace vs
@@ -120,7 +119,6 @@
// A shader that samples the texture
ANGLE_UTIL_EXPORT const char *Texture2D();
-ANGLE_UTIL_EXPORT const char *Texture2DArray();
} // namespace fs
} // namespace essl1_shaders
@@ -151,6 +149,7 @@
// A shader that simply passes through attribute a_position, setting it to gl_Position and varying
// texcoord.
ANGLE_UTIL_EXPORT const char *Texture2DLod();
+ANGLE_UTIL_EXPORT const char *Texture2DArray();
} // namespace vs
@@ -169,6 +168,9 @@
// A shader that samples the texture at a given lod.
ANGLE_UTIL_EXPORT const char *Texture2DLod();
+// A shader that samples the texture at a given slice.
+ANGLE_UTIL_EXPORT const char *Texture2DArray();
+
} // namespace fs
} // namespace essl3_shaders

View File

@@ -145,3 +145,9 @@ viz_create_isbufferqueuesupportedandenabled.patch
viz_fix_visual_artifacts_while_resizing_window_with_dcomp.patch
fix_os_crypt_async_cookie_encryption.patch
graphite_handle_out_of_order_recording_errors.patch
move_wayland_pointer_lock_overrides_to_common_code.patch
loaf_add_feature_to_enable_sourceurl_for_all_protocols.patch
fix_update_dbus_signal_signature_for_xdg_globalshortcuts_portal.patch
patch_osr_control_screen_info.patch
cherry-pick-12f932985275.patch
fix_mac_high_res_icons.patch

View File

@@ -6,10 +6,10 @@ Subject: build: allow electron to use exec_script
This is similar to the //build usecase so we're OK adding ourselves here
diff --git a/.gn b/.gn
index ae58a0b0a64ae1fdb3f9cd8587041d71a121c6b9..0ed56526002b12deb6d29f3dd23a0d74d8e7473c 100644
index ae58a0b0a64ae1fdb3f9cd8587041d71a121c6b9..f9d4e9b015ad266452dfa2a442b432ef31d09a5b 100644
--- a/.gn
+++ b/.gn
@@ -167,4 +167,27 @@ exec_script_allowlist =
@@ -167,4 +167,28 @@ exec_script_allowlist =
"//tools/grit/grit_rule.gni",
"//tools/gritsettings/BUILD.gn",
@@ -25,6 +25,7 @@ index ae58a0b0a64ae1fdb3f9cd8587041d71a121c6b9..0ed56526002b12deb6d29f3dd23a0d74
+ "//third_party/electron_node/deps/googletest/unofficial.gni",
+ "//third_party/electron_node/deps/histogram/unofficial.gni",
+ "//third_party/electron_node/deps/llhttp/unofficial.gni",
+ "//third_party/electron_node/deps/merve/unofficial.gni",
+ "//third_party/electron_node/deps/nbytes/unofficial.gni",
+ "//third_party/electron_node/deps/ncrypto/unofficial.gni",
+ "//third_party/electron_node/deps/nghttp2/unofficial.gni",

View File

@@ -9,10 +9,10 @@ potentially prevent a window from being created.
TODO(loc): this patch is currently broken.
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index edaf9a7b2efc5ed7f4e946d720de54d5001f44d4..7d27b076c1947d2cd08364f87286ed6d9f460cdc 100644
index ce64151028cc30c81292326ee73126cb8415aec5..3feca12a6185afef139a0cb4a8148b5a3ca9e32f 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -9867,6 +9867,7 @@ void RenderFrameHostImpl::CreateNewWindow(
@@ -9868,6 +9868,7 @@ void RenderFrameHostImpl::CreateNewWindow(
last_committed_origin_, params->window_container_type,
params->target_url, params->referrer.To<Referrer>(),
params->frame_name, params->disposition, *params->features,

View File

@@ -0,0 +1,762 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Geoff Lang <geofflang@chromium.org>
Date: Wed, 11 Feb 2026 08:05:52 -0800
Subject: Ensure the previous complete fbo is not deleted on IMG.
Change-Id: I7d84833312749fc58ecb511b276ff6bd783af1ba
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7533383
Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1583241}
diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc
index 9a913cdefd0681d9972a83d8f940a3c48af0f46d..4a3a68b4415b6cc05eab01f98b1a0afffe73afc9 100644
--- a/gpu/command_buffer/service/context_group.cc
+++ b/gpu/command_buffer/service/context_group.cc
@@ -120,9 +120,17 @@ ContextGroup::ContextGroup(
use_passthrough_cmd_decoder_ = gpu_preferences_.use_passthrough_cmd_decoder;
}
-
gpu::ContextResult ContextGroup::Initialize(DecoderContext* decoder,
ContextType context_type) {
+ return InitializeWithCompleteFramebufferForWorkarounds(decoder, context_type,
+ 0);
+}
+
+gpu::ContextResult
+ContextGroup::InitializeWithCompleteFramebufferForWorkarounds(
+ DecoderContext* decoder,
+ ContextType context_type,
+ uint32_t complete_fbo_for_workarounds) {
switch (context_type) {
case CONTEXT_TYPE_WEBGL1:
if (kGpuFeatureStatusBlocklisted ==
@@ -156,8 +164,9 @@ gpu::ContextResult ContextGroup::Initialize(DecoderContext* decoder,
DisallowedFeatures adjusted_disallowed_features =
GetDisallowedFeatures(context_type);
- feature_info_->Initialize(context_type, use_passthrough_cmd_decoder_,
- adjusted_disallowed_features);
+ feature_info_->InitializeWithCompleteFramebufferForWorkarounds(
+ context_type, use_passthrough_cmd_decoder_, adjusted_disallowed_features,
+ complete_fbo_for_workarounds);
// Fail early if ES3 is requested and driver does not support it.
if ((context_type == CONTEXT_TYPE_WEBGL2 ||
diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h
index 78ea1ccd987cfc6f8ec0e378f906fb19fdccbc19..051d8126c128c47af71d0862cc0ec9476414825e 100644
--- a/gpu/command_buffer/service/context_group.h
+++ b/gpu/command_buffer/service/context_group.h
@@ -72,7 +72,10 @@ class GPU_GLES2_EXPORT ContextGroup : public base::RefCounted<ContextGroup> {
// call to destroy if it succeeds.
gpu::ContextResult Initialize(DecoderContext* decoder,
ContextType context_type);
-
+ gpu::ContextResult InitializeWithCompleteFramebufferForWorkarounds(
+ DecoderContext* decoder,
+ ContextType context_type,
+ uint32_t complete_fbo_for_workarounds);
// Destroys all the resources when called for the last context in the group.
// It should only be called by DecoderContext.
void Destroy(DecoderContext* decoder, bool have_context);
diff --git a/gpu/command_buffer/service/decoder_context.h b/gpu/command_buffer/service/decoder_context.h
index f00ad2459ff2b4993af37ac6fe0a5aa661fee692..96edc25e2d1ce364470b75ec1a3658ed0e217e54 100644
--- a/gpu/command_buffer/service/decoder_context.h
+++ b/gpu/command_buffer/service/decoder_context.h
@@ -139,6 +139,12 @@ class GPU_GLES2_EXPORT DecoderContext : public AsyncAPIInterface,
virtual gles2::ContextGroup* GetContextGroup() = 0;
virtual gles2::ErrorState* GetErrorState() = 0;
+ //
+ // Methods required by GLES2 Decoder helpers
+ //
+ // Bind the framebuffer `service_id` and perform any workarounds needed.
+ virtual void BindFramebuffer(unsigned target, uint32_t service_id) const = 0;
+
//
// Methods required by Texture.
//
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index 14bf6c1a220f7b37fa81ddbc7ac1f2a16fb08e4c..6f1cb7f75f8bc4b80d1bd95be721285bd0bab1a8 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -64,7 +64,8 @@ class ScopedPixelUnpackBufferOverride {
bool IsWebGLDrawBuffersSupported(bool webglCompatibilityContext,
GLenum depth_texture_internal_format,
- GLenum depth_stencil_texture_internal_format) {
+ GLenum depth_stencil_texture_internal_format,
+ GLuint complete_fbo_for_workarounds) {
// This is called after we make sure GL_EXT_draw_buffers is supported.
GLint max_draw_buffers = 0;
GLint max_color_attachments = 0;
@@ -81,6 +82,9 @@ bool IsWebGLDrawBuffersSupported(bool webglCompatibilityContext,
GLuint fbo;
glGenFramebuffersEXT(1, &fbo);
+ if (complete_fbo_for_workarounds) {
+ glBindFramebufferEXT(GL_FRAMEBUFFER, complete_fbo_for_workarounds);
+ }
glBindFramebufferEXT(GL_FRAMEBUFFER, fbo);
GLuint depth_stencil_texture = 0;
@@ -157,6 +161,9 @@ bool IsWebGLDrawBuffersSupported(bool webglCompatibilityContext,
}
}
+ if (complete_fbo_for_workarounds) {
+ glBindFramebufferEXT(GL_FRAMEBUFFER, complete_fbo_for_workarounds);
+ }
glBindFramebufferEXT(GL_FRAMEBUFFER, static_cast<GLuint>(fb_binding));
glDeleteFramebuffersEXT(1, &fbo);
@@ -238,6 +245,15 @@ void FeatureInfo::InitializeBasicState(const base::CommandLine* command_line) {
void FeatureInfo::Initialize(ContextType context_type,
bool is_passthrough_cmd_decoder,
const DisallowedFeatures& disallowed_features) {
+ InitializeWithCompleteFramebufferForWorkarounds(
+ context_type, is_passthrough_cmd_decoder, disallowed_features, 0);
+}
+
+void FeatureInfo::InitializeWithCompleteFramebufferForWorkarounds(
+ ContextType context_type,
+ bool is_passthrough_cmd_decoder,
+ const DisallowedFeatures& disallowed_features,
+ unsigned complete_fbo_for_workarounds) {
if (initialized_) {
DCHECK_EQ(context_type, context_type_);
DCHECK_EQ(is_passthrough_cmd_decoder, is_passthrough_cmd_decoder_);
@@ -248,14 +264,14 @@ void FeatureInfo::Initialize(ContextType context_type,
disallowed_features_ = disallowed_features;
context_type_ = context_type;
is_passthrough_cmd_decoder_ = is_passthrough_cmd_decoder;
- InitializeFeatures();
+ InitializeFeatures(complete_fbo_for_workarounds);
initialized_ = true;
}
void FeatureInfo::ForceReinitialize() {
CHECK(initialized_);
CHECK(is_passthrough_cmd_decoder_);
- InitializeFeatures();
+ InitializeFeatures(0);
}
void FeatureInfo::InitializeForTesting(
@@ -277,7 +293,7 @@ void FeatureInfo::InitializeForTesting(ContextType context_type) {
DisallowedFeatures());
}
-bool IsGL_REDSupportedOnFBOs() {
+bool IsGL_REDSupportedOnFBOs(uint32_t complete_fbo_for_workarounds) {
#if BUILDFLAG(IS_MAC)
// The glTexImage2D call below can hang on Mac so skip this since it's only
// really needed to workaround a Mesa issue. See https://crbug.com/1158744.
@@ -311,6 +327,9 @@ bool IsGL_REDSupportedOnFBOs() {
GL_UNSIGNED_BYTE, nullptr);
GLuint textureFBOID = 0;
glGenFramebuffersEXT(1, &textureFBOID);
+ if (complete_fbo_for_workarounds) {
+ glBindFramebufferEXT(GL_FRAMEBUFFER, complete_fbo_for_workarounds);
+ }
glBindFramebufferEXT(GL_FRAMEBUFFER, textureFBOID);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
textureId, 0);
@@ -319,6 +338,9 @@ bool IsGL_REDSupportedOnFBOs() {
glDeleteFramebuffersEXT(1, &textureFBOID);
glDeleteTextures(1, &textureId);
+ if (complete_fbo_for_workarounds) {
+ glBindFramebufferEXT(GL_FRAMEBUFFER, complete_fbo_for_workarounds);
+ }
glBindFramebufferEXT(GL_FRAMEBUFFER, static_cast<GLuint>(fb_binding));
glBindTexture(GL_TEXTURE_2D, static_cast<GLuint>(tex_binding));
@@ -476,7 +498,7 @@ void FeatureInfo::EnableWEBGLMultiDrawIfPossible(
}
}
-void FeatureInfo::InitializeFeatures() {
+void FeatureInfo::InitializeFeatures(uint32_t complete_fbo_for_workarounds) {
// Figure out what extensions to turn on.
std::string extensions_string(gl::GetGLExtensionsFromCurrentContext());
gfx::ExtensionSet extensions(gfx::MakeExtensionSet(extensions_string));
@@ -1264,9 +1286,9 @@ void FeatureInfo::InitializeFeatures() {
can_emulate_es2_draw_buffers_on_es3_nv) &&
(context_type_ == CONTEXT_TYPE_OPENGLES2 ||
(context_type_ == CONTEXT_TYPE_WEBGL1 &&
- IsWebGLDrawBuffersSupported(is_webgl_compatibility_context,
- depth_texture_format,
- depth_stencil_texture_format)));
+ IsWebGLDrawBuffersSupported(
+ is_webgl_compatibility_context, depth_texture_format,
+ depth_stencil_texture_format, complete_fbo_for_workarounds)));
if (have_es2_draw_buffers) {
AddExtensionString("GL_EXT_draw_buffers");
feature_flags_.ext_draw_buffers = true;
@@ -1387,7 +1409,7 @@ void FeatureInfo::InitializeFeatures() {
if ((gl_version_info_->is_es3 ||
gfx::HasExtension(extensions, "GL_EXT_texture_rg")) &&
- IsGL_REDSupportedOnFBOs()) {
+ IsGL_REDSupportedOnFBOs(complete_fbo_for_workarounds)) {
feature_flags_.ext_texture_rg = true;
AddExtensionString("GL_EXT_texture_rg");
diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h
index 2db3588ca3ed729799b113350ea8a7c449712587..83c683e900a3267061ced97ba971bf9dc0b88f4f 100644
--- a/gpu/command_buffer/service/feature_info.h
+++ b/gpu/command_buffer/service/feature_info.h
@@ -163,6 +163,14 @@ class GPU_GLES2_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> {
bool is_passthrough_cmd_decoder,
const DisallowedFeatures& disallowed_features);
+ // Same as initialize but with a provided `complete_fbo_for_workarounds` to
+ // use with the ensure_previous_framebuffer_not_deleted driver bug workaround.
+ void InitializeWithCompleteFramebufferForWorkarounds(
+ ContextType context_type,
+ bool is_passthrough_cmd_decoder,
+ const DisallowedFeatures& disallowed_features,
+ uint32_t complete_fbo_for_workarounds);
+
// Same as above, but allows reinitialization.
void ForceReinitialize();
@@ -250,7 +258,7 @@ class GPU_GLES2_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> {
void AddExtensionString(std::string_view s);
void InitializeBasicState(const base::CommandLine* command_line);
- void InitializeFeatures();
+ void InitializeFeatures(uint32_t complete_fbo_for_workarounds);
void InitializeFloatAndHalfFloatFeatures(const gfx::ExtensionSet& extensions);
void EnableANGLEInstancedArrayIfPossible(const gfx::ExtensionSet& extensions);
diff --git a/gpu/command_buffer/service/gles2_cmd_copy_tex_image.cc b/gpu/command_buffer/service/gles2_cmd_copy_tex_image.cc
index b500acb4fe7cbff0e84a4e52e66459d5b85fdf75..a08bb3ac4ab625f220865803352e206713763d77 100644
--- a/gpu/command_buffer/service/gles2_cmd_copy_tex_image.cc
+++ b/gpu/command_buffer/service/gles2_cmd_copy_tex_image.cc
@@ -185,7 +185,7 @@ void CopyTexImageResourceManager::DoCopyTexSubImageToLUMACompatibilityTexture(
// framebuffer is copying from a texture and sample directly from that texture
// instead of doing an extra copy
- glBindFramebufferEXT(GL_FRAMEBUFFER, source_framebuffer);
+ decoder->BindFramebuffer(GL_FRAMEBUFFER, source_framebuffer);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, scratch_textures_[0]);
glCopyTexImage2D(GL_TEXTURE_2D, 0, source_framebuffer_internal_format, x, y,
@@ -217,7 +217,7 @@ void CopyTexImageResourceManager::DoCopyTexSubImageToLUMACompatibilityTexture(
glTexImage2D(GL_TEXTURE_2D, 0, compatability_format, width, height, 0,
compatability_format, luma_type, nullptr);
- glBindFramebufferEXT(GL_FRAMEBUFFER, scratch_fbo_);
+ decoder->BindFramebuffer(GL_FRAMEBUFFER, scratch_fbo_);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
scratch_textures_[1], 0);
diff --git a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
index 469642028b839d490199379254a5a44c2fcd7f02..98f476de9e4d423b6ec86f2a69638e43bd0fb423 100644
--- a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
+++ b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
@@ -491,7 +491,8 @@ void DeleteShader(GLuint shader) {
glDeleteShader(shader);
}
-bool BindFramebufferTexture2D(GLenum target,
+bool BindFramebufferTexture2D(DecoderContext* decoder,
+ GLenum target,
GLuint texture_id,
GLint level,
GLuint framebuffer) {
@@ -511,7 +512,7 @@ bool BindFramebufferTexture2D(GLenum target,
glTexParameterf(binding_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(binding_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(binding_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer);
+ decoder->BindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target,
texture_id, level);
@@ -545,7 +546,7 @@ void DoCopyTexImage2D(
DCHECK(dest_binding_target == GL_TEXTURE_2D ||
dest_binding_target == GL_TEXTURE_CUBE_MAP);
DCHECK(source_level == 0 || decoder->GetFeatureInfo()->IsES3Capable());
- if (BindFramebufferTexture2D(source_target, source_id, source_level,
+ if (BindFramebufferTexture2D(decoder, source_target, source_id, source_level,
framebuffer)) {
glBindTexture(dest_binding_target, dest_id);
glTexParameterf(dest_binding_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -603,7 +604,7 @@ void DoCopyTexSubImage2D(
DCHECK(dest_binding_target == GL_TEXTURE_2D ||
dest_binding_target == GL_TEXTURE_CUBE_MAP);
DCHECK(source_level == 0 || decoder->GetFeatureInfo()->IsES3Capable());
- if (BindFramebufferTexture2D(source_target, source_id, source_level,
+ if (BindFramebufferTexture2D(decoder, source_target, source_id, source_level,
framebuffer)) {
glBindTexture(dest_binding_target, dest_id);
glTexParameterf(dest_binding_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -767,7 +768,7 @@ void DoReadbackAndTexImage(TexImageCommandType command_type,
DCHECK(dest_binding_target == GL_TEXTURE_2D ||
dest_binding_target == GL_TEXTURE_CUBE_MAP);
DCHECK(source_level == 0 || decoder->GetFeatureInfo()->IsES3Capable());
- if (BindFramebufferTexture2D(source_target, source_id, source_level,
+ if (BindFramebufferTexture2D(decoder, source_target, source_id, source_level,
framebuffer)) {
glBindTexture(dest_binding_target, dest_id);
glTexParameterf(dest_binding_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -1341,7 +1342,7 @@ void CopyTextureResourceManagerImpl::DoCopyTextureInternal(
(y + height / 2.f) * m_y / source_height);
DCHECK(dest_level == 0 || decoder->GetFeatureInfo()->IsES3Capable());
- if (BindFramebufferTexture2D(dest_target, dest_id, dest_level,
+ if (BindFramebufferTexture2D(decoder, dest_target, dest_id, dest_level,
framebuffer_)) {
#ifndef NDEBUG
// glValidateProgram of MACOSX validates FBO unlike other platforms, so
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 0bb2581fa602217ab77aa429ed51ce0ce5a06f00..895266f5988e2446eadf3d3e1d5c4919416cba76 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -675,6 +675,9 @@ class GLES2DecoderImpl : public GLES2Decoder,
// Implements GpuSwitchingObserver.
void OnGpuSwitched() override;
+ // Bind the framebuffer `fbo` and perform any workarounds needed.
+ void BindFramebuffer(unsigned target, uint32_t service_id) const override;
+
// Restores the current state to the user's settings.
void RestoreCurrentFramebufferBindings();
@@ -2418,6 +2421,10 @@ class GLES2DecoderImpl : public GLES2Decoder,
// Backbuffer attachments that are currently undefined.
uint32_t backbuffer_needs_clear_bits_;
+ // An always-complete FBO to use for workarounds
+ GLuint complete_fbo_ = 0;
+ GLuint complete_fbo_color_texture_ = 0;
+
// The current decoder error communicates the decoder error through command
// processing functions that do not return the error value. Should be set only
// if not returning an error.
@@ -2594,7 +2601,7 @@ ScopedFramebufferBinder::ScopedFramebufferBinder(GLES2DecoderImpl* decoder,
: decoder_(decoder) {
ScopedGLErrorSuppressor suppressor("ScopedFramebufferBinder::ctor",
decoder_->error_state_.get());
- decoder->api()->glBindFramebufferEXTFn(GL_FRAMEBUFFER, id);
+ decoder->BindFramebuffer(GL_FRAMEBUFFER, id);
decoder->OnFboChanged();
}
@@ -2980,7 +2987,27 @@ gpu::ContextResult GLES2DecoderImpl::Initialize(
return gpu::ContextResult::kFatalFailure;
}
- auto result = group_->Initialize(this, context_type);
+ if (workarounds().ensure_previous_framebuffer_not_deleted) {
+ // Use a 1x1 RGBA8 framebuffer as the "always complete" framebuffer to bind
+ // before binding other framebuffers
+ api()->glGenTexturesFn(1, &complete_fbo_color_texture_);
+ api()->glBindTextureFn(GL_TEXTURE_2D, complete_fbo_color_texture_);
+ api()->glTexImage2DFn(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, nullptr);
+
+ api()->glGenFramebuffersEXTFn(1, &complete_fbo_);
+ api()->glBindFramebufferEXTFn(GL_FRAMEBUFFER, complete_fbo_);
+ api()->glFramebufferTexture2DEXTFn(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D,
+ complete_fbo_color_texture_, 0);
+ CHECK_EQ(api()->glCheckFramebufferStatusEXTFn(GL_FRAMEBUFFER),
+ static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE));
+ }
+ CHECK_GL_ERROR();
+
+ auto result = group_->InitializeWithCompleteFramebufferForWorkarounds(
+ this, context_type, complete_fbo_);
+
if (result != gpu::ContextResult::kSuccess) {
// Must not destroy ContextGroup if it is not initialized.
group_ = nullptr;
@@ -3116,7 +3143,7 @@ gpu::ContextResult GLES2DecoderImpl::Initialize(
state_.viewport_width = initial_size.width();
state_.viewport_height = initial_size.height();
} else {
- api()->glBindFramebufferEXTFn(GL_FRAMEBUFFER, GetBackbufferServiceId());
+ BindFramebuffer(GL_FRAMEBUFFER, GetBackbufferServiceId());
// These are NOT if the back buffer has these proprorties. They are
// if we want the command buffer to enforce them regardless of what
// the real backbuffer is assuming the real back buffer gives us more than
@@ -3809,7 +3836,7 @@ void GLES2DecoderImpl::DeleteFramebuffersHelper(
if (workarounds().unbind_attachments_on_bound_render_fbo_delete)
framebuffer->DoUnbindGLAttachmentsForWorkaround(target);
- api()->glBindFramebufferEXTFn(target, GetBackbufferServiceId());
+ BindFramebuffer(target, GetBackbufferServiceId());
state_.UpdateWindowRectanglesForBoundDrawFramebufferClientID(0);
framebuffer_state_.bound_draw_framebuffer = nullptr;
framebuffer_state_.clear_state_dirty = true;
@@ -3817,7 +3844,7 @@ void GLES2DecoderImpl::DeleteFramebuffersHelper(
if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
framebuffer_state_.bound_read_framebuffer = nullptr;
GLenum target = GetReadFramebufferTarget();
- api()->glBindFramebufferEXTFn(target, GetBackbufferServiceId());
+ BindFramebuffer(target, GetBackbufferServiceId());
}
OnFboChanged();
RemoveFramebuffer(client_id);
@@ -3965,33 +3992,32 @@ void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
ProcessPendingReadPixels(false);
}
-static void RebindCurrentFramebuffer(gl::GLApi* api,
- GLenum target,
- Framebuffer* framebuffer,
- GLuint back_buffer_service_id) {
- GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
+void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
+ framebuffer_state_.clear_state_dirty = true;
- if (framebuffer_id == 0) {
- framebuffer_id = back_buffer_service_id;
- }
+ auto rebind_current_framebuffer = [this](GLenum target,
+ Framebuffer* framebuffer,
+ GLuint back_buffer_service_id) {
+ GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
- api->glBindFramebufferEXTFn(target, framebuffer_id);
-}
+ if (framebuffer_id == 0) {
+ framebuffer_id = back_buffer_service_id;
+ }
-void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
- framebuffer_state_.clear_state_dirty = true;
+ BindFramebuffer(target, framebuffer_id);
+ };
if (!SupportsSeparateFramebufferBinds()) {
- RebindCurrentFramebuffer(api(), GL_FRAMEBUFFER,
- framebuffer_state_.bound_draw_framebuffer.get(),
- GetBackbufferServiceId());
+ rebind_current_framebuffer(GL_FRAMEBUFFER,
+ framebuffer_state_.bound_draw_framebuffer.get(),
+ GetBackbufferServiceId());
} else {
- RebindCurrentFramebuffer(api(), GL_READ_FRAMEBUFFER,
- framebuffer_state_.bound_read_framebuffer.get(),
- GetBackbufferServiceId());
- RebindCurrentFramebuffer(api(), GL_DRAW_FRAMEBUFFER,
- framebuffer_state_.bound_draw_framebuffer.get(),
- GetBackbufferServiceId());
+ rebind_current_framebuffer(GL_READ_FRAMEBUFFER,
+ framebuffer_state_.bound_read_framebuffer.get(),
+ GetBackbufferServiceId());
+ rebind_current_framebuffer(GL_DRAW_FRAMEBUFFER,
+ framebuffer_state_.bound_draw_framebuffer.get(),
+ GetBackbufferServiceId());
}
OnFboChanged();
}
@@ -4380,6 +4406,16 @@ void GLES2DecoderImpl::OnGpuSwitched() {
client()->OnGpuSwitched();
}
+void GLES2DecoderImpl::BindFramebuffer(unsigned target,
+ uint32_t service_id) const {
+ if (workarounds().ensure_previous_framebuffer_not_deleted) {
+ DCHECK(complete_fbo_);
+ api()->glBindFramebufferEXTFn(target, complete_fbo_);
+ }
+
+ api()->glBindFramebufferEXTFn(target, service_id);
+}
+
void GLES2DecoderImpl::Destroy(bool have_context) {
if (!initialized())
return;
@@ -4429,6 +4465,13 @@ void GLES2DecoderImpl::Destroy(bool have_context) {
offscreen_target_frame_buffer_->Destroy();
if (offscreen_target_color_texture_.get())
offscreen_target_color_texture_->Destroy();
+
+ if (complete_fbo_color_texture_) {
+ api()->glDeleteTexturesFn(1, &complete_fbo_color_texture_);
+ }
+ if (complete_fbo_) {
+ api()->glDeleteFramebuffersEXTFn(1, &complete_fbo_);
+ }
} else {
if (offscreen_target_frame_buffer_.get())
offscreen_target_frame_buffer_->Invalidate();
@@ -5058,13 +5101,13 @@ void GLES2DecoderImpl::RestoreFramebufferBindings() const {
? framebuffer_state_.bound_draw_framebuffer->service_id()
: GetBackbufferServiceId();
if (!SupportsSeparateFramebufferBinds()) {
- api()->glBindFramebufferEXTFn(GL_FRAMEBUFFER, service_id);
+ BindFramebuffer(GL_FRAMEBUFFER, service_id);
} else {
- api()->glBindFramebufferEXTFn(GL_DRAW_FRAMEBUFFER, service_id);
+ BindFramebuffer(GL_DRAW_FRAMEBUFFER, service_id);
service_id = framebuffer_state_.bound_read_framebuffer.get()
? framebuffer_state_.bound_read_framebuffer->service_id()
: GetBackbufferServiceId();
- api()->glBindFramebufferEXTFn(GL_READ_FRAMEBUFFER, service_id);
+ BindFramebuffer(GL_READ_FRAMEBUFFER, service_id);
}
OnFboChanged();
}
@@ -5205,7 +5248,7 @@ void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
service_id = GetBackbufferServiceId();
}
- api()->glBindFramebufferEXTFn(target, service_id);
+ BindFramebuffer(target, service_id);
OnFboChanged();
}
@@ -6976,8 +7019,7 @@ void GLES2DecoderImpl::ClearUnclearedAttachments(
if (target == GL_READ_FRAMEBUFFER && draw_framebuffer != framebuffer) {
// TODO(zmo): There is no guarantee that an FBO that is complete on the
// READ attachment will be complete as a DRAW attachment.
- api()->glBindFramebufferEXTFn(GL_DRAW_FRAMEBUFFER,
- framebuffer->service_id());
+ BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer->service_id());
}
state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
@@ -7024,8 +7066,7 @@ void GLES2DecoderImpl::ClearUnclearedAttachments(
target == GL_READ_FRAMEBUFFER && draw_framebuffer != framebuffer) {
// TODO(zmo): There is no guarantee that an FBO that is complete on the
// READ attachment will be complete as a DRAW attachment.
- api()->glBindFramebufferEXTFn(GL_DRAW_FRAMEBUFFER,
- framebuffer->service_id());
+ BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer->service_id());
}
state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
ClearDeviceWindowRectangles();
@@ -7043,7 +7084,7 @@ void GLES2DecoderImpl::ClearUnclearedAttachments(
if (target == GL_READ_FRAMEBUFFER && draw_framebuffer != framebuffer) {
GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
GetBackbufferServiceId();
- api()->glBindFramebufferEXTFn(GL_DRAW_FRAMEBUFFER, service_id);
+ BindFramebuffer(GL_DRAW_FRAMEBUFFER, service_id);
}
}
@@ -7900,7 +7941,8 @@ void GLES2DecoderImpl::RenderbufferStorageMultisampleHelperAMD(
bool GLES2DecoderImpl::RegenerateRenderbufferIfNeeded(
Renderbuffer* renderbuffer) {
- if (!renderbuffer->RegenerateAndBindBackingObjectIfNeeded(workarounds())) {
+ if (!renderbuffer->RegenerateAndBindBackingObjectIfNeeded(this,
+ workarounds())) {
return false;
}
@@ -12059,7 +12101,7 @@ bool GLES2DecoderImpl::ClearLevelUsingGL(Texture* texture,
GLenum fb_target = GetDrawFramebufferTarget();
GLuint fb = 0;
api()->glGenFramebuffersEXTFn(1, &fb);
- api()->glBindFramebufferEXTFn(fb_target, fb);
+ BindFramebuffer(fb_target, fb);
bool have_color = (channels & GLES2Util::kRGBA) != 0;
if (have_color) {
@@ -12102,7 +12144,7 @@ bool GLES2DecoderImpl::ClearLevelUsingGL(Texture* texture,
Framebuffer* framebuffer = GetFramebufferInfoForTarget(fb_target);
GLuint fb_service_id =
framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
- api()->glBindFramebufferEXTFn(fb_target, fb_service_id);
+ BindFramebuffer(fb_target, fb_service_id);
return result;
}
@@ -14581,8 +14623,9 @@ error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
new FeatureInfo(workarounds(), group_->gpu_feature_info()));
DisallowedFeatures disallowed_features = feature_info_->disallowed_features();
disallowed_features.AllowExtensions();
- info->Initialize(feature_info_->context_type(),
- false /* is_passthrough_cmd_decoder */, disallowed_features);
+ info->InitializeWithCompleteFramebufferForWorkarounds(
+ feature_info_->context_type(), false /* is_passthrough_cmd_decoder */,
+ disallowed_features, complete_fbo_);
bucket->SetFromString(gfx::MakeExtensionString(info->extensions()).c_str());
return error::kNoError;
}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
index bd3158e174f0881f99c45a0c8b8d5640e3be2b8f..cc160b5771954b485652f4b0cdc6695bfdea9954 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
@@ -147,6 +147,8 @@ class MockGLES2Decoder : public GLES2Decoder {
int height,
int depth));
MOCK_METHOD0(GetErrorState, ErrorState *());
+ MOCK_CONST_METHOD2(BindFramebuffer,
+ void(unsigned target, uint32_t service_id));
MOCK_METHOD0(GetLogger, Logger*());
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
index e8808f50df6d179879bc44fcacfb4154a4ac0454..de9f2f5cfb247a914606d3ba8b24f0924ac728e0 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
@@ -1541,6 +1541,11 @@ gpu::gles2::ErrorState* GLES2DecoderPassthroughImpl::GetErrorState() {
return nullptr;
}
+void GLES2DecoderPassthroughImpl::BindFramebuffer(unsigned target,
+ uint32_t service_id) const {
+ NOTREACHED();
+}
+
void GLES2DecoderPassthroughImpl::WaitForReadPixels(
base::OnceClosure callback) {}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
index 30dc611c8f0a84ec3493e3f865b6640cab157e2a..50938ca4a0086d14493ec7e0d85b99615c0c7fb7 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
@@ -315,6 +315,8 @@ class GPU_GLES2_EXPORT GLES2DecoderPassthroughImpl
ErrorState* GetErrorState() override;
+ void BindFramebuffer(unsigned target, uint32_t service_id) const override;
+
void WaitForReadPixels(base::OnceClosure callback) override;
// Returns true if the context was lost either by GL_ARB_robustness, forced
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc
index 5f61aac4fc217a97ccfcdbd6634056e5f305a425..767fee8cace6dec4cfaf1ccdd46f1764a7ae5318 100644
--- a/gpu/command_buffer/service/raster_decoder.cc
+++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -560,6 +560,7 @@ class RasterDecoderImpl final : public RasterDecoder,
gles2::ContextGroup* GetContextGroup() override;
gles2::ErrorState* GetErrorState() override;
+ void BindFramebuffer(unsigned target, uint32_t service_id) const override;
bool IsCompressedTextureFormat(unsigned format) override;
bool ClearLevel(gles2::Texture* texture,
@@ -1598,6 +1599,11 @@ gles2::ErrorState* RasterDecoderImpl::GetErrorState() {
return error_state_.get();
}
+void RasterDecoderImpl::BindFramebuffer(unsigned target,
+ uint32_t service_id) const {
+ NOTREACHED();
+}
+
bool RasterDecoderImpl::IsCompressedTextureFormat(unsigned format) {
return feature_info()->validators()->compressed_texture_format.IsValid(
format);
diff --git a/gpu/command_buffer/service/renderbuffer_manager.cc b/gpu/command_buffer/service/renderbuffer_manager.cc
index 8075cb3acf7204a661a6c094edc1c1a783d46dfb..6cdb9186c4e3bfe40dd437db6b92343f60830171 100644
--- a/gpu/command_buffer/service/renderbuffer_manager.cc
+++ b/gpu/command_buffer/service/renderbuffer_manager.cc
@@ -15,6 +15,7 @@
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/trace_event.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
+#include "gpu/command_buffer/service/decoder_context.h"
#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/framebuffer_manager.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
@@ -141,6 +142,7 @@ Renderbuffer::Renderbuffer(RenderbufferManager* manager,
}
bool Renderbuffer::RegenerateAndBindBackingObjectIfNeeded(
+ const DecoderContext* decoder,
const GpuDriverBugWorkarounds& workarounds) {
bool multisample_workaround =
workarounds.multisample_renderbuffer_resize_emulation;
@@ -167,7 +169,7 @@ bool Renderbuffer::RegenerateAndBindBackingObjectIfNeeded(
// Attach new renderbuffer to all framebuffers
for (auto& point : framebuffer_attachment_points_) {
- glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, point.first->service_id());
+ decoder->BindFramebuffer(GL_DRAW_FRAMEBUFFER, point.first->service_id());
glFramebufferRenderbufferEXT(GL_DRAW_FRAMEBUFFER, point.second,
GL_RENDERBUFFER, service_id_);
}
diff --git a/gpu/command_buffer/service/renderbuffer_manager.h b/gpu/command_buffer/service/renderbuffer_manager.h
index 7d575387ca8f6a7cb1b4bb020c52f7b53bed5d10..5eabeb9dd160122366507b7dfba53fd1c3285115 100644
--- a/gpu/command_buffer/service/renderbuffer_manager.h
+++ b/gpu/command_buffer/service/renderbuffer_manager.h
@@ -22,6 +22,7 @@
namespace gpu {
class GpuDriverBugWorkarounds;
+class DecoderContext;
namespace gles2 {
@@ -79,6 +80,7 @@ class GPU_GLES2_EXPORT Renderbuffer : public base::RefCounted<Renderbuffer> {
// Regenerates the object backing this client_id, creating a new service_id.
// Also reattaches any framebuffers using this renderbuffer.
bool RegenerateAndBindBackingObjectIfNeeded(
+ const DecoderContext* decoder,
const GpuDriverBugWorkarounds& workarounds);
void AddFramebufferAttachmentPoint(Framebuffer* framebuffer,
diff --git a/gpu/command_buffer/service/webgpu_decoder_impl.cc b/gpu/command_buffer/service/webgpu_decoder_impl.cc
index 172834911e75edb3ed1c4dceb3ec23755bf3b5f6..fb873fee0e4b1d33edd4210fad8ad74c6d563355 100644
--- a/gpu/command_buffer/service/webgpu_decoder_impl.cc
+++ b/gpu/command_buffer/service/webgpu_decoder_impl.cc
@@ -305,6 +305,9 @@ class WebGPUDecoderImpl final : public WebGPUDecoder {
std::string_view GetLogPrefix() override { return "WebGPUDecoderImpl"; }
gles2::ContextGroup* GetContextGroup() override { return nullptr; }
gles2::ErrorState* GetErrorState() override { NOTREACHED(); }
+ void BindFramebuffer(unsigned target, uint32_t service_id) const override {
+ NOTREACHED();
+ }
bool IsCompressedTextureFormat(unsigned format) override { NOTREACHED(); }
bool ClearLevel(gles2::Texture* texture,
unsigned target,
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json
index ebea892a523322b38a22ba6b0442262edcd6166b..2af5b0460beed7b78c00c9f2a70e14e5f7696ac0 100644
--- a/gpu/config/gpu_driver_bug_list.json
+++ b/gpu/config/gpu_driver_bug_list.json
@@ -3818,6 +3818,31 @@
"features": [
"disable_d3d12_video_encoder"
]
+ },
+ {
+ "id": 470,
+ "description": "Disable D3D12 video encoder on Windows versions older 11 24H2",
+ "os": {
+ "type": "win",
+ "version": {
+ "op": "<",
+ "value": "10.0.26100.2033"
+ }
+ },
+ "features": [
+ "disable_d3d12_video_encoder"
+ ]
+ },
+ {
+ "id": 471,
+ "description": "IMG drivers can sometimes reference previously bound complete framebuffers.",
+ "os": {
+ "type": "android"
+ },
+ "gl_vendor": "Imagination.*",
+ "features": [
+ "ensure_previous_framebuffer_not_deleted"
+ ]
}
]
}
diff --git a/gpu/config/gpu_workaround_list.txt b/gpu/config/gpu_workaround_list.txt
index 7f8b6e019f9b1986411b17c4ef1a2e863eb689f0..30ee7799cdd0a344e433e95cd74e4630a7c87aff 100644
--- a/gpu/config/gpu_workaround_list.txt
+++ b/gpu/config/gpu_workaround_list.txt
@@ -78,6 +78,7 @@ dont_delete_source_texture_for_egl_image
dont_use_loops_to_initialize_variables
enable_bgra8_overlays_with_yuv_overlay_support
enable_webgl_timer_query_extensions
+ensure_previous_framebuffer_not_deleted
etc1_power_of_two_only
exit_on_context_lost
flush_before_create_fence

View File

@@ -65,7 +65,7 @@ index 2748dd196fe1f56357348a204e24f0b8a28b97dd..5800dd00b47c657d9e6766f3fc5a3065
#if BUILDFLAG(IS_WIN)
bool EscapeVirtualization(const base::FilePath& user_data_dir);
diff --git a/chrome/browser/process_singleton_posix.cc b/chrome/browser/process_singleton_posix.cc
index 73aa4cb9652870b0bff4684d7c72ae7dbd852db8..b55c942a8ccb326e4898172a7b4f6c0aa3183a0b 100644
index 73aa4cb9652870b0bff4684d7c72ae7dbd852db8..144788ceadea85c9d1fae12d1ba4dbc1fc7cd699 100644
--- a/chrome/browser/process_singleton_posix.cc
+++ b/chrome/browser/process_singleton_posix.cc
@@ -619,6 +619,7 @@ class ProcessSingleton::LinuxWatcher
@@ -106,22 +106,41 @@ index 73aa4cb9652870b0bff4684d7c72ae7dbd852db8..b55c942a8ccb326e4898172a7b4f6c0a
const size_t kMinMessageLength = kStartToken.length() + 4;
if (bytes_read_ < kMinMessageLength) {
buf_[bytes_read_] = 0;
@@ -745,10 +751,26 @@ void ProcessSingleton::LinuxWatcher::SocketReader::
@@ -745,10 +751,45 @@ void ProcessSingleton::LinuxWatcher::SocketReader::
tokens.erase(tokens.begin());
tokens.erase(tokens.begin());
+ size_t num_args;
+ base::StringToSizeT(tokens[0], &num_args);
+ std::vector<std::string> command_line(tokens.begin() + 1, tokens.begin() + 1 + num_args);
+ if (!base::StringToSizeT(tokens[0], &num_args) ||
+ num_args > tokens.size() - 1) {
+ LOG(ERROR) << "Invalid num_args in socket message";
+ CleanupAndDeleteSelf();
+ return;
+ }
+ std::vector<std::string> command_line(tokens.begin() + 1,
+ tokens.begin() + 1 + num_args);
+
+ std::vector<uint8_t> additional_data;
+ if (tokens.size() >= 3 + num_args) {
+ // After consuming [num_args, argv...], two more tokens are needed for
+ // additional data: [size, payload]. Subtract to avoid overflow when
+ // num_args is large.
+ if (tokens.size() - 1 - num_args >= 2) {
+ size_t additional_data_size;
+ base::StringToSizeT(tokens[1 + num_args], &additional_data_size);
+ if (!base::StringToSizeT(tokens[1 + num_args], &additional_data_size)) {
+ LOG(ERROR) << "Invalid additional_data_size in socket message";
+ CleanupAndDeleteSelf();
+ return;
+ }
+ std::string remaining_args = base::JoinString(
+ base::span(tokens).subspan(2 + num_args),
+ std::string(1, kTokenDelimiter));
+ const auto adspan = base::as_byte_span(remaining_args).first(additional_data_size);
+ if (additional_data_size > remaining_args.size()) {
+ LOG(ERROR) << "additional_data_size exceeds payload length";
+ CleanupAndDeleteSelf();
+ return;
+ }
+ const auto adspan =
+ base::as_byte_span(remaining_args).first(additional_data_size);
+ additional_data.assign(adspan.begin(), adspan.end());
+ }
+
@@ -134,7 +153,7 @@ index 73aa4cb9652870b0bff4684d7c72ae7dbd852db8..b55c942a8ccb326e4898172a7b4f6c0a
fd_watch_controller_.reset();
// LinuxWatcher::HandleMessage() is in charge of destroying this SocketReader
@@ -777,8 +799,10 @@ void ProcessSingleton::LinuxWatcher::SocketReader::FinishWithACK(
@@ -777,8 +818,10 @@ void ProcessSingleton::LinuxWatcher::SocketReader::FinishWithACK(
//
ProcessSingleton::ProcessSingleton(
const base::FilePath& user_data_dir,
@@ -145,7 +164,7 @@ index 73aa4cb9652870b0bff4684d7c72ae7dbd852db8..b55c942a8ccb326e4898172a7b4f6c0a
current_pid_(base::GetCurrentProcId()) {
socket_path_ = user_data_dir.Append(chrome::kSingletonSocketFilename);
lock_path_ = user_data_dir.Append(chrome::kSingletonLockFilename);
@@ -899,7 +923,8 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
@@ -899,7 +942,8 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
sizeof(socket_timeout));
// Found another process, prepare our command line
@@ -155,7 +174,7 @@ index 73aa4cb9652870b0bff4684d7c72ae7dbd852db8..b55c942a8ccb326e4898172a7b4f6c0a
std::string to_send(kStartToken);
to_send.push_back(kTokenDelimiter);
@@ -909,11 +934,21 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
@@ -909,11 +953,21 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
to_send.append(current_dir.value());
const std::vector<std::string>& argv = cmd_line.argv();
@@ -178,10 +197,18 @@ index 73aa4cb9652870b0bff4684d7c72ae7dbd852db8..b55c942a8ccb326e4898172a7b4f6c0a
if (!WriteToSocket(socket.fd(), to_send)) {
// Try to kill the other process, because it might have been dead.
diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc
index ae659d84a5ae2f2e87ce288477506575f8d86839..d93c7e8487ab1a2bbb5f56f2ca44868f947e6bfc 100644
index ae659d84a5ae2f2e87ce288477506575f8d86839..274887d62ff8d008bb86815a11205fcaa5f2c2ff 100644
--- a/chrome/browser/process_singleton_win.cc
+++ b/chrome/browser/process_singleton_win.cc
@@ -81,10 +81,12 @@ BOOL CALLBACK BrowserWindowEnumeration(HWND window, LPARAM param) {
@@ -9,6 +9,7 @@
#include <shellapi.h>
#include <stddef.h>
+#include "base/base64.h"
#include "base/base_paths.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
@@ -81,10 +82,12 @@ BOOL CALLBACK BrowserWindowEnumeration(HWND window, LPARAM param) {
bool ParseCommandLine(const COPYDATASTRUCT* cds,
base::CommandLine* parsed_command_line,
@@ -196,7 +223,7 @@ index ae659d84a5ae2f2e87ce288477506575f8d86839..d93c7e8487ab1a2bbb5f56f2ca44868f
static const int min_message_size = 7;
if (cds->cbData < min_message_size * sizeof(wchar_t) ||
cds->cbData % sizeof(wchar_t) != 0) {
@@ -134,6 +136,23 @@ bool ParseCommandLine(const COPYDATASTRUCT* cds,
@@ -134,6 +137,25 @@ bool ParseCommandLine(const COPYDATASTRUCT* cds,
const std::wstring cmd_line =
msg.substr(second_null + 1, third_null - second_null);
*parsed_command_line = base::CommandLine::FromString(cmd_line);
@@ -209,18 +236,20 @@ index ae659d84a5ae2f2e87ce288477506575f8d86839..d93c7e8487ab1a2bbb5f56f2ca44868f
+ return true;
+ }
+
+ // Get the actual additional data.
+ const std::wstring additional_data =
+ msg.substr(third_null + 1, fourth_null - third_null);
+ base::span<const uint8_t> additional_data_bytes =
+ base::as_byte_span(additional_data);
+ *parsed_additional_data = std::vector<uint8_t>(
+ additional_data_bytes.begin(), additional_data_bytes.end());
+ // Get the actual additional data. It is base64-encoded so it can
+ // safely traverse the null-delimited wchar_t buffer.
+ const std::wstring encoded_w =
+ msg.substr(third_null + 1, fourth_null - third_null - 1);
+ std::string encoded = base::WideToASCII(encoded_w);
+ std::optional<std::vector<uint8_t>> decoded = base::Base64Decode(encoded);
+ if (decoded) {
+ *parsed_additional_data = std::move(*decoded);
+ }
+
return true;
}
return false;
@@ -155,13 +174,14 @@ bool ProcessLaunchNotification(
@@ -155,13 +177,14 @@ bool ProcessLaunchNotification(
base::CommandLine parsed_command_line(base::CommandLine::NO_PROGRAM);
base::FilePath current_directory;
@@ -238,7 +267,7 @@ index ae659d84a5ae2f2e87ce288477506575f8d86839..d93c7e8487ab1a2bbb5f56f2ca44868f
return true;
}
@@ -265,9 +285,11 @@ bool ProcessSingleton::EscapeVirtualization(
@@ -265,9 +288,11 @@ bool ProcessSingleton::EscapeVirtualization(
ProcessSingleton::ProcessSingleton(
const std::string& program_name,
const base::FilePath& user_data_dir,
@@ -250,7 +279,7 @@ index ae659d84a5ae2f2e87ce288477506575f8d86839..d93c7e8487ab1a2bbb5f56f2ca44868f
program_name_(program_name),
is_app_sandboxed_(is_app_sandboxed),
is_virtualized_(false),
@@ -294,7 +316,7 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
@@ -294,7 +319,7 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
return PROCESS_NONE;
}
@@ -260,10 +289,18 @@ index ae659d84a5ae2f2e87ce288477506575f8d86839..d93c7e8487ab1a2bbb5f56f2ca44868f
return PROCESS_NOTIFIED;
case NotifyChromeResult::kFailed:
diff --git a/chrome/browser/win/chrome_process_finder.cc b/chrome/browser/win/chrome_process_finder.cc
index 594f3bc08a4385c177fb488123cef79448e94850..5a1dde19a4bc2bf728eba4c738f831c3e5b73942 100644
index 594f3bc08a4385c177fb488123cef79448e94850..28e5a18a19718b2e748ada6882341413a1ab0705 100644
--- a/chrome/browser/win/chrome_process_finder.cc
+++ b/chrome/browser/win/chrome_process_finder.cc
@@ -39,7 +39,9 @@ HWND FindRunningChromeWindow(const base::FilePath& user_data_dir) {
@@ -11,6 +11,7 @@
#include <string>
#include <string_view>
+#include "base/base64.h"
#include "base/check.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
@@ -39,7 +40,9 @@ HWND FindRunningChromeWindow(const base::FilePath& user_data_dir) {
return base::win::MessageWindow::FindWindow(user_data_dir.value());
}
@@ -274,7 +311,7 @@ index 594f3bc08a4385c177fb488123cef79448e94850..5a1dde19a4bc2bf728eba4c738f831c3
TRACE_EVENT0("startup", "AttemptToNotifyRunningChrome");
DCHECK(remote_window);
@@ -70,12 +72,24 @@ NotifyChromeResult AttemptToNotifyRunningChrome(HWND remote_window) {
@@ -70,12 +73,22 @@ NotifyChromeResult AttemptToNotifyRunningChrome(HWND remote_window) {
new_command_line.AppendSwitch(switches::kSourceAppId);
}
// Send the command line to the remote chrome window.
@@ -286,14 +323,12 @@ index 594f3bc08a4385c177fb488123cef79448e94850..5a1dde19a4bc2bf728eba4c738f831c3
std::wstring_view{L"\0", 1}, new_command_line.GetCommandLineString(),
std::wstring_view{L"\0", 1}});
+ size_t additional_data_size = additional_data.size_bytes();
+ if (additional_data_size) {
+ size_t padded_size = additional_data_size / sizeof(wchar_t);
+ if (additional_data_size % sizeof(wchar_t) != 0) {
+ padded_size++;
+ }
+ to_send.append(reinterpret_cast<const wchar_t*>(additional_data.data()),
+ padded_size);
+ if (!additional_data.empty()) {
+ // Base64-encode so the payload survives the null-delimited wchar_t
+ // framing; raw serialized bytes can contain 0x0000 sequences which
+ // would otherwise terminate the field early.
+ std::string encoded = base::Base64Encode(additional_data);
+ to_send.append(base::ASCIIToWide(encoded));
+ to_send.append(L"\0", 1); // Null separator.
+ }
+

View File

@@ -9,6 +9,8 @@ Subject: feat: configure launch options for service process
Allows configuring base::LaunchOptions::handles_to_inherit, base::LaunchOptions::stdout_handle,
base::LaunchOptions::stderr_handle and base::LaunchOptions::feedback_cursor_off when launching
the child process.
- Mac:
Allows configuring base::LaunchOptions::disclaim_responsibility when launching the child process.
- All:
Allows configuring base::LauncOptions::current_directory, base::LaunchOptions::enviroment
and base::LaunchOptions::clear_environment.
@@ -165,10 +167,10 @@ index 0791b5317fc6846389f65f93734ae5e816d04623..71df2459fd759a75be573449accd3a4d
FinishStartSandboxedProcessOnLauncherThread,
this));
diff --git a/content/browser/service_host/service_process_host_impl.cc b/content/browser/service_host/service_process_host_impl.cc
index d9c14f91747bde0e76056d7f2f2ada166e67f994..53be16879777a3b9bef58ead5f7e420c1bf6acbe 100644
index d9c14f91747bde0e76056d7f2f2ada166e67f994..09335acac17f526fb8d8e42e4b2d993b11045786 100644
--- a/content/browser/service_host/service_process_host_impl.cc
+++ b/content/browser/service_host/service_process_host_impl.cc
@@ -69,6 +69,17 @@ void LaunchServiceProcess(mojo::GenericPendingReceiver receiver,
@@ -69,6 +69,21 @@ void LaunchServiceProcess(mojo::GenericPendingReceiver receiver,
utility_options.WithGpuClientAllowed();
}
@@ -179,6 +181,10 @@ index d9c14f91747bde0e76056d7f2f2ada166e67f994..53be16879777a3b9bef58ead5f7e420c
+#elif BUILDFLAG(IS_POSIX)
+ utility_options.WithAdditionalFds(std::move(service_options.fds_to_remap));
+#endif
+#if BUILDFLAG(IS_MAC)
+ utility_options.WithDisclaimResponsibility(
+ service_options.disclaim_responsibility);
+#endif
+ utility_options.WithCurrentDirectory(service_options.current_directory);
+ utility_options.WithEnvironment(service_options.environment,
+ service_options.clear_environment);
@@ -187,7 +193,7 @@ index d9c14f91747bde0e76056d7f2f2ada166e67f994..53be16879777a3b9bef58ead5f7e420c
UtilityProcessHost::Start(std::move(utility_options),
diff --git a/content/browser/service_host/utility_process_host.cc b/content/browser/service_host/utility_process_host.cc
index c798b3394db7638e38613a016c2dbb0bfcf54d03..1298ea85a176db2150a4101afc205745f32eb8f5 100644
index c798b3394db7638e38613a016c2dbb0bfcf54d03..e90c8a9b2ac7d17fe7e5e814fd6eb3333f440bbe 100644
--- a/content/browser/service_host/utility_process_host.cc
+++ b/content/browser/service_host/utility_process_host.cc
@@ -241,13 +241,13 @@ UtilityProcessHost::Options& UtilityProcessHost::Options::WithFileToPreload(
@@ -207,7 +213,7 @@ index c798b3394db7638e38613a016c2dbb0bfcf54d03..1298ea85a176db2150a4101afc205745
#if BUILDFLAG(USE_ZYGOTE)
UtilityProcessHost::Options& UtilityProcessHost::Options::WithZygoteForTesting(
@@ -257,6 +257,36 @@ UtilityProcessHost::Options& UtilityProcessHost::Options::WithZygoteForTesting(
@@ -257,6 +257,45 @@ UtilityProcessHost::Options& UtilityProcessHost::Options::WithZygoteForTesting(
}
#endif // BUILDFLAG(USE_ZYGOTE)
@@ -240,11 +246,20 @@ index c798b3394db7638e38613a016c2dbb0bfcf54d03..1298ea85a176db2150a4101afc205745
+ return *this;
+}
+#endif // BUILDFLAG(IS_WIN)
+
+#if BUILDFLAG(IS_MAC)
+UtilityProcessHost::Options&
+UtilityProcessHost::Options::WithDisclaimResponsibility(
+ bool disclaim_responsibility) {
+ disclaim_responsibility_ = disclaim_responsibility;
+ return *this;
+}
+#endif // BUILDFLAG(IS_MAC)
+
UtilityProcessHost::Options&
UtilityProcessHost::Options::WithBoundReceiverOnChildProcessForTesting(
mojo::GenericPendingReceiver receiver) {
@@ -520,9 +550,26 @@ bool UtilityProcessHost::StartProcess() {
@@ -520,9 +559,30 @@ bool UtilityProcessHost::StartProcess() {
}
#endif // BUILDFLAG(ENABLE_GPU_CHANNEL_MEDIA_CAPTURE) && !BUILDFLAG(IS_WIN)
@@ -269,11 +284,15 @@ index c798b3394db7638e38613a016c2dbb0bfcf54d03..1298ea85a176db2150a4101afc205745
+#if BUILDFLAG(IS_WIN)
+ delegate->SetFeedbackCursorOff(options_.feedback_cursor_off_);
+#endif // BUILDFLAG(IS_WIN)
+
+#if BUILDFLAG(IS_MAC)
+ delegate->SetDisclaimResponsibility(options_.disclaim_responsibility_);
+#endif // BUILDFLAG(IS_MAC)
#if BUILDFLAG(IS_WIN)
if (!options_.preload_libraries_.empty()) {
diff --git a/content/browser/service_host/utility_process_host.h b/content/browser/service_host/utility_process_host.h
index dfdcb66d65f07f4543703396eb529a6ec02b3f4a..d731211d727f6e96533a058106c13f339263712d 100644
index dfdcb66d65f07f4543703396eb529a6ec02b3f4a..96c0cadf5caf5bf27f2a767c43f0f1da04298800 100644
--- a/content/browser/service_host/utility_process_host.h
+++ b/content/browser/service_host/utility_process_host.h
@@ -30,6 +30,7 @@
@@ -284,7 +303,7 @@ index dfdcb66d65f07f4543703396eb529a6ec02b3f4a..d731211d727f6e96533a058106c13f33
#endif // BUILDFLAG(IS_WIN)
namespace base {
@@ -133,14 +134,31 @@ class CONTENT_EXPORT UtilityProcessHost final
@@ -133,14 +134,36 @@ class CONTENT_EXPORT UtilityProcessHost final
std::variant<base::FilePath, base::ScopedFD> file);
#endif
@@ -315,11 +334,16 @@ index dfdcb66d65f07f4543703396eb529a6ec02b3f4a..d731211d727f6e96533a058106c13f33
+ // Specifies if the process should trigger mouse cursor feedback.
+ Options& WithFeedbackCursorOff(bool feedback_cursor_off);
+#endif // BUILDFLAG(IS_WIN)
+
+#if BUILDFLAG(IS_MAC)
+ // Specifies if the process should disclaim TCC responsibility.
+ Options& WithDisclaimResponsibility(bool disclaim_responsibility);
+#endif // BUILDFLAG(IS_MAC)
+
// Requests that the process bind a receiving pipe targeting the interface
// named by `receiver`. Calls to this method generally end up in
// `ChildThreadImpl::OnBindReceiver()` and the option is used for testing
@@ -184,6 +202,27 @@ class CONTENT_EXPORT UtilityProcessHost final
@@ -184,6 +207,32 @@ class CONTENT_EXPORT UtilityProcessHost final
std::optional<raw_ptr<ZygoteCommunication>> zygote_for_testing_;
#endif // BUILDFLAG(USE_ZYGOTE)
@@ -343,12 +367,17 @@ index dfdcb66d65f07f4543703396eb529a6ec02b3f4a..d731211d727f6e96533a058106c13f33
+ // Specifies if the process should trigger mouse cursor feedback.
+ bool feedback_cursor_off_ = false;
+#endif // BUILDFLAG(IS_WIN)
+
+#if BUILDFLAG(IS_MAC)
+ // Specifies if the process should disclaim TCC responsibility.
+ bool disclaim_responsibility_ = false;
+#endif // BUILDFLAG(IS_MAC)
+
#if BUILDFLAG(ENABLE_GPU_CHANNEL_MEDIA_CAPTURE)
// Whether or not to bind viz::mojom::Gpu to the utility process.
bool allowed_gpu_;
diff --git a/content/browser/service_host/utility_sandbox_delegate.cc b/content/browser/service_host/utility_sandbox_delegate.cc
index ada7034c8926c276ea1c7ebf8242c61b0a993c39..b852d40936f1e876681a00f2eb57c9077a086a1d 100644
index ada7034c8926c276ea1c7ebf8242c61b0a993c39..aec3de8bd0c18666b33147779cad68c6b41fe1fe 100644
--- a/content/browser/service_host/utility_sandbox_delegate.cc
+++ b/content/browser/service_host/utility_sandbox_delegate.cc
@@ -39,17 +39,19 @@ UtilitySandboxedProcessLauncherDelegate::
@@ -406,8 +435,24 @@ index ada7034c8926c276ea1c7ebf8242c61b0a993c39..b852d40936f1e876681a00f2eb57c907
#if BUILDFLAG(USE_ZYGOTE)
ZygoteCommunication* UtilitySandboxedProcessLauncherDelegate::GetZygote() {
@@ -189,6 +208,15 @@ UtilitySandboxedProcessLauncherDelegate::GetProcessRequirement() {
return std::nullopt;
}
+
+void UtilitySandboxedProcessLauncherDelegate::SetDisclaimResponsibility(
+ bool disclaim_responsibility) {
+ disclaim_responsibility_ = disclaim_responsibility;
+}
+
+bool UtilitySandboxedProcessLauncherDelegate::DisclaimResponsibility() {
+ return disclaim_responsibility_;
+}
#endif // BUILDFLAG(IS_MAC)
} // namespace content
diff --git a/content/browser/service_host/utility_sandbox_delegate.h b/content/browser/service_host/utility_sandbox_delegate.h
index f2e8c1d62c1cb1677f618b584ed401685b03034b..7c47ec471e4676365cf3e023808983cb3e7a18d0 100644
index f2e8c1d62c1cb1677f618b584ed401685b03034b..00a20885092bd299e817685dd18c3971b25f721b 100644
--- a/content/browser/service_host/utility_sandbox_delegate.h
+++ b/content/browser/service_host/utility_sandbox_delegate.h
@@ -36,7 +36,9 @@ class CONTENT_EXPORT UtilitySandboxedProcessLauncherDelegate
@@ -438,7 +483,12 @@ index f2e8c1d62c1cb1677f618b584ed401685b03034b..7c47ec471e4676365cf3e023808983cb
#if BUILDFLAG(USE_ZYGOTE)
void SetZygote(ZygoteCommunication* handle);
@@ -77,9 +84,7 @@ class CONTENT_EXPORT UtilitySandboxedProcessLauncherDelegate
@@ -74,12 +81,12 @@ class CONTENT_EXPORT UtilitySandboxedProcessLauncherDelegate
#if BUILDFLAG(IS_MAC)
std::optional<base::mac::ProcessRequirement> GetProcessRequirement() override;
+ void SetDisclaimResponsibility(bool disclaim_responsibility);
+ bool DisclaimResponsibility() override;
#endif // BUILDFLAG(IS_MAC)
private:
@@ -448,7 +498,7 @@ index f2e8c1d62c1cb1677f618b584ed401685b03034b..7c47ec471e4676365cf3e023808983cb
#if BUILDFLAG(IS_WIN)
// Adds preload-libraries to the delegate blob for utility_main() to access
@@ -95,12 +100,17 @@ class CONTENT_EXPORT UtilitySandboxedProcessLauncherDelegate
@@ -95,12 +102,20 @@ class CONTENT_EXPORT UtilitySandboxedProcessLauncherDelegate
std::optional<raw_ptr<ZygoteCommunication>> zygote_;
#endif // BUILDFLAG(USE_ZYGOTE)
@@ -463,6 +513,9 @@ index f2e8c1d62c1cb1677f618b584ed401685b03034b..7c47ec471e4676365cf3e023808983cb
+#if BUILDFLAG(IS_WIN)
+ bool feedback_cursor_off_ = false;
+#endif // BUILDFLAG(IS_WIN)
+#if BUILDFLAG(IS_MAC)
+ bool disclaim_responsibility_ = false;
+#endif // BUILDFLAG(IS_MAC)
};
} // namespace content
@@ -489,10 +542,10 @@ index 39c96d4423b24695eee86353057cfeed19318b57..31b343d97b7672294644041c9bb1a4cd
}
diff --git a/content/public/browser/service_process_host.cc b/content/public/browser/service_process_host.cc
index d1bc550a891979e2d41d8d5b18a2f9287468e460..5fcac7a8493e5065f80303067a04f59e7c4509ef 100644
index d1bc550a891979e2d41d8d5b18a2f9287468e460..5d255f628788bc8b40d8df0039b08c06ffec8730 100644
--- a/content/public/browser/service_process_host.cc
+++ b/content/public/browser/service_process_host.cc
@@ -53,12 +53,53 @@ ServiceProcessHost::Options::WithExtraCommandLineSwitches(
@@ -53,12 +53,62 @@ ServiceProcessHost::Options::WithExtraCommandLineSwitches(
return *this;
}
@@ -542,12 +595,21 @@ index d1bc550a891979e2d41d8d5b18a2f9287468e460..5fcac7a8493e5065f80303067a04f59e
+ return *this;
+}
+#endif // #if BUILDFLAG(IS_WIN)
+
+#if BUILDFLAG(IS_MAC)
+ServiceProcessHost::Options&
+ServiceProcessHost::Options::WithDisclaimResponsibility(
+ bool should_disclaim_responsibility) {
+ disclaim_responsibility = should_disclaim_responsibility;
+ return *this;
+}
+#endif // BUILDFLAG(IS_MAC)
+
#if BUILDFLAG(IS_WIN)
ServiceProcessHost::Options&
ServiceProcessHost::Options::WithPreloadedLibraries(
diff --git a/content/public/browser/service_process_host.h b/content/public/browser/service_process_host.h
index 0062d2cb6634b8b29977a0312516b1b13936b40a..611a52e908f4cb70fbe5628e220a082e45320b70 100644
index 0062d2cb6634b8b29977a0312516b1b13936b40a..888ff36d70c83010f1f45e9eeb2dd6b573158db5 100644
--- a/content/public/browser/service_process_host.h
+++ b/content/public/browser/service_process_host.h
@@ -14,6 +14,7 @@
@@ -569,7 +631,7 @@ index 0062d2cb6634b8b29977a0312516b1b13936b40a..611a52e908f4cb70fbe5628e220a082e
namespace base {
class Process;
} // namespace base
@@ -94,11 +99,35 @@ class CONTENT_EXPORT ServiceProcessHost {
@@ -94,11 +99,40 @@ class CONTENT_EXPORT ServiceProcessHost {
// Specifies extra command line switches to append before launch.
Options& WithExtraCommandLineSwitches(std::vector<std::string> switches);
@@ -601,11 +663,16 @@ index 0062d2cb6634b8b29977a0312516b1b13936b40a..611a52e908f4cb70fbe5628e220a082e
+ // Specifies if the process should trigger mouse cursor feedback.
+ Options& WithFeedbackCursorOff(bool feedback_cursor_off);
+#endif // #if BUILDFLAG(IS_WIN)
+
+#if BUILDFLAG(IS_MAC)
+ // Specifies if the process should disclaim TCC responsibility.
+ Options& WithDisclaimResponsibility(bool disclaim_responsibility);
+#endif // BUILDFLAG(IS_MAC)
+
#if BUILDFLAG(IS_WIN)
// Specifies libraries to preload before the sandbox is locked down. Paths
// should be absolute paths. Libraries will be preloaded before sandbox
@@ -127,11 +156,23 @@ class CONTENT_EXPORT ServiceProcessHost {
@@ -127,11 +161,26 @@ class CONTENT_EXPORT ServiceProcessHost {
std::optional<GURL> site;
std::optional<int> child_flags;
std::vector<std::string> extra_switches;
@@ -626,6 +693,9 @@ index 0062d2cb6634b8b29977a0312516b1b13936b40a..611a52e908f4cb70fbe5628e220a082e
+#if BUILDFLAG(IS_WIN)
+ bool feedback_cursor_off = false;
+#endif // BUILDFLAG(IS_WIN)
+#if BUILDFLAG(IS_MAC)
+ bool disclaim_responsibility = false;
+#endif // BUILDFLAG(IS_MAC)
};
// An interface which can be implemented and registered/unregistered with

View File

@@ -84,10 +84,10 @@ index 2648adb1cf38ab557b66ffd0e3034b26b04d76d6..98eab587f343f6ca472efc3d4e7b31b2
private:
const std::string service_interface_name_;
diff --git a/content/browser/service_host/utility_process_host.cc b/content/browser/service_host/utility_process_host.cc
index 1298ea85a176db2150a4101afc205745f32eb8f5..1668345fb66b5a150b01dc3cce2e7262890a9c66 100644
index e90c8a9b2ac7d17fe7e5e814fd6eb3333f440bbe..4e11fbf6b5489acc212256fbedc1b9b2d627f7e4 100644
--- a/content/browser/service_host/utility_process_host.cc
+++ b/content/browser/service_host/utility_process_host.cc
@@ -624,7 +624,7 @@ void UtilityProcessHost::OnProcessCrashed(int exit_code) {
@@ -637,7 +637,7 @@ void UtilityProcessHost::OnProcessCrashed(int exit_code) {
: Client::CrashType::kPreIpcInitialization;
}
#endif // BUILDFLAG(IS_WIN)
@@ -97,7 +97,7 @@ index 1298ea85a176db2150a4101afc205745f32eb8f5..1668345fb66b5a150b01dc3cce2e7262
std::optional<std::string> UtilityProcessHost::GetServiceName() {
diff --git a/content/browser/service_host/utility_process_host.h b/content/browser/service_host/utility_process_host.h
index d731211d727f6e96533a058106c13f339263712d..19e35a0684746d6f5703ac4237de4d8aeddbaa4e 100644
index 96c0cadf5caf5bf27f2a767c43f0f1da04298800..5a16fe5c01ae7777064168e8883ec8ec0b82a873 100644
--- a/content/browser/service_host/utility_process_host.h
+++ b/content/browser/service_host/utility_process_host.h
@@ -87,7 +87,7 @@ class CONTENT_EXPORT UtilityProcessHost final

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