Compare commits

...

109 Commits

Author SHA1 Message Date
Samuel Attard
01416243d2 build: replace spec dep fork with patch 2026-04-27 23:17:01 -05:00
Charles Kerr
de8fddcacd chore: fix linter error in spec/fixtures/crash-cases/content-tracing-before-ready/ (#51356)
chore: fix linter error in spec/fixtures/crash-cases/content-tracing-before-ready/

introduced earlier today in 6f2e5cd4
2026-04-27 21:49:16 -05:00
electron-roller[bot]
76c5257fea chore: bump chromium to 149.0.7811.0 (main) (#51300)
* chore: bump chromium in DEPS to 149.0.7809.0

* chore: bump chromium in DEPS to 149.0.7810.2

* chore: bump chromium in DEPS to 149.0.7811.0

* chore: revert [OSCrypt] Remove sync backend

Electron still depends on the synchronous os_crypt API.
Revert upstream CL 7765593 until migration to async is complete.

Followup: https://github.com/electron/electron/issues/51301
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7765593

Co-Authored-By: GitHub Copilot (Claude Opus 4.6)

* fix(patch): UAF fix in OnMouseRange

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7780978

Co-Authored-By: GitHub Copilot (Claude Opus 4.6)

* fix(patch): kGlicTrustFirstOnboarding references removed

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7773143

Co-Authored-By: GitHub Copilot (Claude Opus 4.6)

* chore: update patches (trivial only)

* fix(patch): SubtlePassKey and profile methods updates

Re-add OSCryptImpl as a friend of crypto::SubtlePassKey (removed by
https://chromium-review.googlesource.com/c/chromium/src/+/7759877)
since Electron still uses the sync backend.

Followup: https://github.com/electron/electron/issues/51301

Co-Authored-By: GitHub Copilot (Claude Opus 4.6)

* fix(patch): exclude upstream scripting API

CL 7784831 moved the Scripting API from //chrome to //extensions,
which caused duplicate symbols with Electron's own implementation.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7784831

Co-Authored-By: GitHub Copilot (Claude Opus 4.6)

* 7748618: [extensions] Move MimeHandlerStreamManager

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7748618

Co-Authored-By: GitHub Copilot (Claude Opus 4.6)

* 7713176: Move GetURLLoaderFactory from Profile to BrowserContext

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7713176

Co-Authored-By: GitHub Copilot (Claude Opus 4.6)

* 7755340: Refactor CaptureHandle storage to PageImpl

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7755340

Co-Authored-By: GitHub Copilot (Claude Opus 4.6)

* 7765593: [OSCrypt] Remove sync backend

No replacement code is needed: Electron already uses the async path.
CookieEncryptionProviderImpl (backed by OSCryptAsync) supplies
encryption to the network service via the cookie_encryption_provider
NetworkContext param, making SetEncryptionKey redundant.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7765593

Co-Authored-By: GitHub Copilot (Claude Opus 4.6)

* chore: stop disabling enterprise_cloud_content_analysis

CL 7757742 moved cloud_content_scanning from unconditional deps into
a conditional block gated on enterprise_cloud_content_analysis,
safe_browsing_mode, or is_android. Since Electron sets
safe_browsing_mode = 1, the dep is still included regardless, but
explicitly overriding enterprise_cloud_content_analysis to false now
causes other targets (e.g. chrome/browser/download) to omit enterprise
connectors code that the rest of the build expects to find.

It is simpler to let it default to true than to patch around it.
Electron does not use this feature — our PerformContentAnalysisIfNeeded
is a no-op passthrough that skips straight to NotifyListenerAndEnd.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7757742

Co-Authored-By: GitHub Copilot (Claude Opus 4.6)

* chore: update patches (trivial only)

* chore: update filenames.libcxx.gni

* chore: add GPU libraries to chromedriver zip manifests

Chromedriver now has transitive runtime dependencies on libEGL,
libGLESv2, and vk_swiftshader on macOS and Windows. These are
transitive deps pulled through chromedriver_server's dependency
on //mojo/core/embedder and //net.

* fix: add MicrotasksScope for worker exit emit in ContextWillDestroy

a39108c5a4 (#47244) replaced gin_helper::EmitEvent with a direct
`v8::Function::Call()` in `WebWorkerObserver::ContextWillDestroy`
to avoid re-entering the microtask checkpoint during worker teardown.

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

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

* chore: override CreateChromeMetadataPacketRecorder in tracing delegate

https://chromium-review.googlesource.com/c/chromium/src/+/7770189
product-version, os-name, and channel metadata from the legacy
ChromeEventBundle path to a new ChromeMetadataPacket recorder callback.
Override the new TracingDelegate virtual so Electron still emits these fields.

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2026-04-27 19:41:19 -05:00
Kunal Dubey
d6888df13b fix: honor webContents.print dpi horizontal/vertical options (#51046)
* fix: honor webContents.print dpi horizontal/vertical options

* style: fix clang-format in print dpi parsing

* style: extract print dpi key constants

* fix: use local dpi constants in print options parser
2026-04-27 16:46:46 -04:00
Om Ghante
6f2e5cd426 fix: prevent crash when calling contentTracing APIs before app is ready (#50920)
Added Browser::Get()->is_ready() guards to all contentTracing API functions (startRecording, stopRecording, getCategories, getTraceBufferUsage) so they reject their returned Promises with a clear error message instead of crashing when called before app.whenReady().

Added a crash-case fixture test that validates all four APIs reject properly before readiness and work normally after.
2026-04-27 16:44:37 -04:00
Charles Kerr
126a422cfa perf: use GIO for Browser::IsDefaultProtocolClient() on Linux (#51316)
* perf: use GIO for Browser::IsDefaultProtocolClient() on Linux

perf: use GIO for Browser::SetAsDefaultProtocolClient() on Linux

Similar to 7d6227a, this speeds up app.isDefaultProtocolClient()
by using the GIO library instead of spawning a shell command to
get the info.

* feat: log errors if g_app_info_set_as_default_for_type() fails
2026-04-27 16:31:40 -04:00
Charles Kerr
170e07eee8 fix: remove early capturer_.reset() that causes nullptr deref on next refresh (#51329)
fix: remove early capturer_.reset() that causes null deref on next refresh

Another followup to dad4ab658a: remove the `capturer_.reset()` that
`desktop_media_list.patch` was adding `Worker::RefreshNextThumbnail()`.
Since we switched from the one-shot Update() model to the continuous
StartUpdating() model, resetting `capturer_` isn't necessary and is
now dangerous: ScheduleNextRefresh() posts a delayed Worker::Refresh()
that dereferences capturer_, causing a nullptr crash.

Under CI load, the NativeDesktopMediaList can survive long enough
for the next 1-second refresh cycle to fire before FinalizeList()
destroys it. The crash can manifest as either a SIGSEGV or a
DCHECK(can_refresh()) failure, which is extra fun because dad4ab658a
was fixing a similar DCHECK crash in the first place.

Sample crash:

```
[6690:0426/173732.876803:FATAL:chrome/browser/media/webrtc/native_desktop_media_list.cc:934] DCHECK failed: can_refresh().0x00000001337aa7f3 NativeDesktopMediaList::RefreshForVizFrameSinkWindows(...) + 131
```
2026-04-27 16:30:03 -04:00
Charles Kerr
6c49cb3b27 fix: add MicrotasksScope for worker exit emit in ContextWillDestroy (#51326)
a39108c5a4 (#47244) replaced gin_helper::EmitEvent with a direct
`v8::Function::Call()` in `WebWorkerObserver::ContextWillDestroy`
to avoid re-entering the microtask checkpoint during worker teardown.

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

This PR copies a39108c5a4's changes in `ShareEnvironmentWithContext()`:
it explicitly adds a `kDoNotRunMicrotasks` scope.
2026-04-27 16:18:09 -04:00
John Kleinschmidt
002249c0ed ci: Revert "build: use 32-core Windows ARC runners for build jobs (#51256)" (#51341)
* Revert "build: use 32-core Windows ARC runners for build jobs (#51256)"

This reverts commit 099c5c0038.

* chore: put back siso patch

* Revert "fix: route ThinLTO cache through junction outside bindflt mount (#51328)"

This reverts commit 9e7a343f39.

* Revert "fix: pre-create thinlto-cache dir on Windows to avoid bindflt race (#51292)"

This reverts commit 98e91ca555.
2026-04-27 15:04:20 -04:00
Noah Gregory
411e3be571 fix: make macOS text replacement work on contenteditable (#51289)
* fix: make macOS text replacement work on `contenteditable`

* fix: remove accidentally included patch line
2026-04-27 11:09:47 -05:00
Keeley Hammond
9e7a343f39 fix: route ThinLTO cache through junction outside bindflt mount (#51328)
Pre-creating out\Default\thinlto-cache dodged the CreateDirectoryW
race on bindflt-mounted ARC runners but left CreateFileW for the
cache files inside still racy. Latest symptom (publish-x86-win on
the v43.0.0-nightly.20260425 re-run):

  lld-link: error: Failed to open cache file
  thinlto-cache\llvmcache-...: invalid argument

That is the same ERROR_INVALID_PARAMETER bindflt returns under the
concurrent ThinLTO write load, just on a different file op.

Replace the pre-created directory with a junction at
out\Default\thinlto-cache pointing to $env:TEMP\electron-thinlto-cache
on the underlying volume. The reparse point is resolved in the I/O
manager before bindflt sees per-file operations, so cache reads and
writes bypass the filter driver entirely.

Idempotent for re-runs: detects an existing junction (without
following it via Remove-Item) and a leftover real directory from
older builds.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:06:29 -04:00
Mitchell Cohen
ccaab437cc fix: remove insets on fullscreen windows on Windows (#51287) 2026-04-26 16:32:37 -05:00
Shelley Vohr
849485dc33 fix: dispatch toast action and reply events from WinRT activation path (#51286)
* fix: dispatch toast action and reply events from WinRT activation path

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

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

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

* fix: release HSTRING out-params from toast activation
2026-04-26 15:31:38 -05:00
Charles Kerr
ded39eecc7 test: fix race in reentrant loadURL() ready-to-commit test (#51315)
test: fix race in reentrant loadURL() ready-to-commit test

Fix 'fails if loadurl is called after the navigation is ready to commit'
by using a done() callback to ensure the test waits for did-fail-load
before exiting.

Previously, the test would return and call afterEach(closeAllWindows),
potentially destroying the window while navigation was in flight.
2026-04-26 09:40:04 -05:00
Charles Kerr
5af1a06082 fix: crash in AutofillPopup teardown (#51302)
Fix a crash in AutofillPopupView::Show() when the popup
tried to show itself after the parent's native view had
already gone away during teardown.

2026-04-23T20:44:32.7015810Z Received signal 11 SEGV_ACCERR 000000000160
2026-04-23T20:44:32.9322010Z 4   Electron Framework  ... views::Widget::IsVisible() const + 28
2026-04-23T20:44:32.9528810Z 6   Electron Framework  ... electron::AutofillPopupView::Show() + 200
2026-04-23T20:44:32.9632090Z 7   Electron Framework  ... electron::AutofillPopup::CreateView(...) + 1380
2026-04-23T20:44:32.9749770Z 8   Electron Framework  ... electron::AutofillDriver::ShowAutofillPopup(...) + 736
2026-04-23T20:44:33.0015220Z ✗ Electron tests failed with kill signal SIGSEGV.
2026-04-25 21:59:21 -05:00
Samuel Attard
e52001b0c8 ci: run siso build as part of Apply Patches workflow (#51304)
* ci: run siso build as part of Apply Patches workflow

This adds a build-siso job that runs when DEPS or .github/siso-patches
change, so siso patch issues are detected before chromium rolls land.

https://claude.ai/code/session_01TggMjnXwKFFtuLQAsrGfA3

* ci: trigger rerun-apply-patches on siso-patches changes

https://claude.ai/code/session_01TggMjnXwKFFtuLQAsrGfA3

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-25 13:23:22 -07:00
Samuel Attard
44f030f039 fix: track Node.js and V8 header sources for build invalidation (#51225)
* fix: add inputs to node_headers target for proper invalidation

The `generate_node_headers` action had no `inputs` declared, so Ninja
would not rebuild when node or V8 header files changed. This caused
stale headers to remain in gen/node_headers after a Node.js bump,
leading to build failures with errors in files like target_agent.h.

Add inputs including the install.py script (which determines which
headers to copy), key Node.js headers, inspector headers, and V8
version headers. Changes to any of these will now trigger regeneration.

https://claude.ai/code/session_018qZ1FBZCEkmDC1sRvPQnqp

* refactor: drive node_headers inputs from filenames.auto.gni

Wire the `generate_node_headers` action's inputs through the existing
auto_filenames mechanism so there is a single source of truth for which
files should invalidate the generated node_headers directory.

`script/gen-filenames.ts` now enumerates node and v8 header files via
filesystem scan and records them under `auto_filenames.node_header_sources`
in filenames.auto.gni, alongside install.py (which drives which headers
get copied). BUILD.gn consumes the list directly as the action's `inputs`
parameter.

The list will repopulate fully the next time `ts-node script/gen-filenames.ts`
runs (via lint-staged on any JS/TS commit), the same way webpack bundle
deps are refreshed today.

https://claude.ai/code/session_018qZ1FBZCEkmDC1sRvPQnqp

* chore: update filenames

* fmt

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-25 18:03:36 +00:00
Robo
f6a99d04a4 ci: route rustc linker invocations through abs_link_wrapper (#51313)
* ci: route rustc linker invocations through abs_link_wrapper

* fix: abs path to generated cmd file

* fix: remove extra quotes around args
2026-04-25 11:34:05 -05:00
Robo
37a81876de ci: test with absolute paths for lld-link on windows (#51311)
* ci: test with absolute paths for lld-link on windows

* fix: exclude system libs

* fix: skip abs wrapper for thin archive step
2026-04-25 00:17:35 +00:00
Keeley Hammond
98e91ca555 fix: pre-create thinlto-cache dir on Windows to avoid bindflt race (#51292)
* fix: pre-create thinlto-cache dir on Windows to avoid bindflt race

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>

* fix: discover ThinLTO cache path from GN instead of hardcoding

Addresses review feedback from @deepak1556: the hardcoded
`out\Default\thinlto-cache` path goes out of sync if upstream
changes `cache_dir` in Chromium's build/config/compiler/BUILD.gn.

Read the `/lldltocache:` flag from `gn desc` on a linked target
(`//electron:electron_app`) and pre-create whatever path GN
actually configured. Skips the pre-create entirely when ThinLTO
is disabled (non-official builds), which is the correct no-op.

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

* fix: run gn gen before discovering ThinLTO cache path

Previous attempt failed on Windows CI for two reasons:

1. `e init` does not run `gn gen` — out/Default is still unpopulated
   when the build step starts, so `gn desc` had nothing to introspect.
2. `e` writes informational lines to stderr (e.g. "INFO Auto-updates
   disabled"), which GitHub Actions' default $ErrorActionPreference =
   'Stop' turned into a terminating NativeCommandError before e build
   could run.

Run `gn gen` explicitly here so `gn desc` can report the effective
`/lldltocache:` path, and shell each `e` invocation through cmd.exe
so its informational stderr stays out of PowerShell's error stream.
`e build` re-uses the same generated build dir so gn gen is paid
once.

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

* fix: revert to hardcoded thinlto-cache path, document the coupling

Dynamic discovery via `gn desc` required `gn gen` to run beforehand,
and `gn gen` can't run before `e build` on Windows CI — gn.exe isn't
installed in `src/third_party/gn/` or `src/buildtools/win/gn/` until
a Chromium gclient hook that the current CI workflow doesn't trigger.
`e build` works because the restored src cache lets it skip the gen
step; any attempt to force `gn gen` earlier fails with exit 2.

Go back to pre-creating the path the upstream default currently
resolves to, and leave a comment explaining the coupling so a future
upstream relocation fails loudly (via the original LLVM error) rather
than silently.

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

---------

Co-authored-by: Claude <svc-devxp-claude@slack-corp.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 08:50:17 -05:00
Robo
0960ddc688 ci: limit the lld concurreny on windows runners (#51310) 2026-04-24 17:18:10 +09:00
Noah Gregory
9f25fc4e06 docs: fix @electron/osx-sign package name (#51254) 2026-04-23 22:32:30 -04:00
David Sanders
e04ee76c7f build: add more checks to Chromium roll message linting (#51291) 2026-04-23 22:30:16 -04:00
Samuel Attard
bd14ed60e0 build: rebase siso patches onto siso 7bcc56206d23 (#51303)
The Chromium 149.0.7798.0 roll bumped the pinned siso revision, and
upstream added a `path/filepath` import to file_parser.go. That broke
the import-block context for the 0002 ERROR_INVALID_PARAMETER retry
patch, so `git am --3way` could no longer build a fake ancestor and the
build-siso-windows job started failing at the apply step.

Re-export both patches against the new siso SHA. No functional change to
the patched code; only line offsets, index hashes and the import context
move.
2026-04-23 19:15:12 -07:00
Keeley Hammond
56ac67bf48 build: restrict npm tarball contents to an explicit allowlist (#51293)
* build: restrict npm tarball contents to an explicit allowlist

The npm publish flow runs `npm pack` in a staging temp dir, but
`npm/package.json` had no `files` field — so any file that happened
to land in that dir was packed into the published tarball.

Recent releases (41.2.1+, 40.9.1+, 39.8.8+) shipped a self-referential
`.npm-cache/_logs/*-debug-0.log` (npm's own debug log, written into
the pack dir before pack finishes reading files) and a stray copy of
`SHASUMS256.txt` that duplicates the info already in `checksums.json`.

Add an explicit `files` allowlist so only the intended contents are
packaged, regardless of staging-dir contamination. `package.json`,
`README.md`, and `LICENSE` are auto-included by npm.

Fixes #51290.

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

* build: include LICENSE and README.md in files allowlist

These are auto-included by npm regardless, but listing them makes the
intended contents of the tarball self-documenting alongside the other
entries.

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 19:14:08 -07:00
Charles Kerr
746b1b2579 chore: temporarily disable new flaky test (#51295) 2026-04-23 17:56:37 -05:00
electron-roller[bot]
b93642678c chore: bump chromium to 149.0.7798.0 (main) (#50814)
* chore: bump chromium in DEPS to 149.0.7779.0

* chore: bump chromium in DEPS to 149.0.7781.0

* 7726883: Add secondary label support to SimpleMenuModel and update views_examples

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7726883

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>

* chore: update patches (trivial only)

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>

* fix: IWYU for base/logging.h

Upstream is removing transitive includes of base/logging.h as part of
crbug.com/499476145. Several CLs landed in this roll that required
adding explicit includes across Electron source and patches.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7732103
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7735571

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

* 7732482: [bedrock] Create BrowserProcess setters for system tray icons

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7732482

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>

* chore: update patches (trivial only)

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>

* 7739543: Add RenderWidgetHostView::HasSavedFrame

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7739543

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>

* chore: bump chromium in DEPS to 149.0.7783.0

* chore: bump chromium in DEPS to 149.0.7789.0

* chore: update patches (trivial only)

* 7703728: DedicatedWorker: Enforce same-origin check for main script fetch.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7703728

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

* 7720140: Remove GetPrefServiceForContext from ExtensionsBrowserClient

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7720140

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

* chore: update patches (trivial only)

* 7728375: Disable reentrancy by default except for Android and iOS

Upstream changed the default ObserverList reentrancy policy from
kAllowReentrancy to kDisallowReentrancy. Electron's observer lists
are re-entered when macOS AppKit delivers synchronous window
notifications (e.g. windowDidResignMain: during windowDidChangeOcclusionState:)
because JS event handlers can trigger window state changes mid-iteration.

Explicitly opt into kAllowReentrancy for now. A follow-up should
convert synchronous Emit calls in window observer callbacks to
EmitEventSoon to eliminate the reentrancy.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7728375

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

* chore: bump chromium in DEPS to 149.0.7791.1

* chore: update patches (trivial only)

* 7696481: [pdf] Rename PdfViewerStreamManager to MimeHandlerStreamManager

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7696481

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

* 7745796: Printing: Remove parameter from ShowScriptedPrintPreview() interface

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7745796

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

* 7688714: [Lens / Cookies] Grant secure cookie exemptions for Lens side panel

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7688714

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

* 7752609: don't show glic button for non-normal BWIs.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7752609

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

* 7749860: [media] Remove VideoFrame::WrapSharedImage with coded_size

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7749860

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

* chore: bump chromium in DEPS to 149.0.7793.0

* chore: bump chromium in DEPS to 149.0.7795.0

* chore: bump chromium in DEPS to 149.0.7797.0

* chore: update patches

* chore: remove upstreamed patches

- fix_pass_trigger_for_global_shortcuts_on_wayland.patch: https://chromium-review.googlesource.com/c/chromium/src/+/7620219
- gin_mark_argumentholder_as_cppgc_stack_allocated.patch: https://chromium-review.googlesource.com/c/chromium/src/+/7728865

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

* chore: bump chromium in DEPS to 149.0.7798.0

* chore: update filenames.libcxx.gni

* 7760061: Reland Reland Add a client-side decorated frame view for non-browser widgets on Linux

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7760061

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

* 7760945: Rename WebString::UTF8ConversionMode to Utf8ConversionMode

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7760945

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

* chore: update patches

* chore: remove upstreamed patches

- patches/devtools_frontend/fix_context_selector_not_showing_execution_contexts.patch: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/7761316

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

* 7719004: [extensions] Gate dict-format mime_types_handler parsing

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7719004

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

* 7716681: [pdf] Introduce MimeHandlerStreamDelegate and plumb ownership

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7716681

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

* 7725342: Rename WebString::FromUTF8 to FromUtf8 in Blink

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7725342

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

* 7615475: Add a native frame view for non-browser widgets on Linux

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7615475

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

* 7735248: Move ManifestV2ExperimentManager to //extensions

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7735248

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

* 7725187: linux: set env FC_FONTATIONS and EGL_PLATFORM early

Move Ozone pre-init from ElectronBrowserMainParts::PreEarlyInitialization()
to ElectronMainDelegate::PreSandboxStartup() to match upstream's rename
and relocation. The call has to run before threads are created.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7725187

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

* 7743280: Introduce client ID for network throttling conditions.

Ref: https://chromium-review.googlesource.com/c/chromium/src/+/7743280

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

* chore: disable ml-kem node test incompatible with BoringSSL

test-crypto-pqc-key-objects-ml-kem: BoringSSL's ML-KEM support is
inconsistent with the test's OpenSSL-version-based assumptions.

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

* test: update V8 serialization wire format version to 16

V8 14.9 (Chromium 149) bumped the serialization wire format from
version 15 to 16. Update the hardcoded expected bytes in the
test-v8-serdes.js test.

Remove this patch once upstream Node.js catches up via its next
V8 roll.

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

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Samuel Maddock <samuelmaddock@electronjs.org>
Co-authored-by: Claude <svc-devxp-claude@slack-corp.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: clavin <clavin@electronjs.org>
2026-04-23 16:32:10 -05:00
Charles Kerr
7d6227ad86 perf: use GIO instead of xdg-mime for app.getApplicationNameForProtocol() (#51251)
perf: use GIO instead of xdg-mime for app.getApplicationNameForProtocol()

The Linux impl of app.getApplicationNameForProtocol() now uses
`g_app_info_get_default_for_uri_scheme()` + `g_app_info_get_display_name()`
instead of spawning a call to the `xdg-mime` shell command.

Clean up the related tests: remove the xdg-mime mock.
2026-04-23 15:09:43 -05:00
Niklas Wenzel
f99a3980e5 fix: heap profiling test flakes (#51224) 2026-04-23 14:47:32 -05:00
Mitchell Cohen
38cfc66c6f fix: ensure stable bounds on Windows when toggling setResizable for frameless windows (#51252) 2026-04-23 14:47:00 -05:00
Samuel Attard
099c5c0038 build: use 32-core Windows ARC runners for build jobs (#51256)
* build: use 32-core Windows ARC runners for build jobs

* ci: add siso patch to retry ERROR_INVALID_PARAMETER on ninja file open

The existing patch removes the redundant per-chunk re-open in
fileParser.readFile, but the single remaining os.Open per subninja can
still hit the bindflt race under the ~90k-file concurrent open burst on
the 32-core Windows runners. Layer a second patch on top that wraps that
open in a Windows-only 5-attempt retry (5-80ms backoff) so a single
transient failure no longer aborts the whole manifest load.
2026-04-23 02:23:32 -07:00
Charles Kerr
2c46abe361 test: add linux coverage for default protocol client APIs (#51253)
Add Linux-only app tests to check the default protocol handler.
This includes adding reusable XDG mock fixtures.
2026-04-23 10:10:08 +02:00
David Sanders
05e0cd085c build: drop script/run-gn-format.py (#51263) 2026-04-23 09:52:36 +02:00
Asish Kumar
7c56577639 fix: preserve return value in deprecate.removeFunction (#51028)
The wrapper returned by `deprecate.removeFunction` dropped the wrapped
function's return value because it did not `return` from `fn.apply`.
Every other function wrapper in this module (`renameFunction`,
`moveAPI`) forwards the return value, and the generic type signature
`<T extends Function>(fn: T, ...): T` promises that `T`'s return type
is preserved. Callers that relied on the return value of a function
wrapped by `removeFunction` would silently receive `undefined` from
the wrapper.

Mirror the forwarding done by `renameFunction` / `moveAPI` and extend
the existing spec to assert that the wrapper preserves both the return
value and the `this` context of the deprecated function.

Assisted-By: Claude Opus 4.6

Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
2026-04-23 00:05:30 +00:00
Robo
350de668e2 refactor: api::autoUpdater managed by cppgc (#51241) 2026-04-23 05:38:47 +09:00
Robo
111b6275ee build: track PDL files as inputs in inspector GN build (#51239)
* fix: track PDL files as inputs in inspector GN build

* chore: address review feedback
2026-04-22 13:48:44 +00:00
Charles Kerr
54eb30a642 chore: remove calls to DeprecatedLayoutImmediately (#51183)
* chore: remove calls to DeprecatedLayoutImmediately

Replace the calls to `DeprecatedLayoutImmediately` that have test
coverage.

- The docked DevTools test added last week covers the three calls in IWCV.

- api-web-contents-view-spec covers the calls from NativeWindow{Views,Mac}.

There are a couple of remaining calls that don't have test coverage yet.
I'll get to them in a followup.

* test: handle both sync or microtask layout

* refactor: add a FlushPendingRootLayout() helper
2026-04-22 12:34:07 +02:00
Charles Kerr
71e8a5ca80 build: FTBFS when pdf is disabled (#51223)
fix: FTBFS when pdf is disabled

pdf_features.h has a static_assert that pdf is enabled
2026-04-22 12:33:59 +02:00
Shelley Vohr
c74de25b01 fix: ignore draggable regions in hidden WebContentsView (#51200)
fix: ignore draggable regions in hidden WebContentsView

Hidden child WebContentsViews were still contributing their draggable
regions to the parent window's non-client hit test, so clicks in the
area where a hidden view's draggable element would render still dragged
the window. Early-return HTNOWHERE when the view is not visible.
2026-04-22 12:33:41 +02:00
Samuel Attard
44e4839580 build: update @electron/get to v5 (#51234) 2026-04-21 19:54:24 -07:00
Samuel Attard
fac0a1624b build: use Yarn JsZipImpl for node-modules link to fix arm32 OOM (#51226)
* build: use Yarn JsZipImpl for node-modules link step

Patch the vendored .yarn/releases/yarn-4.12.0.cjs so the node-modules
(and pnpm-loose) linker constructs its read-only ZipOpenFS with
customZipImplementation = JsZipImpl instead of the default WASM
LibZipImpl.

LibZipImpl loads each cache zip fully into the Emscripten WASM heap and
malloc's a WASM buffer per file read. With up to 80 zips held open, the
32-bit arm32v7 test container intermittently fails to allocate the ~9 MB
buffer for typescript/lib/typescript.js. Yarn's cross-FS copyFilePromise
swallows the real error and surfaces it as a generic
"EINVAL: invalid argument, copyfile", which has been failing ~1-in-3
linux-arm test shards at Install Dependencies since 2026-04-13.

JsZipImpl opens zips by fd, reads only the central directory, and pulls
individual entries into plain Node Buffers — no WASM heap involved.
There is no .yarnrc.yml or env knob for this, so the vendored release is
edited directly. .claude/README.md documents the patch and how to
re-apply it on Yarn upgrades.

Refs: yarnpkg/berry#3972, yarnpkg/berry#6722, yarnpkg/berry#6550

* docs: move JsZipImpl patch notes to .yarn/README.md

Relocate the patch rationale next to the vendored release it documents,
reword the intro for its new home, and update the header comment in
yarn-4.12.0.cjs to point at .yarn/README.md.
2026-04-21 17:58:46 -07:00
Robo
23d95ea9f8 refactor: api::cookies managed by cppgc (#51196)
* refactor: api::cookies managed by cppgc

* chore: remove unused header
2026-04-22 05:28:31 +09:00
Shelley Vohr
89050762c6 fix: reset printToPDF queue after a rejection (#51174)
fix: reset printToPDF queue after a rejection

The module-scoped `pendingPromise` in `webContents.printToPDF` was chained
with `.then(onFulfilled)` and never cleared. Once a call rejected (e.g.
an out-of-range `pageRanges` like `"999"`), subsequent calls chained onto
the rejected promise and short-circuited without ever invoking
`_printToPDF` — so every following call re-surfaced the original error.

Replace the shared variable with a per-`WebContents` `WeakMap` queue that
swallows prior rejections before chaining and clears its entry once the
tail drains.
2026-04-21 11:36:02 -07:00
Niklas Wenzel
b8be33814e fix: skip heap profiling tests in CI (#51209) 2026-04-21 18:26:14 +00:00
Mr.Chaofan
76a03e1010 feat: Add WebContents::Clone method (#49959) 2026-04-21 10:37:48 -07:00
Shelley Vohr
2ba6d28c09 fix: preserve transparency across setResizable toggles on Windows (#51175)
After #49428 made `NativeWindowViews::CanResize()` return `resizable_`
for frameless windows (instead of `resizable_ && thick_frame_`),
`HWNDMessageHandler::SizeConstraintsChanged()` started adding
`WS_THICKFRAME` to the window style whenever `CanResize()` reported true.
`WS_THICKFRAME` is incompatible with layered (translucent) windows and
destroys their transparency.

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

Apply the same guard in `SetResizable`. Min/max constraints are still
enforced — Chromium reads them from the widget delegate on every
`WM_GETMINMAXINFO`, independent of `SizeConstraintsChanged()`.
2026-04-21 10:32:29 -07:00
Charles Kerr
5ed6e4bf62 test: add Linux-specific test for app.getApplicationNameForProtocol() (#51197)
* test: add Linux-specific test for getApplicationNameForProtocol()

On Linux, use XDG env vars to inject a mock that we can use
to test app.getApplicationNameForProtocol().

* fixup! test: add Linux-specific test for getApplicationNameForProtocol()

better system mocks
2026-04-21 10:16:14 -07:00
Charles Kerr
4d780c67f9 test: improve browser window layout coverage (#51189)
* test: browser window webContents viewport matches content bounds

* test: browser window webContents same after vibrancy change

* fixup! test: browser window webContents viewport matches content bounds

* refactor: extract-method helper getViewportSize()

* refactor: remove non-spec change

* chore: more accurate naming
2026-04-21 10:06:49 -07:00
Keeley Hammond
313f8955d1 fix: trigger ShipIt Mach service after SMJobSubmit to unblock on-demand-only mode (#51191)
* fix: trigger ShipIt Mach service to unblock on-demand-only mode

When a macOS system update is pending, launchd puts the user domain
into on-demand-only mode, preventing ShipIt from starting. The
MachServices endpoint in the job dictionary was registered but never
connected to (a leftover from the XPC removal in 2013).

Instead of removing MachServices, fire a lightweight XPC connection
to the Mach port after SMJobSubmit. This satisfies launchd's
on-demand trigger, starting ShipIt immediately while preserving
KeepAlive retry behavior.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>

* fix: add ResetAtClose to ShipIt MachServices to prevent standing demand

The XPC trigger message sent after SMJobSubmit sits in the Mach port's
kernel queue unread. Without ResetAtClose, this creates standing demand
that causes launchd to respawn ShipIt after a successful exit(0),
defeating KeepAlive.SuccessfulExit = NO.

Set ResetAtClose on the MachServices registration so launchd tears down
and recreates the port when ShipIt exits, flushing the stale trigger.

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>

* fix: drain Mach port before exit(0) instead of using ResetAtClose

ResetAtClose blocks KeepAlive.SuccessfulExit retries in on-demand-only
mode because it removes demand when the port resets. Instead, have
ShipIt drain its own Mach service port (via bootstrap_check_in +
mach_msg) before each exit(EXIT_SUCCESS). This clears the standing
demand from the trigger message so launchd won't respawn after a
successful exit, while leaving the message in place on failure exits
so KeepAlive retries remain demand-backed.

Tested in on-demand-only mode (pending macOS update):
- exit(0) + drain: 1 run, no respawn ✓
- exit(1) + no drain: continuous respawn every 2s ✓

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>

* chore: update patch

* chore: harden ShipIt Mach trigger and simplify port drain

Scope the XPC trigger to the unprivileged path and add a send barrier
so the connection cannot be released before the message is on the wire.
Reduce drainMachServicePort to bootstrap_check_in (process exit flushes
the queue), dropping the mach_msg loop whose buffer/dealloc usage was
incorrect, and remove the no-op drain from the posix_spawn'd launch
helper. Patch filename regenerated to match the commit subject.

* fix: restore explicit mach_msg drain in drainMachServicePort

bootstrap_check_in alone does not prevent respawn: launchd tracks
outstanding demand independently of the receive right's lifetime, so the
queued trigger message must be explicitly dequeued with mach_msg before
exit(0). Verified empirically (check-in-only: 5 respawns in 10s; full
drain: 1 run). Keep the correctness fixes from the previous commit
(4K buffer, mach_msg_destroy on each receive, no mach_port_deallocate).

---------

Co-authored-by: Claude <svc-devxp-claude@slack-corp.com>
Co-authored-by: Samuel Attard <sattard@anthropic.com>
2026-04-21 09:46:18 -07:00
Robo
1ad6173286 fix: add crash diagnostics for ARM64 power notification crash (#51198)
On ARM64 Windows, UnregisterSuspendResumeNotification (user32) forwards
to PowerUnregisterSuspendResumeNotification (powrprof), which treats the
HPOWERNOTIFY handle as a pointer and dereferences it. The user32 API
returns an opaque handle, not a pointer-backed allocation, causing an
access violation at shutdown.

Add crash keys (pm-reg-handle, pm-reg-memstate, pm-unreg-memstate) to
capture
- The handle value
- VirtualQuery memory state at both registration and unregistration

If the handle address is MEM_FREE, it confirms the handle is an opaque
index and powrprof is incorrectly dereferencing it. If MEM_COMMIT, it
would indicate a use-after-free of the underlying allocation.

Refs https://github.com/MicrosoftDocs/sdk-api/blob/docs/sdk-api-src/content/powerbase/nf-powerbase-powerunregistersuspendresumenotification.md
2026-04-21 21:20:51 +09:00
dependabot[bot]
9861250310 build(deps): bump dsanders11/project-actions from 2.0.0 to 2.0.1 (#51195)
Bumps [dsanders11/project-actions](https://github.com/dsanders11/project-actions) from 2.0.0 to 2.0.1.
- [Release notes](https://github.com/dsanders11/project-actions/releases)
- [Commits](https://github.com/dsanders11/project-actions/compare/v2.0.0...4b06452b0128cf601dac14399aa668a8eed2d684)

---
updated-dependencies:
- dependency-name: dsanders11/project-actions
  dependency-version: 2.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-21 09:10:23 +00:00
David Sanders
0396220dce ci: don't upload build stats on Windows if build fails (#51199) 2026-04-21 09:05:25 +00:00
dependabot[bot]
a0c3be5656 build(deps): bump actions/setup-node from 6.3.0 to 6.4.0 (#51193)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6.3.0 to 6.4.0.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](53b83947a5...48b55a011b)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 6.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-21 10:46:09 +02:00
dependabot[bot]
b5c68d13d5 build(deps): bump github/codeql-action from 4.35.1 to 4.35.2 (#51194)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.1 to 4.35.2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](c10b8064de...95e58e9a2c)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.35.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-21 10:45:59 +02:00
Samuel Attard
f7ba34064e ci: centralize build-image SHA and pre-seed node-gyp headers (#51148)
* ci: centralize build-image SHA and pre-seed node-gyp headers

- Add .github/actions/build-image-sha as the single source of truth for
  the ghcr.io/electron/build (and arch-tagged electron/test) image SHA,
  with an optional override input for workflow_dispatch.
- Refactor build.yml, apply-patches.yml, build-git-cache.yml,
  clean-src-cache.yml, clean-orphaned-cache-uploads.yml, and the three
  publish workflows to resolve the SHA via a small ubuntu-slim setup job
  instead of hardcoding it in each file.
- Bump the image to daad061f (electron/build-images#68, which pre-warms
  the node-gyp header cache in the Linux images).
- Run the build.yml setup job on ubuntu-slim instead of ubuntu-latest.
- In install-dependencies (and the inline yarn installs in
  pipeline-electron-lint and generate-types), link deps with
  --mode=skip-build first, run `node-gyp install` with up to 3 retries
  (5s backoff) to populate the header cache, then run the build phase.
  This avoids the parallel-download race that intermittently fails the
  first native-addon configure with an empty common.gypi on cold
  macOS/Windows runners.

* ci: skip node-gyp header pre-seed on Linux

* ci: invoke node-gyp via its JS entrypoint for Windows compat
2026-04-20 15:44:10 -07:00
David Sanders
61e815c28a ci: run clang-tidy on macOS and Windows (#50771)
* ci: run clang-tidy on macOS and Windows

* ci: copy framework headers for clang-tidy on macOS

* chore: exclude electron_smooth_round_rect.cc in CI

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

* chore: add extra args on Windows to clear out warnings

* ci: fix for macOS --remote-build none
2026-04-20 13:31:22 -07:00
Asish Kumar
51c0b025d8 docs: remove obsolete websql from clearStorageData storages list (#51097)
WebSQL support was removed in Electron 31 (see breaking-changes.md), and
the 'websql' key was subsequently removed from the storages lookup in
session.ClearStorageData() during the Chromium 126 bump (#41868).

The documentation for `ses.clearStorageData()` was not updated at the
time and still lists `websql` as a valid value for the `storages`
option. Passing `websql` now silently has no effect, leaving the docs
out of sync with the implementation.

Remove `websql` from the documented list of storage types so the
documentation matches the actual behavior.

Refs: #33900

Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
2026-04-20 12:45:00 -07:00
David Franco
bc8ed1808c feat: import shared texture supports nv16 (#50728) 2026-04-20 12:39:13 -07:00
Shelley Vohr
db9bcbd3e4 chore: add Phase Three (node smoke tests) to Node.js upgrade skill (#51127)
Adds test suite workflow, BoringSSL incompatibility reference table,
snapshot regeneration instructions, and commit guidelines.
2026-04-20 12:38:13 -07:00
Samuel Attard
92f0993d94 fix: ensure corsEnabled: false protocol handlers do not work across protocols (#51152)
* fix: ensure corsEnabled: false protocol handlers do not work across protocols

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

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

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

* chore: oxfmt
2026-04-20 09:34:37 -07:00
Charles Kerr
bef68b6bb7 fix: dangling raw_ptr regression in DesktopCapturer (#51158)
fix: dangling raw_ptr in desktopCapturer
2026-04-20 10:26:43 -05:00
Erick Zhao
0866d39006 docs: update versioning references (#51030)
* docs: update versioning references

* fixups
2026-04-20 12:02:00 +02:00
Charles Kerr
2e17a57d49 test: increase test coverage for docked DevTools and attached WebContentsView (#51071)
* test: strengthen layout-sensitive coverage for docked DevTools and attached WebContentsView

Improve test coverage for layout-dependent behavior by asserting geometry results:

- Test that opening right-docked DevTools shrinks the inspected page
  viewport and that closing DevTools restores it.

- Test that a newly-attached WebContentsView becomes visible with a
  viewport that immediately matches the window’s content bounds.

* fixup! test: strengthen layout-sensitive coverage for docked DevTools and attached WebContentsView
2026-04-20 12:01:25 +02:00
electron-roller[bot]
0ab23201e7 chore: bump node to v24.15.0 (main) (#51091) 2026-04-20 11:52:38 +02:00
David Sanders
1bea748a45 ci: randomly assign stable prep tasks (#51131)
Assisted-by: Claude Opus 4.6
2026-04-20 11:52:11 +02:00
Samuel Attard
09361b6d7b build: update ANGLE repository URL to GitHub mirror (#51156)
Clone angle from github.com/google/angle in fix-sync action

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-20 11:51:39 +02:00
Samuel Attard
a98d19a3ba build: resolve electron_version from git when building in a worktree (#51146)
BUILD.gn previously hard-coded read_file(".git/packed-refs", ...) and
".git/HEAD" to derive electron_version. In a `git worktree` checkout
.git is a file containing a gitdir: pointer, not a directory, so GN's
read_file() fails and gn gen aborts unless override_electron_version is
set manually.

Ask git itself for the real locations via `git rev-parse --git-dir` /
`--git-common-dir` in a small helper script, and feed those resolved
paths to read_file() and the exec_script dependency list. Behaviour in
a plain clone is unchanged (both resolve to electron/.git/...), and the
tarball case still fails loudly with a pointer to
override_electron_version.
2026-04-20 00:54:14 -07:00
Niklas Wenzel
e2143f5e8e feat: support heap profiling in contentTracing (#50826)
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2026-04-20 15:01:13 +09:00
Charles Kerr
a1d28e6764 fix: do not block indefinitely on thumbnails in desktopCapturer (#51128)
* fix: do not block indefinitely on thumbnails in desktopCapturer

fixes dad4ab6 regression

* fix: build error

* fixup! fix: do not block indefinitely on thumbnails in desktopCapturer

chore: remove unnecessary code

* Update shell/browser/api/electron_api_desktop_capturer.cc

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

---------

Co-authored-by: Niklas Wenzel <dev@nikwen.de>
2026-04-19 13:48:38 -05:00
Charles Kerr
72a168f653 fix: linux test shutdown error "AttributeError: type object 'DBusTestCase' has no attribute 'stop_dbus'" (#51129)
stop_dbus() was removed on 2025-09-14 by
99c4800e9e

I think CI isn't seeing this yet because its image has an older version.

This patched script should work on old & new versions of python-dbusmock.
2026-04-18 17:30:53 -07:00
Niklas Wenzel
f6f71fa787 build: remove maintainer issue template (#51142) 2026-04-18 16:59:12 -07:00
Robo
9d77099a8c build: update rules for chrome-release-cls skill (#51140) 2026-04-18 07:43:22 +00:00
Samuel Attard
85be1a05e1 build: add chrome-release-verify and chrome-release-cls skills (#51138)
* build: add chrome-release-verify and chrome-release-cls skills

Adds two project skills under .claude/skills/ for security backports:

* chrome-release-cls — given a Chrome Releases blog post URL, extract
  every CVE/bug and locate the underlying Gerrit CL by searching the
  local Chromium checkout and sub-repos.
* chrome-release-verify — end-to-end backport flow for a release
  branch: maps CVEs→CLs, verifies which fixes are already in the synced
  source tree, writes the cherry-pick patches locally, validates with
  `e sync --3` + `lint --patches` (with the export→lint→re-apply loop),
  then opens a single PR with the linked-CL/crbug/CVE body format.

* ci: skip platform builds for .claude/** changes
2026-04-17 20:28:36 -07:00
Charles Kerr
2f749e24ed fix: intermittent CI failure is-not-alwaysOnTop (#51110)
* fix: intermittent CI failure is-not-alwaysOnTop

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

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

* test: keep eventually-becomes-consistent test but do not loop 1000 times
2026-04-17 19:03:16 -05:00
David Sanders
15ed78d807 build: don't use //third_party/depot_tools in lint.js (#51034)
* build: don't use //third_party/depot_tools in lint.js

* chore: also run python3 through depot tools
2026-04-17 12:20:27 +02:00
Keeley Hammond
2fbd11d978 feat: add Notification.getHistory() for macOS (#50325)
* feat: add `Notification.getHistory()` static method (macOS)

Add `Notification.getHistory()` which returns a `Promise<Notification[]>`
of all delivered notifications still present in Notification Center.

Each returned Notification is a live object connected to the corresponding
delivered notification — interaction events (click, reply, action, close)
will fire on these objects, enabling apps to re-attach event handlers after
a restart.

Key implementation details:
- Queries UNUserNotificationCenter's getDeliveredNotifications API
- Creates live Notification objects with populated id, groupId, title,
  subtitle, and body properties from what macOS provides
- Registers each object with the presenter via Restore() so the
  NotificationCenterDelegate routes events correctly
- Restored notifications use is_restored_ flag to prevent removal from
  Notification Center when the JS object is garbage collected
- Requires code-signed builds (unsigned builds resolve with empty array)

Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>

* test: fix typecheck

* fix: avoid dangling presenter pointer in GetHistory callback

* fix: document show() behavior

Notifications returned by getHistory() now set is_restored_ so that Dismiss() skips removal from Notification Center on GC. Calling show() on a restored notification removes the original from NC and posts a new one.

* fix: address code review feedback

* test: fix oxfmt linting

* docs: update docs/api/notification.md

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

---------

Co-authored-by: Claude <svc-devxp-claude@slack-corp.com>
Co-authored-by: Erick Zhao <erick@hotmail.ca>
2026-04-16 16:49:10 -07:00
Keeley Hammond
d813618538 fix: remove vestigial MachServices from ShipIt launchd job (#51070) 2026-04-16 15:12:38 -07:00
Keeley Hammond
99e8170f3f fix: fix types in devtools console for release (#51104) 2026-04-16 13:28:18 -07:00
Shelley Vohr
02d90a5ba3 chore: add Node.js skill to settings (#51092) 2026-04-16 15:28:45 -04:00
Niklas Wenzel
3c826c7503 fix: linter issue (#51105) 2026-04-16 12:07:16 -07:00
Charles Kerr
f35122b21e test: add tab source ID tests for media handler (#51068)
* test: add getMediaSourceId tab source coverage

* chore: move captureWithTabSourceId() to a shared helper

* test: improve "webContents module getMediaSourceId()" testing
2026-04-16 13:13:10 -04:00
Samuel Attard
5523130c92 ci: build a patched siso for Windows builds (#51077)
* ci: build a patched siso for Windows builds

The Windows Chromium builds intermittently fail during manifest load
with 'The parameter is incorrect.' (ERROR_INVALID_PARAMETER) out of
bindflt.sys. Root cause is a handle-relative NtCreateFile race in
siso/toolsupport/ninjautil/file_parser.go, which opens each subninja
twice — once in the outer goroutine and once more per chunk for
ReadAt. (*os.File).ReadAt is documented as safe for concurrent use,
so the extra open is redundant and removing it both halves the
CreateFileW calls per subninja and sidesteps the race.

Add a new build-siso-windows job on ubuntu-latest (runs in parallel
with checkout-windows) that:

- reads chromium_version from DEPS and pulls the matching siso_version
  SHA from the Chromium mirror's DEPS at that ref
- shallow-clones chromium.googlesource.com/build at that SHA
- applies the in-tree patches under .github/siso-patches/ via git am
- cross-compiles siso.exe for windows/amd64
- caches the binary keyed on siso SHA + sha256 of the patches, so
  subsequent runs hit the cache and skip the clone/patch/build steps
- uploads the result as a siso-windows-amd64 artifact

The Windows build jobs now depend on build-siso-windows, download the
artifact into $RUNNER_TEMP/siso, and export SISO_PATH, which
depot_tools/siso.py already honors. Mirrored into windows-publish.yml
and the regenerated pipeline-segment-electron-publish.yml so release
builds pick it up too.

Notes: none

* ci: extract siso build into a reusable workflow segment

Move the build-siso-windows job body into
pipeline-segment-build-siso-windows.yml and call it from both build.yml
and windows-publish.yml via workflow_call. Also pin actions/cache to
v5.0.5 and add version comments next to the action SHAs introduced by
this change.
2026-04-16 12:40:33 -04:00
Samuel Attard
abffba4548 fix: use CreateDataProperty when copying objects across contextBridge (#50900) 2026-04-16 12:39:53 +02:00
Shelley Vohr
d164b7af01 fix: prevent uaf when destroying guest WebContents during event emission (#50833)
fix: prevent use-after-free when destroying guest WebContents during event emission

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

The fix has two layers:

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

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

Destroy() now requires both `is_safe_to_delete_` (navigation re-entrancy)
and `!is_emitting_event_` (event emission) to allow synchronous guest
deletion. The existing AutoReset guards on `is_safe_to_delete_` in
DidStartNavigation, DidRedirectNavigation, and ReadyToCommitNavigation
are also now effective for guests.
2026-04-16 12:26:55 +02:00
Fedor Indutny
2434c5a73c fix: show 'Electron Isolated Context' in Dev Tools (#51062)
Because of a bug after the [upstream refactor][0] Dev Tools stopped
showing 'Electron Isolated Context' in the execution context selector.
'Electron Isolated Context' runs with origin set to `file://`. Since
domain name is empty for the origin the respective UI item in the
context selector is created with an empty `subtitle`. However, with the
upstream change items with either of `title` or `subtitle` are omitted
from rendering.

Here we float an [in-review patch][1] until it is fixed upstream.

[0]: dbb61cf4b2
[1]: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/7761316
2026-04-16 11:48:09 +02:00
Charles Kerr
cc738f2a6c refactor: avoid unnecessary extends EventEmitter in lib (#51058)
* refactor: MessageChannel does not need to extend EventEmitter

Added in f66d4c7 but never used.

Apparently added as a copy-paste side effect when adding better interface
info into the lib types, eg extends/implements.

* refactor: ShareMenu does not need to extend EventEmitter

Added in f66d4c7 but never used.

Apparently added as a copy-paste side effect when adding better interface
info into the lib types, eg extends/implements.
2026-04-15 23:24:15 -05:00
Charles Kerr
9569c48bfe refactor: SafeStorage never emits, so do not inherit from EventEmitter (#51057) 2026-04-15 23:24:00 -05:00
Charles Kerr
0a80d4d879 fix: UAF in api::UtilityProcessWrapper (#51069)
* fix: UAF in api::UtilityProcessWrapper

Detach the wrapper from ServiceProcessHost during termination instead
of waiting for destruction. Add a regression test that forces GC.

This fixes a UAF error reported by ASAN: the wrapper lost its last JS
reference and become collectible after emitting exit *but* before it
had been removed from the global observer list.

UtilityProcessWrapper is now cppgc-managed as of b9e462f397, but its
ServiceProcessHost observer cleanup still depended on destructor-time
teardown.

* fixup! fix: UAF in api::UtilityProcessWrapper

fix: much better cleanup from Deepak code review
2026-04-15 16:56:57 -07:00
Shelley Vohr
0227bcfb9f fix: allow PDF viewer to show save file picker (#51042)
The PDF viewer's "save with changes" feature uses
`window.showSaveFilePicker()`, but the PDF extension runs in a
cross-origin iframe (chrome-extension:// inside the app's origin).
Chromium's File System Access API blocks cross-origin subframes from
showing file pickers unless the embedder explicitly allows them via
`ContentClient::IsFilePickerAllowedForCrossOriginSubframe()`.

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

This adds the same override to `ElectronContentClient`, allowing the
built-in PDF extension origin to bypass the cross-origin check.
2026-04-15 18:04:24 -05:00
Anirudh Sevugan
0ad0d44b3d docs: add ELECTRON_INSTALL env vars and remove ELECTRON_SKIP_BINARY_D… (#50979)
docs: add ELECTRON_INSTALL env vars and remove ELECTRON_SKIP_BINARY_DOWNLOAD

these were added recently in a commit but no docs were there for them

also, ELECTRON_SKIP_BINARY_DOWNLOAD was deprecated in electron v42, so that is removed as well
2026-04-15 11:35:35 -05:00
Samuel Attard
04b9b7bc22 build: fail gha-done check when required job fails (#50959)
fix: fail gha-done when any required job failed

Previously, the `gha-done` gate job used an `if:` expression that
evaluated to false whenever any needed job reported a failure, which
caused the job to be *skipped* rather than *failed*. GitHub branch
protection treats skipped required checks as non-blocking, so a PR
could be marked mergeable even though one of its test jobs had failed.

Keep the job always running and move the failure check into a step
that explicitly exits 1 when any dependency failed or was cancelled,
so the "GitHub Actions Completed" required check actually blocks the
merge in that case.

Notes: none
2026-04-15 16:12:13 +02:00
Samuel Attard
22f15ec476 build: authenticate sudowoodo /token exchange via Actions OIDC (#51051) 2026-04-14 15:54:45 -07:00
Charles Kerr
53bf94fdf4 refactor: move electron::api::GlobalShortcut to cppgc (#50192)
* refactor: migrate electron::api::GlobalShortcut to cppgc

* refactor: lazy-create electron::api::GlobalShortcut

copy the lazy-create idom used by electron::api::Screen

* refactor: use gin::WeakCellFactory in GlobalCallbacks

* fix: make a copy of `callback` before running it

safeguard against the callback changing the map, invalidating `cb`

* chore: reduce unnecessary diffs with main

* fixup! refactor: use gin::WeakCellFactory in GlobalCallbacks

fix: must Trace() the weak cell factory

* fix: destruction order

- Setup isolate dispose observer to run destruction sequences
and remove self persistent reference
- Skip NOTREACHED check during destruction, it can happen
as a result of plaform listeners scheduling callbacks when Unregister is invoked.
- Fix the order of unregistration in GlobalShortcut::Unregister
- Add GlobalShortcut::UnregisterAllInternal to avoid any callsites
that can re-enter V8

* fix: crash during gc from incorrect cppgc object headers

* chore: update patches

* chore: cleanup

* chore: fix lint

---------

Co-authored-by: deepak1556 <hop2deep@gmail.com>
2026-04-14 15:52:13 -04:00
Michaela Laurencin
21c5e25f04 ci: allow manual backports to pass template check (#50916)
* ci: allow manual backports to pass template check

Co-Authored-By: Claude <noreply@anthropic.com>
Generated-By: GitHub Copilot

* Update .github/workflows/pr-template-check.yml

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Niklas Wenzel <dev@nikwen.de>
2026-04-14 12:15:35 -07:00
Erick Zhao
cf2cc4d80f docs: mention pre-release installation (#51020)
* docs: pre-release installation

* Update installation.md

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

---------

Co-authored-by: Niklas Wenzel <dev@nikwen.de>
2026-04-14 09:23:46 -07:00
Charles Kerr
8ea3d16ce9 chore: remove unused parts of chore_provide_iswebcontentscreationoverridden_with_full_params.patch (#51025)
chore: remove dead patches from chore_provide_iswebcontentscreationoverridden_with_full_params.patch
2026-04-14 09:23:43 -07:00
Charles Kerr
c30655785b refactor: remove FramelessView::Init() (#51008)
* refactor: remove FramelessView::Init()

move to constructor instead

* refactor: make FramelessView::window_ const

refactor: make FramelessView::frame_ const

* refactor: simplify NativeWindowViews::CreateFrameView() logic branches
2026-04-14 16:06:07 +02:00
David Sanders
d223ad67ea build: allow non-zero exit codes locally when linting Chromium rolls (#51031) 2026-04-14 09:04:09 -05:00
Charles Kerr
dad4ab658a fix: timing issue DCHECK crash in DesktopCapturer on macOS (#50960)
refactor: use StartUpdating in desktopCapturer

Replace the one-shot Update() callback model with the continuous
StartUpdating() observer model for NativeDesktopMediaList.

Fixes a macOS DCHECK(can_refresh()) crash in UpdateSourceThumbnail(),
where ScreenCaptureKit's recurrent thumbnail capturer would post
UpdateSourceThumbnail callbacks after the one-shot refresh_callback_
had been consumed. Now, can_refresh() is always true because
refresh_callback_ is repopulated via ScheduleNextRefresh().

Each capturer (window, screen) gets its own ListObserver that tracks
readiness via OnSourceAdded and OnSourceThumbnailChanged events.
Once a list has both sources and thumbnails (or thumbnails aren't
requested), its data is snapshotted and the capturer checks if all
requested types are ready before resolving to JS.

Also remove the "skip_next_refresh_" Chromium patch, which was a
workaround for the timing mismatch between the one-shot Update()
model and ScreenCaptureKit's asynchronous thumbnail delivery.

refactor: simplify state logic in DesktopCapturer
2026-04-14 09:03:18 -05:00
dependabot[bot]
9b85b9c0bc build(deps): bump actions/upload-artifact from 7.0.0 to 7.0.1 (#51032)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 7.0.0 to 7.0.1.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](bbbca2ddaa...043fb46d1a)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-14 12:44:07 +02:00
John Kleinschmidt
abd29a397e ci: don't login to RBE for clang-tidy and gn-check (#51022)
* ci: don't login to RBE for clang-tidy

* ci: don't login to RBE for gn check
2026-04-14 12:33:34 +02:00
John Kleinschmidt
604e7e82f2 test: fixup autoupdater tests failures (#51024) 2026-04-14 12:33:28 +02:00
Shelley Vohr
2e3da1d079 fix: crash when closing devtools after focus (#47435) 2026-04-14 12:32:19 +02:00
dependabot[bot]
edbff16029 build(deps): bump actions/github-script from 8.0.0 to 9.0.0 (#51033)
Bumps [actions/github-script](https://github.com/actions/github-script) from 8.0.0 to 9.0.0.
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](ed597411d8...3a2844b7e9)

---
updated-dependencies:
- dependency-name: actions/github-script
  dependency-version: 9.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-14 11:22:02 +02:00
John Kleinschmidt
b5fbbed4db ci: only move items to Needs Review when appropriate (#51023) 2026-04-14 11:02:09 +02:00
Niklas Wenzel
663773a677 fix: linter issue (#51009) 2026-04-13 08:14:34 -07:00
Niklas Wenzel
351f35da8c fix: include missing metadata in trace files (#50892) 2026-04-13 09:36:06 -04:00
Robo
b9e462f397 refactor: api::utilityProcessWrapper managed by cppgc (#50955)
* refactor: api::utilityProcessWrapper managed by cppgc

* chore: fix lint
2026-04-13 10:46:51 +02:00
Shelley Vohr
a39108c5a4 fix: nodeIntegrationInWorker not working in AudioWorklet (#47244)
* fix: nodeIntegrationInWorker not working in AudioWorklet

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

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

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

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

* chore: address review feedback

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

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

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

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

* chore: address outstanding feedback
2026-04-13 10:27:30 +02:00
402 changed files with 14593 additions and 2486 deletions

View File

@@ -11,6 +11,7 @@
"Bash(e patches:*)",
"Bash(e sync:*)",
"Skill(electron-chromium-upgrade)",
"Skill(electron-node-upgrade)",
"Read(*)",
"Bash(echo:*)",
"Bash(e build:*)",

View File

@@ -0,0 +1,106 @@
---
name: chrome-release-cls
description: Given a Chrome Releases blog post URL (chromereleases.googleblog.com), extract every CVE/bug and find the underlying Gerrit CL that fixed it by searching the local Chromium checkout and sub-repos. Use when asked to map Chrome security release notes to fixing CLs, or to find which commits correspond to CVEs in a Chrome stable update.
---
# Chrome Release → Fixing CL Mapper
Maps every security fix in a Chrome Releases blog post to the Gerrit CL(s) that fixed it.
## Input
`$ARGUMENTS` — a `https://chromereleases.googleblog.com/...` URL. If empty, ask the user for one.
## Procedure
### 1. Extract CVE → bug ID pairs from the blog post
The blog HTML buries bug IDs inside `<a>` tags, so strip tags first. Run:
```bash
curl -sL "$URL" | python3 -c '
import sys, re, html
t = re.sub(r"<[^>]+>", " ", sys.stdin.read())
t = re.sub(r"\s+", " ", html.unescape(t))
seen = set()
for m in re.finditer(r"\[\s*(\d{6,})\s*\]\s*(Critical|High|Medium|Low)\s*(CVE-\d{4}-\d+):\s*([^.]+?)\.", t):
if m.group(3) in seen: continue
seen.add(m.group(3))
print(f"{m.group(3)}|{m.group(1)}|{m.group(2)}|{m.group(4).strip()}")
' > /tmp/cve_bugs.txt
cat /tmp/cve_bugs.txt
```
If this yields nothing, the page may have changed format — fall back to `grep -oE 'CVE-[0-9]{4}-[0-9]+'` and `grep -oE 'crbug\.com/[0-9]+'` and pair them by order.
### 2. Find the fixing CL for each bug
Search git history in the Chromium checkout and relevant sub-repos for commits whose `Bug:` or `Fixed:` footer references the bug ID, then extract the `Reviewed-on:` Gerrit URL.
Repo selection by component keyword:
- ANGLE → `third_party/angle`
- Skia, Graphite → `third_party/skia`
- PDFium → `third_party/pdfium`
- Dawn → `third_party/dawn`
- V8, Turbofan, Maglev, Turboshaft → `v8`
- everything else → `.` (chromium/src)
Always also fall back to `.` if the hinted repo has no match.
```bash
cd /root/src/electron/src # chromium root (parent of electron/)
lookup() {
local bug="$1" repos="$2"
for repo in $repos . v8 third_party/skia third_party/angle third_party/pdfium third_party/dawn; do
local hits
hits=$(git -C "$repo" log --all --since='6 months ago' -E \
--grep="(Bug|Fixed):.*\\b${bug}\\b" --format='%H' 2>/dev/null | sort -u)
[[ -z "$hits" ]] && continue
while read -r h; do
git -C "$repo" log -1 --format='%B' "$h" | grep '^Reviewed-on:' | sed 's/^/ /'
echo "$(git -C "$repo" log -1 --format='%s' "$h")"
done <<<"$hits"
return 0
done
echo " (not found locally)"
}
```
Drive it from `/tmp/cve_bugs.txt`. Prefer the **non-`[M1xx]`-prefixed** commit subject as the canonical main CL; the `[M1xx]` ones are branch cherry-picks.
### 3. Handle misses
For any bug with no local hit:
- `git -C <repo> fetch origin` then re-search `--remotes` (fix may be newer than the checkout).
- Query Gerrit directly: `curl -s "https://chromium-review.googlesource.com/changes/?q=bug:${BUG}&n=10" | tail -n +2 | python3 -m json.tool` (also try `skia-review`, `pdfium-review`, `dawn-review`, `aomedia-review`).
- **`b/` bug format (Skia, Graphite, Dawn):** These repos reference bugs as `b/<id>` in commit messages rather than `Bug: <id>` footers. The Gerrit `bug:` query will return nothing. Use `message:<id>` search instead:
```bash
curl -s "https://skia-review.googlesource.com/changes/?q=message:${BUG}&n=5" | tail -n +2
```
Apply the same pattern for `dawn-review.googlesource.com` when the component is Dawn.
- **Tracing main CLs from merges:** When only `[M1xx]` merge CLs are found, query the CL detail for `cherry_pick_of_change` to find the original main CL number:
```bash
curl -s "https://chromium-review.googlesource.com/changes/${CL_NUM}?o=CURRENT_REVISION" | tail -n +2 | python3 -c "
import sys, json
d = json.load(sys.stdin)
print(d.get('cherry_pick_of_change', 'none'))
"
```
- If still nothing and the bug was reported very recently (especially by "Google Threat Intelligence" or marked in-the-wild), the CL is likely still access-restricted — report it as such rather than guessing.
### 4. Special cases
- **Roll CLs — skip and find the upstream fix:** For components whose fixes land in upstream repos (PDFium, Dawn, Skia, Graphite, libaom, libvpx, ffmpeg), the chromium-review hit will be a `Roll src/third_party/...` commit. Do not report the roll CL as the fix. Instead, query the component's own Gerrit instance directly for the actual fixing CL:
- PDFium → `pdfium-review.googlesource.com` (use `bug:` or `message:` query)
- Dawn → `dawn-review.googlesource.com` (use `message:` query — uses `b/` format)
- Skia / Graphite → `skia-review.googlesource.com` (use `message:` query — uses `b/` format)
- libaom → `aomedia-review.googlesource.com`
Only if the upstream Gerrit instance returns no results should you fall back to reporting the roll CL — in that case, include the roll CL and note that the actual fix is upstream but the specific CL could not be identified.
- Multiple `Reviewed-on:` lines in one commit body: cherry-picks keep the original line plus a new one. The **first** `Reviewed-on:` is the original CL.
- A bug may have multiple distinct fix CLs (fix + follow-up hardening) — list all of them.
### 5. Output
Produce a markdown table per severity level: `CVE | Bug | Component | Fix CL (main)`. Link bugs as `https://crbug.com/<id>`. Save raw output (including all branch merges) to `/tmp/cve_cls.txt` and mention the path.

View File

@@ -0,0 +1,123 @@
---
name: chrome-release-verify
description: End-to-end Chrome security backport for an Electron release branch. Given a Chrome Releases blog URL and a branch (e.g. 41-x-y), determines which CVE fixes are missing from the *actual synced source*, writes the cherry-pick patches locally, validates them with `e sync --3` + `lint --patches`, then pushes a single PR. Use when asked to backport a Chrome security release to N-x-y, "is CVE-X already in N-x-y?", or to produce/validate the cherry-pick set for a release branch.
---
# Chrome Release → Validated Backport PR
Input: `$ARGUMENTS` = `<release-branch> <chrome-releases-blog-url>` (e.g. `41-x-y https://chromereleases.googleblog.com/2026/04/stable-channel-update-for-desktop_15.html`). Ask if either is missing.
The flow is **local-first**: nothing is pushed until every patch applies via `e sync --3` and passes `lint --patches`.
## 1. Map CVE → bug → fix CL
Run `/chrome-release-cls <blog-url>` (or its inline procedure) to produce `/tmp/cve_bugs.txt` (`CVE|bug|severity|desc`) and a per-bug canonical fix CL. For each CL also note `repo` (path under `src/`: `.`, `v8`, `third_party/{skia,angle,pdfium,dawn}`, `third_party/libaom/source/libaom`) and `gerrit-host`.
**Prefer the target-milestone merge CL** if one exists (e.g. on `41-x-y` ≈ M146, prefer the `[M146]` cherry-pick over the main CL) — it's already rebased and far less likely to conflict. Find it via `git log --all --grep` on the Change-Id, or Gerrit `?q=bug:<n>`. If Chrome did *not* merge a fix to the target milestone, that's a strong signal the vulnerable code doesn't exist there — flag it for skip rather than forcing a port.
## 2. Prepare a synced worktree
Reuse `bp-<NN>` from `e show configs` if present, else `e worktree add bp-<NN> ~/src/electron-bp-<NN> --source <current> --no-sync`.
```bash
cd <root>/src/electron
git fetch origin <branch>
git checkout -B security-backport/<branch>/<short-date> origin/<branch>
e use bp-<NN>
e sync 2>&1 | tee /tmp/bp_sync.log
```
If sync fails with `NotADirectoryError: '<root>/src/.git/objects/info/alternates'`, remove `GIT_CACHE_PATH` from the bp config's `env` and retry.
## 3. Verify IN-TREE vs NEEDS-BACKPORT
For each bug, three checks against the **synced** repo:
1. `git -C "$repo" log HEAD --since='1 year ago' -E --grep="\b${bug}\b" --format='%h %s'`
2. Fetch Change-Id from Gerrit, then `git log HEAD --grep="^Change-Id: ${cid}$"`
3. `grep -rlE "(\b${bug}\b|${cid})" <root>/src/electron/patches/`
Any hit ⇒ IN-TREE. All empty ⇒ NEEDS-BACKPORT.
For each NEEDS-BACKPORT CL, also fetch its file list (`/changes/<proj>~<cl>/revisions/current/files`) and **skip** if every file is under `chrome/browser/`, `chrome/android/`, `ios/`, or `components/**/android/` — Electron doesn't compile those.
Report the table now (`CVE | Sev | Bug | Component | Verdict | CL`) and the proposed backport set; get user sign-off before continuing.
## 4. Write patches locally (no push yet)
For each backport CL, fetch the raw patch and write it into `patches/<dir>/`:
```bash
curl -s "https://${host}.googlesource.com/changes/${proj//\//%2F}~${cl}/revisions/current/patch" \
| base64 -d > "patches/${dir}/cherry-pick-${short}.patch"
echo "cherry-pick-${short}.patch" >> "patches/${dir}/.patches"
```
For repos with no Gerrit host `e cherry-pick` supports (e.g. **libaom** on aomedia), instead `git cherry-pick` the upstream commits onto the synced sub-repo HEAD and `git format-patch` the result.
For any newly-created `patches/<dir>/`, append to `patches/config.json` **preserving the compact one-line-per-entry style**:
```json
{ "patch_dir": "src/electron/patches/<dir>", "repo": "src/third_party/<dir-or-nested-path>" }
```
## 5. Validate with `e sync --3`
```bash
e sync --3 2>&1 | tee /tmp/bp_sync3.log
```
On `Patch failed at NNNN <subject>`:
- `cd` into the failing repo, inspect `git diff` for conflict markers.
- **Test-only files** (e.g. `web_tests/VirtualTestSuites`, `*_unittest.cc` context drift): take ours (`git checkout --ours -- <file>`) if the security-relevant hunks merged cleanly.
- **Substantive code conflicts**: check whether a target-milestone merge CL exists and swap to it. If none exists upstream and the surrounding code is structurally different, **drop the patch** (delete the file, remove from `.patches` and `config.json`) and note it for a separate manual-port PR — do not improvise security-fix semantics.
- After resolving: `git add <files> && git -c commit.gpgsign=false am --continue`, then `e patches <repo>` to export the resolved patch, then re-run `e sync --3`. Repeat until clean.
## 6. Export → lint → re-apply loop
```bash
e patches all
node script/lint.js --patches # must exit 0
```
If lint reports findings (typically trailing whitespace on `+` content lines), fixing them **changes the bytes the patch writes**, which invalidates the `index <old>..<new>` blob hashes that `e patches` baked in. Hand-editing a `.patch` and pushing it as-is will pass lint locally but fail CI's Apply Patches re-export check with a one-line `index` hash diff.
So whenever lint (or you) modifies any `.patch` file after export, round-trip once more:
```bash
# fix the lint findings in patches/**/*.patch, then:
e sync # re-apply the edited patches (no --3 needed; they applied cleanly last time)
e patches all # re-export so index blob hashes match the edited content
node script/lint.js --patches # must now exit 0
git diff --quiet -- patches/ || { echo "patches changed again — repeat the loop"; }
```
Repeat until `lint --patches` exits 0 **and** `git diff -- patches/` is empty after the final `e patches all`. Only then is the patch set CI-stable.
## 7. Commit, push, PR
```bash
git add patches/
git commit -m "chore: cherry-pick <N> changes from <dirs>"
git push origin HEAD
gh pr create --repo electron/electron --base <branch> --head <this-branch> \
--title "chore: cherry-pick <N> changes from <dirs>" \
--label "<branch>" --label backport-check-skip --label semver/patch --label "security 🔒" \
--body-file /tmp/pr_body.md
```
PR body format:
```markdown
Backports the following changes:
* [`<shortCommit>`](<gerrit-CL-url>) from <patchDir> — <subject> ([<bug>](https://crbug.com/<bug>), CVE-YYYY-NNNN)
* ...
Notes: Security: backported fixes for CVE-YYYY-NNNN, CVE-YYYY-NNNN, ....
```
Short commit links to the **Gerrit CL**; bug links to `crbug.com`; CVE comes from the blog mapping (the patch's own `Bug:` footer may differ); `Notes:` is the last line. Mention any dropped patches (with reason) above the `Notes:` line.
Restore `e use <previous>` when done.

View File

@@ -1,6 +1,6 @@
---
name: electron-node-upgrade
description: Guide for performing Node.js version upgrades in the Electron project. Use when working on the roller/node/main branch to fix patch conflicts during `e sync --3`. Covers the patch application workflow, conflict resolution, analyzing upstream Node.js changes, and proper commit formatting for patch fixes.
description: Guide for performing Node.js version upgrades in the Electron project. Use when working on the roller/node/main branch to fix patch conflicts during `e sync --3`. Covers the patch application workflow, conflict resolution, analyzing upstream Node.js changes, building, running the Node.js test suite, and proper commit formatting for patch fixes.
---
# Electron Node.js Upgrade: Phase One
@@ -174,10 +174,127 @@ When the error is in Electron's own source code:
1. Edit files directly in the electron repo
2. Commit directly (no patch export needed)
# Electron Node.js Upgrade: Phase Three
## Summary
Run the Node.js test suite via `script/node-spec-runner.js`, fix failing tests, and commit fixes until all tests pass. Certain tests are permanently disabled (listed in `script/node-disabled-tests.json`) and should not be run.
Run Phase Three immediately after Phase Two is complete.
## Success Criteria
Phase Three is complete when:
- `node script/node-spec-runner.js --default` exits with zero failures
- All changes are committed per the commit guidelines
Do not stop until these criteria are met.
## Context
Electron runs a subset of Node.js's upstream test suite using a custom runner (`script/node-spec-runner.js`). Tests are executed with the built Electron binary via `ELECTRON_RUN_AS_NODE=true`. Many tests need adaptation because Electron uses BoringSSL (not OpenSSL) and Chromium's V8 (which may differ from Node.js's bundled V8).
**Key files:**
- `script/node-spec-runner.js` — Test runner script
- `script/node-disabled-tests.json` — Permanently disabled tests (do not try to fix these)
- `../third_party/electron_node/test/` — Node.js test files (where patches apply)
- `patches/node/fix_crypto_tests_to_run_with_bssl.patch` — BoringSSL crypto test adaptations
- `patches/node/test_formally_mark_some_tests_as_flaky.patch` — Flaky test list
## Workflow
1. Run `node script/node-spec-runner.js --default` from the electron repo
2. If all tests pass → Phase Three is complete
3. If tests fail:
- Identify the failing test file(s) from the output
- Analyze each failure (see "Common Failure Patterns" below)
- Fix the test in `../third_party/electron_node/test/...`
- Re-run the specific failing test to verify: `node script/node-spec-runner.js {test-path}`
- The test path is relative to the node `test/` directory, e.g. `test/parallel/test-crypto-key-objects-raw.js`
- Do NOT use `--default` when running specific tests — it adds the full suite flags
- Do NOT run tests directly with `ELECTRON_RUN_AS_NODE` — the runner handles environment setup (e.g. temporarily switching `package.json` from ESM to CommonJS)
- Commit the fix using the fixup workflow and commit guidelines
- Return to step 1
## Commands Reference
| Command | Purpose |
|---------|---------|
| `node script/node-spec-runner.js --default` | Run full Node.js test suite |
| `node script/node-spec-runner.js test/parallel/test-foo.js` | Run a single test |
| `NODE_REGENERATE_SNAPSHOTS=1 node script/node-spec-runner.js test/test-runner/test-foo.mjs` | Regenerate snapshot for a snapshot-based test |
## Common Failure Patterns
### BoringSSL incompatibilities
Electron uses BoringSSL (via Chromium) instead of OpenSSL. Many crypto features are missing or behave differently:
| Unsupported in BoringSSL | Guard pattern |
|--------------------------|---------------|
| ChaCha20-Poly1305 | `if (!process.features.openssl_is_boringssl)` |
| AES-CCM (aes-128-ccm, aes-256-ccm) | `if (ciphers.includes('aes-128-ccm'))` |
| AES-KW (key wrapping) | `if (!process.features.openssl_is_boringssl)` |
| DSA keys | `if (!process.features.openssl_is_boringssl)` |
| Ed448 / X448 curves | `if (!process.features.openssl_is_boringssl)` |
| DH key PEM loading | `if (!process.features.openssl_is_boringssl)` |
| PQC algorithms (ML-KEM, ML-DSA, SLH-DSA) | `if (hasOpenSSL(3, 5))` (already guards these) |
When guarding tests, prefer checking cipher availability (`ciphers.includes(algo)`) over blanket BoringSSL checks where possible, as it's more precise and self-documenting.
New upstream tests that exercise these features will need guards added to the `fix_crypto_tests_to_run_with_bssl` patch.
### Snapshot test mismatches
Some tests compare output against committed `.snapshot` files using `assert.strictEqual` — these are NOT wildcard comparisons. When Chromium's V8 produces different output (e.g. different stack traces due to V8 enhancements), the snapshot must be regenerated:
```bash
NODE_REGENERATE_SNAPSHOTS=1 node script/node-spec-runner.js test/test-runner/test-foo.mjs
```
Then inspect the diff to verify the changes are expected, and commit the updated snapshot into the appropriate patch.
### V8 behavioral differences
Chromium's V8 may be ahead of Node.js's bundled V8. This can cause:
- Different stack trace formats (e.g. thenable async stack frames)
- Different error messages
- Features available in Chromium V8 that aren't in stock Node.js V8 (or vice versa)
## Two Types of Test Fixes
### A. Patch Fixes (most common for test failures)
Most test fixes go into existing patches in `patches/node/`. Use the fixup workflow:
1. Edit the test file in `../third_party/electron_node/test/...`
2. Find the relevant patch commit: `git log --oneline | grep -i "keyword"`
- Crypto/BoringSSL tests → `fix crypto tests to run with bssl`
- Snapshot tests → the specific snapshot patch (e.g. `test: accomodate V8 thenable`)
- Flaky tests → `test: formally mark some tests as flaky`
3. Create a fixup commit:
```bash
cd ../third_party/electron_node
git add test/path/to/test.js
git commit --fixup=<patch-commit-hash>
GIT_SEQUENCE_EDITOR=: git rebase --autosquash --autostash -i <commit>^
```
4. Export: `e patches node`
5. **Read `references/phase-three-commit-guidelines.md` NOW**, then commit the updated patch file.
### B. New Patches (rare)
Only create a new patch when the fix doesn't belong in any existing patch. The new patch commit in `../third_party/electron_node` must include a description explaining why the patch exists and when it can be removed — the lint check enforces this.
## Adding to Disabled Tests
Only add a test to `script/node-disabled-tests.json` as a **last resort** — when the test is fundamentally incompatible with Electron's architecture (not just a BoringSSL difference that can be guarded). Tests disabled here are completely skipped and never run.
# Critical: Read Before Committing
- Before ANY Phase One commits: Read `references/phase-one-commit-guidelines.md`
- Before ANY Phase Two commits: Read `references/phase-two-commit-guidelines.md`
- Before ANY Phase Three commits: Read `references/phase-three-commit-guidelines.md`
# High-Churn Patches
@@ -201,5 +318,6 @@ This skill has additional reference files in `references/`:
- patch-analysis.md - How to analyze patch failures
- phase-one-commit-guidelines.md - Commit format for Phase One
- phase-two-commit-guidelines.md - Commit format for Phase Two
- phase-three-commit-guidelines.md - Commit format for Phase Three
Read these when referenced in the workflow steps.

View File

@@ -0,0 +1,80 @@
# Phase Three Commit Guidelines
Only follow these instructions if there are uncommitted changes after fixing a test failure during Phase Three.
Ignore other instructions about making commit messages, our guidelines are CRITICALLY IMPORTANT and must be followed.
## Commit Message Style
**Titles** follow the 60/80-character guideline: simple changes fit within 60 characters, otherwise the limit is 80 characters.
Always include a `Co-Authored-By` trailer identifying the AI model that assisted (e.g., `Co-Authored-By: <AI model attribution>`).
## Commit Types
### Patch updates (most test fixes)
Test fixes go into existing patches via the fixup workflow. Use `fix(patch):` prefix with a descriptive topic:
```
fix(patch): {topic headline}
Ref: {Node.js commit or issue link}
Co-Authored-By: <AI model attribution>
```
Examples:
- `fix(patch): guard DH key test for BoringSSL`
- `fix(patch): adapt new crypto tests for BoringSSL`
- `fix(patch): correct thenable snapshot for Chromium V8`
- `fix(patch): skip AES-KW tests with BoringSSL`
Group related test fixes into a single commit when they address the same root cause (e.g., multiple crypto tests all needing BoringSSL guards for the same missing cipher). Don't create one commit per test file if they share the same fix pattern.
### Snapshot regeneration
When a snapshot test fails because Chromium's V8 produces different output, regenerate it:
```bash
NODE_REGENERATE_SNAPSHOTS=1 node script/node-spec-runner.js test/test-runner/test-foo.mjs
```
Then commit the updated snapshot patch with a title describing what changed:
```
fix(patch): correct {name} snapshot for Chromium V8
Ref: {V8 CL or issue link if known}
Co-Authored-By: <AI model attribution>
```
### Trivial patch updates
After any patch modification, check for dependent patches that only have index/hunk header changes:
```bash
git status
# If other .patch files show as modified with only trivial changes:
git add patches/
git commit -m "chore: update patches (trivial only)"
```
## Finding References
For BoringSSL-related test fixes, the reference is typically the upstream Node.js PR that added the new test:
```bash
cd ../third_party/electron_node
git log --oneline -5 -- test/parallel/test-crypto-foo.js
git log -1 <commit> --format="%B" | grep "PR-URL"
```
For V8 behavioral differences, reference the Chromium CL:
```
Ref: https://chromium-review.googlesource.com/c/v8/v8/+/NNNNNNN
```
If no reference found after searching: `Ref: Unable to locate reference`

View File

@@ -1,14 +0,0 @@
name: Maintainer Issue (not for public use)
description: Only to be created by Electron maintainers
body:
- type: checkboxes
attributes:
label: Confirmation
options:
- label: I am a [maintainer](https://github.com/orgs/electron/people) of the Electron project. (If not, please create a [different issue type](https://github.com/electron/electron/issues/new/).)
required: true
- type: textarea
attributes:
label: Description
validations:
required: true

View File

@@ -40,9 +40,15 @@ runs:
echo "GN_EXTRA_ARGS=$GN_APPENDED_ARGS" >> $GITHUB_ENV
- name: Set GN_EXTRA_ARGS for Windows
shell: bash
if: ${{inputs.target-arch != 'x64' && inputs.target-platform == 'win' }}
if: ${{ inputs.target-platform == 'win' }}
run: |
GN_APPENDED_ARGS="$GN_EXTRA_ARGS target_cpu=\"${{ inputs.target-arch }}\""
# Resolve .obj paths to absolute in linker response files to work
# around BindFlt concurrency bug in Windows containers.
# https://github.com/microsoft/Windows-Containers/issues/635
GN_APPENDED_ARGS="$GN_EXTRA_ARGS win_abs_link_wrapper=\"//electron/build/win/abs_link_wrapper.py\""
if [ "${{ inputs.target-arch }}" != "x64" ]; then
GN_APPENDED_ARGS="$GN_APPENDED_ARGS target_cpu=\"${{ inputs.target-arch }}\""
fi
echo "GN_EXTRA_ARGS=$GN_APPENDED_ARGS" >> $GITHUB_ENV
- name: Add Clang problem matcher
shell: bash
@@ -107,6 +113,10 @@ runs:
} else {
e build --target electron:testing_build
}
if ($LASTEXITCODE -ne 0) {
Write-Host "e build failed with exit code $LASTEXITCODE"
exit $LASTEXITCODE
}
Copy-Item out\Default\.ninja_log out\electron_ninja_log
node electron\script\check-symlinks.js

View File

@@ -0,0 +1,24 @@
name: 'Build Image SHA'
description: 'Single source of truth for the ghcr.io/electron/build image SHA'
inputs:
override:
description: 'Optional override SHA (e.g. from a workflow_dispatch input)'
required: false
default: ''
outputs:
build-image-sha:
description: 'The electron/build image SHA to use'
value: ${{ steps.set.outputs.build-image-sha }}
runs:
using: 'composite'
steps:
- id: set
shell: bash
env:
OVERRIDE: ${{ inputs.override }}
run: |
if [ -n "$OVERRIDE" ]; then
echo "build-image-sha=$OVERRIDE" >> "$GITHUB_OUTPUT"
else
echo "build-image-sha=daad061f4b99a0ae1c841be4aa09188280a9c8a4" >> "$GITHUB_OUTPUT"
fi

View File

@@ -133,7 +133,7 @@ runs:
run : |
cd src/third_party/angle
rm -f .git/objects/info/alternates
git remote set-url origin https://chromium.googlesource.com/angle/angle.git
git remote set-url origin https://github.com/google/angle.git
cp .git/config .git/config.backup
git remote remove origin
mv .git/config.backup .git/config

View File

@@ -21,11 +21,28 @@ runs:
if [ "$TARGET_ARCH" = "x86" ]; then
export npm_config_arch="ia32"
fi
# if running on linux arm skip yarn Builds
ARCH=$(uname -m)
node script/yarn.js install --immutable --mode=skip-build
# if running on linux arm skip yarn Builds
if [ "$ARCH" = "armv7l" ]; then
echo "Skipping yarn build on linux arm"
node script/yarn.js install --immutable --mode=skip-build
else
# Pre-seed the node-gyp header cache so the parallel native-addon
# builds below don't race on a cold cache. Linux build containers
# already ship a warm cache (electron/build-images#68), so only do
# this on macOS / Windows runners.
if [ "$(uname -s)" != "Linux" ]; then
for i in 1 2 3; do
if node node_modules/node-gyp/bin/node-gyp.js install; then
break
fi
if [ "$i" = "3" ]; then
echo "node-gyp header pre-seed failed after 3 attempts" >&2
exit 1
fi
echo "node-gyp header pre-seed failed (attempt $i), retrying in 5s..." >&2
sleep 5
done
fi
node script/yarn.js install --immutable
fi

View File

@@ -0,0 +1,47 @@
From aab86e682d6f40e110700f36c9c37f6655fb14f1 Mon Sep 17 00:00:00 2001
From: Samuel Attard <sam@electronjs.org>
Date: Wed, 8 Apr 2026 23:24:15 -0700
Subject: [PATCH] siso: reuse the outer *os.File for chunked ReadAt in
fileParser.readFile
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The per-chunk goroutine currently re-opens fname to get its own handle
for ReadAt. (*os.File).ReadAt is documented as safe for concurrent
calls on the same File (on Windows it is ReadFile with an OVERLAPPED
offset, so there is no shared seek state), so the extra open is
redundant — the goroutines can share the outer f.
Besides halving the CreateFileW calls per subninja, this avoids an
intermittent 'The parameter is incorrect.' (ERROR_INVALID_PARAMETER)
from bindflt.sys when out/ is a mapped directory inside a Windows
container: bindflt's handle-relative NtCreateFile path races when a
second relative open arrives while the first handle to the same target
is still being set up. Absolute paths and single opens do not trigger
it; see microsoft/Windows-Containers#<tbd>.
---
siso/toolsupport/ninjautil/file_parser.go | 7 -------
1 file changed, 7 deletions(-)
diff --git a/siso/toolsupport/ninjautil/file_parser.go b/siso/toolsupport/ninjautil/file_parser.go
index f8c7eff..75b1d6e 100644
--- a/siso/toolsupport/ninjautil/file_parser.go
+++ b/siso/toolsupport/ninjautil/file_parser.go
@@ -128,13 +128,6 @@ func (p *fileParser) readFile(ctx context.Context, fname string) ([]byte, error)
eg.Go(func() error {
p.sema <- struct{}{}
defer func() { <-p.sema }()
- f, err := os.Open(fname)
- if err != nil {
- return err
- }
- defer func() {
- _ = f.Close()
- }()
for len(chunkBuf) > 0 {
n, err := f.ReadAt(chunkBuf, pos)
if err != nil {
--
2.52.0

View File

@@ -0,0 +1,132 @@
From 1786f2266cba6a66343e5af2b724214930c8292f Mon Sep 17 00:00:00 2001
From: Samuel Attard <sam@electronjs.org>
Date: Wed, 22 Apr 2026 16:27:51 -0700
Subject: [PATCH] siso: retry transient ERROR_INVALID_PARAMETER when opening
ninja files on Windows
ManifestParser.Load fans out across all subninja files (~90k in a
Chromium build) at NumCPU parallelism. On Windows builders where out/
is served through a filesystem filter driver (e.g. bindflt/wcifs for
container bind mounts), CreateFileW can intermittently return
ERROR_INVALID_PARAMETER under this concurrent open burst. The previous
patch removes the redundant per-chunk re-open, but the single remaining
open per file can still hit the race; without a retry a single transient
failure aborts the entire manifest load.
Wrap the remaining os.Open call in readFile in a small Windows-only
retry for ERROR_INVALID_PARAMETER (5 attempts, 5-80ms backoff). Each
retry is logged via clog.Warningf and also written to stderr so it is
visible in CI step output where glog warnings are file-only by default.
Other platforms keep the direct os.Open path.
---
siso/toolsupport/ninjautil/file_parser.go | 3 +-
siso/toolsupport/ninjautil/openfile_other.go | 18 +++++++
.../toolsupport/ninjautil/openfile_windows.go | 50 +++++++++++++++++++
3 files changed, 69 insertions(+), 2 deletions(-)
create mode 100644 siso/toolsupport/ninjautil/openfile_other.go
create mode 100644 siso/toolsupport/ninjautil/openfile_windows.go
diff --git a/siso/toolsupport/ninjautil/file_parser.go b/siso/toolsupport/ninjautil/file_parser.go
index 75b1d6e..4a3e639 100644
--- a/siso/toolsupport/ninjautil/file_parser.go
+++ b/siso/toolsupport/ninjautil/file_parser.go
@@ -7,7 +7,6 @@ package ninjautil
import (
"context"
"fmt"
- "os"
"path/filepath"
"runtime/trace"
"sync"
@@ -108,7 +107,7 @@ func (p *fileParser) parseFile(ctx context.Context, fname string) error {
// readFile reads a file of fname in parallel.
func (p *fileParser) readFile(ctx context.Context, fname string) ([]byte, error) {
defer trace.StartRegion(ctx, "ninja.read").End()
- f, err := os.Open(fname)
+ f, err := openFile(ctx, fname)
if err != nil {
return nil, err
}
diff --git a/siso/toolsupport/ninjautil/openfile_other.go b/siso/toolsupport/ninjautil/openfile_other.go
new file mode 100644
index 0000000..9fca690
--- /dev/null
+++ b/siso/toolsupport/ninjautil/openfile_other.go
@@ -0,0 +1,18 @@
+// Copyright 2026 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//go:build !windows
+
+package ninjautil
+
+import (
+ "context"
+ "os"
+)
+
+// openFile opens fname for reading.
+// See openfile_windows.go for the Windows variant with transient-error retry.
+func openFile(ctx context.Context, fname string) (*os.File, error) {
+ return os.Open(fname)
+}
diff --git a/siso/toolsupport/ninjautil/openfile_windows.go b/siso/toolsupport/ninjautil/openfile_windows.go
new file mode 100644
index 0000000..f9d8e9d
--- /dev/null
+++ b/siso/toolsupport/ninjautil/openfile_windows.go
@@ -0,0 +1,50 @@
+// Copyright 2026 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//go:build windows
+
+package ninjautil
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "os"
+ "time"
+
+ "golang.org/x/sys/windows"
+
+ "go.chromium.org/build/siso/o11y/clog"
+)
+
+// openFile opens fname for reading, retrying transient
+// ERROR_INVALID_PARAMETER failures.
+//
+// On Windows, CreateFileW can intermittently return
+// ERROR_INVALID_PARAMETER when the target lives behind a filesystem
+// filter driver (e.g. bindflt/wcifs for container bind mounts) under
+// highly concurrent opens. loadFile fans out across ~90k subninja
+// files at NumCPU parallelism, so a single transient failure would
+// otherwise abort the whole manifest load.
+func openFile(ctx context.Context, fname string) (*os.File, error) {
+ const maxAttempts = 5
+ delay := 5 * time.Millisecond
+ for i := 0; ; i++ {
+ f, err := os.Open(fname)
+ if err == nil {
+ return f, nil
+ }
+ if i+1 >= maxAttempts || !errors.Is(err, windows.ERROR_INVALID_PARAMETER) {
+ return nil, err
+ }
+ clog.Warningf(ctx, "open %s: %v; retrying (%d/%d) after %s", fname, err, i+1, maxAttempts, delay)
+ fmt.Fprintf(os.Stderr, "siso: open %s: %v; retrying (%d/%d) after %s\n", fname, err, i+1, maxAttempts, delay)
+ select {
+ case <-time.After(delay):
+ case <-ctx.Done():
+ return nil, context.Cause(ctx)
+ }
+ delay *= 2
+ }
+}
--
2.52.0

View File

@@ -18,6 +18,8 @@ jobs:
pull-requests: read
outputs:
has-patches: ${{ steps.filter.outputs.patches }}
has-siso-patches: ${{ steps.filter.outputs.siso-patches }}
build-image-sha: ${{ steps.build-image-sha.outputs.build-image-sha }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
@@ -33,6 +35,12 @@ jobs:
patches:
- DEPS
- 'patches/**'
siso-patches:
- DEPS
- '.github/siso-patches/**'
- name: Set Build Image SHA
id: build-image-sha
uses: ./.github/actions/build-image-sha
apply-patches:
needs: setup
@@ -41,7 +49,7 @@ jobs:
permissions:
contents: read
container:
image: ghcr.io/electron/build:eac3529546ea8f3aa356d31e345715eef342233b
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
options: --user root
volumes:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
@@ -73,9 +81,16 @@ jobs:
target-platform: linux
- name: Upload Patch Conflict Fix
if: ${{ failure() }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: update-patches
path: patches/update-patches.patch
if-no-files-found: ignore
archive: false
build-siso:
needs: setup
if: ${{ needs.setup.outputs.has-siso-patches == 'true' }}
uses: ./.github/workflows/pipeline-segment-build-siso-windows.yml
permissions:
contents: read

View File

@@ -17,7 +17,7 @@ jobs:
with:
fetch-depth: 0
- name: Setup Node.js/npm
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
with:
node-version: 24.12.x
- name: Setting Up Dig Site
@@ -49,7 +49,7 @@ jobs:
sha-file: .dig-old
filename: electron.old.d.ts
- name: Upload artifacts
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f #v7.0.0
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a #v7.0.1
with:
name: artifacts
path: electron/artifacts

View File

@@ -17,7 +17,7 @@ jobs:
contents: read
steps:
- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 22.17.x
- name: Sparse checkout repository
@@ -28,7 +28,7 @@ jobs:
.github
.yarn
- run: yarn workspaces focus @electron/gha-workflows
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
id: audit-errors
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -105,7 +105,7 @@ jobs:
org: electron
- name: Generate Release Project Board Metadata
if: ${{ steps.check-major-version.outputs.MAJOR }}
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
id: generate-project-metadata
env:
MAJOR: ${{ steps.check-major-version.outputs.MAJOR }}
@@ -157,7 +157,7 @@ jobs:
}))
- name: Create Release Project Board
if: ${{ steps.check-major-version.outputs.MAJOR }}
uses: dsanders11/project-actions/copy-project@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
uses: dsanders11/project-actions/copy-project@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
id: create-release-board
with:
drafts: true
@@ -170,6 +170,60 @@ jobs:
template-view: ${{ steps.generate-project-metadata.outputs.template-view }}
title: ${{ steps.generate-project-metadata.outputs.major }}-x-y
token: ${{ steps.generate-token.outputs.token }}
- name: Randomly Assign Draft Issues to Release WG Members
if: ${{ steps.check-major-version.outputs.MAJOR }}
uses: dsanders11/project-actions/github-script@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
env:
PROJECT_ID: ${{ steps.create-release-board.outputs.id }}
with:
token: ${{ steps.generate-token.outputs.token }}
script: |
const { data: members } = await github.rest.teams.listMembersInOrg({
org: 'electron',
team_slug: 'wg-releases',
});
const excludedLogins = ['nikwen'];
const memberLogins = new Set(members.map(m => m.login));
for (const login of excludedLogins) {
if (!memberLogins.has(login)) {
core.warning(`Excluded member "${login}" is not in @electron/wg-releases`);
}
}
const eligible = members.filter(m => !excludedLogins.includes(m.login));
if (eligible.length === 0) {
core.warning('No eligible members found in @electron/wg-releases team');
return;
}
const projectId = process.env.PROJECT_ID;
const draftIssues = await actions.getDraftIssues(projectId);
if (draftIssues.length === 0) {
core.info('No draft issues found in the project');
return;
}
// Fisher-Yates shuffle for uniform random assignment
const shuffled = [...eligible];
for (let i = shuffled.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
}
// Assign draft issues round-robin across team members
for (let i = 0; i < draftIssues.length; i++) {
const member = shuffled[i % shuffled.length];
const draftIssue = draftIssues[i];
core.info(`Assigning "${draftIssue.content.title}" to ${member.login}`);
await actions.editItem(projectId, draftIssue.content.id, {
assignees: [member.login],
});
}
core.info(`Assigned ${draftIssues.length} draft issues to ${eligible.length} team members`);
- name: Dump Release Project Board Contents
if: ${{ steps.check-major-version.outputs.MAJOR }}
run: gh project item-list ${{ steps.create-release-board.outputs.number }} --owner electron --format json | jq
@@ -177,7 +231,7 @@ jobs:
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
- name: Find Previous Release Project Board
if: ${{ steps.check-major-version.outputs.MAJOR }}
uses: dsanders11/project-actions/find-project@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
uses: dsanders11/project-actions/find-project@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
id: find-prev-release-board
with:
fail-if-project-not-found: false
@@ -185,7 +239,7 @@ jobs:
token: ${{ steps.generate-token.outputs.token }}
- name: Close Previous Release Project Board
if: ${{ steps.find-prev-release-board.outputs.number }}
uses: dsanders11/project-actions/close-project@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
uses: dsanders11/project-actions/close-project@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
with:
project-number: ${{ steps.find-prev-release-board.outputs.number }}
token: ${{ steps.generate-token.outputs.token }}

View File

@@ -2,25 +2,38 @@ name: Build Git Cache
# This workflow updates git cache on the cross-instance cache volumes
# It runs daily at midnight.
on:
on:
schedule:
- cron: "0 0 * * *"
permissions: {}
jobs:
build-git-cache-linux:
setup:
if: github.repository == 'electron/electron'
runs-on: ubuntu-slim
permissions:
contents: read
outputs:
build-image-sha: ${{ steps.build-image-sha.outputs.build-image-sha }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Set Build Image SHA
id: build-image-sha
uses: ./.github/actions/build-image-sha
build-git-cache-linux:
needs: setup
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read
container:
image: ghcr.io/electron/build:eac3529546ea8f3aa356d31e345715eef342233b
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
options: --user root
volumes:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
env:
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
steps:
- name: Checkout Electron
@@ -34,12 +47,12 @@ jobs:
target-platform: linux
build-git-cache-windows:
if: github.repository == 'electron/electron'
needs: setup
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read
container:
image: ghcr.io/electron/build:eac3529546ea8f3aa356d31e345715eef342233b
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
options: --user root --device /dev/fuse --cap-add SYS_ADMIN
volumes:
- /mnt/win-cache:/mnt/win-cache
@@ -59,14 +72,13 @@ jobs:
target-platform: win
build-git-cache-macos:
if: github.repository == 'electron/electron'
# This job updates the same git cache as linux, so it needs to run after the linux one.
needs: [setup, build-git-cache-linux]
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:eac3529546ea8f3aa356d31e345715eef342233b
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
options: --user root
volumes:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
@@ -82,4 +94,4 @@ jobs:
- name: Build Git Cache
uses: ./src/electron/.github/actions/build-git-cache
with:
target-platform: macos
target-platform: macos

View File

@@ -6,8 +6,8 @@ on:
build-image-sha:
type: string
description: 'SHA for electron/build image'
default: 'eac3529546ea8f3aa356d31e345715eef342233b'
required: true
default: ''
required: false
skip-macos:
type: boolean
description: 'Skip macOS builds'
@@ -48,14 +48,14 @@ permissions: {}
jobs:
setup:
if: github.repository == 'electron/electron'
runs-on: ubuntu-latest
runs-on: ubuntu-slim
permissions:
contents: read
pull-requests: read
outputs:
docs: ${{ steps.filter.outputs.docs }}
src: ${{ steps.filter.outputs.src }}
build-image-sha: ${{ steps.set-output.outputs.build-image-sha }}
build-image-sha: ${{ steps.build-image-sha.outputs.build-image-sha }}
docs-only: ${{ steps.set-output.outputs.docs-only }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
@@ -67,20 +67,21 @@ jobs:
filters: |
docs:
- 'docs/**'
- '.claude/**'
- README.md
- SECURITY.md
- CONTRIBUTING.md
- CODE_OF_CONDUCT.md
src:
- '!docs/**'
- name: Set Outputs for Build Image SHA & Docs Only
- '!{docs,.claude}/**'
- name: Set Build Image SHA
id: build-image-sha
uses: ./.github/actions/build-image-sha
with:
override: ${{ inputs.build-image-sha }}
- name: Set Docs Only
id: set-output
run: |
if [ -z "${{ inputs.build-image-sha }}" ]; then
echo "build-image-sha=eac3529546ea8f3aa356d31e345715eef342233b" >> "$GITHUB_OUTPUT"
else
echo "build-image-sha=${{ inputs.build-image-sha }}" >> "$GITHUB_OUTPUT"
fi
echo "docs-only=${{ steps.filter.outputs.docs == 'true' && steps.filter.outputs.src == 'false' }}" >> "$GITHUB_OUTPUT"
# Lint Jobs
@@ -200,6 +201,15 @@ jobs:
generate-sas-token: 'true'
target-platform: win
# Build a patched siso binary for Windows CI in parallel with checkout-windows.
# The Windows build jobs download the resulting artifact and use it via SISO_PATH.
build-siso-windows:
needs: setup
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }}
uses: ./.github/workflows/pipeline-segment-build-siso-windows.yml
permissions:
contents: read
# GN Check Jobs
macos-gn-check:
uses: ./.github/workflows/pipeline-segment-electron-gn-check.yml
@@ -265,10 +275,11 @@ jobs:
contents: read
issues: read
pull-requests: read
uses: ./.github/workflows/pipeline-electron-build-and-test.yml
uses: ./.github/workflows/pipeline-electron-build-and-tidy-and-test.yml
needs: checkout-macos
with:
build-runs-on: macos-15-xlarge
clang-tidy-runs-on: macos-15-large
test-runs-on: macos-15
target-platform: macos
target-arch: arm64
@@ -383,12 +394,14 @@ jobs:
contents: read
issues: read
pull-requests: read
uses: ./.github/workflows/pipeline-electron-build-and-test.yml
needs: checkout-windows
uses: ./.github/workflows/pipeline-electron-build-and-tidy-and-test.yml
needs: [checkout-windows, build-siso-windows]
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }}
with:
build-runs-on: electron-arc-centralus-windows-amd64-16core
clang-tidy-runs-on: electron-arc-centralus-linux-amd64-8core
test-runs-on: windows-latest
clang-tidy-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-windows.outputs.build-image-sha }}","options":"--user root --device /dev/fuse --cap-add SYS_ADMIN","volumes":["/mnt/win-cache:/mnt/win-cache"]}'
target-platform: win
target-arch: x64
is-release: false
@@ -403,7 +416,7 @@ jobs:
issues: read
pull-requests: read
uses: ./.github/workflows/pipeline-electron-build-and-test.yml
needs: checkout-windows
needs: [checkout-windows, build-siso-windows]
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }}
with:
build-runs-on: electron-arc-centralus-windows-amd64-16core
@@ -422,7 +435,7 @@ jobs:
issues: read
pull-requests: read
uses: ./.github/workflows/pipeline-electron-build-and-test.yml
needs: checkout-windows
needs: [checkout-windows, build-siso-windows]
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }}
with:
build-runs-on: electron-arc-centralus-windows-amd64-16core
@@ -440,9 +453,12 @@ jobs:
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() && github.repository == 'electron/electron' && !contains(needs.*.result, 'failure')
needs: [docs-only, macos-x64, macos-arm64, linux-x64, linux-x64-asan, linux-arm, linux-arm64, build-siso-windows, windows-x64, windows-x86, windows-arm64]
if: always() && github.repository == 'electron/electron'
steps:
- name: Fail if any needed job failed or was cancelled
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
run: exit 1
- name: GitHub Actions Jobs Done
run: |
echo "All GitHub Actions Jobs are done"

View File

@@ -13,13 +13,26 @@ on:
permissions: {}
jobs:
clean-orphaned-uploads:
setup:
if: github.repository == 'electron/electron'
runs-on: ubuntu-slim
permissions:
contents: read
outputs:
build-image-sha: ${{ steps.build-image-sha.outputs.build-image-sha }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Set Build Image SHA
id: build-image-sha
uses: ./.github/actions/build-image-sha
clean-orphaned-uploads:
needs: setup
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read
container:
image: ghcr.io/electron/build:bc2f48b2415a670de18d13605b1cf0eb5fdbaae1
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
options: --user root
volumes:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache

View File

@@ -12,15 +12,28 @@ on:
permissions: {}
jobs:
clean-src-cache:
setup:
if: github.repository == 'electron/electron'
runs-on: ubuntu-slim
permissions:
contents: read
outputs:
build-image-sha: ${{ steps.build-image-sha.outputs.build-image-sha }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Set Build Image SHA
id: build-image-sha
uses: ./.github/actions/build-image-sha
clean-src-cache:
needs: setup
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read
env:
DD_API_KEY: ${{ secrets.DD_API_KEY }}
container:
image: ghcr.io/electron/build:bc2f48b2415a670de18d13605b1cf0eb5fdbaae1
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
options: --user root
volumes:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache

View File

@@ -21,7 +21,7 @@ jobs:
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
org: electron
- name: Set status
uses: dsanders11/project-actions/edit-item@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
uses: dsanders11/project-actions/edit-item@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
with:
token: ${{ steps.generate-token.outputs.token }}
project-number: 90
@@ -42,7 +42,7 @@ jobs:
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
org: electron
- name: Set status
uses: dsanders11/project-actions/edit-item@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
uses: dsanders11/project-actions/edit-item@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
with:
token: ${{ steps.generate-token.outputs.token }}
project-number: 90

View File

@@ -20,7 +20,7 @@ jobs:
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
org: electron
- name: Add to Issue Triage
uses: dsanders11/project-actions/add-item@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
uses: dsanders11/project-actions/add-item@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
with:
field: Reporter
field-value: ${{ github.event.issue.user.login }}
@@ -46,7 +46,7 @@ jobs:
.yarn
- run: yarn workspaces focus @electron/gha-workflows
- name: Add labels
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
id: add-labels
env:
ISSUE_BODY: ${{ github.event.issue.body }}

View File

@@ -20,7 +20,7 @@ jobs:
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
org: electron
- name: Remove from issue triage
uses: dsanders11/project-actions/delete-item@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
uses: dsanders11/project-actions/delete-item@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
with:
token: ${{ steps.generate-token.outputs.token }}
project-number: 90

View File

@@ -33,7 +33,7 @@ jobs:
org: electron
- name: Set status
if: ${{ steps.check-for-blocked-labels.outputs.NOT_BLOCKED }}
uses: dsanders11/project-actions/edit-item@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
uses: dsanders11/project-actions/edit-item@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
with:
token: ${{ steps.generate-token.outputs.token }}
project-number: 90

View File

@@ -6,7 +6,8 @@ on:
build-image-sha:
type: string
description: 'SHA for electron/build image'
default: 'eac3529546ea8f3aa356d31e345715eef342233b'
default: ''
required: false
upload-to-storage:
description: 'Uploads to Azure storage'
required: false
@@ -20,13 +21,28 @@ on:
permissions: {}
jobs:
checkout-linux:
setup:
if: github.repository == 'electron/electron'
runs-on: ubuntu-slim
permissions:
contents: read
outputs:
build-image-sha: ${{ steps.build-image-sha.outputs.build-image-sha }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Set Build Image SHA
id: build-image-sha
uses: ./.github/actions/build-image-sha
with:
override: ${{ inputs.build-image-sha }}
checkout-linux:
needs: setup
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read
container:
image: ghcr.io/electron/build:${{ inputs.build-image-sha }}
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
options: --user root
volumes:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
@@ -50,11 +66,11 @@ jobs:
attestations: write
contents: read
id-token: write
needs: checkout-linux
needs: [setup, checkout-linux]
with:
environment: production-release
build-runs-on: electron-arc-centralus-linux-amd64-32core
build-container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
build-container: '{"image":"ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
target-platform: linux
target-arch: x64
is-release: true
@@ -70,11 +86,11 @@ jobs:
attestations: write
contents: read
id-token: write
needs: checkout-linux
needs: [setup, checkout-linux]
with:
environment: production-release
build-runs-on: electron-arc-centralus-linux-amd64-32core
build-container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
build-container: '{"image":"ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
target-platform: linux
target-arch: arm
is-release: true
@@ -90,11 +106,11 @@ jobs:
attestations: write
contents: read
id-token: write
needs: checkout-linux
needs: [setup, checkout-linux]
with:
environment: production-release
build-runs-on: electron-arc-centralus-linux-amd64-32core
build-container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
build-container: '{"image":"ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
target-platform: linux
target-arch: arm64
is-release: true

View File

@@ -6,8 +6,8 @@ on:
build-image-sha:
type: string
description: 'SHA for electron/build image'
default: 'eac3529546ea8f3aa356d31e345715eef342233b'
required: true
default: ''
required: false
upload-to-storage:
description: 'Uploads to Azure storage'
required: false
@@ -21,13 +21,28 @@ on:
permissions: {}
jobs:
checkout-macos:
setup:
if: github.repository == 'electron/electron'
runs-on: ubuntu-slim
permissions:
contents: read
outputs:
build-image-sha: ${{ steps.build-image-sha.outputs.build-image-sha }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Set Build Image SHA
id: build-image-sha
uses: ./.github/actions/build-image-sha
with:
override: ${{ inputs.build-image-sha }}
checkout-macos:
needs: setup
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read
container:
image: ghcr.io/electron/build:${{ inputs.build-image-sha }}
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
options: --user root
volumes:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache

View File

@@ -0,0 +1,98 @@
name: Pipeline Segment - Build Siso (Windows)
# Builds a patched siso binary for Windows CI. Reads the siso revision from
# the Chromium DEPS file at the pinned chromium_version, shallow-clones
# chromium.googlesource.com/build at that revision, applies the patches under
# .github/siso-patches/, cross-compiles siso.exe for windows/amd64, and
# publishes it as the `siso-windows-amd64` artifact. The Windows build jobs
# download it and use it via SISO_PATH. The built binary is cached keyed on
# the siso revision + sha256 of the patch contents, so subsequent runs just
# restore it.
on:
workflow_call: {}
permissions: {}
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout Electron
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 1
ref: ${{ github.event.pull_request.head.sha }}
sparse-checkout: |
DEPS
.github/siso-patches
- name: Resolve siso revision from Chromium DEPS
id: resolve
run: |
set -euo pipefail
CHROMIUM_VERSION=$(python3 -c "import re; print(re.search(r\"'chromium_version':\s*\n\s*'([^']+)'\", open('DEPS').read()).group(1))")
if ! [[ "$CHROMIUM_VERSION" =~ ^[0-9]+(\.[0-9]+){1,3}$ ]]; then
echo "error: unexpected chromium_version format: $CHROMIUM_VERSION" >&2
exit 1
fi
curl -sfL "https://raw.githubusercontent.com/chromium/chromium/${CHROMIUM_VERSION}/DEPS" -o /tmp/chromium-DEPS
SISO_SHA=$(python3 -c "import re; print(re.search(r\"'siso_version':\s*'git_revision:([0-9a-f]+)'\", open('/tmp/chromium-DEPS').read()).group(1))")
if ! [[ "$SISO_SHA" =~ ^[0-9a-f]{40}$ ]]; then
echo "error: unexpected siso_version SHA: $SISO_SHA" >&2
exit 1
fi
PATCHES_HASH=$(find .github/siso-patches -type f -name '*.patch' | sort | xargs sha256sum | sha256sum | awk '{print $1}')
echo "siso-sha=${SISO_SHA}" >> "$GITHUB_OUTPUT"
echo "patches-hash=${PATCHES_HASH}" >> "$GITHUB_OUTPUT"
echo "Chromium ${CHROMIUM_VERSION} pins siso at ${SISO_SHA}"
echo "Patches hash: ${PATCHES_HASH}"
- name: Restore cached siso binary
id: cache-siso
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: siso-out/siso.exe
key: siso-windows-amd64-${{ steps.resolve.outputs.siso-sha }}-${{ steps.resolve.outputs.patches-hash }}
- name: Shallow clone chromium build repo at pinned revision
if: steps.cache-siso.outputs.cache-hit != 'true'
env:
SISO_SHA: ${{ steps.resolve.outputs.siso-sha }}
run: |
set -euo pipefail
mkdir chromium-build
cd chromium-build
git init -q
git remote add origin https://chromium.googlesource.com/build
git -c protocol.version=2 fetch --depth=1 origin "$SISO_SHA"
git checkout --detach FETCH_HEAD
- name: Apply in-tree siso patches
if: steps.cache-siso.outputs.cache-hit != 'true'
run: |
set -euo pipefail
cd chromium-build
git -c user.name=electron-ci -c user.email=ci@electronjs.org \
am --3way "${GITHUB_WORKSPACE}/.github/siso-patches"/*.patch
- name: Set up Go
if: steps.cache-siso.outputs.cache-hit != 'true'
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version-file: chromium-build/siso/go.mod
cache: false
- name: Build siso (windows/amd64)
if: steps.cache-siso.outputs.cache-hit != 'true'
working-directory: chromium-build/siso
env:
CGO_ENABLED: '0'
GOOS: windows
GOARCH: amd64
run: |
mkdir -p "${GITHUB_WORKSPACE}/siso-out"
go build -trimpath -o "${GITHUB_WORKSPACE}/siso-out/siso.exe" .
- name: Upload siso artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: siso-windows-amd64
path: siso-out/siso.exe
if-no-files-found: error
retention-days: 1

View File

@@ -77,7 +77,6 @@ env:
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 }}
@@ -124,7 +123,7 @@ jobs:
run: df -h
- name: Setup Node.js/npm
if: ${{ inputs.target-platform == 'macos' }}
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
with:
node-version: 22.21.x
cache: yarn
@@ -195,6 +194,22 @@ jobs:
- name: Free up space (macOS)
if: ${{ inputs.target-platform == 'macos' }}
uses: ./src/electron/.github/actions/free-space-macos
- name: Download custom siso binary (Windows)
if: ${{ inputs.target-platform == 'win' }}
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: siso-windows-amd64
path: ${{ runner.temp }}/siso
- name: Set SISO_PATH (Windows)
if: ${{ inputs.target-platform == 'win' }}
run: |
SISO_BIN="${RUNNER_TEMP}/siso/siso.exe"
if [ ! -f "$SISO_BIN" ]; then
echo "error: expected siso binary at $SISO_BIN" >&2
exit 1
fi
echo "SISO_PATH=$SISO_BIN" >> "$GITHUB_ENV"
echo "Using custom siso binary at $SISO_BIN"
- name: Build Electron
if: ${{ inputs.target-platform != 'macos' || (inputs.target-variant == 'all' || inputs.target-variant == 'darwin') }}
uses: ./src/electron/.github/actions/build-electron

View File

@@ -135,15 +135,34 @@ jobs:
run: echo "::add-matcher::src/electron/.github/problem-matchers/clang.json"
- name: Run Clang-Tidy
run: |
e init -f --root=$(pwd) --out=${ELECTRON_OUT_DIR} testing --target-cpu ${TARGET_ARCH}
e init -f --root=$(pwd) --out=${ELECTRON_OUT_DIR} testing --target-cpu ${TARGET_ARCH} --remote-build none
export GN_EXTRA_ARGS="target_cpu=\"${TARGET_ARCH}\""
# For macOS use_remoteexec=false will cause GN errors, so even though we're doing no remote build, set it
export GN_EXTRA_ARGS="use_remoteexec=true target_cpu=\"${TARGET_ARCH}\""
if [ "${{ inputs.target-platform }}" = "win" ]; then
export GN_EXTRA_ARGS="$GN_EXTRA_ARGS use_v8_context_snapshot=true target_os=\"win\""
fi
e build --only-gen
# Copy macOS framework headers so clang-tidy can find them via -F.
# This must happen after e build --only-gen since e init -f may
# recreate the output directory.
if [ "${{ inputs.target-platform }}" = "macos" ]; then
OUT=src/out/${ELECTRON_OUT_DIR}
SQRL=src/third_party/squirrel.mac
mkdir -p ${OUT}/{ReactiveObjC,Squirrel,Mantle}.framework/Headers
cp ${SQRL}/vendor/ReactiveObjC/ReactiveObjC/*.h ${OUT}/ReactiveObjC.framework/Headers/
cp ${SQRL}/vendor/ReactiveObjC/ReactiveObjC/extobjc/*.h ${OUT}/ReactiveObjC.framework/Headers/
cp ${SQRL}/Squirrel/*.h ${OUT}/Squirrel.framework/Headers/
cp ${SQRL}/vendor/Mantle/Mantle/include/*.h ${OUT}/Mantle.framework/Headers/
cp ${SQRL}/vendor/Mantle/Mantle/extobjc/include/*.h ${OUT}/Mantle.framework/Headers/
fi
cd src/electron
node script/yarn.js lint:clang-tidy --jobs 8 --out-dir ../out/${ELECTRON_OUT_DIR}
- name: Remove Clang problem matcher

View File

@@ -130,7 +130,7 @@ jobs:
run: |
for target_cpu in ${{ inputs.target-archs }}
do
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} --import ${{ inputs.gn-build-type }} --target-cpu $target_cpu
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} --import ${{ inputs.gn-build-type }} --target-cpu $target_cpu --remote-build none
cd src
export GN_EXTRA_ARGS="target_cpu=\"$target_cpu\""
if [ "${{ inputs.target-platform }}" = "linux" ]; then

View File

@@ -79,7 +79,6 @@ env:
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' ||
@@ -132,7 +131,7 @@ jobs:
run: df -h
- name: Setup Node.js/npm
if: ${{ inputs.target-platform == 'macos' }}
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
with:
node-version: 22.21.x
cache: yarn
@@ -208,6 +207,22 @@ jobs:
- name: Free up space (macOS)
if: ${{ inputs.target-platform == 'macos' }}
uses: ./src/electron/.github/actions/free-space-macos
- name: Download custom siso binary (Windows)
if: ${{ inputs.target-platform == 'win' }}
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
with:
name: siso-windows-amd64
path: ${{ runner.temp }}/siso
- name: Set SISO_PATH (Windows)
if: ${{ inputs.target-platform == 'win' }}
run: |
SISO_BIN="${RUNNER_TEMP}/siso/siso.exe"
if [ ! -f "$SISO_BIN" ]; then
echo "error: expected siso binary at $SISO_BIN" >&2
exit 1
fi
echo "SISO_PATH=$SISO_BIN" >> "$GITHUB_ENV"
echo "Using custom siso binary at $SISO_BIN"
- name: Build Electron
if: ${{ inputs.target-platform != 'macos' || (inputs.target-variant == 'all' ||
inputs.target-variant == 'darwin') }}

View File

@@ -79,7 +79,7 @@ jobs:
cp $(which node) /mnt/runner-externals/node24/bin/
- name: Setup Node.js/npm
if: ${{ inputs.target-platform == 'win' }}
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
with:
node-version: 22.21.x
- name: Add TCC permissions on macOS
@@ -315,7 +315,7 @@ jobs:
if: always() && !cancelled()
- name: Upload Test Artifacts
if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f #v7.0.0
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a #v7.0.1
with:
name: ${{ inputs.target-platform == 'linux' && format('test_artifacts_{0}_{1}_{2}', env.ARTIFACT_KEY, inputs.display-server, matrix.shard) || format('test_artifacts_{0}_{1}', env.ARTIFACT_KEY, matrix.shard) }}
path: src/electron/spec/artifacts

View File

@@ -25,7 +25,7 @@ jobs:
sparse-checkout: .github/PULL_REQUEST_TEMPLATE.md
sparse-checkout-cone-mode: false
- name: Check for required sections
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const fs = require('fs');
@@ -38,6 +38,12 @@ jobs:
return;
}
const body = context.payload.pull_request.body || '';
// Allow through if body contains a valid backport line
const backportRegex = /Backport of (?:#|https:\/\/github.com\/electron\/electron\/pull\/)\d+/i;
if (backportRegex.test(body)) {
console.log('Backport PR detected, skipping required section check.');
return;
}
const missingSections = requiredSections.filter(
(section) => !body.includes(section),
);

View File

@@ -36,8 +36,18 @@ jobs:
with:
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
org: electron
- name: Get project item status
uses: dsanders11/project-actions/get-item@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
id: get-item
with:
token: ${{ steps.generate-token.outputs.token }}
project-number: 118
fail-if-item-not-found: false
- name: Set status to Needs Review
uses: dsanders11/project-actions/edit-item@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
if: >-
(steps.get-item.outputs.field-status == '🛑 Needs Submitter Response'
|| steps.get-item.outputs.field-status == '🟡 WIP')
uses: dsanders11/project-actions/edit-item@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
with:
token: ${{ steps.generate-token.outputs.token }}
project-number: 118

View File

@@ -42,7 +42,7 @@ jobs:
creds: ${{ secrets.RELEASE_BOARD_GH_APP_CREDS }}
org: electron
- name: Set status
uses: dsanders11/project-actions/edit-item@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
uses: dsanders11/project-actions/edit-item@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
with:
token: ${{ steps.generate-token.outputs.token }}
project-number: 94

View File

@@ -8,6 +8,7 @@ on:
paths:
- 'DEPS'
- 'patches/**'
- '.github/siso-patches/**'
permissions: {}

View File

@@ -43,7 +43,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: SARIF file
path: results.sarif
@@ -51,6 +51,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@c10b8064de6f491fea524254123dbe5e09572f13 # v3.29.5
uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v3.29.5
with:
sarif_file: results.sarif

View File

@@ -29,7 +29,7 @@ jobs:
PROJECT_NUMBER=$(gh project list --owner electron --format json | jq -r '.projects | map(select(.title | test("^[0-9]+-x-y$"))) | max_by(.number) | .number')
echo "PROJECT_NUMBER=$PROJECT_NUMBER" >> "$GITHUB_OUTPUT"
- name: Update Completed Stable Prep Items
uses: dsanders11/project-actions/completed-by@5767984408ccc6742f83acc8b8d8ea5e09f329af # v2.0.0
uses: dsanders11/project-actions/completed-by@4b06452b0128cf601dac14399aa668a8eed2d684 # v2.0.1
with:
field: Prep Status
field-value: ✅ Complete

View File

@@ -6,8 +6,8 @@ on:
build-image-sha:
type: string
description: 'SHA for electron/build image'
default: 'eac3529546ea8f3aa356d31e345715eef342233b'
required: true
default: ''
required: false
upload-to-storage:
description: 'Uploads to Azure storage'
required: false
@@ -21,13 +21,28 @@ on:
permissions: {}
jobs:
checkout-windows:
setup:
if: github.repository == 'electron/electron'
runs-on: ubuntu-slim
permissions:
contents: read
outputs:
build-image-sha: ${{ steps.build-image-sha.outputs.build-image-sha }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Set Build Image SHA
id: build-image-sha
uses: ./.github/actions/build-image-sha
with:
override: ${{ inputs.build-image-sha }}
checkout-windows:
needs: setup
runs-on: electron-arc-centralus-linux-amd64-32core
permissions:
contents: read
container:
image: ghcr.io/electron/build:${{ inputs.build-image-sha }}
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
options: --user root --device /dev/fuse --cap-add SYS_ADMIN
volumes:
- /mnt/win-cache:/mnt/win-cache
@@ -37,8 +52,6 @@ jobs:
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_win=True'
TARGET_OS: 'win'
ELECTRON_DEPOT_TOOLS_WIN_TOOLCHAIN: '1'
outputs:
build-image-sha: ${{ inputs.build-image-sha }}
steps:
- name: Checkout Electron
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
@@ -51,6 +64,14 @@ jobs:
generate-sas-token: 'true'
target-platform: win
# Build the patched siso binary in parallel with checkout-windows; the
# publish-*-win jobs consume it via SISO_PATH.
build-siso-windows:
needs: setup
uses: ./.github/workflows/pipeline-segment-build-siso-windows.yml
permissions:
contents: read
publish-x64-win:
uses: ./.github/workflows/pipeline-segment-electron-publish.yml
permissions:
@@ -58,7 +79,7 @@ jobs:
attestations: write
contents: read
id-token: write
needs: checkout-windows
needs: [checkout-windows, build-siso-windows]
with:
environment: production-release
build-runs-on: electron-arc-centralus-windows-amd64-16core
@@ -77,7 +98,7 @@ jobs:
attestations: write
contents: read
id-token: write
needs: checkout-windows
needs: [checkout-windows, build-siso-windows]
with:
environment: production-release
build-runs-on: electron-arc-centralus-windows-amd64-16core
@@ -96,7 +117,7 @@ jobs:
attestations: write
contents: read
id-token: write
needs: checkout-windows
needs: [checkout-windows, build-siso-windows]
with:
environment: production-release
build-runs-on: electron-arc-centralus-windows-amd64-16core

82
.yarn/README.md Normal file
View File

@@ -0,0 +1,82 @@
# Vendored Yarn release
This directory holds the Yarn release used by this repo (`yarnPath` in
`.yarnrc.yml`). The release file is checked in so every contributor and CI job
runs the exact same Yarn, and so we can carry small local patches when needed.
`releases/yarn-4.12.0.cjs` currently carries one such patch, described below.
If you bump the Yarn version, read the **Upgrading Yarn** section first.
## Patch: use `JsZipImpl` for the node-modules link step
### What changed
Two call sites in `releases/yarn-4.12.0.cjs` are modified so the
`node-modules` linker (and the `pnpm`-loose linker) construct their read-only
`ZipOpenFS` with `customZipImplementation: ST` — Yarn's pure-JS `JsZipImpl`
instead of falling through to the default WASM-backed `LibZipImpl`:
```text
new $f({maxOpenFiles:80,readOnlyArchives:!0})
→ new $f({maxOpenFiles:80,readOnlyArchives:!0,customZipImplementation:ST})
```
A comment block at the top of the `.cjs` file marks the file as patched and
points back here.
### Why
On the `linux-arm` CI test shards we run a 32-bit `arm32v7` container. During
`yarn install`'s **Link step**, Yarn opens up to 80 cache zips concurrently.
With `LibZipImpl`, each open zip is `readFileSync`'d into a Node `Buffer`
**and copied again into the WASM linear memory**, and every file read does a
WASM `_malloc(size)` for the entry. The WASM heap has to grow as a single
contiguous region of the 32-bit address space; once enough zips are resident,
the `_malloc` for a large entry — most often `typescript/lib/typescript.js`
(~9 MB inside a ~22 MB zip) — fails.
Yarn's cross-FS `copyFilePromise` swallows the underlying error and re-throws
a generic one, so CI shows:
```text
YN0001: While persisting .../typescript-patch-...zip/node_modules/typescript/
EINVAL: invalid argument, copyfile '/node_modules/typescript/lib/typescript.js' -> '...'
```
The unmasked form (occasionally seen on `pdfjs-dist`) is the WASM-heap failure
string `Couldn't allocate enough memory`. This started failing ~1-in-3
`linux-arm / test` shards at **Install Dependencies** on 2026-04-13, after
[#50692](https://github.com/electron/electron/pull/50692) grew the cache enough
to push the 32-bit process over the edge nondeterministically — e.g.
[run 24739817558](https://github.com/electron/electron/actions/runs/24739817558/job/72380803746).
`JsZipImpl` avoids the problem entirely: it opens the zip by file descriptor,
reads only the central directory into memory, and `readSync`s individual
entries into ordinary Node `Buffer`s — **no WASM heap involved**. It is
read-only and path-based, which is exactly how the linker uses these archives.
There is no `.yarnrc.yml` setting or environment variable to select the zip
implementation (verified against the bundle), so editing the vendored release
is the only way to switch it short of re-implementing the linker in a plugin.
Upstream references:
[yarnpkg/berry#3972](https://github.com/yarnpkg/berry/issues/3972),
[yarnpkg/berry#6722](https://github.com/yarnpkg/berry/issues/6722),
[yarnpkg/berry#6550](https://github.com/yarnpkg/berry/issues/6550).
### Upgrading Yarn
When bumping `releases/yarn-*.cjs`:
1. Check whether upstream now defaults `readOnlyArchives` opens to `JsZipImpl`,
or exposes a config knob for the zip implementation. If so, drop this patch.
2. Otherwise, re-apply: search the new bundle for
`maxOpenFiles:80,readOnlyArchives:!0` (the surrounding minified identifiers
will differ) and add `,customZipImplementation:<JsZipImpl symbol>` — that
symbol is whatever the new bundle exports as `JsZipImpl` from
`@yarnpkg/libzip`.
3. Re-add the header comment pointing back to this README.
4. Verify with
`rm -rf node_modules spec/node_modules && node script/yarn.js install --immutable --mode=skip-build`
and confirm `node_modules/typescript/lib/typescript.js` is byte-identical to
an unpatched install.

View File

@@ -0,0 +1,26 @@
diff --git a/lib/marshall.js b/lib/marshall.js
index 5a7434162d97208ec34fb87bfce3c953fd90345a..86f0efd9d0c99ecb3ae4d12c46130778f813ac5b 100644
--- a/lib/marshall.js
+++ b/lib/marshall.js
@@ -1,7 +1,7 @@
const assert = require('assert');
const parseSignature = require('./signature');
-const put = require('put');
+const put = require('@nornagon/put');
const Marshallers = require('./marshallers');
const align = require('./align').align;
diff --git a/package.json b/package.json
index 2519ac38fad44569cb8a156a91af25a70c8166a5..f7d88ac6cdb00a0a7064b0e39986821816c75554 100644
--- a/package.json
+++ b/package.json
@@ -42,7 +42,7 @@
"hexy": "^0.2.10",
"long": "^4.0.0",
"optimist": "^0.6.1",
- "put": "0.0.6",
+ "@nornagon/put": "0.0.8",
"safe-buffer": "^5.1.1",
"xml2js": "^0.4.17"
},

File diff suppressed because one or more lines are too long

View File

@@ -105,21 +105,25 @@ electron_mac_bundle_id = branding.mac_bundle_id
if (override_electron_version != "") {
electron_version = override_electron_version
} else {
# When building from source code tarball there is no git tag available and
# When building from a source code tarball there is no git tag available and
# builders must explicitly pass override_electron_version in gn args.
#
# Resolve the real locations of packed-refs and HEAD via git so that this
# also works when electron/ is a `git worktree` (where .git is a file, not a
# directory, and GN's read_file cannot follow the gitdir indirection).
electron_git_ref_paths =
exec_script("script/get-git-ref-paths.py", [], "list lines")
# This read_file call will assert if there is no git information, without it
# gn will generate a malformed build configuration and ninja will get into
# infinite loop.
read_file(".git/packed-refs", "string")
read_file(electron_git_ref_paths[0], "string")
# Set electron version from git tag.
electron_version = exec_script("script/get-git-version.py",
[],
"trim string",
[
".git/packed-refs",
".git/HEAD",
])
electron_git_ref_paths)
}
if (is_mas_build) {
@@ -495,8 +499,10 @@ source_set("electron_lib") {
"//components/certificate_transparency",
"//components/compose:buildflags",
"//components/embedder_support:user_agent",
"//components/heap_profiling/multi_process",
"//components/input",
"//components/language/core/browser",
"//components/memory_system",
"//components/net_log",
"//components/network_hints/browser",
"//components/network_hints/common:mojo_bindings",
@@ -509,6 +515,7 @@ source_set("electron_lib") {
"//components/pref_registry",
"//components/prefs",
"//components/security_state/content",
"//components/tracing:tracing_metrics",
"//components/upload_list",
"//components/user_prefs",
"//components/viz/host",
@@ -794,7 +801,7 @@ source_set("electron_lib") {
"//components/zoom",
"//extensions/browser",
"//extensions/browser/api:api_provider",
"//extensions/browser/mime_handler:stream_info",
"//extensions/browser/mime_handler",
"//extensions/browser/updater",
"//extensions/common",
"//extensions/common:core_api_provider",
@@ -1663,8 +1670,9 @@ action("node_version_header") {
action("generate_node_headers") {
deps = [ ":generate_config_gypi" ]
script = "script/node/generate_node_headers.py"
args = [ rebase_path("$root_gen_dir") ]
inputs = auto_filenames.node_header_sources
outputs = [ "$root_gen_dir/node_headers.json" ]
args = [ rebase_path("$root_gen_dir") ]
}
action("tar_node_headers") {

4
DEPS
View File

@@ -2,9 +2,9 @@ gclient_gn_args_from = 'src'
vars = {
'chromium_version':
'148.0.7778.0',
'149.0.7811.0',
'node_version':
'v24.14.1',
'v24.15.0',
'nan_version':
'675cefebca42410733da8a454c8d9391fcebfbc2',
'squirrel.mac_version':

View File

@@ -63,10 +63,6 @@ v8_enable_private_mapping_fork_optimization = true
# Expose public V8 symbols for native modules.
v8_expose_public_symbols = true
# Disable snapshotting a page when printing for its content to be analyzed for
# sensitive content by enterprise users.
enterprise_cloud_content_analysis = false
# We don't use anything from here, and it causes target collisions
enable_linux_installer = false

View File

@@ -0,0 +1,87 @@
#!/usr/bin/env python3
#
# Copyright (c) 2026 GitHub, Inc.
# Use of this source code is governed by the MIT license that can be
# found in the LICENSE file.
"""Wrapper for lld-link that resolves relative paths to absolute.
Usage: abs_link_wrapper.py <lld-link> <args...>
The first argument is the real linker executable. The script resolves
relative .obj/.rlib/.res/.lib paths in both @rspfile contents and direct
command-line arguments to absolute paths, then invokes the real linker.
"""
import os
import subprocess
import sys
def _is_file_path(token):
"""Check if a token looks like a relative file path (not a flag or bare lib name)."""
# Strip surrounding quotes
t = token.strip('"')
# Linker flags start with / or -
if t.startswith('/') or t.startswith('-'):
return False
# Must contain a directory separator to be a relative path.
# Bare names like "advapi32.lib" are system libraries resolved via
# -libpath: or /winsysroot and must not be turned into absolute paths.
if '/' not in t and '\\' not in t:
return False
# File extensions we care about
return t.endswith(('.obj', '.res', '.lib', '.a', '.o', '.rlib'))
def _resolve_rsp(rsp_path):
"""Rewrite relative file paths in the rsp file to absolute paths."""
with open(rsp_path, 'r') as f:
content = f.read()
lines = []
changed = False
for line in content.splitlines():
tokens = []
for token in line.split():
stripped = token.strip('"')
if _is_file_path(token) and not os.path.isabs(stripped):
abs_path = os.path.abspath(stripped)
tokens.append('"' + abs_path + '"')
changed = True
else:
tokens.append(token)
lines.append(' '.join(tokens))
if not changed:
return rsp_path
abs_rsp = rsp_path + '.abs'
with open(abs_rsp, 'w') as f:
f.write('\n'.join(lines))
return abs_rsp
def _resolve_arg(arg):
"""Resolve a single command-line argument if it's a relative file path."""
stripped = arg.strip('"')
if _is_file_path(arg) and not os.path.isabs(stripped):
return os.path.abspath(stripped)
return arg
def main():
args = []
for arg in sys.argv[1:]:
if arg.startswith('@'):
rsp_path = arg[1:].strip('"')
resolved = _resolve_rsp(rsp_path)
args.append('@' + resolved)
else:
args.append(_resolve_arg(arg))
return subprocess.call(args)
if __name__ == '__main__':
sys.exit(main())

View File

@@ -21,6 +21,8 @@ static_library("chrome") {
"//chrome/browser/browser_features.h",
"//chrome/browser/browser_process.cc",
"//chrome/browser/browser_process.h",
"//chrome/browser/device_notifications/device_connection_tracker.h",
"//chrome/browser/device_notifications/device_system_tray_icon.h",
"//chrome/browser/devtools/devtools_contents_resizing_strategy.cc",
"//chrome/browser/devtools/devtools_contents_resizing_strategy.h",
"//chrome/browser/devtools/devtools_dispatch_http_request_params.cc",
@@ -38,6 +40,7 @@ static_library("chrome") {
"//chrome/browser/devtools/visual_logging.h",
"//chrome/browser/file_system_access/file_system_access_features.cc",
"//chrome/browser/file_system_access/file_system_access_features.h",
"//chrome/browser/hid/hid_system_tray_icon.h",
"//chrome/browser/icon_loader.cc",
"//chrome/browser/icon_loader.h",
"//chrome/browser/icon_manager.cc",
@@ -156,6 +159,7 @@ static_library("chrome") {
"//chrome/browser/ui/webui/accessibility/accessibility_ui.h",
"//chrome/browser/usb/usb_blocklist.cc",
"//chrome/browser/usb/usb_blocklist.h",
"//chrome/browser/usb/usb_system_tray_icon.h",
"//extensions/browser/app_window/size_constraints.cc",
"//extensions/browser/app_window/size_constraints.h",
"//ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.cc",
@@ -247,10 +251,6 @@ static_library("chrome") {
"//chrome/browser/ui/views/dark_mode_manager_linux.cc",
"//chrome/browser/ui/views/dark_mode_manager_linux.h",
]
sources += [
"//chrome/browser/ui/views/frame/browser_frame_view_paint_utils_linux.cc",
"//chrome/browser/ui/views/frame/browser_frame_view_paint_utils_linux.h",
]
public_deps += [ "//components/dbus" ]
}
@@ -389,16 +389,17 @@ static_library("chrome") {
"//chrome/browser/pdf/chrome_pdf_stream_delegate.h",
"//chrome/browser/pdf/pdf_extension_util.cc",
"//chrome/browser/pdf/pdf_extension_util.h",
"//chrome/browser/pdf/pdf_handler_stream_delegate.cc",
"//chrome/browser/pdf/pdf_handler_stream_delegate.h",
"//chrome/browser/pdf/pdf_help_bubble_handler_factory.cc",
"//chrome/browser/pdf/pdf_help_bubble_handler_factory.h",
"//chrome/browser/pdf/pdf_viewer_stream_manager.cc",
"//chrome/browser/pdf/pdf_viewer_stream_manager.h",
"//chrome/browser/plugins/pdf_iframe_navigation_throttle.cc",
"//chrome/browser/plugins/pdf_iframe_navigation_throttle.h",
]
deps += [
"//components/pdf/browser",
"//components/pdf/renderer",
"//components/zoom",
"//ui/base/interaction",
"//ui/webui/resources/cr_components/help_bubble:mojo_bindings",
]

View File

@@ -124,4 +124,65 @@ Returns `Promise<Object>` - Resolves with an object containing the `value` and `
Get the maximum usage across processes of trace buffer as a percentage of the
full state.
### `contentTracing.enableHeapProfiling([options])` _Experimental_
<!--
```YAML history
added:
- pr-url: https://github.com/electron/electron/pull/50826
```
-->
* `options` ([EnableHeapProfilingOptions](structures/enable-heap-profiling-options.md)) (optional)
Returns `Promise<void>` - Resolves once heap profiling has been enabled.
Enable [heap profiling](https://chromium.googlesource.com/chromium/src/+/lkgr/docs/memory-infra/heap_profiler.md)
for MemoryInfra traces. Equivalent to the `--memlog` switch in Chrome.
Only takes effect if the `disabled-by-default-memory-infra` category is included.
Needs to be called before `contentTracing.startRecording()`.
Usage:
```js
const { contentTracing } = require('electron')
async function recordTrace () {
await contentTracing.enableHeapProfiling()
await contentTracing.startRecording({
included_categories: ['disabled-by-default-memory-infra'],
excluded_categories: ['*'],
memory_dump_config: {
triggers: [
{ mode: 'detailed', periodic_interval_ms: 1000 }
]
}
})
await new Promise(resolve => setTimeout(resolve, 5000))
const filePath = await contentTracing.stopRecording()
}
```
To view the recorded heap dumps:
1. Download the breakpad symbols for your Electron version from the Electron GitHub
[releases](https://github.com/electron/electron/releases)
2. Clone the [Electron source code](../development/build-instructions-gn.md)
3. In your Chromium checkout for Electron, run this command to symbolicate the heap dump:
```bash
python3 third_party/catapult/tracing/bin/symbolize_trace --use-breakpad-symbols --breakpad-symbols-directory /path/to/breakpad_symbols /path/to/trace.json
```
4. Open the symbolicated trace in `chrome://tracing` (the Perfetto UI does not support memory dumps
yet)
5. Click on one of the `M` symbols
6. Click on a `` triple bar icon (e.g., in the `malloc` column)
<img src="../images/viewing-heap-dumps.png" alt="Screenshot showing how to view a heapdump in Chromium's tracing view" />
[trace viewer]: https://chromium.googlesource.com/catapult/+/HEAD/tracing/README.md

View File

@@ -203,13 +203,22 @@ the one downloaded by `npm install`. Usage:
export ELECTRON_OVERRIDE_DIST_PATH=/Users/username/projects/electron/out/Testing
```
### `ELECTRON_SKIP_BINARY_DOWNLOAD`
### `ELECTRON_INSTALL_PLATFORM`
If you want to install your project's dependencies but don't need to use Electron functionality,
you can set the `ELECTRON_SKIP_BINARY_DOWNLOAD` environment variable to prevent the binary from being
downloaded. For instance, this feature can be useful in continuous integration environments when
running unit tests that mock out the `electron` module.
Manually overrides platform used by `electron` package during an install.
This can be useful if you are on one platform (e.g macOS) but want to
download binaries for another platform (e.g Windows or Linux). Usage:
```sh
ELECTRON_SKIP_BINARY_DOWNLOAD=1 npm install
ELECTRON_INSTALL_PLATFORM=darwin npm install
```
### `ELECTRON_INSTALL_ARCH`
Manually overrides architecture used by `electron` package during an install.
This can be useful if you are on one arch (e.g `arm64`) but want to download
binaries meant for another arch. Note that this will not work under Rosetta. Usage:
```sh
ELECTRON_INSTALL_ARCH=arm64 npm install
```

View File

@@ -76,6 +76,45 @@ app.whenReady().then(() => {
})
```
#### `Notification.getHistory()` _macOS_
Returns `Promise<Notification[]>` - Resolves with an array of `Notification` objects representing all delivered notifications still present in Notification Center.
Each returned `Notification` is a live object connected to the corresponding delivered notification. Interaction events (`click`, `reply`, `action`, `close`) will fire on these objects when the user interacts with the notification in Notification Center. This is useful after an app restart to re-attach event handlers to notifications from a previous session.
The returned notifications have their `id`, `groupId`, `title`, `subtitle`, and `body` properties populated from information available in the Notification Center. Other properties (e.g., `actions`, `silent`, `icon`) are not available from delivered notifications and will have default values.
> [!NOTE]
> Like all macOS notification APIs, this method requires the application to be
> code-signed. In unsigned development builds, notifications are not delivered
> to Notification Center and this method will resolve with an empty array.
> [!NOTE]
> Unlike notifications created with `new Notification()`, notifications returned
> by `getHistory()` will remain visible in Notification Center when the object
> is garbage collected. Calling `show()` on a restored notification will remove
> the original from Notification Center and post a new one with the same
> properties.
```js
const { Notification, app } = require('electron')
app.whenReady().then(async () => {
// Restore notifications from a previous session
const notifications = await Notification.getHistory()
for (const n of notifications) {
console.log(`Found delivered notification: ${n.id} - ${n.title}`)
n.on('click', () => {
console.log(`User clicked: ${n.id}`)
})
n.on('reply', (event) => {
console.log(`User replied to ${n.id}: ${event.reply}`)
})
}
// Keep references so events continue to fire
})
```
### `new Notification([options])`
* `options` Object (optional)
@@ -292,6 +331,10 @@ call this method before the OS will display it.
If the notification has been shown before, this method will dismiss the previously
shown notification and create a new one with identical properties.
On macOS, calling `show()` on a notification returned by `Notification.getHistory()` will
remove the original notification from Notification Center and post a new one with the same
properties.
```js
const { Notification, app } = require('electron')

View File

@@ -650,7 +650,7 @@ Clears the sessions HTTP cache.
`scheme://host:port`.
* `storages` string[] (optional) - The types of storages to clear, can be
`cookies`, `filesystem`, `indexdb`, `localstorage`,
`shadercache`, `websql`, `serviceworkers`, `cachestorage`. If not
`shadercache`, `serviceworkers`, `cachestorage`. If not
specified, clear all storage types.
Returns `Promise<void>` - resolves when the storage data has been cleared.

View File

@@ -0,0 +1,26 @@
# EnableHeapProfilingOptions Object
* `mode` string (optional) - Controls which processes are profiled. Equivalent to `--memlog` in
Chrome. Default is `all`.
* `all` - Profile all processes.
* `browser` - Profile only the browser process.
* `gpu` - Profile only the GPU process.
* `minimal` - Profile only the browser and GPU processes.
* `renderer-sampling` - Profile at most 1 renderer process. Each renderer process has a fixed
probability of being profiled when the renderer process is started or, for existing processes,
when heap profiling is enabled.
* `all-renderers` - Profile all renderer processes.
* `utility-sampling` - Each utility process has a fixed probability of being profiled.
* `all-utilities` - Profile all utility processes.
* `utility-and-browser` - Profile all utility processes and the browser process.
* `samplingRate` number (optional) - Controls the sampling interval in bytes. The lower the
interval, the more precise the profile is. However it comes at the cost of performance. Default
is `100000` (100KB). That is enough to observe allocation sites that make allocations >500KB
total, where total equals to a single allocation size times the number of such allocations at the
same call site. Equivalent to `--memlog-sampling-rate` in Chrome. Must be an integer between
`1000` and `10000000`.
* `stackMode` string (optional) - Controls the type of metadata recorded for each allocation.
Equivalent to `--memlog-stack-mode` in Chrome. Default is `native`.
* `native` - Instruction addresses from unwinding the stack.
* `native-with-thread-names` - Instruction addresses from unwinding the stack. Includes the thread
name as the first frame.

View File

@@ -5,6 +5,7 @@
* `rgba` - 32bpp RGBA (byte-order), 1 plane.
* `rgbaf16` - Half float RGBA, 1 plane.
* `nv12` - 12bpp with Y plane followed by a 2x2 interleaved UV plane.
* `nv16` - 16bpp with Y plane followed by a 2x1 interleaved UV plane.
* `p010le` - 4:2:0 10-bit YUV (little-endian), Y plane followed by a 2x2 interleaved UV plane.
* `colorSpace` [ColorSpace](color-space.md) (optional) - The color space of the texture.
* `codedSize` [Size](size.md) - The full dimensions of the shared texture.

View File

@@ -2275,6 +2275,20 @@ Returns `Integer` - The Chromium internal `pid` of the associated renderer. Can
be compared to the `frameProcessId` passed by frame specific navigation events
(e.g. `did-frame-navigate`)
#### `contents.clone()`
Returns `WebContents` - A cloned WebContents instance. This method creates a copy
of the WebContents with the following attributes:
* **WebPreferences** - All preferences from the original WebContents are copied
* **SiteInstance** - Uses the same SiteInstance as the original. This means the cloned WebContents will reuse the same render process as the original when loading same-origin pages, and only spawn a new render process for cross-origin navigations. This process allocation behavior is consistent with window.open and tab duplication in Chromium. For more details, see [Chromium's Site Isolation](https://www.chromium.org/developers/design-documents/site-isolation/) design document.
* **Opener relationship** - Inherits the opener (window.opener) relationship
* **Navigation state** - Copies the navigation history and controller state
The cloned WebContents is an independent instance with its own lifecycle that can be destroyed separately and will not contain any open web pages.
This API is useful for use cases where you want to create a new WebContents that shares the same render process with the original for same-origin content, while maintaining full lifecycle independence. Additionally, reusing the existing render process can help optimize memory usage and page load speed to a certain extent, as it eliminates the overhead of spawning and initializing a new render process from scratch.
#### `contents.takeHeapSnapshot(filePath)`
* `filePath` string - Path to the output file.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@@ -2,28 +2,53 @@
Electron frequently releases major versions alongside every other Chromium release.
This document focuses on the release cadence and version support policy.
For a more in-depth guide on our git branches and how Electron uses semantic versions,
check out our [Electron Versioning](./electron-versioning.md) doc.
> [!TIP]
> See the [Electron Versioning](./electron-versioning.md) document for more details
> on how Electron is versioned.
## Timeline
[Electron's Release Schedule](https://releases.electronjs.org/schedule) lists a schedule of Electron major releases showing key milestones including alpha, beta, and stable release dates, as well as end-of-life dates and dependency versions.
:::info Official support dates may change
> [!IMPORTANT]
> Electron's official support policy is the latest 3 stable releases. Our stable
> release and end-of-life dates are determined by Chromium, and may be subject to
> change. While we try to keep our planned release and end-of-life dates frequently
> updated here, future dates may change if affected by upstream scheduling changes,
> and may not always be accurately reflected.
>
> See [Chromium's public release schedule](https://chromiumdash.appspot.com/schedule) for
> definitive information about Chromium's scheduled release dates.
Electron's official support policy is the latest 3 stable releases. Our stable
release and end-of-life dates are determined by Chromium, and may be subject to
change. While we try to keep our planned release and end-of-life dates frequently
updated here, future dates may change if affected by upstream scheduling changes,
and may not always be accurately reflected.
Electron's cadence between major version releases is 8 weeks long. Before each major
version hits stable, it goes through a four-week **alpha** phase and a four-week
**beta** phase.
See [Chromium's public release schedule](https://chromiumdash.appspot.com/schedule) for
definitive information about Chromium's scheduled release dates.
:::
```mermaid
gantt
title Electron release cycle
dateFormat YYYY-MM-DD
axisFormat Week %W
todayMarker off
section v41
Alpha phase :a1, 2026-01-19, 4w
M146 enters Chrome beta :milestone, bm1, after a1, 0d
Beta phase :b1, after a1, 4w
M146 enters Chrome stable :milestone, s1, after b1, 0d
Supported until v44 release :active, after b1, 12w
section v42
Alpha phase :a2, after b1, 4w
M148 enters Chrome beta :milestone, bm2, after a2, 0d
Beta phase :b2, after a2, 4w
M148 enters Chrome stable :milestone, s2, after b2, 0d
Supported until v45 release :active, after b2, 4w
```
**Notes:**
* Alphas are generally less stable than beta releases. The cutoff between the two
corresponds to when the underlying Chromium version enters Chrome's Beta channel.
* The `-alpha.1`, `-beta.1`, and `stable` dates are our solid release dates.
* We strive for weekly alpha/beta releases, but we often release more than scheduled.
* All dates are our goals but there may be reasons for adjusting the stable deadline, such as security bugs.
@@ -38,10 +63,11 @@ and may not always be accurately reflected.
## Version support policy
The latest three _stable_ major versions are supported by the Electron team.
For example, if the latest release is 6.1.x, then the 5.0.x as well
as the 4.2.x series are supported. We only support the latest minor release
For example, if the latest release is 42.1.x, then the 41.0.x as well
as the 40.2.x series are supported. We only support the latest minor release
for each stable release series. This means that in the case of a security fix,
6.1.x will receive the fix, but we will not release a new version of 6.0.x.
42.1.x will receive the fix, but we will not release a new version of 42.0.x.
The latest stable release unilaterally receives all fixes from `main`,
and the version prior to that receives the vast majority of those fixes
@@ -50,11 +76,8 @@ only security fixes directly.
### Chromium version support
:::info Chromium release schedule
Chromium's public release schedule is [here](https://chromiumdash.appspot.com/schedule).
:::
> [!TIP]
> Chromium's public release schedule is [here](https://chromiumdash.appspot.com/schedule).
Electron targets Chromium even-number versions, releasing every 8 weeks in concert
with Chromium's 4-week release schedule. For example, Electron 26 uses Chromium 116, while Electron 27 uses Chromium 118.
@@ -82,3 +105,7 @@ and that number is reduced to two in major version 10, the three-argument versio
continue to work until, at minimum, major version 12. Past the minimum two-version
threshold, we will attempt to support backwards compatibility beyond two versions
until the maintainers feel the maintenance burden is too high to continue doing so.
> [!TIP]
> For a canonical list of breaking changes, see the [Breaking Changes](../breaking-changes.md)
> document.

View File

@@ -14,18 +14,6 @@ To update an existing project to use the latest stable version:
npm install --save-dev electron@latest
```
## Versioning scheme
There are several major changes from our 1.x strategy outlined below. Each change is intended to satisfy the needs and priorities of developers/maintainers and app developers.
1. Strict use of the [SemVer](#semver) spec
2. Introduction of semver-compliant `-beta` tags
3. Introduction of [conventional commit messages](https://conventionalcommits.org/)
4. Well-defined stabilization branches
5. The `main` branch is versionless; only stabilization branches contain version information
We will cover in detail how git branching works, how npm tagging works, what developers should expect to see, and how one can backport changes.
## SemVer
Below is a table explicitly mapping types of changes to their corresponding category of SemVer (e.g. Major, Minor, Patch).
@@ -34,7 +22,7 @@ Below is a table explicitly mapping types of changes to their corresponding cate
| ------------------------------- | ---------------------------------- | ----------------------------- |
| Electron breaking API changes | Electron non-breaking API changes | Electron bug fixes |
| Node.js major version updates | Node.js minor version updates | Node.js patch version updates |
| Chromium version updates | | fix-related chromium patches |
| Chromium version updates | | fix-related Chromium patches |
For more information, see the [Semantic Versioning 2.0.0](https://semver.org/) spec.
@@ -44,68 +32,189 @@ Note that most Chromium updates will be considered breaking. Fixes that can be b
Stabilization branches are branches that run parallel to `main`, taking in only cherry-picked commits that are related to security or stability. These branches are never merged back to `main`.
![Stabilization Branches](../images/versioning-sketch-1.png)
Since Electron 8, stabilization branches are always **major** version lines, and named against the following template `$MAJOR-x-y` e.g. `8-x-y`. Prior to that we used **minor** version lines and named them as `$MAJOR-$MINOR-x` e.g. `2-0-x`.
We allow for multiple stabilization branches to exist simultaneously, one for each supported version. For more details on which versions are supported, see our [Electron Releases](./electron-timelines.md) doc.
![Multiple Stability Branches](../images/versioning-sketch-2.png)
Older lines will not be supported by the Electron project, but other groups can take ownership and backport stability and security fixes on their own. We discourage this, but recognize that it makes life easier for many app developers.
## Beta releases and bug fixes
Developers want to know which releases are _safe_ to use. Even seemingly innocent features can introduce regressions in complex applications. At the same time, locking to a fixed version is dangerous because youre ignoring security patches and bug fixes that may have come out since your version. Our goal is to allow the following standard semver ranges in `package.json` :
* Use `~2.0.0` to admit only stability or security related fixes to your `2.0.0` release.
* Use `^2.0.0` to admit non-breaking _reasonably stable_ feature work as well as security and bug fixes.
Whats important about the second point is that apps using `^` should still be able to expect a reasonable level of stability. To accomplish this, SemVer allows for a _pre-release identifier_ to indicate a particular version is not yet _safe_ or _stable_.
Whatever you choose, you will periodically have to bump the version in your `package.json` as breaking changes are a fact of Chromium life.
The process is as follows:
1. All new major and minor releases lines begin with a beta series indicated by SemVer prerelease tags of `beta.N`, e.g. `2.0.0-beta.1`. After the first beta, subsequent beta releases must meet all of the following conditions:
1. The change is backwards API-compatible (deprecations are allowed)
2. The risk to meeting our stability timeline must be low.
2. If allowed changes need to be made once a release is beta, they are applied and the prerelease tag is incremented, e.g. `2.0.0-beta.2`.
3. If a particular beta release is _generally regarded_ as stable, it will be re-released as a stable build, changing only the version information. e.g. `2.0.0`. After the first stable, all changes must be backwards-compatible bug or security fixes.
4. If future bug fixes or security patches need to be made once a release is stable, they are applied and the _patch_ version is incremented
e.g. `2.0.1`.
Specifically, the above means:
1. Admitting non-breaking-API changes before Week 3 in the beta cycle is okay, even if those changes have the potential to cause moderate side-effects.
2. Admitting feature-flagged changes, that do not otherwise alter existing code paths, at most points in the beta cycle is okay. Users can explicitly enable those flags in their apps.
3. Admitting features of any sort after Week 3 in the beta cycle is 👎 without a very good reason.
For each major and minor bump, you should expect to see something like the following:
```plaintext
2.0.0-beta.1
2.0.0-beta.2
2.0.0-beta.3
2.0.0
2.0.1
2.0.2
```mermaid
gitGraph
commit
commit
branch N-x-y
checkout main
commit id:"fix-1"
checkout N-x-y
cherry-pick id:"fix-1"
checkout main
commit id:"fix-2"
checkout N-x-y
cherry-pick id:"fix-2"
checkout main
commit
commit
```
An example lifecycle in pictures:
Since Electron 8, stabilization branches are always **major** version lines, and named against the following template `$MAJOR-x-y` e.g. `8-x-y`. (Prior to that, we used **minor** version lines and named them as `$MAJOR-$MINOR-x` e.g. `2-0-x`.)
* A new release branch is created that includes the latest set of features. It is published as `2.0.0-beta.1`.
![New Release Branch](../images/versioning-sketch-3.png)
* A bug fix comes into master that can be backported to the release branch. The patch is applied, and a new beta is published as `2.0.0-beta.2`.
![Bugfix Backport to Beta](../images/versioning-sketch-4.png)
* The beta is considered _generally stable_ and it is published again as a non-beta under `2.0.0`.
![Beta to Stable](../images/versioning-sketch-5.png)
* Later, a zero-day exploit is revealed and a fix is applied to master. We backport the fix to the `2-0-x` line and release `2.0.1`.
![Security Backports](../images/versioning-sketch-6.png)
We allow for multiple stabilization branches to exist simultaneously, one for each supported version.
A few examples of how various SemVer ranges will pick up new releases:
> [!TIP]
> For more details on which versions are supported, see our [Electron Releases](./electron-timelines.md) doc.
![Semvers and Releases](../images/versioning-sketch-7.png)
```mermaid
gitGraph
commit
branch "41-x-y"
checkout main
commit
commit
commit id:"fix-a"
checkout "41-x-y"
cherry-pick id:"fix-a"
checkout main
commit
commit id:"fix-b"
checkout "41-x-y"
cherry-pick id:"fix-b"
checkout main
commit
branch "42-x-y"
checkout main
commit
commit id:"fix-c"
checkout "41-x-y"
cherry-pick id:"fix-c"
checkout "42-x-y"
cherry-pick id:"fix-c"
checkout main
commit
commit id:"fix-d"
checkout "41-x-y"
cherry-pick id:"fix-d"
checkout "42-x-y"
cherry-pick id:"fix-d"
checkout main
commit
```
Older lines will not be supported by the Electron project.
## Release cycle
Electron follows an **8-week regular release cycle** where key milestones correspond to
matching dates in the Chromium release cycle.
```mermaid
gantt
title Electron release cycle
dateFormat YYYY-MM-DD
axisFormat Week %W
todayMarker off
section v41
Alpha phase :a1, 2026-01-19, 4w
M146 enters Chrome beta :milestone, bm1, after a1, 0d
Beta phase :b1, after a1, 4w
M146 enters Chrome stable :milestone, s1, after b1, 0d
Supported until v44 release :active, after b1, 12w
section v42
Alpha phase :a2, after b1, 4w
M148 enters Chrome beta :milestone, bm2, after a2, 0d
Beta phase :b2, after a2, 4w
M148 enters Chrome stable :milestone, s2, after b2, 0d
Supported until v45 release :active, after b2, 4w
```
### Example
When Electron 41 hits its stable release, the release line for Electron 42 is branched off of `main`.
Its first alpha release is created with all the changes contained on `main`:
```mermaid
gitGraph
commit
commit
commit
branch "42-x-y"
checkout "42-x-y"
commit tag:"v42.0.0-alpha.1"
```
A bug fix comes into `main` that can be backported to the release branch. The patch is applied,
and it is published in the next `v42.0.0-alpha.2` release.
```mermaid
gitGraph
commit
commit
commit
branch "42-x-y"
checkout "42-x-y"
commit id:"42.0.0-alpha.1" tag:"v42.0.0-alpha.1"
checkout "main"
commit
commit id:"fix-1"
checkout "42-x-y"
cherry-pick id:"fix-1" tag:"v42.0.0-alpha.2"
```
The version of Chromium that powers Electron 42 hits Chrome's beta channel. The `alpha` line is
promoted to `beta`.
```mermaid
gitGraph
commit
commit
commit
branch "42-x-y"
checkout "42-x-y"
commit id:"42.0.0-alpha.1" tag:"v42.0.0-alpha.1"
checkout "main"
commit
commit id:"fix-1"
checkout "42-x-y"
cherry-pick id:"fix-1" tag:"v42.0.0-alpha.2"
checkout "main"
commit
commit
commit id:"fix-2"
checkout "42-x-y"
cherry-pick id:"fix-2" tag:"v42.0.0-beta.1"
```
Beta releases continue weekly until Electron 42 is promoted to stable and the same cycle starts again
with `43-x-y`. Later, a zero-day exploit is revealed and a fix is applied to `main`. We backport the
fix to the `42-x-y` line and release `42.0.1`.
```mermaid
gitGraph
commit
commit
commit
branch "42-x-y"
checkout "42-x-y"
commit id:"42.0.0-alpha.1" tag:"v42.0.0-alpha.1"
checkout "main"
commit
commit id:"fix-1"
checkout "42-x-y"
cherry-pick id:"fix-1" tag:"v42.0.0-alpha.2"
checkout "main"
commit
commit
commit id:"fix-2"
checkout "42-x-y"
cherry-pick id:"fix-2" tag:"v42.0.0-beta.1"
checkout "main"
commit id:"fix-3"
checkout "42-x-y"
cherry-pick id:"fix-3" tag:"v42.0.0"
checkout "main"
branch "43-x-y"
checkout "43-x-y"
commit id:"43.0.0-alpha.1" tag:"v43.0.0-alpha.1"
checkout "main"
commit id:"security-fix"
checkout "42-x-y"
cherry-pick id:"security-fix" tag:"v42.0.1"
checkout "43-x-y"
cherry-pick id:"security-fix" tag:"v43.0.0-alpha.2"
```
### Backport request process
@@ -136,10 +245,11 @@ The `electron/electron` repository also enforces squash merging, so you only nee
## Versioned `main` branch
* The `main` branch will always contain the next major version `X.0.0-nightly.DATE` in its `package.json`.
* The `main` branch always corresponds to the major version above the current pre-release line.
* Unstable nightly releases of `main` are released under the [`electron-nightly`](https://www.npmjs.com/package/electron-nightly)
package on npm.
* Release branches are never merged back to `main`.
* Release branches _do_ contain the correct version in their `package.json`.
* As soon as a release branch is cut for a major, `main` must be bumped to the next major (i.e. `main` is always versioned as the next theoretical release branch).
* All `package.json` values are fixed at `0.0.0-development`.
## Historical versioning (Electron 1.X)
@@ -147,6 +257,29 @@ Electron versions _< 2.0_ did not conform to the [SemVer](https://semver.org) sp
Here is an example of the 1.x strategy:
![1.x Versioning](../images/versioning-sketch-0.png)
```mermaid
---
config:
gitGraph:
mainBranchName: 'master'
---
gitGraph
commit
branch "bugfix-1"
checkout "bugfix-1"
commit
checkout master
merge "bugfix-1" tag:"1.8.1"
branch "feature"
checkout "feature"
commit
checkout master
merge "feature" tag:"1.8.2"
branch "bugfix-2"
checkout "bugfix-2"
commit
checkout master
merge "bugfix-2" tag:"1.8.3"
```
An app developed with `1.8.1` cannot take the `1.8.3` bug fix without either absorbing the `1.8.2` feature, or by backporting the fix and maintaining a new release line.

View File

@@ -25,6 +25,27 @@ included in the `electron` package:
npx install-electron --no
```
## Installing prereleases
Electron [distributes experimental releases of future major versions](./electron-timelines.md)
via npm as well.
Nightly builds contain the latest changes from the `main` branch:
```sh
npm install electron-nightly --save-dev
```
Alpha and beta builds contain changes slated for the next major version:
```sh
npm install electron@alpha --save-dev
npm install electron@beta --save-dev
```
> [!TIP]
> For more information on available Electron releases, see the [Release Status dashboard](https://releases.electronjs.org).
## Running Electron ad-hoc
If you're in a pinch and would prefer to not use `npm install` in your local

View File

@@ -107,7 +107,7 @@ When signing the app with `@electron/osx-sign`, it will automatically add the
necessary entitlements to your app's entitlements.
<details>
<summary>Extra steps without `electron-osx-sign`</summary>
<summary>Extra steps without `@electron/osx-sign`</summary>
If you are signing your app without using `@electron/osx-sign`, you must ensure
the app bundle's entitlements have at least following keys:

View File

@@ -91,6 +91,7 @@ auto_filenames = {
"docs/api/structures/custom-scheme.md",
"docs/api/structures/desktop-capturer-source.md",
"docs/api/structures/display.md",
"docs/api/structures/enable-heap-profiling-options.md",
"docs/api/structures/extension-info.md",
"docs/api/structures/extension.md",
"docs/api/structures/file-filter.md",
@@ -174,6 +175,347 @@ auto_filenames = {
"docs/api/structures/window-session-end-event.md",
]
node_header_sources = [
"../third_party/electron_node/src/acorn_version.h",
"../third_party/electron_node/src/aliased_buffer-inl.h",
"../third_party/electron_node/src/aliased_buffer.h",
"../third_party/electron_node/src/aliased_struct-inl.h",
"../third_party/electron_node/src/aliased_struct.h",
"../third_party/electron_node/src/amaro_version.h",
"../third_party/electron_node/src/async_context_frame.h",
"../third_party/electron_node/src/async_wrap-inl.h",
"../third_party/electron_node/src/async_wrap.h",
"../third_party/electron_node/src/base_object-inl.h",
"../third_party/electron_node/src/base_object.h",
"../third_party/electron_node/src/base_object_types.h",
"../third_party/electron_node/src/blob_serializer_deserializer-inl.h",
"../third_party/electron_node/src/blob_serializer_deserializer.h",
"../third_party/electron_node/src/builtin_info.h",
"../third_party/electron_node/src/callback_queue-inl.h",
"../third_party/electron_node/src/callback_queue.h",
"../third_party/electron_node/src/cares_wrap.h",
"../third_party/electron_node/src/cleanup_queue-inl.h",
"../third_party/electron_node/src/cleanup_queue.h",
"../third_party/electron_node/src/compile_cache.h",
"../third_party/electron_node/src/connect_wrap.h",
"../third_party/electron_node/src/connection_wrap.h",
"../third_party/electron_node/src/cppgc_helpers-inl.h",
"../third_party/electron_node/src/cppgc_helpers.h",
"../third_party/electron_node/src/crypto/crypto_aes.h",
"../third_party/electron_node/src/crypto/crypto_argon2.h",
"../third_party/electron_node/src/crypto/crypto_bio.h",
"../third_party/electron_node/src/crypto/crypto_chacha20_poly1305.h",
"../third_party/electron_node/src/crypto/crypto_cipher.h",
"../third_party/electron_node/src/crypto/crypto_clienthello-inl.h",
"../third_party/electron_node/src/crypto/crypto_clienthello.h",
"../third_party/electron_node/src/crypto/crypto_common.h",
"../third_party/electron_node/src/crypto/crypto_context.h",
"../third_party/electron_node/src/crypto/crypto_dh.h",
"../third_party/electron_node/src/crypto/crypto_dsa.h",
"../third_party/electron_node/src/crypto/crypto_ec.h",
"../third_party/electron_node/src/crypto/crypto_hash.h",
"../third_party/electron_node/src/crypto/crypto_hkdf.h",
"../third_party/electron_node/src/crypto/crypto_hmac.h",
"../third_party/electron_node/src/crypto/crypto_kem.h",
"../third_party/electron_node/src/crypto/crypto_keygen.h",
"../third_party/electron_node/src/crypto/crypto_keys.h",
"../third_party/electron_node/src/crypto/crypto_kmac.h",
"../third_party/electron_node/src/crypto/crypto_ml_dsa.h",
"../third_party/electron_node/src/crypto/crypto_pbkdf2.h",
"../third_party/electron_node/src/crypto/crypto_random.h",
"../third_party/electron_node/src/crypto/crypto_rsa.h",
"../third_party/electron_node/src/crypto/crypto_scrypt.h",
"../third_party/electron_node/src/crypto/crypto_sig.h",
"../third_party/electron_node/src/crypto/crypto_spkac.h",
"../third_party/electron_node/src/crypto/crypto_timing.h",
"../third_party/electron_node/src/crypto/crypto_tls.h",
"../third_party/electron_node/src/crypto/crypto_util.h",
"../third_party/electron_node/src/crypto/crypto_x509.h",
"../third_party/electron_node/src/dataqueue/queue.h",
"../third_party/electron_node/src/debug_utils-inl.h",
"../third_party/electron_node/src/debug_utils.h",
"../third_party/electron_node/src/diagnosticfilename-inl.h",
"../third_party/electron_node/src/embedded_data.h",
"../third_party/electron_node/src/encoding_binding.h",
"../third_party/electron_node/src/env-inl.h",
"../third_party/electron_node/src/env.h",
"../third_party/electron_node/src/env_properties.h",
"../third_party/electron_node/src/handle_wrap.h",
"../third_party/electron_node/src/histogram-inl.h",
"../third_party/electron_node/src/histogram.h",
"../third_party/electron_node/src/inspector/io_agent.h",
"../third_party/electron_node/src/inspector/main_thread_interface.h",
"../third_party/electron_node/src/inspector/network_agent.h",
"../third_party/electron_node/src/inspector/network_inspector.h",
"../third_party/electron_node/src/inspector/network_requests_buffer.h",
"../third_party/electron_node/src/inspector/network_resource_manager.h",
"../third_party/electron_node/src/inspector/node_json.h",
"../third_party/electron_node/src/inspector/node_string.h",
"../third_party/electron_node/src/inspector/protocol_helper.h",
"../third_party/electron_node/src/inspector/runtime_agent.h",
"../third_party/electron_node/src/inspector/target_agent.h",
"../third_party/electron_node/src/inspector/target_manager.h",
"../third_party/electron_node/src/inspector/tracing_agent.h",
"../third_party/electron_node/src/inspector/worker_agent.h",
"../third_party/electron_node/src/inspector/worker_inspector.h",
"../third_party/electron_node/src/inspector_agent.h",
"../third_party/electron_node/src/inspector_io.h",
"../third_party/electron_node/src/inspector_profiler.h",
"../third_party/electron_node/src/inspector_socket.h",
"../third_party/electron_node/src/inspector_socket_server.h",
"../third_party/electron_node/src/js_native_api.h",
"../third_party/electron_node/src/js_native_api_types.h",
"../third_party/electron_node/src/js_native_api_v8.h",
"../third_party/electron_node/src/js_native_api_v8_internals.h",
"../third_party/electron_node/src/js_stream.h",
"../third_party/electron_node/src/json_utils.h",
"../third_party/electron_node/src/large_pages/node_large_page.h",
"../third_party/electron_node/src/lru_cache-inl.h",
"../third_party/electron_node/src/memory_tracker-inl.h",
"../third_party/electron_node/src/memory_tracker.h",
"../third_party/electron_node/src/module_wrap.h",
"../third_party/electron_node/src/node.h",
"../third_party/electron_node/src/node_api.h",
"../third_party/electron_node/src/node_api_internals.h",
"../third_party/electron_node/src/node_api_types.h",
"../third_party/electron_node/src/node_binding.h",
"../third_party/electron_node/src/node_blob.h",
"../third_party/electron_node/src/node_bob-inl.h",
"../third_party/electron_node/src/node_bob.h",
"../third_party/electron_node/src/node_buffer.h",
"../third_party/electron_node/src/node_builtins.h",
"../third_party/electron_node/src/node_config_file.h",
"../third_party/electron_node/src/node_constants.h",
"../third_party/electron_node/src/node_context_data.h",
"../third_party/electron_node/src/node_contextify.h",
"../third_party/electron_node/src/node_crypto.h",
"../third_party/electron_node/src/node_debug.h",
"../third_party/electron_node/src/node_diagnostics_channel.h",
"../third_party/electron_node/src/node_dir.h",
"../third_party/electron_node/src/node_dotenv.h",
"../third_party/electron_node/src/node_errors.h",
"../third_party/electron_node/src/node_exit_code.h",
"../third_party/electron_node/src/node_external_reference.h",
"../third_party/electron_node/src/node_file-inl.h",
"../third_party/electron_node/src/node_file.h",
"../third_party/electron_node/src/node_http2.h",
"../third_party/electron_node/src/node_http2_state.h",
"../third_party/electron_node/src/node_http_common-inl.h",
"../third_party/electron_node/src/node_http_common.h",
"../third_party/electron_node/src/node_i18n.h",
"../third_party/electron_node/src/node_internals.h",
"../third_party/electron_node/src/node_locks.h",
"../third_party/electron_node/src/node_main_instance.h",
"../third_party/electron_node/src/node_mem-inl.h",
"../third_party/electron_node/src/node_mem.h",
"../third_party/electron_node/src/node_messaging.h",
"../third_party/electron_node/src/node_metadata.h",
"../third_party/electron_node/src/node_modules.h",
"../third_party/electron_node/src/node_mutex.h",
"../third_party/electron_node/src/node_object_wrap.h",
"../third_party/electron_node/src/node_options-inl.h",
"../third_party/electron_node/src/node_options.h",
"../third_party/electron_node/src/node_perf.h",
"../third_party/electron_node/src/node_perf_common.h",
"../third_party/electron_node/src/node_platform.h",
"../third_party/electron_node/src/node_process-inl.h",
"../third_party/electron_node/src/node_process.h",
"../third_party/electron_node/src/node_realm-inl.h",
"../third_party/electron_node/src/node_realm.h",
"../third_party/electron_node/src/node_report.h",
"../third_party/electron_node/src/node_revert.h",
"../third_party/electron_node/src/node_root_certs.h",
"../third_party/electron_node/src/node_sea.h",
"../third_party/electron_node/src/node_shadow_realm.h",
"../third_party/electron_node/src/node_snapshot_builder.h",
"../third_party/electron_node/src/node_snapshotable.h",
"../third_party/electron_node/src/node_sockaddr-inl.h",
"../third_party/electron_node/src/node_sockaddr.h",
"../third_party/electron_node/src/node_sqlite.h",
"../third_party/electron_node/src/node_stat_watcher.h",
"../third_party/electron_node/src/node_task_runner.h",
"../third_party/electron_node/src/node_threadsafe_cow-inl.h",
"../third_party/electron_node/src/node_threadsafe_cow.h",
"../third_party/electron_node/src/node_union_bytes.h",
"../third_party/electron_node/src/node_url.h",
"../third_party/electron_node/src/node_url_pattern.h",
"../third_party/electron_node/src/node_v8.h",
"../third_party/electron_node/src/node_v8_platform-inl.h",
"../third_party/electron_node/src/node_version.h",
"../third_party/electron_node/src/node_wasi.h",
"../third_party/electron_node/src/node_wasm_web_api.h",
"../third_party/electron_node/src/node_watchdog.h",
"../third_party/electron_node/src/node_webstorage.h",
"../third_party/electron_node/src/node_worker.h",
"../third_party/electron_node/src/path.h",
"../third_party/electron_node/src/permission/addon_permission.h",
"../third_party/electron_node/src/permission/child_process_permission.h",
"../third_party/electron_node/src/permission/fs_permission.h",
"../third_party/electron_node/src/permission/inspector_permission.h",
"../third_party/electron_node/src/permission/permission.h",
"../third_party/electron_node/src/permission/permission_base.h",
"../third_party/electron_node/src/permission/wasi_permission.h",
"../third_party/electron_node/src/permission/worker_permission.h",
"../third_party/electron_node/src/pipe_wrap.h",
"../third_party/electron_node/src/quic/application.h",
"../third_party/electron_node/src/quic/bindingdata.h",
"../third_party/electron_node/src/quic/cid.h",
"../third_party/electron_node/src/quic/data.h",
"../third_party/electron_node/src/quic/defs.h",
"../third_party/electron_node/src/quic/endpoint.h",
"../third_party/electron_node/src/quic/http3.h",
"../third_party/electron_node/src/quic/logstream.h",
"../third_party/electron_node/src/quic/packet.h",
"../third_party/electron_node/src/quic/preferredaddress.h",
"../third_party/electron_node/src/quic/session.h",
"../third_party/electron_node/src/quic/sessionticket.h",
"../third_party/electron_node/src/quic/streams.h",
"../third_party/electron_node/src/quic/tlscontext.h",
"../third_party/electron_node/src/quic/tokens.h",
"../third_party/electron_node/src/quic/transportparams.h",
"../third_party/electron_node/src/req_wrap-inl.h",
"../third_party/electron_node/src/req_wrap.h",
"../third_party/electron_node/src/spawn_sync.h",
"../third_party/electron_node/src/stream_base-inl.h",
"../third_party/electron_node/src/stream_base.h",
"../third_party/electron_node/src/stream_pipe.h",
"../third_party/electron_node/src/stream_wrap.h",
"../third_party/electron_node/src/string_bytes.h",
"../third_party/electron_node/src/string_decoder-inl.h",
"../third_party/electron_node/src/string_decoder.h",
"../third_party/electron_node/src/tcp_wrap.h",
"../third_party/electron_node/src/threadpoolwork-inl.h",
"../third_party/electron_node/src/timer_wrap-inl.h",
"../third_party/electron_node/src/timer_wrap.h",
"../third_party/electron_node/src/timers.h",
"../third_party/electron_node/src/tracing/agent.h",
"../third_party/electron_node/src/tracing/node_trace_buffer.h",
"../third_party/electron_node/src/tracing/node_trace_writer.h",
"../third_party/electron_node/src/tracing/trace_categories.h",
"../third_party/electron_node/src/tracing/trace_event.h",
"../third_party/electron_node/src/tracing/trace_event_common.h",
"../third_party/electron_node/src/tracing/traced_value.h",
"../third_party/electron_node/src/tty_wrap.h",
"../third_party/electron_node/src/udp_wrap.h",
"../third_party/electron_node/src/undici_version.h",
"../third_party/electron_node/src/util-inl.h",
"../third_party/electron_node/src/util.h",
"../third_party/electron_node/src/zlib_version.h",
"../third_party/electron_node/tools/install.py",
"../v8/include/cppgc/allocation.h",
"../v8/include/cppgc/common.h",
"../v8/include/cppgc/cross-thread-persistent.h",
"../v8/include/cppgc/custom-space.h",
"../v8/include/cppgc/default-platform.h",
"../v8/include/cppgc/explicit-management.h",
"../v8/include/cppgc/garbage-collected.h",
"../v8/include/cppgc/heap-consistency.h",
"../v8/include/cppgc/heap-handle.h",
"../v8/include/cppgc/heap-state.h",
"../v8/include/cppgc/heap-statistics.h",
"../v8/include/cppgc/heap.h",
"../v8/include/cppgc/internal/api-constants.h",
"../v8/include/cppgc/internal/atomic-entry-flag.h",
"../v8/include/cppgc/internal/base-page-handle.h",
"../v8/include/cppgc/internal/caged-heap-local-data.h",
"../v8/include/cppgc/internal/caged-heap.h",
"../v8/include/cppgc/internal/compiler-specific.h",
"../v8/include/cppgc/internal/conditional-stack-allocated.h",
"../v8/include/cppgc/internal/finalizer-trait.h",
"../v8/include/cppgc/internal/gc-info.h",
"../v8/include/cppgc/internal/logging.h",
"../v8/include/cppgc/internal/member-storage.h",
"../v8/include/cppgc/internal/name-trait.h",
"../v8/include/cppgc/internal/persistent-node.h",
"../v8/include/cppgc/internal/pointer-policies.h",
"../v8/include/cppgc/internal/write-barrier.h",
"../v8/include/cppgc/liveness-broker.h",
"../v8/include/cppgc/macros.h",
"../v8/include/cppgc/member.h",
"../v8/include/cppgc/name-provider.h",
"../v8/include/cppgc/object-size-trait.h",
"../v8/include/cppgc/persistent.h",
"../v8/include/cppgc/platform.h",
"../v8/include/cppgc/prefinalizer.h",
"../v8/include/cppgc/process-heap-statistics.h",
"../v8/include/cppgc/sentinel-pointer.h",
"../v8/include/cppgc/source-location.h",
"../v8/include/cppgc/tagged-member.h",
"../v8/include/cppgc/testing.h",
"../v8/include/cppgc/trace-trait.h",
"../v8/include/cppgc/type-traits.h",
"../v8/include/cppgc/visitor.h",
"../v8/include/libplatform/libplatform-export.h",
"../v8/include/libplatform/libplatform.h",
"../v8/include/libplatform/v8-tracing.h",
"../v8/include/v8-array-buffer.h",
"../v8/include/v8-callbacks.h",
"../v8/include/v8-container.h",
"../v8/include/v8-context.h",
"../v8/include/v8-cpp-heap-external.h",
"../v8/include/v8-cppgc.h",
"../v8/include/v8-data.h",
"../v8/include/v8-date.h",
"../v8/include/v8-debug.h",
"../v8/include/v8-embedder-heap.h",
"../v8/include/v8-embedder-state-scope.h",
"../v8/include/v8-exception.h",
"../v8/include/v8-extension.h",
"../v8/include/v8-external-memory-accounter.h",
"../v8/include/v8-external.h",
"../v8/include/v8-fast-api-calls.h",
"../v8/include/v8-forward.h",
"../v8/include/v8-function-callback.h",
"../v8/include/v8-function.h",
"../v8/include/v8-handle-base.h",
"../v8/include/v8-initialization.h",
"../v8/include/v8-inspector-protocol.h",
"../v8/include/v8-inspector.h",
"../v8/include/v8-internal.h",
"../v8/include/v8-isolate.h",
"../v8/include/v8-json.h",
"../v8/include/v8-local-handle.h",
"../v8/include/v8-locker.h",
"../v8/include/v8-maybe.h",
"../v8/include/v8-memory-span.h",
"../v8/include/v8-message.h",
"../v8/include/v8-metrics.h",
"../v8/include/v8-microtask-queue.h",
"../v8/include/v8-microtask.h",
"../v8/include/v8-object.h",
"../v8/include/v8-persistent-handle.h",
"../v8/include/v8-platform.h",
"../v8/include/v8-primitive-object.h",
"../v8/include/v8-primitive.h",
"../v8/include/v8-profiler.h",
"../v8/include/v8-promise.h",
"../v8/include/v8-proxy.h",
"../v8/include/v8-regexp.h",
"../v8/include/v8-sandbox.h",
"../v8/include/v8-script.h",
"../v8/include/v8-snapshot.h",
"../v8/include/v8-source-location.h",
"../v8/include/v8-statistics.h",
"../v8/include/v8-template.h",
"../v8/include/v8-trace-categories.h",
"../v8/include/v8-traced-handle.h",
"../v8/include/v8-typed-array.h",
"../v8/include/v8-unwinder-state.h",
"../v8/include/v8-unwinder.h",
"../v8/include/v8-util.h",
"../v8/include/v8-value-serializer-version.h",
"../v8/include/v8-value-serializer.h",
"../v8/include/v8-value.h",
"../v8/include/v8-version-string.h",
"../v8/include/v8-version.h",
"../v8/include/v8-wasm-trap-handler-posix.h",
"../v8/include/v8-wasm-trap-handler-win.h",
"../v8/include/v8-wasm.h",
"../v8/include/v8-weak-callback-info.h",
"../v8/include/v8.h",
"../v8/include/v8config.h",
]
sandbox_bundle_deps = [
"lib/common/api/native-image.ts",
"lib/common/define-properties.ts",

View File

@@ -432,6 +432,10 @@ filenames = {
"shell/browser/media/media_capture_devices_dispatcher.h",
"shell/browser/media/media_device_id_salt.cc",
"shell/browser/media/media_device_id_salt.h",
"shell/browser/metrics/electron_metrics_log_uploader.cc",
"shell/browser/metrics/electron_metrics_log_uploader.h",
"shell/browser/metrics/electron_metrics_service_client.cc",
"shell/browser/metrics/electron_metrics_service_client.h",
"shell/browser/microtasks_runner.cc",
"shell/browser/microtasks_runner.h",
"shell/browser/native_window.cc",
@@ -508,6 +512,10 @@ filenames = {
"shell/browser/session_preferences.h",
"shell/browser/special_storage_policy.cc",
"shell/browser/special_storage_policy.h",
"shell/browser/tracing/electron_background_tracing_metrics_provider.cc",
"shell/browser/tracing/electron_background_tracing_metrics_provider.h",
"shell/browser/tracing/electron_tracing_delegate.cc",
"shell/browser/tracing/electron_tracing_delegate.h",
"shell/browser/ui/accelerator_util.cc",
"shell/browser/ui/accelerator_util.h",
"shell/browser/ui/autofill_popup.cc",

View File

@@ -215,6 +215,7 @@ libcxx_headers = [
"//third_party/libc++/src/include/__atomic/atomic_lock_free.h",
"//third_party/libc++/src/include/__atomic/atomic_ref.h",
"//third_party/libc++/src/include/__atomic/atomic_sync.h",
"//third_party/libc++/src/include/__atomic/atomic_waitable_traits.h",
"//third_party/libc++/src/include/__atomic/check_memory_order.h",
"//third_party/libc++/src/include/__atomic/contention_t.h",
"//third_party/libc++/src/include/__atomic/fence.h",
@@ -1182,6 +1183,7 @@ libcxx_headers = [
"//third_party/libc++/src/include/__memory/unique_temporary_buffer.h",
"//third_party/libc++/src/include/__memory/uses_allocator.h",
"//third_party/libc++/src/include/__memory/uses_allocator_construction.h",
"//third_party/libc++/src/include/__memory/valid_range.h",
"//third_party/libc++/src/include/__memory_resource/memory_resource.h",
"//third_party/libc++/src/include/__memory_resource/monotonic_buffer_resource.h",
"//third_party/libc++/src/include/__memory_resource/polymorphic_allocator.h",
@@ -1506,7 +1508,6 @@ libcxx_headers = [
"//third_party/libc++/src/include/__utility/in_place.h",
"//third_party/libc++/src/include/__utility/integer_sequence.h",
"//third_party/libc++/src/include/__utility/is_pointer_in_range.h",
"//third_party/libc++/src/include/__utility/is_valid_range.h",
"//third_party/libc++/src/include/__utility/lazy_synth_three_way_comparator.h",
"//third_party/libc++/src/include/__utility/move.h",
"//third_party/libc++/src/include/__utility/no_destroy.h",
@@ -1602,7 +1603,6 @@ libcxx_headers = [
"//third_party/libc++/src/include/filesystem",
"//third_party/libc++/src/include/flat_map",
"//third_party/libc++/src/include/flat_set",
"//third_party/libc++/src/include/float.h",
"//third_party/libc++/src/include/format",
"//third_party/libc++/src/include/forward_list",
"//third_party/libc++/src/include/fstream",

View File

@@ -53,45 +53,50 @@ export async function getSources(args: Electron.SourcesOptions) {
}
}
let resolveGetSources!: (value: ElectronInternal.GetSourcesResult[]) => void;
let rejectGetSources!: (reason?: any) => void;
const getSources = new Promise<ElectronInternal.GetSourcesResult[]>((resolve, reject) => {
let capturer: ElectronInternal.DesktopCapturer | null = createDesktopCapturer();
resolveGetSources = resolve;
rejectGetSources = reject;
});
const stopRunning = () => {
if (capturer) {
delete capturer._onerror;
delete capturer._onfinished;
capturer = null;
// Register in currentlyRunning BEFORE startHandling so that synchronous
// completion (e.g. when no capturers are created) can properly clean up.
currentlyRunning.push({ options, getSources });
if (process.platform === 'darwin') {
for (const win of BrowserWindow.getAllWindows()) {
if (resizableValues.has(win.id)) {
win.resizable = resizableValues.get(win.id);
}
let capturer: ElectronInternal.DesktopCapturer | null = createDesktopCapturer();
const stopRunning = () => {
if (capturer) {
delete capturer._onerror;
delete capturer._onfinished;
capturer = null;
if (process.platform === 'darwin') {
for (const win of BrowserWindow.getAllWindows()) {
if (resizableValues.has(win.id)) {
win.resizable = resizableValues.get(win.id);
}
}
}
// Remove from currentlyRunning once we resolve or reject
currentlyRunning = currentlyRunning.filter((running) => running.options !== options);
};
}
// Remove from currentlyRunning once we resolve or reject
currentlyRunning = currentlyRunning.filter((running) => running.options !== options);
};
capturer._onerror = (error: string) => {
stopRunning();
// eslint-disable-next-line prefer-promise-reject-errors
reject(error);
};
capturer._onerror = (error: string) => {
stopRunning();
// eslint-disable-next-line prefer-promise-reject-errors
rejectGetSources(error);
};
capturer._onfinished = (sources: Electron.DesktopCapturerSource[]) => {
stopRunning();
resolve(sources);
};
capturer._onfinished = (sources: Electron.DesktopCapturerSource[]) => {
stopRunning();
resolveGetSources(sources);
};
capturer.startHandling(captureWindow, captureScreen, thumbnailSize, fetchWindowIcons);
});
currentlyRunning.push({
options,
getSources
});
capturer.startHandling(captureWindow, captureScreen, thumbnailSize, fetchWindowIcons);
return getSources;
}

View File

@@ -1,2 +1,39 @@
const { globalShortcut } = process._linkedBinding('electron_browser_global_shortcut');
export default globalShortcut;
const { createGlobalShortcut } = process._linkedBinding('electron_browser_global_shortcut');
let globalShortcut: Electron.GlobalShortcut;
const createGlobalShortcutIfNeeded = () => {
if (globalShortcut === undefined) {
globalShortcut = createGlobalShortcut();
}
};
export default new Proxy(
{},
{
get: (_target, property: keyof Electron.GlobalShortcut) => {
createGlobalShortcutIfNeeded();
const value = globalShortcut[property];
if (typeof value === 'function') {
return value.bind(globalShortcut);
}
return value;
},
set: (_target, property: string, value: unknown) => {
createGlobalShortcutIfNeeded();
return Reflect.set(globalShortcut, property, value);
},
ownKeys: () => {
createGlobalShortcutIfNeeded();
return Reflect.ownKeys(globalShortcut);
},
has: (_target, property: string) => {
createGlobalShortcutIfNeeded();
return property in globalShortcut;
},
getOwnPropertyDescriptor: (_target, property: string) => {
createGlobalShortcutIfNeeded();
return Reflect.getOwnPropertyDescriptor(globalShortcut, property);
}
}
);

View File

@@ -1,14 +1,11 @@
import { MessagePortMain } from '@electron/internal/browser/message-port-main';
import { EventEmitter } from 'events';
const { createPair } = process._linkedBinding('electron_browser_message_port');
export default class MessageChannelMain extends EventEmitter implements Electron.MessageChannelMain {
export default class MessageChannelMain implements Electron.MessageChannelMain {
port1: MessagePortMain;
port2: MessagePortMain;
constructor() {
super();
const { port1, port2 } = createPair();
this.port1 = new MessagePortMain(port1);
this.port2 = new MessagePortMain(port2);

View File

@@ -2,6 +2,7 @@ const binding = process._linkedBinding('electron_browser_notification');
const ElectronNotification = binding.Notification;
ElectronNotification.isSupported = binding.isSupported;
ElectronNotification.getHistory = binding.getHistory;
if (process.platform === 'win32' && binding.handleActivation) {
ElectronNotification.handleActivation = binding.handleActivation;

View File

@@ -1,12 +1,9 @@
import { BrowserWindow, Menu, SharingItem, PopupOptions } from 'electron/main';
import { EventEmitter } from 'events';
class ShareMenu extends EventEmitter implements Electron.ShareMenu {
class ShareMenu implements Electron.ShareMenu {
private menu: Menu;
constructor(sharingItem: SharingItem) {
super();
this.menu = new (Menu as any)({ sharingItem });
}

View File

@@ -229,7 +229,7 @@ function parsePageSize(pageSize: string | ElectronInternal.PageSize) {
// Translate the options of printToPDF.
let pendingPromise: Promise<any> | undefined;
const printToPDFQueues = new WeakMap<Electron.WebContents, Promise<unknown>>();
WebContents.prototype.printToPDF = async function (options) {
const margins = checkType(options.margins ?? {}, 'object', 'margins');
const pageSize = parsePageSize(options.pageSize ?? 'letter');
@@ -261,16 +261,19 @@ WebContents.prototype.printToPDF = async function (options) {
...pageSize
};
if (this._printToPDF) {
if (pendingPromise) {
pendingPromise = pendingPromise.then(() => this._printToPDF(printSettings));
} else {
pendingPromise = this._printToPDF(printSettings);
}
return pendingPromise;
} else {
if (!this._printToPDF) {
throw new Error('Printing feature is disabled');
}
const prev = printToPDFQueues.get(this) ?? Promise.resolve();
const next = prev.catch(() => {}).then(() => this._printToPDF(printSettings));
printToPDFQueues.set(this, next);
next
.finally(() => {
if (printToPDFQueues.get(this) === next) printToPDFQueues.delete(this);
})
.catch(() => {});
return next;
};
// TODO(codebytere): deduplicate argument sanitization by moving rest of

View File

@@ -56,7 +56,7 @@ export function removeFunction<T extends Function>(fn: T, removedName: string):
const warn = warnOnce(`${fn.name} function`);
return function (this: any) {
warn();
fn.apply(this, arguments);
return fn.apply(this, arguments);
} as unknown as typeof fn;
}

View File

@@ -5,12 +5,22 @@
"electron": "cli.js",
"install-electron": "install.js"
},
"files": [
"LICENSE",
"README.md",
"abi_version",
"checksums.json",
"cli.js",
"electron.d.ts",
"index.js",
"install.js"
],
"dependencies": {
"@electron/get": "^4.0.3",
"@electron/get": "^5.0.0",
"@types/node": "^24.9.0",
"extract-zip": "^2.0.1"
},
"engines": {
"node": ">= 12.20.55"
"node": ">= 22.12.0"
}
}

View File

@@ -78,7 +78,7 @@
"gn-typescript-definitions": "npm run create-typescript-definitions && node script/cp.mjs electron.d.ts",
"pre-flight": "pre-flight",
"gn-check": "node ./script/gn-check.js",
"gn-format": "python3 script/run-gn-format.py",
"gn-format": "node ./script/lint.js --gn --fix",
"precommit": "lint-staged",
"preinstall": "node -e 'process.exit(0)'",
"pretest": "npm run create-typescript-definitions",
@@ -117,7 +117,7 @@
],
"*.{gn,gni}": [
"npm run gn-check",
"npm run gn-format"
"node ./script/lint.js --gn --fix --only --"
],
"*.py": [
"node script/lint.js --py --fix --only --"
@@ -143,7 +143,8 @@
"resolutions": {
"dbus-native/xml2js": "0.5.0",
"abstract-socket": "github:deepak1556/node-abstractsocket#928cc591decd12aff7dad96449da8afc29832c19",
"minimist@npm:~0.0.1": "0.2.4"
"minimist@npm:~0.0.1": "0.2.4",
"put": "npm:@nornagon/put@0.0.8"
},
"packageManager": "yarn@4.12.0",
"workspaces": [

View File

@@ -12,6 +12,7 @@ boringssl_build_gn.patch
gtk_visibility.patch
resource_file_conflict.patch
scroll_bounce_flag.patch
revert_oscrypt_remove_sync_backend.patch
mas_avoid_private_macos_api_usage.patch.patch
add_didinstallconditionalfeatures.patch
desktop_media_list.patch
@@ -103,7 +104,6 @@ chore_remove_check_is_test_on_script_injection_tracker.patch
fix_restore_original_resize_performance_on_macos.patch
feat_allow_code_cache_in_custom_schemes.patch
build_run_reclient_cfg_generator_after_chrome.patch
fix_add_support_for_skipping_first_2_no-op_refreshes_in_thumb_cap.patch
refactor_expose_file_system_access_blocklist.patch
feat_add_support_for_missing_dialog_features_to_shell_dialogs.patch
feat_enable_passing_exit_code_on_service_process_crash.patch
@@ -141,7 +141,6 @@ patch_osr_control_screen_info.patch
refactor_allow_customizing_config_in_freedesktopsecretkeyprovider.patch
fix_wayland_test_crash_on_teardown.patch
fix_set_correct_app_id_on_linux.patch
fix_pass_trigger_for_global_shortcuts_on_wayland.patch
feat_plumb_node_integration_in_worker_through_workersettings.patch
fix_restore_sdk_inputs_cross-toolchain_deps_for_macos.patch
fix_use_fresh_lazynow_for_onendworkitemimpl_after_didruntask.patch
@@ -150,4 +149,7 @@ fix_fire_menu_popup_start_for_dynamically_created_aria_menus.patch
feat_allow_enabling_extensions_on_custom_protocols.patch
fix_initialize_com_on_desktopmedialistcapturethread_on_windows.patch
chore_register_node_as_a_dynamic_trace_category_prefix.patch
gin_mark_argumentholder_as_cppgc_stack_allocated.patch
fix_make_macos_text_replacement_work_on_contenteditable.patch
fix_allow_reentrancy_on_downloadmanagerimpl_observer_list.patch
build_gn_arg_to_support_linker_wrapper_script_on_windows.patch
chore_exclude_upstream_scripting_api_when_building_electron.patch

View File

@@ -10,7 +10,7 @@ DidCreateScriptContext is called, not all JS APIs are available in the
context, which can cause some preload scripts to trip.
diff --git a/content/public/renderer/render_frame_observer.h b/content/public/renderer/render_frame_observer.h
index 3f8cf4edc7448e6b584adae8fcbb872d27377126..1d03dc809d4c18f24314d94811e0bf527aa7b5b4 100644
index 2c07b4f604cfc06d5fbfb3f0969ee37ea2f9dc85..1b8541bfa56a7e53c8396c29ea45a0b5af89ef81 100644
--- a/content/public/renderer/render_frame_observer.h
+++ b/content/public/renderer/render_frame_observer.h
@@ -141,6 +141,8 @@ class CONTENT_EXPORT RenderFrameObserver {
@@ -23,10 +23,10 @@ index 3f8cf4edc7448e6b584adae8fcbb872d27377126..1d03dc809d4c18f24314d94811e0bf52
int32_t world_id) {}
virtual void DidClearWindowObject() {}
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index ab959e66f8841d7367863bb13d6c7a0854d0df23..5279ba15f45bd7634b5f24553ad64c0069318cc0 100644
index 2f86c18cac89d5b29fb21c93ab575e304dd57173..93ee72d4eccd314388d0283249bc3c784559d9b4 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -4733,6 +4733,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
@@ -4735,6 +4735,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
observer.DidCreateScriptContext(context, world_id);
}
@@ -40,10 +40,10 @@ index ab959e66f8841d7367863bb13d6c7a0854d0df23..5279ba15f45bd7634b5f24553ad64c00
int world_id) {
for (auto& observer : observers_)
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 1733f28e69b331b33f36084391f1d3ddb47c8e14..2ce05bce0a02338aba018c18f0a808a4eb392ff4 100644
index c0961551b19c40f449da0922bcbad49bd7d70710..a6abdca5a4fd91afa7af007e4c595fe69bbf8821 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -607,6 +607,8 @@ class CONTENT_EXPORT RenderFrameImpl
@@ -605,6 +605,8 @@ class CONTENT_EXPORT RenderFrameImpl
void DidObserveLayoutShift(double score, bool after_input_or_scroll) override;
void DidCreateScriptContext(v8::Local<v8::Context> context,
int world_id) override;
@@ -53,10 +53,10 @@ index 1733f28e69b331b33f36084391f1d3ddb47c8e14..2ce05bce0a02338aba018c18f0a808a4
int world_id) override;
void DidChangeScrollOffset() override;
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h
index 0f218d3f96f0c3a3a5773937e50ba9e8d7df0498..27b21f02d2dbfd60cb64f09be393b0e50928756f 100644
index 7d3c4b9bc955873ad67e5ab00406d884d77d3f57..222278059beb1681c1d8e2a93e33279d4194227b 100644
--- a/third_party/blink/public/web/web_local_frame_client.h
+++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -675,6 +675,9 @@ class BLINK_EXPORT WebLocalFrameClient {
@@ -670,6 +670,9 @@ class BLINK_EXPORT WebLocalFrameClient {
virtual void DidCreateScriptContext(v8::Local<v8::Context>,
int32_t world_id) {}
@@ -79,10 +79,10 @@ index d293c49e6774de889fa9959234c82b41a4b1efe1..0787bc8a602c60e5b42933813baa6b9d
if (World().IsMainWorld()) {
probe::DidCreateMainWorldContext(GetFrame());
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h
index a68832975b5d359f7eddaf2326bd47ff1e7e18df..ae565a4d3fdc2d02e2c7a27312d8296bbdf61e0b 100644
index 8497afc3eccd6270839a0ab8b7e8441b4ce09ee3..bc8850ea6d8b18d7cbf33bdfda66530cf6a5d1b2 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client.h
+++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -310,6 +310,8 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
@@ -311,6 +311,8 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
virtual void DidCreateScriptContext(v8::Local<v8::Context>,
int32_t world_id) = 0;
@@ -92,7 +92,7 @@ index a68832975b5d359f7eddaf2326bd47ff1e7e18df..ae565a4d3fdc2d02e2c7a27312d8296b
int32_t world_id) = 0;
virtual bool AllowScriptExtensions() = 0;
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
index 5e5e43e204f006989a859a6077dcb56c81a08e60..aaf03855e53d5529bb51d70cd9b4355d68fed48c 100644
index 10c6f66543bfd993ede93a857830f504dcd64a73..b2df880309120ba650c18b5718fe22739aed3373 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
@@ -301,6 +301,13 @@ void LocalFrameClientImpl::DidCreateScriptContext(
@@ -110,7 +110,7 @@ index 5e5e43e204f006989a859a6077dcb56c81a08e60..aaf03855e53d5529bb51d70cd9b4355d
v8::Local<v8::Context> context,
int32_t world_id) {
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.h b/third_party/blink/renderer/core/frame/local_frame_client_impl.h
index b00211cf215fb820b3fe49139b8ef95be6a10d21..cc593168947e469b599794260692e1deb9b5f1a5 100644
index eda52e671ae638dffe23d125571e6013ca2fdb2c..4f225120efa4e149cac9d23761fa3842f15dc162 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client_impl.h
+++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.h
@@ -78,6 +78,8 @@ class CORE_EXPORT LocalFrameClientImpl final : public LocalFrameClient {
@@ -123,10 +123,10 @@ index b00211cf215fb820b3fe49139b8ef95be6a10d21..cc593168947e469b599794260692e1de
int32_t world_id) override;
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h
index bcdcc5f04edaf06d89375b05eb2d5f6bfa3d3237..5a0f42b4b7e5eb67d476c948caa201ee6fc7b3ca 100644
index 86172d090065051f4d3a640fa6cb9f182f4972e6..24b317ef1f5df5999e6c2f4e456ba3ab81c5b3c6 100644
--- a/third_party/blink/renderer/core/loader/empty_clients.h
+++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -425,6 +425,8 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
@@ -426,6 +426,8 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
void DidCreateScriptContext(v8::Local<v8::Context>,
int32_t world_id) override {}

View File

@@ -7,7 +7,7 @@ Ensure that licenses for the dependencies introduced by Electron
are included in `LICENSES.chromium.html`
diff --git a/tools/licenses/licenses.py b/tools/licenses/licenses.py
index 4272e2ab96c64b1970e1cf035a3385893b1f2f0c..387fa19ca4ea8aace08bfef67d4b7c0870ad1d23 100755
index 5cd3128beeac4072723d99d75cae7435a3511f97..19f535f2e7975cd45a535d7032e416435df790c6 100755
--- a/tools/licenses/licenses.py
+++ b/tools/licenses/licenses.py
@@ -354,6 +354,31 @@ SPECIAL_CASES = {

View File

@@ -6,7 +6,7 @@ Subject: allow disabling blink scheduler throttling per RenderView
This allows us to disable throttling for hidden windows.
diff --git a/content/browser/renderer_host/navigation_controller_impl_unittest.cc b/content/browser/renderer_host/navigation_controller_impl_unittest.cc
index f5a6ffc61f6cdff3897a97003b74838aac27e2a1..9b10aeb457a010db0ab89211610ea97b1a364453 100644
index 913c92c8b224dc749c25864311d401b51b41d9b9..5c9772ede144b35792c59c4173935813cad7d0dd 100644
--- a/content/browser/renderer_host/navigation_controller_impl_unittest.cc
+++ b/content/browser/renderer_host/navigation_controller_impl_unittest.cc
@@ -168,6 +168,12 @@ class MockPageBroadcast : public blink::mojom::PageBroadcast {
@@ -23,10 +23,10 @@ index f5a6ffc61f6cdff3897a97003b74838aac27e2a1..9b10aeb457a010db0ab89211610ea97b
return receiver_.BindNewEndpointAndPassDedicatedRemote();
}
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index 6b881f610932eacd5412accd61431e6a59124e71..999022342a06592cc1bc7838b49afddaed1f9995 100644
index d663fead3e1e2085a02ecbeb7a901c5d7311d55e..4f64c067c8598c3a3e36ee04467fc485039ed585 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -761,6 +761,11 @@ void RenderViewHostImpl::SetBackgroundOpaque(bool opaque) {
@@ -753,6 +753,11 @@ void RenderViewHostImpl::SetBackgroundOpaque(bool opaque) {
GetWidget()->GetAssociatedFrameWidget()->SetBackgroundOpaque(opaque);
}
@@ -39,7 +39,7 @@ index 6b881f610932eacd5412accd61431e6a59124e71..999022342a06592cc1bc7838b49afdda
return is_active();
}
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h
index 89fed16c112d55c13a9f23695e2898d630f7d815..b7f486337f46daac015644525c9870f54e03bb46 100644
index 55277d9fd7b4e3d09805615eba262f4b8c8a8685..39d3a3e107799d656d12150577eb457ad658790a 100644
--- a/content/browser/renderer_host/render_view_host_impl.h
+++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -134,6 +134,7 @@ class CONTENT_EXPORT RenderViewHostImpl
@@ -51,7 +51,7 @@ index 89fed16c112d55c13a9f23695e2898d630f7d815..b7f486337f46daac015644525c9870f5
void SendRendererPreferencesToRenderer(
const blink::RendererPreferences& preferences);
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index 53ec5cd693539d74424c683f78e953e85c13c098..ccfe78580c2acb9a3afa43d246e1a83cc0e28598 100644
index 74f987e8aa28a78dc5f67999e940b1ee5ce49da7..ff9ad46805b722fb9c93c901a56096e9c4bf8c99 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -655,8 +655,8 @@ void RenderWidgetHostViewAura::ShowImpl(PageVisibilityState page_visibility) {
@@ -116,10 +116,10 @@ index 932658273154ef2e022358e493a8e7c00c86e732..57bbfb5cde62c9496c351c861880a189
// Visibility -----------------------------------------------------------
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index b5a7e1b177f031837f670c26bff7394315eb6ea5..ed63aa041733e2fb09d77a219c93c322985cc81e 100644
index 135110e1ea397d52623bd1cd71759a2a014b454a..42b9ec3ca008be91318c843aba66a7a2e1c75ea5 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -2471,6 +2471,10 @@ void WebViewImpl::SetPageLifecycleStateInternal(
@@ -2468,6 +2468,10 @@ void WebViewImpl::SetPageLifecycleStateInternal(
TRACE_EVENT2("navigation", "WebViewImpl::SetPageLifecycleStateInternal",
"old_state", old_state, "new_state", new_state);
@@ -130,7 +130,7 @@ index b5a7e1b177f031837f670c26bff7394315eb6ea5..ed63aa041733e2fb09d77a219c93c322
bool storing_in_bfcache = new_state->is_in_back_forward_cache &&
!old_state->is_in_back_forward_cache;
bool restoring_from_bfcache = !new_state->is_in_back_forward_cache &&
@@ -4170,10 +4174,23 @@ PageScheduler* WebViewImpl::Scheduler() const {
@@ -4016,10 +4020,23 @@ PageScheduler* WebViewImpl::Scheduler() const {
return GetPage()->GetPageScheduler();
}
@@ -155,10 +155,10 @@ index b5a7e1b177f031837f670c26bff7394315eb6ea5..ed63aa041733e2fb09d77a219c93c322
// Do not throttle if the page should be painting.
bool is_visible =
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h
index b2ad789e53146b06e0e416f2dcf384cf7e9c17ae..838c67ac5b02c427858febbfbddf25fb03632b37 100644
index f638ff2647fdeee4e1e180e1394b49a91227022b..698d1f78a0b2cabee59e3a7f0619935bea010b36 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.h
+++ b/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -446,6 +446,7 @@ class CORE_EXPORT WebViewImpl final : public WebView,
@@ -437,6 +437,7 @@ class CORE_EXPORT WebViewImpl final : public WebView,
LocalDOMWindow* PagePopupWindow() const;
PageScheduler* Scheduler() const override;
@@ -166,7 +166,7 @@ index b2ad789e53146b06e0e416f2dcf384cf7e9c17ae..838c67ac5b02c427858febbfbddf25fb
void SetVisibilityState(mojom::blink::PageVisibilityState visibility_state,
bool is_initial_state) override;
mojom::blink::PageVisibilityState GetVisibilityState() override;
@@ -957,6 +958,8 @@ class CORE_EXPORT WebViewImpl final : public WebView,
@@ -927,6 +928,8 @@ class CORE_EXPORT WebViewImpl final : public WebView,
// If true, we send IPC messages when |preferred_size_| changes.
bool send_preferred_size_changes_ = false;

View File

@@ -10,7 +10,7 @@ so we can remove this patch once we migrate our code to use
os_crypt async.
diff --git a/components/os_crypt/sync/BUILD.gn b/components/os_crypt/sync/BUILD.gn
index 3b1c34e213b0990b8f0823228a1a02c5bf0c7198..ea48241edef8eaf7bfc8285d7cbbea567d3a7cbb 100644
index e90e275b33bb88c6b1e8a7044ca6eb382460b467..6a2266a01a6283bf239001dbd21e638bf62e10d5 100644
--- a/components/os_crypt/sync/BUILD.gn
+++ b/components/os_crypt/sync/BUILD.gn
@@ -10,6 +10,7 @@ import("//components/os_crypt/sync/features.gni")
@@ -19,5 +19,5 @@ index 3b1c34e213b0990b8f0823228a1a02c5bf0c7198..ea48241edef8eaf7bfc8285d7cbbea56
visibility = [
+ "//electron:*",
"//chrome/browser",
"//chrome/browser/net:impl",
"//chrome/test:test_support",
"//components/os_crypt/async/browser:dpapi_key_provider",

View File

@@ -8,10 +8,10 @@ WebPreferences of in-process child windows, rather than relying on
process-level command line switches, as before.
diff --git a/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc b/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc
index 9ab1b47509c8b72b7844e83f1d69499d13e26837..8fe07713a01123cc21d2649f8a3e9347a49a2bb8 100644
index 6f8c4ba8b32b5c9fb9bca783ef720e0102c827e6..430d6bab3fb20866af6bf5af8515c3900a0d7ede 100644
--- a/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc
+++ b/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc
@@ -149,6 +149,19 @@ bool StructTraits<blink::mojom::WebPreferencesDataView,
@@ -150,6 +150,19 @@ bool StructTraits<blink::mojom::WebPreferencesDataView,
out->v8_cache_options = data.v8_cache_options();
out->record_whole_document = data.record_whole_document();
out->stylus_handwriting_enabled = data.stylus_handwriting_enabled();
@@ -32,7 +32,7 @@ index 9ab1b47509c8b72b7844e83f1d69499d13e26837..8fe07713a01123cc21d2649f8a3e9347
out->accelerated_video_decode_enabled =
data.accelerated_video_decode_enabled();
diff --git a/third_party/blink/public/common/web_preferences/web_preferences.h b/third_party/blink/public/common/web_preferences/web_preferences.h
index efcb7d9457045c2d58ecec4b68d7c4547cb5d08a..e37fa2e8cb0896e61ef11259df13d97b8fbff548 100644
index dbff6419e64087a39a906f6cb7df63e2d56c099f..2e03035a0533b39caaa1f50b7605b59b2ae325de 100644
--- a/third_party/blink/public/common/web_preferences/web_preferences.h
+++ b/third_party/blink/public/common/web_preferences/web_preferences.h
@@ -10,6 +10,7 @@
@@ -43,9 +43,9 @@ index efcb7d9457045c2d58ecec4b68d7c4547cb5d08a..e37fa2e8cb0896e61ef11259df13d97b
#include "build/build_config.h"
#include "net/nqe/effective_connection_type.h"
#include "third_party/blink/public/common/common_export.h"
@@ -481,6 +482,19 @@ struct BLINK_COMMON_EXPORT WebPreferences {
bool should_screenshot_on_mainframe_same_doc_navigation = true;
#endif // BUILDFLAG(IS_ANDROID)
@@ -492,6 +493,19 @@ struct BLINK_COMMON_EXPORT WebPreferences {
// Consumed only in chrome/renderer/ (not by Blink).
bool is_indigo_onboarding = false;
+ // Begin Electron-specific WebPreferences.
+ bool context_isolation = false;
@@ -64,7 +64,7 @@ index efcb7d9457045c2d58ecec4b68d7c4547cb5d08a..e37fa2e8cb0896e61ef11259df13d97b
// chrome, except for the cases where it would require lots of extra work for
// the embedder to use the same default value.
diff --git a/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h b/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h
index fade1dd1310d8339fff45b9ae74ebff4673eec37..ea3f8f3e30f76ebf71ed470f43e4f61995829932 100644
index 2b8ad78d33a3cfc810e280db7a8f1b5aa1e1cc83..4f9793d751ba3d7796111a641411c74a797797d7 100644
--- a/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h
+++ b/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h
@@ -8,6 +8,7 @@
@@ -75,7 +75,7 @@ index fade1dd1310d8339fff45b9ae74ebff4673eec37..ea3f8f3e30f76ebf71ed470f43e4f619
#include "mojo/public/cpp/bindings/struct_traits.h"
#include "net/nqe/effective_connection_type.h"
#include "third_party/blink/public/common/common_export.h"
@@ -440,6 +441,52 @@ struct BLINK_COMMON_EXPORT StructTraits<blink::mojom::WebPreferencesDataView,
@@ -444,6 +445,52 @@ struct BLINK_COMMON_EXPORT StructTraits<blink::mojom::WebPreferencesDataView,
return r.stylus_handwriting_enabled;
}
@@ -129,7 +129,7 @@ index fade1dd1310d8339fff45b9ae74ebff4673eec37..ea3f8f3e30f76ebf71ed470f43e4f619
return r.cookie_enabled;
}
diff --git a/third_party/blink/public/mojom/webpreferences/web_preferences.mojom b/third_party/blink/public/mojom/webpreferences/web_preferences.mojom
index c637783517d250b7aa6f34af11fd3ca804a2a705..0268d33da3150a37ca8206695a5f324d8fde22e6 100644
index 3003eff973c9323a427b9ddddcd1f445223cd383..83e360b74fbe7d8ef922f023ebc319e891059c3f 100644
--- a/third_party/blink/public/mojom/webpreferences/web_preferences.mojom
+++ b/third_party/blink/public/mojom/webpreferences/web_preferences.mojom
@@ -4,6 +4,7 @@
@@ -140,7 +140,7 @@ index c637783517d250b7aa6f34af11fd3ca804a2a705..0268d33da3150a37ca8206695a5f324d
import "mojo/public/mojom/base/string16.mojom";
import "mojo/public/mojom/base/time.mojom";
import "skia/public/mojom/skcolor.mojom";
@@ -222,6 +223,19 @@ struct WebPreferences {
@@ -223,6 +224,19 @@ struct WebPreferences {
// If true, stylus handwriting recognition to text input will be available in
// editable input fields which are non-password type.
bool stylus_handwriting_enabled;

View File

@@ -6,7 +6,7 @@ Subject: Allow setting secondary label via SimpleMenuModel
Builds on https://chromium-review.googlesource.com/c/chromium/src/+/2208976
diff --git a/ui/menus/simple_menu_model.cc b/ui/menus/simple_menu_model.cc
index 069f5000b8b648fefba2b8970bb88a8daae0ba5b..652fcecf32b05193bfb31a6a1002bcb019c3077f 100644
index 12e6479770d24e4943dce7e797e0185b010ace8b..967d7c42a998a31a940ccc0ac0786300d70d8a34 100644
--- a/ui/menus/simple_menu_model.cc
+++ b/ui/menus/simple_menu_model.cc
@@ -57,6 +57,11 @@ std::u16string SimpleMenuModel::Delegate::GetLabelForCommandId(
@@ -21,33 +21,17 @@ index 069f5000b8b648fefba2b8970bb88a8daae0ba5b..652fcecf32b05193bfb31a6a1002bcb0
ImageModel SimpleMenuModel::Delegate::GetIconForCommandId(
int command_id) const {
return ImageModel();
@@ -350,6 +355,11 @@ void SimpleMenuModel::SetAcceleratorAt(size_t index,
MenuItemsChanged();
@@ -469,6 +474,8 @@ std::u16string SimpleMenuModel::GetLabelAt(size_t index) const {
}
+void SimpleMenuModel::SetSecondaryLabel(size_t index, const std::u16string& secondary_label) {
+ items_[ValidateItemIndex(index)].secondary_label = secondary_label;
+ MenuItemsChanged();
+}
+
void SimpleMenuModel::SetMinorText(size_t index,
const std::u16string& minor_text) {
items_[ValidateItemIndex(index)].minor_text = minor_text;
@@ -462,6 +472,12 @@ std::u16string SimpleMenuModel::GetLabelAt(size_t index) const {
return items_[ValidateItemIndex(index)].label;
}
+std::u16string SimpleMenuModel::GetSecondaryLabelAt(size_t index) const {
std::u16string SimpleMenuModel::GetSecondaryLabelAt(size_t index) const {
+ if (IsItemDynamicAt(index))
+ return delegate_->GetSecondaryLabelForCommandId(GetCommandIdAt(index));
+ return items_[ValidateItemIndex(index)].secondary_label;
+}
+
std::u16string SimpleMenuModel::GetMinorTextAt(size_t index) const {
return items_[ValidateItemIndex(index)].minor_text;
return items_[ValidateItemIndex(index)].secondary_label;
}
diff --git a/ui/menus/simple_menu_model.h b/ui/menus/simple_menu_model.h
index 78e2be4c0146c09eccb23edecc304119095c4761..17fe4df6737f0d7b59ef955c27854c3a08a18a59 100644
index cd41d9ef6d306332dbe09f7821ea8e7bdd401ba4..77c616d267759f707e917e8efe61a239154f03f8 100644
--- a/ui/menus/simple_menu_model.h
+++ b/ui/menus/simple_menu_model.h
@@ -99,6 +99,7 @@ class COMPONENT_EXPORT(UI_MENUS) SimpleMenuModel : public MenuModel {
@@ -58,29 +42,3 @@ index 78e2be4c0146c09eccb23edecc304119095c4761..17fe4df6737f0d7b59ef955c27854c3a
// Gets the icon for the item with the specified id.
virtual ImageModel GetIconForCommandId(int command_id) const;
@@ -224,6 +225,9 @@ class COMPONENT_EXPORT(UI_MENUS) SimpleMenuModel : public MenuModel {
// former is set).
void SetAcceleratorAt(size_t index, const ui::Accelerator& accelerator);
+ // Sets the secondary_label for the item at |index|.
+ void SetSecondaryLabel(size_t index, const std::u16string& secondary_label);
+
// Sets the minor text for the item at |index|.
void SetMinorText(size_t index, const std::u16string& minor_text);
@@ -279,6 +283,7 @@ class COMPONENT_EXPORT(UI_MENUS) SimpleMenuModel : public MenuModel {
ui::MenuSeparatorType GetSeparatorTypeAt(size_t index) const override;
int GetCommandIdAt(size_t index) const override;
std::u16string GetLabelAt(size_t index) const override;
+ std::u16string GetSecondaryLabelAt(size_t index) const override;
std::u16string GetMinorTextAt(size_t index) const override;
bool GetMinorTextIsUrlAt(size_t index) const override;
@@ -329,6 +334,7 @@ class COMPONENT_EXPORT(UI_MENUS) SimpleMenuModel : public MenuModel {
ItemType type = TYPE_COMMAND;
std::u16string label;
ui::Accelerator accelerator;
+ std::u16string secondary_label;
std::u16string minor_text;
bool minor_text_is_url = false;
ImageModel minor_icon;

View File

@@ -49,10 +49,10 @@ index 9827a89c56141596fde57b78f9c9894f273db83e..cedb4bd8217a0ad3ab07d85421e1850b
// its owning reference back to our owning LocalFrame.
client_->Detached(type);
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index 4c38cd881b5a81b7939f61688f05949be799f008..8970537416e171d513bc9c015706fb18a574eab6 100644
index 1580d7224cc152ee4453496dffbc1f9df984de36..98d28eaada654b52d40c144d597039410540f290 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -758,10 +758,6 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
@@ -756,10 +756,6 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
}
DCHECK(!view_ || !view_->IsAttached());
@@ -63,7 +63,7 @@ index 4c38cd881b5a81b7939f61688f05949be799f008..8970537416e171d513bc9c015706fb18
if (!Client())
return false;
@@ -817,6 +813,11 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
@@ -814,6 +810,11 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
DCHECK(!view_->IsAttached());
Client()->WillBeDetached();

View File

@@ -6,7 +6,7 @@ Subject: boringssl BUILD.gn
Build BoringSSL with some extra functions that nodejs needs.
diff --git a/third_party/boringssl/BUILD.gn b/third_party/boringssl/BUILD.gn
index 708bb2066269b57ff54649638938a1719d657b6a..7485078ed7a4cfdc8bfecf2d3a4a009e10ca4893 100644
index 30aa77bdf5d5f9a30404290cd94eee88275e3c96..25be8463ba34227e269ce40d38cd0105b8aef5b3 100644
--- a/third_party/boringssl/BUILD.gn
+++ b/third_party/boringssl/BUILD.gn
@@ -48,6 +48,21 @@ all_sources = bcm_internal_headers + bcm_sources + crypto_internal_headers +

View File

@@ -8,7 +8,7 @@ categories in use are known / declared. This patch is required for us
to introduce a new Electron category for Electron-specific tracing.
diff --git a/base/trace_event/builtin_categories.h b/base/trace_event/builtin_categories.h
index 440349df6c5767fe3f93b51f78b33bf9d3bb5c1a..85c6f973788938b6a48a7a89e9fa803dc1030580 100644
index 8bc03cb77ebdfe991e0ebe05aa187dfdea8c2764..976221d0303036ecae500b7861931ff96e9ea0c1 100644
--- a/base/trace_event/builtin_categories.h
+++ b/base/trace_event/builtin_categories.h
@@ -133,6 +133,7 @@ PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE_WITH_ATTRS(

View File

@@ -6,10 +6,10 @@ Subject: build: allow electron to use exec_script
This is similar to the //build usecase so we're OK adding ourselves here
diff --git a/.gn b/.gn
index 0013a7fd5a260ea4f04f6421031a571c7bbf90b9..216974ae53ec574514abbfb0a1d7276a396380e5 100644
index 56bd5cad399cd5cfa38a20c72c357935c195d9cc..37cd230ba11d93685f30d7291bf3f34fd571355e 100644
--- a/.gn
+++ b/.gn
@@ -169,4 +169,28 @@ exec_script_allowlist =
@@ -169,6 +169,30 @@ exec_script_allowlist =
"//tools/gritsettings/BUILD.gn",
"//third_party/blink/renderer/build/scripts/scripts.gni",
@@ -38,3 +38,5 @@ index 0013a7fd5a260ea4f04f6421031a571c7bbf90b9..216974ae53ec574514abbfb0a1d7276a
+ "//third_party/electron_node/deps/zstd/unofficial.gni",
+ "//third_party/electron_node/src/inspector/unofficial.gni",
]
expand_directory_allowlist = build_dotfile_settings.expand_directory_allowlist

View File

@@ -11,10 +11,10 @@ This patch can (and should) be removed when we can prevent those symbols
from being stripped in the release build.
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni
index 9e7353df432d5de6c24c485579c1d99bc1dc5bb2..0d799db2dcd3dfd635b0b7f8e0142ef76ae29beb 100644
index d9cbf64ce68e21ea06a6bf2c213daa7d67b931f5..150736bcabec57bd262e0ebe1649096ba656b386 100644
--- a/build/config/compiler/compiler.gni
+++ b/build/config/compiler/compiler.gni
@@ -149,7 +149,7 @@ declare_args() {
@@ -151,7 +151,7 @@ declare_args() {
# Chrome's clang. crbug.com/1033839
use_thin_lto =
is_cfi || (is_clang && is_official_build && chrome_pgo_phase != 1 &&

View File

@@ -11,7 +11,7 @@ if we ever align our .pak file generation with Chrome we can remove this
patch.
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index 0af4d4b75d0519fabcb5d48bd9d5bd465bc80e92..eb6b23655afaa268f25d99301a0853aaecd23652 100644
index 48f28a61eac4b31c3d9be62100c00cadff84174c..6c2632d85db3d2115bc0c0fc3dc6970e680877c2 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -201,6 +201,12 @@ if (!is_android && !is_mac) {
@@ -28,10 +28,10 @@ index 0af4d4b75d0519fabcb5d48bd9d5bd465bc80e92..eb6b23655afaa268f25d99301a0853aa
":chrome_dll",
":chrome_exe_version",
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index e91f97276866bd500720962c74acaca2c22fff7c..22867153821d2b1e83feb1a2a7a6b8c26ba776eb 100644
index 684cc6c47f61e02831cfdb977b1719a0b0f899a5..ddbb1f4b58d8bee0b80410294c5a54d432d65a4f 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -7737,6 +7737,10 @@ test("unit_tests") {
@@ -7745,6 +7745,10 @@ test("unit_tests") {
"//chrome/notification_helper",
]
@@ -42,7 +42,7 @@ index e91f97276866bd500720962c74acaca2c22fff7c..22867153821d2b1e83feb1a2a7a6b8c2
deps += [
"//chrome:other_version",
"//chrome//services/util_win:unit_tests",
@@ -8711,6 +8715,10 @@ test("unit_tests") {
@@ -8683,6 +8687,10 @@ test("unit_tests") {
"../browser/performance_manager/policies/background_tab_loading_policy_unittest.cc",
]
@@ -53,7 +53,7 @@ index e91f97276866bd500720962c74acaca2c22fff7c..22867153821d2b1e83feb1a2a7a6b8c2
sources += [
# The importer code is not used on Android.
"../common/importer/firefox_importer_utils_unittest.cc",
@@ -8767,7 +8775,7 @@ test("unit_tests") {
@@ -8726,7 +8734,7 @@ test("unit_tests") {
# TODO(crbug.com/417513088): Maybe merge with the non-android `deps` declaration above?
deps += [
"../browser/screen_ai:screen_ai_install_state",

View File

@@ -7,7 +7,7 @@ These are variables we add to the root BUILDCONFIG so that they're available
everywhere, without having to import("//electron/.../flags.gni").
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn
index cc00f84630e063fee2b1897eced42c6a53a3a79e..5d4a82783dbe86636bbef47f2fb26ff9147ea57b 100644
index a4d71c98b0fe276ec698c67c7f51cc0371ed107c..f251e5d8eb873606193c903104adda0fc40e7446 100644
--- a/build/config/BUILDCONFIG.gn
+++ b/build/config/BUILDCONFIG.gn
@@ -123,6 +123,9 @@ if (current_os == "") {

View File

@@ -0,0 +1,90 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Fri, 24 Apr 2026 20:50:22 +0900
Subject: build: gn arg to support linker wrapper script on windows
Windows containers using BindFlt have a known bug with high-volume
concurrent file reads on relative paths. This seems to affect
the lld-link phase when jumped from 16->32 core ARC runners. Use the
wrapper to convert rsp file arguments to absolute paths.
Should be removed when associated container bug is addressed.
diff --git a/build/toolchain/win/toolchain.gni b/build/toolchain/win/toolchain.gni
index 99f4809b941406416f887e3d6f9b3729c96e969d..2bb7a2f466b8cb4d0ba6021bcfe1d9c6f53d868c 100644
--- a/build/toolchain/win/toolchain.gni
+++ b/build/toolchain/win/toolchain.gni
@@ -14,6 +14,12 @@ import("//build/toolchain/win/win_toolchain_data.gni")
assert(is_win, "Should only be running on Windows")
+declare_args() {
+ # Path to a Python script that wraps linker invocations to resolve relative
+ # file paths in response files to absolute paths.
+ win_abs_link_wrapper = ""
+}
+
# This tool will is used as a wrapper for various commands below.
_tool_wrapper_path =
rebase_path("//build/toolchain/win/tool_wrapper.py", root_build_dir)
@@ -141,7 +147,14 @@ template("msvc_toolchain") {
}
if (host_os != "win" || (use_lld && defined(invoker.sys_lib_flags))) {
- linker_wrapper = ""
+ if (win_abs_link_wrapper != "") {
+ _abs_link_wrapper_path =
+ rebase_path(win_abs_link_wrapper, root_build_dir)
+ linker_wrapper =
+ "\"$python_path\" $_abs_link_wrapper_path "
+ } else {
+ linker_wrapper = ""
+ }
sys_lib_flags = "${invoker.sys_lib_flags}"
# TODO(thakis): Remove once crbug.com/1300005 is fixed
@@ -356,6 +369,26 @@ template("msvc_toolchain") {
rustc_windows_args = " -Clinker=$link$rust_linkflags $rustc_common_args"
+ # When win_abs_link_wrapper is set, generate a .cmd wrapper that rustc
+ # will invoke as the "linker". The wrapper resolves relative file paths
+ # to absolute before calling the real lld-link
+ if (win_abs_link_wrapper != "") {
+ _abs_link_wrapper_py =
+ rebase_path(win_abs_link_wrapper, root_build_dir)
+ _rust_link_wrapper_cmd =
+ "$root_build_dir/abs_link_wrapper_" + target_name + ".cmd"
+ write_file(_rust_link_wrapper_cmd,
+ [
+ "@echo off",
+ "\"$python_path\" \"$_abs_link_wrapper_py\" \"$link\" %*",
+ "exit /b %ERRORLEVEL%",
+ ])
+ _rust_link_wrapper_rel =
+ rebase_path(_rust_link_wrapper_cmd)
+ rustc_windows_args =
+ " -Clinker=$_rust_link_wrapper_rel$rust_linkflags $rustc_common_args"
+ }
+
tool("rust_staticlib") {
libname = "{{output_dir}}/{{target_output_name}}{{output_extension}}"
rspfile = rustc_rsp_path
@@ -569,7 +602,16 @@ template("msvc_toolchain") {
tool("alink") {
rspfile = "{{output}}.rsp"
- command = "$linker_wrapper$lib \"/OUT:{{output}}\" /nologo {{arflags}} \"@$rspfile\""
+
+ # Don't use the abs_link_wrapper for alink. Thin archives store paths
+ # to .obj members; absolute paths break downstream consumers (e.g.
+ # rustc) that prepend the archive directory to member paths.
+ if (win_abs_link_wrapper != "") {
+ command = "$lib \"/OUT:{{output}}\" /nologo {{arflags}} \"@$rspfile\""
+ } else {
+ command =
+ "$linker_wrapper$lib \"/OUT:{{output}}\" /nologo {{arflags}} \"@$rspfile\""
+ }
description = "LIB {{output}}"
outputs = [
# Ignore {{output_extension}} and always use .lib, there's no reason to

View File

@@ -7,10 +7,10 @@ Build libc++ as static library to compile and pass
nan tests
diff --git a/buildtools/third_party/libc++/BUILD.gn b/buildtools/third_party/libc++/BUILD.gn
index 49bd8af6f4e5762c6059c2f8d2663683f350e386..f386b473b73ba83b383adbb90acb98709f5a3bf1 100644
index ce38758afaa191b394a014a68aded12417aa72a1..d846b89156182073cff1aaac6cd32888a73867b2 100644
--- a/buildtools/third_party/libc++/BUILD.gn
+++ b/buildtools/third_party/libc++/BUILD.gn
@@ -480,6 +480,7 @@ target(libcxx_target_type, "libc++") {
@@ -456,6 +456,7 @@ target(libcxx_target_type, "libc++") {
# need to explicitly depend on libc++.
visibility = [
"//build/config:common_deps",

View File

@@ -15,7 +15,7 @@ References:
* third_party/libc++/src/include/__configuration/abi.h
diff --git a/buildtools/third_party/libc++/__config_site b/buildtools/third_party/libc++/__config_site
index 8e1fb11322711b10256b3eaf5f0c30dabd18ff4f..5b26dbaf522b7f95ccdf4b40573db69b22603235 100644
index c94ace80e45de876a175506b66d4b96dba2f7c02..359f8688158fd5b57e819893047524dbbb1b1b45 100644
--- a/buildtools/third_party/libc++/__config_site
+++ b/buildtools/third_party/libc++/__config_site
@@ -18,7 +18,11 @@

View File

@@ -9,10 +9,10 @@ potentially prevent a window from being created.
TODO(loc): this patch is currently broken.
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index ac474e220d411dec278c40448f038b25e6788d2a..e4ff8f11bed9e53f3134068492ac94b4c9bb4df2 100644
index b4b82c13852232443f15785a1e8f2820c20fa0ca..80d3b463984813ac1459b02fac41ee995b437353 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -10228,6 +10228,7 @@ void RenderFrameHostImpl::CreateNewWindow(
@@ -10262,6 +10262,7 @@ void RenderFrameHostImpl::CreateNewWindow(
last_committed_origin_, params->window_container_type,
params->target_url, params->referrer.To<Referrer>(),
params->frame_name, params->disposition, *params->features,
@@ -21,10 +21,10 @@ index ac474e220d411dec278c40448f038b25e6788d2a..e4ff8f11bed9e53f3134068492ac94b4
&no_javascript_access);
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 3e0c8bd308d8a947a2bd295a2d83e385e53853fb..4e91b3aeb5630476c660e8814e2fd9d92c5a9ca1 100644
index 3dbcb361d8f41f8109ae7e544f6558fdda0997fe..86273f84bf55276c3b6ae91397332a019874c2af 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -5501,6 +5501,10 @@ FrameTree* WebContentsImpl::CreateNewWindow(
@@ -5507,6 +5507,10 @@ FrameTree* WebContentsImpl::CreateNewWindow(
create_params.initially_hidden = renderer_started_hidden;
create_params.initial_popup_url = params.target_url;
@@ -35,7 +35,7 @@ index 3e0c8bd308d8a947a2bd295a2d83e385e53853fb..4e91b3aeb5630476c660e8814e2fd9d9
// Even though all codepaths leading here are in response to a renderer
// trying to open a new window, if the new window ends up in a different
// browsing instance, then the RenderViewHost, RenderWidgetHost,
@@ -5555,6 +5559,12 @@ FrameTree* WebContentsImpl::CreateNewWindow(
@@ -5561,6 +5565,12 @@ FrameTree* WebContentsImpl::CreateNewWindow(
// Sets the newly created WebContents WindowOpenDisposition.
new_contents_impl->original_window_open_disposition_ = params.disposition;
@@ -48,7 +48,7 @@ index 3e0c8bd308d8a947a2bd295a2d83e385e53853fb..4e91b3aeb5630476c660e8814e2fd9d9
// If the new frame has a name, make sure any SiteInstances that can find
// this named frame have proxies for it. Must be called after
// SetSessionStorageNamespace, since this calls CreateRenderView, which uses
@@ -5596,12 +5606,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
@@ -5602,12 +5612,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
AddWebContentsDestructionObserver(new_contents_impl);
}
@@ -62,7 +62,7 @@ index 3e0c8bd308d8a947a2bd295a2d83e385e53853fb..4e91b3aeb5630476c660e8814e2fd9d9
new_contents_impl, opener, params.target_url,
params.referrer.To<Referrer>(), params.disposition,
diff --git a/content/common/frame.mojom b/content/common/frame.mojom
index 444fa7009d0db33470cac9ab9cfdc23ceacec942..ab9aeb852e5ea89583284386d9a78a3e3e17a310 100644
index a2566982ff81db5166e41243232e23af94dc3c05..ff5c410e78fb171963122f8a24802b7bf89a2b67 100644
--- a/content/common/frame.mojom
+++ b/content/common/frame.mojom
@@ -617,6 +617,10 @@ struct CreateNewWindowParams {
@@ -77,10 +77,10 @@ index 444fa7009d0db33470cac9ab9cfdc23ceacec942..ab9aeb852e5ea89583284386d9a78a3e
// Operation result when the renderer asks the browser to create a new window.
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index e806de04ca92cb8351e9a242a5241c0d4286da97..d0b3e4bc348921df7e6446dbc1f14860b8a84d87 100644
index 0713f0cbbbd93be954758f0b1ddb20b9f9701228..9d2e8a70a4307f1d055b356e6bccd98f3e56109c 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -854,6 +854,8 @@ bool ContentBrowserClient::CanCreateWindow(
@@ -858,6 +858,8 @@ bool ContentBrowserClient::CanCreateWindow(
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
@@ -90,10 +90,10 @@ index e806de04ca92cb8351e9a242a5241c0d4286da97..d0b3e4bc348921df7e6446dbc1f14860
bool opener_suppressed,
bool* no_javascript_access) {
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 70588ccd619ac7969918771bccf5c054320e4f6f..eb684232648424fab4ba73b1fc813b0b3f8b809b 100644
index 124994cc22f2923247b831e30c3241751c7b4c92..9d164c9386fe1906216db656e3972ef5dc50c583 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -205,6 +205,7 @@ class NetworkService;
@@ -204,6 +204,7 @@ class NetworkService;
class TrustedURLLoaderHeaderClient;
} // namespace mojom
struct ResourceRequest;
@@ -101,7 +101,7 @@ index 70588ccd619ac7969918771bccf5c054320e4f6f..eb684232648424fab4ba73b1fc813b0b
} // namespace network
namespace sandbox {
@@ -1406,6 +1407,8 @@ class CONTENT_EXPORT ContentBrowserClient {
@@ -1411,6 +1412,8 @@ class CONTENT_EXPORT ContentBrowserClient {
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
@@ -111,10 +111,10 @@ index 70588ccd619ac7969918771bccf5c054320e4f6f..eb684232648424fab4ba73b1fc813b0b
bool opener_suppressed,
bool* no_javascript_access);
diff --git a/content/public/browser/web_contents_delegate.cc b/content/public/browser/web_contents_delegate.cc
index 0c0672e0a2d05d5dff31ae171f1a3af1d20b3019..51be0b86d083318f01a9ebe76fb7d1fb60cd72fd 100644
index 8f35d9844d79375a80758daee10c63083fb4460e..f40037ac4e232810d3bc814f6b744e31e7c3fc1a 100644
--- a/content/public/browser/web_contents_delegate.cc
+++ b/content/public/browser/web_contents_delegate.cc
@@ -34,6 +34,17 @@ namespace content {
@@ -35,6 +35,17 @@ namespace content {
WebContentsDelegate::WebContentsDelegate() = default;
@@ -133,7 +133,7 @@ index 0c0672e0a2d05d5dff31ae171f1a3af1d20b3019..51be0b86d083318f01a9ebe76fb7d1fb
WebContents* source,
const OpenURLParams& params,
diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h
index 0650197909d484b8a0f48ab61b22471c71bce0e8..29c380d7845aab1a7b3417e0d3940ea00460260b 100644
index 91ecedfc2aab50aa1aa54acdbe1b3f67041c75ce..b4602cf88acc2989b7e44543cd0e6296828f02ed 100644
--- a/content/public/browser/web_contents_delegate.h
+++ b/content/public/browser/web_contents_delegate.h
@@ -18,6 +18,7 @@
@@ -144,7 +144,7 @@ index 0650197909d484b8a0f48ab61b22471c71bce0e8..29c380d7845aab1a7b3417e0d3940ea0
#include "content/public/browser/eye_dropper.h"
#include "content/public/browser/fullscreen_types.h"
#include "content/public/browser/invalidate_type.h"
@@ -29,6 +30,7 @@
@@ -28,6 +29,7 @@
#include "content/public/browser/select_audio_output_request.h"
#include "content/public/browser/serial_chooser.h"
#include "content/public/browser/storage_partition_config.h"
@@ -170,25 +170,25 @@ index 0650197909d484b8a0f48ab61b22471c71bce0e8..29c380d7845aab1a7b3417e0d3940ea0
// typically happens when popups are created.
virtual void WebContentsCreated(WebContents* source_contents,
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 5936c5eaa081abde7f7c26cc990a122622e46908..ab959e66f8841d7367863bb13d6c7a0854d0df23 100644
index c5bb0593bcb16cb275bfafd99212f53b525b6c2a..2f86c18cac89d5b29fb21c93ab575e304dd57173 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -6845,6 +6845,10 @@ WebView* RenderFrameImpl::CreateNewWindow(
@@ -6855,6 +6855,10 @@ WebView* RenderFrameImpl::CreateNewWindow(
params->started_by_ad =
GetWebFrame()->IsAdFrame() || GetWebFrame()->IsAdScriptInStack();
+ params->raw_features = features.raw_features.Utf8(
+ WebString::UTF8ConversionMode::kStrictReplacingErrorsWithFFFD);
+ WebString::Utf8ConversionMode::kStrictReplacingErrors);
+ params->body = GetRequestBodyForWebURLRequest(request);
+
// We preserve this information before sending the message since |params| is
// moved on send.
bool is_background_tab =
diff --git a/content/web_test/browser/web_test_content_browser_client.cc b/content/web_test/browser/web_test_content_browser_client.cc
index 9453418ab164904cb9d75930d649abe21b94bb03..b2acd05882e8dfb04e5a75b249705c1a15209056 100644
index 4e16ac38a721bf963810727bb673af2a5d6deca7..0894fe76d5b78908017b4cfdc16e3e0490debf28 100644
--- a/content/web_test/browser/web_test_content_browser_client.cc
+++ b/content/web_test/browser/web_test_content_browser_client.cc
@@ -540,6 +540,8 @@ bool WebTestContentBrowserClient::CanCreateWindow(
@@ -543,6 +543,8 @@ bool WebTestContentBrowserClient::CanCreateWindow(
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
@@ -224,10 +224,10 @@ index d92bab531c12c62a5321a23f4a0cb89691668127..2060e04795ba8e7a923fd0fe3485b8c5
} // namespace blink
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index 51f03729c2d40a225dbcfc42091d44f78f77d971..780ee21199701b01a97932cd4a59aeb5db98017b 100644
index f442c8d8e331b9f608db69a144aaae87ee0342a7..af810b2904870e37e7609980b1708b269776c791 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -2342,6 +2342,8 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
@@ -2327,6 +2327,8 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
WebWindowFeatures window_features =
GetWindowFeaturesFromString(features, entered_window);

View File

@@ -18,7 +18,7 @@ index 870c721e8048f70e47bb79cd0b94f8afe1eea50a..14bc85e912fe6ad90656086b2aa1f7b5
/google_apis/gcm/gcm.xml
/googleurl
diff --git a/third_party/.gitignore b/third_party/.gitignore
index 0b3cc63da588d371a6416f8158ad79014c6364c3..a33362e439d5d9cb4f3f0ff4ec77d14f3bda9387 100644
index 0695483330b74430354fbea912b501b4d9b027e1..84c01b161826c62a36b80c843693630a2010727b 100644
--- a/third_party/.gitignore
+++ b/third_party/.gitignore
@@ -45,7 +45,9 @@
@@ -31,7 +31,7 @@ index 0b3cc63da588d371a6416f8158ad79014c6364c3..a33362e439d5d9cb4f3f0ff4ec77d14f
/espresso/lib/
/eyesfree/src
/fast_float/src
@@ -94,6 +96,7 @@
@@ -93,6 +95,7 @@
/mocha
/mockito/src
/nacl_sdk_binaries/
@@ -39,7 +39,7 @@ index 0b3cc63da588d371a6416f8158ad79014c6364c3..a33362e439d5d9cb4f3f0ff4ec77d14f
/ninja
/node/*.tar.gz
/node/linux/
@@ -139,7 +142,7 @@
@@ -138,7 +141,7 @@
/spirv-cross/src
/spirv-headers/src
/spirv-tools/src

View File

@@ -0,0 +1,34 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Electron Scripts <scripts@electron>
Date: Sat, 25 Apr 2026 21:10:03 -0500
Subject: chore: exclude upstream scripting API when building Electron
Electron provides its own implementation of the Scripting API at
shell/browser/extensions/api/scripting/ that includes Electron-specific
modifications. CL 7784831 moved the upstream implementation from
//chrome to //extensions, which caused it to be transitively linked
into Electron, resulting in duplicate symbols.
Exclude the upstream sources when is_electron_build is set.
diff --git a/extensions/browser/api/scripting/BUILD.gn b/extensions/browser/api/scripting/BUILD.gn
index 14d18bfbc36673f3eb9ffe0777d34ddd2163af0d..cff84c1a9e713e2845b2331913dde9be730305b1 100644
--- a/extensions/browser/api/scripting/BUILD.gn
+++ b/extensions/browser/api/scripting/BUILD.gn
@@ -12,6 +12,16 @@ source_set("scripting") {
"scripting_api.cc",
"scripting_api.h",
]
+
+ # Electron provides its own scripting API implementation in
+ # shell/browser/extensions/api/scripting/.
+ if (is_electron_build) {
+ sources -= [
+ "scripting_api.cc",
+ "scripting_api.h",
+ ]
+ }
+
public_deps = [
"//extensions/browser:browser_sources",
"//extensions/common/api",

View File

@@ -8,10 +8,10 @@ where callsites that deal with multiple contexts need to distinguish
the current isolate.
diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h
index d64fef6bfc37264dcdc1bbea22eb5c4e099553dd..41d40326505c4ced9837df7f03b791c9435124bf 100644
index cde924d79c67e9312f393c54c45bd6fc92509d0f..72c4d2f042afd428f2bf945bf54de873f256ca21 100644
--- a/content/public/renderer/content_renderer_client.h
+++ b/content/public/renderer/content_renderer_client.h
@@ -382,6 +382,7 @@ class CONTENT_EXPORT ContentRendererClient {
@@ -381,6 +381,7 @@ class CONTENT_EXPORT ContentRendererClient {
// WillDestroyServiceWorkerContextOnWorkerThread() is called.
virtual void WillEvaluateServiceWorkerOnWorkerThread(
blink::WebServiceWorkerContextProxy* context_proxy,
@@ -20,7 +20,7 @@ index d64fef6bfc37264dcdc1bbea22eb5c4e099553dd..41d40326505c4ced9837df7f03b791c9
int64_t service_worker_version_id,
const GURL& service_worker_scope,
diff --git a/content/public/renderer/render_frame_observer.h b/content/public/renderer/render_frame_observer.h
index 1d03dc809d4c18f24314d94811e0bf527aa7b5b4..16030bcecb2e39b8870144ce7c3d11dd4c7fb15e 100644
index 1b8541bfa56a7e53c8396c29ea45a0b5af89ef81..28ffec368e5d6bc1744605e9dda7fc685eee44f4 100644
--- a/content/public/renderer/render_frame_observer.h
+++ b/content/public/renderer/render_frame_observer.h
@@ -143,7 +143,8 @@ class CONTENT_EXPORT RenderFrameObserver {
@@ -34,10 +34,10 @@ index 1d03dc809d4c18f24314d94811e0bf527aa7b5b4..16030bcecb2e39b8870144ce7c3d11dd
virtual void DidClearWindowObject() {}
virtual void DidChangeScrollOffset() {}
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 5279ba15f45bd7634b5f24553ad64c0069318cc0..2840f22e2b8b4aae09a06774a70f2ec7340536d9 100644
index 93ee72d4eccd314388d0283249bc3c784559d9b4..859cea7d1d539822f21bc7ac7f391dd60c3ee249 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -4739,10 +4739,11 @@ void RenderFrameImpl::DidInstallConditionalFeatures(
@@ -4741,10 +4741,11 @@ void RenderFrameImpl::DidInstallConditionalFeatures(
observer.DidInstallConditionalFeatures(context, world_id);
}
@@ -52,10 +52,10 @@ index 5279ba15f45bd7634b5f24553ad64c0069318cc0..2840f22e2b8b4aae09a06774a70f2ec7
void RenderFrameImpl::DidChangeScrollOffset() {
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 2ce05bce0a02338aba018c18f0a808a4eb392ff4..2736b65de7f0a6e4cd2d56970d35687da8fcab6b 100644
index a6abdca5a4fd91afa7af007e4c595fe69bbf8821..48ba5ec1653e0372c4dafdbb42af50aaa6ee12db 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -609,7 +609,8 @@ class CONTENT_EXPORT RenderFrameImpl
@@ -607,7 +607,8 @@ class CONTENT_EXPORT RenderFrameImpl
int world_id) override;
void DidInstallConditionalFeatures(v8::Local<v8::Context> context,
int world_id) override;
@@ -103,7 +103,7 @@ index 8482d7fab12634e6b9a8d5f9bab6c7e428bb99ee..4f131fbfc9350352bce4430f92b9f2cf
void WillInitializeWorkerContext() override;
void WillDestroyWorkerContext(v8::Local<v8::Context> context) override;
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc
index fd3960fce4c61c5c530c817bd12e1ba1698b8db6..48a159d7d5ea57b4533fdaf38fe79a74c490207a 100644
index 2ec5cee9b3bb1f80b8313f3515a1f636117ae751..ebc88b63a0cd5e309df220796e0433f81b08b9e4 100644
--- a/extensions/renderer/dispatcher.cc
+++ b/extensions/renderer/dispatcher.cc
@@ -530,6 +530,7 @@ void Dispatcher::DidInitializeServiceWorkerContextOnWorkerThread(
@@ -127,7 +127,7 @@ index c2a6eb257469647183167dad78f1ea42fa3922bb..3423e3a8315c5fc5958ec75adf3a844f
int64_t service_worker_version_id,
const GURL& service_worker_scope,
diff --git a/extensions/renderer/extension_frame_helper.cc b/extensions/renderer/extension_frame_helper.cc
index 1ab0e8afc84b8e14f3a7f241f8d24ceac0abf188..2d1dbc6f57a0c6ba91194dde5da4de9d0bd5d383 100644
index 5273756a5fca9337b2bffa61e09b988fe7ba3f1b..1e26053159afd86852b10ee11ac76ac5e858fc54 100644
--- a/extensions/renderer/extension_frame_helper.cc
+++ b/extensions/renderer/extension_frame_helper.cc
@@ -449,6 +449,7 @@ void ExtensionFrameHelper::DidCreateScriptContext(
@@ -167,10 +167,10 @@ index f96781a047056876b030581b539be0507acc3a1c..cd9be80be2500a001b1895c81ee597dd
// Called when initial script evaluation finished for the main script.
// |success| is true if the evaluation completed with no uncaught exception.
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h
index 27b21f02d2dbfd60cb64f09be393b0e50928756f..c8da817ffab883573ae2dcfb6fb02d2baf8bcdaf 100644
index 222278059beb1681c1d8e2a93e33279d4194227b..f68b1f841e20a78e3a109b61b11fd1446c63a026 100644
--- a/third_party/blink/public/web/web_local_frame_client.h
+++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -679,7 +679,8 @@ class BLINK_EXPORT WebLocalFrameClient {
@@ -674,7 +674,8 @@ class BLINK_EXPORT WebLocalFrameClient {
int32_t world_id) {}
// WebKit is about to release its reference to a v8 context for a frame.
@@ -200,10 +200,10 @@ index 0787bc8a602c60e5b42933813baa6b9d923c9823..c4adcc6083e09e56416587fbcde10c90
->ContextWillBeDestroyed(script_state_);
if (next_status == Lifecycle::kV8MemoryIsForciblyPurged ||
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h
index ae565a4d3fdc2d02e2c7a27312d8296bbdf61e0b..f54cc6c10a957a2218258f72de2b92a2ba96f9ea 100644
index bc8850ea6d8b18d7cbf33bdfda66530cf6a5d1b2..13a406e3e7eaa557f833d621a225f0348f9e2e5d 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client.h
+++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -312,7 +312,8 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
@@ -313,7 +313,8 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
int32_t world_id) = 0;
virtual void DidInstallConditionalFeatures(v8::Local<v8::Context>,
int32_t world_id) = 0;
@@ -214,7 +214,7 @@ index ae565a4d3fdc2d02e2c7a27312d8296bbdf61e0b..f54cc6c10a957a2218258f72de2b92a2
virtual bool AllowScriptExtensions() = 0;
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
index aaf03855e53d5529bb51d70cd9b4355d68fed48c..a889202f30bc4a3b6bc7dc3fc7b4fc5058684bcb 100644
index b2df880309120ba650c18b5718fe22739aed3373..6a4fcdfba8a8a785aac2e8bb3b1a51a84d2f422a 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
@@ -309,10 +309,11 @@ void LocalFrameClientImpl::DidInstallConditionalFeatures(
@@ -231,7 +231,7 @@ index aaf03855e53d5529bb51d70cd9b4355d68fed48c..a889202f30bc4a3b6bc7dc3fc7b4fc50
}
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.h b/third_party/blink/renderer/core/frame/local_frame_client_impl.h
index cc593168947e469b599794260692e1deb9b5f1a5..6b360ad1c123f5e6fef9b127ae55968456172776 100644
index 4f225120efa4e149cac9d23761fa3842f15dc162..ddce34b5e275f5259b1d2d939583191ac9a45ec0 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client_impl.h
+++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.h
@@ -80,7 +80,8 @@ class CORE_EXPORT LocalFrameClientImpl final : public LocalFrameClient {
@@ -245,10 +245,10 @@ index cc593168947e469b599794260692e1deb9b5f1a5..6b360ad1c123f5e6fef9b127ae559684
// Returns true if we should allow register V8 extensions to be added.
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h
index 5a0f42b4b7e5eb67d476c948caa201ee6fc7b3ca..1a0562ad9ccfd414d6295b597b9d8094df384ff5 100644
index 24b317ef1f5df5999e6c2f4e456ba3ab81c5b3c6..229dd5ae1fb264f3a8819030fd9ce2450053cf05 100644
--- a/third_party/blink/renderer/core/loader/empty_clients.h
+++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -427,7 +427,8 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
@@ -428,7 +428,8 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
int32_t world_id) override {}
void DidInstallConditionalFeatures(v8::Local<v8::Context>,
int32_t world_id) override {}

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