Compare commits

...

94 Commits

Author SHA1 Message Date
trop[bot]
8a42df2b63 docs: fix some string enum typings (#49932)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2026-02-24 11:18:59 -05:00
trop[bot]
47e54e38de fix: updated Alt detection to explicitly exclude AltGraph/AltGr (#49914)
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:37 -08:00
trop[bot]
6ad3726bfa fix: prevent GBytes leak in GdkPixbufFromSkBitmap on Linux/GTK (#49896)
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 14:58:00 -08:00
trop[bot]
a9c0dc5d6c fix: refresh menu item state on key equivalent dispatch (#49888)
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:59:32 -05:00
trop[bot]
6b0aef1d59 ci: log mocha retries in spec runner (#49879)
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 17:54:42 -06:00
Sam Maddock
e54b5eec81 fix: frameless window resize in MAS builds (#49861)
fix: frameless window resize in MAS builds (#49780)

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-02-19 09:53:55 +01:00
trop[bot]
79f164a724 docs: note required windows in 'new-window-for-tab' event (#49858)
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:35:19 -08:00
trop[bot]
0bcaabff0c feat: add support for long-animation-frame script attribution (#49771)
* 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 16:19:21 -05:00
trop[bot]
2ffb9e1e05 fix: draggable region position with docked DevTools (#49846)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-02-18 15:01:01 -05:00
trop[bot]
02e6c95754 build: use spawn instead of spawnSync for build (#49829)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
2026-02-18 12:34:35 +01:00
trop[bot]
46e18e8263 docs: fix typos across tutorial documentation (#49834)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: ron <ronald_eddy@yahoo.com>
2026-02-17 15:05:01 -05:00
trop[bot]
4b6eb69fd0 chore: add Copilot CLI instructions (#49820)
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:27:08 -05:00
Keeley Hammond
a229dbf7a5 chore: cherry-pick e045399a1ecb from chromium (#49791)
* chore: cherry-pick e045399a1ecb from chromium

* chore: update patch
2026-02-12 18:35:12 -08:00
John Kleinschmidt
cad033849b build: generate artifact attestions for released assets (#49769)
* build: generate artifact attestions for released assets (#48239)

* build: generate artifact attestions for released assets

* chore: address review feedback

---------

Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
(cherry picked from commit dec7f937ae)

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

(cherry picked from commit 0852893910)

* chore: update publish workflow

---------

Co-authored-by: Samuel Attard <sam@electronjs.org>
2026-02-12 10:51:35 -05:00
Keeley Hammond
16fc71f561 feat: add support for disclaiming utility processes (#49696)
feat: add support for disclaiming utility processes (#49128)

* feat: add support for disclaiming utility processes

* chore: update patches

---------
2026-02-12 10:32:09 -05:00
trop[bot]
f521b01eb8 build(dev-deps): update micromark-core-commonmark to 2.0.3 (#49760)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2026-02-11 15:53:31 -05:00
trop[bot]
1a9c08914b ci: add markdownlint problem matcher (#49765)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2026-02-11 13:58:04 -05:00
trop[bot]
0aba4a6ab8 fix: address upstream Chromium shift to enable CoreAudio Tap API for audio capture used in electron's desktopCapturer (🍏 macOS). (#49740)
* 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-11 11:05:24 +01:00
trop[bot]
c49899af4c ci: fix patches changes detected in apply patches workflow (#49709)
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:56 -08:00
trop[bot]
92ef86b64a refactor: don't log error just for unsigned code (#49675)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Noah Gregory <noahmgregory@gmail.com>
2026-02-06 14:28:19 -08:00
Robo
30d8e1834c fix: Treat DND drop performed with NONE action as a cancellation (#49694)
Refs https://chromium-review.googlesource.com/c/chromium/src/+/7002773
2026-02-06 19:33:33 +09:00
trop[bot]
b35f4eeaf0 refactor: use ComPtr pattern for MSIX to avoid exception handling (#49688)
* 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 14:37:04 -08:00
trop[bot]
63f7692da5 fix: menu state in macOS dock menus (#49626)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-02-05 10:57:47 -05:00
trop[bot]
a4af2354dc fix: default accelerator for role-based menu items (#49670)
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-05 10:57:01 -05:00
trop[bot]
bd49864f1d ci: use squash merge for apply patches workflow (#49674)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2026-02-04 21:29:51 -08:00
trop[bot]
abc5d1280d fix(squirrel.mac): clean up old staged updates before downloading new update (#49637)
fix: clean up old staged updates before downloading new update

When checkForUpdates() is called while an update is already staged,
Squirrel creates a new temporary directory for the download without
cleaning up the old one. This can lead to disk usage growth when
new versions are released while the app hasn't restarted.

This adds a force parameter to pruneUpdateDirectories that bypasses
the AwaitingRelaunch state check. This is called before creating a
new temp directory, ensuring old staged updates are cleaned up.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Andy Locascio <loc@anthropic.com>
2026-02-04 18:54:12 +01:00
trop[bot]
712bafde02 ci: handle PRs with no checks in rerun apply patches (#49663)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2026-02-04 09:45:43 -08:00
trop[bot]
013768c429 docs: add Wayland note to win.getPosition() and win.getBounds() (#49660)
docs: add Wayland note to win.getPosition()

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-02-04 11:50:15 -05:00
trop[bot]
681a2c1aba fix: possible crash in FileSystem API (#49634)
Refs https://chromium-review.googlesource.com/6880247

Fixes a crash that can arise in the File System Access API in the
following scenario:

1. Create fileHandle1 at path1.
2. Call fileHandle1.remove() or user manually delete the file.
3. Create fileHandle2 at path2.
4. fileHandle2.move(path1).

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-02-04 16:12:59 +01:00
trop[bot]
98521d22ec fix: alt-space should route through 'system-context-menu' (#49641)
fix: alt-space should route through system-context-menu

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-02-04 16:11:59 +01:00
trop[bot]
faa40332ad fix: handle out of order recording errors in skia graphite (#49615)
* fix: handle out of order recording errors in skia graphite

Refs https://issues.chromium.org/issues/458722690

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

* chore: fixup patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: Niklas Wenzel <dev@nikwen.de>
2026-02-02 15:06:17 -08:00
David Sanders
e1ac9d5d1b build(dev-deps): bump @electron/lint-roller to 3.2.0 (#49588)
build(dev-deps): bump @electron/lint-roller to 3.2.0 (#49565)
2026-02-02 11:34:17 +01:00
trop[bot]
dc254e4bfc fix: duplicate fullscreen macOS menu item (#49597)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-02-02 09:39:24 +01:00
trop[bot]
5631882390 refactor: address PathProvider TODO (#49600)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-02-02 09:39:05 +01:00
trop[bot]
e6b53033dd feat: msix auto-updater (#49585)
* feat: native auto updater for MSIX on Windows

Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>

* doc: added MSIX debug documentation

Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>

* fix: allow downgrade with json release file and emit update-available

Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>

* test: msix auot-update tests

Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>

* doc: API documentation

Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>

* test: add package version validation

Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>

* fix: docs typo

Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>

* fix: don't allow auto-updating when using appinstaller manifest

Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>

* fix: getPackageInfo interface implementation

Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>

* fix: review feedback, add comment

Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>

* fix: missed filename commit

Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>

* fix: install test cert on demand

Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>

* fix: time stamp mismatch in tests

Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>

* fix: feedback - rename to MSIXPackageInfo

Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>

* fix: update and reference windowsStore property

Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>

* fix: remove getPackagInfo from public API

Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>

* fix: type error bcause of removed API

Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>

* fix: fix Windows MSIX release build errors (#49613)

* fix: fix MSIX release build

* fix: add C++/WinRT headers

* build: modify include paths

* fix: compile msix as seperate source set

* build: add additional needed deps for msix

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
2026-02-02 09:33:46 +01:00
trop[bot]
fd4f835f37 fix: macOS menu item accelerators when item disabled (#49593)
fix: macOS menu item acceerators when item disabled

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-01-30 14:52:17 -05:00
David Sanders
f36da597ff ci: rework reapply patches (#49589)
ci: rework reapply patches (#49552)
2026-01-30 13:17:05 -05:00
trop[bot]
87badb84f8 test: remove split dependency (#49555)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2026-01-28 15:38:05 +01:00
trop[bot]
2f3a1ca461 fix: chrome://accessibility drift (#49559)
https://chromium-review.googlesource.com/c/chromium/src/+/6870052

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-01-28 15:37:39 +01:00
trop[bot]
81ae20905c ci: reapply patches if PR base branch updates them (#49533)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2026-01-27 17:40:35 -05:00
trop[bot]
da4a808af7 docs: correct type for process.noDeprecation (#49545)
* docs: correct type for process.noDeprecation

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

* docs: mark `noDeprecation` as optional instead

Co-authored-by: René <contact.9a5d6388@renegade334.me.uk>

Co-authored-by: David Sanders <dsanders11@ucsbalum.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: David Sanders <dsanders11@ucsbalum.com>
2026-01-27 11:37:32 +01:00
trop[bot]
71579e4749 fix: second argument to shell.writeShortcutLink is optional (#49502)
fix: second argument to shell.writeShortcutLink is optional

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-01-23 14:31:09 -05:00
trop[bot]
06fdee87b3 fix: return early from platform_util::Beep() on Linux if there is no default GDK display (#49484)
fix: return early from beep on linux if there is no default gdk display

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Noah Gregory <noahmgregory@gmail.com>
2026-01-23 11:07:47 +01:00
trop[bot]
6ce52ad792 fix: potential devtools crash on empty (#49489)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-01-22 11:59:57 -05:00
electron-roller[bot]
7784d25821 chore: bump node to v22.22.0 (39-x-y) (#49389)
* chore: bump node in DEPS to v22.22.0

* chore: update patches

* chore: fixup sandboxed pointers patch

(cherry picked from commit f52fbdbe51)

* chore: fixup v8 sandbox pointers node patch

* tls: route callback exceptions through error handlers

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

* chore:remove zero-fill sandbox patch component

xref https://github.com/electron/electron/pull/49452

* fixup! chore:remove zero-fill sandbox patch component

* test: correct conditional secure heap flags test

xref:  https://github.com/nodejs/node/pull/60385

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2026-01-22 09:53:44 -05:00
trop[bot]
126a32c5d2 docs: document that shell.trashItem requires backslashes (#49479)
docs: Update shell.md: Document that shell.trashItem requires backslashes

In Windows many functions relating to files (e.g. shell.openItem, the Node fs functions, as well as native Win32 APIs) will accept either type of slash / or \ as a folder separator.

shell.trashItem does not work with / as folder separator in Windows. This documentation change explains that.

See also:
https://github.com/electron/electron/issues/28831

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: sam marshall <s.marshall@open.ac.uk>
2026-01-21 14:52:13 -05:00
trop[bot]
811b1d6326 revert: use deprecated setAllowedFileTypes in macOS dialogs (#49472)
* revert: use deprectated setAllowedFileTypes in macOS dialogs

Closes https://github.com/electron/electron/issues/48191

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

* chore: remove stray import

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-01-21 17:57:35 +01:00
trop[bot]
50fc493ae6 ci: detect patch needs update error with problem matcher (#49412)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2026-01-21 12:32:04 +01:00
trop[bot]
9453e8bfe1 build: roll build-image to a82b87d (#49450)
build: roll build-image to a82b87d

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-01-19 19:01:42 +01:00
trop[bot]
a4eb213a04 fix: restore AXDocument accessibility attribute for representedFilename on macOS (#49418)
Starting from Chromium 134.0.6989.0 (Electron 35.0.0-beta.5), the
NativeWidgetMacNSWindow class overrides accessibilityDocument to return
the web content URL from the accessibility tree, but doesn't fall back
to NSWindow's default behavior when that URL is empty.

This broke Electron's setRepresentedFilename() API - the file path was
still set on the NSWindow, but no longer exposed via the AXDocument
accessibility attribute that screen readers use.

This fix adds an accessibilityDocument override in ElectronNSWindow that
checks representedFilename first, falling back to Chromium's behavior
for web content URLs.

Fixes: https://github.com/electron/electron/issues/XXXXX

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Daniel Gräfe <Daniel.Alm@ForumD.net>
2026-01-19 15:02:51 +01:00
trop[bot]
81c08e80f6 docs: fix webContents.hostWebContents types (#49445)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Niklas Wenzel <dev@nikwen.de>
2026-01-19 10:58:28 +01:00
trop[bot]
5f630c7de7 fix: try clearing InspectableWebContents delegate earlier (#49423)
fix: try clearing InspectableWebContents delegate earlier

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-01-18 09:52:20 +01:00
trop[bot]
2dc82ea1f3 fix: make toplevel icon Wayland protocol work (#49415)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Alex Schwartz <alexschwartz01@gmail.com>
2026-01-16 11:04:40 -05:00
Shelley Vohr
f57d6f92b6 feat: support WebSocket authentication handling (#49065)
* feat: support WebSocket authentication handling

* chore: make linter happy

---------

Co-authored-by: Charles Kerr <charles@charleskerr.com>
2026-01-13 08:52:14 -05:00
Robo
744142fe54 fix: reduce stack memory consumption in BytecodeGenerator (#49360)
Reduce stack memory consumption in BytecodeGenerator

Backports

1) https://chromium-review.googlesource.com/c/v8/v8/+/7180480
2) https://chromium-review.googlesource.com/c/v8/v8/+/7160576
3) https://chromium-review.googlesource.com/c/v8/v8/+/7062734

2 and 3 are needed to cleanly land 1. However, most of the code
changes are noop since v8_flags.proto_assign_seq_opt is experimental
and disabled by default for feature. The reason why stack memory
consumption is improved for all scenarios can be found in
https://github.com/microsoft/vscode/issues/283403#issuecomment-3737968271
2026-01-13 19:04:51 +09:00
trop[bot]
b200b8d6c0 build: roll build-tools SHA to 4430e4a (#49367)
build: roll build-tools SHA to 4430e4a

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-01-12 15:44:02 -05:00
electron-roller[bot]
cdaf0e96b6 chore: bump chromium to 142.0.7444.265 (39-x-y) (#49322)
chore: bump chromium in DEPS to 142.0.7444.265

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
2026-01-12 11:29:53 +01:00
trop[bot]
981df181c1 chore: improvements to script/run-clang-tidy.ts (#49341)
* chore: disable color output for clang-tidy in CI

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>

* chore: small QoL improvements to run-clang-tidy.ts

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>

* chore: add --fix option to script/run-clang-tidy.ts

Co-authored-by: David Sanders <dsanders11@ucsbalum.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2026-01-09 14:43:00 -06:00
John Kleinschmidt
218300e57f build: use @electron-ci/dev-root for package.json default (#49319)
* build: use @electron-ci/dev-root for package.json default (#49154)

(cherry picked from commit bab6bd3dae)

* fxiup
2026-01-07 09:48:08 -05:00
Charles Kerr
6ccee512e4 chore: remove patches/v8/cherry-pick-e0052e7af9c9 (#49309)
chore: remove patches/v8/cherry-pick-e0052e7af9c9.patch

included in latest roll of upstream w/v8 14.2.231.22
2026-01-06 12:43:37 -06:00
trop[bot]
b6e4f514d8 docs: update roundedCorners documentation (#49310)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Niklas Wenzel <dev@nikwen.de>
2026-01-06 11:00:23 -05:00
trop[bot]
ade4c00984 fix: webRequest.onBeforeSendHeaders not being able to modify reserved headers (#49242)
* fix: `webRequest.onBeforeSendHeaders` not being able to modify reserved headers

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

* chore: add unit test for reserved header

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

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <sattard@anthropic.com>
2026-01-05 16:30:50 -05:00
trop[bot]
d8687cfc9d build: fixup release notes generation (#49304)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
2026-01-05 15:56:30 -05:00
electron-roller[bot]
2ab4489447 chore: bump chromium to 142.0.7444.243 (39-x-y) (#49228)
chore: bump chromium in DEPS to 142.0.7444.243

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
2026-01-02 13:49:22 +09:00
Keeley Hammond
ab9b156113 chore: cherry-pick e0052e7af9c9 from v8 (#49287)
* chore: cherry-pick e0052e7af9c9 from v8

* chore: update patches
2025-12-31 17:02:33 +13:00
trop[bot]
35a531953b build: drop dugite as a dependency (#49205)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
2025-12-15 16:39:41 -05:00
trop[bot]
4d18062d0f ci: disallow non-maintainer changes to Yarn files (#49192)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2025-12-11 17:14:14 -05:00
electron-roller[bot]
832ffb2330 chore: bump chromium to 142.0.7444.235 (39-x-y) (#49190)
chore: bump chromium in DEPS to 142.0.7444.235

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
2025-12-11 15:25:12 -05:00
trop[bot]
03121eeaef build: upgrade yarn to 4.12.0 (#49179)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
2025-12-10 19:20:43 -08:00
trop[bot]
8282c07a0f build: upgrade github-app-auth to 3.2.0 (#49177)
build: upgrade github-app-auth to 3.2.0 (#49152)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2025-12-10 14:20:43 -05:00
Niklas Wenzel
f2d1cb21b0 fix: visual artifacts while resizing on Windows (#49138)
Manual backports of:

- crrev.com/c/7129658
- crrev.com/c/7210913
- crrev.com/c/7115438
2025-12-04 16:42:24 -08:00
electron-roller[bot]
ef9b4162af chore: bump chromium to 142.0.7444.226 (39-x-y) (#49137)
* chore: bump chromium in DEPS to 142.0.7444.226

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Niklas Wenzel <dev@nikwen.de>
2025-12-03 15:50:16 -05:00
trop[bot]
6e97bca80d fix: run toast creation on background thread (#49130)
* fix: run toast creation on background thread

notes: attempts to fix app freeze when triggering notifications and the COM server in WindowsShellExperienceHost hangs

Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>

* fix: comments

Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com>
2025-12-02 20:41:24 -08:00
trop[bot]
c511fc5c3f chore: reclaim macOS disk space (#49121)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2025-12-01 15:30:07 -08:00
trop[bot]
22dfbb0822 ci: use clang problem matcher with nan spec runner (#49099)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2025-12-01 09:45:35 -05:00
trop[bot]
85913a38da fix: ensure menu-did-close is emitted for application menus (#49093)
fix: ensure menu-did-close is emitted for application menus

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2025-11-26 11:47:13 -06:00
trop[bot]
a327629ca2 ci: don't build yarn modules for linux arm (#49088)
This should fix the oom errors

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2025-11-26 10:32:30 -05:00
Niklas Wenzel
7deed2b980 fix: reduce visual artifacts while resizing on Windows (#49076) 2025-11-26 10:23:52 +01:00
trop[bot]
65fc06a9f7 chore: backport 744f40f from devtools-frontend (#49044)
* chore: backport 744f40f from devtools-frontend

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

* chore: update patch

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2025-11-25 12:07:04 -06:00
John Kleinschmidt
245e70aedd test: fixup test failures on linux (#49059)
* test: fixup spec runner to properly fail on linux when tests fail

* test: fixup dbus tests

* test: disable context menu spellcheck tests on linux

https://github.com/electron/electron/pull/48657 broke those tests
(cherry picked from commit cc3c999148)

* test:rebuild native modules

(cherry picked from commit bb8e2a924b)

* fix: wait for devtools blur event in focus test to avoid race condition

(cherry picked from commit 6fd2575cbc)

* fix: wait for devtools blur event in focus test to avoid race condition

(cherry picked from commit ea830139af)

---------

Co-authored-by: Alice Zhao <alicelovescake@anthropic.com>
2025-11-24 17:02:14 -05:00
trop[bot]
2a8164f499 fix: exception when reading system certificates via nodejs (#49042)
* fix: exception when reading system certificates via nodejs

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

* fixup! fix: exception when reading system certificates via nodejs

chore: fix trop patch shear

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2025-11-24 14:47:53 -06:00
trop[bot]
2f7024dbcc docs: update linux build instructions (#49060)
* docs: update linux build instructions

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>

* Update docs/development/build-instructions-linux.md

Co-authored-by: Erick Zhao <ezhao@slack-corp.com>

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>

* Update docs/development/build-instructions-linux.md

Co-authored-by: Erick Zhao <ezhao@slack-corp.com>

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2025-11-24 13:50:33 -06:00
trop[bot]
d53d3bb99e docs: explain how to create transparent window using BaseWindow (#49051)
docs: clarify how to create transparent BaseWindow

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: teoyuqi <83915879+teoyuqi@users.noreply.github.com>
2025-11-24 09:41:48 +01:00
trop[bot]
c2c1d40294 fix: only call popup closecallback for top-level menu (#49045)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2025-11-23 21:35:47 +01:00
electron-roller[bot]
0e9decd459 chore: bump chromium to 142.0.7444.177 (39-x-y) (#49037)
chore: bump chromium in DEPS to 142.0.7444.177

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
2025-11-21 10:21:05 -05:00
John Kleinschmidt
b2e73d28e2 build: update to yarn v4 (#48994)
* build: update to yarn v4

(cherry picked from commit 6adec744f3)

* chore: fixup types after yarn v4 migration

* chore: update nan yarn.lock patch

* build: automatically install git for dugite
2025-11-19 17:32:30 -05:00
trop[bot]
aeb5af803f fix: abort more descriptively for beforeunload (#49011)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2025-11-19 17:00:51 -05:00
trop[bot]
53819a8a2a fix: revert the parent window remained interactive after the modal window was opened (#49019)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: bill.shen <15865969+cucbin@users.noreply.github.com>
2025-11-19 16:56:33 -05:00
electron-roller[bot]
14565211f7 chore: bump chromium to 142.0.7444.175 (39-x-y) (#49003)
* chore: bump chromium in DEPS to 142.0.7444.175

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2025-11-18 11:25:22 -08:00
trop[bot]
00646c9db6 fix: handle empty event scenario in ipc callbacks (#48992)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2025-11-18 09:17:20 -05:00
trop[bot]
d9c33a951a build: add header for SetStackDumpFirstChanceCallback in renderer client (#48980)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
2025-11-15 10:04:28 -08:00
trop[bot]
8b02e33187 build: limit workflow gh token permissions (#48969)
* build: limit workflow gh token permissions

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

* feedback

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

---------

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: Samuel Attard <sattard@anthropic.com>
2025-11-15 11:32:21 +01:00
trop[bot]
eecca2cb19 fix: revert enabling WASM trap handlers in all Node.js processes (#48975)
Revert "fix: enable wasm trap handlers in all Node.js processes (#48788)"

This reverts commit ca0b46b413.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Keeley Hammond <khammond@slack-corp.com>
2025-11-14 18:56:50 -08:00
trop[bot]
08b5ef556c test: add view.getBounds|setBounds tests (#48961)
test: add view.getBounds|setBounds tests

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2025-11-14 12:12:22 -05:00
247 changed files with 25971 additions and 12413 deletions

View File

@@ -2,7 +2,7 @@ version: '3'
services:
buildtools:
image: ghcr.io/electron/devcontainer:933c7d6ff6802706875270bec2e3c891cf8add3f
image: ghcr.io/electron/devcontainer:a82b87d7a4f5ff0cab61405f8151ac4cf4942aeb
volumes:
- ..:/workspaces/gclient/src/electron:cached

View File

@@ -184,10 +184,11 @@ runs:
shell: bash
run: |
cd src/electron
node script/yarn create-typescript-definitions
node script/yarn.js create-typescript-definitions
- 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
@@ -198,6 +199,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

@@ -143,16 +143,17 @@ runs:
echo "No changes to patches detected"
fi
fi
- name: Remove patch conflict problem matcher
- name: Remove patch conflict problem matchers
shell: bash
run: |
echo "::remove-matcher owner=merge-conflict::"
echo "::remove-matcher owner=patch-conflict::"
echo "::remove-matcher owner=patch-needs-update::"
- name: Upload patches stats
if: ${{ inputs.target-platform == 'linux' && github.ref == 'refs/heads/main' }}
shell: bash
run: |
npx node src/electron/script/patches-stats.mjs --upload-stats || true
node src/electron/script/patches-stats.mjs --upload-stats || true
# delete all .git directories under src/ except for
# third_party/angle/ and third_party/dawn/ because of build time generation of files
# gen/angle/commit.h depends on third_party/angle/.git/HEAD

View File

@@ -64,15 +64,24 @@ runs:
sudo rm -rf /Applications/Xcode_16.1.app
sudo rm -rf /Applications/Xcode_16.2.app
sudo rm -rf /Applications/Xcode_16.3.app
sudo rm -rf /Applications/Xcode_26*
sudo rm -rf /Applications/Google Chrome.app
sudo rm -rf /Applications/Google Chrome for Testing.app
sudo rm -rf /Applications/Firefox.app
sudo rm -rf /Applications/Firefox.app
sudo rm -rf /Applications/Microsoft Edge.app
sudo rm -rf ~/project/src/third_party/catapult/tracing/test_data
sudo rm -rf ~/project/src/third_party/angle/third_party/VK-GL-CTS
sudo rm -rf /Users/runner/Library/Android
sudo rm -rf $JAVA_HOME_11_arm64
sudo rm -rf $JAVA_HOME_17_arm64
sudo rm -rf $JAVA_HOME_21_arm64
sudo rm -rf $JAVA_HOME_25_arm64
sudo rm -rf /Users/runner/.dotnet/
sudo rm -rf /Users/runner/.rustup
# remove homebrew packages we don't need
brew uninstall -f --zap aws-sam-cli session-manager-plugin gcc gcc@13 gcc@14 llvm@18 gradle maven ant azure-cli
brew autoremove
# lipo off some huge binaries arm64 versions to save space
strip_universal_deep $(xcode-select -p)/../SharedFrameworks

View File

@@ -13,12 +13,16 @@ runs:
- name: Generating Types for SHA in ${{ inputs.sha-file }}
shell: bash
run: |
git checkout $(cat ${{ inputs.sha-file }})
rm -rf node_modules
yarn install --frozen-lockfile --ignore-scripts
export ELECTRON_DIR=$(pwd)
if [ "${{ inputs.sha-file }}" == ".dig-old" ]; then
cd /tmp
git clone https://github.com/electron/electron.git
cd electron
fi
git checkout $(cat $ELECTRON_DIR/${{ inputs.sha-file }})
node script/yarn.js install --immutable
echo "#!/usr/bin/env node\nglobal.x=1" > node_modules/typescript/bin/tsc
node node_modules/.bin/electron-docs-parser --dir=./ --outDir=./ --moduleVersion=0.0.0-development
node node_modules/.bin/electron-typescript-definitions --api=electron-api.json --outDir=artifacts
mv artifacts/electron.d.ts artifacts/${{ inputs.filename }}
git checkout .
mv artifacts/electron.d.ts $ELECTRON_DIR/artifacts/${{ inputs.filename }}
working-directory: ./electron

View File

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

View File

@@ -6,7 +6,7 @@ runs:
- name: Get yarn cache directory path
shell: bash
id: yarn-cache-dir-path
run: echo "dir=$(node src/electron/script/yarn cache dir)" >> $GITHUB_OUTPUT
run: echo "dir=$(node src/electron/script/yarn.js config get cacheFolder)" >> $GITHUB_OUTPUT
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
id: yarn-cache
with:
@@ -18,4 +18,14 @@ runs:
shell: bash
run: |
cd src/electron
node script/yarn install --frozen-lockfile --prefer-offline
if [ "$TARGET_ARCH" = "x86" ]; then
export npm_config_arch="ia32"
fi
# if running on linux arm skip yarn Builds
ARCH=$(uname -m)
if [ "$ARCH" = "armv7l" ]; then
echo "Skipping yarn build on linux arm"
node script/yarn.js install --immutable --mode=skip-build
else
node script/yarn.js install --immutable
fi

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

@@ -19,6 +19,16 @@
"line": 3
}
]
},
{
"owner": "patch-needs-update",
"pattern": [
{
"regexp": "^((patches\/.*): needs update)$",
"message": 1,
"file": 2
}
]
}
]
}

73
.github/workflows/apply-patches.yml vendored Normal file
View File

@@ -0,0 +1,73 @@
name: Apply Patches
on:
pull_request:
permissions: {}
concurrency:
group: apply-patches-${{ github.ref }}
cancel-in-progress: true
jobs:
setup:
if: github.repository == 'electron/electron'
runs-on: ubuntu-slim
permissions:
contents: read
pull-requests: read
outputs:
has-patches: ${{ steps.filter.outputs.patches }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
persist-credentials: false
ref: ${{ github.event.pull_request.head.sha }}
# Use dorny/paths-filter instead of the path filter under the on: pull_request: block
# so that the output can be used to conditionally run the apply-patches job, which lets
# the job be marked as a required status check (conditional skip counts as a success).
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: filter
with:
filters: |
patches:
- DEPS
- 'patches/**'
apply-patches:
needs: setup
if: ${{ needs.setup.outputs.has-patches == 'true' }}
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read
container:
image: ghcr.io/electron/build:a82b87d7a4f5ff0cab61405f8151ac4cf4942aeb
options: --user root
volumes:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
- /var/run/sas:/var/run/sas
env:
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
steps:
- name: Checkout Electron
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
path: src/electron
fetch-depth: 0
persist-credentials: false
ref: ${{ github.event.pull_request.base.ref }}
- name: Merge PR HEAD
working-directory: src/electron
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
git config user.email "electron@github.com"
git config user.name "Electron Bot"
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:
target-platform: linux

View File

@@ -3,10 +3,14 @@ name: Archaeologist
on:
pull_request:
permissions: {}
jobs:
archaeologist-dig:
name: Archaeologist Dig
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout Electron
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.0.2

View File

@@ -6,11 +6,15 @@ on:
schedule:
- cron: "0 0 * * *"
permissions: {}
jobs:
build-git-cache-linux:
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read
container:
image: ghcr.io/electron/build:bc2f48b2415a670de18d13605b1cf0eb5fdbaae1
image: ghcr.io/electron/build:a82b87d7a4f5ff0cab61405f8151ac4cf4942aeb
options: --user root
volumes:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
@@ -30,8 +34,10 @@ jobs:
build-git-cache-windows:
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read
container:
image: ghcr.io/electron/build:bc2f48b2415a670de18d13605b1cf0eb5fdbaae1
image: ghcr.io/electron/build:a82b87d7a4f5ff0cab61405f8151ac4cf4942aeb
options: --user root --device /dev/fuse --cap-add SYS_ADMIN
volumes:
- /mnt/win-cache:/mnt/win-cache
@@ -52,10 +58,12 @@ jobs:
build-git-cache-macos:
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read
# This job updates the same git cache as linux, so it needs to run after the linux one.
needs: build-git-cache-linux
container:
image: ghcr.io/electron/build:bc2f48b2415a670de18d13605b1cf0eb5fdbaae1
image: ghcr.io/electron/build:a82b87d7a4f5ff0cab61405f8151ac4cf4942aeb
options: --user root
volumes:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache

View File

@@ -6,7 +6,7 @@ on:
build-image-sha:
type: string
description: 'SHA for electron/build image'
default: '933c7d6ff6802706875270bec2e3c891cf8add3f'
default: 'a82b87d7a4f5ff0cab61405f8151ac4cf4942aeb'
required: true
skip-macos:
type: boolean
@@ -43,10 +43,13 @@ defaults:
run:
shell: bash
permissions: {}
jobs:
setup:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
outputs:
docs: ${{ steps.filter.outputs.docs }}
@@ -73,7 +76,7 @@ jobs:
id: set-output
run: |
if [ -z "${{ inputs.build-image-sha }}" ]; then
echo "build-image-sha=933c7d6ff6802706875270bec2e3c891cf8add3f" >> "$GITHUB_OUTPUT"
echo "build-image-sha=a82b87d7a4f5ff0cab61405f8151ac4cf4942aeb" >> "$GITHUB_OUTPUT"
else
echo "build-image-sha=${{ inputs.build-image-sha }}" >> "$GITHUB_OUTPUT"
fi
@@ -84,6 +87,8 @@ jobs:
needs: setup
if: ${{ !inputs.skip-lint }}
uses: ./.github/workflows/pipeline-electron-lint.yml
permissions:
contents: read
with:
container: '{"image":"ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}","options":"--user root"}'
secrets: inherit
@@ -93,6 +98,8 @@ jobs:
needs: [setup, checkout-linux]
if: ${{ needs.setup.outputs.docs-only == 'true' }}
uses: ./.github/workflows/pipeline-electron-docs-only.yml
permissions:
contents: read
with:
container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
secrets: inherit
@@ -102,6 +109,8 @@ jobs:
needs: setup
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-macos}}
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read
container:
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
options: --user root
@@ -130,6 +139,8 @@ jobs:
needs: setup
if: ${{ !inputs.skip-linux}}
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read
container:
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
options: --user root
@@ -159,6 +170,8 @@ jobs:
needs: setup
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }}
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read
container:
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
options: --user root --device /dev/fuse --cap-add SYS_ADMIN
@@ -189,6 +202,8 @@ jobs:
# GN Check Jobs
macos-gn-check:
uses: ./.github/workflows/pipeline-segment-electron-gn-check.yml
permissions:
contents: read
needs: checkout-macos
with:
target-platform: macos
@@ -199,6 +214,8 @@ jobs:
linux-gn-check:
uses: ./.github/workflows/pipeline-segment-electron-gn-check.yml
permissions:
contents: read
needs: checkout-linux
if: ${{ needs.setup.outputs.src == 'true' }}
with:
@@ -211,6 +228,8 @@ jobs:
windows-gn-check:
uses: ./.github/workflows/pipeline-segment-electron-gn-check.yml
permissions:
contents: read
needs: checkout-windows
with:
target-platform: win
@@ -314,7 +333,7 @@ jobs:
build-runs-on: electron-arc-centralus-linux-amd64-32core
test-runs-on: electron-arc-centralus-linux-arm64-4core
build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
test-container: '{"image":"ghcr.io/electron/test:arm32v7-${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init","volumes":["/home/runner/externals:/mnt/runner-externals"]}'
test-container: '{"image":"ghcr.io/electron/test:arm32v7-${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init --memory=12g","volumes":["/home/runner/externals:/mnt/runner-externals"]}'
target-platform: linux
target-arch: arm
is-release: false
@@ -404,6 +423,8 @@ jobs:
gha-done:
name: GitHub Actions Completed
runs-on: ubuntu-latest
permissions:
contents: read
needs: [docs-only, macos-x64, macos-arm64, linux-x64, linux-x64-asan, linux-arm, linux-arm64, windows-x64, windows-x86, windows-arm64]
if: always() && !contains(needs.*.result, 'failure')
steps:

View File

@@ -1,16 +1,20 @@
name: Clean Source Cache
description: |
This workflow cleans up the source cache on the cross-instance cache volume
to free up space. It runs daily at midnight and clears files older than 15 days.
# Description:
# This workflow cleans up the source cache on the cross-instance cache volume
# to free up space. It runs daily at midnight and clears files older than 15 days.
on:
schedule:
- cron: "0 0 * * *"
permissions: {}
jobs:
clean-src-cache:
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read
container:
image: ghcr.io/electron/build:bc2f48b2415a670de18d13605b1cf0eb5fdbaae1
options: --user root

View File

@@ -4,14 +4,15 @@ on:
issues:
types: [labeled]
permissions: # added using https://github.com/step-security/secure-workflows
contents: read
permissions: {}
jobs:
issue-labeled-with-status:
name: status/{confirmed,reviewed} label added
if: github.event.label.name == 'status/confirmed' || github.event.label.name == 'status/reviewed'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Generate GitHub App token
uses: electron/github-app-auth-action@384fd19694fe7b6dcc9a684746c6976ad78228ae # v1.1.1
@@ -31,6 +32,8 @@ jobs:
name: blocked/* label added
if: startsWith(github.event.label.name, 'blocked/')
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Generate GitHub App token
uses: electron/github-app-auth-action@384fd19694fe7b6dcc9a684746c6976ad78228ae # v1.1.1

View File

@@ -11,6 +11,7 @@ jobs:
add-to-issue-triage:
if: ${{ contains(github.event.issue.labels.*.name, 'bug :beetle:') }}
runs-on: ubuntu-latest
permissions: {}
steps:
- name: Generate GitHub App token
uses: electron/github-app-auth-action@384fd19694fe7b6dcc9a684746c6976ad78228ae # v1.1.1
@@ -28,6 +29,7 @@ jobs:
set-labels:
if: ${{ contains(github.event.issue.labels.*.name, 'bug :beetle:') }}
runs-on: ubuntu-latest
permissions: {}
steps:
- name: Generate GitHub App token
uses: electron/github-app-auth-action@384fd19694fe7b6dcc9a684746c6976ad78228ae # v1.1.1

View File

@@ -10,6 +10,7 @@ jobs:
issue-transferred:
name: Issue Transferred
runs-on: ubuntu-latest
permissions: {}
if: ${{ !github.event.changes.new_repository.private }}
steps:
- name: Generate GitHub App token

View File

@@ -4,14 +4,15 @@ on:
issues:
types: [unlabeled]
permissions:
contents: read
permissions: {}
jobs:
issue-unlabeled-blocked:
name: All blocked/* labels removed
if: startsWith(github.event.label.name, 'blocked/') && github.event.issue.state == 'open'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Check for any blocked labels
id: check-for-blocked-labels

View File

@@ -6,7 +6,7 @@ on:
build-image-sha:
type: string
description: 'SHA for electron/build image'
default: '933c7d6ff6802706875270bec2e3c891cf8add3f'
default: 'a82b87d7a4f5ff0cab61405f8151ac4cf4942aeb'
upload-to-storage:
description: 'Uploads to Azure storage'
required: false
@@ -17,9 +17,13 @@ on:
type: boolean
default: false
permissions: {}
jobs:
checkout-linux:
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read
container:
image: ghcr.io/electron/build:${{ inputs.build-image-sha }}
options: --user root
@@ -39,7 +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
@@ -54,7 +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
@@ -69,7 +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

@@ -6,7 +6,7 @@ on:
build-image-sha:
type: string
description: 'SHA for electron/build image'
default: '933c7d6ff6802706875270bec2e3c891cf8add3f'
default: 'a82b87d7a4f5ff0cab61405f8151ac4cf4942aeb'
required: true
upload-to-storage:
description: 'Uploads to Azure storage'
@@ -18,9 +18,13 @@ on:
type: boolean
default: false
permissions: {}
jobs:
checkout-macos:
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read
container:
image: ghcr.io/electron/build:${{ inputs.build-image-sha }}
options: --user root
@@ -43,7 +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
@@ -58,7 +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
@@ -73,7 +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
@@ -88,7 +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

@@ -7,6 +7,8 @@ on:
- 'spec/yarn.lock'
- '.github/workflows/**'
- '.github/actions/**'
- '.yarn/**'
- '.yarnrc.yml'
permissions: {}

View File

@@ -55,6 +55,8 @@ on:
type: boolean
default: false
permissions: {}
concurrency:
group: electron-build-and-test-and-nan-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref_protected == true && github.run_id || github.ref }}
cancel-in-progress: ${{ github.ref_protected != true }}
@@ -62,6 +64,8 @@ concurrency:
jobs:
build:
uses: ./.github/workflows/pipeline-segment-electron-build.yml
permissions:
contents: read
with:
build-runs-on: ${{ inputs.build-runs-on }}
build-container: ${{ inputs.build-container }}
@@ -74,6 +78,10 @@ jobs:
secrets: inherit
test:
uses: ./.github/workflows/pipeline-segment-electron-test.yml
permissions:
contents: read
issues: read
pull-requests: read
needs: build
with:
target-arch: ${{ inputs.target-arch }}
@@ -83,6 +91,8 @@ jobs:
secrets: inherit
nn-test:
uses: ./.github/workflows/pipeline-segment-node-nan-test.yml
permissions:
contents: read
needs: build
with:
target-arch: ${{ inputs.target-arch }}

View File

@@ -64,14 +64,13 @@ concurrency:
group: electron-build-and-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref_protected == true && github.run_id || github.ref }}
cancel-in-progress: ${{ github.ref_protected != true }}
permissions:
contents: read
issues: read
pull-requests: read
permissions: {}
jobs:
build:
uses: ./.github/workflows/pipeline-segment-electron-build.yml
permissions:
contents: read
with:
build-runs-on: ${{ inputs.build-runs-on }}
build-container: ${{ inputs.build-container }}
@@ -86,6 +85,10 @@ jobs:
secrets: inherit
test:
uses: ./.github/workflows/pipeline-segment-electron-test.yml
permissions:
contents: read
issues: read
pull-requests: read
needs: build
with:
target-arch: ${{ inputs.target-arch }}

View File

@@ -8,6 +8,8 @@ on:
description: 'Container to run the docs-only ts compile in'
type: string
permissions: {}
concurrency:
group: electron-docs-only-${{ github.ref }}
cancel-in-progress: true
@@ -19,6 +21,8 @@ jobs:
docs-only:
name: Docs Only Compile
runs-on: electron-arc-centralus-linux-amd64-4core
permissions:
contents: read
timeout-minutes: 20
container: ${{ fromJSON(inputs.container) }}
steps:
@@ -50,12 +54,12 @@ jobs:
shell: bash
run: |
cd src/electron
node script/yarn create-typescript-definitions
node script/yarn tsc -p tsconfig.default_app.json --noEmit
node script/yarn.js create-typescript-definitions
node script/yarn.js tsc -p tsconfig.default_app.json --noEmit
for f in build/webpack/*.js
do
out="${f:29}"
if [ "$out" != "base.js" ]; then
node script/yarn webpack --config $f --output-filename=$out --output-path=./.tmp --env mode=development
node script/yarn.js webpack --config $f --output-filename=$out --output-path=./.tmp --env mode=development
fi
done

View File

@@ -8,6 +8,8 @@ on:
description: 'Container to run lint in'
type: string
permissions: {}
concurrency:
group: electron-lint-${{ github.ref_protected == true && github.run_id || github.ref }}
cancel-in-progress: ${{ github.ref_protected != true }}
@@ -19,6 +21,8 @@ jobs:
lint:
name: Lint
runs-on: electron-arc-centralus-linux-amd64-4core
permissions:
contents: read
timeout-minutes: 20
container: ${{ fromJSON(inputs.container) }}
steps:
@@ -61,9 +65,11 @@ jobs:
curl -sL "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: |
@@ -74,11 +80,15 @@ jobs:
# but then we would lint its contents (at least gn format), and it doesn't pass it.
cd src/electron
node script/yarn install --frozen-lockfile
node script/yarn lint
node script/yarn.js install --immutable
node script/yarn.js lint
- name: Run Script Typechecker
shell: bash
run: |
cd src/electron
node script/yarn tsc -p tsconfig.script.json
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

@@ -59,6 +59,8 @@ on:
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 }}
@@ -81,6 +83,8 @@ jobs:
run:
shell: bash
runs-on: ${{ inputs.build-runs-on }}
permissions:
contents: read
container: ${{ fromJSON(inputs.build-container) }}
environment: ${{ inputs.environment }}
env:

View File

@@ -26,6 +26,8 @@ on:
type: string
default: testing
permissions: {}
concurrency:
group: electron-gn-check-${{ inputs.target-platform }}-${{ github.ref }}
cancel-in-progress: true
@@ -41,6 +43,8 @@ jobs:
run:
shell: bash
runs-on: ${{ inputs.check-runs-on }}
permissions:
contents: read
container: ${{ fromJSON(inputs.check-container) }}
steps:
- name: Checkout Electron

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@11bd71901bbe5b1630ceea73d27597364c9af683
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@49933ea5288caeca8642d1e84afbd3f7d6820020
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@11bd71901bbe5b1630ceea73d27597364c9af683
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

@@ -35,10 +35,7 @@ concurrency:
group: electron-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ inputs.is-asan }}-${{ github.ref_protected == true && github.run_id || github.ref }}
cancel-in-progress: ${{ github.ref_protected != true }}
permissions:
contents: read
issues: read
pull-requests: read
permissions: {}
env:
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
@@ -53,6 +50,10 @@ jobs:
run:
shell: bash
runs-on: ${{ inputs.test-runs-on }}
permissions:
contents: read
issues: read
pull-requests: read
container: ${{ fromJSON(inputs.test-container) }}
strategy:
fail-fast: false
@@ -195,10 +196,7 @@ jobs:
# sudo security authorizationdb write com.apple.trust-settings.admin allow
# cd src/electron
# ./script/codesign/generate-identity.sh
- name: Install Datadog CLI
run: |
cd src/electron
node script/yarn global add @datadog/datadog-ci
- name: Run Electron Tests
shell: bash
env:
@@ -224,7 +222,7 @@ jobs:
export ELECTRON_FORCE_TEST_SUITE_EXIT="true"
fi
fi
node script/yarn test --runners=main --enableRerun=3 --trace-uncaught --enable-logging --files $tests_files
node script/yarn.js test --runners=main --enableRerun=3 --trace-uncaught --enable-logging --files $tests_files
else
chown :builduser .. && chmod g+w ..
chown -R :builduser . && chmod -R g+w .
@@ -241,9 +239,14 @@ jobs:
export MOCHA_TIMEOUT=180000
echo "Piping output to ASAN_SYMBOLIZE ($ASAN_SYMBOLIZE)"
cd electron
runuser -u builduser -- xvfb-run script/actions/run-tests.sh script/yarn test --runners=main --trace-uncaught --enable-logging --files $tests_files | $ASAN_SYMBOLIZE
runuser -u builduser -- xvfb-run script/actions/run-tests.sh script/yarn.js test --runners=main --trace-uncaught --enable-logging --files $tests_files | $ASAN_SYMBOLIZE
else
runuser -u builduser -- xvfb-run script/actions/run-tests.sh script/yarn test --runners=main --trace-uncaught --enable-logging --files $tests_files
if [ "${{ inputs.target-arch }}" = "arm" ]; then
runuser -u builduser -- xvfb-run script/actions/run-tests.sh script/yarn.js test --skipYarnInstall --runners=main --enableRerun=3 --trace-uncaught --enable-logging --files $tests_files
else
runuser -u builduser -- xvfb-run script/actions/run-tests.sh script/yarn.js test --runners=main --enableRerun=3 --trace-uncaught --enable-logging --files $tests_files
fi
fi
fi
- name: Upload Test results to Datadog
@@ -255,9 +258,10 @@ jobs:
DD_TAGS: "os.architecture:${{ inputs.target-arch }},os.family:${{ inputs.target-platform }},os.platform:${{ inputs.target-platform }},asan:${{ inputs.is-asan }}"
run: |
if ! [ -z $DD_API_KEY ] && [ -f src/electron/junit/test-results-main.xml ]; then
export DATADOG_PATH=`node src/electron/script/yarn global bin`
$DATADOG_PATH/datadog-ci junit upload src/electron/junit/test-results-main.xml
fi
cd src/electron
export DATADOG_PATH=`node script/yarn.js bin datadog-ci`
$DATADOG_PATH junit upload junit/test-results-main.xml
fi
if: always() && !cancelled()
- name: Upload Test Artifacts
if: always() && !cancelled()

View File

@@ -26,6 +26,8 @@ on:
type: string
default: testing
permissions: {}
concurrency:
group: electron-node-nan-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref_protected == true && github.run_id || github.ref }}
cancel-in-progress: ${{ github.ref_protected != true }}
@@ -39,6 +41,8 @@ jobs:
node-tests:
name: Run Node.js Tests
runs-on: electron-arc-centralus-linux-amd64-8core
permissions:
contents: read
timeout-minutes: 30
env:
TARGET_ARCH: ${{ inputs.target-arch }}
@@ -93,6 +97,8 @@ jobs:
nan-tests:
name: Run Nan Tests
runs-on: electron-arc-centralus-linux-amd64-4core
permissions:
contents: read
timeout-minutes: 30
env:
TARGET_ARCH: ${{ inputs.target-arch }}
@@ -132,10 +138,16 @@ jobs:
unzip -:o dist.zip
- name: Setup Linux for Headless Testing
run: sh -e /etc/init.d/xvfb start
- name: Add Clang problem matcher
shell: bash
run: echo "::add-matcher::src/electron/.github/problem-matchers/clang.json"
- name: Run Nan Tests
run: |
cd src
node electron/script/nan-spec-runner.js
- name: Remove Clang problem matcher
shell: bash
run: echo "::remove-matcher owner=clang::"
- name: Wait for active SSH sessions
shell: bash
if: always() && !cancelled()

View File

@@ -11,6 +11,7 @@ jobs:
name: backport/requested label added
if: github.event.label.name == 'backport/requested 🗳'
runs-on: ubuntu-latest
permissions: {}
steps:
- name: Trigger Slack workflow
uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1
@@ -28,6 +29,7 @@ jobs:
name: deprecation-review/complete label added
if: github.event.label.name == 'deprecation-review/complete ✅'
runs-on: ubuntu-latest
permissions: {}
steps:
- name: Generate GitHub App token
uses: electron/github-app-auth-action@384fd19694fe7b6dcc9a684746c6976ad78228ae # v1.1.1

View File

@@ -0,0 +1,71 @@
name: Rerun PR Apply Patches
on:
push:
branches:
- main
- '[1-9][0-9]-x-y'
paths:
- 'DEPS'
- 'patches/**'
permissions: {}
jobs:
rerun-apply-patches:
runs-on: ubuntu-latest
permissions:
actions: write
checks: read
contents: read
pull-requests: read
steps:
- name: Find PRs and Rerun Apply Patches
env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }}
run: |
BRANCH="${GITHUB_REF#refs/heads/}"
# Find all open PRs targeting this branch
PRS=$(gh pr list --base "$BRANCH" --state open --limit 250 --json number)
echo "$PRS" | jq -c '.[]' | while read -r pr; do
PR_NUMBER=$(echo "$pr" | jq -r '.number')
echo "Processing PR #${PR_NUMBER}"
# Find the Apply Patches workflow check for this PR
CHECK=$(gh pr view "$PR_NUMBER" --json statusCheckRollup --jq '[.statusCheckRollup[] | select(.workflowName == "Apply Patches" and .name == "apply-patches")] | first')
if [ -z "$CHECK" ] || [ "$CHECK" = "null" ]; then
echo " No Apply Patches workflow found for PR #${PR_NUMBER}"
continue
fi
CONCLUSION=$(echo "$CHECK" | jq -r '.conclusion')
if [ "$CONCLUSION" = "SKIPPED" ]; then
echo " apply-patches job was skipped for PR #${PR_NUMBER} (no patches)"
continue
fi
LINK=$(echo "$CHECK" | jq -r '.detailsUrl')
# Extract the run ID from the link (format: .../runs/RUN_ID/job/JOB_ID)
RUN_ID=$(echo "$LINK" | grep -oE 'runs/[0-9]+' | cut -d'/' -f2)
if [ -z "$RUN_ID" ]; then
echo " Could not extract run ID from link: ${LINK}"
continue
fi
# Check if the workflow is currently in progress
RUN_STATUS=$(gh run view "$RUN_ID" --json status --jq '.status')
if [ "$RUN_STATUS" = "in_progress" ] || [ "$RUN_STATUS" = "queued" ] || [ "$RUN_STATUS" = "waiting" ]; then
echo " Workflow run ${RUN_ID} is ${RUN_STATUS}, cancelling..."
gh run cancel "$RUN_ID" --force
gh run watch "$RUN_ID"
fi
gh run rerun "$RUN_ID"
done

View File

@@ -7,8 +7,7 @@ on:
- edited
- synchronize
permissions:
contents: read
permissions: {}
jobs:
main:

View File

@@ -11,6 +11,7 @@ jobs:
check-stable-prep-items:
name: Check Stable Prep Items
runs-on: ubuntu-latest
permissions: {}
steps:
- name: Generate GitHub App token
uses: electron/github-app-auth-action@384fd19694fe7b6dcc9a684746c6976ad78228ae # v1.1.1

View File

@@ -10,6 +10,7 @@ permissions: {}
jobs:
stale:
runs-on: ubuntu-latest
permissions: {}
steps:
- name: Generate GitHub App token
uses: electron/github-app-auth-action@384fd19694fe7b6dcc9a684746c6976ad78228ae # v1.1.1
@@ -31,6 +32,7 @@ jobs:
only-pr-labels: not-a-real-label
pending-repro:
runs-on: ubuntu-latest
permissions: {}
if: ${{ always() }}
needs: stale
steps:

View File

@@ -6,7 +6,7 @@ on:
build-image-sha:
type: string
description: 'SHA for electron/build image'
default: '933c7d6ff6802706875270bec2e3c891cf8add3f'
default: 'a82b87d7a4f5ff0cab61405f8151ac4cf4942aeb'
required: true
upload-to-storage:
description: 'Uploads to Azure storage'
@@ -18,9 +18,13 @@ on:
type: boolean
default: false
permissions: {}
jobs:
checkout-windows:
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read
container:
image: ghcr.io/electron/build:${{ inputs.build-image-sha }}
options: --user root --device /dev/fuse --cap-add SYS_ADMIN
@@ -47,7 +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
@@ -61,7 +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
@@ -75,7 +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

2
.gitignore vendored
View File

@@ -53,3 +53,5 @@ ts-gen
patches/mtime-cache.json
spec/fixtures/logo.png
.yarn/install-state.gz

942
.yarn/releases/yarn-4.12.0.cjs vendored Executable file

File diff suppressed because one or more lines are too long

12
.yarnrc.yml Normal file
View File

@@ -0,0 +1,12 @@
enableScripts: false
nmHoistingLimits: workspaces
nodeLinker: node-modules
npmMinimalAgeGate: 10080
npmPreapprovedPackages:
- "@electron/*"
yarnPath: .yarn/releases/yarn-4.12.0.cjs

9
DEPS
View File

@@ -2,9 +2,9 @@ gclient_gn_args_from = 'src'
vars = {
'chromium_version':
'142.0.7444.162',
'142.0.7444.265',
'node_version':
'v22.21.1',
'v22.22.0',
'nan_version':
'e14bdcd1f72d62bca1d541b66da43130384ec213',
'squirrel.mac_version':
@@ -30,9 +30,6 @@ vars = {
# The path of the sysroots.json file.
'sysroots_json_path': 'electron/script/sysroots.json',
# KEEP IN SYNC WITH utils.js FILE
'yarn_version': '1.22.22',
# To be able to build clean Chromium from sources.
'apply_patches': True,
@@ -155,7 +152,7 @@ hooks = [
'action': [
'python3',
'-c',
'import os, subprocess; os.chdir(os.path.join("src", "electron")); subprocess.check_call(["python3", "script/lib/npx.py", "yarn@' + (Var("yarn_version")) + '", "install", "--frozen-lockfile"]);',
'import os, subprocess; os.chdir(os.path.join("src", "electron")); subprocess.check_call(["node", ".yarn/releases/yarn-4.12.0.cjs", "install", "--immutable"]);',
],
},
{

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'
@@ -1315,7 +1317,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.
@@ -1330,13 +1332,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_

View File

@@ -32,9 +32,19 @@ update process. Apps that need to disable ATS can add the
### Windows
On Windows, you have to install your app into a user's machine before you can
use the `autoUpdater`, so it is recommended that you use
[electron-winstaller][installer-lib] or [Electron Forge's Squirrel.Windows maker][electron-forge-lib] to generate a Windows installer.
On Windows, the `autoUpdater` module automatically selects the appropriate update mechanism
based on how your app is packaged:
* **MSIX packages**: If your app is running as an MSIX package (created with [electron-windows-msix][msix-lib] and detected via [`process.windowsStore`](process.md#processwindowsstore-readonly)),
the module uses the MSIX updater, which supports direct MSIX file links and JSON update feeds.
* **Squirrel.Windows**: For apps installed via traditional installers (created with
[electron-winstaller][installer-lib] or [Electron Forge's Squirrel.Windows maker][electron-forge-lib]),
the module uses Squirrel.Windows for updates.
You don't need to configure which updater to use; Electron automatically detects the packaging
format and uses the appropriate one.
#### Squirrel.Windows
Apps built with Squirrel.Windows will trigger [custom launch events](https://github.com/Squirrel/Squirrel.Windows/blob/51f5e2cb01add79280a53d51e8d0cfa20f8c9f9f/docs/using/custom-squirrel-events-non-cs.md#application-startup-commands)
that must be handled by your Electron application to ensure proper setup and teardown.
@@ -55,6 +65,14 @@ The installer generated with Squirrel.Windows will create a shortcut icon with a
same ID for your app with `app.setAppUserModelId` API, otherwise Windows will
not be able to pin your app properly in task bar.
#### MSIX Packages
When your app is packaged as an MSIX, the `autoUpdater` module provides additional
functionality:
* Use the `allowAnyVersion` option in `setFeedURL()` to allow updates to older versions (downgrades)
* Support for direct MSIX file links or JSON update feeds (similar to Squirrel.Mac format)
## Events
The `autoUpdater` object emits the following events:
@@ -92,7 +110,7 @@ Returns:
Emitted when an update has been downloaded.
On Windows only `releaseName` is available.
With Squirrel.Windows only `releaseName` is available.
> [!NOTE]
> It is not strictly necessary to handle this event. A successfully
@@ -111,10 +129,12 @@ The `autoUpdater` object has the following methods:
### `autoUpdater.setFeedURL(options)`
* `options` Object
* `url` string
* `url` string - The update server URL. For _Windows_ MSIX, this can be either a direct link to an MSIX file (e.g., `https://example.com/update.msix`) or a JSON endpoint that returns update information (see the [Squirrel.Mac][squirrel-mac] README for more information).
* `headers` Record\<string, string\> (optional) _macOS_ - HTTP request headers.
* `serverType` string (optional) _macOS_ - Can be `json` or `default`, see the [Squirrel.Mac][squirrel-mac]
README for more information.
* `allowAnyVersion` boolean (optional) _Windows_ - If `true`, allows downgrades to older versions for MSIX packages.
Defaults to `false`.
Sets the `url` and initialize the auto updater.
@@ -151,3 +171,4 @@ closed.
[electron-forge-lib]: https://www.electronforge.io/config/makers/squirrel.windows
[app-user-model-id]: https://learn.microsoft.com/en-us/windows/win32/shell/appids
[event-emitter]: https://nodejs.org/api/events.html#events_class_eventemitter
[msix-lib]: https://github.com/electron-userland/electron-windows-msix

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_
@@ -756,6 +760,9 @@ Returns [`Rectangle`](structures/rectangle.md) - The `bounds` of the window as `
> [!NOTE]
> On macOS, the y-coordinate value returned will be at minimum the [Tray](tray.md) height. For example, calling `win.setBounds({ x: 25, y: 20, width: 800, height: 600 })` with a tray height of 38 means that `win.getBounds()` will return `{ x: 25, y: 38, width: 800, height: 600 }`.
> [!NOTE]
> On Wayland, this method will return `{ x: 0, y: 0, ... }` as introspecting or programmatically changing the global window coordinates is prohibited.
#### `win.getBackgroundColor()`
Returns `string` - Gets the background color of the window in Hex (`#RRGGBB`) format.
@@ -969,6 +976,9 @@ Moves window to `x` and `y`.
Returns `Integer[]` - Contains the window's current position.
> [!NOTE]
> On Wayland, this method will return `[0, 0]` as introspecting or programmatically changing the global window coordinates is prohibited.
#### `win.setTitle(title)`
* `title` string

View File

@@ -435,7 +435,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_
@@ -862,6 +866,9 @@ Returns [`Rectangle`](structures/rectangle.md) - The `bounds` of the window as `
> [!NOTE]
> On macOS, the y-coordinate value returned will be at minimum the [Tray](tray.md) height. For example, calling `win.setBounds({ x: 25, y: 20, width: 800, height: 600 })` with a tray height of 38 means that `win.getBounds()` will return `{ x: 25, y: 38, width: 800, height: 600 }`.
> [!NOTE]
> On Wayland, this method will return `{ x: 0, y: 0, ... }` as introspecting or programmatically changing the global window coordinates is prohibited.
#### `win.getBackgroundColor()`
Returns `string` - Gets the background color of the window in Hex (`#RRGGBB`) format.
@@ -1087,6 +1094,9 @@ Not supported on Wayland (Linux).
Returns `Integer[]` - Contains the window's current position.
> [!NOTE]
> On Wayland, this method will return `[0, 0]` as introspecting or programmatically changing the global window coordinates is prohibited.
#### `win.setTitle(title)`
* `title` string
@@ -1252,7 +1262,8 @@ Captures a snapshot of the page within `rect`. Omitting `rect` will capture the
Returns `Promise<void>` - the promise will resolve when the page has finished loading
(see [`did-finish-load`](web-contents.md#event-did-finish-load)), and rejects
if the page fails to load (see [`did-fail-load`](web-contents.md#event-did-fail-load)).
if the page fails to load (see
[`did-fail-load`](web-contents.md#event-did-fail-load)). A noop rejection handler is already attached, which avoids unhandled rejection errors. If the existing page has a beforeUnload handler, [`did-fail-load`](web-contents.md#event-did-fail-load) will be called unless [`will-prevent-unload`](web-contents.md#event-did-fail-load) is handled.
Same as [`webContents.loadURL(url[, options])`](web-contents.md#contentsloadurlurl-options).

View File

@@ -361,6 +361,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

@@ -94,18 +94,45 @@ 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`][].
> * 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.
---
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`.
### MacOS versions 14.2 or higher
`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

@@ -159,6 +159,22 @@ Notification activated (com.github.Electron:notification:EAF7B87C-A113-43D7-8E76
Notification replied to (com.github.Electron:notification:EAF7B87C-A113-43D7-8E76-F88EC9D73D44)
```
### `ELECTRON_DEBUG_MSIX_UPDATER`
Adds extra logs to MSIX updater operations on Windows to aid in debugging. Extra logging will be displayed when MSIX update operations are initiated, including package updates, package registration, and restart registration. This helps diagnose issues with MSIX package updates and deployments.
Sample output:
```sh
UpdateMsix called with URI: https://example.com/app.msix
DoUpdateMsix: Starting
Calling AddPackageByUriAsync... URI: https://example.com/app.msix
Update options - deferRegistration: true, developerMode: false, forceShutdown: false, forceTargetShutdown: false, forceUpdateFromAnyVersion: false
Waiting for deployment...
Deployment finished.
MSIX Deployment completed.
```
### `ELECTRON_LOG_ASAR_READS`
When Electron reads from an ASAR file, log the read offset and file path to

View File

@@ -107,7 +107,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_

View File

@@ -71,7 +71,7 @@ will disable the support for `asar` archives in Node's built-in modules.
### `process.noDeprecation`
A `boolean` that controls whether or not deprecation warnings are printed to `stderr`.
A `boolean` (optional) that controls whether or not deprecation warnings are printed to `stderr`.
Setting this to `true` will silence deprecation warnings. This property is used
instead of the `--no-deprecation` command line flag.
@@ -128,8 +128,8 @@ A `string` representing Electron's version string.
### `process.windowsStore` _Readonly_
A `boolean`. If the app is running as a Windows Store app (appx), this property is `true`,
for otherwise it is `undefined`.
A `boolean`. If the app is running as an MSIX package (including AppX for Windows Store),
this property is `true`, otherwise it is `undefined`.
### `process.contextId` _Readonly_

View File

@@ -58,6 +58,10 @@ Rejects if there was an error while deleting the requested item.
This moves a path to the OS-specific trash location (Trash on macOS, Recycle
Bin on Windows, and a desktop-environment-specific location on Linux).
The path must use the default path separator for the platform (backslash on
Windows). Use `path.resolve()` from the `node:path` module to ensure correct
handling on all filesystems.
### `shell.beep()`
Play the beep sound.

View File

@@ -72,6 +72,9 @@
some GTK+3 desktop environments. Default is `false`.
* `transparent` boolean (optional) - Makes the window [transparent](../../tutorial/custom-window-styles.md#transparent-windows).
Default is `false`. On Windows, does not work unless the window is frameless.
When you add a [`View`](../view.md) to a `BaseWindow`, you'll need to call
[`view.setBackgroundColor`](../view.md#viewsetbackgroundcolorcolor) with a transparent
background color on that view to make its background transparent as well.
* `type` string (optional) - The type of window, default is normal window. See more about
this below.
* `visualEffectState` string (optional) _macOS_ - Specify how the material
@@ -99,9 +102,9 @@
* `trafficLightPosition` [Point](point.md) (optional) _macOS_ -
Set a custom position for the traffic light buttons in frameless windows.
* `roundedCorners` boolean (optional) _macOS_ _Windows_ - Whether frameless window
should have rounded corners. Default is `true`. Setting this property
to `false` will prevent the window from being fullscreenable on macOS.
On Windows versions older than Windows 11 Build 22000 this property has no effect, and frameless windows will not have rounded corners.
should have rounded corners. Default is `true`. On Windows versions older than
Windows 11 Build 22000 this property has no effect, and frameless windows will
not have rounded corners.
* `thickFrame` boolean (optional) _Windows_ - Use `WS_THICKFRAME` style for
frameless windows on Windows, which adds the standard window frame. Setting it
to `false` will remove window shadow and window animations, and disable window

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

@@ -1079,7 +1079,7 @@ Emitted when the [mainFrame](web-contents.md#contentsmainframe-readonly), an `<i
Returns `Promise<void>` - the promise will resolve when the page has finished loading
(see [`did-finish-load`](web-contents.md#event-did-finish-load)), and rejects
if the page fails to load (see
[`did-fail-load`](web-contents.md#event-did-fail-load)). A noop rejection handler is already attached, which avoids unhandled rejection errors.
[`did-fail-load`](web-contents.md#event-did-fail-load)). A noop rejection handler is already attached, which avoids unhandled rejection errors. If the existing page has a beforeUnload handler, [`did-fail-load`](web-contents.md#event-did-fail-load) will be called unless [`will-prevent-unload`](web-contents.md#event-did-fail-load) is handled.
Loads the `url` in the window. The `url` must contain the protocol prefix,
e.g. the `http://` or `file://`. If the load should bypass http cache then
@@ -2410,7 +2410,8 @@ A [`NavigationHistory`](navigation-history.md) used by this webContents.
#### `contents.hostWebContents` _Readonly_
A [`WebContents`](web-contents.md) instance that might own this `WebContents`.
A `WebContents | null` property that represents a [`WebContents`](web-contents.md)
instance that might own this `WebContents`.
#### `contents.devToolsWebContents` _Readonly_

View File

@@ -37,6 +37,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.

View File

@@ -6,77 +6,17 @@ Follow the guidelines below for building **Electron itself** on Linux, for the p
## Prerequisites
* At least 25GB disk space and 8GB RAM.
* Python >= 3.9.
* [Node.js](https://nodejs.org/download/) >= 22.12.0
* [clang](https://clang.llvm.org/get_started.html) 3.4 or later.
* Development headers of GTK 3 and libnotify.
Due to Electron's dependency on Chromium, prerequisites and dependencies for Electron change over time. [Chromium's documentation on building on Linux](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/linux/build_instructions.md) has up to date information for building Chromium on Linux. This documentation can generally
be followed for building Electron on Linux as well.
On Ubuntu >= 20.04, install the following libraries:
```sh
$ sudo apt-get install build-essential clang libdbus-1-dev libgtk-3-dev \
libnotify-dev libasound2-dev libcap-dev \
libcups2-dev libxtst-dev \
libxss1 libnss3-dev gcc-multilib g++-multilib curl \
gperf bison python3-dbusmock openjdk-8-jre
```
On Ubuntu < 20.04, install the following libraries:
```sh
$ sudo apt-get install build-essential clang libdbus-1-dev libgtk-3-dev \
libnotify-dev libgnome-keyring-dev \
libasound2-dev libcap-dev libcups2-dev libxtst-dev \
libxss1 libnss3-dev gcc-multilib g++-multilib curl \
gperf bison python-dbusmock openjdk-8-jre
```
On RHEL / CentOS, install the following libraries:
```sh
$ sudo yum install clang dbus-devel gtk3-devel libnotify-devel \
libgnome-keyring-devel xorg-x11-server-utils libcap-devel \
cups-devel libXtst-devel alsa-lib-devel libXrandr-devel \
nss-devel python-dbusmock openjdk-8-jre
```
On Fedora, install the following libraries:
```sh
$ sudo dnf install clang dbus-devel gperf gtk3-devel \
libnotify-devel libgnome-keyring-devel libcap-devel \
cups-devel libXtst-devel alsa-lib-devel libXrandr-devel \
nss-devel python-dbusmock
```
On Arch Linux / Manjaro, install the following libraries:
```sh
$ sudo pacman -Syu base-devel clang libdbus gtk2 libnotify \
libgnome-keyring alsa-lib libcap libcups libxtst \
libxss nss gcc-multilib curl gperf bison \
python2 python-dbusmock jdk8-openjdk
```
Other distributions may offer similar packages for installation via package
managers such as pacman. Or one can compile from source code.
Additionally, Electron's [Linux dependency installer](https://github.com/electron/build-images/blob/main/tools/install-deps.sh) can be referenced to get the current dependencies that Electron requires in addition to what Chromium installs via [build/install-deps.sh](https://chromium.googlesource.com/chromium/src/+/HEAD/build/install-build-deps.sh).
### Cross compilation
If you want to build for an `arm` target you should also install the following
dependencies:
If you want to build for an `arm` target, you can use Electron's [Linux dependency installer](https://github.com/electron/build-images/blob/main/tools/install-deps.sh) to install the additional dependencies by passing the `--arm argument`:
```sh
$ sudo apt-get install libc6-dev-armhf-cross linux-libc-dev-armhf-cross \
g++-arm-linux-gnueabihf
```
Similarly for `arm64`, install the following:
```sh
$ sudo apt-get install libc6-dev-arm64-cross linux-libc-dev-arm64-cross \
g++-aarch64-linux-gnu
$ sudo install-deps.sh --arm
```
And to cross-compile for `arm` or targets, you should pass the

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

@@ -24,7 +24,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

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

@@ -36,7 +36,7 @@ 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
texture to your own rendering program. You can read more details
[here](https://github.com/electron/electron/blob/main/shell/browser/osr/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

@@ -767,7 +767,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,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

@@ -222,8 +222,10 @@ auto_filenames = {
browser_bundle_deps = [
"lib/browser/api/app.ts",
"lib/browser/api/auto-updater.ts",
"lib/browser/api/auto-updater/auto-updater-msix.ts",
"lib/browser/api/auto-updater/auto-updater-native.ts",
"lib/browser/api/auto-updater/auto-updater-win.ts",
"lib/browser/api/auto-updater/msix-update-win.ts",
"lib/browser/api/auto-updater/squirrel-update-win.ts",
"lib/browser/api/base-window.ts",
"lib/browser/api/browser-view.ts",

View File

@@ -277,6 +277,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",
@@ -587,6 +589,7 @@ filenames = {
"shell/common/electron_command_line.cc",
"shell/common/electron_command_line.h",
"shell/common/electron_constants.h",
"shell/common/electron_paths.cc",
"shell/common/electron_paths.h",
"shell/common/gin_converters/accelerator_converter.cc",
"shell/common/gin_converters/accelerator_converter.h",

View File

@@ -1,5 +1,10 @@
if (process.platform === 'win32') {
module.exports = require('./auto-updater/auto-updater-win');
// windowsStore indicates whether the app is running as a packaged app (MSIX), even outside of the store
if (process.windowsStore) {
module.exports = require('./auto-updater/auto-updater-msix');
} else {
module.exports = require('./auto-updater/auto-updater-win');
}
} else {
module.exports = require('./auto-updater/auto-updater-native');
}

View File

@@ -0,0 +1,449 @@
import * as msixUpdate from '@electron/internal/browser/api/auto-updater/msix-update-win';
import { app, net } from 'electron/main';
import { EventEmitter } from 'events';
interface UpdateInfo {
ok: boolean; // False if error encountered
available?: boolean; // True if the update is available, false if not
updateUrl?: string; // The URL of the update
releaseNotes?: string; // The release notes of the update
releaseName?: string; // The release name of the update
releaseDate?: Date; // The release date of the update
}
interface MSIXPackageInfo {
id: string;
familyName: string;
developmentMode: boolean;
version: string;
signatureKind: 'developer' | 'enterprise' | 'none' | 'store' | 'system';
appInstallerUri?: string;
}
/**
* Options for updating an MSIX package.
* Used with `updateMsix()` to control how the package update behaves.
*
* These options correspond to the Windows.Management.Deployment.AddPackageOptions class properties.
*
* @see https://learn.microsoft.com/en-us/uwp/api/windows.management.deployment.addpackageoptions?view=winrt-26100
*/
export interface UpdateMsixOptions {
/**
* Gets or sets a value that indicates whether to delay registration of the main package
* or dependency packages if the packages are currently in use.
*
* Corresponds to `AddPackageOptions.DeferRegistrationWhenPackagesAreInUse`
*
* @default false
*/
deferRegistration?: boolean;
/**
* Gets or sets a value that indicates whether the app is installed in developer mode.
* When set, the app is installed in development mode which allows for a more rapid
* development cycle. The BlockMap.xml, [Content_Types].xml, and digital signature
* files are not required for app installation.
*
* Corresponds to `AddPackageOptions.DeveloperMode`
*
* @default false
*/
developerMode?: boolean;
/**
* Gets or sets a value that indicates whether the processes associated with the package
* will be shut down forcibly so that registration can continue if the package, or any
* package that depends on the package, is currently in use.
*
* Corresponds to `AddPackageOptions.ForceAppShutdown`
*
* @default false
*/
forceShutdown?: boolean;
/**
* Gets or sets a value that indicates whether the processes associated with the package
* will be shut down forcibly so that registration can continue if the package is
* currently in use.
*
* Corresponds to `AddPackageOptions.ForceTargetAppShutdown`
*
* @default false
*/
forceTargetShutdown?: boolean;
/**
* Gets or sets a value that indicates whether to force a specific version of a package
* to be added, regardless of if a higher version is already added.
*
* Corresponds to `AddPackageOptions.ForceUpdateFromAnyVersion`
*
* @default false
*/
forceUpdateFromAnyVersion?: boolean;
}
/**
* Options for registering an MSIX package.
* Used with `registerPackage()` to control how the package registration behaves.
*
* These options correspond to the Windows.Management.Deployment.DeploymentOptions enum.
*
* @see https://learn.microsoft.com/en-us/uwp/api/windows.management.deployment.deploymentoptions?view=winrt-26100
*/
interface RegisterPackageOptions {
/**
* Force shutdown of the application if it's currently running.
* If this package, or any package that depends on this package, is currently in use,
* the processes associated with the package are shut down forcibly so that registration can continue.
*
* Corresponds to `DeploymentOptions.ForceApplicationShutdown` (value: 1)
*
* @default false
*/
forceShutdown?: boolean;
/**
* Force shutdown of the target application if it's currently running.
* If this package is currently in use, the processes associated with the package
* are shut down forcibly so that registration can continue.
*
* Corresponds to `DeploymentOptions.ForceTargetApplicationShutdown` (value: 64)
*
* @default false
*/
forceTargetShutdown?: boolean;
/**
* Force a specific version of a package to be staged/registered, regardless of if
* a higher version is already staged/registered.
*
* Corresponds to `DeploymentOptions.ForceUpdateFromAnyVersion` (value: 262144)
*
* @default false
*/
forceUpdateFromAnyVersion?: boolean;
}
class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
updateAvailable: boolean = false;
updateURL: string | null = null;
updateHeaders: Record<string, string> | null = null;
allowAnyVersion: boolean = false;
// Private: Validate that the URL points to an MSIX file (following redirects)
private async validateMsixUrl (url: string): Promise<void> {
try {
// Make a HEAD request to follow redirects and get the final URL
const response = await net.fetch(url, {
method: 'HEAD',
headers: this.updateHeaders ? new Headers(this.updateHeaders) : undefined,
redirect: 'follow' // Follow redirects to get the final URL
});
// Get the final URL after redirects (response.url contains the final URL)
const finalUrl = response.url || url;
const urlObj = new URL(finalUrl);
const pathname = urlObj.pathname.toLowerCase();
// Check if final URL ends with .msix or .msixbundle extension
const hasMsixExtension = pathname.endsWith('.msix') || pathname.endsWith('.msixbundle');
if (!hasMsixExtension) {
throw new Error(`Update URL does not point to an MSIX file. Expected .msix or .msixbundle extension, got final URL: ${finalUrl}`);
}
} catch (error) {
if (error instanceof TypeError) {
throw new Error(`Invalid MSIX URL: ${url}`);
}
throw error;
}
}
// Private: Check if URL is a direct MSIX file (following redirects)
private async isDirectMsixUrl (url: string, emitError: boolean = false): Promise<boolean> {
try {
await this.validateMsixUrl(url);
return true;
} catch (error) {
if (emitError) {
this.emitError(error as Error);
}
return false;
}
}
// Supports both versioning (x.y.z) and Windows version format (x.y.z.a)
// Returns: 1 if v1 > v2, -1 if v1 < v2, 0 if v1 === v2
private compareVersions (v1: string, v2: string): number {
const parts1 = v1.split('.').map(part => {
const parsed = parseInt(part, 10);
return isNaN(parsed) ? 0 : parsed;
});
const parts2 = v2.split('.').map(part => {
const parsed = parseInt(part, 10);
return isNaN(parsed) ? 0 : parsed;
});
const maxLength = Math.max(parts1.length, parts2.length);
for (let i = 0; i < maxLength; i++) {
const part1 = parts1[i] ?? 0;
const part2 = parts2[i] ?? 0;
if (part1 > part2) return 1;
if (part1 < part2) return -1;
}
return 0;
}
// Private: Parse the static releases array format
// This is a static JSON file containing all releases
private parseStaticReleasFile (json: any, currentVersion: string): { ok: boolean; available: boolean; url?: string; name?: string; notes?: string; pub_date?: string } {
if (!Array.isArray(json.releases) || !json.currentRelease || typeof json.currentRelease !== 'string') {
this.emitError(new Error('Invalid releases format. Expected \'releases\' array and \'currentRelease\' string.'));
return { ok: false, available: false };
}
// Use currentRelease property to determine if update is available
const currentReleaseVersion = json.currentRelease;
// Compare current version with currentRelease
const versionComparison = this.compareVersions(currentReleaseVersion, currentVersion);
// If versions match, we're up to date
if (versionComparison === 0) {
return { ok: true, available: false };
}
// If currentRelease is older than current version, check allowAnyVersion
if (versionComparison < 0) {
// If allowAnyVersion is true, allow downgrades
if (this.allowAnyVersion) {
// Continue to find the release entry for downgrade
} else {
return { ok: true, available: false };
}
}
// currentRelease is newer, find the release entry
const releaseEntry = json.releases.find((r: any) => r.version === currentReleaseVersion);
if (!releaseEntry || !releaseEntry.updateTo) {
this.emitError(new Error(`Release entry for version '${currentReleaseVersion}' not found or missing 'updateTo' property.`));
return { ok: false, available: false };
}
const updateTo = releaseEntry.updateTo;
if (!updateTo.url) {
this.emitError(new Error(`Invalid release entry. 'updateTo.url' is missing for version ${currentReleaseVersion}.`));
return { ok: false, available: false };
}
return {
ok: true,
available: true,
url: updateTo.url,
name: updateTo.name,
notes: updateTo.notes,
pub_date: updateTo.pub_date
};
}
private parseDynamicReleasFile (json: any): { ok: boolean; available: boolean; url?: string; name?: string; notes?: string; pub_date?: string } {
if (!json.url) {
this.emitError(new Error('Invalid releases format. Expected \'url\' string property.'));
return { ok: false, available: false };
}
return { ok: true, available: true, url: json.url, name: json.name, notes: json.notes, pub_date: json.pub_date };
}
private async fetchSquirrelJson (url: string) {
const headers: Record<string, string> = {
...this.updateHeaders,
Accept: 'application/json' // Always set Accept header, overriding any user-provided Accept
};
const response = await net.fetch(url, {
headers
});
if (response.status === 204) {
return { ok: true, available: false };
} else if (response.status === 200) {
const updateJson = await response.json();
// Check if this is the static releases array format
if (Array.isArray(updateJson.releases)) {
// Get current package version
const packageInfo = msixUpdate.getPackageInfo();
const currentVersion = packageInfo.version;
if (!currentVersion) {
this.emitError(new Error('Cannot determine current package version.'));
return { ok: false, available: false };
}
return this.parseStaticReleasFile(updateJson, currentVersion);
} else {
// Dynamic format: server returns JSON with update info for current version
return this.parseDynamicReleasFile(updateJson);
}
} else {
this.emitError(new Error(`Unexpected response status: ${response.status}`));
return { ok: false, available: false };
}
}
private async getUpdateInfo (url: string): Promise<UpdateInfo> {
if (url && await this.isDirectMsixUrl(url)) {
return { ok: true, available: true, updateUrl: url, releaseDate: new Date() };
} else {
const updateJson = await this.fetchSquirrelJson(url);
if (!updateJson.ok) {
return { ok: false };
} else if (updateJson.ok && !updateJson.available) {
return { ok: true, available: false };
} else {
// updateJson.ok && updateJson.available must be true here
// Parse the publication date if present (ISO 8601 format)
let releaseDate: Date | null = null;
if (updateJson.pub_date) {
releaseDate = new Date(updateJson.pub_date);
}
const updateUrl = updateJson.url ?? '';
const releaseNotes = updateJson.notes ?? '';
const releaseName = updateJson.name ?? '';
releaseDate = releaseDate ?? new Date();
if (!await this.isDirectMsixUrl(updateUrl, true)) {
return { ok: false };
} else {
return {
ok: true,
available: true,
updateUrl,
releaseNotes,
releaseName,
releaseDate
};
}
}
}
}
getFeedURL () {
return this.updateURL ?? '';
}
setFeedURL (options: { url: string; headers?: Record<string, string>; allowAnyVersion?: boolean } | string) {
let updateURL: string;
let headers: Record<string, string> | undefined;
let allowAnyVersion: boolean | undefined;
if (typeof options === 'object') {
if (typeof options.url === 'string') {
updateURL = options.url;
headers = options.headers;
allowAnyVersion = options.allowAnyVersion;
} else {
throw new TypeError('Expected options object to contain a \'url\' string property in setFeedUrl call');
}
} else if (typeof options === 'string') {
updateURL = options;
} else {
throw new TypeError('Expected an options object with a \'url\' property to be provided');
}
this.updateURL = updateURL;
this.updateHeaders = headers ?? null;
this.allowAnyVersion = allowAnyVersion ?? false;
}
getPackageInfo (): MSIXPackageInfo {
return msixUpdate.getPackageInfo() as MSIXPackageInfo;
}
async checkForUpdates () {
const url = this.updateURL;
if (!url) {
return this.emitError(new Error('Update URL is not set'));
}
// Check if running in MSIX package
const packageInfo = msixUpdate.getPackageInfo();
if (!packageInfo.familyName) {
return this.emitError(new Error('MSIX updates are not supported'));
}
// If appInstallerUri is set, Windows App Installer manages updates automatically
// Prevent updates here to avoid conflicts
if (packageInfo.appInstallerUri) {
return this.emitError(new Error('Auto-updates are managed by Windows App Installer. Updates are not allowed when installed via Application Manifest.'));
}
this.emit('checking-for-update');
try {
const msixUrlInfo = await this.getUpdateInfo(url);
if (!msixUrlInfo.ok) {
return this.emitError(new Error('Invalid update or MSIX URL. See previous errors.'));
}
if (!msixUrlInfo.available) {
this.emit('update-not-available');
} else {
this.updateAvailable = true;
this.emit('update-available');
await msixUpdate.updateMsix(msixUrlInfo.updateUrl, {
deferRegistration: true,
developerMode: false,
forceShutdown: false,
forceTargetShutdown: false,
forceUpdateFromAnyVersion: this.allowAnyVersion
} as UpdateMsixOptions);
this.emit('update-downloaded', {}, msixUrlInfo.releaseNotes, msixUrlInfo.releaseName, msixUrlInfo.releaseDate, msixUrlInfo.updateUrl, () => {
this.quitAndInstall();
});
}
} catch (error) {
this.emitError(error as Error);
}
}
async quitAndInstall () {
if (!this.updateAvailable) {
this.emitError(new Error('No update available, can\'t quit and install'));
app.quit();
return;
}
try {
// Get package info to get family name
const packageInfo = msixUpdate.getPackageInfo();
if (!packageInfo.familyName) {
return this.emitError(new Error('MSIX updates are not supported'));
}
msixUpdate.registerRestartOnUpdate('');
this.emit('before-quit-for-update');
// force shutdown of the application and register the package to be installed on restart
await msixUpdate.registerPackage(packageInfo.familyName, {
forceShutdown: true
} as RegisterPackageOptions);
} catch (error) {
this.emitError(error as Error);
}
}
// Private: Emit both error object and message, this is to keep compatibility
// with Old APIs.
emitError (error: Error) {
this.emit('error', error, error.message);
}
}
export default new AutoUpdater();

View File

@@ -20,6 +20,11 @@ class AutoUpdater extends EventEmitter implements Electron.AutoUpdater {
return this.updateURL ?? '';
}
getPackageInfo () {
// Squirrel-based Windows apps don't have MSIX package information
return undefined;
}
setFeedURL (options: { url: string } | string) {
let updateURL: string;
if (typeof options === 'object') {

View File

@@ -0,0 +1,4 @@
const { updateMsix, registerPackage, registerRestartOnUpdate, getPackageInfo } =
process._linkedBinding('electron_browser_msix_updater');
export { updateMsix, registerPackage, registerRestartOnUpdate, getPackageInfo };

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,7 +25,7 @@ const MenuItem = function (this: any, options: any) {
this.overrideReadOnlyProperty('type', roles.getDefaultType(this.role));
this.overrideReadOnlyProperty('role');
this.overrideReadOnlyProperty('accelerator');
this.overrideReadOnlyProperty('accelerator', roles.getDefaultAccelerator(this.role));
this.overrideReadOnlyProperty('icon');
this.overrideReadOnlyProperty('submenu');

View File

@@ -119,7 +119,10 @@ export function fetchWithSession (input: RequestInfo, init: (RequestInit & {bypa
p.reject(err);
});
if (!req.body?.pipeTo(Writable.toWeb(r as unknown as Writable)).then(() => r.end())) { r.end(); }
// pipeTo expects a WritableStream<Uint8Array>. Node.js' Writable.toWeb returns WritableStream<any>,
// which causes a TS structural mismatch.
const writable = Writable.toWeb(r as unknown as Writable) as unknown as WritableStream<Uint8Array>;
if (!req.body?.pipeTo(writable).then(() => r.end())) { r.end(); }
return p.promise;
}

View File

@@ -4,6 +4,8 @@ import { createReadStream } from 'fs';
import { Readable } from 'stream';
import { ReadableStream } from 'stream/web';
import type { ReadableStreamDefaultReader } from 'stream/web';
// Global protocol APIs.
const { registerSchemesAsPrivileged, getStandardSchemes, Protocol } = process._linkedBinding('electron_browser_protocol');
@@ -12,7 +14,7 @@ const ERR_UNEXPECTED = -9;
const isBuiltInScheme = (scheme: string) => ['http', 'https', 'file'].includes(scheme);
function makeStreamFromPipe (pipe: any): ReadableStream {
function makeStreamFromPipe (pipe: any): ReadableStream<Uint8Array> {
const buf = new Uint8Array(1024 * 1024 /* 1 MB */);
return new ReadableStream({
async pull (controller) {
@@ -38,21 +40,26 @@ function makeStreamFromFileInfo ({
filePath: string;
offset?: number;
length?: number;
}): ReadableStream {
}): ReadableStream<Uint8Array> {
// Node's Readable.toWeb produces a WHATWG ReadableStream whose chunks are Uint8Array.
return Readable.toWeb(createReadStream(filePath, {
start: offset,
end: length >= 0 ? offset + length : undefined
}));
})) as ReadableStream<Uint8Array>;
}
function convertToRequestBody (uploadData: ProtocolRequest['uploadData']): RequestInit['body'] {
if (!uploadData) return null;
// Optimization: skip creating a stream if the request is just a single buffer.
if (uploadData.length === 1 && (uploadData[0] as any).type === 'rawData') return uploadData[0].bytes;
if (uploadData.length === 1 && (uploadData[0] as any).type === 'rawData') {
return uploadData[0].bytes as any;
}
const chunks = [...uploadData] as any[]; // TODO: types are wrong
let current: ReadableStreamDefaultReader | null = null;
return new ReadableStream({
const chunks = [...uploadData] as any[]; // TODO: refine ProtocolRequest types
// Use Node's web stream types explicitly to avoid DOM lib vs Node lib structural mismatches.
// Generic <Uint8Array> ensures reader.read() returns value?: Uint8Array consistent with enqueue.
let current: ReadableStreamDefaultReader<Uint8Array> | null = null;
return new ReadableStream<Uint8Array>({
async pull (controller) {
if (current) {
const { done, value } = await current.read();
@@ -67,7 +74,7 @@ function convertToRequestBody (uploadData: ProtocolRequest['uploadData']): Reque
if (!chunks.length) { return controller.close(); }
const chunk = chunks.shift()!;
if (chunk.type === 'rawData') {
controller.enqueue(chunk.bytes);
controller.enqueue(chunk.bytes as Uint8Array);
} else if (chunk.type === 'file') {
current = makeStreamFromFileInfo(chunk).getReader();
return this.pull!(controller);

View File

@@ -40,7 +40,7 @@ process.on('uncaughtException', function (error) {
// Emit 'exit' event on quit.
const { app } = require('electron');
app.on('quit', (_event, exitCode) => {
app.on('quit', (_event: any, exitCode: number) => {
process.emit('exit', exitCode);
});

View File

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

View File

@@ -1,15 +1,16 @@
{
"name": "electron",
"name": "@electron-ci/dev-root",
"version": "0.0.0-development",
"repository": "https://github.com/electron/electron",
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
"devDependencies": {
"@azure/storage-blob": "^12.28.0",
"@datadog/datadog-ci": "^4.1.2",
"@electron/asar": "^3.2.13",
"@electron/docs-parser": "^2.0.0",
"@electron/fiddle-core": "^1.3.4",
"@electron/github-app-auth": "^2.2.1",
"@electron/lint-roller": "^3.1.2",
"@electron/github-app-auth": "^3.2.0",
"@electron/lint-roller": "^3.2.0",
"@electron/typescript-definitions": "^9.1.2",
"@octokit/rest": "^20.1.2",
"@primer/octicons": "^10.0.0",
@@ -24,7 +25,6 @@
"buffer": "^6.0.3",
"chalk": "^4.1.0",
"check-for-leaks": "^1.2.1",
"dugite": "^2.7.1",
"eslint": "^8.57.1",
"eslint-config-standard": "^17.1.0",
"eslint-plugin-import": "^2.32.0",
@@ -40,6 +40,7 @@
"lint-staged": "^16.1.0",
"markdownlint-cli2": "^0.18.0",
"minimist": "^1.2.8",
"node-gyp": "^11.4.2",
"null-loader": "^4.0.1",
"pre-flight": "^2.0.0",
"process": "^0.11.10",
@@ -56,7 +57,8 @@
"url": "^0.11.4",
"webpack": "^5.95.0",
"webpack-cli": "^5.1.4",
"wrapper-webpack-plugin": "^2.2.0"
"wrapper-webpack-plugin": "^2.2.0",
"yaml": "^2.8.1"
},
"private": true,
"scripts": {
@@ -131,9 +133,25 @@
"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": {
"nan": "nodejs/nan#e14bdcd1f72d62bca1d541b66da43130384ec213"
"dbus-native/xml2js": "0.5.0",
"abstract-socket": "github:deepak1556/node-abstractsocket#928cc591decd12aff7dad96449da8afc29832c19",
"minimist@npm:~0.0.1": "0.2.4"
},
"packageManager": "yarn@4.12.0",
"workspaces": [
"spec",
"spec/fixtures/native-addon/*"
],
"dependenciesMeta": {
"abstract-socket": {
"built": true
}
}
}

View File

@@ -143,3 +143,11 @@ allow_electron_to_depend_on_components_os_crypt_sync.patch
expose_referrerscriptinfo_hostdefinedoptionsindex.patch
chore_disable_protocol_handler_dcheck.patch
fix_release_mouse_buttons_on_focus_loss_on_wayland.patch
viz_fix_visual_artifacts_due_to_resizing_root_render_pass_with_dcomp.patch
viz_do_not_overallocate_surface_on_initial_render.patch
viz_create_isbufferqueuesupportedandenabled.patch
viz_fix_visual_artifacts_while_resizing_window_with_dcomp.patch
graphite_handle_out_of_order_recording_errors.patch
ozone_wayland_treat_dnd_drop_performed_with_none_action_as_a.patch
cherry-pick-e045399a1ecb.patch
loaf_add_feature_to_enable_sourceurl_for_all_protocols.patch

View File

@@ -46,7 +46,7 @@ index 7280ef29b85c1b16b11dd9e4d628a9eb579bb4dd..ab56e29d402a400a8c91aa97b6e82ad7
# than here in :chrome_dll.
deps += [ "//chrome:packed_resources_integrity_header" ]
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 15cfa64348e80a3507fc83c3819e9abdb238bffb..4650080f45da4e321d4b0f0dabd98f2bf097c7c2 100644
index d8978eb678048850cc0e629d0c978f23417b5be9..219c9ae3dde4f2239b5c1331b99c8f2e9a170628 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -7571,9 +7571,12 @@ test("unit_tests") {

View File

@@ -0,0 +1,132 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dominik=20R=C3=B6ttsches?= <drott@chromium.org>
Date: Thu, 12 Feb 2026 06:35:36 -0800
Subject: Avoid stale iteration in CSSFontFeatureValuesMap
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
To avoid invalid iterator state, take a snapshot of the
map when creating the iteration source. This addresses
the immediate problem of iterating while modifying.
Remaining work tracked in https://crbug.com/483936078
Fixed: 483569511
Change-Id: Ie29cfdf7ed94bbe189b44c842a5efce571bb2cee
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7566570
Commit-Queue: Dominik Röttsches <drott@chromium.org>
Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1583927}
diff --git a/third_party/blink/renderer/core/css/css_font_feature_values_map.cc b/third_party/blink/renderer/core/css/css_font_feature_values_map.cc
index 0c5990799fbfdff5f1d1e04a9038a471217ad0d2..2ea27901e3ba503e7e1acc5dacf90dc60d52ac1a 100644
--- a/third_party/blink/renderer/core/css/css_font_feature_values_map.cc
+++ b/third_party/blink/renderer/core/css/css_font_feature_values_map.cc
@@ -13,16 +13,15 @@ class FontFeatureValuesMapIterationSource final
: public PairSyncIterable<CSSFontFeatureValuesMap>::IterationSource {
public:
FontFeatureValuesMapIterationSource(const CSSFontFeatureValuesMap& map,
- const FontFeatureAliases* aliases)
- : map_(map), aliases_(aliases), iterator_(aliases->begin()) {}
+ const FontFeatureAliases aliases)
+ : map_(map),
+ aliases_(std::move(aliases)),
+ iterator_(aliases_.begin()) {}
bool FetchNextItem(ScriptState* script_state,
String& map_key,
Vector<uint32_t>& map_value) override {
- if (!aliases_) {
- return false;
- }
- if (iterator_ == aliases_->end()) {
+ if (iterator_ == aliases_.end()) {
return false;
}
map_key = iterator_->key;
@@ -37,9 +36,13 @@ class FontFeatureValuesMapIterationSource final
}
private:
- // Needs to be kept alive while we're iterating over it.
const Member<const CSSFontFeatureValuesMap> map_;
- const FontFeatureAliases* aliases_;
+ // Create a copy to keep the iterator from becoming invalid if there are
+ // modifications to the aliases HashMap while iterating.
+ // TODO(https://crbug.com/483936078): Implement live/stable iteration over
+ // FontFeatureAliases by changing its storage type, avoiding taking a copy
+ // here.
+ const FontFeatureAliases aliases_;
FontFeatureAliases::const_iterator iterator_;
};
@@ -49,8 +52,8 @@ uint32_t CSSFontFeatureValuesMap::size() const {
PairSyncIterable<CSSFontFeatureValuesMap>::IterationSource*
CSSFontFeatureValuesMap::CreateIterationSource(ScriptState*) {
- return MakeGarbageCollected<FontFeatureValuesMapIterationSource>(*this,
- aliases_);
+ return MakeGarbageCollected<FontFeatureValuesMapIterationSource>(
+ *this, aliases_ ? *aliases_ : FontFeatureAliases());
}
bool CSSFontFeatureValuesMap::GetMapEntry(ScriptState*,
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/font_feature_values_map_iteration.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/font_feature_values_map_iteration.html
new file mode 100644
index 0000000000000000000000000000000000000000..eac7198b0b4a58007cbcc77ad3e9357a1009117c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/font_feature_values_map_iteration.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>CSSFontFeatureValuesMap Iteration and Modification</title>
+ <link
+ rel="help"
+ href="https://drafts.csswg.org/css-fonts-4/#om-fontfeaturevalues"
+ />
+ <meta
+ name="assert"
+ content="Iteration while modifying CSSFontFeatureValuesMap does not crash."
+ />
+ <script type="text/javascript" src="/resources/testharness.js"></script>
+ <script
+ type="text/javascript"
+ src="/resources/testharnessreport.js"
+ ></script>
+ </head>
+ <body>
+ <style>
+ @font-feature-values TestFont {
+ @styleset {
+ a: 1;
+ b: 2;
+ c: 3;
+ }
+ }
+ </style>
+ <script>
+ test(() => {
+ const rule = document.styleSheets[0].cssRules[0];
+ const map = rule.styleset;
+ const iterator = map.entries();
+ let count = 0;
+
+ while (count < 10) {
+ const { value: entry, done } = iterator.next();
+ if (done) break;
+
+ const [key, value] = entry;
+
+ map.delete(key);
+ for (let i = 0; i < 100; i++) {
+ map.set(`newkey_${count}_${i}`, i);
+ }
+
+ count++;
+ }
+ }, "Iteration of the CSSFontFeatureValuesMap does not crash.");
+ </script>
+ </body>
+</html>

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..48948b409d6da58ade72c60ed848df49
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 ab48c8b88a7cf311205b221169308d96e95f239f..d714d2022f685052e1def3b0d242d2ea596d790b 100644
index ab48c8b88a7cf311205b221169308d96e95f239f..54883f202c1769227c823d46454173b53692a7dd 100644
--- a/content/browser/service_host/utility_process_host.cc
+++ b/content/browser/service_host/utility_process_host.cc
@@ -245,13 +245,13 @@ UtilityProcessHost::Options& UtilityProcessHost::Options::WithFileToPreload(
@@ -207,7 +213,7 @@ index ab48c8b88a7cf311205b221169308d96e95f239f..d714d2022f685052e1def3b0d242d2ea
#if BUILDFLAG(USE_ZYGOTE)
UtilityProcessHost::Options& UtilityProcessHost::Options::WithZygoteForTesting(
@@ -261,6 +261,36 @@ UtilityProcessHost::Options& UtilityProcessHost::Options::WithZygoteForTesting(
@@ -261,6 +261,45 @@ UtilityProcessHost::Options& UtilityProcessHost::Options::WithZygoteForTesting(
}
#endif // BUILDFLAG(USE_ZYGOTE)
@@ -240,11 +246,20 @@ index ab48c8b88a7cf311205b221169308d96e95f239f..d714d2022f685052e1def3b0d242d2ea
+ 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) {
@@ -525,9 +555,26 @@ bool UtilityProcessHost::StartProcess() {
@@ -525,9 +564,30 @@ bool UtilityProcessHost::StartProcess() {
}
#endif // BUILDFLAG(ENABLE_GPU_CHANNEL_MEDIA_CAPTURE) && !BUILDFLAG(IS_WIN)
@@ -269,11 +284,15 @@ index ab48c8b88a7cf311205b221169308d96e95f239f..d714d2022f685052e1def3b0d242d2ea
+#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 580fa663e729a43bef44a10de8983c4aecc312fb..f39af3df87786a472f987309ac0dea699b9f0d9f 100644
index 580fa663e729a43bef44a10de8983c4aecc312fb..c339f2b8504beee6ed2e5746a8e6b961a7aa9746 100644
--- a/content/browser/service_host/utility_process_host.h
+++ b/content/browser/service_host/utility_process_host.h
@@ -31,6 +31,7 @@
@@ -284,7 +303,7 @@ index 580fa663e729a43bef44a10de8983c4aecc312fb..f39af3df87786a472f987309ac0dea69
#endif // BUILDFLAG(IS_WIN)
namespace base {
@@ -134,14 +135,31 @@ class CONTENT_EXPORT UtilityProcessHost final
@@ -134,14 +135,36 @@ class CONTENT_EXPORT UtilityProcessHost final
std::variant<base::FilePath, base::ScopedFD> file);
#endif
@@ -315,11 +334,16 @@ index 580fa663e729a43bef44a10de8983c4aecc312fb..f39af3df87786a472f987309ac0dea69
+ // 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
@@ -185,6 +203,27 @@ class CONTENT_EXPORT UtilityProcessHost final
@@ -185,6 +208,32 @@ class CONTENT_EXPORT UtilityProcessHost final
std::optional<raw_ptr<ZygoteCommunication>> zygote_for_testing_;
#endif // BUILDFLAG(USE_ZYGOTE)
@@ -343,12 +367,17 @@ index 580fa663e729a43bef44a10de8983c4aecc312fb..f39af3df87786a472f987309ac0dea69
+ // 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 8f89c28144e1ecf3d7dbf9a3b43031cbad12a8ea..faa49bb63bd2e9080da441286bdbf427f22cd26f 100644
index 8f89c28144e1ecf3d7dbf9a3b43031cbad12a8ea..0c6e724f8ad0926076274f696b77b17b77f2aaa9 100644
--- a/content/browser/service_host/utility_sandbox_delegate.cc
+++ b/content/browser/service_host/utility_sandbox_delegate.cc
@@ -43,17 +43,19 @@ UtilitySandboxedProcessLauncherDelegate::
@@ -406,8 +435,24 @@ index 8f89c28144e1ecf3d7dbf9a3b43031cbad12a8ea..faa49bb63bd2e9080da441286bdbf427
#if BUILDFLAG(USE_ZYGOTE)
ZygoteCommunication* UtilitySandboxedProcessLauncherDelegate::GetZygote() {
@@ -203,6 +222,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

@@ -312,7 +312,7 @@ index 7e3d46902fbf736b4240eb3fcb89975a7b222197..57fdc89fc265ad70cb0bff8443cc1026
auto DrawAsSinglePath = [&]() {
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index a25e99fac5f5a171becff833464cdb3dfe7522c2..123a7c1fc980b1b3bcbe0e3e00afa594632d720b 100644
index 2e464ef7bbfd7e0d84df348d012e8020d4758726..b59eceacbd4143ef183bb67c39f9ccccc7582adb 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -214,6 +214,10 @@

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 d714d2022f685052e1def3b0d242d2ea596d790b..fb4cee1416836c4d0b807a862507a52347f24dd2 100644
index 54883f202c1769227c823d46454173b53692a7dd..b2a2f64435f566c67531bac9d0782215739d8fe6 100644
--- a/content/browser/service_host/utility_process_host.cc
+++ b/content/browser/service_host/utility_process_host.cc
@@ -629,7 +629,7 @@ void UtilityProcessHost::OnProcessCrashed(int exit_code) {
@@ -642,7 +642,7 @@ void UtilityProcessHost::OnProcessCrashed(int exit_code) {
: Client::CrashType::kPreIpcInitialization;
}
#endif // BUILDFLAG(IS_WIN)
@@ -97,7 +97,7 @@ index d714d2022f685052e1def3b0d242d2ea596d790b..fb4cee1416836c4d0b807a862507a523
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 f39af3df87786a472f987309ac0dea699b9f0d9f..6f470d19fa5fa0bd4d2bdb1be4aa0cb3a70d3936 100644
index c339f2b8504beee6ed2e5746a8e6b961a7aa9746..e75b67e08755c90670d44b1e06a685aa2b35539d 100644
--- a/content/browser/service_host/utility_process_host.h
+++ b/content/browser/service_host/utility_process_host.h
@@ -88,7 +88,7 @@ class CONTENT_EXPORT UtilityProcessHost final

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