Compare commits

...

11 Commits

Author SHA1 Message Date
John Kleinschmidt
8e077a09f3 ci: only run auto close on PRs targeting main branch (#50357) 2026-03-19 00:19:25 +00:00
John Kleinschmidt
95f0d8156b ci: test linux 64k (#49961) 2026-03-18 19:14:49 -04:00
Noah Gregory
b881f86c8f fix: always call the original impl in swizzled mousedown impls (#50096)
fix: always call the original implementation in swizzled mousedown implementations
2026-03-18 17:54:43 -04:00
John Kleinschmidt
5959ecc3ee ci: auto close PRs that do not fill out the required template (#50348) 2026-03-18 17:52:03 -04:00
John Kleinschmidt
a6a44692dc chore: Respect HTTP(S) proxy env variable for Yarn (#50322)
Respect HTTP(S) proxy env variable for Yarn

Co-authored-by: Filip Mösner <filip.mosner@seznam.cz>
2026-03-18 17:13:05 -04:00
John Beutner
12ea28c23e fix: ensure WebContents::WasShown runs when window is shown (#49421)
Avoids a freeze when failing to enter fullscreen on macOS.
2026-03-18 12:34:11 -04:00
Kyle Cutler
ade684dc35 fix: correctly track BaseWindow::IsActive() on MacOS (#49460)
fix: correctly set IsActive() in BaseWindow on MacOS
2026-03-18 11:47:19 -04:00
electron-roller[bot]
4ec6923898 chore: bump chromium to 148.0.7738.0 (main) (#50323)
* chore: bump chromium in DEPS to 148.0.7738.0

* chore: fixup patch indices

* 7664509: Migrate ServiceWorkerInfo to ChildProcessId

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

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2026-03-18 11:45:24 -04:00
Ryan Zimmerman
e86cd9da96 docs: fix markdown formatting in fuses.md (#50318)
* docs: fix markdown formatting in fuses.md

* Use bulleted list (was being run together on one line)
* Wrap ASCII diagram in code block

* docs: apply suggestions from code review

Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
Co-authored-by: Erick Zhao <erick@hotmail.ca>

* docs: fix misapplied suggestion

---------

Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
Co-authored-by: Erick Zhao <erick@hotmail.ca>
2026-03-18 10:47:52 -04:00
reito
d6db1a27af feat: add nv12 osr format support. (#49799)
* feat: add nv12 osr output format.

* feat: add nv12 osr output format.
2026-03-17 17:14:01 -04:00
Shelley Vohr
76331f0564 refactor: replace CHILD_PLUGIN with CHILD_EMBEDDER_FIRST on macOS (#50278)
refactor: replace CHILD_PLUGIN with CHILD_EMBEDDER_FIRST on macOS

Chromium removed upstream support for child plugin processes without
library validation in https://crbug.com/461717105, which we patched
back via feat_restore_macos_child_plugin_process.patch.

Chromium's CHILD_EMBEDDER_FIRST mechanism already provides the right
extensibility point for this: values > CHILD_EMBEDDER_FIRST are reserved
for embedders and resolved via ContentBrowserClient::GetChildProcessSuffix().
Chrome itself uses this pattern for its Alerts helper process.

This commit replaces the Chromium patch with an Electron-native
implementation.
2026-03-17 14:41:15 -04:00
37 changed files with 415 additions and 117 deletions

View File

@@ -5,6 +5,8 @@ Thank you for your Pull Request. Please provide a description above and review
the requirements below.
Contributors guide: https://github.com/electron/electron/blob/main/CONTRIBUTING.md
NOTE: PRS submitted without this template will be automatically closed.
-->
#### Checklist

View File

@@ -365,6 +365,18 @@ jobs:
generate-symbols: false
upload-to-storage: '0'
secrets: inherit
test-linux-arm64-64k:
uses: ./.github/workflows/pipeline-segment-electron-test-64k.yml
permissions:
contents: read
issues: read
pull-requests: read
needs: [checkout-linux, linux-arm64]
with:
test-runs-on: ubuntu-22.04-arm
test-container: '{"image":"ghcr.io/electron/test:arm64v8-${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init"}'
secrets: inherit
windows-x64:
permissions:

View File

@@ -0,0 +1,67 @@
name: Pipeline Segment - Electron Test on Linux ARM64 64k
on:
workflow_call:
inputs:
test-runs-on:
type: string
description: 'What host to run the tests on'
required: true
test-container:
type: string
description: 'JSON container information for aks runs-on'
required: false
default: '{"image":null}'
concurrency:
group: electron-test-linux-64k-${{ github.ref_protected == true && github.run_id || github.ref }}
cancel-in-progress: ${{ github.ref_protected != true }}
permissions: {}
env:
ELECTRON_OUT_DIR: Default
jobs:
test-linux-arm64-64k:
env:
BUILD_TYPE: linux
TARGET_ARCH: arm64
defaults:
run:
shell: bash
runs-on: ${{ inputs.test-runs-on }}
permissions:
contents: read
issues: read
pull-requests: read
steps:
- name: Checkout Electron
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
path: src/electron
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Download Generated Artifacts
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
with:
name: generated_artifacts_linux_arm64
path: ./generated_artifacts_linux_arm64
- name: Restore Generated Artifacts
run: ./src/electron/script/actions/restore-artifacts.sh
- name: Unzip Dist
run: |
cd src/out/Default
unzip -:o dist.zip
- name: Run Electron Tests in QEMU 64k Container
shell: bash
env:
MOCHA_REPORTER: mocha-multi-reporters
MOCHA_MULTI_REPORTERS: mocha-junit-reporter, tap
ELECTRON_DISABLE_SECURITY_WARNINGS: 1
DISPLAY: ':99.0'
run: |
container=$(echo '${{ inputs.test-container }}' | jq -r '.image')
src/electron/script/run-qemu-64k.sh --container $container --testfiles "`pwd`/src"

55
.github/workflows/pr-template-check.yml vendored Normal file
View File

@@ -0,0 +1,55 @@
name: PR Template Check
on:
pull_request_target:
types: [opened, edited]
branches:
- main
permissions: {}
jobs:
check-pr-template:
name: Check PR Template
runs-on: ubuntu-slim
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
sparse-checkout: .github/PULL_REQUEST_TEMPLATE.md
sparse-checkout-cone-mode: false
- name: Check for required sections
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const fs = require('fs');
const template = fs.readFileSync('.github/PULL_REQUEST_TEMPLATE.md', 'utf8');
const requiredSections = [...template.matchAll(/^(#{1,4} .+)$/gm)].map(
(m) => m[1],
);
if (requiredSections.length === 0) {
console.log('No heading sections found in PR template');
return;
}
const body = context.payload.pull_request.body || '';
const missingSections = requiredSections.filter(
(section) => !body.includes(section),
);
if (missingSections.length > 0) {
const list = missingSections.map((s) => `- \`${s}\``).join('\n');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
body: `This PR was automatically closed because the PR template was not properly filled out. The following required sections are missing:\n\n${list}\n\nPlease update your PR description to include all required sections and reopen the PR.`,
});
await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number,
state: 'closed',
});
}

View File

@@ -9,4 +9,8 @@ npmMinimalAgeGate: 10080
npmPreapprovedPackages:
- "@electron/*"
httpProxy: "${HTTP_PROXY:-}"
httpsProxy: "${HTTPS_PROXY:-}"
yarnPath: .yarn/releases/yarn-4.12.0.cjs

View File

@@ -1017,7 +1017,17 @@ if (is_mac) {
}
}
foreach(helper_params, content_mac_helpers) {
# Electron defines its own plugin helper (using CHILD_EMBEDDER_FIRST + 1) to
# allow loading of unsigned or third-party-signed libraries.
_electron_plugin_helper_params = [
"plugin",
".plugin",
" (Plugin)",
]
electron_mac_helpers =
content_mac_helpers + [ _electron_plugin_helper_params ]
foreach(helper_params, electron_mac_helpers) {
_helper_target = helper_params[0]
_helper_bundle_id = helper_params[1]
_helper_suffix = helper_params[2]
@@ -1070,7 +1080,7 @@ if (is_mac) {
":stripped_squirrel_framework",
]
foreach(helper_params, content_mac_helpers) {
foreach(helper_params, electron_mac_helpers) {
sources +=
[ "$root_out_dir/${electron_helper_name}${helper_params[2]}.app" ]
public_deps += [ ":electron_helper_app_${helper_params[0]}" ]
@@ -1174,7 +1184,7 @@ if (is_mac) {
deps = [ ":electron_framework" ]
}
foreach(helper_params, content_mac_helpers) {
foreach(helper_params, electron_mac_helpers) {
_helper_target = helper_params[0]
_helper_bundle_id = helper_params[1]
_helper_suffix = helper_params[2]
@@ -1226,7 +1236,7 @@ if (is_mac) {
deps += [ ":crashpad_handler_syms" ]
}
foreach(helper_params, content_mac_helpers) {
foreach(helper_params, electron_mac_helpers) {
_helper_target = helper_params[0]
deps += [ ":electron_helper_syms_${_helper_target}" ]
}

2
DEPS
View File

@@ -2,7 +2,7 @@ gclient_gn_args_from = 'src'
vars = {
'chromium_version':
'148.0.7737.0',
'148.0.7738.0',
'node_version':
'v24.14.0',
'nan_version':

View File

@@ -94,6 +94,7 @@
The actual output pixel format and color space of the texture should refer to [`OffscreenSharedTexture`](../structures/offscreen-shared-texture.md) object in the `paint` event.
* `argb` - The requested output texture format is 8-bit unorm RGBA, with SRGB SDR color space.
* `rgbaf16` - The requested output texture format is 16-bit float RGBA, with scRGB HDR color space.
* `nv12` - The requested output texture format is 12bpp with Y plane followed by a 2x2 interleaved UV plane, with REC709 color space.
* `deviceScaleFactor` number (optional) _Experimental_ - The device scale factor of the offscreen rendering output. If not set, will use `1` as default.
* `contextIsolation` boolean (optional) - Whether to run Electron APIs and
the specified `preload` script in a separate JavaScript context. Defaults

View File

@@ -146,13 +146,15 @@ The extra privileges granted to the `file://` protocol by this fuse are incomple
The `wasmTrapHandlers` fuse controls whether V8 will use signal handlers to trap Out of Bounds memory
access from WebAssembly. The feature works by surrounding the WebAssembly memory with large guard regions
and then installing a signal handler that traps attempt to access memory in the guard region. The feature
is only supported on the following 64-bit systems.
is only supported on the following 64-bit systems:
Linux. MacOS, Windows - x86_64
Linux, MacOS - aarch64
* Linux, macOS, Windows - x86_64
* Linux, macOS - aarch64
```text
| Guard Pages | WASM heap | Guard Pages |
|-----8GB-----| |-----8GB-----|
```
When the fuse is disabled V8 will use explicit bound checks in the generated WebAssembly code to ensure
memory safety. However, this method has some downsides

View File

@@ -148,5 +148,4 @@ 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
feat_restore_macos_child_plugin_process.patch
fix_restore_sdk_inputs_cross-toolchain_deps_for_macos.patch

View File

@@ -33,10 +33,10 @@ index 4b1fd316496e33f9e805aec89a91062587e6ee16..1b6fce9e2780a37e1e8bf3f8a62dc6bc
"//base",
"//build:branding_buildflags",
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index c36fc5c088b3921ce18b0997e582ba821a2edcab..42f22c828d0982280cc009b3abbc768195ace90c 100644
index 37f3a6b1d9457b04bd1d0c85ce585418d5dd7cb2..e411e434a4e1c5dc610984395eeb769aa6077a53 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -4565,7 +4565,7 @@ static_library("browser") {
@@ -4561,7 +4561,7 @@ static_library("browser") {
]
}
@@ -46,10 +46,10 @@ index c36fc5c088b3921ce18b0997e582ba821a2edcab..42f22c828d0982280cc009b3abbc7681
# than here in :chrome_dll.
deps += [ "//chrome:packed_resources_integrity_header" ]
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 503cb312afe9c24a29565664287a1f47678202ef..e4427dd7ac14f466e6d5ef777658cc77d9f2ff40 100644
index 1c6ed791b83c6cb70c57fb14cd7e3d8b22736895..607b2eb775c37fc8e967a74acaca36b7b793596d 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -7769,9 +7769,12 @@ test("unit_tests") {
@@ -7772,9 +7772,12 @@ test("unit_tests") {
"//chrome/notification_helper",
]
@@ -63,7 +63,7 @@ index 503cb312afe9c24a29565664287a1f47678202ef..e4427dd7ac14f466e6d5ef777658cc77
"//chrome//services/util_win:unit_tests",
"//chrome/app:chrome_dll_resources",
"//chrome/app:win_unit_tests",
@@ -8767,6 +8770,10 @@ test("unit_tests") {
@@ -8771,6 +8774,10 @@ test("unit_tests") {
"../browser/performance_manager/policies/background_tab_loading_policy_unittest.cc",
]
@@ -74,7 +74,7 @@ index 503cb312afe9c24a29565664287a1f47678202ef..e4427dd7ac14f466e6d5ef777658cc77
sources += [
# The importer code is not used on Android.
"../common/importer/firefox_importer_utils_unittest.cc",
@@ -8824,7 +8831,6 @@ test("unit_tests") {
@@ -8828,7 +8835,6 @@ 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

@@ -31,10 +31,10 @@ index 2ded9daa5611d3121677f4d67d19fcdbbcc68d26..d5a9f43850d3d7c3a73873ebb24bf2cc
// In the storage service we allow some overage to
// accommodate concurrent writes from different clients
diff --git a/third_party/blink/public/mojom/dom_storage/storage_area.mojom b/third_party/blink/public/mojom/dom_storage/storage_area.mojom
index 2552cc9cfab2c54caf584b14944324b92ae22171..f6e9a4a998f13d55b4d213a8bae2d50b090f138a 100644
index 535d618c6cb99fea8116baf69f8056d40a15bbdd..d01c79fbc67cfb8e668a2282cb4c4ae48d71e3a3 100644
--- a/third_party/blink/public/mojom/dom_storage/storage_area.mojom
+++ b/third_party/blink/public/mojom/dom_storage/storage_area.mojom
@@ -50,7 +50,8 @@ struct KeyValue {
@@ -67,7 +67,8 @@ struct KeyValue {
interface StorageArea {
// The quota for each storage area.
// This value is enforced in renderer processes and the browser process.

View File

@@ -46,10 +46,10 @@ index 6e60de1319c5506d7180719fa230ab9cf537b832..e570e335fbd413340ddedeee423eca71
'internal-forced-visited-'):
internal_visited_order = 0
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5
index 39e8cc9179c512d5598ad1d87e6f81a25141db35..20e32baac65381bae5927cb74935c6a8a4737d3b 100644
index 2a82493cedbce685ad8dce5856faeff7e94c7c74..ded8bd76c7c06a6f7ae41f5706c7780d12e06887 100644
--- a/third_party/blink/renderer/core/css/css_properties.json5
+++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -9605,6 +9605,27 @@
@@ -9606,6 +9606,27 @@
property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
},
@@ -314,7 +314,7 @@ index 18f283e625101318ee14b50e6e765dfd1c9a1a44..44a3a55974c9e4b9e715574075f25661
auto DrawAsSinglePath = [&]() {
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 3c89773a5ac4d27a6802cdb2ea2c78c5e8688b12..301634f4adab9e105df463b3d191528fc6b75103 100644
index caba0f7e0eec826e95976a129feca71c029226cf..bf93c6a5276c68360646bb5f99a484a3a7971095 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -214,6 +214,10 @@

View File

@@ -17,7 +17,7 @@ headers, moving forward we should find a way in upstream to provide
access to these headers for loader clients created on the browser process.
diff --git a/services/network/public/cpp/resource_request.cc b/services/network/public/cpp/resource_request.cc
index 87258c4eb6234a4e2b78ca84cfaeeb0536239cdb..ed46dc02d646da1e4ffa1b9c10325b51ffe862d0 100644
index a3f0786ceecfdcb80f9c8c4eef22daba4572cd29..0d8f16c92a8f9d05fcf7e2fd1f54c1840bdc6bea 100644
--- a/services/network/public/cpp/resource_request.cc
+++ b/services/network/public/cpp/resource_request.cc
@@ -203,6 +203,7 @@ ResourceRequest::TrustedParams& ResourceRequest::TrustedParams::operator=(
@@ -37,7 +37,7 @@ index 87258c4eb6234a4e2b78ca84cfaeeb0536239cdb..ed46dc02d646da1e4ffa1b9c10325b51
allow_cookies_from_browser == other.allow_cookies_from_browser &&
include_request_cookies_with_response ==
diff --git a/services/network/public/cpp/resource_request.h b/services/network/public/cpp/resource_request.h
index cfc57e89c8d609a329ebfdc514ddf909ef764401..0ecc81ae28d43d62fbddf232dd11786e2a1ae691 100644
index 31fb318fc098a2ac4f3b4ea89caced757d520210..34545e9f2c2fc383344710e78c5904119572e2e6 100644
--- a/services/network/public/cpp/resource_request.h
+++ b/services/network/public/cpp/resource_request.h
@@ -116,6 +116,7 @@ struct COMPONENT_EXPORT(NETWORK_CPP_BASE) ResourceRequest {
@@ -49,7 +49,7 @@ index cfc57e89c8d609a329ebfdc514ddf909ef764401..0ecc81ae28d43d62fbddf232dd11786e
mojo::PendingRemote<mojom::CookieAccessObserver> cookie_observer;
mojo::PendingRemote<mojom::TrustTokenAccessObserver> trust_token_observer;
diff --git a/services/network/public/cpp/url_request_mojom_traits.cc b/services/network/public/cpp/url_request_mojom_traits.cc
index 3146eb91f25befedbe45cbd0e5ca33a22c7a4cc3..4621fc82a435cdde0984798a59ec5fbd4efde56b 100644
index f258e06019ecaccc8e342c0fb5a54c400109f668..c883c93fa94666ab27092c5622e9db089175cc4b 100644
--- a/services/network/public/cpp/url_request_mojom_traits.cc
+++ b/services/network/public/cpp/url_request_mojom_traits.cc
@@ -67,6 +67,7 @@ bool StructTraits<network::mojom::TrustedUrlRequestParamsDataView,
@@ -61,7 +61,7 @@ index 3146eb91f25befedbe45cbd0e5ca33a22c7a4cc3..4621fc82a435cdde0984798a59ec5fbd
return false;
}
diff --git a/services/network/public/cpp/url_request_mojom_traits.h b/services/network/public/cpp/url_request_mojom_traits.h
index cb7367119e7ec2dcc89b3dff381e8f8651dee40d..d914c57f6732dc64c2eb734316ca1a8aca64d7f3 100644
index 35321e7d628e7db05a57d2a86775a313d8daedb0..845f7fe44a135fd98dec47e357365889d3591ab1 100644
--- a/services/network/public/cpp/url_request_mojom_traits.h
+++ b/services/network/public/cpp/url_request_mojom_traits.h
@@ -109,6 +109,10 @@ struct COMPONENT_EXPORT(NETWORK_CPP_BASE)
@@ -76,7 +76,7 @@ index cb7367119e7ec2dcc89b3dff381e8f8651dee40d..d914c57f6732dc64c2eb734316ca1a8a
network::ResourceRequest::TrustedParams::EnabledClientHints>&
enabled_client_hints(
diff --git a/services/network/public/mojom/url_request.mojom b/services/network/public/mojom/url_request.mojom
index 4fc03c32965010a466b96d05c0e3b3afc9ab0d9b..57a67b5980c2d4b66d3eedead6b8fc0cc4dc73e7 100644
index 0f3f9aa4328ac025c4627e550b8652004b4617e9..767bb928e64f06bad713163b004a977baf22c3cd 100644
--- a/services/network/public/mojom/url_request.mojom
+++ b/services/network/public/mojom/url_request.mojom
@@ -111,6 +111,9 @@ struct TrustedUrlRequestParams {

View File

@@ -1,68 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samuel Maddock <smaddock@slack-corp.com>
Date: Fri, 13 Mar 2026 15:35:48 -0400
Subject: feat: restore macos child plugin process
Chromium has removed upstream support for child plugin processes
without library validation; see https://crbug.com/461717105.
This patch partially reverts
https://chromium-review.googlesource.com/c/chromium/src/+/7653455
diff --git a/content/browser/child_process_host_impl.cc b/content/browser/child_process_host_impl.cc
index efd3d6686fa2b3ca121e63ac674fed2d57e82c0c..645434ac6a872bf3f67dd1edd987c19fbb4b0ef6 100644
--- a/content/browser/child_process_host_impl.cc
+++ b/content/browser/child_process_host_impl.cc
@@ -87,6 +87,8 @@ base::FilePath ChildProcessHost::GetChildPath(int flags) {
child_base_name += kMacHelperSuffix_renderer;
} else if (flags == CHILD_GPU) {
child_base_name += kMacHelperSuffix_gpu;
+ } else if (flags == CHILD_PLUGIN) {
+ child_base_name += kMacHelperSuffix_plugin;
} else if (flags > CHILD_EMBEDDER_FIRST) {
child_base_name +=
GetContentClient()->browser()->GetChildProcessSuffix(flags);
diff --git a/content/public/app/mac_helpers.gni b/content/public/app/mac_helpers.gni
index d9588d963684354e9564ccce5a8f8371c144a58e..027158994bb7207125ca819f9f226b9fb691037a 100644
--- a/content/public/app/mac_helpers.gni
+++ b/content/public/app/mac_helpers.gni
@@ -45,4 +45,16 @@ content_mac_helpers = [
"",
" (GPU)",
],
+
+ # A helper that does not perform library validation, allowing code not signed
+ # by either Apple or the signing identity to be loaded, and that can execute
+ # unsigned memory.
+ #
+ # This was removed upstream and is now maintained for Electron; see
+ # https://crbug.com/461717105.
+ [
+ "plugin",
+ ".plugin",
+ " (Plugin)",
+ ],
]
diff --git a/content/public/browser/child_process_host.h b/content/public/browser/child_process_host.h
index 2028deaf624bbfc75b2fa563298f3f4f65b1d65f..5ee19fbca0a73bb81273d162b2c304427b1b85cb 100644
--- a/content/public/browser/child_process_host.h
+++ b/content/public/browser/child_process_host.h
@@ -97,6 +97,18 @@ class CONTENT_EXPORT ChildProcessHost {
// allow-jit entitlement instead.
CHILD_GPU,
+ // Starts a child process with the macOS entitlement that ignores the
+ // library validation code signing enforcement.
+ //
+ // Library validation mandates that all executable pages be backed by a code
+ // signature of either 1) Apple, or 2) the same Team ID as the main
+ // executable. Third-party plug-ins are not signed by the same Team ID as
+ // the main binary, so this flag must be used when loading them.
+ //
+ // This was removed upstream and is now maintained for Electron; see
+ // https://crbug.com/461717105.
+ CHILD_PLUGIN,
+
// Marker for the start of embedder-specific helper child process types.
// Values greater than CHILD_EMBEDDER_FIRST are reserved to be used by the
// embedder to add custom process types and will be resolved via

View File

@@ -1378,10 +1378,10 @@ index 3a079b0fc34031d062045510fe0e2444792ff942..1be75833d46aaa124e5467904f68e46c
} // namespace
#endif
diff --git a/net/dns/BUILD.gn b/net/dns/BUILD.gn
index aa3411b03b674479df96af0d182ffa8e35c9f3be..79167ca3638a13aeb0f3e07b064afaa88cad3b2c 100644
index 012632a440f5078a71cbb327b04990654f282141..8e47b039b63fe74d3de441b8d21e7a9c4ec974f5 100644
--- a/net/dns/BUILD.gn
+++ b/net/dns/BUILD.gn
@@ -207,6 +207,8 @@ source_set("dns") {
@@ -223,6 +223,8 @@ source_set("dns") {
":host_resolver_manager",
":mdns_client",
]

View File

@@ -245,7 +245,7 @@ index 1ef2c9052262eccdbc40030746a858b7f30ac469..c7101b0d71826b05f61bfe0e74429d92
}
diff --git a/content/common/features.cc b/content/common/features.cc
index 3b4ab9f49e73e4af20be84e53f8ff161f913a36c..defcfbb3683062fd80b166cf132458a805a8f365 100644
index d6be1eae15865ae774fcda6f2fb2cc8b1206450a..746dbf32320e8b2f925f63ea8ba47dc2825e2cd9 100644
--- a/content/common/features.cc
+++ b/content/common/features.cc
@@ -364,6 +364,14 @@ BASE_FEATURE(kInterestGroupUpdateIfOlderThan, base::FEATURE_ENABLED_BY_DEFAULT);

View File

@@ -10,10 +10,10 @@ on Windows. We should refactor our code so that this patch isn't
necessary.
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 96c9e029764cc6605e1ca129233daf471d2b8f52..e386cb32cd1234100f58506aabd0adcb903b7bb9 100644
index 00ca9b81e6417f39d197f6c4e330fffa0dd8be86..8ff082655f23410dc1611524ded025471ec206fb 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -21956,6 +21956,21 @@
@@ -21961,6 +21961,21 @@
]
}
],

View File

@@ -10,10 +10,10 @@ to handle this without patching, but this is fairly clean for now and no longer
patching legacy devtools code.
diff --git a/front_end/entrypoints/main/MainImpl.ts b/front_end/entrypoints/main/MainImpl.ts
index f2554f8cabcfd0d0074e4e22de5de8716f1fcaf4..5b6c6056b575b14aa8b76d0238b4d83643db76f4 100644
index ad90070b7acdf891d5cb9e75c3ef06853a63069c..dfc9d200d27f8639c55665ce24609d3dcfe8f776 100644
--- a/front_end/entrypoints/main/MainImpl.ts
+++ b/front_end/entrypoints/main/MainImpl.ts
@@ -818,6 +818,8 @@ export class MainImpl {
@@ -816,6 +816,8 @@ export class MainImpl {
globalThis.Main = globalThis.Main || {};
// @ts-expect-error Exported for Tests.js
globalThis.Main.Main = MainImpl;

44
script/qemu-init.sh Executable file
View File

@@ -0,0 +1,44 @@
#!/bin/sh
echo "Mounting essential filesystems"
mount -t proc proc /proc
mount -t sysfs sys /sys
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
mkdir -p /dev/shm
mount -t tmpfs tmpfs /dev/shm
mount -t tmpfs tmpfs /tmp
chmod 1777 /tmp
mount -t tmpfs tmpfs /run
mkdir -p /run/dbus
mkdir -p /run/user/0
chmod 700 /run/user/0
mount -t tmpfs tmpfs /var/tmp
echo "Setting up hostname and machine-id for D-Bus"
echo "electron-test" > /etc/hostname
hostname electron-test
cat /proc/sys/kernel/random/uuid | tr -d '-' > /etc/machine-id
echo "Setting system clock"
date -s "$(cat /host-time)"
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export XDG_RUNTIME_DIR=/run/user/0
echo "Starting entrypoint"
echo "System: $(uname -s) $(uname -r) $(uname -m), page size: $(getconf PAGESIZE) bytes"
sudo chown -R builduser:builduser /home/builduser
ls -la /home/builduser/src/out/Default/electron
cd /home/builduser/src
runuser -u builduser -- xvfb-run out/Default/electron electron/spec/fixtures/apps/open-new-window-from-link
EXIT_CODE=$?
echo "Test execution finished with exit code $EXIT_CODE"
echo $EXIT_CODE > /exit-code
sync
echo "Powering off"
# poweroff -f bypasses the init system (this script IS pid 1) and
# directly invokes the reboot() syscall, causing QEMU to exit immediately.
poweroff -f

100
script/run-qemu-64k.sh Executable file
View File

@@ -0,0 +1,100 @@
#!/bin/sh
set -e
CONTAINER=""
TESTFILES=""
ARGS=""
while [ $# -gt 0 ]; do
case "$1" in
--container) CONTAINER="$2"; shift 2 ;;
--testfiles) TESTFILES="$2"; shift 2 ;;
--) shift; ARGS="$*"; break ;;
*) echo "Unknown option: $1"; exit 1 ;;
esac
done
if [ -z "$CONTAINER" ]; then
echo "Usage: $0 --container CONTAINER [-- ARGS...]"
exit 1
fi
echo "Installing QEMU system emulation and tools"
sudo apt-get update && sudo apt-get install -y qemu-system-arm binutils
KERNEL_URL="http://ports.ubuntu.com/ubuntu-ports/pool/main/l/linux/linux-image-unsigned-6.8.0-90-generic-64k_6.8.0-90.91_arm64.deb"
KERNEL_DIR=$(mktemp -d)
ROOTFS_DIR=$(mktemp -d)
# Download kernel and export container filesystem in parallel
echo "Downloading kernel and exporting container filesystem in parallel"
curl -fL "$KERNEL_URL" -o "$KERNEL_DIR/kernel.deb" &
CURL_PID=$!
CONTAINER_ID=$(docker create --platform linux/arm64 "$CONTAINER")
docker export "$CONTAINER_ID" | sudo tar -xf - -C "$ROOTFS_DIR"
docker rm -f "$CONTAINER_ID"
echo "Removing container image to free disk space"
docker rmi "$CONTAINER" || true
docker system prune -f || true
wait $CURL_PID
echo "Extracting kernel"
(cd "$KERNEL_DIR" && ar x kernel.deb && tar xf data.tar*)
VMLINUZ="$KERNEL_DIR/boot/vmlinuz-6.8.0-90-generic-64k"
if [ ! -f "$VMLINUZ" ]; then
echo "Error: Could not find kernel at $VMLINUZ"
exit 1
fi
sudo cp -r $TESTFILES "$ROOTFS_DIR/home/builduser"
echo "Storing test arguments and installing init script"
echo "$ARGS" > "$ROOTFS_DIR/test-args"
date -u '+%Y-%m-%d %H:%M:%S' > "$ROOTFS_DIR/host-time"
sudo cp "$TESTFILES/electron/script/qemu-init.sh" "$ROOTFS_DIR/init"
sudo chmod +x "$ROOTFS_DIR/init"
echo "Creating disk image with root filesystem"
df -h
DISK_IMG=$(mktemp)
truncate -s 10G "$DISK_IMG"
sudo mkfs.ext4 -q -d "$ROOTFS_DIR" "$DISK_IMG"
sudo rm -rf "$ROOTFS_DIR"
# Use KVM acceleration if available (ARM64 host can run 64K-page guest via KVM)
if [ -e /dev/kvm ] && [ -w /dev/kvm ]; then
echo "KVM available, using hardware acceleration"
ACCEL="-accel kvm -cpu host"
else
echo "KVM not available, using TCG emulation"
ACCEL="-accel tcg,thread=multi -cpu max,pauth-impdef=on"
fi
echo "Starting QEMU VM with 64K page size kernel"
timeout 1800 qemu-system-aarch64 \
-M virt \
$ACCEL \
-m 4096 \
-smp 2 \
-kernel "$VMLINUZ" \
-append "console=ttyAMA0 root=/dev/vda rw init=/init net.ifnames=0 panic=1" \
-drive file="$DISK_IMG",format=raw,if=virtio \
-virtfs local,path="$TESTFILES",mount_tag=testfiles,security_model=none,id=testfiles \
-netdev user,id=net0 \
-device virtio-net-pci,netdev=net0 \
-nographic \
-no-reboot \
|| true
echo "Extracting test results from disk image"
MOUNT_DIR=$(mktemp -d)
sudo mount -o loop "$DISK_IMG" "$MOUNT_DIR"
if [ -f "$MOUNT_DIR/results.xml" ]; then
cp "$MOUNT_DIR/results.xml" .
fi
EXIT_CODE=$(cat "$MOUNT_DIR/exit-code" 2>/dev/null || echo 1)
sudo umount "$MOUNT_DIR"
exit $EXIT_CODE

View File

@@ -14,6 +14,7 @@
#include "base/strings/sys_string_conversions.h"
#include "content/browser/mac_helpers.h"
#include "content/public/common/content_paths.h"
#include "shell/browser/electron_child_process_host_flags.h"
#include "shell/browser/mac/electron_application.h"
#include "shell/common/application_info.h"
#include "shell/common/mac/main_application_bundle.h"
@@ -38,8 +39,8 @@ base::FilePath GetHelperAppPath(const base::FilePath& frameworks_path,
helper_name += content::kMacHelperSuffix_renderer;
} else if (val.ends_with(content::kMacHelperSuffix_gpu)) {
helper_name += content::kMacHelperSuffix_gpu;
} else if (val.ends_with(content::kMacHelperSuffix_plugin)) {
helper_name += content::kMacHelperSuffix_plugin;
} else if (val.ends_with(kElectronMacHelperSuffixPlugin)) {
helper_name += kElectronMacHelperSuffixPlugin;
}
return frameworks_path.Append(name + " " + helper_name + ".app")

View File

@@ -96,6 +96,7 @@
#include <CoreFoundation/CoreFoundation.h>
#include "base/no_destructor.h"
#include "content/browser/mac_helpers.h"
#include "shell/browser/electron_child_process_host_flags.h"
#include "shell/browser/ui/cocoa/electron_bundle_mover.h"
#include "shell/common/process_util.h"
#endif
@@ -924,7 +925,7 @@ bool App::IsPackaged() {
"electron helper" +
base::ToLowerASCII(content::kMacHelperSuffix_renderer));
static const base::NoDestructor<std::string> plugin_helper(
"electron helper" + base::ToLowerASCII(content::kMacHelperSuffix_plugin));
"electron helper" + base::ToLowerASCII(kElectronMacHelperSuffixPlugin));
if (IsRendererProcess()) {
return base_name != *renderer_helper;
} else if (IsUtilityProcess()) {

View File

@@ -307,6 +307,12 @@ void BaseWindow::OnWindowSheetEnd() {
Emit("sheet-end");
}
void BaseWindow::OnWindowIsKeyChanged(bool is_key) {
#if BUILDFLAG(IS_MAC)
window()->SetActive(is_key);
#endif
}
void BaseWindow::OnWindowEnterHtmlFullScreen() {
Emit("enter-html-full-screen");
}

View File

@@ -84,6 +84,7 @@ class BaseWindow : public gin_helper::TrackableObject<BaseWindow>,
void OnWindowRotateGesture(float rotation) override;
void OnWindowSheetBegin() override;
void OnWindowSheetEnd() override;
void OnWindowIsKeyChanged(bool is_key) override;
void OnWindowEnterFullScreen() override;
void OnWindowLeaveFullScreen() override;
void OnWindowEnterHtmlFullScreen() override;

View File

@@ -276,16 +276,22 @@ v8::Local<v8::Value> BrowserWindow::GetWebContents(v8::Isolate* isolate) {
}
void BrowserWindow::OnWindowShow() {
if (!web_contents_shown_) {
web_contents()->WasShown();
web_contents_shown_ = true;
}
BaseWindow::OnWindowShow();
}
void BrowserWindow::OnWindowHide() {
web_contents()->WasOccluded();
web_contents_shown_ = false;
BaseWindow::OnWindowHide();
}
void BrowserWindow::Show() {
web_contents()->WasShown();
web_contents_shown_ = true;
BaseWindow::Show();
}
@@ -294,6 +300,7 @@ void BrowserWindow::ShowInactive() {
if (IsModal())
return;
web_contents()->WasShown();
web_contents_shown_ = true;
BaseWindow::ShowInactive();
}

View File

@@ -80,6 +80,7 @@ class BrowserWindow : public BaseWindow,
// Helpers.
v8::Global<v8::Value> web_contents_;
bool web_contents_shown_ = false;
v8::Global<v8::Value> web_contents_view_;
base::WeakPtr<api::WebContents> api_web_contents_;

View File

@@ -23,6 +23,7 @@
#include "services/network/public/cpp/originating_process_id.h"
#include "shell/browser/api/message_port.h"
#include "shell/browser/browser.h"
#include "shell/browser/electron_child_process_host_flags.h"
#include "shell/browser/javascript_environment.h"
#include "shell/browser/net/system_network_context_manager.h"
#include "shell/common/gin_converters/callback_converter.h"
@@ -186,7 +187,8 @@ UtilityProcessWrapper::UtilityProcessWrapper(
#endif
#if BUILDFLAG(IS_MAC)
.WithChildFlags(use_plugin_helper
? content::ChildProcessHost::CHILD_PLUGIN
? static_cast<int>(ElectronChildProcessHostFlags::
kChildProcessHelperPlugin)
: content::ChildProcessHost::CHILD_NORMAL)
.WithDisclaimResponsibility(disclaim_responsibility)
#endif

View File

@@ -210,7 +210,7 @@ void ElectronApiSWIPCHandlerImpl::RenderProcessExited(
// static
void ElectronApiSWIPCHandlerImpl::BindReceiver(
int render_process_id,
content::ChildProcessId render_process_id,
int64_t version_id,
mojo::PendingAssociatedReceiver<mojom::ElectronApiIPC> receiver) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

View File

@@ -10,6 +10,7 @@
#include "base/memory/weak_ptr.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host_observer.h"
#include "content/public/common/child_process_id.h"
#include "electron/shell/common/api/api.mojom.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "shell/common/gin_helper/event.h"
@@ -39,7 +40,7 @@ class ElectronApiSWIPCHandlerImpl : public mojom::ElectronApiIPC,
mojo::PendingAssociatedReceiver<mojom::ElectronApiIPC> receiver);
static void BindReceiver(
int render_process_id,
content::ChildProcessId render_process_id,
int64_t version_id,
mojo::PendingAssociatedReceiver<mojom::ElectronApiIPC> receiver);

View File

@@ -86,6 +86,7 @@
#include "shell/browser/electron_autofill_driver_factory.h"
#include "shell/browser/electron_browser_context.h"
#include "shell/browser/electron_browser_main_parts.h"
#include "shell/browser/electron_child_process_host_flags.h"
#include "shell/browser/electron_navigation_throttle.h"
#include "shell/browser/electron_plugin_info_host_impl.h"
#include "shell/browser/electron_speech_recognition_manager_delegate.h"
@@ -500,8 +501,9 @@ void ElectronBrowserClient::AppendExtraCommandLineSwitches(
content::ChildProcessHost::CHILD_RENDERER);
auto gpu_child_path = content::ChildProcessHost::GetChildPath(
content::ChildProcessHost::CHILD_GPU);
auto plugin_child_path = content::ChildProcessHost::GetChildPath(
content::ChildProcessHost::CHILD_PLUGIN);
auto plugin_child_path =
content::ChildProcessHost::GetChildPath(static_cast<int>(
ElectronChildProcessHostFlags::kChildProcessHelperPlugin));
if (program != renderer_child_path && program != gpu_child_path &&
program != plugin_child_path) {
child_path = content::ChildProcessHost::GetChildPath(
@@ -1456,8 +1458,7 @@ void ElectronBrowserClient::OverrideURLLoaderFactoryParams(
void ElectronBrowserClient::RegisterAssociatedInterfaceBindersForServiceWorker(
const content::ServiceWorkerVersionBaseInfo& service_worker_version_info,
blink::AssociatedInterfaceRegistry& associated_registry) {
CHECK(service_worker_version_info.process_id !=
content::ChildProcessHost::kInvalidUniqueID);
CHECK(service_worker_version_info.process_id);
associated_registry.AddInterface<mojom::ElectronApiIPC>(
base::BindRepeating(&ElectronApiSWIPCHandlerImpl::BindReceiver,
service_worker_version_info.process_id,
@@ -1466,11 +1467,11 @@ void ElectronBrowserClient::RegisterAssociatedInterfaceBindersForServiceWorker(
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
associated_registry.AddInterface<extensions::mojom::RendererHost>(
base::BindRepeating(&extensions::RendererStartupHelper::BindForRenderer,
content::ChildProcessId::FromUnsafeValue(
service_worker_version_info.process_id)));
associated_registry.AddInterface<extensions::mojom::ServiceWorkerHost>(
base::BindRepeating(&extensions::ServiceWorkerHost::BindReceiver,
service_worker_version_info.process_id));
associated_registry.AddInterface<extensions::mojom::ServiceWorkerHost>(
base::BindRepeating(
&extensions::ServiceWorkerHost::BindReceiver,
service_worker_version_info.process_id.GetUnsafeValue()));
#endif
}
@@ -1808,6 +1809,15 @@ void ElectronBrowserClient::RegisterBrowserInterfaceBindersForServiceWorker(
}
#if BUILDFLAG(IS_MAC)
std::string ElectronBrowserClient::GetChildProcessSuffix(int child_flags) {
if (child_flags ==
static_cast<int>(
ElectronChildProcessHostFlags::kChildProcessHelperPlugin)) {
return kElectronMacHelperSuffixPlugin;
}
NOTREACHED() << "Unsupported child process flags: " << child_flags;
}
device::GeolocationSystemPermissionManager*
ElectronBrowserClient::GetGeolocationSystemPermissionManager() {
return device::GeolocationSystemPermissionManager::GetInstance();

View File

@@ -118,6 +118,7 @@ class ElectronBrowserClient : public content::ContentBrowserClient,
content::WebAuthenticationDelegate* GetWebAuthenticationDelegate() override;
#if BUILDFLAG(IS_MAC)
std::string GetChildProcessSuffix(int child_flags) override;
device::GeolocationSystemPermissionManager*
GetGeolocationSystemPermissionManager() override;
#endif

View File

@@ -0,0 +1,34 @@
// Copyright (c) 2026 Microsoft GmbH. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ELECTRON_SHELL_BROWSER_ELECTRON_CHILD_PROCESS_HOST_FLAGS_H_
#define ELECTRON_SHELL_BROWSER_ELECTRON_CHILD_PROCESS_HOST_FLAGS_H_
#include "build/build_config.h"
#include "content/public/browser/child_process_host.h"
namespace electron {
// Flags for Electron-specific child processes to resolve the appropriate
// helper executable via ElectronBrowserClient::GetChildProcessSuffix().
enum class ElectronChildProcessHostFlags {
#if BUILDFLAG(IS_MAC)
// Starts a child process with macOS entitlements that disable library
// validation and allow unsigned executable memory. This allows the process
// to load third-party libraries not signed by the same Team ID as the main
// executable.
kChildProcessHelperPlugin =
content::ChildProcessHost::CHILD_EMBEDDER_FIRST + 1,
#endif // BUILDFLAG(IS_MAC)
};
#if BUILDFLAG(IS_MAC)
// Helper app name suffix for the plugin child process. This must match the
// corresponding entry in Electron's BUILD.gn electron_plugin_helper_params.
inline constexpr const char kElectronMacHelperSuffixPlugin[] = " (Plugin)";
#endif // BUILDFLAG(IS_MAC)
} // namespace electron
#endif // ELECTRON_SHELL_BROWSER_ELECTRON_CHILD_PROCESS_HOST_FLAGS_H_

View File

@@ -24,6 +24,8 @@ media::VideoPixelFormat GetTargetPixelFormatFromOption(
return media::PIXEL_FORMAT_ARGB;
} else if (pixel_format_option == "rgbaf16") {
return media::PIXEL_FORMAT_RGBAF16;
} else if (pixel_format_option == "nv12") {
return media::PIXEL_FORMAT_NV12;
}
// Use ARGB as default.

View File

@@ -87,8 +87,8 @@ MouseDownImpl g_nsnextstepframe_mousedown;
(electron::NativeWindowMac*)[(id)self.window shell];
if (shell && !shell->has_frame())
[self cr_mouseDownOnFrameView:event];
g_nsthemeframe_mousedown(self, @selector(mouseDown:), event);
}
g_nsthemeframe_mousedown(self, @selector(mouseDown:), event);
}
- (void)swiz_nsnextstepframe_mouseDown:(NSEvent*)event {
@@ -98,8 +98,8 @@ MouseDownImpl g_nsnextstepframe_mousedown;
if (shell && !shell->has_frame()) {
[self cr_mouseDownOnFrameView:event];
}
g_nsnextstepframe_mousedown(self, @selector(mouseDown:), event);
}
g_nsnextstepframe_mousedown(self, @selector(mouseDown:), event);
}
- (void)swiz_nsview_swipeWithEvent:(NSEvent*)event {

View File

@@ -31,6 +31,8 @@ std::string OsrVideoPixelFormatToString(media::VideoPixelFormat format) {
return "rgba";
case media::PIXEL_FORMAT_RGBAF16:
return "rgbaf16";
case media::PIXEL_FORMAT_NV12:
return "nv12";
default:
NOTREACHED();
}

View File

@@ -10,6 +10,7 @@
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "content/browser/mac_helpers.h"
#include "shell/browser/electron_child_process_host_flags.h"
namespace electron {
@@ -31,7 +32,7 @@ base::FilePath MainApplicationBundlePath() {
// Up to Contents.
if (!HasMainProcessKey() &&
(path.value().ends_with(" Helper") ||
path.value().ends_with(content::kMacHelperSuffix_plugin) ||
path.value().ends_with(kElectronMacHelperSuffixPlugin) ||
path.value().ends_with(content::kMacHelperSuffix_renderer) ||
path.value().ends_with(content::kMacHelperSuffix_gpu))) {
// The running executable is the helper. Go up five steps: