Compare commits

..

21 Commits

Author SHA1 Message Date
Keeley Hammond
e8ec128918 build: modify strip_arm_deep -> strip_universal_deep 2025-06-30 14:35:48 -07:00
Keeley Hammond
957281d351 build: free additional space on MacOS runners 2025-06-30 14:01:44 -07:00
electron-roller[bot]
4f69c5835e chore: bump chromium to 140.0.7261.0 (main) (#47561)
* chore: bump chromium in DEPS to 140.0.7259.0

* chore: update patches

* Add fade in animation to Picture-in-Picture windows

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

* [v8] Use V8 Apis that don't return JSGlobalObject

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

* chore: IWYU

* chore: bump chromium in DEPS to 140.0.7261.0

* chore: update patches

* revert: update to siso-chromium image

* [v8] Use v8::Object::WrapGlobal()

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

* chore: IWYU

* chore: fix --trace-startup spec

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2025-06-30 12:30:05 -04:00
Taiki Komoda
fa15332587 docs: update automated-testing.md (#47017)
* Update automated-testing.md

* fixed lint error
2025-06-30 10:56:48 +02:00
Shelley Vohr
e299a1d098 feat: support complete WebUSB device properties (#47459)
* feat: support complete WebUSB device properties

* docs: correct type consistency
2025-06-30 10:28:21 +02:00
Charles Kerr
c2302960a8 refactor: reduce scope of temporaries when getting dictionary values (#47581)
refactor: reduce scale of temporaries when getting dictionary values
2025-06-29 21:58:18 +02:00
Charles Kerr
5e862f398e fix: Reland "[accessibility] Platform node lifetime cleanups" (#47590)
Reland "[accessibility] Platform node lifetime cleanups"

https://chromium-review.googlesource.com/c/chromium/src/+/6462552
2025-06-29 21:57:48 +02:00
Shelley Vohr
61c245761c test: fix nan tests on macOS (#47583) 2025-06-29 21:57:44 +02:00
Charles Kerr
7c55b24be2 refactor: avoid copies of large objects in range based for loops (#47588)
* Avoid copies of large objects in range-based for-loops.

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

* Avoid copies of large objects in range-based for-loops in Browser::ShowAboutPanel()
2025-06-29 21:32:26 +02:00
Charles Kerr
4af248f2b6 perf: avoid copying a vector when calling ConvertToWeakPtrVector() (#47593) 2025-06-29 21:32:03 +02:00
Erick Zhao
69e9b653ba docs: update example apps (#47597) 2025-06-29 21:31:42 +02:00
electron-roller[bot]
4dccccadbb chore: bump node to v22.17.0 (main) (#47557)
* chore: bump node in DEPS to v22.17.0

* build: use //third_party/simdutf by default in GN

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

* chore: adjust crypto specs:

- https://github.com/nodejs/node/pull/58117
- https://github.com/nodejs/node/pull/58387

* deps: update libuv to 1.51.0

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

* test: fix test-buffer-tostring-range on allocation failure

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

* build: use FILE_OFFSET_BITS=64 esp. on 32-bit arch

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

* build: use //third_party/simdutf by default in GN

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

* inspector: add protocol method Network.dataReceived

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

* test: force slow JSON.stringify path for overflow

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

* chore: fixup patch indices

* 6049967: Remove protocol::Maybe and roll inspector_protocol

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

* chore: fixup crypto test patch

* src: fix module buffer allocation

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

* crypto: expose process.features.openssl_is_boringssl

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

* util: add internal assignFunctionName() function

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

* build: fix pointer compression builds

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

* chore: put back config options

* fixup! deps: update libuv to 1.51.0

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2025-06-28 16:33:09 +02:00
Charles Kerr
79cd6a2614 refactor: sync IsKillURL() with upstream impl in extension_tab_util.cc (#47580)
Use base::MakeFixedFlatSet()
2025-06-27 15:49:41 -05:00
Charles Kerr
2ba8fe9140 refactor: extract-constant static Windows registry keys in Browser code (#47569)
* refactor: extract-constant for registry key in GetProcessExecPath()

* refactor: extract-constant for registry key in Browser::SetLoginItemSettings()

* refactor: extract-constant for registry key in Browser::SetLoginItemSettings()

* refactor: extract-constant for registry key in Browser::GetLoginItemSettings()

* chore: document the symbolic constants

* refactor: prefer base::wcstring_view::c_str() to data() to make zero-termination clearer
2025-06-27 10:34:55 -05:00
Charles Kerr
b21c4b0f88 refactor: make context bridge's private keys hidden, constexpr string_views (#47562)
* refactor: local functions GetPrivate(), SetPrivate() now take std::string_views

* refactor: make local keys std::string_views instead of C-style char arrays

* refactor: make local keys constexpr

* refactor: move local keys into local anonymous namespace
2025-06-27 09:29:53 -05:00
Charles Kerr
f50ad3d022 refactor: remove stray .c_str() calls for absl::StrFormat() (#47548)
refactor: remove stray .c_str() calls for absl::StrFormat()

StrFormat() understands std::string, std::string_view
2025-06-26 11:41:30 +02:00
Keeley Hammond
7a274a711c fix: revert upstream MacOS mouse event routing (#47560)
* fix: revert upstream MacOS mouse event routing

* fix: reduce patch surface area

* chore: update patches
2025-06-26 11:41:11 +02:00
Niklas Wenzel
bc499ffb8a docs: fix --experimental-network-inspection spelling (#47565)
doc: fix `--experimental-network-inspection` spelling
2025-06-26 11:40:55 +02:00
Niklas Wenzel
0a74e91580 docs: update asar integrity fuse availability (#47528) 2025-06-25 23:15:59 +02:00
electron-roller[bot]
035879357e chore: bump chromium to 139.0.7256.0 (main) (#47481)
* chore: bump chromium in DEPS to 139.0.7242.0

* chore: update render_widget_host_view_mac.patch

no code changes; just updating patch context

Do a cleanup pass on the history swiper code | https://chromium-review.googlesource.com/c/chromium/src/+/6604367

* chore: update mas_avoid_private_macos_api_usage.patch.patch

no code changes; just updating patch context

[tracing] Delete base/trace_event/base_tracing.h | https://chromium-review.googlesource.com/c/chromium/src/+/6624012

* chore: update chore_provide_iswebcontentscreationoverridden_with_full_params.patch

no manual changes; just updating patch context

[ActorFramework] Refactor Actor Task Management | https://chromium-review.googlesource.com/c/chromium/src/+/6618684

* chore: update fix_move_autopipsettingshelper_behind_branding_buildflag.patch

[pip] Tuck picture-in-picture windows when a file dialog is open | https://chromium-review.googlesource.com/c/chromium/src/+/6449682

Reland "[document pip] Restrict the size that a website can request" | https://chromium-review.googlesource.com/c/chromium/src/+/6372104

* chore: update feat_corner_smoothing_css_rule_and_blink_painting.patch

Xref: corner-shape: constraint radii based on opposite corner overlap | https://chromium-review.googlesource.com/c/chromium/src/+/6592572

* chore: update revert_code_health_clean_up_stale_macwebcontentsocclusion.patch

no manual changes; just updating patch context

* chore: update fix_rename_sqlite_win32_exports_to_avoid_conflicts_with_node_js.patch

no code changes; just updating patch context

* chore: e patches all

* Plumb Verify2QwacBinding and hook it up in QwacWebContentsObserver

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

* [Extensions] Remove host delegate OnMainFrameCreatedForBackgroundPage

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

* Extensions: Rename GetResourceURL to ResolveExtensionURL

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

* [NonClientFrameView] Consolidate NativeFrameViewMac

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

* ICWYU

* [views-ax] Remove dead code WidgetAXTreeIDMap

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

* Reland "extensions: Add `WillPrepareForEvaluation` to setup MojoJS"

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

* NavigationThrottleRunner2: Remove MaybeAddThrottle

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

* [pip] Tuck picture-in-picture windows when a file dialog is open

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

* build: fix snapshot_blob.bin build error

xref: https://issues.chromium.org/issues/416540976

* chore: e patches all

* build: freeup disk space on macos

* chore: bump chromium in DEPS to 139.0.7244.0

* chore: update printing.patch

no manual changes; just updating patch context

* chore: remove upstreamed ignore_parse_errors_for_resolveshortcutproperties.patch

Prevent Windows crash on unexpected shortcut type | https://chromium-review.googlesource.com/c/chromium/src/+/6633298

* chore: e patches all

* Revert "Reland "extensions: Add `WillPrepareForEvaluation` to setup MojoJS""

This reverts commit 77c4f967a6.

Revert CL for the high confidence crash culprit for http://crash/28f897bb9743dfe0 | https://chromium-review.googlesource.com/c/chromium/src/+/6641819

* Fix spec's expected base64-encoded PNG strings to match upstream changes.

[rust png] Enable by default. | https://chromium-review.googlesource.com/c/chromium/src/+/6085801

* chore: bump chromium in DEPS to 139.0.7246.0

* chore: e patches all

* chore: bump chromium in DEPS to 139.0.7248.0

* chore: update patches

* siso: Enable Siso by default for non-Google builds

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

Disabling for now until we are ready to build siso on all platforms.

* Revert "revert Don't use static variable for UseExternalPopupMenus"

This reverts commit e91e3894e6.

* Update mac_sdk_min to match minimum required SDK version

https://chromium-review.googlesource.com/c/chromium/src/+/6493969
(cherry picked from commit 3e7cbe912d)

* [video pip] Use default window styling on Mac

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

* Reland "Force the unintentional renderer process creation check by default"

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

* fixup: Reland "Force the unintentional renderer process creation check by default

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

* chore: bump chromium in DEPS to 139.0.7249.0

* fixup: Reland "Force the unintentional renderer process creation check by default

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

* chore: update patches

* chore: bump chromium in DEPS to 139.0.7250.0

* chore: bump chromium in DEPS to 139.0.7252.0

* chore: bump chromium in DEPS to 139.0.7254.0

* 6638187: browser level TOCTOU check for coordinate target

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

* chore: fixup patch indices

* chore: add missing base/notimplemented includes

* 6652910: [Frame Cleanup] Push down/hide implementation-specific API

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

* chore: bump chromium in DEPS to 139.0.7256.0

* chore: fix lint

* fixup! 6652910: [Frame Cleanup] Push down/hide implementation-specific API

* fix: move HandleScope location

* chore: bump chromium in DEPS to 139.0.7258.0

* fixup! [NonClientFrameView] Consolidate NativeFrameViewMac

* Revert "chore: bump chromium in DEPS to 139.0.7258.0"

This reverts commit 264b2e934f.

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
2025-06-26 00:12:49 +09:00
Felix Rieseberg
e4c37e4b38 docs: Add C++/Linux tutorial (#46822) 2025-06-25 12:57:43 +02:00
279 changed files with 2998 additions and 3641 deletions

View File

@@ -58,13 +58,13 @@ if [ ! -f $buildtools/configs/evm.testing.json ]; then
},
\"\$schema\": \"file:///home/builduser/.electron_build_tools/evm-config.schema.json\",
\"configValidationLevel\": \"strict\",
\"remoteBuild\": \"reclient\",
\"preserveSDK\": 5
\"reclient\": \"$1\",
\"preserveXcode\": 5
}
" >$buildtools/configs/evm.testing.json
}
write_config
write_config remote_exec
e use testing
else

View File

@@ -47,6 +47,8 @@ runs:
tmpify $(xcode-select -p)/Platforms/WatchSimulator.platform
tmpify $(xcode-select -p)/Platforms/AppleTVSimulator.platform
tmpify $(xcode-select -p)/Platforms/iPhoneSimulator.platform
tmpify $(xcode-select -p)/Platforms/XROS.platform
tmpify $(xcode-select -p)/Platforms/XRSimulator.platform
tmpify $(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/metal/ios
tmpify $(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift
tmpify $(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-5.0
@@ -58,11 +60,13 @@ runs:
sudo rm -rf /Applications/Safari.app
sudo rm -rf /Applications/Xcode_16.1.app
sudo rm -rf /Applications/Xcode_16.3.app
sudo rm -rf /Applications/Xcode_16.2.app
sudo rm -rf /Applications/Google Chrome.app
sudo rm -rf /Applications/Xcode_16.3.app
sudo rm -rf /Applications/Xcode_16.4.app
sudo rm -rf /Applications/Google Chrome.app
sudo rm -rf /Applications/Google Chrome for Testing.app
sudo rm -rf /Applications/Microsoft Edge.app
sudo rm -rf /Applications/Microsoft Edge Webdriver.app
sudo rm -rf /Applications/Firefox.app
sudo rm -rf ~/project/src/third_party/catapult/tracing/test_data
sudo rm -rf ~/project/src/third_party/angle/third_party/VK-GL-CTS
@@ -70,7 +74,8 @@ runs:
sudo rm -rf $JAVA_HOME_11_arm64
sudo rm -rf $JAVA_HOME_17_arm64
sudo rm -rf $JAVA_HOME_21_arm64
sudo rm -rf /Applications/Xcode_26_beta.app
# lipo off some huge binaries arm64 versions to save space
strip_universal_deep $(xcode-select -p)/../SharedFrameworks
# strip_arm_deep /System/Volumes/Data/Library/Developer/CommandLineTools/usr
strip_universal_deep /System/Volumes/Data/Library/Developer/CommandLineTools/usr

View File

@@ -11,10 +11,9 @@ runs:
git config --global core.autocrlf false
git config --global branch.autosetuprebase always
git config --global core.fscache true
git config --global core.longpaths true
git config --global core.preloadindex true
fi
export BUILD_TOOLS_SHA=274cba0474f0d1e4e6adbb66c1da48556cb0add5
export BUILD_TOOLS_SHA=0a7f6bef9453ceee45612442660ca16d2c40171b
npm i -g @electron/build-tools
# Update depot_tools to ensure python
e d update_depot_tools

View File

@@ -96,7 +96,7 @@ runs:
$TEMP_DIR=New-Item -ItemType Directory -Path temp-cache
$TEMP_DIR_PATH = $TEMP_DIR.FullName
C:\ProgramData\Chocolatey\bin\7z.exe -y -snld x $src_cache -o"$TEMP_DIR_PATH"
C:\ProgramData\Chocolatey\bin\7z.exe -y x $src_cache -o"$TEMP_DIR_PATH"
- name: Move Src Cache (Windows)
if: ${{ inputs.target-platform == 'win' }}

View File

@@ -184,7 +184,7 @@ jobs:
with:
target-platform: macos
target-archs: x64 arm64
check-runs-on: macos-14
check-runs-on: macos-15
gn-build-type: testing
secrets: inherit
@@ -219,7 +219,7 @@ jobs:
uses: ./.github/workflows/pipeline-electron-build-and-test.yml
needs: checkout-macos
with:
build-runs-on: macos-14-xlarge
build-runs-on: macos-15-xlarge
test-runs-on: macos-13
target-platform: macos
target-arch: x64
@@ -237,7 +237,7 @@ jobs:
uses: ./.github/workflows/pipeline-electron-build-and-test.yml
needs: checkout-macos
with:
build-runs-on: macos-14-xlarge
build-runs-on: macos-15-xlarge
test-runs-on: macos-14
target-platform: macos
target-arch: arm64

View File

@@ -47,7 +47,7 @@ jobs:
needs: checkout-macos
with:
environment: production-release
build-runs-on: macos-14-xlarge
build-runs-on: macos-15-xlarge
target-platform: macos
target-arch: x64
target-variant: darwin
@@ -62,7 +62,7 @@ jobs:
needs: checkout-macos
with:
environment: production-release
build-runs-on: macos-14-xlarge
build-runs-on: macos-15-xlarge
target-platform: macos
target-arch: x64
target-variant: mas
@@ -77,7 +77,7 @@ jobs:
needs: checkout-macos
with:
environment: production-release
build-runs-on: macos-14-xlarge
build-runs-on: macos-15-xlarge
target-platform: macos
target-arch: arm64
target-variant: darwin
@@ -92,7 +92,7 @@ jobs:
needs: checkout-macos
with:
environment: production-release
build-runs-on: macos-14-xlarge
build-runs-on: macos-15-xlarge
target-platform: macos
target-arch: arm64
target-variant: mas

View File

@@ -100,9 +100,9 @@ jobs:
}
userValuesArray=(
"'kTCCServiceMicrophone','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159"
"'kTCCServiceCamera','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159"
"'kTCCServiceBluetoothAlways','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159"
"'kTCCServiceAppleEvents','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159"
)
for values in "${userValuesArray[@]}"; do
# Sonoma and higher have a few extra values
@@ -135,7 +135,6 @@ jobs:
git config --global core.autocrlf false
git config --global branch.autosetuprebase always
git config --global core.fscache true
git config --global core.longpaths true
git config --global core.preloadindex true
git clone --filter=tree:0 https://chromium.googlesource.com/chromium/tools/depot_tools.git
# Ensure depot_tools does not update.
@@ -193,6 +192,7 @@ jobs:
MOCHA_REPORTER: mocha-multi-reporters
MOCHA_MULTI_REPORTERS: mocha-junit-reporter, tap
ELECTRON_DISABLE_SECURITY_WARNINGS: 1
ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
DISPLAY: ':99.0'
NPM_CONFIG_MSVS_VERSION: '2022'
run: |

View File

@@ -21,9 +21,7 @@
"ul",
"unknown",
"Tabs",
"TabItem",
"DocCardList",
"kbd"
"TabItem"
]
},
"no-newline-in-links": true

6
DEPS
View File

@@ -2,9 +2,9 @@ gclient_gn_args_from = 'src'
vars = {
'chromium_version':
'140.0.7281.0',
'140.0.7261.0',
'node_version':
'v22.17.1',
'v22.17.0',
'nan_version':
'e14bdcd1f72d62bca1d541b66da43130384ec213',
'squirrel.mac_version':
@@ -31,7 +31,7 @@ vars = {
'sysroots_json_path': 'electron/script/sysroots.json',
# KEEP IN SYNC WITH utils.js FILE
'yarn_version': '1.22.22',
'yarn_version': '1.15.2',
# To be able to build clean Chromium from sources.
'apply_patches': True,

View File

@@ -1,8 +1,8 @@
{
"plugins": [
"import"
"unicorn"
],
"rules": {
"import/enforce-node-protocol-usage": ["error", "always"]
"unicorn/prefer-node-protocol": "error"
}
}

View File

@@ -10,6 +10,9 @@ v8_embedder_string = "-electron.0"
# TODO: this breaks mksnapshot
v8_enable_snapshot_native_code_counters = false
# TODO: remove once https://issues.chromium.org/issues/416540976 is resolved
v8_enable_temporal_support = false
# we use this api
v8_enable_javascript_promise_hooks = true
@@ -70,6 +73,10 @@ v8_expose_public_symbols = true
# sensitive content by enterprise users.
enterprise_cloud_content_analysis = false
# TODO: remove dependency on legacy ipc
# https://issues.chromium.org/issues/40943039
content_enable_legacy_ipc = true
# Disable siso until we are ready to use it.
# https://chromium-review.googlesource.com/c/chromium/src/+/6638830
use_siso = false

View File

@@ -225,8 +225,8 @@ static_library("chrome") {
sources += [
"//chrome/browser/platform_util_aura.cc",
"//chrome/browser/ui/views/eye_dropper/eye_dropper_aura.cc",
"//ui/native_window_tracker/native_window_tracker_aura.cc",
"//ui/native_window_tracker/native_window_tracker_aura.h",
"//ui/views/native_window_tracker_aura.cc",
"//ui/views/native_window_tracker_aura.h",
]
deps += [ "//components/eye_dropper" ]
}

View File

@@ -1,8 +1,8 @@
{
"plugins": [
"import"
"unicorn"
],
"rules": {
"import/enforce-node-protocol-usage": ["error", "always"]
"unicorn/prefer-node-protocol": "error"
}
}

View File

@@ -1,8 +1,8 @@
{
"extends": "standard",
"plugins": [
"import",
"markdown"
"markdown",
"unicorn"
],
"overrides": [
{
@@ -30,6 +30,6 @@
"no-undef": "off",
"no-unused-expressions": "off",
"no-unused-vars": "off",
"import/enforce-node-protocol-usage": ["error", "always"]
"unicorn/prefer-node-protocol": "error"
}
}

82
docs/api/accelerator.md Normal file
View File

@@ -0,0 +1,82 @@
# Accelerator
> Define keyboard shortcuts.
Accelerators are strings that can contain multiple modifiers and a single key code,
combined by the `+` character, and are used to define keyboard shortcuts
throughout your application. Accelerators are case insensitive.
Examples:
* `CommandOrControl+A`
* `CommandOrControl+Shift+Z`
Shortcuts are registered with the [`globalShortcut`](global-shortcut.md) module
using the [`register`](global-shortcut.md#globalshortcutregisteraccelerator-callback)
method, i.e.
```js
const { app, globalShortcut } = require('electron')
app.whenReady().then(() => {
// Register a 'CommandOrControl+Y' shortcut listener.
globalShortcut.register('CommandOrControl+Y', () => {
// Do stuff when Y and either Command/Control is pressed.
})
})
```
## Platform notice
On Linux and Windows, the `Command` key does not have any effect so
use `CommandOrControl` which represents `Command` on macOS and `Control` on
Linux and Windows to define some accelerators.
Use `Alt` instead of `Option`. The `Option` key only exists on macOS, whereas
the `Alt` key is available on all platforms.
The `Super` (or `Meta`) key is mapped to the `Windows` key on Windows and Linux and
`Cmd` on macOS.
## Available modifiers
* `Command` (or `Cmd` for short)
* `Control` (or `Ctrl` for short)
* `CommandOrControl` (or `CmdOrCtrl` for short)
* `Alt`
* `Option`
* `AltGr`
* `Shift`
* `Super`
* `Meta`
## Available key codes
* `0` to `9`
* `A` to `Z`
* `F1` to `F24`
* Various Punctuation: `)`, `!`, `@`, `#`, `$`, `%`, `^`, `&`, `*`, `(`, `:`, `;`, `:`, `+`, `=`, `<`, `,`, `_`, `-`, `>`, `.`, `?`, `/`, `~`, `` ` ``, `{`, `]`, `[`, `|`, `\`, `}`, `"`
* `Plus`
* `Space`
* `Tab`
* `Capslock`
* `Numlock`
* `Scrolllock`
* `Backspace`
* `Delete`
* `Insert`
* `Return` (or `Enter` as alias)
* `Up`, `Down`, `Left` and `Right`
* `Home` and `End`
* `PageUp` and `PageDown`
* `Escape` (or `Esc` for short)
* `VolumeUp`, `VolumeDown` and `VolumeMute`
* `MediaNextTrack`, `MediaPreviousTrack`, `MediaStop` and `MediaPlayPause`
* `PrintScreen`
* NumPad Keys
* `num0` - `num9`
* `numdec` - decimal key
* `numadd` - numpad `+` key
* `numsub` - numpad `-` key
* `nummult` - numpad `*` key
* `numdiv` - numpad `÷` key

View File

@@ -1533,8 +1533,8 @@ events.
Prevents the window contents from being captured by other apps.
On macOS it sets the NSWindow's [`sharingType`](https://developer.apple.com/documentation/appkit/nswindow/sharingtype-swift.property?language=objc) to [`NSWindowSharingNone`](https://developer.apple.com/documentation/appkit/nswindow/sharingtype-swift.enum/none?language=objc).
On Windows it calls [`SetWindowDisplayAffinity`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowdisplayaffinity) with `WDA_EXCLUDEFROMCAPTURE`.
On macOS it sets the NSWindow's sharingType to NSWindowSharingNone.
On Windows it calls SetWindowDisplayAffinity with `WDA_EXCLUDEFROMCAPTURE`.
For Windows 10 version 2004 and up the window will be removed from capture entirely,
older Windows versions behave as if `WDA_MONITOR` is applied capturing a black window.

View File

@@ -51,17 +51,19 @@ Use the `system-ui` keyword to match the smoothness to the OS design language.
### Controlling availibility
This CSS rule can be disabled using the Blink feature flag `ElectronCSSCornerSmoothing`.
This CSS rule can be disabled by setting [the `cornerSmoothingCSS` web preference](./structures/web-preferences.md) to `false`.
```js
const myWindow = new BrowserWindow({
// [...]
webPreferences: {
disableBlinkFeatures: 'ElectronCSSCornerSmoothing' // Disables the `-electron-corner-smoothing` CSS rule
enableCornerSmoothingCSS: false // Disables the `-electron-corner-smoothing` CSS rule
}
})
```
The CSS rule will still parse, but will have no visual effect.
### Formal reference
* **Initial value**: `0%`

View File

@@ -63,7 +63,7 @@ The `crashReporter` module has the following methods:
* `extra` Record\<string, string\> (optional) - Extra string key/value
annotations that will be sent along with crash reports that are generated
in the main process. Only string values are supported. Crashes generated in
child processes will not include these extra parameters. To add extra
child processes will not contain these extra
parameters to crash reports generated from child processes, call
[`addExtraParameter`](#crashreporteraddextraparameterkey-value) from the
child process.

View File

@@ -5,8 +5,13 @@
Process: [Main](../glossary.md#main-process)<br />
_This class is not exported from the `'electron'` module. It is only available as a return value of other methods in the Electron API._
> [!TIP]
> See also: [A detailed guide about how to implement Dock menus](../tutorial/macos-dock.md).
The following example shows how to bounce your icon on the dock.
```js
const { app } = require('electron')
app.dock?.bounce()
```
### Instance Methods
@@ -45,9 +50,6 @@ Bounces the Downloads stack if the filePath is inside the Downloads folder.
Sets the string to be displayed in the docks badging area.
> [!IMPORTANT]
> You need to ensure that your application has the permission to display notifications for this method to work.
#### `dock.getBadge()` _macOS_
Returns `string` - The badge string of the dock.

View File

@@ -46,16 +46,13 @@ app.on('will-quit', () => {
})
```
> [!TIP]
> See also: [A detailed guide on Keyboard Shortcuts](../tutorial/keyboard-shortcuts.md).
## Methods
The `globalShortcut` module has the following methods:
### `globalShortcut.register(accelerator, callback)`
* `accelerator` string - An [accelerator](../tutorial/keyboard-shortcuts.md#accelerators) shortcut.
* `accelerator` [Accelerator](accelerator.md)
* `callback` Function
Returns `boolean` - Whether or not the shortcut was registered successfully.
@@ -77,7 +74,7 @@ the app has been authorized as a [trusted accessibility client](https://develope
### `globalShortcut.registerAll(accelerators, callback)`
* `accelerators` string[] - An array of [accelerator](../tutorial/keyboard-shortcuts.md#accelerators) shortcuts.
* `accelerators` [Accelerator](accelerator.md)[] - an array of [Accelerator](accelerator.md)s.
* `callback` Function
Registers a global shortcut of all `accelerator` items in `accelerators`. The `callback` is called when any of the registered shortcuts are pressed by the user.
@@ -96,7 +93,7 @@ the app has been authorized as a [trusted accessibility client](https://develope
### `globalShortcut.isRegistered(accelerator)`
* `accelerator` string - An [accelerator](../tutorial/keyboard-shortcuts.md#accelerators) shortcut.
* `accelerator` [Accelerator](accelerator.md)
Returns `boolean` - Whether this application has registered `accelerator`.
@@ -106,7 +103,7 @@ don't want applications to fight for global shortcuts.
### `globalShortcut.unregister(accelerator)`
* `accelerator` string - An [accelerator](../tutorial/keyboard-shortcuts.md#accelerators) shortcut.
* `accelerator` [Accelerator](accelerator.md)
Unregisters the global shortcut of `accelerator`.

View File

@@ -19,7 +19,7 @@ See [`Menu`](menu.md) for examples.
* `window` [BaseWindow](base-window.md) | undefined - This will not be defined if no window is open.
* `event` [KeyboardEvent](structures/keyboard-event.md)
* `role` string (optional) - Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `toggleSpellChecker`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `showSubstitutions`, `toggleSmartQuotes`, `toggleSmartDashes`, `toggleTextReplacement`, `startSpeaking`, `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `shareMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `showAllTabs`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` - Define the action of the menu item, when specified the
`click` property will be ignored. See [roles](../tutorial/menus.md#roles).
`click` property will be ignored. See [roles](#roles).
* `type` string (optional)
* `normal`
* `separator`
@@ -31,7 +31,7 @@ See [`Menu`](menu.md) for examples.
* `label` string (optional)
* `sublabel` string (optional) _macOS_ - Available in macOS >= 14.4
* `toolTip` string (optional) _macOS_ - Hover text for this menu item.
* `accelerator` string (optional) - An [Accelerator](../tutorial/keyboard-shortcuts.md#accelerators) string.
* `accelerator` [Accelerator](accelerator.md) (optional)
* `icon` ([NativeImage](native-image.md) | string) (optional)
* `enabled` boolean (optional) - If false, the menu item will be greyed out and
unclickable.
@@ -64,13 +64,88 @@ See [`Menu`](menu.md) for examples.
> [!NOTE]
> `acceleratorWorksWhenHidden` is specified as being macOS-only because accelerators always work when items are hidden on Windows and Linux. The option is exposed to users to give them the option to turn it off, as this is possible in native macOS development.
### Roles
Roles allow menu items to have predefined behaviors.
It is best to specify `role` for any menu item that matches a standard role,
rather than trying to manually implement the behavior in a `click` function.
The built-in `role` behavior will give the best native experience.
The `label` and `accelerator` values are optional when using a `role` and will
default to appropriate values for each platform.
Every menu item must have either a `role`, `label`, or in the case of a separator
a `type`.
The `role` property can have following values:
* `undo`
* `about` - Trigger a native about panel (custom message box on Window, which does not provide its own).
* `redo`
* `cut`
* `copy`
* `paste`
* `pasteAndMatchStyle`
* `selectAll`
* `delete`
* `minimize` - Minimize current window.
* `close` - Close current window.
* `quit` - Quit the application.
* `reload` - Reload the current window.
* `forceReload` - Reload the current window ignoring the cache.
* `toggleDevTools` - Toggle developer tools in the current window.
* `togglefullscreen` - Toggle full screen mode on the current window.
* `resetZoom` - Reset the focused page's zoom level to the original size.
* `zoomIn` - Zoom in the focused page by 10%.
* `zoomOut` - Zoom out the focused page by 10%.
* `toggleSpellChecker` - Enable/disable builtin spell checker.
* `fileMenu` - Whole default "File" menu (Close / Quit)
* `editMenu` - Whole default "Edit" menu (Undo, Copy, etc.).
* `viewMenu` - Whole default "View" menu (Reload, Toggle Developer Tools, etc.)
* `windowMenu` - Whole default "Window" menu (Minimize, Zoom, etc.).
The following additional roles are available on _macOS_:
* `appMenu` - Whole default "App" menu (About, Services, etc.)
* `hide` - Map to the `hide` action.
* `hideOthers` - Map to the `hideOtherApplications` action.
* `unhide` - Map to the `unhideAllApplications` action.
* `showSubstitutions` - Map to the `orderFrontSubstitutionsPanel` action.
* `toggleSmartQuotes` - Map to the `toggleAutomaticQuoteSubstitution` action.
* `toggleSmartDashes` - Map to the `toggleAutomaticDashSubstitution` action.
* `toggleTextReplacement` - Map to the `toggleAutomaticTextReplacement` action.
* `startSpeaking` - Map to the `startSpeaking` action.
* `stopSpeaking` - Map to the `stopSpeaking` action.
* `front` - Map to the `arrangeInFront` action.
* `zoom` - Map to the `performZoom` action.
* `toggleTabBar` - Map to the `toggleTabBar` action.
* `selectNextTab` - Map to the `selectNextTab` action.
* `selectPreviousTab` - Map to the `selectPreviousTab` action.
* `showAllTabs` - Map to the `showAllTabs` action.
* `mergeAllWindows` - Map to the `mergeAllWindows` action.
* `moveTabToNewWindow` - Map to the `moveTabToNewWindow` action.
* `window` - The submenu is a "Window" menu.
* `help` - The submenu is a "Help" menu.
* `services` - The submenu is a ["Services"](https://developer.apple.com/documentation/appkit/nsapplication/1428608-servicesmenu?language=objc) menu. This is only intended for use in the Application Menu and is _not_ the same as the "Services" submenu used in context menus in macOS apps, which is not implemented in Electron.
* `recentDocuments` - The submenu is an "Open Recent" menu.
* `clearRecentDocuments` - Map to the `clearRecentDocuments` action.
* `shareMenu` - The submenu is [share menu][ShareMenu]. The `sharingItem` property must also be set to indicate the item to share.
When specifying a `role` on macOS, `label` and `accelerator` are the only
options that will affect the menu item. All other options will be ignored.
Lowercase `role`, e.g. `toggledevtools`, is still supported.
> [!NOTE]
> The `enabled` and `visibility` properties are not available for top-level menu items in the tray on macOS.
### Instance Properties
The following properties are available on instances of `MenuItem`:
#### `menuItem.id`
A `string` indicating the item's unique id. This property can be
A `string` indicating the item's unique id, this property can be
dynamically changed.
#### `menuItem.label`
@@ -128,17 +203,17 @@ A `string` indicating the item's hover text.
#### `menuItem.enabled`
A `boolean` indicating whether the item is enabled. This property can be
A `boolean` indicating whether the item is enabled, this property can be
dynamically changed.
#### `menuItem.visible`
A `boolean` indicating whether the item is visible. This property can be
A `boolean` indicating whether the item is visible, this property can be
dynamically changed.
#### `menuItem.checked`
A `boolean` indicating whether the item is checked. This property can be
A `boolean` indicating whether the item is checked, this property can be
dynamically changed.
A `checkbox` menu item will toggle the `checked` property on and off when
@@ -169,3 +244,5 @@ A `number` indicating an item's sequential unique id.
#### `menuItem.menu`
A `Menu` that the item is a part of.
[ShareMenu]: https://developer.apple.com/design/human-interface-guidelines/macos/extensions/share-extensions/

View File

@@ -6,9 +6,6 @@
Process: [Main](../glossary.md#main-process)
> [!TIP]
> See also: [A detailed guide about how to implement menus in your application](../tutorial/menus.md).
> [!WARNING]
> Electron's built-in classes cannot be subclassed in user code.
> For more information, see [the FAQ](../faq.md#class-inheritance-does-not-work-with-electron-built-in-modules).
@@ -23,7 +20,7 @@ The `Menu` class has the following static methods:
#### `Menu.setApplicationMenu(menu)`
- `menu` Menu | null
* `menu` Menu | null
Sets `menu` as the application menu on macOS. On Windows and Linux, the
`menu` will be set as each window's top menu.
@@ -54,18 +51,18 @@ Returns `Menu | null` - The application menu, if set, or `null`, if not set.
#### `Menu.sendActionToFirstResponder(action)` _macOS_
- `action` string
* `action` string
Sends the `action` to the first responder of application. This is used for
emulating default macOS menu behaviors. Usually you would use the
[`role`](../tutorial/menus.md#roles) property of a [`MenuItem`](menu-item.md).
[`role`](menu-item.md#roles) property of a [`MenuItem`](menu-item.md).
See the [macOS Cocoa Event Handling Guide](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html#//apple_ref/doc/uid/10000060i-CH3-SW7)
for more information on macOS' native actions.
#### `Menu.buildFromTemplate(template)`
- `template` (MenuItemConstructorOptions | MenuItem)[]
* `template` (MenuItemConstructorOptions | MenuItem)[]
Returns `Menu`
@@ -80,50 +77,47 @@ The `menu` object has the following instance methods:
#### `menu.popup([options])`
- `options` Object (optional)
- `window` [BaseWindow](base-window.md) (optional) - Default is the focused window.
- `frame` [WebFrameMain](web-frame-main.md) (optional) - Provide the relevant frame
* `options` Object (optional)
* `window` [BaseWindow](base-window.md) (optional) - Default is the focused window.
* `frame` [WebFrameMain](web-frame-main.md) (optional) - Provide the relevant frame
if you want certain OS-level features such as Writing Tools on macOS to function correctly. Typically, this should be `params.frame` from the [`context-menu` event](web-contents.md#event-context-menu) on a WebContents, or the [`focusedFrame` property](web-contents.md#contentsfocusedframe-readonly) of a WebContents.
- `x` number (optional) - Default is the current mouse cursor position.
* `x` number (optional) - Default is the current mouse cursor position.
Must be declared if `y` is declared.
- `y` number (optional) - Default is the current mouse cursor position.
* `y` number (optional) - Default is the current mouse cursor position.
Must be declared if `x` is declared.
- `positioningItem` number (optional) _macOS_ - The index of the menu item to
* `positioningItem` number (optional) _macOS_ - The index of the menu item to
be positioned under the mouse cursor at the specified coordinates. Default
is -1.
- `sourceType` string (optional) _Windows_ _Linux_ - This should map to the `menuSourceType`
* `sourceType` string (optional) _Windows_ _Linux_ - This should map to the `menuSourceType`
provided by the `context-menu` event. It is not recommended to set this value manually,
only provide values you receive from other APIs or leave it `undefined`.
Can be `none`, `mouse`, `keyboard`, `touch`, `touchMenu`, `longPress`, `longTap`, `touchHandle`, `stylus`, `adjustSelection`, or `adjustSelectionReset`.
- `callback` Function (optional) - Called when menu is closed.
* `callback` Function (optional) - Called when menu is closed.
Pops up this menu as a context menu in the [`BaseWindow`](base-window.md).
> [!TIP]
> For more details, see the [Context Menu](../tutorial/context-menu.md) guide.
#### `menu.closePopup([window])`
- `window` [BaseWindow](base-window.md) (optional) - Default is the focused window.
* `window` [BaseWindow](base-window.md) (optional) - Default is the focused window.
Closes the context menu in the `window`.
#### `menu.append(menuItem)`
- `menuItem` [MenuItem](menu-item.md)
* `menuItem` [MenuItem](menu-item.md)
Appends the `menuItem` to the menu.
#### `menu.getMenuItemById(id)`
- `id` string
* `id` string
Returns `MenuItem | null` the item with the specified `id`
#### `menu.insert(pos, menuItem)`
- `pos` Integer
- `menuItem` [MenuItem](menu-item.md)
* `pos` Integer
* `menuItem` [MenuItem](menu-item.md)
Inserts the `menuItem` to the `pos` position of the menu.
@@ -139,7 +133,7 @@ Objects created with `new Menu` or returned by `Menu.buildFromTemplate` emit the
Returns:
- `event` Event
* `event` Event
Emitted when `menu.popup()` is called.
@@ -147,7 +141,7 @@ Emitted when `menu.popup()` is called.
Returns:
- `event` Event
* `event` Event
Emitted when a popup is closed either manually or with `menu.closePopup()`.
@@ -159,5 +153,296 @@ Emitted when a popup is closed either manually or with `menu.closePopup()`.
A `MenuItem[]` array containing the menu's items.
Each `Menu` consists of multiple [`MenuItem`](menu-item.md) instances and each `MenuItem`
can nest a `Menu` into its `submenu` property.
Each `Menu` consists of multiple [`MenuItem`](menu-item.md)s and each `MenuItem`
can have a submenu.
## Examples
An example of creating the application menu with the simple template API:
```js @ts-expect-error=[107]
const { app, Menu } = require('electron')
const isMac = process.platform === 'darwin'
const template = [
// { role: 'appMenu' }
...(isMac
? [{
label: app.name,
submenu: [
{ role: 'about' },
{ type: 'separator' },
{ role: 'services' },
{ type: 'separator' },
{ role: 'hide' },
{ role: 'hideOthers' },
{ role: 'unhide' },
{ type: 'separator' },
{ role: 'quit' }
]
}]
: []),
// { role: 'fileMenu' }
{
label: 'File',
submenu: [
isMac ? { role: 'close' } : { role: 'quit' }
]
},
// { role: 'editMenu' }
{
label: 'Edit',
submenu: [
{ role: 'undo' },
{ role: 'redo' },
{ type: 'separator' },
{ role: 'cut' },
{ role: 'copy' },
{ role: 'paste' },
...(isMac
? [
{ role: 'pasteAndMatchStyle' },
{ role: 'delete' },
{ role: 'selectAll' },
{ type: 'separator' },
{
label: 'Speech',
submenu: [
{ role: 'startSpeaking' },
{ role: 'stopSpeaking' }
]
}
]
: [
{ role: 'delete' },
{ type: 'separator' },
{ role: 'selectAll' }
])
]
},
// { role: 'viewMenu' }
{
label: 'View',
submenu: [
{ role: 'reload' },
{ role: 'forceReload' },
{ role: 'toggleDevTools' },
{ type: 'separator' },
{ role: 'resetZoom' },
{ role: 'zoomIn' },
{ role: 'zoomOut' },
{ type: 'separator' },
{ role: 'togglefullscreen' }
]
},
// { role: 'windowMenu' }
{
label: 'Window',
submenu: [
{ role: 'minimize' },
{ role: 'zoom' },
...(isMac
? [
{ type: 'separator' },
{ role: 'front' },
{ type: 'separator' },
{ role: 'window' }
]
: [
{ role: 'close' }
])
]
},
{
role: 'help',
submenu: [
{
label: 'Learn More',
click: async () => {
const { shell } = require('electron')
await shell.openExternal('https://electronjs.org')
}
}
]
}
]
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
```
### Render process
To create menus initiated by the renderer process, send the required
information to the main process using IPC and have the main process display the
menu on behalf of the renderer.
Below is an example of showing a menu when the user right clicks the page:
```js @ts-expect-error=[21]
// renderer
window.addEventListener('contextmenu', (e) => {
e.preventDefault()
ipcRenderer.send('show-context-menu')
})
ipcRenderer.on('context-menu-command', (e, command) => {
// ...
})
// main
ipcMain.on('show-context-menu', (event) => {
const template = [
{
label: 'Menu Item 1',
click: () => { event.sender.send('context-menu-command', 'menu-item-1') }
},
{ type: 'separator' },
{ label: 'Menu Item 2', type: 'checkbox', checked: true }
]
const menu = Menu.buildFromTemplate(template)
menu.popup({ window: BrowserWindow.fromWebContents(event.sender) })
})
```
## Notes on macOS Application Menu
macOS has a completely different style of application menu from Windows and
Linux. Here are some notes on making your app's menu more native-like.
### Standard Menus
On macOS there are many system-defined standard menus, like the [`Services`](https://developer.apple.com/documentation/appkit/nsapplication/1428608-servicesmenu?language=objc) and
`Windows` menus. To make your menu a standard menu, you should set your menu's
`role` to one of the following and Electron will recognize them and make them
become standard menus:
* `window`
* `help`
* `services`
### Standard Menu Item Actions
macOS has provided standard actions for some menu items, like `About xxx`,
`Hide xxx`, and `Hide Others`. To set the action of a menu item to a standard
action, you should set the `role` attribute of the menu item.
### Main Menu's Name
On macOS the label of the application menu's first item is always your app's
name, no matter what label you set. To change it, modify your app bundle's
`Info.plist` file. See
[About Information Property List Files][AboutInformationPropertyListFiles]
for more information.
### Menu Sublabels
Menu sublabels, or [subtitles](https://developer.apple.com/documentation/appkit/nsmenuitem/subtitle?language=objc), can be added to menu items using the `sublabel` option. Below is an example based on the renderer example above:
```js @ts-expect-error=[12]
// main
ipcMain.on('show-context-menu', (event) => {
const template = [
{
label: 'Menu Item 1',
sublabel: 'Subtitle 1',
click: () => { event.sender.send('context-menu-command', 'menu-item-1') }
},
{ type: 'separator' },
{ label: 'Menu Item 2', sublabel: 'Subtitle 2', type: 'checkbox', checked: true }
]
const menu = Menu.buildFromTemplate(template)
menu.popup({ window: BrowserWindow.fromWebContents(event.sender) })
})
```
## Setting Menu for Specific Browser Window (_Linux_ _Windows_)
The [`setMenu` method][setMenu] of browser windows can set the menu of certain
browser windows.
## Menu Item Position
You can make use of `before`, `after`, `beforeGroupContaining`, `afterGroupContaining` and `id` to control how the item will be placed when building a menu with `Menu.buildFromTemplate`.
* `before` - Inserts this item before the item with the specified id. If the
referenced item doesn't exist the item will be inserted at the end of
the menu. Also implies that the menu item in question should be placed in the same “group” as the item.
* `after` - Inserts this item after the item with the specified id. If the
referenced item doesn't exist the item will be inserted at the end of
the menu. Also implies that the menu item in question should be placed in the same “group” as the item.
* `beforeGroupContaining` - Provides a means for a single context menu to declare
the placement of their containing group before the containing group of the item with the specified id.
* `afterGroupContaining` - Provides a means for a single context menu to declare
the placement of their containing group after the containing group of the item with the specified id.
By default, items will be inserted in the order they exist in the template unless one of the specified positioning keywords is used.
### Examples
Template:
```js
[
{ id: '1', label: 'one' },
{ id: '2', label: 'two' },
{ id: '3', label: 'three' },
{ id: '4', label: 'four' }
]
```
Menu:
```sh
- 1
- 2
- 3
- 4
```
Template:
```js
[
{ id: '1', label: 'one' },
{ type: 'separator' },
{ id: '3', label: 'three', beforeGroupContaining: ['1'] },
{ id: '4', label: 'four', afterGroupContaining: ['2'] },
{ type: 'separator' },
{ id: '2', label: 'two' }
]
```
Menu:
```sh
- 3
- 4
- ---
- 1
- ---
- 2
```
Template:
```js
[
{ id: '1', label: 'one', after: ['3'] },
{ id: '2', label: 'two', before: ['1'] },
{ id: '3', label: 'three' }
]
```
Menu:
```sh
- ---
- 3
- 2
- 1
```
[AboutInformationPropertyListFiles]: https://developer.apple.com/library/ios/documentation/general/Reference/InfoPlistKeyReference/Articles/AboutInformationPropertyListFiles.html
[setMenu]: browser-window.md#winsetmenumenu-linux-windows

View File

@@ -2,5 +2,5 @@
* `type` string - The type of the event, can be `rawKeyDown`, `keyDown`, `keyUp` or `char`.
* `keyCode` string - The character that will be sent
as the keyboard event. Should only use valid [Accelerator](../../tutorial/keyboard-shortcuts.md#accelerators)
key codes.
as the keyboard event. Should only use the valid key codes in
[Accelerator](../accelerator.md).

View File

@@ -1,17 +1,35 @@
# USBDevice Object
* `configuration` Object (optional) - A [USBConfiguration](https://developer.mozilla.org/en-US/docs/Web/API/USBConfiguration) object containing information about the currently selected configuration of a USB device.
* `configurationValue` Integer - the configuration value of this configuration.
* `configurationName` string - the name provided by the device to describe this configuration.
* `interfaces` Object[] - An array of [USBInterface](https://developer.mozilla.org/en-US/docs/Web/API/USBInterface) objects containing information about an interface provided by the USB device.
* `interfaceNumber` Integer - the interface number of this interface.
* `alternate` Object - the currently selected alternative configuration of this interface.
* `alternateSetting` Integer - the alternate setting number of this interface.
* `interfaceClass` Integer - the class of this interface. See [USB.org](https://www.usb.org/defined-class-codes) for class code descriptions.
* `interfaceSubclass` Integer - the subclass of this interface.
* `interfaceProtocol` Integer - the protocol supported by this interface.
* `interfaceName` string (optional) - the name of the interface, if one is provided by the device.
* `endpoints` Object[] - an array containing instances of the [USBEndpoint interface](https://developer.mozilla.org/en-US/docs/Web/API/USBEndpoint) describing each of the endpoints that are part of this interface.
* `endpointNumber` Integer - this endpoint's "endpoint number" which is a value from 1 to 15.
* `direction` string - the direction in which this endpoint transfers data - can be either 'in' or 'out'.
* `type` string - the type of this endpoint - can be either 'bulk', 'interrupt', or 'isochronous'.
* `packetSize` Integer - the size of the packets that data sent through this endpoint will be divided into.
* `alternates` Object[] - an array containing instances of the [USBAlternateInterface](https://developer.mozilla.org/en-US/docs/Web/API/USBAlternateInterface) interface describing each of the alternative configurations possible for this interface.
* `configurations` Object[] - An array of [USBConfiguration](https://developer.mozilla.org/en-US/docs/Web/API/USBConfiguration) interfaces for controlling a paired USB device.
* `deviceClass` Integer - The device class for the communication interface supported by the device.
* `deviceId` string - Unique identifier for the device.
* `vendorId` Integer - The USB vendor ID.
* `productId` Integer - The USB product ID.
* `productName` string (optional) - Name of the device.
* `serialNumber` string (optional) - The USB device serial number.
* `manufacturerName` string (optional) - The manufacturer name of the device.
* `usbVersionMajor` Integer - The USB protocol major version supported by the device
* `usbVersionMinor` Integer - The USB protocol minor version supported by the device
* `usbVersionSubminor` Integer - The USB protocol subminor version supported by the device
* `deviceClass` Integer - The device class for the communication interface supported by the device
* `deviceSubclass` Integer - The device subclass for the communication interface supported by the device
* `deviceProtocol` Integer - The device protocol for the communication interface supported by the device
* `deviceProtocol` Integer - The device protocol for the communication interface supported by the device.
* `deviceSubclass` Integer - The device subclass for the communication interface supported by the device.
* `deviceVersionMajor` Integer - The major version number of the device as defined by the device manufacturer.
* `deviceVersionMinor` Integer - The minor version number of the device as defined by the device manufacturer.
* `deviceVersionSubminor` Integer - The subminor version number of the device as defined by the device manufacturer.
* `manufacturerName` string (optional) - The manufacturer name of the device.
* `productId` Integer - The USB product ID.
* `productName` string (optional) - Name of the device.
* `serialNumber` string (optional) - The USB device serial number.
* `usbVersionMajor` Integer - The USB protocol major version supported by the device.
* `usbVersionMinor` Integer - The USB protocol minor version supported by the device.
* `usbVersionSubminor` Integer - The USB protocol subminor version supported by the device.
* `vendorId` Integer - The USB vendor ID.

View File

@@ -149,6 +149,7 @@
`WebContents` when the preferred size changes. Default is `false`.
* `transparent` boolean (optional) - Whether to enable background transparency for the guest page. Default is `true`. **Note:** The guest page's text and background colors are derived from the [color scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/color-scheme) of its root element. When transparency is enabled, the text color will still change accordingly but the background will remain transparent.
* `enableDeprecatedPaste` boolean (optional) _Deprecated_ - Whether to enable the `paste` [execCommand](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand). Default is `false`.
* `enableCornerSmoothingCSS` boolean (optional) _Experimental_ - Whether the [`-electron-corner-smoothing` CSS rule](../corner-smoothing-css.md) is enabled. Default is `true`.
[chrome-content-scripts]: https://developer.chrome.com/extensions/content_scripts#execution-environment
[runtime-enabled-features]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/runtime_enabled_features.json5

View File

@@ -8,7 +8,7 @@ Process: [Main](../glossary.md#main-process)
`Tray` is an [EventEmitter][event-emitter].
```js title='Creating a basic tray menu'
```js
const { app, Menu, Tray } = require('electron')
let tray = null
@@ -25,9 +25,6 @@ app.whenReady().then(() => {
})
```
> [!TIP]
> See also: [A detailed guide about how to implement Tray menus](../tutorial/tray.md).
> [!WARNING]
> Electron's built-in classes cannot be subclassed in user code.
> For more information, see [the FAQ](../faq.md#class-inheritance-does-not-work-with-electron-built-in-modules).
@@ -332,47 +329,3 @@ The `bounds` of this tray icon as `Object`.
Returns `boolean` - Whether the tray icon is destroyed.
[event-emitter]: https://nodejs.org/api/events.html#events_class_eventemitter
## Platform considerations
### Linux
* Tray icon uses [StatusNotifierItem](https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/)
by default, when it is not available in user's desktop environment the
`GtkStatusIcon` will be used instead.
* The `click` event is emitted when the tray icon receives activation from
user, however the StatusNotifierItem spec does not specify which action would
cause an activation, for some environments it is left mouse click, but for
some it might be double left mouse click.
* In order for changes made to individual `MenuItem`s to take effect,
you have to call `setContextMenu` again. For example:
```js
const { app, Menu, Tray } = require('electron')
let appIcon = null
app.whenReady().then(() => {
appIcon = new Tray('/path/to/my/icon')
const contextMenu = Menu.buildFromTemplate([
{ label: 'Item1', type: 'radio' },
{ label: 'Item2', type: 'radio' }
])
// Make a change to the context menu
contextMenu.items[1].checked = false
// Call this again for Linux because we modified the context menu
appIcon.setContextMenu(contextMenu)
})
```
### macOS
* Icons passed to the Tray constructor should be [Template Images](native-image.md#template-image-macos).
* To make sure your icon isn't grainy on retina monitors, be sure your `@2x` image is 144dpi.
* If you are bundling your application (e.g., with webpack for development), be sure that the file names are not being mangled or hashed. The filename needs to end in Template, and the `@2x` image needs to have the same filename as the standard image, or MacOS will not magically invert your image's colors or use the high density image.
* 16x16 (72dpi) and 32x32@2x (144dpi) work well for most icons.
### Windows
* It is recommended to use `ICO` icons to get best visual effects.

View File

@@ -486,6 +486,16 @@ Emitted when the web page becomes unresponsive.
Emitted when the unresponsive web page becomes responsive again.
#### Event: 'plugin-crashed'
Returns:
* `event` Event
* `name` string
* `version` string
Emitted when a plugin process has crashed.
#### Event: 'destroyed'
Emitted when `webContents` is destroyed.

View File

@@ -237,11 +237,6 @@ not used again.
A `string` representing the frame name.
#### `frame.frameToken` _Readonly_
A `string` which uniquely identifies the frame within its associated renderer
process. This is equivalent to [`webFrame.frameToken`](web-frame.md#webframeframetoken-readonly).
#### `frame.osProcessId` _Readonly_
An `Integer` representing the operating system `pid` of the process which owns this frame.

View File

@@ -67,7 +67,7 @@ Sets the maximum and minimum pinch-to-zoom level.
> [!NOTE]
> Visual zoom only applies to pinch-to-zoom behavior. Cmd+/-/0 zoom shortcuts are
> controlled by the 'zoomIn', 'zoomOut', and 'resetZoom' MenuItem roles in the application
> Menu. To disable shortcuts, manually [define the Menu](../tutorial/menus.md) and omit zoom roles
> Menu. To disable shortcuts, manually [define the Menu](./menu.md#examples) and omit zoom roles
> from the definition.
### `webFrame.setSpellCheckProvider(language, provider)`
@@ -265,7 +265,7 @@ Returns `WebFrame` - A child of `webFrame` with the supplied `name`, `null`
would be returned if there's no such frame or if the frame is not in the current
renderer process.
### `webFrame.findFrameByRoutingId(routingId)` _Deprecated_
### `webFrame.findFrameByRoutingId(routingId)`
* `routingId` Integer - An `Integer` representing the unique frame id in the
current renderer process. Routing IDs can be retrieved from `WebFrame`
@@ -274,15 +274,6 @@ renderer process.
Returns `WebFrame` - that has the supplied `routingId`, `null` if not found.
### `webFrame.findFrameByToken(frameToken)`
* `frameToken` string - A `string` representing the unique frame id in the
current renderer process. Frame tokens can be retrieved from `WebFrame`
instances (`webFrame.frameToken`) and can also be retrieved from
`WebFrameMain` instances using `webFrameMain.frameToken`.
Returns `WebFrame` - that has the supplied `frameToken`, `null` if not found.
### `webFrame.isWordMisspelled(word)`
* `word` string - The word to be spellchecked.
@@ -327,14 +318,8 @@ A `WebFrame | null` representing next sibling frame, the property would be `null
`webFrame` is the last frame in its parent or if the next sibling is not in the
current renderer process.
### `webFrame.routingId` _Readonly_ _Deprecated_
### `webFrame.routingId` _Readonly_
An `Integer` representing the unique frame id in the current renderer process.
Distinct WebFrame instances that refer to the same underlying frame will have
the same `routingId`.
### `webFrame.frameToken` _Readonly_
A `string` representing the unique frame token in the current renderer process.
Distinct WebFrame instances that refer to the same underlying frame will have
the same `frameToken`.

View File

@@ -1002,6 +1002,15 @@ Returns:
Fired when the renderer process unexpectedly disappears. This is normally
because it was crashed or killed.
### Event: 'plugin-crashed'
Returns:
* `name` string
* `version` string
Fired when a plugin process is crashed.
### Event: 'destroyed'
Fired when the WebContents is destroyed.

View File

@@ -21,22 +21,6 @@ macOS 11 (Big Sur) is no longer supported by [Chromium](https://chromium-review.
Older versions of Electron will continue to run on Big Sur, but macOS 12 (Monterey)
or later will be required to run Electron v38.0.0 and higher.
### Removed: `plugin-crashed` event
The `plugin-crashed` event has been removed from `webContents`.
### Deprecated: `webFrame.routingId` property
The `routingId` property will be removed from `webFrame` objects.
You should use `webFrame.frameToken` instead.
### Deprecated: `webFrame.findFrameByRoutingId(routingId)`
The `webFrame.findFrameByRoutingId(routingId)` function will be removed.
You should use `webFrame.findFrameByToken(frameToken)` instead.
## Planned Breaking API Changes (37.0)
### Utility Process unhandled rejection behavior change

View File

@@ -7,8 +7,11 @@ Follow the guidelines below for building **Electron itself** on Linux, for the p
## Prerequisites
* At least 25GB disk space and 8GB RAM.
* Python >= 3.9.
* [Node.js](https://nodejs.org/download/) >= 22.12.0
* Python >= 3.7.
* Node.js. There are various ways to install Node. You can download
source code from [nodejs.org](https://nodejs.org) and compile it.
Doing so permits installing Node on your own home directory as a standard user.
Or try repositories such as [NodeSource](https://nodesource.com/blog/nodejs-v012-iojs-and-the-nodesource-linux-repositories).
* [clang](https://clang.llvm.org/get_started.html) 3.4 or later.
* Development headers of GTK 3 and libnotify.

View File

@@ -10,8 +10,8 @@ Follow the guidelines below for building **Electron itself** on macOS, for the p
* [Xcode](https://developer.apple.com/technologies/tools/). The exact version
needed depends on what branch you are building, but the latest version of
Xcode is generally a good bet for building `main`.
* Python >= 3.9
* [Node.js](https://nodejs.org/download/) >= 22.12.0
* [node.js](https://nodejs.org) (external)
* Python >= 3.7
### Arm64-specific prerequisites

View File

@@ -14,7 +14,7 @@ Follow the guidelines below for building **Electron itself** on Windows, for the
set a few environment variables to point the toolchains to your installation path.
* `vs2022_install = DRIVE:\path\to\Microsoft Visual Studio\2022\Community`, replacing `2022` and `Community` with your installed versions and replacing `DRIVE:` with the drive that Visual Studio is on. Often, this will be `C:`.
* `WINDOWSSDKDIR = DRIVE:\path\to\Windows Kits\10`, replacing `DRIVE:` with the drive that Windows Kits is on. Often, this will be `C:`.
* [Node.js](https://nodejs.org/download/) >= 22.12.0
* [Node.js](https://nodejs.org/download/)
* [Git](https://git-scm.com)
* Debugging Tools for Windows of Windows SDK 10.0.15063.468 if you plan on
creating a full distribution since `symstore.exe` is used for creating a symbol

View File

@@ -60,12 +60,12 @@ namespace electron {
namespace api {
class ApiName : public gin::DeprecatedWrappable<ApiName> {
class ApiName : public gin::Wrappable<ApiName> {
public:
static gin::Handle<ApiName> Create(v8::Isolate* isolate);
// gin::Wrappable
static gin::DeprecatedWrapperInfo kWrapperInfo;
static gin::WrapperInfo kWrapperInfo;
gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) override;
const char* GetTypeName() override;
@@ -90,7 +90,7 @@ namespace electron {
namespace api {
gin::DeprecatedWrapperInfo ApiName::kWrapperInfo = {gin::kEmbedderNativeGin};
gin::WrapperInfo ApiName::kWrapperInfo = {gin::kEmbedderNativeGin};
gin::ObjectTemplateBuilder ApiName::GetObjectTemplateBuilder(
v8::Isolate* isolate) {

View File

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>Hit Alt+Ctrl+I on Windows or Opt+Cmd+I on Mac to see a message printed to the console.</p>
</body>
</html>

View File

@@ -0,0 +1,28 @@
const { app, BrowserWindow, globalShortcut } = require('electron/main')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
globalShortcut.register('Alt+CommandOrControl+I', () => {
console.log('Electron loves global shortcuts!')
})
}).then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

View File

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>Hit Alt+Shift+I on Windows, or Opt+Cmd+I on mac to see a message printed to the console.</p>
</body>
</html>

View File

@@ -0,0 +1,36 @@
const { app, BrowserWindow, Menu, MenuItem } = require('electron/main')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
const menu = new Menu()
menu.append(new MenuItem({
label: 'Electron',
submenu: [{
role: 'help',
accelerator: process.platform === 'darwin' ? 'Alt+Cmd+I' : 'Alt+Shift+I',
click: () => { console.log('Electron rocks!') }
}]
}))
Menu.setApplicationMenu(menu)
app.whenReady().then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

View File

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>Right click the dock icon to see the custom menu options.</p>
</body>
</html>

View File

@@ -0,0 +1,40 @@
const { app, BrowserWindow, Menu } = require('electron/main')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
const dockMenu = Menu.buildFromTemplate([
{
label: 'New Window',
click () { console.log('New Window') }
}, {
label: 'New Window with Settings',
submenu: [
{ label: 'Basic' },
{ label: 'Pro' }
]
},
{ label: 'New Command...' }
])
app.whenReady().then(() => {
app.dock?.setMenu(dockMenu)
}).then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})

View File

@@ -1,14 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Context Menu Demo</title>
</head>
<body>
<h1>Context Menu Demo</h1>
<!-- highlight-next-line -->
<textarea id="editable"></textarea>
</body>
</html>

View File

@@ -1,39 +0,0 @@
// Modules to control application life and create native browser window
const { app, BrowserWindow, ipcMain, Menu } = require('electron/main')
const path = require('node:path')
function createWindow () {
const mainWindow = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
mainWindow.loadFile('index.html')
const menu = Menu.buildFromTemplate([
{ role: 'copy' },
{ role: 'cut' },
{ role: 'paste' },
{ role: 'selectall' }
])
// highlight-start
ipcMain.on('context-menu', (event) => {
menu.popup({
window: BrowserWindow.fromWebContents(event.sender)
})
})
// highlight-end
}
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})

View File

@@ -1,11 +0,0 @@
const { ipcRenderer } = require('electron/renderer')
document.addEventListener('DOMContentLoaded', () => {
const textarea = document.getElementById('editable')
// highlight-start
textarea.addEventListener('contextmenu', (event) => {
event.preventDefault()
ipcRenderer.send('context-menu')
})
// highlight-end
})

View File

@@ -1,14 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Context Menu Demo</title>
</head>
<body>
<h1>Context Menu Demo</h1>
<!-- highlight-next-line -->
<textarea></textarea>
</body>
</html>

View File

@@ -1,32 +0,0 @@
const { app, BrowserWindow, Menu } = require('electron/main')
function createWindow () {
const win = new BrowserWindow()
// highlight-start
const menu = Menu.buildFromTemplate([
{ role: 'copy' },
{ role: 'cut' },
{ role: 'paste' },
{ role: 'selectall' }
])
win.webContents.on('context-menu', (_event, params) => {
// only show the context menu if the element is editable
if (params.isEditable) {
menu.popup()
}
})
// highlight-end
win.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})

View File

@@ -0,0 +1,124 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Customize Menus</title>
</head>
<body>
<div>
<h1>Customize Menus</h1>
<h3>
The <code>Menu</code> and <code>MenuItem</code> modules can be used to
create custom native menus.
</h3>
<p>
There are two kinds of menus: the application (top) menu and context
(right-click) menu.
</p>
<p>
Open the
<a href="https://www.electronjs.org/docs/latest/api/menu"
>full API documentation<span
>(opens in new window)</span
></a
>
in your browser.
</p>
</div>
<div>
<h2>Create an application menu</h2>
<div>
<div>
<p>
The <code>Menu</code> and <code>MenuItem</code> modules allow you to
customize your application menu. If you don't set any menu, Electron
will generate a minimal menu for your app by default.
</p>
<p>
If you click the 'View' option in the application menu and then the
'App Menu Demo', you'll see an information box displayed.
</p>
<div>
<h2>ProTip</h2>
<strong>Know operating system menu differences.</strong>
<p>
When designing an app for multiple operating systems it's
important to be mindful of the ways application menu conventions
differ on each operating system.
</p>
<p>
For instance, on Windows, accelerators are set with an
<code>&</code>. Naming conventions also vary, like between
"Settings" or "Preferences". Below are resources for learning
operating system specific standards.
</p>
<ul>
<li>
<a
href="https://developer.apple.com/design/human-interface-guidelines/the-menu-bar"
>macOS<span
>(opens in new window)</span
></a
>
</li>
<li>
<a
href="https://learn.microsoft.com/en-us/windows/apps/design/controls/menus-and-context-menus"
>Windows<span
>(opens in new window)</span
></a
>
</li>
<li>
<a
href="https://developer.gnome.org/hig/patterns/controls/menus.html"
>Linux<span
>(opens in new window)</span
></a
>
</li>
</ul>
</div>
</div>
</div>
</div>
<div>
<h2>Create a context menu</h2>
<div>
<div>
<div>
<button id="context-menu">View Demo</button>
</div>
<p>
A context, or right-click, menu can be created with the
<code>Menu</code> and <code>MenuItem</code> modules as well. You can
right-click anywhere in this app or click the demo button to see an
example context menu.
</p>
<p>
In this demo we use the <code>ipcRenderer</code> module to show the
context menu when explicitly calling it from the renderer process.
</p>
<p>
See the full
<a
href="https://www.electronjs.org/docs/latest/api/web-contents/#event-context-menu"
>context-menu event documentation</a
>
for all the available properties.
</p>
</div>
</div>
</div>
<script src="renderer.js"></script>
</body>
</html>

View File

@@ -0,0 +1,368 @@
// Modules to control application life and create native browser window
const {
BrowserWindow,
Menu,
MenuItem,
ipcMain,
app,
shell,
dialog,
autoUpdater
} = require('electron/main')
const path = require('node:path')
const menu = new Menu()
menu.append(new MenuItem({ label: 'Hello' }))
menu.append(new MenuItem({ type: 'separator' }))
menu.append(
new MenuItem({ label: 'Electron', type: 'checkbox', checked: true })
)
const template = [
{
label: 'Edit',
submenu: [
{
label: 'Undo',
accelerator: 'CmdOrCtrl+Z',
role: 'undo'
},
{
label: 'Redo',
accelerator: 'Shift+CmdOrCtrl+Z',
role: 'redo'
},
{
type: 'separator'
},
{
label: 'Cut',
accelerator: 'CmdOrCtrl+X',
role: 'cut'
},
{
label: 'Copy',
accelerator: 'CmdOrCtrl+C',
role: 'copy'
},
{
label: 'Paste',
accelerator: 'CmdOrCtrl+V',
role: 'paste'
},
{
label: 'Select All',
accelerator: 'CmdOrCtrl+A',
role: 'selectall'
}
]
},
{
label: 'View',
submenu: [
{
label: 'Reload',
accelerator: 'CmdOrCtrl+R',
click: (item, focusedWindow) => {
if (focusedWindow) {
// on reload, start fresh and close any old
// open secondary windows
if (focusedWindow.id === 1) {
for (const win of BrowserWindow.getAllWindows()) {
if (win.id > 1) win.close()
}
}
focusedWindow.reload()
}
}
},
{
label: 'Toggle Full Screen',
accelerator: (() => {
if (process.platform === 'darwin') {
return 'Ctrl+Command+F'
} else {
return 'F11'
}
})(),
click: (item, focusedWindow) => {
if (focusedWindow) {
focusedWindow.setFullScreen(!focusedWindow.isFullScreen())
}
}
},
{
label: 'Toggle Developer Tools',
accelerator: (() => {
if (process.platform === 'darwin') {
return 'Alt+Command+I'
} else {
return 'Ctrl+Shift+I'
}
})(),
click: (item, focusedWindow) => {
if (focusedWindow) {
focusedWindow.webContents.toggleDevTools()
}
}
},
{
type: 'separator'
},
{
label: 'App Menu Demo',
click: function (item, focusedWindow) {
if (focusedWindow) {
const options = {
type: 'info',
title: 'Application Menu Demo',
buttons: ['Ok'],
message:
'This demo is for the Menu section, showing how to create a clickable menu item in the application menu.'
}
dialog.showMessageBox(focusedWindow, options, function () {})
}
}
}
]
},
{
label: 'Window',
role: 'window',
submenu: [
{
label: 'Minimize',
accelerator: 'CmdOrCtrl+M',
role: 'minimize'
},
{
label: 'Close',
accelerator: 'CmdOrCtrl+W',
role: 'close'
},
{
type: 'separator'
},
{
label: 'Reopen Window',
accelerator: 'CmdOrCtrl+Shift+T',
enabled: false,
key: 'reopenMenuItem',
click: () => {
app.emit('activate')
}
}
]
},
{
label: 'Help',
role: 'help',
submenu: [
{
label: 'Learn More',
click: () => {
shell.openExternal('https://electronjs.org')
}
}
]
}
]
function addUpdateMenuItems (items, position) {
if (process.mas) return
const version = app.getVersion()
const updateItems = [
{
label: `Version ${version}`,
enabled: false
},
{
label: 'Checking for Update',
enabled: false,
key: 'checkingForUpdate'
},
{
label: 'Check for Update',
visible: false,
key: 'checkForUpdate',
click: () => {
autoUpdater.checkForUpdates()
}
},
{
label: 'Restart and Install Update',
enabled: true,
visible: false,
key: 'restartToUpdate',
click: () => {
autoUpdater.quitAndInstall()
}
}
]
items.splice.apply(items, [position, 0].concat(updateItems))
}
function findReopenMenuItem () {
const menu = Menu.getApplicationMenu()
if (!menu) return
let reopenMenuItem
for (const item of menu.items) {
if (item.submenu) {
for (const subitem of item.submenu.items) {
if (subitem.key === 'reopenMenuItem') {
reopenMenuItem = subitem
}
}
}
}
return reopenMenuItem
}
if (process.platform === 'darwin') {
const name = app.getName()
template.unshift({
label: name,
submenu: [
{
label: `About ${name}`,
role: 'about'
},
{
type: 'separator'
},
{
label: 'Services',
role: 'services',
submenu: []
},
{
type: 'separator'
},
{
label: `Hide ${name}`,
accelerator: 'Command+H',
role: 'hide'
},
{
label: 'Hide Others',
accelerator: 'Command+Alt+H',
role: 'hideothers'
},
{
label: 'Show All',
role: 'unhide'
},
{
type: 'separator'
},
{
label: 'Quit',
accelerator: 'Command+Q',
click: () => {
app.quit()
}
}
]
})
// Window menu.
template[3].submenu.push(
{
type: 'separator'
},
{
label: 'Bring All to Front',
role: 'front'
}
)
addUpdateMenuItems(template[0].submenu, 1)
}
if (process.platform === 'win32') {
const helpMenu = template[template.length - 1].submenu
addUpdateMenuItems(helpMenu, 0)
}
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null
})
// Open external links in the default browser
mainWindow.webContents.on('will-navigate', (event, url) => {
event.preventDefault()
shell.openExternal(url)
})
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
createWindow()
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
})
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
const reopenMenuItem = findReopenMenuItem()
if (reopenMenuItem) reopenMenuItem.enabled = true
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On macOS it is common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
app.on('browser-window-created', (event, win) => {
const reopenMenuItem = findReopenMenuItem()
if (reopenMenuItem) reopenMenuItem.enabled = false
win.webContents.on('context-menu', (e, params) => {
menu.popup(win, params.x, params.y)
})
})
ipcMain.on('show-context-menu', event => {
const win = BrowserWindow.fromWebContents(event.sender)
menu.popup(win)
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

View File

@@ -0,0 +1,5 @@
const { contextBridge, ipcRenderer } = require('electron/renderer')
contextBridge.exposeInMainWorld('electronAPI', {
showContextMenu: () => ipcRenderer.send('show-context-menu')
})

View File

@@ -0,0 +1,6 @@
// Tell main process to show the menu when demo button is clicked
const contextMenuBtn = document.getElementById('context-menu')
contextMenuBtn.addEventListener('click', () => {
window.electronAPI.showContextMenu()
})

View File

@@ -1,18 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Dock Menu Demo</title>
</head>
<body>
<h1>Dock Menu Demo</h1>
<ul>
<li>Create new BrowserWindow instances via the "New Window" option</li>
<li>Close all BrowserWindow instances via the "Close All Windows" option</li>
<li>Read the docs via the "Show Electron Docs" option</li>
</ul>
<script src="./renderer.js"></script>
</body>
</html>

View File

@@ -1,46 +0,0 @@
const { app, BrowserWindow, Menu } = require('electron/main')
const { shell } = require('electron/common')
function createWindow () {
const win = new BrowserWindow()
win.loadFile('index.html')
}
function closeAllWindows () {
const wins = BrowserWindow.getAllWindows()
for (const win of wins) {
win.close()
}
}
app.whenReady().then(() => {
createWindow()
const dockMenu = Menu.buildFromTemplate([
{
label: 'New Window',
click: () => { createWindow() }
},
{
label: 'Close All Windows',
click: () => { closeAllWindows() }
},
{
label: 'Open Electron Docs',
click: () => {
shell.openExternal('https://electronjs.org/docs')
}
}
// add more menu options to the array
])
app.dock.setMenu(dockMenu)
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})

View File

@@ -1 +0,0 @@
document.title = `${document.title} - ${new Date()}`

View File

@@ -1,19 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Tray Menu Demo</title>
</head>
<body>
<h1>Tray Menu Demo</h1>
<p>This app will stay running even after all windows are closed.</p>
<ul>
<li>Use the "Open App" menu item to focus the main window (or open one if it does not exist).</li>
<li>Change between red and green Tray icons with the "Set Green Icon" checkbox.</li>
<li>Give the Tray icon a title using the "Set Title" checkbox.</li>
<li>Quit the app using the "Quit" menu item.</li>
</ul>
</body>
</html>

View File

@@ -1,60 +0,0 @@
const { app, BrowserWindow, Menu, Tray } = require('electron/main')
const { nativeImage } = require('electron/common')
// save a reference to the Tray object globally to avoid garbage collection
let tray = null
function createWindow () {
const mainWindow = new BrowserWindow()
mainWindow.loadFile('index.html')
}
// The Tray object can only be instantiated after the 'ready' event is fired
app.whenReady().then(() => {
createWindow()
const red = nativeImage.createFromDataURL('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACTSURBVHgBpZKBCYAgEEV/TeAIjuIIbdQIuUGt0CS1gW1iZ2jIVaTnhw+Cvs8/OYDJA4Y8kR3ZR2/kmazxJbpUEfQ/Dm/UG7wVwHkjlQdMFfDdJMFaACebnjJGyDWgcnZu1/lrCrl6NCoEHJBrDwEr5NrT6ko/UV8xdLAC2N49mlc5CylpYh8wCwqrvbBGLoKGvz8Bfq0QPWEUo/EAAAAASUVORK5CYII=')
const green = nativeImage.createFromDataURL('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACOSURBVHgBpZLRDYAgEEOrEzgCozCCGzkCbKArOIlugJvgoRAUNcLRpvGH19TkgFQWkqIohhK8UEaKwKcsOg/+WR1vX+AlA74u6q4FqgCOSzwsGHCwbKliAF89Cv89tWmOT4VaVMoVbOBrdQUz+FrD6XItzh4LzYB1HFJ9yrEkZ4l+wvcid9pTssh4UKbPd+4vED2Nd54iAAAAAElFTkSuQmCC')
tray = new Tray(red)
tray.setToolTip('Tray Icon Demo')
const contextMenu = Menu.buildFromTemplate([
{
label: 'Open App',
click: () => {
const wins = BrowserWindow.getAllWindows()
if (wins.length === 0) {
createWindow()
} else {
wins[0].focus()
}
}
},
{
label: 'Set Green Icon',
type: 'checkbox',
click: ({ checked }) => {
checked ? tray.setImage(green) : tray.setImage(red)
}
},
{
label: 'Set Title',
type: 'checkbox',
click: ({ checked }) => {
checked ? tray.setTitle('Title') : tray.setTitle('')
}
},
{ role: 'quit' }
])
tray.setContextMenu(contextMenu)
})
app.on('window-all-closed', function () {
// This will prevent the app from closing when windows close
})
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})

View File

@@ -0,0 +1,47 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Tray</title>
</head>
<body>
<div>
<h1>Tray</h1>
<h3>
The <code>tray</code> module allows you to create an icon in the
operating system's notification area.
</h3>
<p>This icon can also have a context menu attached.</p>
<p>
Open the
<a href="https://www.electronjs.org/docs/latest/api/tray">
full API documentation
</a>
in your browser.
</p>
</div>
<div>
<div>
<h2>ProTip</h2>
<strong>Tray support in Linux.</strong>
<p>
On Linux distributions that only have app indicator support, users
will need to install <code>libappindicator1</code> to make the
tray icon work. See the
<a href="https://www.electronjs.org/docs/latest/api/tray">
full API documentation
</a>
for more details about using Tray on Linux.
</p>
</div>
</div>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./renderer.js");
</script>
</body>
</html>

View File

@@ -0,0 +1,18 @@
const { app, Tray, Menu, nativeImage } = require('electron/main')
let tray
app.whenReady().then(() => {
const icon = nativeImage.createFromDataURL('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAVlpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KTMInWQAACsZJREFUWAmtWFlsXFcZ/u82++Jt7IyT2Em6ZFHTpAtWIzspEgjEUhA8VNAiIYEQUvuABBIUwUMkQIVKPCIoEiABLShISEBbhFJwIGRpIKRpbNeJ7bh2HHvssR3PPnPnLnzfmRlju6EQqUc+c++c8y/fv54z1uQOh+/7Glh0TD59TE/TND7lnfa4/64OKsM071QoeZpA/y9WWvk/B4XCC06TUC+Xyw8HTXNQ1+Ww6PpOrMebewXxvBueJ6/XHOdMJBL5J9Y97m2R0SS/wweE6JxkGx5dilWr1S/7dXsEa2o4+LyFmcFcaL5zbX3Y9gh5hpeWYpSB9XV5/H678V89BGYDXnHJlCsWn4gHrGc1K9CXxferOdvPOOKUfF8cH7nUyCtklQZXih/VNNlmirk3GdBSoIcRswW7/vVkLPYi5W2Uze8bh7J+4wLfh4dViFx5/nmrUi7/MhGNvrCkBfpeWqnW/7BUdadqntQ8zwr6vhUV34xpYnDynWvcmwQNaclDXsqgLMqkocPDw7fNx7d5qIX+/PmJxKGD6VdDkeh7ztyqOFfrokGCEWiiZ1mp0uITnuKAosaT7+pNxMYTyefutcQfbA+b1XLpH5fnF97/yD335Fu6mqTqsclDINBVmI4fDxw80KPAvJSt1MZtMcLiGxYUu83p4UkgnJZlqcl3LAj3WnTkIS9lUBYNPJjueVWgg7qocyOgliFqjZsg8gq5tRdiieQTf1gq15Y8CUbRZtyWOzZwc8lEqS3PTCtgqd13ieO68BQ2uNl64tXAewktrFuX2mPdkWAxn3sxnmx7sqUTJGqso8MGS9tbXFz8DMH8bblUX3T9QARVi8RV8qljfcJy0zRlaf6mzHEuzEtmekqCoZB4rqp0OmudHtUnlEWZlE0d1EWd1N3EozourcO65pw4eTIZQTW9VazJtbqvw9XwKVFQMsKDBuNhtp4uvGGFI+IDgKnpMjYyIis3ZsQMBIR7pONsIaMsyqRs6ohY1rPUSd3EQFDqo+kdZ3Fh4aupbdu+99uFQr2A1CBs4uEAjZjIFUMHi4dVxMXzCdCXQj4vBrwVCofl0ulTcv/DAxJJJBUPc8mpoyI2JDw7bFyT+ifTcSubyXytJ51+roWBxwG9Q73WWjZ7eSUU3//nXM0NI+x0PBGrTSgsLS9JFuFxHFrvSqIrJV279gi6tjiVspTza3JjZhY+0CQZj0mlWJSeHTslCro6eFqymCcVVN77kkGjs1p4sy2VOoSlOrFwT+XR+PjkgGaZ+ycKVbRTYUdVrmaImCvzk1dlFCEJdHRJ284+ie/ol0h7p7jFvExcvCCXzp2Rqem3pAMAiqWS6JGYhFI9Mjo6KjevXVUyKEuFHrKpY6JQ8TXT3D8+OTkAHBw6o6LCFo9ag3o4JtlCyTHEt5AxKvS6YUi5kJeZG3Py0NAxlLcJ9xti+K7Mjo/JfGZRuvv6Ze+9+yWEhDZAvzg3JyhX2d6/S7q6e+TimdOS7ElLKBZDwqvmj6rztayr1fVI1IoXi4PAcYZY1tPEEO1wEVlXgRFBDcmIXTqJsS+XyhKLJ5A/OpIVXXptWUYv/UvaenfIocEhMQ2EzHHErlXFCgQl3paU1eVl6QAY8sQTCSmVihKJx1V/ogvgIYF/pACdcMBhqONoHhF88/2d+bojyA6cRvje2IdFjoSjUSnBS8hgyS9lZOzKFdmPxO3o6gQIGzwuDn1dVSCtCKPy1pZXlATXqUsVYMLRmKo87vP4Y1ioqwCdCegmMYx3W/VPn8RrSDwwIMMbcEjkYo29JZVOy+ybI7K4eksODx1VSqvligpReSVLgySM/FI5h2q062jNyL3s7FtoAyGJIlx1225UmwJF6aJRJ3XzHXO9bWvsJa3jQFlBJkz6iuXdu32HzM7MyP0PPNgAU6ko4Qzp6b+flr8MD9OYJg9CwtzL5+T65ITs2bsP3mGxN/ZbBcOn0sk20gAkLQ+huXpFi8vkoY9AoyDjxTR1mbo6Ltt275HpN0dlNxQE40mVM8Ajjxx9VAGhAvQR1akZFCq799ADysMuQqOxh2FNmamEaz51ItGLfFD9+oUJoZkLowHoFA2mljUacqOMflKuVmHpfmnfvlMuvXZeStmMBIMhcWEdjgFJtrUjXI0KchAuAg0ilxLJNoRVBxhIBm0TjjKAuqjTqTs3CQZ6QUUMGFW7eiWMUg6w+yo8YMW7DqtqlZLkUDV2ISfd29KyDwk9MjYmMyOXxQIIKuShqo4VGFNBEgeDQYqVam5N5tEePFQgURIUBCsd1EWd1XrtDUUMLARD9bKaK5ytQ2Gb75g8WMiEP6VkfnZGevv6UF1vSBW5E0PFDAweFRvlfun8WVmamhDNrkmweQ0pwaPt6M4m8mgKTTFXqcrV0ZH1FKBg6qAu6qTuJiCV1Cp2Q0NDr9Uq5Ym+oMEDlSewsoRwrVBEaij7AJ4s7zrOpumxEdm15y6558GHJVe1Zezy6zJx6aJkpq5JFB4z6zVZmBiX1VWUP0IY4CFMYcpQdZ3xqIs6oftCE5DHKwd0q/tzOV8svdDb3nk8VnG9qmgQC0ZURz8Ur91alXgSByZ6ES9kZZTr/PR16UOCh+7dq0CWyyXJ4xqCQ0nKt9YQSlPue2gAeYZzD7yNLk0wmqAreb2WYSxAJ8Dget64wxtEBlDaqVOn/K5dB67t6+t5MhoMJuc8w8UPKiQ9CQR9JK5czhZAQxPt7TKF3OiAIisUViAD2Lg5d0P2HDgoKeRaW0enyqVwBJcO5fFG5dqa7h406qaeX8384uTZL5w9+UqxhYHFp0YLIYA9ddfu3T+4UJF6Rg+YAc9D0+RoIGP1ULhpWspr10evyK7+ftWTrk9PS/++A9KZSm26cih2mMOErem6n/ZsZwA2TM/MPHXs2LEftnSTbh0Q36mIIbx44cLvOnu3f+xUwbWLmoHTCUlF6g2jBQo/GnFrnGNqSHdvr+rIKGMW1KahwEBdzHft98aNwMr8zd8/NDDwccihc0hLi3GubRjY0Bm6H19fPvnZI4c/fHd7PJ2peXYZ+WQ26JufZELjQ6lbAQtnWre0d3apY8TFIdtAo+Qri6mupsB49lBMC+QXF0YefObZT8j0eKWlswVjEyCCOXHihPGb575VCvVuf3lvetsH9rXF0rla3cnhpoIGjgsUPhR3I4TMKYJQV1Z6WO02aEjHa5mNe3OPW3OPRHVrbXFh9Ocvv/KR1372owx1Pf3005uc35Ddgtd8rsf06IdS5777zZ+mUqmPzjm6TPpmvayZOq4LyATeCzkanmiy4qEuC/yXiO8CSMRzvLs1x9phepLNZl868sy3Pyen/5hd1/EfRvWmuvSWNeaRS/RkPDI4+NjE1NSXEoXlpaNB1zqo20abi59/vu/UfM2pie7WUDVq8l3wTwnskeZ+zTbIQ17KoCzKpGzq2KqX32/roRbh8ePHdUzl0s9/5Rv9n/7go19MxCKfCkZiu3V06wrO5gocxL7Dgd/IEobEMH6rejg+auXidL5Y/vWv/vTX53/y/e/MkGajTH7fOt4RUJOY1df4RdtY6ICFRzqTySOhUOA+3Ai3o31H1ZbnlXBruFmt2iMrudy5xx9//BzWV7nXDBGN2xpjbt/5oGUEdhtO3iD47xZOvm8a5CHvpsV38wsUaMwBWsz3rbK5xr0mzdv2t9Jv/f5vhsF4J+Q63IUAAAAASUVORK5CYII=')
tray = new Tray(icon)
const contextMenu = Menu.buildFromTemplate([
{ label: 'Item1', type: 'radio' },
{ label: 'Item2', type: 'radio' },
{ label: 'Item3', type: 'radio', checked: true },
{ label: 'Item4', type: 'radio' }
])
tray.setToolTip('This is my application.')
tray.setContextMenu(contextMenu)
})

View File

@@ -1,208 +0,0 @@
---
title: Application Menu
description: Customize the main application menu for your Electron app
slug: application-menu
hide_title: true
---
# Application Menu
Each Electron app has a single top-level application menu.
* On macOS, this menu is shown in the system [menu bar](https://support.apple.com/en-ca/guide/mac-help/mchlp1446/mac).
* On Windows and Linux, this menu is shown at the top of each [BaseWindow](../api/base-window.md).
## Building application menus
The application menu can be set by passing a [Menu](../api/menu.md) instance into the
[`Menu.setApplicationMenu`](../api/menu.md#menusetapplicationmenumenu) static function.
When building an application menu in Electron, each top-level array menu item **must be a submenu**.
Electron will set a default menu for your app if this API is never called. Below is an example of
that default menu being created manually using shorthand [`MenuItem` roles](./menus.md#roles).
```js title='Manually creating the default menu' @ts-expect-error=[107]
const { shell } = require('electron/common')
const { app, Menu } = require('electron/main')
const isMac = process.platform === 'darwin'
const template = [
// { role: 'appMenu' }
...(isMac
? [{
label: app.name,
submenu: [
{ role: 'about' },
{ type: 'separator' },
{ role: 'services' },
{ type: 'separator' },
{ role: 'hide' },
{ role: 'hideOthers' },
{ role: 'unhide' },
{ type: 'separator' },
{ role: 'quit' }
]
}]
: []),
// { role: 'fileMenu' }
{
label: 'File',
submenu: [
isMac ? { role: 'close' } : { role: 'quit' }
]
},
// { role: 'editMenu' }
{
label: 'Edit',
submenu: [
{ role: 'undo' },
{ role: 'redo' },
{ type: 'separator' },
{ role: 'cut' },
{ role: 'copy' },
{ role: 'paste' },
...(isMac
? [
{ role: 'pasteAndMatchStyle' },
{ role: 'delete' },
{ role: 'selectAll' },
{ type: 'separator' },
{
label: 'Speech',
submenu: [
{ role: 'startSpeaking' },
{ role: 'stopSpeaking' }
]
}
]
: [
{ role: 'delete' },
{ type: 'separator' },
{ role: 'selectAll' }
])
]
},
// { role: 'viewMenu' }
{
label: 'View',
submenu: [
{ role: 'reload' },
{ role: 'forceReload' },
{ role: 'toggleDevTools' },
{ type: 'separator' },
{ role: 'resetZoom' },
{ role: 'zoomIn' },
{ role: 'zoomOut' },
{ type: 'separator' },
{ role: 'togglefullscreen' }
]
},
// { role: 'windowMenu' }
{
label: 'Window',
submenu: [
{ role: 'minimize' },
{ role: 'zoom' },
...(isMac
? [
{ type: 'separator' },
{ role: 'front' },
{ type: 'separator' },
{ role: 'window' }
]
: [
{ role: 'close' }
])
]
},
{
role: 'help',
submenu: [
{
label: 'Learn More',
click: async () => {
const { shell } = require('electron')
await shell.openExternal('https://electronjs.org')
}
}
]
}
]
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
```
> [!IMPORTANT]
> On macOS, the first submenu of the application menu will **always** have your application's name
> as its label. In general, you can populate this submenu by conditionally adding a menu item with
> the `appMenu` role.
> [!TIP]
> For additional descriptions of available roles, see the [`MenuItem` roles](./menus.md#roles)
> section of the general Menus guide.
### Using standard OS menu roles
Defining each submenu explicitly can get very verbose. If you want to re-use default submenus
in your app, you can use various submenu-related roles provided by Electron.
```js title='Using default roles for each submenu' @ts-expect-error=[26]
const { shell } = require('electron/common')
const { app, Menu } = require('electron/main')
const template = [
...(process.platform === 'darwin'
? [{ role: 'appMenu' }]
: []),
{ role: 'fileMenu' },
{ role: 'editMenu' },
{ role: 'viewMenu' },
{ role: 'windowMenu' },
{
role: 'help',
submenu: [
{
label: 'Learn More',
click: async () => {
const { shell } = require('electron')
await shell.openExternal('https://electronjs.org')
}
}
]
}
]
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
```
> [!NOTE]
> On macOS, the `help` role defines a top-level Help submenu that has a search bar for
> other menu items. It requires items to be added to its `submenu` to function.
## Setting window-specific application menus _Linux_ _Windows_
Since the root application menu exists on each `BaseWindow` on Windows and Linux, you can override
it with a window-specific `Menu` instance via the [`win.setMenu`](../api/browser-window.md#winsetmenumenu-linux-windows) method.
```js title='Override a window's menu'
const { BrowserWindow, Menu } = require('electron/main')
const win = new BrowserWindow()
const menu = Menu.buildFromTemplate([
{
label: 'my custom menu',
submenu: [
{ role: 'copy' },
{ role: 'paste' }
]
}
])
win.setMenu(menu)
```
> [!TIP]
> You can remove a specific window's application menu by calling the
> [`win.removeMenu`](../api/base-window.md#winremovemenu-linux-windows) API.

View File

@@ -74,46 +74,22 @@ describe('keyboard input', () => {
Furthermore, WebdriverIO allows you to access Electron APIs to get static information about your application:
```js @ts-nocheck
import { browser, $, expect } from '@wdio/globals'
import { browser } from '@wdio/globals'
describe('when the make smaller button is clicked', () => {
it('should decrease the window height and width by 10 pixels', async () => {
const boundsBefore = await browser.electron.browserWindow('getBounds')
expect(boundsBefore.width).toEqual(210)
expect(boundsBefore.height).toEqual(310)
await $('.make-smaller').click()
const boundsAfter = await browser.electron.browserWindow('getBounds')
expect(boundsAfter.width).toEqual(200)
expect(boundsAfter.height).toEqual(300)
})
})
```
or to retrieve other Electron process information:
```js @ts-nocheck
import fs from 'node:fs'
import path from 'node:path'
import { browser, expect } from '@wdio/globals'
const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), { encoding: 'utf-8' }))
const { name, version } = packageJson
describe('electron APIs', () => {
it('should retrieve app metadata through the electron API', async () => {
const appName = await browser.electron.app('getName')
expect(appName).toEqual(name)
const appVersion = await browser.electron.app('getVersion')
expect(appVersion).toEqual(version)
})
it('should pass args through to the launched application', async () => {
// custom args are set in the wdio.conf.js file as they need to be set before WDIO starts
const argv = await browser.electron.mainProcess('argv')
expect(argv).toContain('--foo')
expect(argv).toContain('--bar=baz')
describe('trigger message modal', async () => {
it('message modal can be triggered from a test', async () => {
await browser.electron.execute(
(electron, param1, param2, param3) => {
const appWindow = electron.BrowserWindow.getFocusedWindow()
electron.dialog.showMessageBox(appWindow, {
message: 'Hello World!',
detail: `${param1} + ${param2} + ${param3} = ${param1 + param2 + param3}`
})
},
1,
2,
3
)
})
})
```
@@ -206,7 +182,7 @@ npm install --save-dev @playwright/test
```
:::caution Dependencies
This tutorial was written with `@playwright/test@1.41.1`. Check out
This tutorial was written with `@playwright/test@1.52.0`. Check out
[Playwright's releases][playwright-releases] page to learn about
changes that might affect the code below.
:::
@@ -218,10 +194,10 @@ To point this API to your Electron app, you can pass the path to your main proce
entry point (here, it is `main.js`).
```js {5} @ts-nocheck
const { test, _electron: electron } = require('@playwright/test')
import { test, _electron as electron } from '@playwright/test'
test('launch app', async () => {
const electronApp = await electron.launch({ args: ['main.js'] })
const electronApp = await electron.launch({ args: ['.'] })
// close app
await electronApp.close()
})
@@ -231,10 +207,10 @@ After that, you will access to an instance of Playwright's `ElectronApp` class.
is a powerful class that has access to main process modules for example:
```js {5-10} @ts-nocheck
const { test, _electron: electron } = require('@playwright/test')
import { test, _electron as electron } from '@playwright/test'
test('get isPackaged', async () => {
const electronApp = await electron.launch({ args: ['main.js'] })
const electronApp = await electron.launch({ args: ['.'] })
const isPackaged = await electronApp.evaluate(async ({ app }) => {
// This runs in Electron's main process, parameter here is always
// the result of the require('electron') in the main app script.
@@ -250,10 +226,10 @@ It can also create individual [Page][playwright-page] objects from Electron Brow
For example, to grab the first BrowserWindow and save a screenshot:
```js {6-7} @ts-nocheck
const { test, _electron: electron } = require('@playwright/test')
import { test, _electron as electron } from '@playwright/test'
test('save screenshot', async () => {
const electronApp = await electron.launch({ args: ['main.js'] })
const electronApp = await electron.launch({ args: ['.'] })
const window = await electronApp.firstWindow()
await window.screenshot({ path: 'intro.png' })
// close app
@@ -265,7 +241,7 @@ Putting all this together using the Playwright test-runner, let's create a `exam
test file with a single test and assertion:
```js title='example.spec.js' @ts-nocheck
const { test, expect, _electron: electron } = require('@playwright/test')
import { test, expect, _electron as electron } from '@playwright/test'
test('example test', async () => {
const electronApp = await electron.launch({ args: ['.'] })

View File

@@ -1,69 +0,0 @@
---
title: Context Menu
description: Configure cross-platform native OS menus with the Menu API.
slug: context-menu
hide_title: true
---
# Context Menu
Context menus are pop-up menus that appear when right-clicking (or pressing a shortcut
such as <kbd>Shift</kbd> + <kbd>F10</kbd> on Windows) somewhere in an app's interface.
No context menu will appear by default in Electron. However, context menus can be created by using
the [`menu.popup`](../api/menu.md#menupopupoptions) function on an instance of the
[Menu](../api/menu.md) class. You will need to listen for specific context menu events and set up
the trigger for `menu.popup` manually.
There are two ways of listening for context menu events in Electron: either via the main process
through [webContents](../api/web-contents.md) or in the renderer process via the
[`contextmenu`](https://developer.mozilla.org/en-US/docs/Web/API/Element/contextmenu_event) web event.
## Using the `context-menu` event (main)
Whenever a right-click is detected within the bounds of a specific `WebContents` instance, a
[`context-menu`](../api/web-contents.md#event-context-menu) event is triggered. The `params` object
passed to the listener provides an extensive list of attributes to distinguish which type of element
is receiving the event.
For example, if you want to provide a context menu for links, check for the `linkURL` parameter.
If you want to check for editable elements such as `<textarea/>`, check for the `isEditable` parameter.
```fiddle docs/fiddles/menus/context-menu/web-contents
```
## Using the `contextmenu` event (renderer)
Alternatively, you can also listen to the [`contextmenu`](https://developer.mozilla.org/en-US/docs/Web/API/Element/contextmenu_event)
event available on DOM elements in the renderer process and call the `menu.popup` function via IPC.
> [!TIP]
> To learn more about IPC basics in Electron, see the [Inter-Process Communication](./ipc.md) guide.
```fiddle docs/fiddles/menus/context-menu/dom|focus=preload.js
```
## Additional macOS menu items (e.g. Writing Tools)
On macOS, the [Writing Tools](https://support.apple.com/en-ca/guide/mac-help/mchldcd6c260/15.0/mac/15.0),
[AutoFill](https://support.apple.com/en-mz/guide/safari/ibrwf71ba236/mac), and
[Services](https://support.apple.com/en-ca/guide/mac-help/mchlp1012/mac) menu items
are disabled by default for context menus in Electron. To enable these features, pass the
[WebFrameMain](../api/web-frame-main.md) associated to the target `webContents` to the `frame`
parameter in `menu.popup`.
```js title='Associating a frame to the context menu'
const { BrowserWindow, Menu } = require('electron/main')
const menu = Menu.buildFromTemplate([{ role: 'editMenu' }])
const win = new BrowserWindow()
win.webContents.on('context-menu', (_event, params) => {
// Whether the context is editable.
if (params.isEditable) {
menu.popup({
// highlight-next-line
frame: params.frame
})
}
})
```

View File

@@ -1,170 +1,127 @@
---
title: "Keyboard Shortcuts"
description: "Define accelerator strings for local and global keyboard shortcuts"
slug: keyboard-shortcuts
hide_title: false
---
# Keyboard Shortcuts
## Accelerators
## Overview
Accelerators are strings that can be used to represent keyboard shortcuts throughout your Electron.
These strings can contain multiple modifiers keys and a single key code joined by the `+` character.
This feature allows you to configure local and global keyboard shortcuts
for your Electron application.
> [!NOTE]
> Accelerators are **case-insensitive**.
## Example
### Available modifiers
### Local Shortcuts
* `Command` (or `Cmd` for short)
* `Control` (or `Ctrl` for short)
* `CommandOrControl` (or `CmdOrCtrl` for short)
* `Alt`
* `Option`
* `AltGr`
* `Shift`
* `Super` (or `Meta` as alias)
Local keyboard shortcuts are triggered only when the application is focused.
To configure a local keyboard shortcut, you need to specify an [`accelerator`][]
property when creating a [MenuItem][] within the [Menu][] module.
### Available key codes
Starting with a working application from the
[tutorial starter code][tutorial-starter-code], update the `main.js` to be:
* `0` to `9`
* `A` to `Z`
* `F1` to `F24`
* Various Punctuation: `)`, `!`, `@`, `#`, `$`, `%`, `^`, `&`, `*`, `(`, `:`, `;`, `:`, `+`, `=`, `<`, `,`, `_`, `-`, `>`, `.`, `?`, `/`, `~`, `` ` ``, `{`, `]`, `[`, `|`, `\`, `}`, `"`
* `Plus`
* `Space`
* `Tab`
* `Capslock`
* `Numlock`
* `Scrolllock`
* `Backspace`
* `Delete`
* `Insert`
* `Return` (or `Enter` as alias)
* `Up`, `Down`, `Left` and `Right`
* `Home` and `End`
* `PageUp` and `PageDown`
* `Escape` (or `Esc` for short)
* `VolumeUp`, `VolumeDown` and `VolumeMute`
* `MediaNextTrack`, `MediaPreviousTrack`, `MediaStop` and `MediaPlayPause`
* `PrintScreen`
* NumPad Keys
* `num0` - `num9`
* `numdec` - decimal key
* `numadd` - numpad `+` key
* `numsub` - numpad `-` key
* `nummult` - numpad `*` key
* `numdiv` - numpad `÷` key
```fiddle docs/fiddles/features/keyboard-shortcuts/local
const { app, BrowserWindow, Menu, MenuItem } = require('electron/main')
### Cross-platform modifiers
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
})
Many modifier accelerators map to different keys between operating systems.
| Modifier | macOS | Windows and Linux |
|------------------|-------------|----------------------|
|`CommandOrControl`| Command (⌘) | Control |
|`Command` | Command (⌘) | N/A |
|`Control` | Control (^) | Control |
|`Alt` | Option (⌥) | Alt |
|`Option` | Option (⌥) | N/A |
|`Super` (`Meta`) | Command (⌘) | Windows (⊞) |
> [!IMPORTANT]
>
> * On Linux and Windows, the `Command` modifier does not have any effect. In general, you should use
> the `CommandOrControl` modifier instead, which represents <kbd>⌘ Cmd</kbd> on macOS and <kbd>Ctrl</kbd>
> on Linux and Windows.
> * Use `Alt` instead of `Option`. The <kbd>⌥ Opt</kbd> key only exists on macOS, whereas the `Alt` will
> map to the appropriate modifier on all platforms.
#### Examples
Here are some examples of cross-platform Electron accelerators for common editing operations:
* Copy: `CommandOrControl+C`
* Paste: `CommandOrControl+V`
* Undo: `CommandOrControl+Z`
* Redo: `CommandOrControl+Shift+Z`
## Local shortcuts
**Local** keyboard shortcuts are triggered only when the application is focused. These shortcuts
map to specific menu items within the app's main [application menu](./application-menu.md).
To define a local keyboard shortcut, you need to configure the `accelerator` property when creating
a [MenuItem](../api/menu-item.md). Then, the `click` event associated to that menu item will trigger
upon using that accelerator.
```js title='Opening a dialog via accelerator (local)'
const { dialog, Menu, MenuItem } = require('electron/main')
const menu = new Menu()
// The first submenu needs to be the app menu on macOS
if (process.platform === 'darwin') {
const appMenu = new MenuItem({ role: 'appMenu' })
menu.append(appMenu)
win.loadFile('index.html')
}
// highlight-start
const submenu = Menu.buildFromTemplate([{
label: 'Open a Dialog',
click: () => dialog.showMessageBox({ message: 'Hello World!' }),
accelerator: 'CommandOrControl+Alt+R'
}])
menu.append(new MenuItem({ label: 'Custom Menu', submenu }))
// highlight-end
const menu = new Menu()
menu.append(new MenuItem({
label: 'Electron',
submenu: [{
role: 'help',
accelerator: process.platform === 'darwin' ? 'Alt+Cmd+I' : 'Alt+Shift+I',
click: () => { console.log('Electron rocks!') }
}]
}))
Menu.setApplicationMenu(menu)
```
In the above example, a native "Hello World" dialog will open when pressing <kbd>⌘ Cmd</kbd>+<kbd>⌥ Opt</kbd>+<kbd>R</kbd>
on macOS or <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>R</kbd> on other platforms.
app.whenReady().then(createWindow)
> [!TIP]
> Accelerators can work even when menu items are hidden. On macOS, this feature can be disabled by
> setting `acceleratorWorksWhenHidden: false` when building a `MenuItem`.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
> [!TIP]
> On Windows and Linux, the `registerAccelerator` property of the `MenuItem` can be set to `false`
> so that the accelerator is visible in the system menu but not enabled.
## Global shortcuts
**Global** keyboard shortcuts work even when your app is out of focus. To configure a global keyboard
shortcut, you can use the [`globalShortcut.register`](../api/global-shortcut.md#globalshortcutregisteraccelerator-callback)
function to specify shortcuts.
```js title='Opening a dialog via accelerator (global)'
const { dialog, globalShortcut } = require('electron/main')
globalShortcut.register('CommandOrControl+Alt+R', () => {
dialog.showMessageBox({ message: 'Hello World!' })
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
```
To later unregister a shortcut, you can use the [`globalShortcut.unregisterAccelerator`](../api/global-shortcut.md#globalshortcutunregisteraccelerator)
function.
> NOTE: In the code above, you can see that the accelerator differs based on the
user's operating system. For MacOS, it is `Alt+Cmd+I`, whereas for Linux and
Windows, it is `Alt+Shift+I`.
```js title='Opening a dialog via accelerator (global)'
const { globalShortcut } = require('electron/main')
After launching the Electron application, you should see the application menu
along with the local shortcut you just defined:
globalShortcut.unregister('CommandOrControl+Alt+R')
![Menu with a local shortcut](../images/local-shortcut.png)
If you click `Help` or press the defined accelerator and then open the terminal
that you ran your Electron application from, you will see the message that was
generated after triggering the `click` event: "Electron rocks!".
### Global Shortcuts
To configure a global keyboard shortcut, you need to use the [globalShortcut][]
module to detect keyboard events even when the application does not have
keyboard focus.
Starting with a working application from the
[tutorial starter code][tutorial-starter-code], update the `main.js` to be:
```fiddle docs/fiddles/features/keyboard-shortcuts/global
const { app, BrowserWindow, globalShortcut } = require('electron/main')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
globalShortcut.register('Alt+CommandOrControl+I', () => {
console.log('Electron loves global shortcuts!')
})
}).then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
```
> [!WARNING]
> On macOS, there's a long-standing bug with `globalShortcut` that prevents it from working with
> keyboard layouts other than QWERTY ([electron/electron#19747](https://github.com/electron/electron/issues/19747)).
> NOTE: In the code above, the `CommandOrControl` combination uses `Command`
on macOS and `Control` on Windows/Linux.
## Shortcuts within a window
After launching the Electron application, if you press the defined key
combination then open the terminal that you ran your Electron application from,
you will see that Electron loves global shortcuts!
### In the renderer process
### Shortcuts within a BrowserWindow
If you want to handle keyboard shortcuts within a [BaseWindow](../api/base-window.md), you can
listen for the [`keyup`](https://developer.mozilla.org/en-US/docs/Web/API/Element/keyup_event) and
[`keydown`](https://developer.mozilla.org/en-US/docs/Web/API/Element/keydown_event) DOM Events inside
the renderer process using the [addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) API.
#### Using web APIs
If you want to handle keyboard shortcuts within a [BrowserWindow][], you can
listen for the `keyup` and `keydown` [DOM events][dom-events] inside the
renderer process using the [addEventListener() API][addEventListener-api].
```fiddle docs/fiddles/features/keyboard-shortcuts/web-apis|focus=renderer.js
function handleKeyPress (event) {
@@ -184,14 +141,18 @@ window.addEventListener('keyup', handleKeyPress, true)
#### Intercepting events in the main process
The [`before-input-event`](../api/web-contents.md#event-before-input-event) event
is emitted before dispatching `keydown` and `keyup` events in the renderer process. It can
is emitted before dispatching `keydown` and `keyup` events in the page. It can
be used to catch and handle custom shortcuts that are not visible in the menu.
```js title='Intercepting the Ctrl+I event from the main process'
Starting with a working application from the
[tutorial starter code][tutorial-starter-code], update the `main.js` file with the
following lines:
```fiddle docs/fiddles/features/keyboard-shortcuts/interception-from-main
const { app, BrowserWindow } = require('electron/main')
app.whenReady().then(() => {
const win = new BrowserWindow()
const win = new BrowserWindow({ width: 800, height: 600 })
win.loadFile('index.html')
win.webContents.on('before-input-event', (event, input) => {
@@ -202,3 +163,49 @@ app.whenReady().then(() => {
})
})
```
After launching the Electron application, if you open the terminal that you ran
your Electron application from and press `Ctrl+I` key combination, you will
see that this key combination was successfully intercepted.
#### Using third-party libraries
If you don't want to do manual shortcut parsing, there are libraries that do
advanced key detection, such as [mousetrap][]. Below are examples of usage of the
`mousetrap` running in the Renderer process:
```js @ts-nocheck
Mousetrap.bind('4', () => { console.log('4') })
Mousetrap.bind('?', () => { console.log('show shortcuts!') })
Mousetrap.bind('esc', () => { console.log('escape') }, 'keyup')
// combinations
Mousetrap.bind('command+shift+k', () => { console.log('command shift k') })
// map multiple combinations to the same callback
Mousetrap.bind(['command+k', 'ctrl+k'], () => {
console.log('command k or control k')
// return false to prevent default behavior and stop event from bubbling
return false
})
// gmail style sequences
Mousetrap.bind('g i', () => { console.log('go to inbox') })
Mousetrap.bind('* a', () => { console.log('select all') })
// konami code!
Mousetrap.bind('up up down down left right left right b a enter', () => {
console.log('konami code')
})
```
[Menu]: ../api/menu.md
[MenuItem]: ../api/menu-item.md
[globalShortcut]: ../api/global-shortcut.md
[`accelerator`]: ../api/accelerator.md
[BrowserWindow]: ../api/browser-window.md
[mousetrap]: https://github.com/ccampbell/mousetrap
[dom-events]: https://developer.mozilla.org/en-US/docs/Web/Events
[addEventListener-api]: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
[tutorial-starter-code]: tutorial-2-first-app.md#final-starter-code

View File

@@ -1,73 +1,76 @@
---
title: Dock Menu
description: Configure your app's Dock presence on macOS.
title: Dock
description: Configure your application's Dock presence on macOS.
slug: macos-dock
hide_title: true
---
# Dock Menu
# Dock
On macOS, the [Dock](https://support.apple.com/en-ca/guide/mac-help/mh35859/mac) is an interface
element that displays open and frequently-used apps. While opened or pinned, each app has its own
icon in the Dock.
Electron has APIs to configure the app's icon in the macOS Dock. A macOS-only
API exists to create a custom dock menu, but Electron also uses the app dock
icon as the entry point for cross-platform features like
[recent documents][recent-documents] and [application progress][progress-bar].
> [!NOTE]
> On macOS, the Dock is the entry point for certain cross-platform features like
> [Recent Documents](./recent-documents.md) and [Application Progress](./progress-bar.md).
> Read those guides for more details.
The custom dock is commonly used to add shortcuts to tasks the user wouldn't
want to open the whole app window for.
## Dock API
**Dock menu of Terminal.app:**
All functionality for the Dock is exposed via the [Dock](../api/dock.md) class exposed via
[`app.dock`](../api/app.md#appdock-macos-readonly) property. There is a single `Dock` instance per
Electron application, and this property only exists on macOS.
![Dock Menu][dock-menu-image]
One of the main uses for your app's Dock icon is to expose additional app menus. The Dock menu is
triggered by right-clicking or <kbd>Ctrl</kbd>-clicking the app icon. By default, the app's Dock menu
will come with system-provided window management utilities, including the ability to show all windows,
hide the app, and switch betweeen different open windows.
To set your custom dock menu, you need to use the
[`app.dock.setMenu`](../api/dock.md#docksetmenumenu-macos) API,
which is only available on macOS.
To set an app-defined custom Dock menu, pass any [Menu](../api/menu.md) instance into the
[`dock.setMenu`](../api/dock.md#docksetmenumenu-macos) API.
> [!TIP]
> For best practices to make your Dock menu feel more native, see Apple's
> [Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/dock-menus)
> page on Dock menus.
## Attaching a context menu
```js title='Setting a Dock menu'
```fiddle docs/fiddles/features/macos-dock-menu
const { app, BrowserWindow, Menu } = require('electron/main')
// dock.setMenu only works after the 'ready' event is fired
app.whenReady().then(() => {
const dockMenu = Menu.buildFromTemplate([
{
label: 'New Window',
click: () => { const win = new BrowserWindow() }
}
// add more menu options to the array
])
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
})
// Dock is undefined on platforms outside of macOS
// highlight-next-line
win.loadFile('index.html')
}
const dockMenu = Menu.buildFromTemplate([
{
label: 'New Window',
click () { console.log('New Window') }
}, {
label: 'New Window with Settings',
submenu: [
{ label: 'Basic' },
{ label: 'Pro' }
]
},
{ label: 'New Command...' }
])
app.whenReady().then(() => {
app.dock?.setMenu(dockMenu)
}).then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
```
> [!NOTE]
> Unlike with regular [context menus](./context-menu.md), Dock context menus don't need to be
> manually instrumented using the `menu.popup` API. Instead, the Dock object handles click events
> for you.
After launching the Electron application, right click the application icon.
You should see the custom menu you just defined:
> [!TIP]
> To learn more about crafting menus in Electron, see the [Menus](./menus.md#building-menus) guide.
![macOS dock menu](../images/macos-dock-menu.png)
## Runnable Fiddle demo
Below is a runnable example of how you can use the Dock menu to create and close windows in your
Electron app.
```fiddle docs/fiddles/menus/dock-menu
```
[dock-menu-image]: https://cloud.githubusercontent.com/assets/639601/5069962/6032658a-6e9c-11e4-9953-aa84006bdfff.png
[recent-documents]: ./recent-documents.md
[progress-bar]: ./progress-bar.md

View File

@@ -1,348 +0,0 @@
---
title: Menus
description: Configure cross-platform native OS menus with the Menu API.
slug: menus
hide_title: true
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import DocCardList from '@theme/DocCardList';
# Menus
Electron's [Menu](../api/menu.md) class provides a standardized way to create cross-platform native
menus throughout your application.
## Available menus in Electron
The same menu API is used for multiple use cases:
* The **application menu** is the top-level menu for your application. Each app only has a single
application menu at a time.
* **Context menus** are triggered by the user when right-clicking on a portion of your app's
interface.
* The **tray menu** is a special context menu triggered when right-clicking on your app's [Tray](../api/tray.md)
instance.
* On macOS, the **dock menu** is a special context menu triggered when right-clicking on your app's
icon in the system [Dock](https://support.apple.com/en-ca/guide/mac-help/mh35859/mac).
To learn more about the various kinds of native menus you can create and how to specify keyboard
shortcuts, see the individual guides in this section:
<DocCardList />
## Building menus
Each `Menu` instance is composed of an array of [MenuItem](../api/menu-item.md) objects accessible via
the `menu.items` instance property. Menus can be nested by setting the `item.submenu` property to
another menu.
There are two ways to build a menu: either by directly calling [`menu.append`](../api/menu.md#menuappendmenuitem)
or by using the static [`Menu.buildFromTemplate`](../api/menu.md#menubuildfromtemplatetemplate)
helper function.
The helper function reduces boilerplate by allowing you to pass a collection of `MenuItem`
constructor options (or instantiated `MenuItem` instances) in a single array rather than having to
append each item in a separate function call.
Below is an example of a minimal application menu:
<Tabs>
<TabItem value="constructor" label="Constructor">
```js title='menu.js'
const submenu = new Menu()
submenu.append(new MenuItem({ label: 'Hello' }))
submenu.append(new MenuItem({ type: 'separator' }))
submenu.append(new MenuItem({ label: 'Electron', type: 'checkbox', checked: true }))
const menu = new Menu()
menu.append(new MenuItem({ label: 'Menu', submenu }))
Menu.setApplicationMenu(menu)
```
</TabItem>
<TabItem value="template" label="Template Helper">
```js title='menu.js'
const menu = Menu.buildFromTemplate([{
label: 'Menu',
submenu: [
{ label: 'Hello' },
{ type: 'separator' },
{ label: 'Electron', type: 'checkbox', checked: true }
]
}])
Menu.setApplicationMenu(menu)
```
</TabItem>
</Tabs>
> [!IMPORTANT]
> All menu items (except for the `separator` type) must have a label. Labels can either be manually
> defined using the `label` property or inherited from the item's `role`.
### Types
A menu item's type grants it a particular appearance and functionality. Some types are
automatically assigned based on other constructor options:
* By default, menu items have the `normal` type.
* Menu items that contain the `submenu` property will be assigned the `submenu` type.
Other available types, when specified, give special additional properties to the menu item:
* `checkbox` - toggles the `checked` property whenever the menu item is clicked
* `radio` - toggles the `checked` property and turns off that property for all adjacent `radio` items
* `palette` - creates a [Palette](https://developer.apple.com/documentation/appkit/nsmenu/presentationstyle-swift.enum/palette)
submenu, which aligns items horizontally (available on macOS 14 and above)
* `header` - creates a section header, which can convey groupings with labels (available on macOS 14 and above)
> [!TIP]
> Adjacent `radio` items are at the same level of submenu and not divided by a separator.
>
> ```js
> [
> { type: 'radio', label: 'Adjacent 1' },
> { type: 'radio', label: 'Adjacent 2' },
> { type: 'separator' },
> { type: 'radio', label: 'Non-adjacent' } // unaffected by the others
> ]
> ```
### Roles
Roles give `normal` type menu items predefined behaviors.
We recommend specifying the `role` attribute for any menu item that matches a standard role
rather than trying to manually implement the behavior in a `click` function.
The built-in `role` behavior will give the best native experience.
The `label` and `accelerator` values are optional when using a `role` and will
default to appropriate values for each platform.
> [!TIP]
> Role strings are **case-insensitive**. For example, `toggleDevTools`, `toggledevtools`, and
> `TOGGLEDEVTOOLS` are all equivalent roles when defining menu items.
#### Edit roles
* `undo`
* `redo`
* `cut`
* `copy`
* `paste`
* `pasteAndMatchStyle`
* `selectAll`
* `delete`
#### Window roles
* `about` - Trigger a native about panel (custom message box on Window, which does not provide its own).
* `minimize` - Minimize current window.
* `close` - Close current window.
* `quit` - Quit the application.
* `reload` - Reload the current window.
* `forceReload` - Reload the current window ignoring the cache.
* `toggleDevTools` - Toggle developer tools in the current window.
* `togglefullscreen` - Toggle full screen mode on the current window.
* `resetZoom` - Reset the focused page's zoom level to the original size.
* `zoomIn` - Zoom in the focused page by 10%.
* `zoomOut` - Zoom out the focused page by 10%.
* `toggleSpellChecker` - Enable/disable built-in spellchecker.
#### Default menu roles
* `fileMenu` - The submenu is a "File" menu (Close / Quit)
* `editMenu` - The submenu is an "Edit" menu (Undo, Copy, etc.)
* `viewMenu` - The submenu is a "View" menu (Reload, Toggle Developer Tools, etc.)
* `windowMenu` - The submenu is a "Window" menu (Minimize, Zoom, etc.)
#### macOS-only roles
macOS has a number of platform-specific menu roles available. Many of these map to underlying
[AppKit](https://developer.apple.com/documentation/appkit) APIs.
##### App management roles
* `hide` - Map to the [`hide`](https://developer.apple.com/documentation/appkit/nsapplication/hide(_:)) action.
* `hideOthers` - Map to the [`hideOtherApplications`](https://developer.apple.com/documentation/appkit/nsapplication/hideotherapplications(_:)) action.
* `unhide` - Map to the [`unhideAllApplications`](https://developer.apple.com/documentation/appkit/nsapplication/unhideallapplications(_:)) action.
* `front` - Map to the [`arrangeInFront`](https://developer.apple.com/documentation/appkit/nsapplication/arrangeinfront(_:)) action.
* `zoom` - Map to the [`performZoom`](https://developer.apple.com/documentation/appkit/nswindow/performzoom(_:)) action.
##### Edit roles
* `showSubstitutions` - Map to the [`orderFrontSubstitutionsPanel`](https://developer.apple.com/documentation/appkit/nstextview/orderfrontsubstitutionspanel(_:)) action.
* `toggleSmartQuotes` - Map to the [`toggleAutomaticQuoteSubstitution`](https://developer.apple.com/documentation/appkit/nstextview/toggleautomaticquotesubstitution(_:)) action.
* `toggleSmartDashes` - Map to the [`toggleAutomaticDashSubstitution`](https://developer.apple.com/documentation/appkit/nstextview/toggleautomaticdashsubstitution(_:)) action.
* `toggleTextReplacement` - Map to the [`toggleAutomaticTextReplacement`](https://developer.apple.com/documentation/appkit/nstextview/toggleautomatictextreplacement(_:)) action.
##### Speech roles
* `startSpeaking` - Map to the [`startSpeaking`](https://developer.apple.com/documentation/appkit/nstextview/startspeaking(_:)) action.
* `stopSpeaking` - Map to the [`stopSpeaking`](https://developer.apple.com/documentation/appkit/nstextview/stopspeaking(_:)) action.
##### Native tab roles
* `toggleTabBar` - Map to the [`toggleTabBar`](https://developer.apple.com/documentation/appkit/nswindow/toggletabbar(_:)) action.
* `selectNextTab` - Map to the [`selectNextTab`](https://developer.apple.com/documentation/appkit/nswindow/selectnexttab(_:)) action.
* `selectPreviousTab` - Map to the [`selectPreviousTab`](https://developer.apple.com/documentation/appkit/nswindow/selectprevioustab(_:)) action.
<!-- * `showAllTabs` - Map to the `showAllTabs` action. -->
* `mergeAllWindows` - Map to the [`mergeAllWindows`](https://developer.apple.com/documentation/appkit/nswindow/mergeallwindows(_:)) action.
* `moveTabToNewWindow` - Map to the [`moveTabToNewWindow`](https://developer.apple.com/documentation/appkit/nswindow/movetabtonewwindow(_:)) action.
##### Default menu roles
* `appMenu` - Whole default "App" menu (About, Services, etc.)
* `services` - The submenu is a ["Services"](https://developer.apple.com/documentation/appkit/nsapplication/1428608-servicesmenu?language=objc) menu.
* `window` - The submenu is a "Window" menu.
* `help` - The submenu is a "Help" menu.
##### Other menu roles
* `recentDocuments` - The submenu is an "Open Recent" menu.
* `clearRecentDocuments` - Map to the [`clearRecentDocuments`](https://developer.apple.com/documentation/appkit/nsdocumentcontroller/clearrecentdocuments(_:)) action.
* `shareMenu` - The submenu is [share menu][ShareMenu]. The `sharingItem` property must also be set to indicate the item to share.
> [!IMPORTANT]
> When specifying a `role` on macOS, `label` and `accelerator` are the only
> options that will affect the menu item. All other options will be ignored.
### Accelerators
The `accelerator` property allows you to define accelerator strings to map menu items to keyboard
shortcuts. For more details, see the [Keyboard Shortcuts](./keyboard-shortcuts.md) guide.
## Advanced configuration
### Programmatic item positioning
You can make use of the `before`, `after`, `beforeGroupContaining`, `afterGroupContaining` and `id` attributes
to control how menu items will be placed when building a menu with `Menu.buildFromTemplate`.
* `before` - Inserts this item before the item with the specified id. If the
referenced item doesn't exist, the item will be inserted at the end of
the menu. Also implies that the menu item in question should be placed in the same “group” as the item.
* `after` - Inserts this item after the item with the specified id. If the
referenced item doesn't exist, the item will be inserted at the end of
the menu. Also implies that the menu item in question should be placed in the same “group” as the item.
* `beforeGroupContaining` - Provides a means for a single context menu to declare
the placement of their containing group before the containing group of the item with the specified id.
* `afterGroupContaining` - Provides a means for a single context menu to declare
the placement of their containing group after the containing group of the item with the specified id.
By default, items will be inserted in the order they exist in the template unless one of the specified
positioning keywords is used.
#### Examples
Template:
```js
[
{ id: '1', label: 'one' },
{ id: '2', label: 'two' },
{ id: '3', label: 'three' },
{ id: '4', label: 'four' }
]
```
Menu:
```plaintext
- one
- two
- three
- four
```
Template:
```js
[
{ id: '1', label: 'one' },
{ type: 'separator' },
{ id: '3', label: 'three', beforeGroupContaining: ['1'] },
{ id: '4', label: 'four', afterGroupContaining: ['2'] },
{ type: 'separator' },
{ id: '2', label: 'two' }
]
```
Menu:
```plaintext
- three
- four
- ---
- one
- ---
- two
```
Template:
```js
[
{ id: '1', label: 'one', after: ['3'] },
{ id: '2', label: 'two', before: ['1'] },
{ id: '3', label: 'three' }
]
```
Menu:
```plaintext
- ---
- three
- two
- one
```
### Icons
To add visual aid to your menus, you can use the `icon` property to assign images to individual
`MenuItem` instances.
```js title='Adding a little green circle to a menu item'
const { nativeImage } = require('electron/common')
const { MenuItem } = require('electron/main')
// highlight-next-line
const green = nativeImage.createFromDataURL('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACOSURBVHgBpZLRDYAgEEOrEzgCozCCGzkCbKArOIlugJvgoRAUNcLRpvGH19TkgFQWkqIohhK8UEaKwKcsOg/+WR1vX+AlA74u6q4FqgCOSzwsGHCwbKliAF89Cv89tWmOT4VaVMoVbOBrdQUz+FrD6XItzh4LzYB1HFJ9yrEkZ4l+wvcid9pTssh4UKbPd+4vED2Nd54iAAAAAElFTkSuQmCC')
const item = new MenuItem({
label: 'Green Circle',
// highlight-next-line
icon: green
})
```
### Sublabels _macOS_
You can add sublabels (also known as [subtitles](https://developer.apple.com/documentation/appkit/nsmenuitem/subtitle))
to menu items using the `sublabel` option on macOS 14.4 and above.
```js title='Adding descriptions via sublabel'
const { MenuItem } = require('electron/main')
const item = new MenuItem({
label: 'Log Message',
// highlight-next-line
sublabel: 'This will use the console.log utility',
click: () => { console.log('Logging via menu...') }
})
```
### Tooltips _macOS_
Tooltips are informational indicators that appear when you hover over a menu item. You can set menu
item tooltips on macOS using the `toolTip` option.
```js title='Adding additional information via tooltip'
const { MenuItem } = require('electron/main')
const item = new MenuItem({
label: 'Hover Over Me',
// highlight-next-line
toolTip: 'This is additional info that appears on hover'
})
```

View File

@@ -1,86 +1,83 @@
---
title: Tray Menu
description: Create a Tray icon with its own menu in the system's notification area.
title: Tray
description: This guide will take you through the process of creating
a Tray icon with its own context menu to the system's notification area.
slug: tray
hide_title: true
---
# Tray Menu
# Tray
This guide will take you through the process of creating an icon with its own context menu to the
system tray.
## Overview
* On macOS, the icon will be located on the top right corner of your screen in the
[menu bar extras](https://developer.apple.com/design/human-interface-guidelines/the-menu-bar#Menu-bar-extras)
area.
* On Windows, the icon will be located in the [notification area](https://learn.microsoft.com/en-us/windows/win32/shell/notification-area)
at the end of the taskbar.
* On Linux, the location of the Tray will differ based on your desktop environment.
<!-- ✍ Update this section if you want to provide more details -->
## Creating a Tray icon
This guide will take you through the process of creating a
[Tray](../api/tray.md) icon with
its own context menu to the system's notification area.
The tray icon for your Electron app needs to be created programmatically with an instance of
the [Tray](../api/tray.md#new-trayimage-guid) class. The class constructor requires a single
instance of a [NativeImage](../api/native-image.md#class-nativeimage) or a path to a compatible icon
file.
On MacOS and Ubuntu, the Tray will be located on the top
right corner of your screen, adjacent to your battery and wifi icons.
On Windows, the Tray will usually be located in the bottom right corner.
> [!NOTE]
> File formats vary per operating system. For more details, see the
> [Platform Considerations](../api/tray.md#platform-considerations) section of the Tray API documentation.
## Example
## Minimizing to tray
### main.js
In order to keep the app and the system tray icon alive even when all windows are closed, you need to
have a listener for the [`window-all-closed`](../api/app.md#event-window-all-closed) event on the
`app` module. The base Electron templates generally listen for this event but quit the app on
Windows and Linux to emulate standard OS behavior.
First we must import `app`, `Tray`, `Menu`, `nativeImage` from `electron`.
```js title='Setting up minimize to tray'
app.on('window-all-closed', () => {
// having this listener active will prevent the app from quitting.
})
```js
const { app, Tray, Menu, nativeImage } = require('electron')
```
## Attaching a context menu
Next we will create our Tray. To do this, we will use a
[`NativeImage`](../api/native-image.md) icon,
which can be created through any one of these
[methods](../api/native-image.md#methods).
Note that we wrap our Tray creation code within an
[`app.whenReady`](../api/app.md#appwhenready)
as we will need to wait for our electron app to finish initializing.
You can attach a context menu to the Tray object by passing in a [Menu](../api/menu.md) instance
into the [`tray.setContextMenu`](../api/tray.md#traysetcontextmenumenu) function.
> [!NOTE]
> Unlike with regular [context menus](./context-menu.md), Tray context menus don't need to be
> manually instrumented using the `menu.popup` API. Instead, the Tray object handles click events
> for you (although various click-related events exist on the API for advanced use cases).
```js title='Creating a Tray menu that can quit the app'
const { nativeImage } = require('electron/common')
const { app, Tray, Menu } = require('electron/main')
// save a reference to the Tray object globally to avoid garbage collection
```js title='main.js'
let tray
// 16x16 red circle data URL
const icon = nativeImage.createFromDataURL('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACTSURBVHgBpZKBCYAgEEV/TeAIjuIIbdQIuUGt0CS1gW1iZ2jIVaTnhw+Cvs8/OYDJA4Y8kR3ZR2/kmazxJbpUEfQ/Dm/UG7wVwHkjlQdMFfDdJMFaACebnjJGyDWgcnZu1/lrCrl6NCoEHJBrDwEr5NrT6ko/UV8xdLAC2N49mlc5CylpYh8wCwqrvbBGLoKGvz8Bfq0QPWEUo/EAAAAASUVORK5CYII=')
// The Tray can only be instantiated after the 'ready' event is fired
app.whenReady().then(() => {
const icon = nativeImage.createFromPath('path/to/asset.png')
tray = new Tray(icon)
const contextMenu = Menu.buildFromTemplate([
{ role: 'quit' }
])
tray.setContextMenu(contextMenu)
// note: your contextMenu, Tooltip and Title code will go here!
})
```
> [!TIP]
> To learn more about crafting menus in Electron, see the [Menus](./menus.md#building-menus) guide.
Great! Now we can start attaching a context menu to our Tray, like so:
> [!WARNING]
> The `enabled` and `visibility` properties are not available for top-level menu items in the tray on macOS.
```js @ts-expect-error=[8]
const contextMenu = Menu.buildFromTemplate([
{ label: 'Item1', type: 'radio' },
{ label: 'Item2', type: 'radio' },
{ label: 'Item3', type: 'radio', checked: true },
{ label: 'Item4', type: 'radio' }
])
## Runnable Fiddle demo
Below is a runnable example of attaching various menu items to the Tray's context menu that help
control app state and interact with the Tray API itself.
```fiddle docs/fiddles/menus/tray-menu
tray.setContextMenu(contextMenu)
```
The code above will create 4 separate radio-type items in the context menu.
To read more about constructing native menus, click
[here](../api/menu.md#menubuildfromtemplatetemplate).
Finally, let's give our tray a tooltip and a title.
```js @ts-type={tray:Electron.Tray}
tray.setToolTip('This is my application')
tray.setTitle('This is my title')
```
## Conclusion
After you start your electron app, you should see the Tray residing
in either the top or bottom right of your screen, depending on your
operating system.
```fiddle docs/fiddles/native-ui/tray
```

View File

@@ -14,6 +14,7 @@ Windows, and Linux.
> supports composing many web views. `BaseWindow` can be used interchangeably with `BrowserWindow`
> in the examples of the documents in this section.
<!-- markdownlint-disable-next-line MD033 -->
<DocCardList />
[`BaseWindow`]: ../api/base-window.md

View File

@@ -1,6 +1,7 @@
# THIS FILE IS AUTO-GENERATED, PLEASE DO NOT EDIT BY HAND
auto_filenames = {
api_docs = [
"docs/api/accelerator.md",
"docs/api/app.md",
"docs/api/auto-updater.md",
"docs/api/base-window.md",

View File

@@ -80,7 +80,7 @@ function makeLoadURLOptions (params: Record<string, any>) {
}
// Create a new guest instance.
const createGuest = function (embedder: Electron.WebContents, embedderFrameToken: string, elementInstanceId: number, params: Record<string, any>) {
const createGuest = function (embedder: Electron.WebContents, embedderFrameId: number, elementInstanceId: number, params: Record<string, any>) {
const webPreferences = makeWebPreferences(embedder, params);
const event = {
sender: embedder,
@@ -198,7 +198,7 @@ const createGuest = function (embedder: Electron.WebContents, embedderFrameToken
watchEmbedder(embedder);
webViewManager.addGuest(guestInstanceId, embedder, guest, webPreferences);
guest.attachToIframe(embedder, embedderFrameToken);
guest.attachToIframe(embedder, embedderFrameId);
return guestInstanceId;
};
@@ -286,8 +286,8 @@ const handleMessageSync = function (channel: string, handler: (event: { sender:
ipcMainUtils.handleSync(channel, makeSafeHandler(channel, handler));
};
handleMessage(IPC_MESSAGES.GUEST_VIEW_MANAGER_CREATE_AND_ATTACH_GUEST, function (event, embedderFrameToken: string, elementInstanceId: number, params) {
return createGuest(event.sender, embedderFrameToken, elementInstanceId, params);
handleMessage(IPC_MESSAGES.GUEST_VIEW_MANAGER_CREATE_AND_ATTACH_GUEST, function (event, embedderFrameId: number, elementInstanceId: number, params) {
return createGuest(event.sender, embedderFrameId, elementInstanceId, params);
});
handleMessageSync(IPC_MESSAGES.GUEST_VIEW_MANAGER_DETACH_GUEST, function (event, guestInstanceId: number) {

View File

@@ -22,6 +22,7 @@ export const webViewEvents: Record<string, readonly string[]> = {
'-focus-change': ['focus'],
close: [],
'render-process-gone': ['details'],
'plugin-crashed': ['name', 'version'],
destroyed: [],
'page-title-updated': ['title', 'explicitSet'],
'page-favicon-updated': ['favicons'],

View File

@@ -23,12 +23,12 @@ export function createGuest (iframe: HTMLIFrameElement, elementInstanceId: numbe
throw new TypeError('Invalid embedder frame');
}
const embedderFrame = webFrame._findFrameByWindow(iframe.contentWindow!);
if (!embedderFrame) { // this error should not happen.
const embedderFrameId = webFrame.getWebFrameId(iframe.contentWindow!);
if (embedderFrameId < 0) { // this error should not happen.
throw new Error('Invalid embedder frame');
}
return ipcRendererInternal.invoke(IPC_MESSAGES.GUEST_VIEW_MANAGER_CREATE_AND_ATTACH_GUEST, embedderFrame.frameToken, elementInstanceId, params);
return ipcRendererInternal.invoke(IPC_MESSAGES.GUEST_VIEW_MANAGER_CREATE_AND_ATTACH_GUEST, embedderFrameId, elementInstanceId, params);
}
export function detachGuest (guestInstanceId: number) {

View File

@@ -18,6 +18,7 @@
"@types/semver": "^7.5.8",
"@types/stream-json": "^1.7.7",
"@types/temp": "^0.9.4",
"@types/webpack": "^5.28.5",
"@types/webpack-env": "^1.18.5",
"@typescript-eslint/eslint-plugin": "^8.32.1",
"@typescript-eslint/parser": "^8.7.0",
@@ -27,12 +28,13 @@
"dugite": "^2.7.1",
"eslint": "^8.57.1",
"eslint-config-standard": "^17.1.0",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-import": "^2.30.0",
"eslint-plugin-markdown": "^5.1.0",
"eslint-plugin-mocha": "^10.5.0",
"eslint-plugin-n": "^16.6.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^6.6.0",
"eslint-plugin-unicorn": "^55.0.0",
"events": "^3.2.0",
"folder-hash": "^2.1.1",
"got": "^11.8.5",

View File

@@ -20,7 +20,7 @@ index 2cdcbc346175eeee69402ecee7f169e61c655199..f7226fe711e4214b216ea2c5173a0212
case ssl_open_record_error:
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc
index 241d75770d9263f982ea0d4cd71c4af4f82b0d14..0f95e4371ff2ca0c0adc764ffc140565a27ea0bf 100644
index 4fe7ba0ca52f5cf5f10b41f0b8b0a94e641a74d0..470112636356e344b0760ac75f3ee22249a2d437 100644
--- a/ssl/ssl_lib.cc
+++ b/ssl/ssl_lib.cc
@@ -1204,7 +1204,7 @@ int SSL_get_error(const SSL *ssl, int ret_code) {
@@ -32,7 +32,7 @@ index 241d75770d9263f982ea0d4cd71c4af4f82b0d14..0f95e4371ff2ca0c0adc764ffc140565
return SSL_ERROR_ZERO_RETURN;
}
// An EOF was observed which violates the protocol, and the underlying
@@ -2565,13 +2565,7 @@ void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) {
@@ -2571,13 +2571,7 @@ void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) {
return CRYPTO_get_ex_data(&ctx->ex_data, idx);
}

View File

@@ -102,6 +102,7 @@ fix_use_delegated_generic_capturer_when_available.patch
expose_webblob_path_to_allow_embedders_to_get_file_paths.patch
fix_move_autopipsettingshelper_behind_branding_buildflag.patch
revert_remove_the_allowaggressivethrottlingwithwebsocket_feature.patch
fix_activate_background_material_on_windows.patch
feat_allow_passing_of_objecttemplate_to_objecttemplatebuilder.patch
chore_remove_check_is_test_on_script_injection_tracker.patch
fix_restore_original_resize_performance_on_macos.patch
@@ -134,7 +135,3 @@ refactor_patch_electron_permissiontypes_into_blink.patch
revert_views_remove_desktopwindowtreehostwin_window_enlargement.patch
build_partial_revert_mac_fullscreen_top_chrome_mouse_events.patch
revert_update_siso-chromium_image.patch
build_set_mac_sdk_minimum_to_10.patch
partitionalloc_use_fewer_vmas_by_default_on_linux_systems.patch
fix_add_macos_memory_query_fallback_to_avoid_crash.patch
fix_resolve_dynamic_background_material_update_issue_on_windows_11.patch

View File

@@ -10,7 +10,7 @@ Allows Electron to restore WER when ELECTRON_DEFAULT_ERROR_MODE is set.
This should be upstreamed.
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc
index b6403600631c97100c7356265b88ed32d9d7716b..9225d26c2eb46d4a70a1e08ce34e02c32c15ea92 100644
index 620a5f208328ba136ddeb406052797b95813da46..127552073fe61254ff89b649987255985e0959d5 100644
--- a/content/gpu/gpu_main.cc
+++ b/content/gpu/gpu_main.cc
@@ -267,6 +267,10 @@ int GpuMain(MainFunctionParams parameters) {
@@ -33,10 +33,10 @@ index b6403600631c97100c7356265b88ed32d9d7716b..9225d26c2eb46d4a70a1e08ce34e02c3
client->PostSandboxInitialized();
}
diff --git a/content/public/gpu/content_gpu_client.h b/content/public/gpu/content_gpu_client.h
index 47de52a1c9d34753ec27c33d976987cd2550cd27..bdc35a9d6fab02502715ed2bf27bd65990239bd6 100644
index c89b010e7ac78e2a7246ee54fe302cd6b9299710..46fd522fb2ac2793a3a073a4f833a4425dcee941 100644
--- a/content/public/gpu/content_gpu_client.h
+++ b/content/public/gpu/content_gpu_client.h
@@ -35,6 +35,10 @@ class CONTENT_EXPORT ContentGpuClient {
@@ -32,6 +32,10 @@ class CONTENT_EXPORT ContentGpuClient {
public:
virtual ~ContentGpuClient() {}

View File

@@ -10,10 +10,10 @@ 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 b08febf8bba8ceb94eb80d04d83931d1e219c5b7..60eedf298de4af314e2459933adda42a7e90e483 100644
index 65f4d645acae41e45b07443d88f169a9d4771041..0d17b88493bc4c15012c7ed3948127ec18053d78 100644
--- a/content/public/renderer/render_frame_observer.h
+++ b/content/public/renderer/render_frame_observer.h
@@ -140,6 +140,8 @@ class CONTENT_EXPORT RenderFrameObserver {
@@ -149,6 +149,8 @@ class CONTENT_EXPORT RenderFrameObserver
virtual void DidHandleOnloadEvents() {}
virtual void DidCreateScriptContext(v8::Local<v8::Context> context,
int32_t world_id) {}
@@ -23,10 +23,10 @@ index b08febf8bba8ceb94eb80d04d83931d1e219c5b7..60eedf298de4af314e2459933adda42a
int32_t world_id) {}
virtual void DidClearWindowObject() {}
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index b74623455d53d109a97e6c767f56a9beeb0e87e5..2f13ff0b2671c0851f31f527fe1f76b118bf03d2 100644
index 654088d4615a39ae691be12d289dc4bfe3952199..85b12548a9e2a690cc01662aa29ea21c40eaa82d 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -4666,6 +4666,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
@@ -4733,6 +4733,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
observer.DidCreateScriptContext(context, world_id);
}
@@ -40,10 +40,10 @@ index b74623455d53d109a97e6c767f56a9beeb0e87e5..2f13ff0b2671c0851f31f527fe1f76b1
int world_id) {
for (auto& observer : observers_)
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 79383765a3a0095b92355d6d5777be461c926447..e0b57c2b7aee0706b6b164ac555a3264236268e3 100644
index 9e6efd6ad45312e9ffa07915a942c076fb217aad..0b100dcdc6716fce788ccc1953e00d2271c080f8 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -604,6 +604,8 @@ class CONTENT_EXPORT RenderFrameImpl
@@ -626,6 +626,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;
@@ -110,7 +110,7 @@ index 327a013b77c09bd3c7b781d67d8d9ec64807fb5b..51ade9075a184597ed7580a5243ce5ad
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 c1f8fc071a4c3f3781fcc29e929714e2c85b02b5..35357334aeb090ad6bb0cf8215beadab3bc70371 100644
index fa9b3648d7daeb5aa5c588245f021da7294df2bd..c785039fd56c0a72dd9cf364013acc8fbbe5f986 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
@@ -82,6 +82,8 @@ class CORE_EXPORT LocalFrameClientImpl final : public LocalFrameClient {

View File

@@ -116,10 +116,10 @@ index f5d921fb5de6d5decc53815d959d91f8c7e8c5dc..3cca9aec9ccb02dbaf29298d89e5c862
// 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 2c7db5d15c6b844186a4a2715d8ce02b554cba9a..85a2d5c468107d51fe931ba3b8464517a2bbdddf 100644
index cdbb6b31e62017bf4b7cad9928a516dfe1ae62ba..353c093d9fc15913dec6301cfc654c1a3a3fbc10 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -2484,6 +2484,10 @@ void WebViewImpl::SetPageLifecycleStateInternal(
@@ -2489,6 +2489,10 @@ void WebViewImpl::SetPageLifecycleStateInternal(
TRACE_EVENT2("navigation", "WebViewImpl::SetPageLifecycleStateInternal",
"old_state", old_state, "new_state", new_state);
@@ -130,7 +130,7 @@ index 2c7db5d15c6b844186a4a2715d8ce02b554cba9a..85a2d5c468107d51fe931ba3b8464517
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 &&
@@ -3978,10 +3982,23 @@ PageScheduler* WebViewImpl::Scheduler() const {
@@ -3983,10 +3987,23 @@ PageScheduler* WebViewImpl::Scheduler() const {
return GetPage()->GetPageScheduler();
}

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 c207ad535db9310dcb473b7269ccc577e40448c2..bf7e7b89d3f30ac9ce6999e6d2a810fb94ba121a 100644
index 365577275f54cbe8dbbdcd2d7d5b1bdf0f68bdba..883f6aa72c8f1c4829f5d8455d12a238094fe354 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
@@ -148,6 +148,19 @@ bool StructTraits<blink::mojom::WebPreferencesDataView,
@@ -149,6 +149,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 c207ad535db9310dcb473b7269ccc577e40448c2..bf7e7b89d3f30ac9ce6999e6d2a810fb
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 f17fb9ec701d1a5ef3deb728f8e97d53331978db..d5563e79944827fa3a68dd621445899349295f59 100644
index a2ade031f073bfc94b7593e7925f9f47e9f330e4..c68e59a3c8ff5623f3ee72d9101a90effad84b7e 100644
--- a/third_party/blink/public/common/web_preferences/web_preferences.h
+++ b/third_party/blink/public/common/web_preferences/web_preferences.h
@@ -9,6 +9,7 @@
@@ -43,7 +43,7 @@ index f17fb9ec701d1a5ef3deb728f8e97d53331978db..d5563e79944827fa3a68dd6214458993
#include "build/build_config.h"
#include "net/nqe/effective_connection_type.h"
#include "third_party/blink/public/common/common_export.h"
@@ -453,6 +454,20 @@ struct BLINK_COMMON_EXPORT WebPreferences {
@@ -454,6 +455,20 @@ struct BLINK_COMMON_EXPORT WebPreferences {
// fingerprinting are enabled.
bool api_based_fingerprinting_interventions_enabled = false;
@@ -65,7 +65,7 @@ index f17fb9ec701d1a5ef3deb728f8e97d53331978db..d5563e79944827fa3a68dd6214458993
// 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 61451bfeb59780dba5d41650619d13f4639fb752..ff9a431ae3c7adf6d79912ab9edc41884a99dd26 100644
index e093a39ab999afb95d520df28d262cdc9de0c239..5edbccbc37a2019274b42060fbcc18301fab769d 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 @@
@@ -76,7 +76,7 @@ index 61451bfeb59780dba5d41650619d13f4639fb752..ff9a431ae3c7adf6d79912ab9edc4188
#include "mojo/public/cpp/bindings/struct_traits.h"
#include "net/nqe/effective_connection_type.h"
#include "third_party/blink/public/common/common_export.h"
@@ -434,6 +435,52 @@ struct BLINK_COMMON_EXPORT StructTraits<blink::mojom::WebPreferencesDataView,
@@ -438,6 +439,52 @@ struct BLINK_COMMON_EXPORT StructTraits<blink::mojom::WebPreferencesDataView,
return r.stylus_handwriting_enabled;
}
@@ -130,7 +130,7 @@ index 61451bfeb59780dba5d41650619d13f4639fb752..ff9a431ae3c7adf6d79912ab9edc4188
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 e0c02352054a112bef293aa9eaa2b18daa768048..82eff7fed067ab3cda80ca950756232b15d8d090 100644
index 13b0e0ed94ddda963877db39af0ef0fd0249a67e..a18abdf47cdcd60a08ac58484ce338f92ce89bea 100644
--- a/third_party/blink/public/mojom/webpreferences/web_preferences.mojom
+++ b/third_party/blink/public/mojom/webpreferences/web_preferences.mojom
@@ -8,9 +8,11 @@ import "third_party/blink/public/mojom/css/preferred_color_scheme.mojom";
@@ -145,7 +145,7 @@ index e0c02352054a112bef293aa9eaa2b18daa768048..82eff7fed067ab3cda80ca950756232b
enum PointerType {
kPointerNone = 1, // 1 << 0
kPointerFirstType = kPointerNone,
@@ -217,6 +219,19 @@ struct WebPreferences {
@@ -218,6 +220,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

@@ -49,7 +49,7 @@ index c9f34fa47702504ccdefb8d61c55f5eaae501085..26df03d777c9ea487cae37f3df91d1df
// 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 02f07b5cbabe54c4452c2e8e5dea73653320acd1..f74e7cdbaa4c77b84ed9ecba839874ed6c26c4e8 100644
index e981e1c930aaa50a57b467781beed3ad0227242d..eb492c266c9c4ee9d1a6ebde3e2eb9a12cfca0c1 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -738,10 +738,6 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {

View File

@@ -10,10 +10,10 @@ Needed for:
2) //electron/shell/common:web_contents_utility
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn
index c67d8bad398f754d7d99f8a39936608d64c8b818..addb4e76f72e2b1037c75be2387db5f048c100a8 100644
index a595a2dde93b7cd950e68e6f61983c3fcc845129..fa0ae0d23232775a30b82aeabd0711a8c5fb8556 100644
--- a/content/public/common/BUILD.gn
+++ b/content/public/common/BUILD.gn
@@ -379,6 +379,8 @@ mojom("interfaces") {
@@ -378,6 +378,8 @@ mojom("interfaces") {
"//content/common/*",
"//extensions/common:mojom",
"//extensions/common:mojom_blink",

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 61c3779e9fd11869fdf7b789e3b728fd03ed8fd0..f0638cdfe9cd75834c09e5361201d9c50dad74af 100644
index bbe8e5f2cf0d70121a649e0a4897e0643445c57c..3461b5daf6b80b7fe54d03b2e2ba8896780db973 100644
--- a/build/config/compiler/compiler.gni
+++ b/build/config/compiler/compiler.gni
@@ -88,7 +88,7 @@ declare_args() {
@@ -82,7 +82,7 @@ declare_args() {
# have the same LLVM revisions as us, making bitcode useless to them.
use_thin_lto =
is_cfi || (is_clang && is_official_build && chrome_pgo_phase != 1 &&

View File

@@ -33,10 +33,10 @@ index 58ab462a5bdb335a54a8f7d9f3d27e6f039c50cb..5e0da948970cbd6f526b927158111625
"//base",
"//build:branding_buildflags",
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 30c7fa8addf7f10919e3f185697dda0cdaed0d0e..2a0b917df579e6c5393a57b90bd540bbfb9e3db6 100644
index ab49fe9caf03364bb5f1d4dc2da9fe88c4e7bd66..8d2c79c1ef13e60ac6f4a9c9561e578c4b0e7f9d 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -4782,7 +4782,7 @@ static_library("browser") {
@@ -4783,7 +4783,7 @@ static_library("browser") {
[ "//chrome/browser/ui/webui/signin:profile_impl" ]
}
@@ -46,10 +46,10 @@ index 30c7fa8addf7f10919e3f185697dda0cdaed0d0e..2a0b917df579e6c5393a57b90bd540bb
# than here in :chrome_dll.
deps += [ "//chrome:packed_resources_integrity_header" ]
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 6e7ba06e1edfce3d0890013fa8fb1369899a297a..2ed7f27a1e194abcdcd72852c83b8f906e7012e6 100644
index d5f3b8544d0df0ed54d43c080f96df6242700cbf..a22241133329a0fca905d13f24e2c415f56f350c 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -7396,9 +7396,12 @@ test("unit_tests") {
@@ -7355,9 +7355,12 @@ test("unit_tests") {
"//chrome/notification_helper",
]
@@ -63,7 +63,7 @@ index 6e7ba06e1edfce3d0890013fa8fb1369899a297a..2ed7f27a1e194abcdcd72852c83b8f90
"//chrome//services/util_win:unit_tests",
"//chrome/app:chrome_dll_resources",
"//chrome/app:win_unit_tests",
@@ -8336,6 +8339,10 @@ test("unit_tests") {
@@ -8299,6 +8302,10 @@ test("unit_tests") {
"../browser/performance_manager/policies/background_tab_loading_policy_unittest.cc",
]
@@ -74,7 +74,7 @@ index 6e7ba06e1edfce3d0890013fa8fb1369899a297a..2ed7f27a1e194abcdcd72852c83b8f90
sources += [
# The importer code is not used on Android.
"../common/importer/firefox_importer_utils_unittest.cc",
@@ -8391,7 +8398,6 @@ test("unit_tests") {
@@ -8354,7 +8361,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

@@ -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 8ffff25f7d89b3dcf35b598d5f2213d0716699e2..6788fe50093372acaf6209e740c560d215bd8643 100644
index 0e654a522fd1a98f1b7be62570fe697b801daabe..f19b6c0fc3379849da077d74768766e2eb8906fe 100644
--- a/build/config/BUILDCONFIG.gn
+++ b/build/config/BUILDCONFIG.gn
@@ -123,6 +123,9 @@ if (current_os == "") {

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 b7cb32a0639b9bda3e6648dd86d735d030897699..3796793317febae3661a3c46a0815647a36266f4 100644
index 05e743e72e95a75ae1504525ce5da9b173514873..0ed662b313de6ed5431872ac821bc7edf34687b1 100644
--- a/buildtools/third_party/libc++/BUILD.gn
+++ b/buildtools/third_party/libc++/BUILD.gn
@@ -582,6 +582,7 @@ target(libcxx_target_type, "libc++") {
@@ -275,6 +275,7 @@ target(libcxx_target_type, "libc++") {
# need to explicitly depend on libc++.
visibility = [
"//build/config:common_deps",

View File

@@ -1,26 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Keeley Hammond <khammond@slack-corp.com>
Date: Tue, 1 Jul 2025 15:40:02 -0700
Subject: build: Set MacOS SDK minimum back to 10
This commit reverts 6493969: Update mac_sdk_min to
match minimum required SDK version |
https://chromium-review.googlesource.com/c/chromium/src/+/6493969
This patch is purely to unblock nightlies while
we merge an upstream fix and allocate additional space
on the Mac runners. If this patch is still in main
anytime after July 30, 2025, find @VerteDinde and yell
at her.
diff --git a/build/config/mac/mac_sdk_overrides.gni b/build/config/mac/mac_sdk_overrides.gni
index 8f8ac1c218ce15fa5c1aecbbcd0b93281f6c52f2..15ddfd5cffbaba0704b3217e1ae4f2825f399d96 100644
--- a/build/config/mac/mac_sdk_overrides.gni
+++ b/build/config/mac/mac_sdk_overrides.gni
@@ -7,5 +7,5 @@
declare_args() {
# Minimum supported version of the Mac SDK.
- mac_sdk_min = "15"
+ mac_sdk_min = "10.15"
}

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 63b6d11a3752cf7eea37e477ae438a4375e6ac4f..b0de3dc68c75388591e54cc3c1d8e8c7a56a8773 100644
index d891f8c6a6f8f24a467216772719407d029ff233..34155be5e9071dc0de8fec707ab9736b2c81460b 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -9757,6 +9757,7 @@ void RenderFrameHostImpl::CreateNewWindow(
@@ -9726,6 +9726,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 63b6d11a3752cf7eea37e477ae438a4375e6ac4f..b0de3dc68c75388591e54cc3c1d8e8c7
&no_javascript_access);
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index f4cb3ab03bba197652e000a1cdfd8593d526b5cc..133718bc2e270ac7ed02ef4a7f17bf4efb773d5c 100644
index de45975cbb12b4b169b3771204621dc3c835c97a..089a46b598bbf527bed6734c96497172651b5497 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -5287,6 +5287,12 @@ FrameTree* WebContentsImpl::CreateNewWindow(
@@ -5302,6 +5302,12 @@ FrameTree* WebContentsImpl::CreateNewWindow(
// Sets the newly created WebContents WindowOpenDisposition.
new_contents_impl->original_window_open_disposition_ = params.disposition;
@@ -37,7 +37,7 @@ index f4cb3ab03bba197652e000a1cdfd8593d526b5cc..133718bc2e270ac7ed02ef4a7f17bf4e
// 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
@@ -5328,12 +5334,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
@@ -5343,12 +5349,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
AddWebContentsDestructionObserver(new_contents_impl);
}
@@ -51,7 +51,7 @@ index f4cb3ab03bba197652e000a1cdfd8593d526b5cc..133718bc2e270ac7ed02ef4a7f17bf4e
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 0dfcbbd0e3274d01d938f843530b61a52028771d..14007f8b9c30a72b8303eccd1891a7fd409cc7ad 100644
index 09f1899c9b044a05b2e40c291f17fdf1f9f2fcac..89643bf7059d4fc0d6de6116ffe0fdac883b3fc9 100644
--- a/content/common/frame.mojom
+++ b/content/common/frame.mojom
@@ -653,6 +653,10 @@ struct CreateNewWindowParams {
@@ -66,10 +66,10 @@ index 0dfcbbd0e3274d01d938f843530b61a52028771d..14007f8b9c30a72b8303eccd1891a7fd
// 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 8b21f2ba284ece1d6b339cf10dfe9181fae9b1d7..a1f71d06e8f205d651c5a3f8a3f1af3e774d6800 100644
index acedc33297e4863e38b664c70031ac8bb110d2b8..430324e24d9f6b2f04c1ff69725e3795f2f0a23a 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -858,6 +858,8 @@ bool ContentBrowserClient::CanCreateWindow(
@@ -859,6 +859,8 @@ bool ContentBrowserClient::CanCreateWindow(
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
@@ -79,10 +79,10 @@ index 8b21f2ba284ece1d6b339cf10dfe9181fae9b1d7..a1f71d06e8f205d651c5a3f8a3f1af3e
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 3244924132a833c7c712aa46f96e990cacf42eca..96f343fa47565d6f88925548b1f1c7f9b5c8736c 100644
index 57e22765a4d66cb1cbfa66c4119c6fda4ee13e1c..fb83711948c2249bbcb488b17adac83ac69b00e3 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -199,6 +199,7 @@ class NetworkService;
@@ -200,6 +200,7 @@ class NetworkService;
class TrustedURLLoaderHeaderClient;
} // namespace mojom
struct ResourceRequest;
@@ -90,7 +90,7 @@ index 3244924132a833c7c712aa46f96e990cacf42eca..96f343fa47565d6f88925548b1f1c7f9
} // namespace network
namespace sandbox {
@@ -1425,6 +1426,8 @@ class CONTENT_EXPORT ContentBrowserClient {
@@ -1429,6 +1430,8 @@ class CONTENT_EXPORT ContentBrowserClient {
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
@@ -122,7 +122,7 @@ index ca92e2ddf78d8f386b5ab23a09876d3b44e21334..33be50ce93dd998df5244f9ade391943
WebContents* source,
const OpenURLParams& params,
diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h
index 4c687a84d14d5fa8cd5e376580b594ed0d116ef5..1a71f8020ba4de7bd4966bb02563155237659c32 100644
index d33274984bf6523beeb3ab5ee586499d224bff3c..83bdd195339eb7d61ac88e2994fd8dabe93f6ecc 100644
--- a/content/public/browser/web_contents_delegate.h
+++ b/content/public/browser/web_contents_delegate.h
@@ -18,6 +18,7 @@
@@ -133,7 +133,7 @@ index 4c687a84d14d5fa8cd5e376580b594ed0d116ef5..1a71f8020ba4de7bd4966bb025631552
#include "content/public/browser/eye_dropper.h"
#include "content/public/browser/fullscreen_types.h"
#include "content/public/browser/invalidate_type.h"
@@ -383,6 +384,13 @@ class CONTENT_EXPORT WebContentsDelegate {
@@ -380,6 +381,13 @@ class CONTENT_EXPORT WebContentsDelegate {
const StoragePartitionConfig& partition_config,
SessionStorageNamespace* session_storage_namespace);
@@ -148,22 +148,22 @@ index 4c687a84d14d5fa8cd5e376580b594ed0d116ef5..1a71f8020ba4de7bd4966bb025631552
// 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 414af5f3574d3fa7c45a5b809cd99d19e5202160..b74623455d53d109a97e6c767f56a9beeb0e87e5 100644
index c2be73830eb3922f12337be463ea446d1fdf3f23..654088d4615a39ae691be12d289dc4bfe3952199 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -6756,6 +6756,10 @@ WebView* RenderFrameImpl::CreateNewWindow(
@@ -6807,6 +6807,10 @@ WebView* RenderFrameImpl::CreateNewWindow(
request.HasUserGesture(), GetWebFrame()->IsAdFrame(),
GetWebFrame()->IsAdScriptInStack());
+ params->raw_features = features.raw_features.Utf8(
+ blink::Utf8ConversionMode::kStrictReplacingErrors);
+ WTF::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 66a10226b043a490295e518230c20bba0ed71d6c..14b78014d93ce459789fd497dfcfb71e2cc769bd 100644
index 1aeb38acfef08fc1f7120be73a5b20c2863e9895..a2896b364e6f4333172e66656a4811170dbd96eb 100644
--- a/content/web_test/browser/web_test_content_browser_client.cc
+++ b/content/web_test/browser/web_test_content_browser_client.cc
@@ -537,6 +537,8 @@ bool WebTestContentBrowserClient::CanCreateWindow(
@@ -176,10 +176,10 @@ index 66a10226b043a490295e518230c20bba0ed71d6c..14b78014d93ce459789fd497dfcfb71e
bool opener_suppressed,
bool* no_javascript_access) {
diff --git a/content/web_test/browser/web_test_content_browser_client.h b/content/web_test/browser/web_test_content_browser_client.h
index 790f004d2a3a9ae5a3588fda097732a5daac0c75..83fcc9418b89b669863e730f2049a1d836eef260 100644
index b50d5628cfe6dc3009d889b6a8c4a0925d19592b..43d67de5ef7552bec5ced1496318724c01a806ce 100644
--- a/content/web_test/browser/web_test_content_browser_client.h
+++ b/content/web_test/browser/web_test_content_browser_client.h
@@ -98,6 +98,8 @@ class WebTestContentBrowserClient : public ShellContentBrowserClient {
@@ -94,6 +94,8 @@ class WebTestContentBrowserClient : public ShellContentBrowserClient {
const std::string& frame_name,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& features,
@@ -210,7 +210,7 @@ index 82e9d3dfb5f7da76d89fe15ae61d379fa46e177d..fd035512099a54dff6cc951a2226c23a
} // 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 03277987be8d0799b8ae61b6714bc71f74adb5f0..12e6ca5e45c16a76c0bac3674e74def93f0a0593 100644
index 47d4a455aec76c00d51d11fb2b678b0d4d52b5ca..c2207b8f9ee1193d40201ef25d29c510b6e8346f 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -2317,6 +2317,8 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,

View File

@@ -10,7 +10,7 @@ Subject: chore: "grandfather in" Electron Views and Delegates
6448510: Lock further access to View::set_owned_by_client(). | https://chromium-review.googlesource.com/c/chromium/src/+/6448510
diff --git a/ui/views/view.h b/ui/views/view.h
index 23232b148b002e83926b8848c2e2ada42d608083..df2e5a84387620bfa2e642e957e4d7e7d8106b44 100644
index 2897bc3816c9e2989829848e556ffaea6e1d0a73..0ebc9bc2509648f36dc05fee40709f02be9743ed 100644
--- a/ui/views/view.h
+++ b/ui/views/view.h
@@ -82,6 +82,19 @@ class ArcNotificationContentView;

View File

@@ -7,7 +7,7 @@ This patch comes after Chromium removed the ScopedAllowIO API in favor
of explicitly adding ScopedAllowBlocking calls as friends.
diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h
index ecbd353eac1f4fb3022d822d38938b81ba182fd6..22b643e960e89ee58f5190eebd6093952eefaa6f 100644
index b1abcfaab58df4555d3a26481915d64ef5458e17..f2f43454c1c124da9983998564837ebf3589aefd 100644
--- a/base/threading/thread_restrictions.h
+++ b/base/threading/thread_restrictions.h
@@ -132,6 +132,7 @@ class KeyStorageLinux;
@@ -18,7 +18,7 @@ index ecbd353eac1f4fb3022d822d38938b81ba182fd6..22b643e960e89ee58f5190eebd609395
class Profile;
class ProfileImpl;
class ScopedAllowBlockingForProfile;
@@ -278,6 +279,9 @@ class BackendImpl;
@@ -277,6 +278,9 @@ class BackendImpl;
class InFlightIO;
bool CleanupDirectorySync(const base::FilePath&);
} // namespace disk_cache
@@ -28,7 +28,7 @@ index ecbd353eac1f4fb3022d822d38938b81ba182fd6..22b643e960e89ee58f5190eebd609395
namespace enterprise_connectors {
class LinuxKeyRotationCommand;
} // namespace enterprise_connectors
@@ -578,6 +582,7 @@ class BASE_EXPORT ScopedAllowBlocking {
@@ -577,6 +581,7 @@ class BASE_EXPORT ScopedAllowBlocking {
friend class ::DesktopNotificationBalloon;
friend class ::FirefoxProfileLock;
friend class ::GaiaConfig;
@@ -36,7 +36,7 @@ index ecbd353eac1f4fb3022d822d38938b81ba182fd6..22b643e960e89ee58f5190eebd609395
friend class ::ProfileImpl;
friend class ::ScopedAllowBlockingForProfile;
friend class ::StartupTabProviderImpl;
@@ -618,6 +623,7 @@ class BASE_EXPORT ScopedAllowBlocking {
@@ -615,6 +620,7 @@ class BASE_EXPORT ScopedAllowBlocking {
friend class cronet::CronetPrefsManager;
friend class crypto::ScopedAllowBlockingForNSS; // http://crbug.com/59847
friend class drive::FakeDriveService;

View File

@@ -34,7 +34,7 @@ index 2dc44d4787d5198cff7be2cf98ad5acf2d3a9a0b..27a0335aac2bd4239616cf71f5d015c9
class ScrollEvent;
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
index 9233270a3a713810080abc1705b53e56d37e8a63..513899d94b28a8389133f943d41e74ae1bcd5dbd 100644
index b08abb912fa6f8369448b27abf639faa4c438b88..e32e408e9dc4baf897669f5610b8bb3647cd8a92 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -1341,6 +1341,10 @@ HBRUSH DesktopWindowTreeHostWin::GetBackgroundPaintBrush() {
@@ -49,7 +49,7 @@ index 9233270a3a713810080abc1705b53e56d37e8a63..513899d94b28a8389133f943d41e74ae
DesktopWindowTreeHostWin::GetSingletonDesktopNativeCursorManager() {
return new DesktopNativeCursorManagerWin();
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
index ed45fcbe7fe204d7d3623dd91ca91093351a014e..dbf242fd1a9b4eb4f63065a89983de5c2319e25f 100644
index 0d567cbde1ca06d8cc4dd25785e89550d7190744..8753821149dc870b9865884dccf1ba4dec7e29f2 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
@@ -272,6 +272,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin

View File

@@ -14,10 +14,10 @@ track down the source of this problem & figure out if we can fix it
by changing something in Electron.
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index b5feb80ee47826eb8d052e2bcdb1e602fa50ec5f..56a2bedb0f594d9ccd0dfb9046ef1da64e1fc72b 100644
index 29667a364354b230a6e8a6ccab8d8ac95cdf1e84..bf228613571121a4c6b788b4c066db04fbcb6054 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -5203,7 +5203,7 @@ FrameTree* WebContentsImpl::CreateNewWindow(
@@ -5218,7 +5218,7 @@ FrameTree* WebContentsImpl::CreateNewWindow(
: IsGuest();
// While some guest types do not have a guest SiteInstance, the ones that
// don't all override WebContents creation above.

View File

@@ -80,10 +80,10 @@ index b6582b4013d9682d32bd524b4053b443a4df00f8..afcbce72e0f247b4d5a637b27c9f25d9
content::WebContents* source,
const content::OpenURLParams& params,
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 32516a8e60d96b2370f0f030852015e6d30d9cb1..1efcb0fd83062af0301fe6d8e3166d657bfb18c7 100644
index 9b13df3562fa08eff02cae11f87369ae7417f6a8..88a85350965f9e13f5660632033e958829a85008 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -2363,8 +2363,7 @@ bool Browser::IsWebContentsCreationOverridden(
@@ -2379,8 +2379,7 @@ bool Browser::IsWebContentsCreationOverridden(
content::SiteInstance* source_site_instance,
content::mojom::WindowContainerType window_container_type,
const GURL& opener_url,
@@ -93,7 +93,7 @@ index 32516a8e60d96b2370f0f030852015e6d30d9cb1..1efcb0fd83062af0301fe6d8e3166d65
if (IsActorExecutionEngineActingOnTab(
profile(), content::WebContents::FromRenderFrameHost(opener))) {
// If an ExecutionEngine is acting on the opener, prevent it from creating
@@ -2376,7 +2375,7 @@ bool Browser::IsWebContentsCreationOverridden(
@@ -2392,7 +2391,7 @@ bool Browser::IsWebContentsCreationOverridden(
return (window_container_type ==
content::mojom::WindowContainerType::BACKGROUND &&
ShouldCreateBackgroundContents(source_site_instance, opener_url,
@@ -103,10 +103,10 @@ index 32516a8e60d96b2370f0f030852015e6d30d9cb1..1efcb0fd83062af0301fe6d8e3166d65
WebContents* Browser::CreateCustomWebContents(
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index a795d6515099dea389913f84f25f5170bc5dcefc..68e63fdbd07ea7b6b8175932386cac5b3a0db89a 100644
index de64b1217202846a285d7a4bcbce7780575ebaf0..a6139653fd82db949ffd960ea46fb1604e6c7317 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -986,8 +986,7 @@ class Browser : public TabStripModelObserver,
@@ -993,8 +993,7 @@ class Browser : public TabStripModelObserver,
content::SiteInstance* source_site_instance,
content::mojom::WindowContainerType window_container_type,
const GURL& opener_url,
@@ -222,10 +222,10 @@ index b969f1d97b7e3396119b579cfbe61e19ff7d2dd4..b8d6169652da28266a514938b45b39c5
content::WebContents* AddNewContents(
content::WebContents* source,
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 2789ab0d799653e34b2a3f81333daf5e0cf3ecf5..ef4630910570726091ad9170864a1509a4558524 100644
index 487e6d8db0d19e9a2257d17fcbe348544e7905b7..16bb1ca75b2e105b381ee5564f9332d4eeb2e7d7 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -5166,8 +5166,7 @@ FrameTree* WebContentsImpl::CreateNewWindow(
@@ -5181,8 +5181,7 @@ FrameTree* WebContentsImpl::CreateNewWindow(
if (delegate_ &&
delegate_->IsWebContentsCreationOverridden(
opener, source_site_instance, params.window_container_type,
@@ -250,10 +250,10 @@ index 33be50ce93dd998df5244f9ade391943f06978ad..3bb9baf76d331351d23d59fc2b9eb82d
}
diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h
index 1a71f8020ba4de7bd4966bb02563155237659c32..526a165f9e8bd20747ee00e6f987c995ac737176 100644
index 83bdd195339eb7d61ac88e2994fd8dabe93f6ecc..682e5eecb7ce514094f76253447aa7ac4b6f29b1 100644
--- a/content/public/browser/web_contents_delegate.h
+++ b/content/public/browser/web_contents_delegate.h
@@ -362,8 +362,7 @@ class CONTENT_EXPORT WebContentsDelegate {
@@ -359,8 +359,7 @@ class CONTENT_EXPORT WebContentsDelegate {
SiteInstance* source_site_instance,
mojom::WindowContainerType window_container_type,
const GURL& opener_url,

View File

@@ -7,7 +7,7 @@ By default, chromium sets up one v8 snapshot to be used in all v8 contexts. This
to have a dedicated browser process v8 snapshot defined by the file `browser_v8_context_snapshot.bin`.
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc
index c53bea0517ba3e2f7e127a27737240f054d6b6ed..2ed4e422f0ff0f3dd0194f767c976244be02c3d2 100644
index 81b2d4ffddb31d5703d6e4db2f50644a300b20d7..9b5a6e768b41e231f932e4d2c5d2d84bd89f06cd 100644
--- a/content/app/content_main_runner_impl.cc
+++ b/content/app/content_main_runner_impl.cc
@@ -270,8 +270,13 @@ void AsanProcessInfoCB(const char*, bool*) {
@@ -40,7 +40,7 @@ index c53bea0517ba3e2f7e127a27737240f054d6b6ed..2ed4e422f0ff0f3dd0194f767c976244
#endif // V8_USE_EXTERNAL_STARTUP_DATA
}
@@ -944,7 +950,7 @@ int ContentMainRunnerImpl::Initialize(ContentMainParams params) {
@@ -981,7 +987,7 @@ int ContentMainRunnerImpl::Initialize(ContentMainParams params) {
return TerminateForFatalInitializationError();
#endif // BUILDFLAG(IS_ANDROID) && (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE)
@@ -94,10 +94,10 @@ index db611d99a6c0f18f39967b38791822fda7d175b5..cc150475de655d5ef20a107ae3ef80c0
friend class ContentClientCreator;
friend class ContentClientInitializer;
diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc
index e7d14253e0a6324e6603923c5d6e0769a051b475..e48f92eb5b5e1423c8e8b2c9da0dbb6919880684 100644
index e2ff4bdcc0f474c13659f7527c04cbc85af99b57..6cde70fba12b84399d0b532994b678e09df3eb43 100644
--- a/gin/v8_initializer.cc
+++ b/gin/v8_initializer.cc
@@ -656,8 +656,7 @@ void V8Initializer::GetV8ExternalSnapshotData(const char** snapshot_data_out,
@@ -658,8 +658,7 @@ void V8Initializer::GetV8ExternalSnapshotData(const char** snapshot_data_out,
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
@@ -107,7 +107,7 @@ index e7d14253e0a6324e6603923c5d6e0769a051b475..e48f92eb5b5e1423c8e8b2c9da0dbb69
if (g_mapped_snapshot) {
// TODO(crbug.com/40558459): Confirm not loading different type of snapshot
// files in a process.
@@ -666,10 +665,17 @@ void V8Initializer::LoadV8Snapshot(V8SnapshotFileType snapshot_file_type) {
@@ -668,10 +667,17 @@ void V8Initializer::LoadV8Snapshot(V8SnapshotFileType snapshot_file_type) {
base::MemoryMappedFile::Region file_region;
base::File file =

View File

@@ -8,10 +8,10 @@ Allow registering custom protocols to handle service worker main script fetching
Refs https://bugs.chromium.org/p/chromium/issues/detail?id=996511
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc
index 9adc60ae6da7beb305f58ec326346532d1afd158..434b33a2f1f9531038372e26d3c0ceec704818bd 100644
index 56136ecc71829522295407d1a61518a08537df09..720ce64d0541d96c1294ef3bc1a4b45643c30772 100644
--- a/content/browser/service_worker/service_worker_context_wrapper.cc
+++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -1937,6 +1937,26 @@ ServiceWorkerContextWrapper::GetLoaderFactoryForBrowserInitiatedRequest(
@@ -1936,6 +1936,26 @@ ServiceWorkerContextWrapper::GetLoaderFactoryForBrowserInitiatedRequest(
loader_factory_bundle_info =
context()->loader_factory_bundle_for_update_check()->Clone();
@@ -38,7 +38,7 @@ index 9adc60ae6da7beb305f58ec326346532d1afd158..434b33a2f1f9531038372e26d3c0ceec
if (auto* config = content::WebUIConfigMap::GetInstance().GetConfig(
browser_context(), scope)) {
// If this is a Service Worker for a WebUI, the WebUI's URLDataSource
@@ -1956,9 +1976,7 @@ ServiceWorkerContextWrapper::GetLoaderFactoryForBrowserInitiatedRequest(
@@ -1955,9 +1975,7 @@ ServiceWorkerContextWrapper::GetLoaderFactoryForBrowserInitiatedRequest(
features::kEnableServiceWorkersForChromeScheme) &&
scope.scheme_piece() == kChromeUIScheme) {
config->RegisterURLDataSource(browser_context());
@@ -49,7 +49,7 @@ index 9adc60ae6da7beb305f58ec326346532d1afd158..434b33a2f1f9531038372e26d3c0ceec
.emplace(kChromeUIScheme, CreateWebUIServiceWorkerLoaderFactory(
browser_context(), kChromeUIScheme,
base::flat_set<std::string>()));
@@ -1966,9 +1984,7 @@ ServiceWorkerContextWrapper::GetLoaderFactoryForBrowserInitiatedRequest(
@@ -1965,9 +1983,7 @@ ServiceWorkerContextWrapper::GetLoaderFactoryForBrowserInitiatedRequest(
features::kEnableServiceWorkersForChromeUntrusted) &&
scope.scheme_piece() == kChromeUIUntrustedScheme) {
config->RegisterURLDataSource(browser_context());

View File

@@ -6,10 +6,10 @@ Subject: disable_hidden.patch
Electron uses this to disable background throttling for hidden windows.
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 80ccb50098f642f4ce7bd97de20d821decd8fab6..1874493c21087f1cf3a565956bd48ebac6892135 100644
index 252edf0bb40ba4c16061425013d9e4c559b91e78..624094ba6459f3663a12f868c4cb47dfa9f8dce1 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -834,6 +834,10 @@ void RenderWidgetHostImpl::WasHidden() {
@@ -833,6 +833,10 @@ void RenderWidgetHostImpl::WasHidden() {
return;
}
@@ -21,10 +21,10 @@ index 80ccb50098f642f4ce7bd97de20d821decd8fab6..1874493c21087f1cf3a565956bd48eba
// Prompts should remain open and functional across tab switches.
if (!delegate_ || !delegate_->IsWaitingForPointerLockPrompt(this)) {
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index ad3b28d343c6c7c454bb6deb2459ba807e992ca5..65431096f65d6bb3f4c3efeae7f80617ed596cad 100644
index f24d02054c89c8bc6b75e127146cb97a72e3f94a..9b8919ab2d8c9432c5d908337e7a19bd055b440e 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -1020,6 +1020,9 @@ class CONTENT_EXPORT RenderWidgetHostImpl
@@ -1021,6 +1021,9 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// Requests a commit and forced redraw in the renderer compositor.
void ForceRedrawForTesting();

View File

@@ -6,7 +6,7 @@ Subject: feat: enable setting aspect ratio to 0
Make SetAspectRatio accept 0 as valid input, which would reset to null.
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
index 7647828a5952da59351f9e2e295ae58a17c1f8d3..9233270a3a713810080abc1705b53e56d37e8a63 100644
index 4f94ed1e9f7cda90b4356839967972ca59decb9c..b08abb912fa6f8369448b27abf639faa4c438b88 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -594,7 +594,7 @@ void DesktopWindowTreeHostWin::SetOpacity(float opacity) {

View File

@@ -15,10 +15,10 @@ Ideally we could add an embedder observer pattern here but that can be
done in future work.
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 85a2d5c468107d51fe931ba3b8464517a2bbdddf..bb9745b97e411c03c4757f7a96e240df93b28559 100644
index 353c093d9fc15913dec6301cfc654c1a3a3fbc10..7163be14508786f67c3ea01cff9bc70c3692acac 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -1875,6 +1875,8 @@ void WebView::ApplyWebPreferences(const web_pref::WebPreferences& prefs,
@@ -1880,6 +1880,8 @@ void WebView::ApplyWebPreferences(const web_pref::WebPreferences& prefs,
#if BUILDFLAG(IS_MAC)
web_view_impl->SetMaximumLegibleScale(
prefs.default_maximum_page_scale_factor);

View File

@@ -88,27 +88,28 @@ index dc3a5b0678b9c686e241b492e2c3b5ac833611a3..32a7ba4f557e65d9525d2ca07e8597e7
// testing.
V8IsolateMemoryDumpProvider* isolate_memory_dump_provider_for_testing()
diff --git a/gin/wrappable.cc b/gin/wrappable.cc
index 721a0f3dc2c1714726b711b1b661907e80a9bdcc..6b954d9840f9b1798aa1778fa39c8a20cb4f34df 100644
index 402355cb836cea14e9ee725a142a4bad44fd5bed..7e7f028dcfb87c7b80adebabac19ced8791f642e 100644
--- a/gin/wrappable.cc
+++ b/gin/wrappable.cc
@@ -53,6 +53,8 @@ v8::MaybeLocal<v8::Object> WrappableBase::GetWrapper(v8::Isolate* isolate) {
DeprecatedWrappableBase::DeprecatedWrappableBase() = default;
@@ -13,6 +13,9 @@ namespace gin {
WrappableBase::WrappableBase() = default;
DeprecatedWrappableBase::~DeprecatedWrappableBase() {
+ if (!wrapper_.IsEmpty())
WrappableBase::~WrappableBase() {
+ if (!wrapper_.IsEmpty()) {
+ wrapper_.ClearWeak();
+ }
wrapper_.Reset();
}
@@ -68,9 +70,13 @@ const char* DeprecatedWrappableBase::GetTypeName() {
void DeprecatedWrappableBase::FirstWeakCallback(
const v8::WeakCallbackInfo<DeprecatedWrappableBase>& data) {
DeprecatedWrappableBase* wrappable = data.GetParameter();
@@ -28,15 +31,24 @@ const char* WrappableBase::GetTypeName() {
void WrappableBase::FirstWeakCallback(
const v8::WeakCallbackInfo<WrappableBase>& data) {
WrappableBase* wrappable = data.GetParameter();
- wrappable->dead_ = true;
- wrappable->wrapper_.Reset();
- data.SetSecondPassCallback(SecondWeakCallback);
+ DeprecatedWrappableBase* wrappable_from_field =
+ static_cast<DeprecatedWrappableBase*>(data.GetInternalField(1));
+ WrappableBase* wrappable_from_field =
+ static_cast<WrappableBase*>(data.GetInternalField(1));
+ if (wrappable && wrappable == wrappable_from_field) {
+ wrappable->dead_ = true;
+ wrappable->wrapper_.Reset();
@@ -116,21 +117,20 @@ index 721a0f3dc2c1714726b711b1b661907e80a9bdcc..6b954d9840f9b1798aa1778fa39c8a20
+ }
}
NamedPropertyInterceptor*
@@ -80,8 +86,11 @@ DeprecatedWrappableBase::GetNamedPropertyInterceptor() {
void DeprecatedWrappableBase::SecondWeakCallback(
const v8::WeakCallbackInfo<DeprecatedWrappableBase>& data) {
+ if (IsolateHolder::DestroyedMicrotasksRunner())
void WrappableBase::SecondWeakCallback(
const v8::WeakCallbackInfo<WrappableBase>& data) {
+ if (IsolateHolder::DestroyedMicrotasksRunner()) {
+ return;
DeprecatedWrappableBase* wrappable = data.GetParameter();
+ }
WrappableBase* wrappable = data.GetParameter();
- delete wrappable;
+ if (wrappable)
+ if (wrappable) {
+ delete wrappable;
+ }
}
v8::MaybeLocal<v8::Object> DeprecatedWrappableBase::GetWrapperImpl(
@@ -117,10 +126,15 @@ v8::MaybeLocal<v8::Object> DeprecatedWrappableBase::GetWrapperImpl(
v8::MaybeLocal<v8::Object> WrappableBase::GetWrapperImpl(v8::Isolate* isolate,
@@ -71,10 +83,16 @@ v8::MaybeLocal<v8::Object> WrappableBase::GetWrapperImpl(v8::Isolate* isolate,
void* values[] = {info, this};
wrapper->SetAlignedPointerInInternalFields(2, indices, values);
wrapper_.Reset(isolate, wrapper);
@@ -139,21 +139,22 @@ index 721a0f3dc2c1714726b711b1b661907e80a9bdcc..6b954d9840f9b1798aa1778fa39c8a20
return v8::MaybeLocal<v8::Object>(wrapper);
}
+void DeprecatedWrappableBase::ClearWeak() {
+ if (!wrapper_.IsEmpty())
+void WrappableBase::ClearWeak() {
+ if (!wrapper_.IsEmpty()) {
+ wrapper_.ClearWeak();
+ }
+}
+
namespace internal {
void* FromV8Impl(v8::Isolate* isolate,
void* FromV8Impl(v8::Isolate* isolate, v8::Local<v8::Value> val,
diff --git a/gin/wrappable.h b/gin/wrappable.h
index 9048c4fc9f6b0a19f0620d6eb7e35d5005381d81..566d590890ba40ca3a254c7d88c0b30817d2a5e6 100644
index 2ae2cf67157ce8b161ae917291a913d237b7d535..c8c8cbe84e946cebde97a71b42815c62ccaf7b96 100644
--- a/gin/wrappable.h
+++ b/gin/wrappable.h
@@ -172,6 +172,13 @@ class GIN_EXPORT DeprecatedWrappableBase {
v8::Isolate* isolate,
DeprecatedWrapperInfo* wrapper_info);
@@ -80,6 +80,13 @@ class GIN_EXPORT WrappableBase {
v8::MaybeLocal<v8::Object> GetWrapperImpl(v8::Isolate* isolate,
WrapperInfo* wrapper_info);
+ // Make this wrappable strong again. This is useful when the wrappable is
+ // destroyed outside the finalizer callbacks and we want to avoid scheduling
@@ -164,4 +165,4 @@ index 9048c4fc9f6b0a19f0620d6eb7e35d5005381d81..566d590890ba40ca3a254c7d88c0b308
+
private:
static void FirstWeakCallback(
const v8::WeakCallbackInfo<DeprecatedWrappableBase>& data);
const v8::WeakCallbackInfo<WrappableBase>& data);

View File

@@ -262,10 +262,10 @@ index 61683d0eddb04c494ca5e650e7d556b44968ec49..5492456a9138b250e97a5479838bb443
} // namespace ui
diff --git a/ui/shell_dialogs/select_file_dialog_linux_portal.cc b/ui/shell_dialogs/select_file_dialog_linux_portal.cc
index 9853bac93511ff5f790833528829a2c0017ed505..8cd68dddc2de3ecc393858194e825283fcd544db 100644
index 8dafba0690d9cde3506b60a21ba36c49394d9125..03fdd2d86e776d4be60c52790dcb2946e9341954 100644
--- a/ui/shell_dialogs/select_file_dialog_linux_portal.cc
+++ b/ui/shell_dialogs/select_file_dialog_linux_portal.cc
@@ -30,6 +30,7 @@
@@ -29,6 +29,7 @@
#include "dbus/message.h"
#include "dbus/object_path.h"
#include "dbus/object_proxy.h"
@@ -273,7 +273,7 @@ index 9853bac93511ff5f790833528829a2c0017ed505..8cd68dddc2de3ecc393858194e825283
#include "ui/aura/window_tree_host.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/native_widget_types.h"
@@ -101,7 +102,7 @@ void OnGetPropertyReply(dbus::Response* response) {
@@ -100,7 +101,7 @@ void OnGetPropertyReply(dbus::Response* response) {
: ServiceAvailability::kNotAvailable;
}
@@ -282,10 +282,10 @@ index 9853bac93511ff5f790833528829a2c0017ed505..8cd68dddc2de3ecc393858194e825283
if (!service_started.value_or(false)) {
g_service_availability = ServiceAvailability::kNotAvailable;
return;
@@ -120,9 +121,12 @@ void OnServiceStarted(std::optional<bool> service_started) {
}
@@ -167,18 +168,24 @@ void SelectFileDialogLinuxPortal::StartAvailabilityTestInBackground() {
GetMainTaskRunner() = base::SequencedTaskRunner::GetCurrentDefault();
void OnSystemdUnitStarted(dbus_xdg::SystemdUnitStatus) {
+#if 0
dbus_utils::CheckForServiceAndStart(dbus_thread_linux::GetSharedSessionBus(),
kXdgPortalService,
@@ -294,17 +294,6 @@ index 9853bac93511ff5f790833528829a2c0017ed505..8cd68dddc2de3ecc393858194e825283
+ file_dialog::StartPortalAvailabilityTestInBackground();
}
DbusByteArray PathToByteArray(const base::FilePath& path) {
@@ -175,17 +179,20 @@ void SelectFileDialogLinuxPortal::StartAvailabilityTestInBackground() {
GetMainTaskRunner() = base::SequencedTaskRunner::GetCurrentDefault();
dbus_xdg::SetSystemdScopeUnitNameForXdgPortal(
- dbus_thread_linux::GetSharedSessionBus().get(),
- base::BindOnce(&OnSystemdUnitStarted));
+ dbus_thread_linux::GetSharedSessionBus().get(),
+ base::BindOnce(&OnSystemdUnitStarted));
}
// static
bool SelectFileDialogLinuxPortal::IsPortalAvailable() {
+#if 0
@@ -318,7 +307,7 @@ index 9853bac93511ff5f790833528829a2c0017ed505..8cd68dddc2de3ecc393858194e825283
}
bool SelectFileDialogLinuxPortal::IsRunning(
@@ -390,11 +397,14 @@ DbusDictionary SelectFileDialogLinuxPortal::BuildOptionsDictionary(
@@ -383,11 +390,14 @@ DbusDictionary SelectFileDialogLinuxPortal::BuildOptionsDictionary(
const PortalFilterSet& filter_set) {
DbusDictionary dict;
@@ -336,7 +325,7 @@ index 9853bac93511ff5f790833528829a2c0017ed505..8cd68dddc2de3ecc393858194e825283
[[fallthrough]];
case SelectFileDialog::SELECT_FOLDER:
case SelectFileDialog::Type::SELECT_EXISTING_FOLDER:
@@ -407,6 +417,10 @@ DbusDictionary SelectFileDialogLinuxPortal::BuildOptionsDictionary(
@@ -400,6 +410,10 @@ DbusDictionary SelectFileDialogLinuxPortal::BuildOptionsDictionary(
break;
}

View File

@@ -259,7 +259,7 @@ index a2a19b975ddd8799917ec674b53368ab1b123232..3ff87e391f744cd17c26945fa7dcfde5
+
} // namespace content
diff --git a/content/browser/renderer_host/code_cache_host_impl.cc b/content/browser/renderer_host/code_cache_host_impl.cc
index d95cba73aacf4b9156e8c0c3100abd7934369fdd..1583ae512e34c29e849efc2f570e09e74b348406 100644
index 18a3609bfd344716ba7cd550f66d4c4700d227b0..106884585ba2c6e75053474dbd15c728c79fcac1 100644
--- a/content/browser/renderer_host/code_cache_host_impl.cc
+++ b/content/browser/renderer_host/code_cache_host_impl.cc
@@ -6,6 +6,7 @@
@@ -378,10 +378,10 @@ index d95cba73aacf4b9156e8c0c3100abd7934369fdd..1583ae512e34c29e849efc2f570e09e7
process_lock.lock_url().scheme())) {
return process_lock.lock_url();
diff --git a/content/common/url_schemes.cc b/content/common/url_schemes.cc
index 225e017909b8869231b870eaaf161a0b5e93e2a0..846a5251429630b8528a84a3d67ed56cb28df5a1 100644
index ce9644d33fe83379127b01bf9a2b1c4badc3bc7c..fd486d4637ae4766ed78571dee7f9cebbd809f38 100644
--- a/content/common/url_schemes.cc
+++ b/content/common/url_schemes.cc
@@ -102,6 +102,14 @@ void RegisterContentSchemes(bool should_lock_registry) {
@@ -98,6 +98,14 @@ void RegisterContentSchemes(bool should_lock_registry) {
for (auto& scheme : schemes.empty_document_schemes)
url::AddEmptyDocumentScheme(scheme.c_str());
@@ -397,7 +397,7 @@ index 225e017909b8869231b870eaaf161a0b5e93e2a0..846a5251429630b8528a84a3d67ed56c
if (schemes.allow_non_standard_schemes_in_origins)
url::EnableNonStandardSchemesForAndroidWebView();
diff --git a/content/public/common/content_client.h b/content/public/common/content_client.h
index 52f16979b05b692ef72762d0cbc16bcb361b047e..b658ebeb9c572158b27d94af56331be8cbb519e6 100644
index cf71655553cf510e1309ac47bdd5ddab08e52672..0a02d17d06e080f40bf12bb2e48f51ad84ec17b8 100644
--- a/content/public/common/content_client.h
+++ b/content/public/common/content_client.h
@@ -139,6 +139,9 @@ class CONTENT_EXPORT ContentClient {

View File

@@ -10,10 +10,10 @@ Electron needs this constructor, namely for gin_helper::Constructible
objects.
diff --git a/gin/object_template_builder.cc b/gin/object_template_builder.cc
index a694f7dc4da4f1bba579ab8c032eea21d8459995..8aaaba327166b1d3b884fe390a389c0c50890af9 100644
index 50b64c72a837534de727486a026fce1ee610ad23..38bf1e464312e7d4bc2cf5559d10f67d2bf84514 100644
--- a/gin/object_template_builder.cc
+++ b/gin/object_template_builder.cc
@@ -146,6 +146,13 @@ ObjectTemplateBuilder::ObjectTemplateBuilder(v8::Isolate* isolate,
@@ -216,6 +216,13 @@ ObjectTemplateBuilder::ObjectTemplateBuilder(v8::Isolate* isolate,
template_->SetInternalFieldCount(kNumberOfInternalFields);
}

View File

@@ -351,10 +351,10 @@ index 4335d7ff718c3d7de92320ba11c39c3957303788..55379fbe9233ba96f6e4729e2b7d534c
// Whether or not to bind viz::mojom::Gpu to the utility process.
bool allowed_gpu_;
diff --git a/content/browser/service_host/utility_sandbox_delegate.cc b/content/browser/service_host/utility_sandbox_delegate.cc
index ff9941f1f46658574e8ac53bc80fdf665f873bc0..51dfb23c8ebba7ec075ecab597bd84734773f924 100644
index 68063b1f1846bac988e5b25e428666aefa3908e4..e5101df384dc320728105a6d861fc7c61662a504 100644
--- a/content/browser/service_host/utility_sandbox_delegate.cc
+++ b/content/browser/service_host/utility_sandbox_delegate.cc
@@ -43,17 +43,19 @@ UtilitySandboxedProcessLauncherDelegate::
@@ -38,17 +38,19 @@ UtilitySandboxedProcessLauncherDelegate::
UtilitySandboxedProcessLauncherDelegate(
sandbox::mojom::Sandbox sandbox_type,
const base::EnvironmentMap& env,
@@ -378,7 +378,7 @@ index ff9941f1f46658574e8ac53bc80fdf665f873bc0..51dfb23c8ebba7ec075ecab597bd8473
#if DCHECK_IS_ON()
bool supported_sandbox_type =
sandbox_type_ == sandbox::mojom::Sandbox::kNoSandbox ||
@@ -121,11 +123,28 @@ UtilitySandboxedProcessLauncherDelegate::GetSandboxType() {
@@ -112,11 +114,28 @@ UtilitySandboxedProcessLauncherDelegate::GetSandboxType() {
return sandbox_type_;
}

View File

@@ -16,11 +16,66 @@ making three primary changes to Blink:
* Modifies graphics to handle smooth `ContouredRect`s, delegating to
`//electron/shell/renderer/electron_smooth_round_rect`.
3. Adds a renderer feature:
3. Adds a renderer preference / web setting:
* Controls whether the CSS rule is available.
* Mostly simple "plumbing" for the setting through blink.
diff --git a/third_party/blink/common/renderer_preferences/renderer_preferences_mojom_traits.cc b/third_party/blink/common/renderer_preferences/renderer_preferences_mojom_traits.cc
index c13dfd7f20e6f281f51ae373ceebeb86104c5cd9..fac89df9f23f3f098096d2a07a07e623b1067270 100644
--- a/third_party/blink/common/renderer_preferences/renderer_preferences_mojom_traits.cc
+++ b/third_party/blink/common/renderer_preferences/renderer_preferences_mojom_traits.cc
@@ -128,6 +128,8 @@ bool StructTraits<blink::mojom::RendererPreferencesDataView,
return false;
}
+ out->electron_corner_smoothing_css = data.electron_corner_smoothing_css();
+
out->canvas_noise_token = data.canvas_noise_token();
out->view_source_line_wrap_enabled = data.view_source_line_wrap_enabled();
diff --git a/third_party/blink/public/common/renderer_preferences/renderer_preferences.h b/third_party/blink/public/common/renderer_preferences/renderer_preferences.h
index 75acd696a5258e52f5c17b88559dfb3f6373c669..34b5ed725702dca72c383c1def08fdb835f7fa6b 100644
--- a/third_party/blink/public/common/renderer_preferences/renderer_preferences.h
+++ b/third_party/blink/public/common/renderer_preferences/renderer_preferences.h
@@ -91,6 +91,7 @@ struct BLINK_COMMON_EXPORT RendererPreferences {
bool caret_browsing_enabled{false};
bool uses_platform_autofill{false};
std::vector<uint16_t> explicitly_allowed_network_ports;
+ bool electron_corner_smoothing_css{true};
uint64_t canvas_noise_token{0};
// The default value must be false to avoid performance problems on very large
// source pages.
diff --git a/third_party/blink/public/common/renderer_preferences/renderer_preferences_mojom_traits.h b/third_party/blink/public/common/renderer_preferences/renderer_preferences_mojom_traits.h
index defe40d7091cb4ba4b099a22aeaee71f78ff5e77..e8326fa7a3c45c08c7d9250edd52a6d73fcc3ff9 100644
--- a/third_party/blink/public/common/renderer_preferences/renderer_preferences_mojom_traits.h
+++ b/third_party/blink/public/common/renderer_preferences/renderer_preferences_mojom_traits.h
@@ -275,6 +275,11 @@ struct BLINK_COMMON_EXPORT
return data.explicitly_allowed_network_ports;
}
+ static const bool& electron_corner_smoothing_css(
+ const ::blink::RendererPreferences& data) {
+ return data.electron_corner_smoothing_css;
+ }
+
static const uint64_t& canvas_noise_token(
const ::blink::RendererPreferences& data) {
return data.canvas_noise_token;
diff --git a/third_party/blink/public/mojom/renderer_preferences.mojom b/third_party/blink/public/mojom/renderer_preferences.mojom
index f8361faf6151210d65a597562c533aaa0a5235df..328238c34a9381fbbeb5970af3de721c8412104e 100644
--- a/third_party/blink/public/mojom/renderer_preferences.mojom
+++ b/third_party/blink/public/mojom/renderer_preferences.mojom
@@ -202,6 +202,8 @@ struct RendererPreferences {
array<uint16> explicitly_allowed_network_ports;
+ bool electron_corner_smoothing_css;
+
// A randomized 64 bit token that is generated per browser session,
// used for canvas noising.
uint64 canvas_noise_token = 0;
diff --git a/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom b/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom
index e8c017c725f9d9b4f9099c824dfdb4c2cb9cbea6..73e135476bc4c930fd011745503e7f095ccfd8ec 100644
index 917d5ec778658f3890366bbc0cbbe38807089265..3e2c0f0d4632c6d202649ca8f87980b7ee9e9e40 100644
--- a/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom
+++ b/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom
@@ -48,6 +48,7 @@ enum CSSSampleId {
@@ -31,11 +86,23 @@ index e8c017c725f9d9b4f9099c824dfdb4c2cb9cbea6..73e135476bc4c930fd011745503e7f09
// This CSSSampleId represents page load for CSS histograms. It is recorded once
// per page visit for each CSS histogram being logged on the blink side and the
diff --git a/third_party/blink/public/web/web_settings.h b/third_party/blink/public/web/web_settings.h
index 7fdc9866c9db5838ac8852ba156f2f04eb238bf5..56551d8190b3672d7c00c9bc722cf7e3aed255a6 100644
--- a/third_party/blink/public/web/web_settings.h
+++ b/third_party/blink/public/web/web_settings.h
@@ -285,6 +285,7 @@ class WebSettings {
virtual void SetRequireTransientActivationAndAuthorizationForSubAppsAPIs(
bool) = 0;
virtual void SetRootScrollbarThemeColor(std::optional<SkColor>) = 0;
+ virtual void SetCornerSmoothingCSS(bool) = 0;
protected:
~WebSettings() = default;
diff --git a/third_party/blink/renderer/build/scripts/core/css/css_properties.py b/third_party/blink/renderer/build/scripts/core/css/css_properties.py
index e189d584f05f2ce6354c03a9b19f56985df8a15e..41b430e8f2416be098494f5c49fb97cae13447aa 100755
index bc33eaeaff56b3f0e12d87e078e329c35ff4ecb2..bf970892ea846e9e48bf01f9151cb3dee33c0ca9 100755
--- a/third_party/blink/renderer/build/scripts/core/css/css_properties.py
+++ b/third_party/blink/renderer/build/scripts/core/css/css_properties.py
@@ -312,7 +312,7 @@ class CSSProperties(object):
@@ -314,7 +314,7 @@ class CSSProperties(object):
name_without_leading_dash = name_without_leading_dash[1:]
internal_visited_order = 1
if name_without_leading_dash.startswith(
@@ -45,17 +112,16 @@ index e189d584f05f2ce6354c03a9b19f56985df8a15e..41b430e8f2416be098494f5c49fb97ca
'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 9ef592d0d86e4a6296db98b9c31f008f877dd348..b16bc9b41f6b3a596a0e52a516b7182c54c66b1e 100644
index b0d51efeabca3169fc1fffce3a7d6721554a5233..07c11fb1ee66cf17b15ce31617d964cfca4f0b4b 100644
--- a/third_party/blink/renderer/core/css/css_properties.json5
+++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -9002,6 +9002,26 @@
@@ -8939,6 +8939,24 @@
property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
},
+ {
+ name: "-electron-corner-smoothing",
+ property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+ interpolable: true,
+ property_methods: ["ParseSingleValue"],
+ field_group: "*",
+ field_template: "external",
+ // To keep this patch small, Length is used instead of a more descriptive
@@ -63,20 +129,19 @@ index 9ef592d0d86e4a6296db98b9c31f008f877dd348..b16bc9b41f6b3a596a0e52a516b7182c
+ // - `system-ui` = `Length::Auto()`
+ // - percent = `Length::Percent`
+ type_name: "Length",
+ default_value: "Length::None()",
+ keywords: ["system-ui"],
+ converter: "ConvertCornerSmoothing",
+ runtime_flag: "ElectronCSSCornerSmoothing",
+ valid_for_permission_element: true,
+ valid_for_page_context: true,
+ invalidate: ["border-radius", "paint", "corner-shape"],
+ keywords: ["system-ui"],
+ default_value: "Length::None()",
+ typedom_types: ["Keyword", "Percentage"],
+ is_border_radius: true,
+ invalidate: ["paint", "border-radius", "clip"],
+ },
+
// Visited properties.
{
name: "-internal-visited-color",
diff --git a/third_party/blink/renderer/core/css/css_property_equality.cc b/third_party/blink/renderer/core/css/css_property_equality.cc
index 4f13354776da9944ed75874953a2e2c9878a649b..83728e697c5029a79fb75d84a1be5bdf29363826 100644
index a84a3aa2881787f1a9450b977672f339927ce4dd..a78960d5270b52a462feb2858804690612d2feaf 100644
--- a/third_party/blink/renderer/core/css/css_property_equality.cc
+++ b/third_party/blink/renderer/core/css/css_property_equality.cc
@@ -350,6 +350,8 @@ bool CSSPropertyEquality::PropertiesEqual(const PropertyHandle& property,
@@ -89,10 +154,10 @@ index 4f13354776da9944ed75874953a2e2c9878a649b..83728e697c5029a79fb75d84a1be5bdf
return a.EmptyCells() == b.EmptyCells();
case CSSPropertyID::kFill:
diff --git a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
index dc328e04767437d2d9b6d67d07cb6c9d055773f9..19edb190c57b75e29e71d6342e3a648ef4611fdf 100644
index 01ff7488c1cc67dbcdbc372be9c72516cbf9ad29..fd6e883b6e18010974aa5d8ea3051354c6080a73 100644
--- a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
+++ b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
@@ -12325,5 +12325,36 @@ const CSSValue* InternalEmptyLineHeight::ParseSingleValue(
@@ -12156,5 +12156,25 @@ const CSSValue* InternalEmptyLineHeight::ParseSingleValue(
CSSValueID::kNone>(stream);
}
@@ -100,6 +165,12 @@ index dc328e04767437d2d9b6d67d07cb6c9d055773f9..19edb190c57b75e29e71d6342e3a648e
+ CSSParserTokenStream& stream,
+ const CSSParserContext& context,
+ const CSSParserLocalContext&) const {
+ // Fail parsing if this rule is disabled by document settings.
+ if (Settings* settings = context.GetDocument()->GetSettings();
+ settings && !settings->GetElectronCornerSmoothingCSS()) {
+ return nullptr;
+ }
+
+ // Try to parse `system-ui` keyword first.
+ if (auto* ident =
+ css_parsing_utils::ConsumeIdent<CSSValueID::kSystemUi>(stream)) {
@@ -109,31 +180,14 @@ index dc328e04767437d2d9b6d67d07cb6c9d055773f9..19edb190c57b75e29e71d6342e3a648e
+ return css_parsing_utils::ConsumePercent(
+ stream, context, CSSPrimitiveValue::ValueRange::kNonNegative);
+}
+
+const CSSValue* ElectronCornerSmoothing::CSSValueFromComputedStyleInternal(
+ const ComputedStyle& style,
+ const LayoutObject*,
+ bool allow_visited_style,
+ CSSValuePhase value_phase) const {
+ const Length& length = style.ElectronCornerSmoothing();
+ switch (length.GetType()) {
+ case Length::kAuto:
+ return CSSIdentifierValue::Create(CSSValueID::kSystemUi);
+ case Length::kPercent:
+ return CSSNumericLiteralValue::Create(
+ length.Percent(), CSSPrimitiveValue::UnitType::kPercentage);
+ default:
+ return CSSIdentifierValue::Create(CSSValueID::kNone);
+ }
+}
+
} // namespace css_longhand
} // namespace blink
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
index c63e58ac728ebb95de9a7db0a820d6e34eb88128..8b8350322a227cb79de89f5cd827dccc4a383c35 100644
index 192bb06760acbe2fd5d1a59670ee5a535aea2900..a6dbae88a6fd758b5a08e04b430693ca59c251b0 100644
--- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -3988,6 +3988,15 @@ PositionTryFallback StyleBuilderConverter::ConvertSinglePositionTryFallback(
@@ -3982,6 +3982,15 @@ PositionTryFallback StyleBuilderConverter::ConvertSinglePositionTryFallback(
return PositionTryFallback(scoped_name, tactic_list);
}
@@ -150,7 +204,7 @@ index c63e58ac728ebb95de9a7db0a820d6e34eb88128..8b8350322a227cb79de89f5cd827dccc
const CSSValue& value) {
const auto& list = To<CSSValueList>(value);
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.h b/third_party/blink/renderer/core/css/resolver/style_builder_converter.h
index d1430dc2dc30a1962731492c3f53849c7ff8a4db..417ac19f5968b7300ec2f0422728cd85aeeb2ecd 100644
index 960771a0ccdc14abb30d9c72d3f29dc9821d4f4a..9e0a08288a3f4e68c3940104d9c22b7637acc30b 100644
--- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.h
+++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.h
@@ -428,6 +428,7 @@ class StyleBuilderConverter {
@@ -159,8 +213,62 @@ index d1430dc2dc30a1962731492c3f53849c7ff8a4db..417ac19f5968b7300ec2f0422728cd85
const CSSValue&);
+ static Length ConvertCornerSmoothing(StyleResolverState&, const CSSValue&);
static FitText ConvertFitText(StyleResolverState&, const CSSValue&);
};
static ScopedCSSNameList* ConvertTimelineTriggerName(StyleResolverState&,
diff --git a/third_party/blink/renderer/core/exported/web_settings_impl.cc b/third_party/blink/renderer/core/exported/web_settings_impl.cc
index 5a291913e020a785d0e9a1d07dd3bc88d223cc62..f01b25c7af9111596c53dadc5c08c4f1c031fc86 100644
--- a/third_party/blink/renderer/core/exported/web_settings_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_settings_impl.cc
@@ -817,4 +817,8 @@ void WebSettingsImpl::SetRootScrollbarThemeColor(
settings_->SetRootScrollbarThemeColor(theme_color);
}
+void WebSettingsImpl::SetCornerSmoothingCSS(bool available) {
+ settings_->SetElectronCornerSmoothingCSS(available);
+}
+
} // namespace blink
diff --git a/third_party/blink/renderer/core/exported/web_settings_impl.h b/third_party/blink/renderer/core/exported/web_settings_impl.h
index a9fa6e94716bd5e53bc550d0a8d5e200bf0242af..b8d9d99edc8310eda762c83a6a95a43246792b20 100644
--- a/third_party/blink/renderer/core/exported/web_settings_impl.h
+++ b/third_party/blink/renderer/core/exported/web_settings_impl.h
@@ -237,6 +237,7 @@ class CORE_EXPORT WebSettingsImpl final : public WebSettings {
void SetRequireTransientActivationAndAuthorizationForSubAppsAPIs(
bool) override;
void SetRootScrollbarThemeColor(std::optional<SkColor>) override;
+ void SetCornerSmoothingCSS(bool) override;
bool RenderVSyncNotificationEnabled() const {
return render_v_sync_notification_enabled_;
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 7163be14508786f67c3ea01cff9bc70c3692acac..cf477007d90a2c3b9b15ab8a7cd1d0a165c874d7 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -3599,6 +3599,9 @@ void WebViewImpl::UpdateRendererPreferences(
renderer_preferences_.view_source_line_wrap_enabled);
MaybePreloadSystemFonts(GetPage());
+
+ GetSettings()->SetCornerSmoothingCSS(
+ renderer_preferences_.electron_corner_smoothing_css);
}
void WebViewImpl::SetHistoryIndexAndLength(int32_t history_index,
diff --git a/third_party/blink/renderer/core/frame/settings.json5 b/third_party/blink/renderer/core/frame/settings.json5
index 9f68384d71136da79de5fbf7e3feac2a13b7dbec..2bd6f597974c9bdf05b743c8c00182432c8e8dba 100644
--- a/third_party/blink/renderer/core/frame/settings.json5
+++ b/third_party/blink/renderer/core/frame/settings.json5
@@ -1261,5 +1261,10 @@
initial: false,
type: "bool"
},
+ {
+ name: "electronCornerSmoothingCSS",
+ initial: true,
+ invalidate: ["Style"],
+ },
],
}
diff --git a/third_party/blink/renderer/core/paint/contoured_border_geometry.cc b/third_party/blink/renderer/core/paint/contoured_border_geometry.cc
index ec80337fdac36fa1636f5142c3827d3bbc81644c..634db12dfb443acabde79e9faf59cb8415991464 100644
--- a/third_party/blink/renderer/core/paint/contoured_border_geometry.cc
@@ -201,10 +309,10 @@ index ec80337fdac36fa1636f5142c3827d3bbc81644c..634db12dfb443acabde79e9faf59cb84
return result;
}
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn
index 7fde1fa8af8887b77bfe5a90c4f9f49a386a1a7b..11b9d5fb7b3712681e0a2e2b749ac06ff3d3d787 100644
index e6105a54e2534d613943bb56c4c311f35ac69651..e44a985b078ac18c5bc5a05b784f67d156a2dd57 100644
--- a/third_party/blink/renderer/platform/BUILD.gn
+++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -1648,6 +1648,8 @@ component("platform") {
@@ -1650,6 +1650,8 @@ component("platform") {
"widget/widget_base.h",
"widget/widget_base_client.h",
"windows_keyboard_codes.h",
@@ -267,7 +375,7 @@ index 59031b23d3c50aa87db48a5c5a66c5ab04a8103a..1f83cf0dff83d748bf1caafd3685202c
// A Corner is a axis-aligned quad, with the points ordered (start, outer,
diff --git a/third_party/blink/renderer/platform/geometry/path_builder.cc b/third_party/blink/renderer/platform/geometry/path_builder.cc
index 4a77f944e9ad0b18f10f1a572673769453473fb9..73a3fac1be9a8c29d1b3391bf05eef13df9415d9 100644
index ba1be7bc8070c2b97f343298261d597df70dfdaf..fe6e2adafe49082ae266c049c655a13e296ade17 100644
--- a/third_party/blink/renderer/platform/geometry/path_builder.cc
+++ b/third_party/blink/renderer/platform/geometry/path_builder.cc
@@ -4,6 +4,7 @@
@@ -278,7 +386,7 @@ index 4a77f944e9ad0b18f10f1a572673769453473fb9..73a3fac1be9a8c29d1b3391bf05eef13
#include "third_party/blink/renderer/platform/geometry/contoured_rect.h"
#include "third_party/blink/renderer/platform/geometry/infinite_int_rect.h"
#include "third_party/blink/renderer/platform/geometry/path.h"
@@ -248,6 +249,32 @@ PathBuilder& PathBuilder::AddContouredRect(
@@ -248,6 +249,26 @@ PathBuilder& PathBuilder::AddContouredRect(
AddRoundedRect(target_rect);
return *this;
}
@@ -294,35 +402,14 @@ index 4a77f944e9ad0b18f10f1a572673769453473fb9..73a3fac1be9a8c29d1b3391bf05eef13
+ float smoothness = std::clamp(
+ contoured_rect.GetCornerCurvature().Smoothness(), 0.0f, 1.0f);
+
+ // Since the Electron implementation of DrawSmoothRoundRect uses one radius
+ // for both dimensions, we need to use the minimum of the two supplied.
+ auto min_radius = [](const gfx::SizeF& radius) -> float {
+ return std::min(radius.width(), radius.height());
+ };
+
+ builder_.addPath(electron::DrawSmoothRoundRect(
+ box.x(), box.y(), box.width(), box.height(), smoothness,
+ min_radius(radii.TopLeft()), min_radius(radii.TopRight()),
+ min_radius(radii.BottomRight()), min_radius(radii.BottomLeft())));
+ radii.TopLeft().width(), radii.TopRight().width(),
+ radii.BottomRight().width(), radii.BottomLeft().width()));
+
+ return *this;
+ }
+
const FloatRoundedRect& origin_rect = contoured_rect.GetOriginRect();
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 382c9749aaaf2827b76c0a63df96e45a7c88b62b..88c2310c5cccfab7e5a3cdad54657bae185655dd 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 @@
},
data: [
+ {
+ name: "ElectronCSSCornerSmoothing",
+ status: "stable",
+ },
{
name: "Accelerated2dCanvas",
settable_from_internals: true,
// This would include the outer border of the rect, as well as shadow and

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