Compare commits

..

33 Commits

Author SHA1 Message Date
John Kleinschmidt
a0f51d816e build: update linux container (#44392) 2024-10-24 16:58:36 -04:00
Charles Kerr
83d7040096 fix: -Wunsafe-buffer-usage warning in didRegisterForRemoteNotificationsWithDeviceToken (#44348)
* chore: move as_byte_span() to new shell/common/mac_util.h

this way it can be used by multiple mm files

* fix: -Wunsafe-buffer-usage warnings in UNNotificationResponseToNSDictionary

* refactor: use base::HexEncode() instead of rolling our own

* fixup! chore: move as_byte_span() to new shell/common/mac_util.h

* fixup! chore: move as_byte_span() to new shell/common/mac_util.h

fix: move mac_util to the right place in filenames.gni
2024-10-23 14:18:22 -05:00
John Kleinschmidt
c42fb09fc9 test: fixup flaky tests (#44349)
* test: fixup flaky test

* test: disable flaky protocol speed test on macOS

* test: fixup flaky test in api-browser-window-spec.ts
2024-10-23 15:14:50 -04:00
Shelley Vohr
fd500477ac docs: clarify utilityProcess child.pid value (#44339) 2024-10-22 13:09:33 -04:00
electron-appveyor-updater[bot]
d60d526df6 build: update appveyor image to latest version (#44334)
Co-authored-by: electron-appveyor-updater[bot] <161660339+electron-appveyor-updater[bot]@users.noreply.github.com>
2024-10-22 10:40:00 -04:00
Charles Kerr
e3e94d45ee fix: silence -Wunsafe-buffer-usage warning in GetPreferredLanguages() (#44333)
fix: use UNSAFE_BUFFERS macro in GetPreferredLanguages()
2024-10-21 18:20:00 -05:00
Sam Maddock
fff6ea438a fix: software compositing infinite loop (#44318)
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
2024-10-21 18:56:03 -04:00
Robo
3e77faf2f7 fix: crash when generating shortcut text for super accelerator (#44341) 2024-10-22 03:26:38 +09:00
John Kleinschmidt
cc9d85d3ca build: fixup reclient use for prod builds (#44340) 2024-10-21 14:07:02 -04:00
electron-roller[bot]
d3d02ef111 chore: bump chromium to 132.0.6789.0 (main) (#44337)
chore: bump chromium in DEPS to 132.0.6789.0

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
2024-10-21 10:48:59 -04:00
electron-roller[bot]
e70f70f5b4 chore: bump chromium to 132.0.6788.0 (main) (#44331)
chore: bump chromium in DEPS to 132.0.6788.0

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
2024-10-20 23:54:06 -05:00
electron-roller[bot]
0d948da4b9 chore: bump chromium to 132.0.6787.0 (main) (#44329)
* chore: bump chromium in DEPS to 132.0.6785.0

* chore: bump chromium in DEPS to 132.0.6787.0

* 5837702: mac fullscreen: always show traffic lights

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

* 5892572: Move SimpleMenuModel out of ui/base

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

* 5938185: Remove lacros code from //ui/base/clipboard

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

* chore: fixup patch indices

* 5939514: Wire up the preference of overlay scrollbars to the ChromeOS settings

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

* chore: fixup patch indices

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2024-10-20 19:02:21 -05:00
dependabot[bot]
2cf59b3885 build(deps-dev): bump webpack from 5.94.0 to 5.95.0 (#44309)
Bumps [webpack](https://github.com/webpack/webpack) from 5.94.0 to 5.95.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.94.0...v5.95.0)

---
updated-dependencies:
- dependency-name: webpack
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-20 10:40:03 +02:00
Sam Maddock
87bd665e41 feat: expose frame & move properties to console-message event object (#43617)
* feat: expose frame on console-message event

refactor: use property names similar to ServiceWorker's console-message event

refactor: don't use deprecated params in tests

doc: console-message breaking change

chore: add deprecation warning

docs: restore deprecated argument descriptions

* move console-message deprecations to v34

---------

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2024-10-18 16:07:06 -04:00
John Beutner
35aeab6ecd fix: respect setAlwaysOnTop before showInactive on Linux under X11 (#44078)
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2024-10-18 14:29:52 -04:00
electron-roller[bot]
738533dec7 chore: bump chromium to 132.0.6783.0 (main) (#44307)
* chore: bump chromium in DEPS to 132.0.6782.0

* chore: bump chromium in DEPS to 132.0.6783.0

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2024-10-18 12:06:33 -04:00
electron-appveyor-updater[bot]
456aac1f94 build: update appveyor image to latest version (#44311)
Co-authored-by: electron-appveyor-updater[bot] <161660339+electron-appveyor-updater[bot]@users.noreply.github.com>
2024-10-18 11:24:24 -04:00
dependabot[bot]
6c6e5c002a build(deps): bump actions/upload-artifact from 4.4.0 to 4.4.3 (#44173)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.4.0 to 4.4.3.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](50769540e7...b4b15b8c7c)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-18 15:39:55 +02:00
electron-roller[bot]
089f233054 chore: bump chromium to 132.0.6781.0 (main) (#44301)
* chore: bump chromium in DEPS to 132.0.6781.0

* chore: update patches

* 5933789: [MappableSI] Remove kill-switch from RenderableGpuMemoryBufferVideoFramePool.

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

* 5938992: Reland: Remove `force_guest_profile` param from context getters.

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

* 5928743: spanification: Add WTF::String::FromUTF8(span<>) overloads

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

* 5898835: Update windows SDK version to 10.0.26100.1742

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

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2024-10-17 20:00:59 -04:00
dependabot[bot]
2b0624f2f1 build(deps-dev): bump remark-cli from 10.0.0 to 12.0.1 (#44258)
Bumps [remark-cli](https://github.com/remarkjs/remark) from 10.0.0 to 12.0.1.
- [Release notes](https://github.com/remarkjs/remark/releases)
- [Changelog](https://github.com/remarkjs/remark/blob/main/changelog.md)
- [Commits](https://github.com/remarkjs/remark/compare/10.0.0...remark-cli@12.0.1)

---
updated-dependencies:
- dependency-name: remark-cli
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-17 15:15:48 -04:00
Keeley Hammond
ac09d11ed1 build: fix main printing patch conflict (#44302)
build: update patches
2024-10-17 11:29:04 -04:00
John Kleinschmidt
9280add5b4 chore: fixup reclient read only access on forks (#44280) 2024-10-17 11:17:54 -04:00
Mayur
44c398fedb docs: removed AngularJS Batarang from the Devtool Extension Support (#44261)
docs: update Devtool Extension Support
2024-10-17 10:55:05 -04:00
David Sanders
cbc12d6675 ci: use Node.js 20 in Bake AppVeyor Image workflow (#44290)
* ci: use Node.js 20 in Bake AppVeyor Image workflow

* chore: add bake workflow to CODEOWNERS
2024-10-17 10:35:50 -04:00
electron-roller[bot]
d801bad5d2 chore: bump chromium to 132.0.6779.0 (main) (#44273)
* chore: bump chromium in DEPS to 132.0.6779.0

* chore: update patches

* 5904951: controlledframe: Disable File System Access for <controlledframe>

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

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2024-10-16 21:41:31 -04:00
Shelley Vohr
d386664900 build: use new Issue Template types in templates (#44224)
* build: use new Issue Template types in templates

* build: restore existing labels for now
2024-10-16 15:34:35 -04:00
David Sanders
67775d19ec build: remove dead code in prepare release script (#44256) 2024-10-16 15:05:09 -04:00
Shelley Vohr
cbe3cb770a fix: Linux crash after webContents.print() with no parent window (#44246)
fix: Linux crash after print with no parent window
2024-10-16 13:15:21 -04:00
Shelley Vohr
bd4ea5ba72 fix: use proper PDF save approach (#44248) 2024-10-16 11:33:21 -04:00
Robo
af6e2fb257 fix: trace-startup crashing child process on macOS (#44257) 2024-10-16 11:03:00 -04:00
Shelley Vohr
df45474b58 fix: ensure utilityProcess only emits one 'exit' event (#44243)
fix: ensure utilityProcess only emits one exit
2024-10-16 10:47:12 +02:00
Charles Kerr
b5acebf3ba fix: -Wunsafe-buffer-usage warnings in TaskbarHost::SetThumbarButtons() (#44238)
* fix: -Wunsafe-buffer-usage warnings in TaskbarHost::SetThumbarButtons()

* fixup! fix: -Wunsafe-buffer-usage warning in ChunkedDataPipeReadableStream (#44211)
2024-10-15 18:31:44 -05:00
electron-roller[bot]
ef84f13650 chore: bump chromium to 131.0.6778.0 (main) (#44251)
* chore: bump chromium in DEPS to 131.0.6778.0

* 5803393: [UI] Add alias for mojo version of `MenuSourceType`

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

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2024-10-15 16:41:14 -04:00
446 changed files with 4024 additions and 6013 deletions

3
.gitattributes vendored
View File

@@ -1,9 +1,6 @@
# `git apply` and friends don't understand CRLF, even on windows. Force those
# files to be checked out with LF endings even if core.autocrlf is true.
*.patch text eol=lf
DEPS text eol=lf
yarn.lock text eol=lf
script/zip_manifests/*.manifest text eol=lf
patches/**/.patches merge=union
# Source code and markdown files should always use LF as line ending.

1
.github/CODEOWNERS vendored
View File

@@ -8,6 +8,7 @@
DEPS @electron/wg-upgrades
# Releases WG
/.github/workflows/update_appveyor_image.yml @electron/wg-releases
/docs/breaking-changes.md @electron/wg-releases
/npm/ @electron/wg-releases
/script/release @electron/wg-releases

View File

@@ -1,6 +1,6 @@
name: Bug Report
description: Report an Electron bug
title: "[Bug]: "
description: Report a bug in Electron
type: 'bug'
labels: "bug :beetle:"
body:
- type: checkboxes

View File

@@ -1,6 +1,6 @@
name: Feature Request
description: Suggest an idea for Electron
title: "[Feature Request]: "
type: 'enhancement'
labels: "enhancement :sparkles:"
body:
- type: checkboxes

View File

@@ -5,10 +5,10 @@ inputs:
description: 'Target arch'
required: true
target-platform:
description: 'Target platform, should be linux, win, macos'
description: 'Target platform'
required: true
artifact-platform:
description: 'Artifact platform, should be linux, win, darwin or mas'
description: 'Artifact platform, should be linux, darwin or mas'
required: true
step-suffix:
description: 'Suffix for build steps'
@@ -63,7 +63,7 @@ runs:
run: |
cd src
electron/script/copy-debug-symbols.py --target-cpu="${{ inputs.target-arch }}" --out-dir=out/Default/debug --compress
electron/script/strip-binaries.py --target-cpu="${{ inputs.target-arch }}" --verbose
electron/script/strip-binaries.py --target-cpu="${{ inputs.target-arch }}"
electron/script/add-debug-link.py --target-cpu="${{ inputs.target-arch }}" --debug-dir=out/Default/debug
- name: Build Electron dist.zip ${{ inputs.step-suffix }}
shell: bash
@@ -71,7 +71,7 @@ runs:
cd src
e build --target electron:electron_dist_zip -j $NUMBER_OF_NINJA_PROCESSES
if [ "${{ inputs.is-asan }}" != "true" ]; then
target_os=${{ inputs.target-platform == 'macos' && 'mac' || inputs.target-platform }}
target_os=${{ inputs.target-platform == 'linux' && 'linux' || 'mac'}}
if [ "${{ inputs.artifact-platform }}" = "mas" ]; then
target_os="${target_os}_mas"
fi
@@ -82,7 +82,7 @@ runs:
run: |
cd src
e build --target electron:electron_mksnapshot -j $NUMBER_OF_NINJA_PROCESSES
ELECTRON_DEPOT_TOOLS_DISABLE_LOG=1 e d gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
# Remove unused args from mksnapshot_args
SEDOPTION="-i"
if [ "`uname`" = "Darwin" ]; then
@@ -91,7 +91,7 @@ runs:
sed $SEDOPTION '/.*builtins-pgo/d' out/Default/mksnapshot_args
sed $SEDOPTION '/--turbo-profiling-input/d' out/Default/mksnapshot_args
if [ "${{ inputs.target-platform }}" = "linux" ]; then
if [ "`uname`" = "Linux" ]; then
if [ "${{ inputs.target-arch }}" = "arm" ]; then
electron/script/strip-binaries.py --file $PWD/out/Default/clang_x86_v8_arm/mksnapshot
electron/script/strip-binaries.py --file $PWD/out/Default/clang_x86_v8_arm/v8_context_snapshot_generator
@@ -105,13 +105,7 @@ runs:
fi
e build --target electron:electron_mksnapshot_zip -j $NUMBER_OF_NINJA_PROCESSES
if [ "${{ inputs.target-platform }}" = "win" ]; then
cd out/Default
powershell Compress-Archive -update mksnapshot_args mksnapshot.zip
powershell Compress-Archive -update gen/v8/embedded.S mksnapshot.zip
else
(cd out/Default; zip mksnapshot.zip mksnapshot_args gen/v8/embedded.S)
fi
(cd out/Default; zip mksnapshot.zip mksnapshot_args gen/v8/embedded.S)
- name: Generate Cross-Arch Snapshot (arm/arm64) ${{ inputs.step-suffix }}
shell: bash
if: ${{ (inputs.target-arch == 'arm' || inputs.target-arch == 'arm64') && inputs.target-platform == 'linux' }}

View File

@@ -5,10 +5,6 @@ inputs:
description: 'Whether to generate and persist a SAS token for the item in the cache'
required: false
default: 'false'
use-cache:
description: 'Whether to persist the cache to the shared drive'
required: false
default: 'true'
runs:
using: "composite"
steps:
@@ -17,27 +13,31 @@ runs:
run: |
echo "GIT_CACHE_PATH=$(pwd)/git-cache" >> $GITHUB_ENV
- name: Install Dependencies
uses: ./src/electron/.github/actions/install-dependencies
- name: Install Build Tools
uses: ./src/electron/.github/actions/install-build-tools
shell: bash
run: |
cd src/electron
node script/yarn install --frozen-lockfile
- name: Get Depot Tools
shell: bash
run: |
if [[ ! -d depot_tools ]]; then
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
# Ensure depot_tools does not update.
test -d depot_tools && cd depot_tools
touch .disable_auto_update
fi
sed -i '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
# Remove swift-format dep from cipd on macOS until we send a patch upstream.
cd depot_tools
git apply --3way ../src/electron/.github/workflows/config/gclient.diff
# Ensure depot_tools does not update.
test -d depot_tools && cd depot_tools
touch .disable_auto_update
- name: Add Depot Tools to PATH
shell: bash
run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
- name: Generate DEPS Hash
shell: bash
run: |
node src/electron/script/generate-deps-hash.js
echo "DEPSHASH=v1-src-cache-$(cat src/electron/.depshash)" >> $GITHUB_ENV
node src/electron/script/generate-deps-hash.js && cat src/electron/.depshash-target
echo "DEPSHASH=v1-src-cache-$(shasum src/electron/.depshash | cut -f1 -d' ')" >> $GITHUB_ENV
- name: Generate SAS Key
if: ${{ inputs.generate-sas-token == 'true' }}
shell: bash
@@ -54,49 +54,27 @@ runs:
id: check-cache
shell: bash
run: |
if [[ "${{ inputs.use-cache }}" == "false" ]]; then
echo "Not using cache this time..."
cache_path=/mnt/cross-instance-cache/$DEPSHASH.tar
echo "Using cache key: $DEPSHASH"
echo "Checking for cache in: $cache_path"
if [ ! -f "$cache_path" ]; then
echo "cache_exists=false" >> $GITHUB_OUTPUT
echo "Cache Does Not Exist for $DEPSHASH"
else
cache_path=/mnt/cross-instance-cache/$DEPSHASH.tar
echo "Using cache key: $DEPSHASH"
echo "Checking for cache in: $cache_path"
if [ ! -f "$cache_path" ] || [ `du $cache_path | cut -f1` = "0" ]; then
echo "cache_exists=false" >> $GITHUB_OUTPUT
echo "Cache Does Not Exist for $DEPSHASH"
else
echo "cache_exists=true" >> $GITHUB_OUTPUT
echo "Cache Already Exists for $DEPSHASH, Skipping.."
fi
fi
- name: Check cross instance cache disk space
if: steps.check-cache.outputs.cache_exists == 'false' && inputs.use-cache == 'true'
shell: bash
run: |
# if there is less than 20 GB free space then creating the cache might fail so exit early
freespace=`df -m /mnt/cross-instance-cache | grep -w /mnt/cross-instance-cache | awk '{print $4}'`
freespace_human=`df -h /mnt/cross-instance-cache | grep -w /mnt/cross-instance-cache | awk '{print $4}'`
if [ $freespace -le 20000 ]; then
echo "The cross mount cache has $freespace_human free space which is not enough - exiting"
exit 1
else
echo "The cross mount cache has $freespace_human free space - continuing"
echo "cache_exists=true" >> $GITHUB_OUTPUT
echo "Cache Already Exists for $DEPSHASH, Skipping.."
fi
- name: Gclient Sync
if: steps.check-cache.outputs.cache_exists == 'false'
shell: bash
run: |
e d gclient config \
gclient config \
--name "src/electron" \
--unmanaged \
${GCLIENT_EXTRA_ARGS} \
"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY"
if [ "$TARGET_OS" != "" ]; then
echo "target_os=['$TARGET_OS']" >> ./.gclient
fi
ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES=1 e d gclient sync --with_branch_heads --with_tags -vv
ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES=1 gclient sync --with_branch_heads --with_tags -vvvvv
if [ "${{ inputs.is-release }}" != "true" && -n "${{ env.PATCH_UP_APP_CREDS }}" ]; then
# Re-export all the patches to check if there were changes.
python3 src/electron/script/export_all_patches.py src/electron/patches/config.json
@@ -137,13 +115,13 @@ runs:
# https://dawn-review.googlesource.com/c/dawn/+/83901
# TODO: maybe better to always leave out */.git/HEAD file for all targets ?
- name: Delete .git directories under src to free space
if: ${{ steps.check-cache.outputs.cache_exists == 'false' && inputs.use-cache == 'true' }}
if: steps.check-cache.outputs.cache_exists == 'false'
shell: bash
run: |
cd src
( find . -type d -name ".git" -not -path "./third_party/angle/*" -not -path "./third_party/dawn/*" -not -path "./electron/*" ) | xargs rm -rf
- name: Minimize Cache Size for Upload
if: ${{ steps.check-cache.outputs.cache_exists == 'false' && inputs.use-cache == 'true' }}
if: steps.check-cache.outputs.cache_exists == 'false'
shell: bash
run: |
rm -rf src/android_webview
@@ -154,12 +132,9 @@ runs:
rm -rf src/third_party/angle/third_party/VK-GL-CTS/src
rm -rf src/third_party/swift-toolchain
rm -rf src/third_party/swiftshader/tests/regres/testlists
cp src/electron/.github/actions/checkout/action.yml ./
rm -rf src/electron
mkdir -p src/electron/.github/actions/checkout
mv action.yml src/electron/.github/actions/checkout
- name: Compress Src Directory
if: ${{ steps.check-cache.outputs.cache_exists == 'false' && inputs.use-cache == 'true' }}
if: steps.check-cache.outputs.cache_exists == 'false'
shell: bash
run: |
echo "Uncompressed src size: $(du -sh src | cut -f1 -d' ')"
@@ -167,7 +142,7 @@ runs:
echo "Compressed src to $(du -sh $DEPSHASH.tar | cut -f1 -d' ')"
cp ./$DEPSHASH.tar /mnt/cross-instance-cache/
- name: Persist Src Cache
if: ${{ steps.check-cache.outputs.cache_exists == 'false' && inputs.use-cache == 'true' }}
if: steps.check-cache.outputs.cache_exists == 'false'
shell: bash
run: |
final_cache_path=/mnt/cross-instance-cache/$DEPSHASH.tar

View File

@@ -6,15 +6,6 @@ runs:
- name: Install Build Tools
shell: bash
run: |
if [ "$(expr substr $(uname -s) 1 10)" == "MSYS_NT-10" ]; then
git config --global core.filemode false
git config --global core.autocrlf false
git config --global branch.autosetuprebase always
fi
export BUILD_TOOLS_SHA=8246e57791b0af4ae5975eb96f09855f9269b1cd
export BUILD_TOOLS_SHA=eeb1a11392e4cec08fd926c93b31ab556dc0c23b
npm i -g @electron/build-tools
e auto-update disable
if [ "$(expr substr $(uname -s) 1 10)" == "MSYS_NT-10" ]; then
e d cipd.bat --version
cp "C:\Python37\python.exe" "C:\Python37\python3.exe"
fi

View File

@@ -1,21 +0,0 @@
name: 'Install Dependencies'
description: 'Installs yarn depdencies using cache when available'
runs:
using: "composite"
steps:
- name: Get yarn cache directory path
shell: bash
id: yarn-cache-dir-path
run: echo "dir=$(node src/electron/script/yarn cache dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('src/electron/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install Dependencies
shell: bash
run: |
cd src/electron
node script/yarn install --frozen-lockfile --prefer-offline

View File

@@ -17,11 +17,6 @@ runs:
fi
echo "Persisted cache is $(du -sh $cache_path | cut -f1)"
if [ `du $cache_path | cut -f1` = "0" ]; then
echo "Cache is empty - exiting"
exit 1
fi
mkdir temp-cache
tar -xf $cache_path -C temp-cache
echo "Unzipped cache is $(du -sh temp-cache/src | cut -f1)"

View File

@@ -44,11 +44,6 @@ runs:
shell: bash
run: |
echo "Downloaded cache is $(du -sh $DEPSHASH.tar | cut -f1)"
if [ `du $DEPSHASH.tar | cut -f1` = "0" ]; then
echo "Cache is empty - exiting"
exit 1
fi
mkdir temp-cache
tar -xf $DEPSHASH.tar -C temp-cache
echo "Unzipped cache is $(du -sh temp-cache/src | cut -f1)"

View File

@@ -41,7 +41,7 @@ jobs:
sha-file: .dig-old
filename: electron.old.d.ts
- name: Upload artifacts
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 #v4.4.0
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 #v4.4.3
with:
name: artifacts
path: electron/artifacts

View File

@@ -18,11 +18,6 @@ on:
description: 'Skip Linux builds'
default: false
required: false
skip-windows:
type: boolean
description: 'Skip Windows builds'
default: false
required: false
skip-lint:
type: boolean
description: 'Skip lint check'
@@ -33,11 +28,7 @@ on:
- main
- '[1-9][0-9]-x-y'
pull_request:
defaults:
run:
shell: bash
jobs:
setup:
runs-on: ubuntu-latest
@@ -49,9 +40,7 @@ jobs:
build-image-sha: ${{ steps.set-output.outputs.build-image-sha }}
docs-only: ${{ steps.set-output.outputs.docs-only }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.0.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.0.2
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: filter
with:
@@ -109,7 +98,6 @@ jobs:
with:
path: src/electron
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Checkout & Sync & Save
uses: ./src/electron/.github/actions/checkout
with:
@@ -136,68 +124,9 @@ jobs:
with:
path: src/electron
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Checkout & Sync & Save
uses: ./src/electron/.github/actions/checkout
checkout-windows:
needs: setup
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }}
runs-on: electron-arc-linux-amd64-32core
container:
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
options: --user root --device /dev/fuse --cap-add SYS_ADMIN
volumes:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
env:
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_win=True'
TARGET_OS: 'win'
ELECTRON_DEPOT_TOOLS_WIN_TOOLCHAIN: '1'
outputs:
build-image-sha: ${{ needs.setup.outputs.build-image-sha}}
steps:
- name: Checkout Electron
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
with:
path: src/electron
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Checkout & Sync & Save
uses: ./src/electron/.github/actions/checkout
# GN Check Jobs
macos-gn-check:
uses: ./.github/workflows/pipeline-segment-electron-gn-check.yml
needs: checkout-macos
with:
target-platform: macos
target-archs: x64 arm64
check-runs-on: macos-14
gn-build-type: testing
secrets: inherit
linux-gn-check:
uses: ./.github/workflows/pipeline-segment-electron-gn-check.yml
needs: checkout-linux
with:
target-platform: linux
target-archs: x64 arm arm64
check-runs-on: electron-arc-linux-amd64-8core
check-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
gn-build-type: testing
secrets: inherit
windows-gn-check:
uses: ./.github/workflows/pipeline-segment-electron-gn-check.yml
needs: checkout-windows
with:
target-platform: win
target-archs: x64 x86 arm64
check-runs-on: electron-arc-linux-amd64-8core
check-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-windows.outputs.build-image-sha }}","options":"--user root --device /dev/fuse --cap-add SYS_ADMIN","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
gn-build-type: testing
secrets: inherit
# Build Jobs - These cascade into testing jobs
macos-x64:
permissions:
@@ -208,6 +137,7 @@ jobs:
needs: checkout-macos
with:
build-runs-on: macos-14-xlarge
check-runs-on: macos-14
test-runs-on: macos-13
target-platform: macos
target-arch: x64
@@ -226,6 +156,7 @@ jobs:
needs: checkout-macos
with:
build-runs-on: macos-14-xlarge
check-runs-on: macos-14
test-runs-on: macos-14
target-platform: macos
target-arch: arm64
@@ -244,6 +175,7 @@ jobs:
needs: checkout-linux
with:
build-runs-on: electron-arc-linux-amd64-32core
check-runs-on: electron-arc-linux-amd64-8core
test-runs-on: electron-arc-linux-amd64-4core
build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
test-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init"}'
@@ -264,6 +196,7 @@ jobs:
needs: checkout-linux
with:
build-runs-on: electron-arc-linux-amd64-32core
check-runs-on: electron-arc-linux-amd64-8core
test-runs-on: electron-arc-linux-amd64-4core
build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
test-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init"}'
@@ -285,6 +218,7 @@ jobs:
needs: checkout-linux
with:
build-runs-on: electron-arc-linux-amd64-32core
check-runs-on: electron-arc-linux-amd64-8core
test-runs-on: electron-arc-linux-arm64-4core
build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
test-container: '{"image":"ghcr.io/electron/test:arm32v7-${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init","volumes":["/home/runner/externals:/mnt/runner-externals"]}'
@@ -305,6 +239,7 @@ jobs:
needs: checkout-linux
with:
build-runs-on: electron-arc-linux-amd64-32core
check-runs-on: electron-arc-linux-amd64-8core
test-runs-on: electron-arc-linux-arm64-4core
build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
test-container: '{"image":"ghcr.io/electron/test:arm64v8-${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init"}'
@@ -315,70 +250,3 @@ jobs:
generate-symbols: false
upload-to-storage: '0'
secrets: inherit
windows-x64:
permissions:
contents: read
issues: read
pull-requests: read
uses: ./.github/workflows/pipeline-electron-build-and-test.yml
needs: setup
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }}
with:
build-runs-on: electron-arc-windows-amd64-16core
test-runs-on: windows-latest
target-platform: win
target-arch: x64
is-release: false
gn-build-type: testing
generate-symbols: false
upload-to-storage: '0'
secrets: inherit
windows-x86:
permissions:
contents: read
issues: read
pull-requests: read
uses: ./.github/workflows/pipeline-electron-build-and-test.yml
needs: setup
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }}
with:
build-runs-on: electron-arc-windows-amd64-16core
test-runs-on: windows-latest
target-platform: win
target-arch: x86
is-release: false
gn-build-type: testing
generate-symbols: false
upload-to-storage: '0'
secrets: inherit
windows-arm64:
permissions:
contents: read
issues: read
pull-requests: read
uses: ./.github/workflows/pipeline-electron-build-and-test.yml
needs: setup
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }}
with:
build-runs-on: electron-arc-windows-amd64-16core
test-runs-on: electron-hosted-windows-arm64-4core
target-platform: win
target-arch: arm64
is-release: false
gn-build-type: testing
generate-symbols: false
upload-to-storage: '0'
secrets: inherit
gha-done:
name: GitHub Actions Completed
runs-on: ubuntu-latest
needs: [docs-only, macos-x64, macos-arm64, linux-x64, linux-x64-asan, linux-arm, linux-arm64, windows-x64, windows-x86, windows-arm64]
if: always() && !contains(needs.*.result, 'failure')
steps:
- name: GitHub Actions Jobs Done
run: |
echo "All GitHub Actions Jobs are done"

View File

@@ -1,21 +0,0 @@
name: Clean Source Cache
on:
schedule:
- cron: "0 0 * * SUN" # Run at midnight every Sunday
jobs:
clean-src-cache:
runs-on: electron-arc-linux-amd64-32core
container:
image: ghcr.io/electron/build:bc2f48b2415a670de18d13605b1cf0eb5fdbaae1
options: --user root
volumes:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
steps:
- name: Cleanup Source Cache
shell: bash
run: |
df -h /mnt/cross-instance-cache
find /mnt/cross-instance-cache -type f -mtime +30 -delete
df -h /mnt/cross-instance-cache

14
.github/workflows/config/gclient.diff vendored Normal file
View File

@@ -0,0 +1,14 @@
diff --git a/gclient.py b/gclient.py
index 59e2b4c5197928bdba1ef69bdbe637d7dfe471c1..b4bae5e48c83c84bd867187afaf40eed16e69851 100755
--- a/gclient.py
+++ b/gclient.py
@@ -783,7 +783,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
not condition or "non_git_source" not in condition):
continue
cipd_root = self.GetCipdRoot()
- for package in dep_value.get('packages', []):
+ packages = dep_value.get('packages', [])
+ for package in (x for x in packages if "infra/3pp/tools/swift-format" not in x.get('package')):
deps_to_add.append(
CipdDependency(parent=self,
name=name,

View File

@@ -5,7 +5,7 @@ on:
inputs:
target-platform:
type: string
description: 'Platform to run on, can be macos, win or linux.'
description: 'Platform to run on, can be macos or linux'
required: true
target-arch:
type: string
@@ -15,6 +15,10 @@ on:
type: string
description: 'What host to run the build'
required: true
check-runs-on:
type: string
description: 'What host to run the gn-check'
required: true
test-runs-on:
type: string
description: 'What host to run the tests on'
@@ -72,6 +76,16 @@ jobs:
generate-symbols: ${{ inputs.generate-symbols }}
upload-to-storage: ${{ inputs.upload-to-storage }}
secrets: inherit
gn-check:
uses: ./.github/workflows/pipeline-segment-electron-gn-check.yml
with:
target-platform: ${{ inputs.target-platform }}
target-arch: ${{ inputs.target-arch }}
check-runs-on: ${{ inputs.check-runs-on }}
check-container: ${{ inputs.build-container }}
gn-build-type: ${{ inputs.gn-build-type }}
is-asan: ${{ inputs.is-asan }}
secrets: inherit
test:
uses: ./.github/workflows/pipeline-segment-electron-test.yml
needs: build

View File

@@ -5,7 +5,7 @@ on:
inputs:
target-platform:
type: string
description: 'Platform to run on, can be macos, win or linux'
description: 'Platform to run on, can be macos or linux'
required: true
target-arch:
type: string
@@ -15,6 +15,10 @@ on:
type: string
description: 'What host to run the build'
required: true
check-runs-on:
type: string
description: 'What host to run the gn-check'
required: true
test-runs-on:
type: string
description: 'What host to run the tests on'
@@ -78,6 +82,16 @@ jobs:
upload-to-storage: ${{ inputs.upload-to-storage }}
is-asan: ${{ inputs.is-asan}}
secrets: inherit
gn-check:
uses: ./.github/workflows/pipeline-segment-electron-gn-check.yml
with:
target-platform: ${{ inputs.target-platform }}
target-arch: ${{ inputs.target-arch }}
check-runs-on: ${{ inputs.check-runs-on }}
check-container: ${{ inputs.build-container }}
gn-build-type: ${{ inputs.gn-build-type }}
is-asan: ${{ inputs.is-asan }}
secrets: inherit
test:
uses: ./.github/workflows/pipeline-segment-electron-test.yml
needs: build

View File

@@ -24,9 +24,10 @@ jobs:
with:
path: src/electron
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Install Dependencies
uses: ./src/electron/.github/actions/install-dependencies
run: |
cd src/electron
node script/yarn install --frozen-lockfile
- name: Run TS/JS compile
shell: bash
run: |

View File

@@ -24,9 +24,10 @@ jobs:
with:
path: src/electron
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Install Dependencies
uses: ./src/electron/.github/actions/install-dependencies
run: |
cd src/electron
node script/yarn install --frozen-lockfile
- name: Setup third_party Depot Tools
shell: bash
run: |

View File

@@ -9,7 +9,7 @@ on:
type: string
target-platform:
type: string
description: 'Platform to run on, can be macos, win or linux'
description: 'Platform to run on, can be macos or linux'
required: true
target-arch:
type: string
@@ -69,14 +69,11 @@ env:
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
SUDOWOODO_EXCHANGE_URL: ${{ secrets.SUDOWOODO_EXCHANGE_URL }}
SUDOWOODO_EXCHANGE_TOKEN: ${{ secrets.SUDOWOODO_EXCHANGE_TOKEN }}
GCLIENT_EXTRA_ARGS: ${{ inputs.target-platform == 'macos' && '--custom-var=checkout_mac=True --custom-var=host_os=mac' || inputs.target-platform == 'win' && '--custom-var=checkout_win=True' || '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True' }}
GCLIENT_EXTRA_ARGS: ${{ inputs.target-platform == 'macos' && '--custom-var=checkout_mac=True --custom-var=host_os=mac' || '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True' }}
ELECTRON_OUT_DIR: Default
jobs:
build:
defaults:
run:
shell: bash
runs-on: ${{ inputs.build-runs-on }}
container: ${{ fromJSON(inputs.build-container) }}
environment: ${{ inputs.environment }}
@@ -84,14 +81,12 @@ jobs:
TARGET_ARCH: ${{ inputs.target-arch }}
steps:
- name: Create src dir
run: |
mkdir src
run: mkdir src
- name: Checkout Electron
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
with:
path: src/electron
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Free up space (macOS)
if: ${{ inputs.target-platform == 'macos' }}
uses: ./src/electron/.github/actions/free-space-macos
@@ -106,7 +101,9 @@ jobs:
cache: yarn
cache-dependency-path: src/electron/yarn.lock
- name: Install Dependencies
uses: ./src/electron/.github/actions/install-dependencies
run: |
cd src/electron
node script/yarn install --frozen-lockfile
- name: Install AZCopy
if: ${{ inputs.target-platform == 'macos' }}
run: brew install azcopy
@@ -140,13 +137,16 @@ jobs:
# Ensure depot_tools does not update.
test -d depot_tools && cd depot_tools
if [ "`uname`" = "Linux" ]; then
git apply --3way ../src/electron/.github/workflows/config/gclient.diff
fi
touch .disable_auto_update
- name: Add Depot Tools to PATH
run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
- name: Generate DEPS Hash
run: |
node src/electron/script/generate-deps-hash.js
DEPSHASH=v1-src-cache-$(cat src/electron/.depshash)
node src/electron/script/generate-deps-hash.js && cat src/electron/.depshash-target
DEPSHASH=v1-src-cache-$(shasum src/electron/.depshash | cut -f1 -d' ')
echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
echo "CACHE_PATH=$DEPSHASH.tar" >> $GITHUB_ENV
- name: Restore src cache via AZCopy
@@ -155,17 +155,11 @@ jobs:
- name: Restore src cache via AKS
if: ${{ inputs.target-platform == 'linux' }}
uses: ./src/electron/.github/actions/restore-cache-aks
- name: Checkout src via gclient sync
if: ${{ inputs.target-platform == 'win' }}
uses: ./src/electron/.github/actions/checkout
with:
use-cache: 'false'
- name: Checkout Electron
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
with:
path: src/electron
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Install Build Tools
uses: ./src/electron/.github/actions/install-build-tools
- name: Init Build Tools
@@ -173,11 +167,11 @@ jobs:
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} --import ${{ inputs.gn-build-type }} --target-cpu ${{ inputs.target-arch }}
- name: Run Electron Only Hooks
run: |
e d gclient runhooks --spec="solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]"
gclient runhooks --spec="solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]"
- name: Regenerate DEPS Hash
run: |
(cd src/electron && git checkout .) && node src/electron/script/generate-deps-hash.js
echo "DEPSHASH=$(cat src/electron/.depshash)" >> $GITHUB_ENV
(cd src/electron && git checkout .) && node src/electron/script/generate-deps-hash.js && cat src/electron/.depshash-target
echo "DEPSHASH=$(shasum src/electron/.depshash | cut -f1 -d' ')" >> $GITHUB_ENV
- name: Add CHROMIUM_BUILDTOOLS_PATH to env
run: echo "CHROMIUM_BUILDTOOLS_PATH=$(pwd)/src/buildtools" >> $GITHUB_ENV
- name: Fix Sync (macOS)
@@ -185,7 +179,7 @@ jobs:
uses: ./src/electron/.github/actions/fix-sync-macos
- name: Setup Number of Ninja Processes
run: |
echo "NUMBER_OF_NINJA_PROCESSES=${{ inputs.target-platform != 'macos' && '300' || '200' }}" >> $GITHUB_ENV
echo "NUMBER_OF_NINJA_PROCESSES=${{ inputs.target-platform == 'linux' && '300' || '200' }}" >> $GITHUB_ENV
- name: Free up space (macOS)
if: ${{ inputs.target-platform == 'macos' }}
uses: ./src/electron/.github/actions/free-space-macos
@@ -195,7 +189,7 @@ jobs:
with:
target-arch: ${{ inputs.target-arch }}
target-platform: ${{ inputs.target-platform }}
artifact-platform: ${{ inputs.target-platform == 'macos' && 'darwin' || inputs.target-platform }}
artifact-platform: ${{ inputs.target-platform == 'linux' && 'linux' || 'darwin' }}
is-release: '${{ inputs.is-release }}'
generate-symbols: '${{ inputs.generate-symbols }}'
strip-binaries: '${{ inputs.strip-binaries }}'

View File

@@ -5,11 +5,11 @@ on:
inputs:
target-platform:
type: string
description: 'Platform to run on, can be macos, win or linux'
description: 'Platform to run on, can be macos or linux'
required: true
target-archs:
target-arch:
type: string
description: 'Archs to check for, can be x64, x86, arm64 or arm space separated'
description: 'Arch to build for, can be x64, arm64 or arm'
required: true
check-runs-on:
type: string
@@ -25,30 +25,35 @@ on:
required: true
type: string
default: testing
is-asan:
description: 'Building the Address Sanitizer (ASan) Linux build'
required: false
type: boolean
default: false
concurrency:
group: electron-gn-check-${{ inputs.target-platform }}-${{ github.ref }}
group: electron-gn-check-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ inputs.is-asan }}-${{ github.ref }}
cancel-in-progress: true
env:
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
GCLIENT_EXTRA_ARGS: ${{ inputs.target-platform == 'macos' && '--custom-var=checkout_mac=True --custom-var=host_os=mac' || (inputs.target-platform == 'linux' && '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True' || '--custom-var=checkout_win=True') }}
GCLIENT_EXTRA_ARGS: ${{ inputs.target-platform == 'macos' && '--custom-var=checkout_mac=True --custom-var=host_os=mac' || '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True' }}
ELECTRON_OUT_DIR: Default
TARGET_ARCH: ${{ inputs.target-arch }}
jobs:
gn-check:
defaults:
run:
shell: bash
# TODO(codebytere): Change this to medium VM
runs-on: ${{ inputs.check-runs-on }}
container: ${{ fromJSON(inputs.check-container) }}
env:
TARGET_ARCH: ${{ inputs.target-arch }}
steps:
- name: Checkout Electron
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
with:
path: src/electron
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Cleanup disk space on macOS
if: ${{ inputs.target-platform == 'macos' }}
shell: bash
@@ -68,40 +73,58 @@ jobs:
run: df -h
- name: Install Build Tools
uses: ./src/electron/.github/actions/install-build-tools
- name: Enable windows toolchain
if: ${{ inputs.target-platform == 'win' }}
- name: Init Build Tools
run: |
echo "ELECTRON_DEPOT_TOOLS_WIN_TOOLCHAIN=1" >> $GITHUB_ENV
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} --import ${{ inputs.gn-build-type }} --target-cpu ${{ inputs.target-arch }}
- name: Get Depot Tools
timeout-minutes: 5
run: |
git clone --filter=tree:0 https://chromium.googlesource.com/chromium/tools/depot_tools.git
SEDOPTION="-i"
if [ "`uname`" = "Darwin" ]; then
SEDOPTION="-i ''"
fi
# remove ninjalog_uploader_wrapper.py from autoninja since we don't use it and it causes problems
sed $SEDOPTION '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
# Ensure depot_tools does not update.
test -d depot_tools && cd depot_tools
if [ "`uname`" = "Linux" ]; then
git apply --3way ../src/electron/.github/workflows/config/gclient.diff
fi
touch .disable_auto_update
- name: Add Depot Tools to PATH
run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
- name: Set GN_EXTRA_ARGS for Linux
if: ${{ inputs.target-platform == 'linux' }}
run: |
if [ "${{ inputs.target-arch }}" = "arm" ]; then
GN_EXTRA_ARGS='build_tflite_with_xnnpack=false'
elif [ "${{ inputs.target-arch }}" = "arm64" ]; then
GN_EXTRA_ARGS='fatal_linker_warnings=false enable_linux_installer=false'
fi
echo "GN_EXTRA_ARGS=$GN_EXTRA_ARGS" >> $GITHUB_ENV
- name: Generate DEPS Hash
run: |
node src/electron/script/generate-deps-hash.js
DEPSHASH=v1-src-cache-$(cat src/electron/.depshash)
node src/electron/script/generate-deps-hash.js && cat src/electron/.depshash-target
DEPSHASH=v1-src-cache-$(shasum src/electron/.depshash | cut -f1 -d' ')
echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
echo "CACHE_PATH=$DEPSHASH.tar" >> $GITHUB_ENV
- name: Restore src cache via AZCopy
if: ${{ inputs.target-platform == 'macos' }}
uses: ./src/electron/.github/actions/restore-cache-azcopy
- name: Restore src cache via AKS
if: ${{ inputs.target-platform == 'linux' || inputs.target-platform == 'win' }}
if: ${{ inputs.target-platform == 'linux' }}
uses: ./src/electron/.github/actions/restore-cache-aks
- name: Run Electron Only Hooks
run: |
echo "solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]" > tmpgclient
if [ "${{ inputs.target-platform }}" = "win" ]; then
echo "solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False,'install_sysroot':False,'checkout_win':True},'managed':False}]" > tmpgclient
echo "target_os=['win']" >> tmpgclient
fi
e d gclient runhooks --gclientfile=tmpgclient
# Fix VS Toolchain
if [ "${{ inputs.target-platform }}" = "win" ]; then
rm -rf src/third_party/depot_tools/win_toolchain/vs_files
e d python3 src/build/vs_toolchain.py update --force
fi
gclient runhooks --spec="solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]"
- name: Regenerate DEPS Hash
run: |
(cd src/electron && git checkout .) && node src/electron/script/generate-deps-hash.js
echo "DEPSHASH=$(cat src/electron/.depshash)" >> $GITHUB_ENV
(cd src/electron && git checkout .) && node src/electron/script/generate-deps-hash.js && cat src/electron/.depshash-target
echo "DEPSHASH=$(shasum src/electron/.depshash | cut -f1 -d' ')" >> $GITHUB_ENV
- name: Add CHROMIUM_BUILDTOOLS_PATH to env
run: echo "CHROMIUM_BUILDTOOLS_PATH=$(pwd)/src/buildtools" >> $GITHUB_ENV
- name: Checkout Electron
@@ -109,46 +132,26 @@ jobs:
with:
path: src/electron
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Install Dependencies
uses: ./src/electron/.github/actions/install-dependencies
- name: Default GN gen
run: |
cd src/electron
git pack-refs
- name: Run GN Check for ${{ inputs.target-archs }}
cd ..
e build --only-gen
- name: Run GN Check
run: |
for target_cpu in ${{ inputs.target-archs }}
do
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} --import ${{ inputs.gn-build-type }} --target-cpu $target_cpu
cd src
export GN_EXTRA_ARGS="target_cpu=\"$target_cpu\""
if [ "${{ inputs.target-platform }}" = "linux" ]; then
if [ "$target_cpu" = "arm" ]; then
export GN_EXTRA_ARGS="$GN_EXTRA_ARGS build_tflite_with_xnnpack=false"
elif [ "$target_cpu" = "arm64" ]; then
export GN_EXTRA_ARGS="$GN_EXTRA_ARGS fatal_linker_warnings=false enable_linux_installer=false"
fi
fi
if [ "${{ inputs.target-platform }}" = "win" ]; then
export GN_EXTRA_ARGS="$GN_EXTRA_ARGS use_v8_context_snapshot=true target_os=\"win\""
fi
cd src
gn check out/Default //electron:electron_lib
gn check out/Default //electron:electron_app
gn check out/Default //electron/shell/common:mojo
gn check out/Default //electron/shell/common:plugin
e build --only-gen
e d gn check out/Default //electron:electron_lib
e d gn check out/Default //electron:electron_app
e d gn check out/Default //electron/shell/common:mojo
e d gn check out/Default //electron/shell/common:plugin
# Check the hunspell filenames
node electron/script/gen-hunspell-filenames.js --check
node electron/script/gen-libc++-filenames.js --check
cd ..
done
# Check the hunspell filenames
node electron/script/gen-hunspell-filenames.js --check
node electron/script/gen-libc++-filenames.js --check
- name: Wait for active SSH sessions
if: always() && !cancelled()
shell: bash
run: |
while [ -f /var/.ssh-lock ]
do

View File

@@ -5,7 +5,7 @@ on:
inputs:
target-platform:
type: string
description: 'Platform to run on, can be macos, win or linux'
description: 'Platform to run on, can be macos or linux'
required: true
target-arch:
type: string
@@ -41,44 +41,22 @@ env:
jobs:
test:
defaults:
run:
shell: bash
runs-on: ${{ inputs.test-runs-on }}
container: ${{ fromJSON(inputs.test-container) }}
strategy:
fail-fast: false
matrix:
build-type: ${{ inputs.target-platform == 'macos' && fromJSON('["darwin","mas"]') || (inputs.target-platform == 'win' && fromJSON('["win"]') || fromJSON('["linux"]')) }}
shard: ${{ inputs.target-platform == 'linux' && fromJSON('[1, 2, 3]') || fromJSON('[1, 2]') }}
build-type: ${{ inputs.target-platform == 'macos' && fromJSON('["darwin","mas"]') || fromJSON('["linux"]') }}
shard: ${{ inputs.target-platform == 'macos' && fromJSON('[1, 2]') || fromJSON('[1, 2, 3]') }}
env:
BUILD_TYPE: ${{ matrix.build-type }}
TARGET_ARCH: ${{ inputs.target-arch }}
ARTIFACT_KEY: ${{ matrix.build-type }}_${{ inputs.target-arch }}
steps:
- name: Fix node20 on arm32 runners
if: ${{ inputs.target-arch == 'arm' && inputs.target-platform == 'linux' }}
if: ${{ inputs.target-arch == 'arm' }}
run: |
cp $(which node) /mnt/runner-externals/node20/bin/
- name: Install Git on Windows arm64 runners
if: ${{ inputs.target-arch == 'arm64' && inputs.target-platform == 'win' }}
shell: powershell
run: |
Set-ExecutionPolicy Bypass -Scope Process -Force
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
choco install -y --no-progress git.install --params "'/GitAndUnixToolsOnPath'"
choco install -y --no-progress git
choco install -y --no-progress python --version 3.11.9
choco install -y --no-progress visualstudio2022-workload-vctools --package-parameters "--add Microsoft.VisualStudio.Component.VC.Tools.ARM64"
echo "C:\Program Files\Git\cmd" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
echo "C:\Program Files\Git\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
echo "C:\Python311" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Setup Node.js/npm
if: ${{ inputs.target-platform == 'win' }}
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6
with:
node-version: 20.11.x
- name: Add TCC permissions on macOS
if: ${{ inputs.target-platform == 'macos' }}
run: |
@@ -117,18 +95,24 @@ jobs:
with:
path: src/electron
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Install Dependencies
uses: ./src/electron/.github/actions/install-dependencies
run: |
cd src/electron
node script/yarn install --frozen-lockfile
- name: Get Depot Tools
timeout-minutes: 5
run: |
git config --global core.filemode false
git config --global core.autocrlf false
git config --global branch.autosetuprebase always
git clone --filter=tree:0 https://chromium.googlesource.com/chromium/tools/depot_tools.git
# Ensure depot_tools does not update.
test -d depot_tools && cd depot_tools
if [ "`uname`" = "Darwin" ]; then
# remove ninjalog_uploader_wrapper.py from autoninja since we don't use it and it causes problems
sed -i '' '/ninjalog_uploader_wrapper.py/d' ./autoninja
else
sed -i '/ninjalog_uploader_wrapper.py/d' ./autoninja
# Remove swift-format dep from cipd on macOS until we send a patch upstream.
git apply --3way ../src/electron/.github/workflows/config/gclient.diff
fi
touch .disable_auto_update
- name: Add Depot Tools to PATH
run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
@@ -150,17 +134,7 @@ jobs:
path: ./src_artifacts_${{ matrix.build-type }}_${{ inputs.target-arch }}
- name: Restore Generated Artifacts
run: ./src/electron/script/actions/restore-artifacts.sh
- name: Unzip Dist, Mksnapshot & Chromedriver (win)
if: ${{ inputs.target-platform == 'win' }}
shell: powershell
run: |
Set-ExecutionPolicy Bypass -Scope Process -Force
cd src/out/Default
Expand-Archive -Force dist.zip -DestinationPath ./
Expand-Archive -Force chromedriver.zip -DestinationPath ./
Expand-Archive -Force mksnapshot.zip -DestinationPath ./
- name: Unzip Dist, Mksnapshot & Chromedriver (unix)
if: ${{ inputs.target-platform != 'win' }}
- name: Unzip Dist, Mksnapshot & Chromedriver
run: |
cd src/out/Default
unzip -:o dist.zip
@@ -184,24 +158,15 @@ jobs:
ELECTRON_DISABLE_SECURITY_WARNINGS: 1
ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
DISPLAY: ':99.0'
NPM_CONFIG_MSVS_VERSION: '2022'
run: |
cd src/electron
export ELECTRON_TEST_RESULTS_DIR=`pwd`/junit
# Get which tests are on this shard
tests_files=$(node script/split-tests ${{ matrix.shard }} ${{ inputs.target-platform == 'linux' && 3 || 2 }})
tests_files=$(node script/split-tests ${{ matrix.shard }} ${{ inputs.target-platform == 'macos' && 2 || 3 }})
# Run tests
if [ "${{ inputs.target-platform }}" != "linux" ]; then
if [ "`uname`" = "Darwin" ]; then
echo "About to start tests"
if [ "${{ inputs.target-platform }}" = "win" ]; then
if [ "${{ inputs.target-arch }}" = "x86" ]; then
export npm_config_arch="ia32"
fi
if [ "${{ inputs.target-arch }}" = "arm64" ]; then
export ELECTRON_FORCE_TEST_SUITE_EXIT="true"
fi
fi
node script/yarn test --runners=main --trace-uncaught --enable-logging --files $tests_files
else
chown :builduser .. && chmod g+w ..
@@ -232,21 +197,19 @@ jobs:
DD_CIVISIBILITY_LOGS_ENABLED: true
DD_TAGS: "os.architecture:${{ inputs.target-arch }},os.family:${{ inputs.target-platform }},os.platform:${{ inputs.target-platform }},asan:${{ inputs.is-asan }}"
run: |
if ! [ -z $DD_API_KEY ] && [ -f src/electron/junit/test-results-main.xml ]; then
export DATADOG_PATH=`node src/electron/script/yarn global bin`
$DATADOG_PATH/datadog-ci junit upload src/electron/junit/test-results-main.xml
if ! [ -z $DD_API_KEY ]; then
datadog-ci junit upload src/electron/junit/test-results-main.xml
fi
if: always() && !cancelled()
- name: Upload Test Artifacts
if: always() && !cancelled()
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882
with:
name: test_artifacts_${{ env.ARTIFACT_KEY }}_${{ matrix.shard }}
name: test_artifacts_${{ env.ARTIFACT_KEY }}
path: src/electron/spec/artifacts
if-no-files-found: ignore
- name: Wait for active SSH sessions
if: always() && !cancelled()
shell: bash
run: |
while [ -f /var/.ssh-lock ]
do

View File

@@ -5,7 +5,7 @@ on:
inputs:
target-platform:
type: string
description: 'Platform to run on, can be macos, win or linux'
description: 'Platform to run on, can be macos or linux'
required: true
target-arch:
type: string
@@ -49,20 +49,23 @@ jobs:
with:
path: src/electron
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Install Build Tools
uses: ./src/electron/.github/actions/install-build-tools
- name: Init Build Tools
run: |
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} --import ${{ inputs.gn-build-type }} --target-cpu ${{ inputs.target-arch }}
- name: Install Dependencies
uses: ./src/electron/.github/actions/install-dependencies
run: |
cd src/electron
node script/yarn install --frozen-lockfile
- name: Get Depot Tools
timeout-minutes: 5
run: |
git clone --filter=tree:0 https://chromium.googlesource.com/chromium/tools/depot_tools.git
sed -i '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
# Ensure depot_tools does not update.
test -d depot_tools && cd depot_tools
git apply --3way ../src/electron/.github/workflows/config/gclient.diff
touch .disable_auto_update
- name: Add Depot Tools to PATH
run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
@@ -90,7 +93,6 @@ jobs:
node electron/script/node-spec-runner.js --default --jUnitDir=junit
- name: Wait for active SSH sessions
if: always() && !cancelled()
shell: bash
run: |
while [ -f /var/.ssh-lock ]
do
@@ -110,20 +112,23 @@ jobs:
with:
path: src/electron
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Install Build Tools
uses: ./src/electron/.github/actions/install-build-tools
- name: Init Build Tools
run: |
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }}
- name: Install Dependencies
uses: ./src/electron/.github/actions/install-dependencies
run: |
cd src/electron
node script/yarn install --frozen-lockfile
- name: Get Depot Tools
timeout-minutes: 5
run: |
git clone --filter=tree:0 https://chromium.googlesource.com/chromium/tools/depot_tools.git
sed -i '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
# Ensure depot_tools does not update.
test -d depot_tools && cd depot_tools
git apply --3way ../src/electron/.github/workflows/config/gclient.diff
touch .disable_auto_update
- name: Add Depot Tools to PATH
run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
@@ -150,7 +155,6 @@ jobs:
cd src
node electron/script/nan-spec-runner.js
- name: Wait for active SSH sessions
shell: bash
if: always() && !cancelled()
run: |
while [ -f /var/.ssh-lock ]

View File

@@ -42,7 +42,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: SARIF file
path: results.sarif

View File

@@ -23,9 +23,8 @@ jobs:
with:
fetch-depth: 0
token: ${{ steps.generate-token.outputs.token }}
ref: ${{ github.event.pull_request.head.sha }}
- name: Setup Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
with:
node-version: 20.11.x
- name: Yarn install

1
.gitignore vendored
View File

@@ -48,6 +48,7 @@ ts-gen
# Used to accelerate CI builds
.depshash
.depshash-target
# Used to accelerate builds after sync
patches/mtime-cache.json

View File

@@ -5,9 +5,6 @@
"autolink": false,
"shortcut": false
},
"MD049": {
"style": "underscore"
},
"no-angle-brackets": true,
"no-curly-braces": true,
"no-inline-html": {

View File

@@ -518,10 +518,7 @@ source_set("electron_lib") {
"//third_party/blink/renderer",
]
defines = [
"BLINK_MOJO_IMPL=1",
"V8_DEPRECATION_WARNINGS",
]
defines = [ "V8_DEPRECATION_WARNINGS" ]
libs = []
if (is_linux) {

View File

@@ -12,7 +12,7 @@ propose changes to this document in a pull request.
## [Issues](https://electronjs.org/docs/development/issues)
Issues are created [here](https://github.com/electron/electron/issues/new/choose).
Issues are created [here](https://github.com/electron/electron/issues/new).
* [How to Contribute in Issues](https://electronjs.org/docs/development/issues#how-to-contribute-in-issues)
* [Asking for General Help](https://electronjs.org/docs/development/issues#asking-for-general-help)

4
DEPS
View File

@@ -2,9 +2,9 @@ gclient_gn_args_from = 'src'
vars = {
'chromium_version':
'132.0.6834.83',
'132.0.6789.0',
'node_version':
'v20.18.1',
'v20.18.0',
'nan_version':
'e14bdcd1f72d62bca1d541b66da43130384ec213',
'squirrel.mac_version':

View File

@@ -29,7 +29,7 @@
version: 1.0.{build}
build_cloud: electronhq-16-core
image: e-132.0.6824.0
image: e-132.0.6788.0
environment:
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
ELECTRON_OUT_DIR: Default
@@ -39,7 +39,7 @@ environment:
MOCHA_MULTI_REPORTERS: "@marshallofsound/mocha-appveyor-reporter, mocha-junit-reporter, tap"
DEPOT_TOOLS_WIN_TOOLCHAIN: 1
DEPOT_TOOLS_WIN_TOOLCHAIN_BASE_URL: "https://dev-cdn.electronjs.org/windows-toolchains/_"
GYP_MSVS_HASH_7393122652: 3ba76c5c20
GYP_MSVS_HASH_698eb5635a: e2bf90edff
PYTHONIOENCODING: UTF-8
matrix:

View File

@@ -29,7 +29,7 @@
version: 1.0.{build}
build_cloud: electronhq-16-core
image: e-132.0.6824.0
image: e-132.0.6788.0
environment:
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
ELECTRON_OUT_DIR: Default
@@ -39,7 +39,7 @@ environment:
MOCHA_MULTI_REPORTERS: "@marshallofsound/mocha-appveyor-reporter, mocha-junit-reporter, tap"
DEPOT_TOOLS_WIN_TOOLCHAIN: 1
DEPOT_TOOLS_WIN_TOOLCHAIN_BASE_URL: "https://dev-cdn.electronjs.org/windows-toolchains/_"
GYP_MSVS_HASH_7393122652: 3ba76c5c20
GYP_MSVS_HASH_698eb5635a: e2bf90edff
PYTHONIOENCODING: UTF-8
matrix:
@@ -187,12 +187,7 @@ for:
7z a pdb.zip out\Default\*.pdb
}
- ps: |
if ($env:TARGET_ARCH -eq 'ia32') {
$env:MANIFEST_ARCH = "x86"
} else {
$env:MANIFEST_ARCH = $env:TARGET_ARCH
}
$manifest_file = "electron/script/zip_manifests/dist_zip.win.$env:MANIFEST_ARCH.manifest"
$manifest_file = "electron/script/zip_manifests/dist_zip.win.$env:TARGET_ARCH.manifest"
python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip $manifest_file
if ($LASTEXITCODE -ne 0) {
throw "Zip contains files not listed in the manifest $manifest_file"

View File

@@ -2,7 +2,7 @@ import os
import re
import sys
DEFINE_EXTRACT_REGEX = re.compile(r'^ *# *define (\w*)', re.MULTILINE)
DEFINE_EXTRACT_REGEX = re.compile('^ *# *define (\w*)', re.MULTILINE)
def main(out_dir, headers):
defines = []

View File

@@ -59,7 +59,7 @@ def skip_path(dep, dist_zip, target_cpu):
and dep == "snapshot_blob.bin"
)
)
if should_skip and os.environ.get('ELECTRON_DEBUG_ZIP_SKIP') == '1':
if should_skip:
print("Skipping {}".format(dep))
return should_skip

View File

@@ -160,12 +160,14 @@ static_library("chrome") {
"//chrome/browser/icon_loader_win.cc",
"//chrome/browser/media/webrtc/window_icon_util_win.cc",
"//chrome/browser/process_singleton_win.cc",
"//chrome/browser/ui/frame/window_frame_util.h",
"//chrome/browser/win/chrome_process_finder.cc",
"//chrome/browser/win/chrome_process_finder.h",
"//chrome/browser/win/chrome_select_file_dialog_factory.cc",
"//chrome/browser/win/chrome_select_file_dialog_factory.h",
"//chrome/browser/win/titlebar_config.cc",
"//chrome/browser/win/titlebar_config.h",
"//chrome/browser/win/titlebar_config.h",
"//chrome/browser/win/util_win_service.cc",
"//chrome/browser/win/util_win_service.h",
"//chrome/child/v8_crashpad_support_win.cc",
@@ -180,14 +182,13 @@ static_library("chrome") {
public_deps = [
"//chrome/browser:dev_ui_browser_resources",
"//chrome/browser/resources/accessibility:resources",
"//chrome/browser/ui/color:color_headers",
"//chrome/browser/ui/color:mixers",
"//chrome/common",
"//chrome/common:version_header",
"//components/global_media_controls",
"//components/keyed_service/content",
"//components/paint_preview/buildflags",
"//components/proxy_config",
"//components/services/language_detection/public/mojom",
"//content/public/browser",
"//services/strings",
]

View File

@@ -21,6 +21,7 @@ an issue:
### Getting started
* [Introduction](tutorial/introduction.md)
* [Quick Start](tutorial/quick-start.md)
* [Process Model](tutorial/process-model.md)
### Learning the basics

18
docs/api/app.md Normal file → Executable file
View File

@@ -416,7 +416,7 @@ Returns:
* `launch-failed` - Process never successfully launched
* `integrity-failure` - Windows code integrity checks failed
* `exitCode` number - The exit code for the process
(e.g. status from waitpid if on POSIX, from GetExitCodeProcess on Windows).
(e.g. status from waitpid if on posix, from GetExitCodeProcess on Windows).
* `serviceName` string (optional) - The non-localized name of the process.
* `name` string (optional) - The name of the process.
Examples for utility: `Audio Service`, `Content Decryption Module Service`, `Network Service`, `Video Capture`, etc.
@@ -514,20 +514,20 @@ and `will-quit` events will not be emitted.
* `args` string[] (optional)
* `execPath` string (optional)
Relaunches the app when the current instance exits.
Relaunches the app when current instance exits.
By default, the new instance will use the same working directory and command line
arguments as the current instance. When `args` is specified, the `args` will be
passed as the command line arguments instead. When `execPath` is specified, the
`execPath` will be executed for the relaunch instead of the current app.
arguments with current instance. When `args` is specified, the `args` will be
passed as command line arguments instead. When `execPath` is specified, the
`execPath` will be executed for relaunch instead of current app.
Note that this method does not quit the app when executed. You have to call
Note that this method does not quit the app when executed, you have to call
`app.quit` or `app.exit` after calling `app.relaunch` to make the app restart.
When `app.relaunch` is called multiple times, multiple instances will be
started after the current instance exits.
When `app.relaunch` is called for multiple times, multiple instances will be
started after current instance exited.
An example of restarting the current instance immediately and adding a new command
An example of restarting current instance immediately and adding a new command
line argument to the new instance:
```js

View File

@@ -38,7 +38,7 @@ Without `*` prefix the URL has to match exactly.
### --disable-ntlm-v2
Disables NTLM v2 for POSIX platforms, no effect elsewhere.
Disables NTLM v2 for posix platforms, no effect elsewhere.
### --disable-http-cache
@@ -241,13 +241,6 @@ Force using discrete GPU when there are multiple GPUs available.
Force using integrated GPU when there are multiple GPUs available.
### --xdg-portal-required-version=`version`
Sets the minimum required version of XDG portal implementation to `version`
in order to use the portal backend for file dialogs on linux. File dialogs
will fallback to using gtk or kde depending on the desktop environment when
the required version is unavailable. Current default is set to `3`.
## Node.js Flags
Electron supports some of the [CLI flags][node-cli] supported by Node.js.

View File

@@ -78,11 +78,6 @@ dialog.showOpenDialogSync(mainWindow, {
})
```
**Note:** On Linux `defaultPath` is not supported when using portal file chooser
dialogs unless the portal backend is version 4 or higher. You can use `--xdg-portal-required-version`
[command-line switch](./command-line-switches.md#--xdg-portal-required-versionversion)
to force gtk or kde dialogs.
### `dialog.showOpenDialog([window, ]options)`
* `window` [BaseWindow](base-window.md) (optional)
@@ -155,11 +150,6 @@ dialog.showOpenDialog(mainWindow, {
})
```
**Note:** On Linux `defaultPath` is not supported when using portal file chooser
dialogs unless the portal backend is version 4 or higher. You can use `--xdg-portal-required-version`
[command-line switch](./command-line-switches.md#--xdg-portal-required-versionversion)
to force gtk or kde dialogs.
### `dialog.showSaveDialogSync([window, ]options)`
* `window` [BaseWindow](base-window.md) (optional)

View File

@@ -32,7 +32,7 @@ process, see [webContents.send][web-contents-send] for more information.
## Methods
The `ipcMain` module has the following methods to listen for events:
The `ipcMain` module has the following method to listen for events:
### `ipcMain.on(channel, listener)`
@@ -44,16 +44,6 @@ The `ipcMain` module has the following methods to listen for events:
Listens to `channel`, when a new message arrives `listener` would be called with
`listener(event, args...)`.
### `ipcMain.off(channel, listener)`
* `channel` string
* `listener` Function
* `event` [IpcMainEvent][ipc-main-event]
* `...args` any[]
Removes the specified `listener` from the listener array for the specified
`channel`.
### `ipcMain.once(channel, listener)`
* `channel` string
@@ -64,28 +54,20 @@ Removes the specified `listener` from the listener array for the specified
Adds a one time `listener` function for the event. This `listener` is invoked
only the next time a message is sent to `channel`, after which it is removed.
### `ipcMain.addListener(channel, listener)`
* `channel` string
* `listener` Function
* `event` [IpcMainEvent][ipc-main-event]
* `...args` any[]
Alias for [`ipcMain.on`](#ipcmainonchannel-listener).
### `ipcMain.removeListener(channel, listener)`
* `channel` string
* `listener` Function
* `...args` any[]
Alias for [`ipcMain.off`](#ipcmainoffchannel-listener).
Removes the specified `listener` from the listener array for the specified
`channel`.
### `ipcMain.removeAllListeners([channel])`
* `channel` string (optional)
Removes all listeners from the specified `channel`. Removes all listeners from all channels if no channel is specified.
Removes listeners of the specified `channel`.
### `ipcMain.handle(channel, listener)`

View File

@@ -48,8 +48,7 @@ Listens to `channel`, when a new message arrives `listener` would be called with
* `event` [IpcRendererEvent][ipc-renderer-event]
* `...args` any[]
Removes the specified `listener` from the listener array for the specified
`channel`.
Alias for [`ipcRenderer.removeListener`](#ipcrendererremovelistenerchannel-listener).
### `ipcRenderer.once(channel, listener)`
@@ -77,13 +76,14 @@ Alias for [`ipcRenderer.on`](#ipcrendereronchannel-listener).
* `event` [IpcRendererEvent][ipc-renderer-event]
* `...args` any[]
Alias for [`ipcRenderer.off`](#ipcrendereroffchannel-listener).
Removes the specified `listener` from the listener array for the specified
`channel`.
### `ipcRenderer.removeAllListeners([channel])`
### `ipcRenderer.removeAllListeners(channel)`
* `channel` string (optional)
* `channel` string
Removes all listeners from the specified `channel`. Removes all listeners from all channels if no channel is specified.
Removes all listeners, or those of the specified `channel`.
### `ipcRenderer.send(channel, ...args)`

View File

@@ -72,7 +72,7 @@ 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.
* `window` [BrowserWindow](browser-window.md) (optional) - Default is the focused window.
* `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.
@@ -86,13 +86,13 @@ The `menu` object has the following instance methods:
Can be `none`, `mouse`, `keyboard`, `touch`, `touchMenu`, `longPress`, `longTap`, `touchHandle`, `stylus`, `adjustSelection`, or `adjustSelectionReset`.
* `callback` Function (optional) - Called when menu is closed.
Pops up this menu as a context menu in the [`BaseWindow`](base-window.md).
Pops up this menu as a context menu in the [`BrowserWindow`](browser-window.md).
#### `menu.closePopup([window])`
#### `menu.closePopup([browserWindow])`
* `window` [BaseWindow](base-window.md) (optional) - Default is the focused window.
* `browserWindow` [BrowserWindow](browser-window.md) (optional) - Default is the focused window.
Closes the context menu in the `window`.
Closes the context menu in the `browserWindow`.
#### `menu.append(menuItem)`

View File

@@ -27,8 +27,7 @@ The `session` module has the following methods:
* `partition` string
* `options` Object (optional)
* `cache` boolean - Whether to enable cache. Default is `true` unless the
[`--disable-http-cache` switch](command-line-switches.md#--disable-http-cache) is used.
* `cache` boolean - Whether to enable cache.
Returns `Session` - A session instance from `partition` string. When there is an existing
`Session` with the same `partition`, it will be returned; otherwise a new
@@ -47,8 +46,7 @@ of an existing `Session` object.
* `path` string
* `options` Object (optional)
* `cache` boolean - Whether to enable cache. Default is `true` unless the
[`--disable-http-cache` switch](command-line-switches.md#--disable-http-cache) is used.
* `cache` boolean - Whether to enable cache.
Returns `Session` - A session instance from the absolute path as specified by the `path`
string. When there is an existing `Session` with the same absolute path, it
@@ -1360,36 +1358,6 @@ specified when registering the protocol.
Returns `Promise<void>` - resolves when the code cache clear operation is complete.
#### `ses.getSharedDictionaryUsageInfo()`
Returns `Promise<SharedDictionaryUsageInfo[]>` - an array of shared dictionary information entries in Chromium's networking service's storage.
Shared dictionaries are used to power advanced compression of data sent over the wire, specifically with Brotli and ZStandard. You don't need to call any of the shared dictionary APIs in Electron to make use of this advanced web feature, but if you do, they allow deeper control and inspection of the shared dictionaries used during decompression.
To get detailed information about a specific shared dictionary entry, call `getSharedDictionaryInfo(options)`.
#### `ses.getSharedDictionaryInfo(options)`
* `options` Object
* `frameOrigin` string - The origin of the frame where the request originates. Its specific to the individual frame making the request and is defined by its scheme, host, and port. In practice, will look like a URL.
* `topFrameSite` string - The site of the top-level browsing context (the main frame or tab that contains the request). Its less granular than `frameOrigin` and focuses on the broader "site" scope. In practice, will look like a URL.
Returns `Promise<SharedDictionaryInfo[]>` - an array of shared dictionary information entries in Chromium's networking service's storage.
To get information about all present shared dictionaries, call `getSharedDictionaryUsageInfo()`.
#### `ses.clearSharedDictionaryCache()`
Returns `Promise<void>` - resolves when the dictionary cache has been cleared, both in memory and on disk.
#### `ses.clearSharedDictionaryCacheForIsolationKey(options)`
* `options` Object
* `frameOrigin` string - The origin of the frame where the request originates. Its specific to the individual frame making the request and is defined by its scheme, host, and port. In practice, will look like a URL.
* `topFrameSite` string - The site of the top-level browsing context (the main frame or tab that contains the request). Its less granular than `frameOrigin` and focuses on the broader "site" scope. In practice, will look like a URL.
Returns `Promise<void>` - resolves when the dictionary cache has been cleared for the specified isolation key, both in memory and on disk.
#### `ses.setSpellCheckerEnabled(enable)`
* `enable` boolean
@@ -1539,11 +1507,9 @@ session is persisted on disk. For in memory sessions this returns `null`.
#### `ses.clearData([options])`
* `options` Object (optional)
* `dataTypes` String[] (optional) - The types of data to clear. By default, this will clear all types of data. This
can potentially include data types not explicitly listed here. (See Chromium's
[`BrowsingDataRemover`][browsing-data-remover] for the full list.)
* `dataTypes` String[] (optional) - The types of data to clear. By default, this will clear all types of data.
* `backgroundFetch` - Background Fetch
* `cache` - Cache (includes `cachestorage` and `shadercache`)
* `cache` - Cache
* `cookies` - Cookies
* `downloads` - Downloads
* `fileSystems` - File Systems
@@ -1567,9 +1533,7 @@ This method clears more types of data and is more thorough than the
**Note:** Cookies are stored at a broader scope than origins. When removing cookies and filtering by `origins` (or `excludeOrigins`), the cookies will be removed at the [registrable domain](https://url.spec.whatwg.org/#host-registrable-domain) level. For example, clearing cookies for the origin `https://really.specific.origin.example.com/` will end up clearing all cookies for `example.com`. Clearing cookies for the origin `https://my.website.example.co.uk/` will end up clearing all cookies for `example.co.uk`.
**Note:** Clearing cache data will also clear the shared dictionary cache. This means that any dictionaries used for compression may be reloaded after clearing the cache. If you wish to clear the shared dictionary cache but leave other cached data intact, you may want to use the `clearSharedDictionaryCache` method.
For more information, refer to Chromium's [`BrowsingDataRemover` interface][browsing-data-remover].
For more information, refer to Chromium's [`BrowsingDataRemover` interface](https://source.chromium.org/chromium/chromium/src/+/main:content/public/browser/browsing_data_remover.h).
### Instance Properties
@@ -1635,5 +1599,3 @@ app.whenReady().then(async () => {
console.log('Net-logs written to', path)
})
```
[browsing-data-remover]: https://source.chromium.org/chromium/chromium/src/+/main:content/public/browser/browsing_data_remover.h

View File

@@ -36,7 +36,7 @@ Open the given file in the desktop's default manner.
### `shell.openExternal(url[, options])`
* `url` string - Max 2081 characters on Windows.
* `url` string - Max 2081 characters on windows.
* `options` Object (optional)
* `activate` boolean (optional) _macOS_ - `true` to bring the opened application to the foreground. The default is `true`.
* `workingDirectory` string (optional) _Windows_ - The working directory.

View File

@@ -49,7 +49,7 @@
* `show` boolean (optional) - Whether window should be shown when created. Default is
`true`.
* `frame` boolean (optional) - Specify `false` to create a
[frameless window](../../tutorial/custom-window-styles.md#frameless-windows). Default is `true`.
[frameless window](../../tutorial/window-customization.md#create-frameless-windows). Default is `true`.
* `parent` BaseWindow (optional) - Specify parent window. Default is `null`.
* `modal` boolean (optional) - Whether this is a modal window. This only works when the
window is a child window. Default is `false`.
@@ -70,7 +70,7 @@
is only implemented on Windows and macOS.
* `darkTheme` boolean (optional) - Forces using dark theme for the window, only works on
some GTK+3 desktop environments. Default is `false`.
* `transparent` boolean (optional) - Makes the window [transparent](../../tutorial/custom-window-styles.md#transparent-windows).
* `transparent` boolean (optional) - Makes the window [transparent](../../tutorial/window-customization.md#create-transparent-windows).
Default is `false`. On Windows, does not work unless the window is frameless.
* `type` string (optional) - The type of window, default is normal window. See more about
this below.

View File

@@ -1,12 +0,0 @@
# SharedDictionaryInfo Object
* `match` string - The matching path pattern for the dictionary which was declared in 'use-as-dictionary' response header's `match` option.
* `matchDestinations` string[] - An array of matching destinations for the dictionary which was declared in 'use-as-dictionary' response header's `match-dest` option.
* `id` string - The Id for the dictionary which was declared in 'use-as-dictionary' response header's `id` option.
* `dictionaryUrl` string - URL of the dictionary.
* `lastFetchTime` Date - The time of when the dictionary was received from the network layer.
* `responseTime` Date - The time of when the dictionary was received from the server. For cached responses, this time could be "far" in the past.
* `expirationDuration` number - The expiration time for the dictionary which was declared in 'use-as-dictionary' response header's `expires` option in seconds.
* `lastUsedTime` Date - The time when the dictionary was last used.
* `size` number - The amount of bytes stored for this shared dictionary information object in Chromium's internal storage (usually Sqlite).
* `hash` string - The sha256 hash of the dictionary binary.

View File

@@ -1,5 +0,0 @@
# SharedDictionaryUsageInfo Object
* `frameOrigin` string - The origin of the frame where the request originates. Its specific to the individual frame making the request and is defined by its scheme, host, and port. In practice, will look like a URL.
* `topFrameSite` string - The site of the top-level browsing context (the main frame or tab that contains the request). Its less granular than `frameOrigin` and focuses on the broader "site" scope. In practice, will look like a URL.
* `totalSizeBytes` number - The amount of bytes stored for this shared dictionary information object in Chromium's internal storage (usually Sqlite).

View File

@@ -37,10 +37,7 @@ Process: [Main](../glossary.md#main-process)<br />
to load unsigned libraries. Unless you specifically need this capability, it is best to leave this disabled.
Default is `false`.
* `respondToAuthRequestsFromMainProcess` boolean (optional) - With this flag, all HTTP 401 and 407 network
requests created via the [net module](net.md) will allow responding to them via the
[`app#login`](app.md#event-login) event in the main process instead of the default
[`login`](client-request.md#event-login) event on the [`ClientRequest`](client-request.md) object. Default is
`false`.
requests created via the [net module](net.md) will allow responding to them via the [`app#login`](app.md#event-login) event in the main process instead of the default [`login`](client-request.md#event-login) event on the [`ClientRequest`](client-request.md) object.
Returns [`UtilityProcess`](utility-process.md#class-utilityprocess)
@@ -95,8 +92,6 @@ the child process exits, then the value is `undefined` after the `exit` event is
```js
const child = utilityProcess.fork(path.join(__dirname, 'test.js'))
console.log(child.pid) // undefined
child.on('spawn', () => {
console.log(child.pid) // Integer
})
@@ -106,8 +101,6 @@ child.on('exit', () => {
})
```
**Note:** You can use the `pid` to determine if the process is currently running.
#### `child.stdout`
A `NodeJS.ReadableStream | null` that represents the child process's stdout.
@@ -154,7 +147,7 @@ child process terminates.
Returns:
* `code` number - Contains the exit code for
the process obtained from waitpid on POSIX, or GetExitCodeProcess on Windows.
the process obtained from waitpid on posix, or GetExitCodeProcess on windows.
Emitted after the child process ends.

View File

@@ -955,11 +955,17 @@ Emitted when a `<webview>` has been attached to this web contents.
Returns:
* `event` Event
* `level` Integer - The log level, from 0 to 3. In order it matches `verbose`, `info`, `warning` and `error`.
* `message` string - The actual console message
* `line` Integer - The line number of the source that triggered this console message
* `sourceId` string
* `details` Event\<\>
* `message` string - Message text
* `level` string - Message severity
Possible values include `info`, `warning`, `error`, and `debug`.
* `lineNumber` Integer - Line number in the log source
* `sourceId` string - URL of the log source
* `frame` WebFrameMain - Frame that logged the message
* `level` Integer _Deprecated_ - The log level, from 0 to 3. In order it matches `verbose`, `info`, `warning` and `error`.
* `message` string _Deprecated_ - The actual console message
* `line` Integer _Deprecated_ - The line number of the source that triggered this console message
* `sourceId` string _Deprecated_
Emitted when the associated window logs a console message.

View File

@@ -142,29 +142,6 @@ ipcRenderer.on('port', (e, msg) => {
})
```
#### `frame.collectJavaScriptCallStack()` _Experimental_
Returns `Promise<string> | Promise<void>` - A promise that resolves with the currently running JavaScript call
stack. If no JavaScript runs in the frame, the promise will never resolve. In cases where the call stack is
otherwise unable to be collected, it will return `undefined`.
This can be useful to determine why the frame is unresponsive in cases where there's long-running JavaScript.
For more information, see the [proposed Crash Reporting API.](https://wicg.github.io/crash-reporting/)
```js
const { app } = require('electron')
app.commandLine.appendSwitch('enable-features', 'DocumentPolicyIncludeJSCallStacksInCrashReports')
app.on('web-contents-created', (_, webContents) => {
webContents.on('unresponsive', async () => {
// Interrupt execution and collect call stack from unresponsive renderer
const callStack = await webContents.mainFrame.collectJavaScriptCallStack()
console.log('Renderer unresponsive\n', callStack)
})
})
```
### Instance Properties
#### `frame.ipc` _Readonly_

View File

@@ -182,7 +182,7 @@ dispatch errors of isolated worlds to foreign worlds.
### `webFrame.setIsolatedWorldInfo(worldId, info)`
* `worldId` Integer - The ID of the world to run the javascript in, `0` is the default world, `999` is the world used by Electron's `contextIsolation` feature. Chrome extensions reserve the range of IDs in `[1 << 20, 1 << 29)`. You can provide any integer here.
* `worldId` Integer - The ID of the world to run the javascript in, `0` is the default world, `999` is the world used by Electrons `contextIsolation` feature. Chrome extensions reserve the range of IDs in `[1 << 20, 1 << 29)`. You can provide any integer here.
* `info` Object
* `securityOrigin` string (optional) - Security origin for the isolated world.
* `csp` string (optional) - Content Security Policy for the isolated world.

View File

@@ -12,7 +12,7 @@ This document uses the following convention to categorize breaking changes:
* **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
* **Removed:** An API or feature was removed, and is no longer supported by Electron.
## Planned Breaking API Changes (35.0)
## Planned Breaking API Changes (34.0)
### Deprecated: `level`, `message`, `line`, and `sourceId` arguments in `console-message` event on `WebContents`
@@ -29,14 +29,6 @@ webContents.on('console-message', ({ level, message, lineNumber, sourceId, frame
Additionally, `level` is now a string with possible values of `info`, `warning`, `error`, and `debug`.
## Planned Breaking API Changes (34.0)
### Behavior Changed: menu bar will be hidden during fullscreen on Windows
This brings the behavior to parity with Linux. Prior behavior: Menu bar is still visible during fullscreen on Windows. New behavior: Menu bar is hidden during fullscreen on Windows.
**Correction**: This was previously listed as a breaking change in Electron 33, but was first released in Electron 34.
## Planned Breaking API Changes (33.0)
### Behavior Changed: frame properties may retrieve detached WebFrameMain instances or none at all
@@ -94,6 +86,10 @@ mainWindow.loadURL('data:text/html,<script src="loaded-from-dataurl.js"></script
mainWindow.loadURL('other://index.html')
```
### Behavior Changed: menu bar will be hidden during fullscreen on Windows
This brings the behavior to parity with Linux. Prior behavior: Menu bar is still visible during fullscreen on Windows. New behavior: Menu bar is hidden during fullscreen on Windows.
### Behavior Changed: `webContents` property on `login` on `app`
The `webContents` property in the `login` event from `app` will be `null`
@@ -132,14 +128,14 @@ The nonstandard `path` property of the Web `File` object was added in an early v
```js
// Before (renderer)
const file = document.querySelector('input[type=file]').files[0]
const file = document.querySelector('input[type=file]')
alert(`Uploaded file path was: ${file.path}`)
```
```js
// After (renderer)
const file = document.querySelector('input[type=file]').files[0]
const file = document.querySelector('input[type=file]')
electron.showFilePath(file)
// (preload)

View File

@@ -1,6 +1,6 @@
# Experimental APIs
Some of Electron's APIs are tagged with `_Experimental_` in the documentation.
Some of Electrons APIs are tagged with `_Experimental_` in the documentation.
This tag indicates that the API may not be considered stable and the API may
be removed or modified more frequently than other APIs with less warning.

View File

@@ -11,7 +11,7 @@
<button id="clickme">Test Bluetooth</button>
<button id="cancel">Cancel Bluetooth Request</button>
<p>Currently selected bluetooth device: <strong id="device-name"></strong></p>
<p>Currently selected bluetooth device: <strong id="device-name""></strong></p>
<script src="./renderer.js"></script>
</body>

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'; style-src 'self' 'unsafe-inline'">
<link href="./styles.css" rel="stylesheet">
<title>Custom Titlebar App</title>
</head>
<body>
<!-- mount your title bar at the top of you application's body tag -->
<div class="titlebar">Cool titlebar</div>
</body>
</html>

View File

@@ -1,16 +0,0 @@
const { app, BrowserWindow } = require('electron')
function createWindow () {
const win = new BrowserWindow({
// remove the default titlebar
titleBarStyle: 'hidden',
// expose window controlls in Windows/Linux
...(process.platform !== 'darwin' ? { titleBarOverlay: true } : {})
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
})

View File

@@ -1,12 +0,0 @@
body {
margin: 0;
}
.titlebar {
height: 30px;
background: blue;
color: white;
display: flex;
justify-content: center;
align-items: center;
app-region: drag;
}

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'; style-src 'self' 'unsafe-inline'">
<link href="./styles.css" rel="stylesheet">
<title>Custom Titlebar App</title>
</head>
<body>
<!-- mount your title bar at the top of you application's body tag -->
<div class="titlebar">Cool titlebar</div>
</body>
</html>

View File

@@ -1,16 +0,0 @@
const { app, BrowserWindow } = require('electron')
function createWindow () {
const win = new BrowserWindow({
// remove the default titlebar
titleBarStyle: 'hidden',
// expose window controlls in Windows/Linux
...(process.platform !== 'darwin' ? { titleBarOverlay: true } : {})
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
})

View File

@@ -1,12 +0,0 @@
body {
margin: 0;
}
.titlebar {
height: 30px;
background: blue;
color: white;
display: flex;
justify-content: center;
align-items: center;
}

View File

@@ -1,15 +0,0 @@
const { app, BrowserWindow } = require('electron')
function createWindow () {
const win = new BrowserWindow({
// remove the default titlebar
titleBarStyle: 'hidden',
// expose window controlls in Windows/Linux
...(process.platform !== 'darwin' ? { titleBarOverlay: true } : {})
})
win.loadURL('https://example.com')
}
app.whenReady().then(() => {
createWindow()
})

View File

@@ -1,13 +0,0 @@
const { app, BrowserWindow } = require('electron')
function createWindow () {
const win = new BrowserWindow({
// remove the default titlebar
titleBarStyle: 'hidden'
})
win.loadURL('https://example.com')
}
app.whenReady().then(() => {
createWindow()
})

View File

@@ -1,10 +0,0 @@
const { app, BrowserWindow } = require('electron')
function createWindow () {
const win = new BrowserWindow({})
win.loadURL('https://example.com')
}
app.whenReady().then(() => {
createWindow()
})

View File

@@ -1,14 +0,0 @@
const { app, BrowserWindow } = require('electron')
function createWindow () {
const win = new BrowserWindow({
width: 300,
height: 200,
frame: false
})
win.loadURL('https://example.com')
}
app.whenReady().then(() => {
createWindow()
})

View File

@@ -1,15 +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'; style-src 'self' 'unsafe-inline'">
<link href="./styles.css" rel="stylesheet">
<title>Transparent Hello World</title>
</head>
<body>
<div class="white-circle">
<div>Hello World!</div>
</div>
</body>
</html>

View File

@@ -1,16 +0,0 @@
const { app, BrowserWindow } = require('electron')
function createWindow () {
const win = new BrowserWindow({
width: 100,
height: 100,
resizable: false,
frame: false,
transparent: true
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
})

View File

@@ -1,16 +0,0 @@
body {
margin: 0;
padding: 0;
background-color: rgba(0, 0, 0, 0); /* Transparent background */
}
.white-circle {
width: 100px;
height: 100px;
background-color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
app-region: drag;
user-select: none;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 412 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

View File

@@ -1,176 +0,0 @@
# Custom Title Bar
## Basic tutorial
Application windows have a default [chrome][] applied by the OS. Not to be confused
with the Google Chrome browser, window _chrome_ refers to the parts of the window (e.g.
title bar, toolbars, controls) that are not a part of the main web content. While the
default title bar provided by the OS chrome is sufficent for simple use cases, many
applications opt to remove it. Implementing a custom title bar can help your application
feel more modern and consistent across platforms.
You can follow along with this tutorial by opening Fiddle with the following starter code.
```fiddle docs/fiddles/features/window-customization/custom-title-bar/starter-code
```
### Remove the default title bar
Lets start by configuring a window with native window controls and a hidden title bar.
To remove the default title bar, set the [`BaseWindowContructorOptions`][] `titleBarStyle`
param in the `BrowserWindow` constructor to `'hidden'`.
```fiddle docs/fiddles/features/window-customization/custom-title-bar/remove-title-bar
```
### Add native window controls _Windows_ _Linux_
On macOS, setting `titleBarStyle: 'hidden'` removes the title bar while keeping the windows
traffic light controls available in the upper left hand corner. However on Windows and Linux,
youll need to add window controls back into your `BrowserWindow` by setting the
[`BaseWindowContructorOptions`][] `titleBarOverlay` param in the `BrowserWindow` constructor.
```fiddle docs/fiddles/features/window-customization/custom-title-bar/native-window-controls
```
Setting `titleBarOverlay: true` is the simplest way to expose window controls back into
your `BrowserWindow`. If youre interested in customizing the window controls further,
check out the sections [Custom traffic lights][] and [Custom window controls][] that cover
this in more detail.
### Create a custom title bar
Now, lets implement a simple custom title bar in the `webContents` of our `BrowserWindow`.
Theres nothing fancy here, just HTML and CSS!
```fiddle docs/fiddles/features/window-customization/custom-title-bar/custom-title-bar
```
Currently our application window cant be moved. Since weve removed the default title bar,
the application needs to tell Electron which regions are draggable. Well do this by adding
the CSS style `app-region: drag` to the custom title bar. Now we can drag the custom title
bar to reposition our app window!
```fiddle docs/fiddles/features/window-customization/custom-title-bar/custom-drag-region
```
For more information around how to manage drag regions defined by your electron application,
see the [Custom draggable regions][] section below.
Congratulations, you've just implemented a basic custom title bar!
## Advanced window customization
### Custom traffic lights _macOS_
#### Customize the look of your traffic lights _macOS_
The `customButtonsOnHover` title bar style will hide the traffic lights until you hover
over them. This is useful if you want to create custom traffic lights in your HTML but still
use the native UI to control the window.
```js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'customButtonsOnHover' })
```
#### Customize the traffic light position _macOS_
To modify the position of the traffic light window controls, there are two configuration
options available.
Applying `hiddenInset` title bar style will shift the vertical inset of the traffic lights
by a fixed amount.
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hiddenInset' })
```
If you need more granular control over the positioning of the traffic lights, you can pass
a set of coordinates to the `trafficLightPosition` option in the `BrowserWindow`
constructor.
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
trafficLightPosition: { x: 10, y: 10 }
})
```
#### Show and hide the traffic lights programmatically _macOS_
You can also show and hide the traffic lights programmatically from the main process.
The `win.setWindowButtonVisibility` forces traffic lights to be show or hidden depending
on the value of its boolean parameter.
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
// hides the traffic lights
win.setWindowButtonVisibility(false)
```
:::note
Given the number of APIs available, there are many ways of achieving this. For instance,
combining `frame: false` with `win.setWindowButtonVisibility(true)` will yield the same
layout outcome as setting `titleBarStyle: 'hidden'`.
:::
#### Custom window controls
The [Window Controls Overlay API][] is a web standard that gives web apps the ability to
customize their title bar region when installed on desktop. Electron exposes this API
through the `titleBarOverlay` option in the `BrowserWindow` constructor. When `titleBarOverlay`
is enabled, the window controls become exposed in their default position, and DOM elements
cannot use the area underneath this region.
:::note
`titleBarOverlay` requires the `titleBarStyle` param in the `BrowserWindow` constructor
to have a value other than `default`.
:::
The custom title bar tutorial covers a [basic example][Add native window controls] of exposing
window controls by setting `titleBarOverlay: true`. The height, color (_Windows_ _Linux_), and
symbol colors (_Windows_) of the window controls can be customized further by setting
`titleBarOverlay` to an object.
The value passed to the `height` property must be an integer. The `color` and `symbolColor`
properties accept `rgba()`, `hsla()`, and `#RRGGBBAA` color formats and support transparency.
If a color option is not specified, the color will default to its system color for the window
control buttons. Similarly, if the height option is not specified, the window controls will
default to the standard system height:
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: {
color: '#2f3241',
symbolColor: '#74b1be',
height: 60
}
})
```
:::note
Once your title bar overlay is enabled from the main process, you can access the overlay's
color and dimension values from a renderer using a set of readonly
[JavaScript APIs][overlay-javascript-apis] and [CSS Environment Variables][overlay-css-env-vars].
:::
[Add native window controls]: #add-native-window-controls-windows-linux
[`BaseWindowContructorOptions`]: ../api/structures/base-window-options.md
[chrome]: https://developer.mozilla.org/en-US/docs/Glossary/Chrome
[Custom draggable regions]: ./custom-window-interactions.md#custom-draggable-regions
[Custom traffic lights]: #custom-traffic-lights-macos
[Custom window controls]: #custom-window-controls
[overlay-css-env-vars]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#css-environment-variables
[overlay-javascript-apis]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#javascript-apis
[Window Controls Overlay API]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md

View File

@@ -1,107 +0,0 @@
# Custom Window Interactions
## Custom draggable regions
By default, windows are dragged using the title bar provided by the OS chrome. Apps
that remove the default title bar need to use the `app-region` CSS property to define
specific areas that can be used to drag the window. Setting `app-region: drag` marks
a rectagular area as draggable.
It is important to note that draggable areas ignore all pointer events. For example,
a button element that overlaps a draggable region will not emit mouse clicks or mouse
enter/exit events within that overlapping area. Setting `app-region: no-drag` reenables
pointer events by excluding a rectagular area from a draggable region.
To make the whole window draggable, you can add `app-region: drag` as
`body`'s style:
```css title='styles.css'
body {
app-region: drag;
}
```
And note that if you have made the whole window draggable, you must also mark
buttons as non-draggable, otherwise it would be impossible for users to click on
them:
```css title='styles.css'
button {
app-region: no-drag;
}
```
If you're only setting a custom title bar as draggable, you also need to make all
buttons in title bar non-draggable.
### Tip: disable text selection
When creating a draggable region, the dragging behavior may conflict with text selection.
For example, when you drag the title bar, you may accidentally select its text contents.
To prevent this, you need to disable text selection within a draggable area like this:
```css
.titlebar {
user-select: none;
app-region: drag;
}
```
### Tip: disable context menus
On some platforms, the draggable area will be treated as a non-client frame, so
when you right click on it, a system menu will pop up. To make the context menu
behave correctly on all platforms, you should never use a custom context menu on
draggable areas.
## Click-through windows
To create a click-through window, i.e. making the window ignore all mouse
events, you can call the [win.setIgnoreMouseEvents(ignore)][ignore-mouse-events]
API:
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.setIgnoreMouseEvents(true)
```
### Forward mouse events _macOS_ _Windows_
Ignoring mouse messages makes the web contents oblivious to mouse movement,
meaning that mouse movement events will not be emitted. On Windows and macOS, an
optional parameter can be used to forward mouse move messages to the web page,
allowing events such as `mouseleave` to be emitted:
```js title='main.js'
const { BrowserWindow, ipcMain } = require('electron')
const path = require('node:path')
const win = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
ipcMain.on('set-ignore-mouse-events', (event, ignore, options) => {
const win = BrowserWindow.fromWebContents(event.sender)
win.setIgnoreMouseEvents(ignore, options)
})
```
```js title='preload.js'
window.addEventListener('DOMContentLoaded', () => {
const el = document.getElementById('clickThroughElement')
el.addEventListener('mouseenter', () => {
ipcRenderer.send('set-ignore-mouse-events', true, { forward: true })
})
el.addEventListener('mouseleave', () => {
ipcRenderer.send('set-ignore-mouse-events', false)
})
})
```
This makes the web page click-through when over the `#clickThroughElement` element,
and returns to normal outside it.
[ignore-mouse-events]: ../api/browser-window.md#winsetignoremouseeventsignore-options

View File

@@ -1,49 +0,0 @@
# Custom Window Styles
## Frameless windows
![Frameless Window](../images/frameless-window.png)
A frameless window removes all [chrome][] applied by the OS, including window controls.
To create a frameless window, set the [`BaseWindowContructorOptions`][] `frame` param in the `BrowserWindow` constructor to `false`.
```fiddle docs/fiddles/features/window-customization/custom-window-styles/frameless-windows
```
## Transparent windows
![Transparent Window](../images/transparent-window.png)
![Transparent Window in macOS Mission Control](../images/transparent-window-mission-control.png)
To create a fully transparent window, set the [`BaseWindowContructorOptions`][] `transparent` param in the `BrowserWindow` constructor to `true`.
The following fiddle takes advantage of a tranparent window and CSS styling to create
the illusion of a circular window.
```fiddle docs/fiddles/features/window-customization/custom-window-styles/transparent-windows
```
### Limitations
* You cannot click through the transparent area. See
[#1335](https://github.com/electron/electron/issues/1335) for details.
* Transparent windows are not resizable. Setting `resizable` to `true` may make
a transparent window stop working on some platforms.
* The CSS [`blur()`][] filter only applies to the window's web contents, so there is
no way to apply blur effect to the content below the window (i.e. other applications
open on the user's system).
* The window will not be transparent when DevTools is opened.
* On _Windows_:
* Transparent windows will not work when DWM is disabled.
* Transparent windows can not be maximized using the Windows system menu or by double
clicking the title bar. The reasoning behind this can be seen on
PR [#28207](https://github.com/electron/electron/pull/28207).
* On _macOS_:
* The native window shadow will not be shown on a transparent window.
[`BaseWindowContructorOptions`]: ../api/structures/base-window-options.md
[`blur()`]: https://developer.mozilla.org/en-US/docs/Web/CSS/filter-function/blur()
[chrome]: https://developer.mozilla.org/en-US/docs/Glossary/Chrome

View File

@@ -78,7 +78,6 @@ The following Devtools extensions have been tested to work in Electron:
* [React Developer Tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi)
* [Backbone Debugger](https://chrome.google.com/webstore/detail/backbone-debugger/bhljhndlimiafopmmhjlgfpnnchjjbhd)
* [jQuery Debugger](https://chrome.google.com/webstore/detail/jquery-debugger/dbhhnnnpaeobfddmlalhnehgclcmjimi)
* [AngularJS Batarang](https://chrome.google.com/webstore/detail/angularjs-batarang/ighdmehidhipcmcojjgiloacoafjmpfk)
* [Vue.js devtools](https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd)
* [Cerebral Debugger](https://cerebraljs.com/docs/introduction/devtools.html)
* [Redux DevTools Extension](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd)

View File

@@ -9,11 +9,10 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
| Electron | Alpha | Beta | Stable | EOL | Chrome | Node | Supported |
| ------- | ----- | ------- | ------ | ------ | ---- | ---- | ---- |
| 35.0.0 | 2025-Jan-16 | 2025-Feb-05 | 2025-Mar-04 | 2025-Sep-02 | M134 | TBD | ✅ |
| 34.0.0 | 2024-Oct-17 | 2024-Nov-13 | 2025-Jan-14 | 2025-Jun-24 | M132 | v20.18 | ✅ |
| 34.0.0 | 2024-Oct-17 | 2024-Nov-13 | 2024-Jan-07 | 2025-Jun-24 | M132 | TBD | ✅ |
| 33.0.0 | 2024-Aug-22 | 2024-Sep-18 | 2024-Oct-15 | 2025-Apr-29 | M130 | v20.18 | ✅ |
| 32.0.0 | 2024-Jun-14 | 2024-Jul-24 | 2024-Aug-20 | 2025-Mar-04 | M128 | v20.16 | ✅ |
| 31.0.0 | 2024-Apr-18 | 2024-May-15 | 2024-Jun-11 | 2025-Jan-14 | M126 | v20.14 | 🚫 |
| 31.0.0 | 2024-Apr-18 | 2024-May-15 | 2024-Jun-11 | 2025-Jan-07 | M126 | v20.14 | |
| 30.0.0 | 2024-Feb-22 | 2024-Mar-20 | 2024-Apr-16 | 2024-Oct-15 | M124 | v20.11 | 🚫 |
| 29.0.0 | 2023-Dec-07 | 2024-Jan-24 | 2024-Feb-20 | 2024-Aug-20 | M122 | v20.9 | 🚫 |
| 28.0.0 | 2023-Oct-11 | 2023-Nov-06 | 2023-Dec-05 | 2024-Jun-11 | M120 | v18.18 | 🚫 |

View File

@@ -68,10 +68,6 @@ The onlyLoadAppFromAsar fuse changes the search system that Electron uses to loc
The loadBrowserProcessSpecificV8Snapshot fuse changes which V8 snapshot file is used for the browser process. By default Electron's processes will all use the same V8 snapshot file. When this fuse is enabled the browser process uses the file called `browser_v8_context_snapshot.bin` for its V8 snapshot. The other processes will use the V8 snapshot file that they normally do.
V8 snapshots can be useful to improve app startup performance. V8 lets you take snapshots of initialized heaps and then load them back in to avoid the cost of initializing the heap.
Using separate snapshots for renderer processes and the main process can improve security, especially to make sure that the renderer doesn't use a snapshot with `nodeIntegration` enabled. See [#35170](https://github.com/electron/electron/issues/35170) for details.
### `grantFileProtocolExtraPrivileges`
**Default:** Enabled

View File

@@ -14,7 +14,7 @@ To configure a local keyboard shortcut, you need to specify an [`accelerator`][]
property when creating a [MenuItem][] within the [Menu][] module.
Starting with a working application from the
[tutorial starter code][tutorial-starter-code], update the `main.js` to be:
[Quick Start Guide](quick-start.md), update the `main.js` to be:
```fiddle docs/fiddles/features/keyboard-shortcuts/local
const { app, BrowserWindow, Menu, MenuItem } = require('electron/main')
@@ -75,7 +75,7 @@ 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:
[Quick Start Guide](quick-start.md), update the `main.js` to be:
```fiddle docs/fiddles/features/keyboard-shortcuts/global
const { app, BrowserWindow, globalShortcut } = require('electron/main')
@@ -144,7 +144,7 @@ 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.
Starting with a working application from the
[tutorial starter code][tutorial-starter-code], update the `main.js` file with the
[Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines:
```fiddle docs/fiddles/features/keyboard-shortcuts/interception-from-main
@@ -207,4 +207,3 @@ Mousetrap.bind('up up down down left right left right b a enter', () => {
[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

@@ -86,7 +86,7 @@ The main process also controls your application's lifecycle through Electron's
that you can use to add custom application behavior (for instance, programmatically
quitting your application, modifying the application dock, or showing an About panel).
As a practical example, the app shown in the [tutorial starter code][tutorial-lifecycle]
As a practical example, the app shown in the [quick start guide][quick-start-lifecycle]
uses `app` APIs to create a more native application window experience.
```js title='main.js'
@@ -97,7 +97,7 @@ app.on('window-all-closed', () => {
```
[app]: ../api/app.md
[tutorial-lifecycle]: ../tutorial/tutorial-2-first-app.md#quit-the-app-when-all-windows-are-closed-windows--linux
[quick-start-lifecycle]: ../tutorial/quick-start.md#manage-your-windows-lifecycle
### Native APIs

View File

@@ -0,0 +1,513 @@
# Quick Start
This guide will step you through the process of creating a barebones Hello World app in
Electron, similar to [`electron/electron-quick-start`][quick-start].
By the end of this tutorial, your app will open a browser window that displays a web page
with information about which Chromium, Node.js, and Electron versions are running.
[quick-start]: https://github.com/electron/electron-quick-start
## Prerequisites
To use Electron, you need to install [Node.js][node-download]. We recommend that you
use the latest `LTS` version available.
> Please install Node.js using pre-built installers for your platform.
> You may encounter incompatibility issues with different development tools otherwise.
To check that Node.js was installed correctly, type the following commands in your
terminal client:
```sh
node -v
npm -v
```
The commands should print the versions of Node.js and npm accordingly.
**Note:** Since Electron embeds Node.js into its binary, the version of Node.js running
your code is unrelated to the version running on your system.
[node-download]: https://nodejs.org/en/download/
## Create your application
### Scaffold the project
Electron apps follow the same general structure as other Node.js projects.
Start by creating a folder and initializing an npm package.
```sh npm2yarn
mkdir my-electron-app && cd my-electron-app
npm init
```
The interactive `init` command will prompt you to set some fields in your config.
There are a few rules to follow for the purposes of this tutorial:
* `entry point` should be `main.js`.
* `author` and `description` can be any value, but are necessary for
[app packaging](#package-and-distribute-your-application).
Your `package.json` file should look something like this:
```json
{
"name": "my-electron-app",
"version": "1.0.0",
"description": "Hello World!",
"main": "main.js",
"author": "Jane Doe",
"license": "MIT"
}
```
Then, install the `electron` package into your app's `devDependencies`.
```sh npm2yarn
npm install --save-dev electron
```
> Note: If you're encountering any issues with installing Electron, please
> refer to the [Advanced Installation][advanced-installation] guide.
Finally, you want to be able to execute Electron. In the [`scripts`][package-scripts]
field of your `package.json` config, add a `start` command like so:
```json
{
"scripts": {
"start": "electron ."
}
}
```
This `start` command will let you open your app in development mode.
```sh npm2yarn
npm start
```
> Note: This script tells Electron to run on your project's root folder. At this stage,
> your app will immediately throw an error telling you that it cannot find an app to run.
[advanced-installation]: ./installation.md
[package-scripts]: https://docs.npmjs.com/cli/v7/using-npm/scripts
### Run the main process
The entry point of any Electron application is its `main` script. This script controls the
**main process**, which runs in a full Node.js environment and is responsible for
controlling your app's lifecycle, displaying native interfaces, performing privileged
operations, and managing renderer processes (more on that later).
During execution, Electron will look for this script in the [`main`][package-json-main]
field of the app's `package.json` config, which you should have configured during the
[app scaffolding](#scaffold-the-project) step.
To initialize the `main` script, create an empty file named `main.js` in the root folder
of your project.
> Note: If you run the `start` script again at this point, your app will no longer throw
> any errors! However, it won't do anything yet because we haven't added any code into
> `main.js`.
[package-json-main]: https://docs.npmjs.com/cli/v7/configuring-npm/package-json#main
### Create a web page
Before we can create a window for our application, we need to create the content that
will be loaded into it. In Electron, each window displays web contents that can be loaded
from either a local HTML file or a remote URL.
For this tutorial, you will be doing the former. Create an `index.html` file in the root
folder of your project:
```html
<!DOCTYPE html>
<html lang="en">
<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>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
We are using Node.js <span id="node-version"></span>,
Chromium <span id="chrome-version"></span>,
and Electron <span id="electron-version"></span>.
</body>
</html>
```
> Note: Looking at this HTML document, you can observe that the version numbers are
> missing from the body text. We'll manually insert them later using JavaScript.
### Opening your web page in a browser window
Now that you have a web page, load it into an application window. To do so, you'll
need two Electron modules:
* The [`app`][app] module, which controls your application's event lifecycle.
* The [`BrowserWindow`][browser-window] module, which creates and manages application
windows.
Because the main process runs Node.js, you can import these as [CommonJS][commonjs]
modules at the top of your `main.js` file:
```js
const { app, BrowserWindow } = require('electron')
```
Then, add a `createWindow()` function that loads `index.html` into a new `BrowserWindow`
instance.
```js
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
```
Next, call this `createWindow()` function to open your window.
In Electron, browser windows can only be created after the `app` module's
[`ready`][app-ready] event is fired. You can wait for this event by using the
[`app.whenReady()`][app-when-ready] API. Call `createWindow()` after `whenReady()`
resolves its Promise.
```js @ts-type={createWindow:()=>void}
app.whenReady().then(() => {
createWindow()
})
```
> Note: At this point, your Electron application should successfully
> open a window that displays your web page!
[app]: ../api/app.md
[browser-window]: ../api/browser-window.md
[commonjs]: https://nodejs.org/docs/latest/api/modules.html#modules_modules_commonjs_modules
[app-ready]: ../api/app.md#event-ready
[app-when-ready]: ../api/app.md#appwhenready
### Manage your window's lifecycle
Although you can now open a browser window, you'll need some additional boilerplate code
to make it feel more native to each platform. Application windows behave differently on
each OS, and Electron puts the responsibility on developers to implement these
conventions in their app.
In general, you can use the `process` global's [`platform`][node-platform] attribute
to run code specifically for certain operating systems.
#### Quit the app when all windows are closed (Windows & Linux)
On Windows and Linux, exiting all windows generally quits an application entirely.
To implement this, listen for the `app` module's [`'window-all-closed'`][window-all-closed]
event, and call [`app.quit()`][app-quit] if the user is not on macOS (`darwin`).
```js
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
```
[node-platform]: https://nodejs.org/api/process.html#process_process_platform
[window-all-closed]: ../api/app.md#event-window-all-closed
[app-quit]: ../api/app.md#appquit
#### Open a window if none are open (macOS)
Whereas Linux and Windows apps quit when they have no windows open, macOS apps generally
continue running even without any windows open, and activating the app when no windows
are available should open a new one.
To implement this feature, listen for the `app` module's [`activate`][activate]
event, and call your existing `createWindow()` method if no browser windows are open.
Because windows cannot be created before the `ready` event, you should only listen for
`activate` events after your app is initialized. Do this by attaching your event listener
from within your existing `whenReady()` callback.
[activate]: ../api/app.md#event-activate-macos
```js @ts-type={createWindow:()=>void}
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
```
> Note: At this point, your window controls should be fully functional!
### Access Node.js from the renderer with a preload script
Now, the last thing to do is print out the version numbers for Electron and its
dependencies onto your web page.
Accessing this information is trivial to do in the main process through Node's
global `process` object. However, you can't just edit the DOM from the main
process because it has no access to the renderer's `document` context.
They're in entirely different processes!
> Note: If you need a more in-depth look at Electron processes, see the
> [Process Model][] document.
This is where attaching a **preload** script to your renderer comes in handy.
A preload script runs before the renderer process is loaded, and has access to both
renderer globals (e.g. `window` and `document`) and a Node.js environment.
Create a new script named `preload.js` as such:
```js
window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector)
if (element) element.innerText = text
}
for (const dependency of ['chrome', 'node', 'electron']) {
replaceText(`${dependency}-version`, process.versions[dependency])
}
})
```
The above code accesses the Node.js `process.versions` object and runs a basic `replaceText`
helper function to insert the version numbers into the HTML document.
To attach this script to your renderer process, pass in the path to your preload script
to the `webPreferences.preload` option in your existing `BrowserWindow` constructor.
```js
const { app, BrowserWindow } = require('electron')
// include the Node.js 'path' module at the top of your file
const path = require('node:path')
// modify your existing createWindow() function
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
}
// ...
```
There are two Node.js concepts that are used here:
* The [`__dirname`][dirname] string points to the path of the currently executing script
(in this case, your project's root folder).
* The [`path.join`][path-join] API joins multiple path segments together, creating a
combined path string that works across all platforms.
We use a path relative to the currently executing JavaScript file so that your relative
path will work in both development and packaged mode.
[Process Model]: ./process-model.md
[dirname]: https://nodejs.org/api/modules.html#modules_dirname
[path-join]: https://nodejs.org/api/path.html#path_path_join_paths
### Bonus: Add functionality to your web contents
At this point, you might be wondering how to add more functionality to your application.
For any interactions with your web contents, you want to add scripts to your
renderer process. Because the renderer runs in a normal web environment, you can add a
`<script>` tag right before your `index.html` file's closing `</body>` tag to include
any arbitrary scripts you want:
```html
<script src="./renderer.js"></script>
```
The code contained in `renderer.js` can then use the same JavaScript APIs and tooling
you use for typical front-end development, such as using [`webpack`][webpack] to bundle
and minify your code or [React][react] to manage your user interfaces.
[webpack]: https://webpack.js.org
[react]: https://reactjs.org
### Recap
After following the above steps, you should have a fully functional
Electron application that looks like this:
![Simplest Electron app](../images/simplest-electron-app.png)
<!--TODO(erickzhao): Remove the individual code blocks for static website -->
The full code is available below:
```js
// main.js
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron')
const path = require('node:path')
const createWindow = () => {
// Create the browser window.
const 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()
}
// 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()
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
// 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.
```
```js
// preload.js
// All the Node.js APIs are available in the preload process.
// It has the same sandbox as a Chrome extension.
window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector)
if (element) element.innerText = text
}
for (const dependency of ['chrome', 'node', 'electron']) {
replaceText(`${dependency}-version`, process.versions[dependency])
}
})
```
```html
<!--index.html-->
<!DOCTYPE html>
<html lang="en">
<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>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
We are using Node.js <span id="node-version"></span>,
Chromium <span id="chrome-version"></span>,
and Electron <span id="electron-version"></span>.
<!-- You can also require other files to run in this process -->
<script src="./renderer.js"></script>
</body>
</html>
```
```fiddle docs/fiddles/quick-start
```
To summarize all the steps we've done:
* We bootstrapped a Node.js application and added Electron as a dependency.
* We created a `main.js` script that runs our main process, which controls our app
and runs in a Node.js environment. In this script, we used Electron's `app` and
`BrowserWindow` modules to create a browser window that displays web content
in a separate process (the renderer).
* In order to access certain Node.js functionality in the renderer, we attached
a preload script to our `BrowserWindow` constructor.
## Package and distribute your application
The fastest way to distribute your newly created app is using
[Electron Forge](https://www.electronforge.io).
:::info
To build an RPM package for Linux, you will need to [install its required system dependencies](https://www.electronforge.io/config/makers/rpm).
:::
1. Add a description to your `package.json` file, otherwise rpmbuild will fail. Blank description are not valid.
2. Add Electron Forge as a development dependency of your app, and use its `import` command to set up
Forge's scaffolding:
```sh npm2yarn
npm install --save-dev @electron-forge/cli
npx electron-forge import
✔ Checking your system
✔ Initializing Git Repository
✔ Writing modified package.json file
✔ Installing dependencies
✔ Writing modified package.json file
✔ Fixing .gitignore
We have ATTEMPTED to convert your app to be in a format that electron-forge understands.
Thanks for using "electron-forge"!!!
```
3. Create a distributable using Forge's `make` command:
```sh npm2yarn
npm run make
> my-electron-app@1.0.0 make /my-electron-app
> electron-forge make
✔ Checking your system
✔ Resolving Forge Config
We need to package your application before we can make it
✔ Preparing to Package Application for arch: x64
✔ Preparing native dependencies
✔ Packaging Application
Making for the following targets: zip
✔ Making for target: zip - On platform: darwin - For arch: x64
```
Electron Forge creates the `out` folder where your package will be located:
```plain
// Example for macOS
out/
├── out/make/zip/darwin/x64/my-electron-app-darwin-x64-1.0.0.zip
├── ...
└── out/my-electron-app-darwin-x64/my-electron-app.app/Contents/MacOS/my-electron-app
```

View File

@@ -1,21 +1,269 @@
import DocCardList from '@theme/DocCardList';
# Window Customization
The [`BrowserWindow`][] module is the foundation of your Electron application, and
it exposes many APIs that let you customize the look and behavior of your apps windows.
This section covers how to implement various use cases for window customization on macOS,
Windows, and Linux.
The `BrowserWindow` module is the foundation of your Electron application, and it exposes
many APIs that can change the look and behavior of your browser windows. In this
tutorial, we will be going over the various use-cases for window customization on
macOS, Windows, and Linux.
> [!NOTE]
> `BrowserWindow` is a subclass of the [`BaseWindow`][] module. Both modules allow
> you to create and manage application windows in Electron, with the main difference
> being that `BrowserWindow` supports a single, full size web view while `BaseWindow`
> supports composing many web views. `BaseWindow` can be used interchangeably with `BrowserWindow`
> in the examples of the documents in this section.
## Create frameless windows
<!-- markdownlint-disable-next-line MD033 -->
<DocCardList />
A frameless window is a window that has no [chrome][]. Not to be confused with the Google
Chrome browser, window _chrome_ refers to the parts of the window (e.g. toolbars, controls)
that are not a part of the web page.
[`BaseWindow`]: ../api/base-window.md
[`BrowserWindow`]: ../api/browser-window.md
To create a frameless window, you need to set `frame` to `false` in the `BrowserWindow`
constructor.
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ frame: false })
```
## Apply custom title bar styles _macOS_ _Windows_
Title bar styles allow you to hide most of a BrowserWindow's chrome while keeping the
system's native window controls intact and can be configured with the `titleBarStyle`
option in the `BrowserWindow` constructor.
Applying the `hidden` title bar style results in a hidden title bar and a full-size
content window.
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hidden' })
```
### Control the traffic lights _macOS_
On macOS, applying the `hidden` title bar style will still expose the standard window
controls (“traffic lights”) in the top left.
#### Customize the look of your traffic lights _macOS_
The `customButtonsOnHover` title bar style will hide the traffic lights until you hover
over them. This is useful if you want to create custom traffic lights in your HTML but still
use the native UI to control the window.
```js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'customButtonsOnHover' })
```
#### Customize the traffic light position _macOS_
To modify the position of the traffic light window controls, there are two configuration
options available.
Applying `hiddenInset` title bar style will shift the vertical inset of the traffic lights
by a fixed amount.
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hiddenInset' })
```
If you need more granular control over the positioning of the traffic lights, you can pass
a set of coordinates to the `trafficLightPosition` option in the `BrowserWindow`
constructor.
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
trafficLightPosition: { x: 10, y: 10 }
})
```
#### Show and hide the traffic lights programmatically _macOS_
You can also show and hide the traffic lights programmatically from the main process.
The `win.setWindowButtonVisibility` forces traffic lights to be show or hidden depending
on the value of its boolean parameter.
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
// hides the traffic lights
win.setWindowButtonVisibility(false)
```
> Note: Given the number of APIs available, there are many ways of achieving this. For instance,
> combining `frame: false` with `win.setWindowButtonVisibility(true)` will yield the same
> layout outcome as setting `titleBarStyle: 'hidden'`.
## Window Controls Overlay
The [Window Controls Overlay API][] is a web standard that gives web apps the ability to
customize their title bar region when installed on desktop. Electron exposes this API
through the `BrowserWindow` constructor option `titleBarOverlay`.
This option only works whenever a custom `titlebarStyle` is applied.
When `titleBarOverlay` is enabled, the window controls become exposed in their default
position, and DOM elements cannot use the area underneath this region.
The `titleBarOverlay` option accepts two different value formats.
Specifying `true` on either platform will result in an overlay region with default
system colors:
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: true
})
```
On either platform `titleBarOverlay` can also be an object. The height of the overlay can be specified with the `height` property. On Windows and Linux, the color of the overlay and can be specified using the `color` property. On Windows and Linux, the color of the overlay and its symbols can be specified using the `color` and `symbolColor` properties respectively. The `rgba()`, `hsla()`, and `#RRGGBBAA` color formats are supported to apply transparency.
If a color option is not specified, the color will default to its system color for the window control buttons. Similarly, if the height option is not specified it will default to the default height:
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: {
color: '#2f3241',
symbolColor: '#74b1be',
height: 60
}
})
```
> Note: Once your title bar overlay is enabled from the main process, you can access the overlay's
> color and dimension values from a renderer using a set of readonly
> [JavaScript APIs][overlay-javascript-apis] and [CSS Environment Variables][overlay-css-env-vars].
## Create transparent windows
By setting the `transparent` option to `true`, you can make a fully transparent window.
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ transparent: true })
```
### Limitations
* You cannot click through the transparent area. See
[#1335](https://github.com/electron/electron/issues/1335) for details.
* Transparent windows are not resizable. Setting `resizable` to `true` may make
a transparent window stop working on some platforms.
* The CSS [`blur()`][] filter only applies to the window's web contents, so there is no way to apply
blur effect to the content below the window (i.e. other applications open on
the user's system).
* The window will not be transparent when DevTools is opened.
* On _Windows_:
* Transparent windows will not work when DWM is disabled.
* Transparent windows can not be maximized using the Windows system menu or by double
clicking the title bar. The reasoning behind this can be seen on
PR [#28207](https://github.com/electron/electron/pull/28207).
* On _macOS_:
* The native window shadow will not be shown on a transparent window.
## Create click-through windows
To create a click-through window, i.e. making the window ignore all mouse
events, you can call the [win.setIgnoreMouseEvents(ignore)][ignore-mouse-events]
API:
```js title='main.js'
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.setIgnoreMouseEvents(true)
```
### Forward mouse events _macOS_ _Windows_
Ignoring mouse messages makes the web contents oblivious to mouse movement,
meaning that mouse movement events will not be emitted. On Windows and macOS, an
optional parameter can be used to forward mouse move messages to the web page,
allowing events such as `mouseleave` to be emitted:
```js title='main.js'
const { BrowserWindow, ipcMain } = require('electron')
const path = require('node:path')
const win = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
ipcMain.on('set-ignore-mouse-events', (event, ignore, options) => {
const win = BrowserWindow.fromWebContents(event.sender)
win.setIgnoreMouseEvents(ignore, options)
})
```
```js title='preload.js'
window.addEventListener('DOMContentLoaded', () => {
const el = document.getElementById('clickThroughElement')
el.addEventListener('mouseenter', () => {
ipcRenderer.send('set-ignore-mouse-events', true, { forward: true })
})
el.addEventListener('mouseleave', () => {
ipcRenderer.send('set-ignore-mouse-events', false)
})
})
```
This makes the web page click-through when over the `#clickThroughElement` element,
and returns to normal outside it.
## Set custom draggable region
By default, the frameless window is non-draggable. Apps need to specify
`-webkit-app-region: drag` in CSS to tell Electron which regions are draggable
(like the OS's standard titlebar), and apps can also use
`-webkit-app-region: no-drag` to exclude the non-draggable area from the
draggable region. Note that only rectangular shapes are currently supported.
To make the whole window draggable, you can add `-webkit-app-region: drag` as
`body`'s style:
```css title='styles.css'
body {
-webkit-app-region: drag;
}
```
And note that if you have made the whole window draggable, you must also mark
buttons as non-draggable, otherwise it would be impossible for users to click on
them:
```css title='styles.css'
button {
-webkit-app-region: no-drag;
}
```
If you're only setting a custom titlebar as draggable, you also need to make all
buttons in titlebar non-draggable.
### Tip: disable text selection
When creating a draggable region, the dragging behavior may conflict with text selection.
For example, when you drag the titlebar, you may accidentally select its text contents.
To prevent this, you need to disable text selection within a draggable area like this:
```css
.titlebar {
-webkit-user-select: none;
-webkit-app-region: drag;
}
```
### Tip: disable context menus
On some platforms, the draggable area will be treated as a non-client frame, so
when you right click on it, a system menu will pop up. To make the context menu
behave correctly on all platforms, you should never use a custom context menu on
draggable areas.
[`blur()`]: https://developer.mozilla.org/en-US/docs/Web/CSS/filter-function/blur()
[chrome]: https://developer.mozilla.org/en-US/docs/Glossary/Chrome
[ignore-mouse-events]: ../api/browser-window.md#winsetignoremouseeventsignore-options
[overlay-css-env-vars]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#css-environment-variables
[overlay-javascript-apis]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#javascript-apis
[Window Controls Overlay API]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md

View File

@@ -8,7 +8,7 @@ If your app doesn't use any native modules, then it's really easy to create an A
1. Make sure that your app's `node_modules` directory is empty.
2. Using a _Command Prompt_, run `set npm_config_arch=arm64` before running `npm install`/`yarn install` as usual.
3. [If you have Electron installed as a development dependency](tutorial-2-first-app.md#initializing-your-npm-project), npm will download and unpack the arm64 version. You can then package and distribute your app as normal.
3. [If you have Electron installed as a development dependency](quick-start.md#prerequisites), npm will download and unpack the arm64 version. You can then package and distribute your app as normal.
## General considerations

View File

@@ -57,7 +57,7 @@ To set user tasks for your application, you can use
##### Set user tasks
Starting with a working application from the
[tutorial starter code][tutorial-starter-code], update the `main.js` file with the
[Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines:
```js
@@ -121,7 +121,7 @@ To set thumbnail toolbar in your application, you need to use
##### Set thumbnail toolbar
Starting with a working application from the
[tutorial starter code][tutorial-starter-code], update the `main.js` file with the
[Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines:
```js
@@ -185,7 +185,7 @@ To set the overlay icon for a window, you need to use the
#### Example
Starting with a working application from the
[tutorial starter code][tutorial-starter-code], update the `main.js` file with the
[Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines:
```js
@@ -214,7 +214,7 @@ To flash the BrowserWindow taskbar button, you need to use the
#### Example
Starting with a working application from the
[tutorial starter code][tutorial-starter-code], update the `main.js` file with the
[Quick Start Guide](quick-start.md), update the `main.js` file with the
following lines:
```js
@@ -231,10 +231,10 @@ In the above example, it is called when the window comes into focus,
but you might use a timeout or some other event to disable it.
[msdn-flash-frame]: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-flashwindow#remarks
[setthumbarbuttons]: ../api/browser-window.md#winsetthumbarbuttonsbuttons-windows
[setusertaskstasks]: ../api/app.md#appsetusertaskstasks-windows
[setoverlayicon]: ../api/browser-window.md#winsetoverlayiconoverlay-description-windows
[flashframe]: ../api/browser-window.md#winflashframeflag
[recent-documents]: ./recent-documents.md
[progress-bar]: ./progress-bar.md
[tutorial-starter-code]: ../tutorial/tutorial-2-first-app.md#final-starter-code

View File

@@ -1,103 +0,0 @@
# Why Electron
Electron is a framework enabling developers to build cross-platform desktop applications for macOS, Windows, and Linux by combining web technologies (HTML, JavaScript, CSS) with Node.js and native code. It is open-source, MIT-licensed, and free for both commercial and personal use. In this document, well explain why companies and developers choose Electron.
We can split up the benefits of Electron in two questions: First, why should you use web technologies to build your application? Then, why should you choose Electron as the framework to do so?
If youre already using web technologies for your application, you can skip straight to the `Why Electron?` section below.
## Why choose web technologies
Web technologies include HTML, CSS, JavaScript, and WebAssembly. Theyre the storefront of the modern Internet. Those technologies have emerged as the best choice for building user interfaces — both for consumer applications as well as mission-critical business applications. This is true both for applications that need to run in a browser as well as desktop applications that are not accessible from a browser. Our bold claim here is that this isnt just true for cross-platform applications that need to run on multiple operating systems but true overall.
As an example, NASAs actual [Mission Control](https://github.com/nasa/openmct) is written with web technologies. The [Bloomberg Terminal](https://en.wikipedia.org/wiki/Bloomberg_Terminal), the computer system found at every financial institution, is written with web technologies and runs inside Chromium. It costs $25,000 per user, per year. The McDonalds ordering kiosk, powering the worlds biggest food retailer, is entirely built with Chromium. The [SpaceXs Dragon 2 space capsule](https://old.reddit.com/r/spacex/comments/gxb7j1/we_are_the_spacex_software_team_ask_us_anything/ft62781/?context=3) uses Chromium to display its interface. You get the point: web technologies are a great tech stack to build user interfaces.
Here are the reasons we, the Electron maintainers, are betting on the web.
### Versatility
Modern versions of HTML and CSS enable your developers and designers to fully express themselves. The webs showcase includes Google Earth, Netflix, Spotify, Gmail, Facebook, Airbnb, or GitHub. Whatever interface your application needs, you will be able to express it with HTML, CSS, and JavaScript.
If you want to focus on building a great product without figuring out how you can realize your designers vision in a specific UI framework, the web is a safe bet.
### Reliability
Web technologies are the most-used foundation for user interfaces on the planet. The have been hardened accordingly. Modern computers have been optimized from the CPU to the operating system to be good at running web technologies. The manufacturers of your users devices—be that an Android phone or the latest MacBook—will ensure that they can visit websites, play videos on YouTube, or display emails. In turn, theyll also ensure that your app has a stable foundation, even if you have just one user.
If you want to focus on building a great product without debugging a weird quirk that nobody has found before, the web is a safe bet.
### Interoperability
Whatever provider or customer data you need to interact with, they will have probably thought of an integration path with the web. Depending on your technology choice, embedding a YouTube video either takes 30 seconds or requires you to hire a team devoted to streaming and hardware-accelerated video decoding. In the case of YouTube, using anything other than the provided players is actually against their terms and conditions, so youll likely embed a browser frame before you implement your own video streaming decoder.
There will be virtually no platform where your app cannot run if you build it with web technologies. Virtually all devices with a display—be that an ATM, a car infotainment system, a smart TV, a fridge, or a Nintendo Switch—come with means to display web technologies. The web is safe bet if you want to be cross-platform.
### Ubiquity
Its easy to find developers with experience building with web technologies. If youre a developer, itll be easy to find answers to your questions on Google, Stack Overflow, GitHub, or a coding AI of your choice. Whatever problem you need to solve, its likely that somebody has solved it well before—and that you can find the answer to the puzzle online.
If you want to focus on building a great product with ample access to resources and materials, the web is a safe bet.
## Why choose Electron
Electron combines Chromium, Node.js, and the ability to write custom native code into one framework for building powerful desktop applications. There are three main reasons to use Electron:
### Enterprise-grade
Electron is reliable, secure, stable, and mature. It is the premier choice for companies building their flagship product. We have a list of some of those companies on our homepage, but just among chat apps, Slack, Discord, and Skype are built with Electron. Among AI applications, both OpenAIs ChatGPT and Anthropics Claude use Electron. Visual Studio Code, Loom, Canva, Notion, Docker, and countless other leading developers of software bet on Electron.
We did make it a priority to make Electron easy to work with and a delight for developers. Thats likely the main reason why Electron became as popular as it is today — but what keeps Electron alive and thriving is the maintainers focus on making Electron as stable, secure, performant, and capable of mission-critical use cases for end users as possible. Were building an Electron that is ready to be used in scenarios where unfixable bugs, unpatched security holes, and outages of any kind are worst-case scenarios.
### Mature
Our current estimation is that most desktop computers on the planet run at least one Electron app. Electron has grown by prioritizing talent in its maintainer group, fostering excellent and sustainable engineering practices in managing the ongoing maintenance, and proactively inviting companies betting on Electron to directly contribute to the project. Were an impact project with the OpenJS foundation, which is itself a part of the Linux foundation. We share resources and expertise with other foundation projects like Node.js, ESLint, Webpack - or the Linux Kernel or Kubernetes.
What does all of that mean for you, a developer, in practice?
- **Reliable release schedule**: Electron will release a new major version in lockstep with every second major Chromium release, usually on the same day as Chromium. A lot of work, both in the form of building processes and tools, but also in terms of raw invested hours every week, has to go into making that happen.
- **No dictators**: Sometimes, betting on a technology also requires you to bet on a single person or company. In turn, it requires you to trust that the person or company never has a breakdown, starts fighting you directly, or does anything else drastic thatll force you rethink your entire tech stack. Electron is maintained by a diverse set of companies (Microsoft, Slack/Salesforce, Notion, and more) and will continue to welcome more companies interested in ensuring their “seat at the decision-making table”.
### Stability, security, performance
Electron delivers the best experience on all target platforms (macOS, Windows, Linux) by bundling the latest version of Chromium, V8, and Node.js directly with the application binary. When it comes to running and rendering web content with upmost stability, security, and performance, we currently believe that stack to be “best in class”.
#### Why bundle anything at all
You might wonder why we bundle Chromiums web stack with our apps when most modern operating systems already ship a browser and some form of web view. Bundling doesnt just increase the amount of work for Electron maintainers dramatically, it also increases the total disk size of Electron apps (most apps are >100MB). Many Electron maintainers once developed applications that did make use of embedded web views — and have since accepted the increased disk size and maintainer work as a worthy trade-off.
When using an operating system's built-in web view, you're limited by the browser version included in the oldest operating system version you need to support. We have found the following problems with this approach:
- **Stability**: The modern web technology stack is complex, and as a result, youll sooner or later encounter bugs. If you use the operating systems web view, your only recourse will be to ask your customers to upgrade their operating system. If no upgrade is available for that machine (because of no ability to upgrade to the latest macOS or Windows 11), youll have to ask them to buy a new computer. If youre unlucky, youre now losing a major customer because they will not upgrade their entire fleet of thousands of machines just because one team wanted to try your startups app. You have _no recourse_ in this situation. Even the risk of that happening is unacceptable to the companies that employ the Electron maintainers.
- **Security:** Similar to how you can fix stability bugs by releasing an app update, you can also release security fixes to your application without asking your customer to upgrade their operating system. Even if operating system providers prioritize updates to their built-in browser, we have not seen them reliably update the built-in web views with similar urgency. Bundling a web renderer gives you, the developer, control.
- **Performance:** For simple HTML documents, a built-in web view will sometimes use fewer resources than an app with a bundled framework. For bigger apps, it is our experience that we can deliver better performance with the latest version of Chromium than we can with built-in web views. You might think that the built-in view can share a lot of resources with other apps and the operating system— but for security reasons, apps have to run in their own sandboxes, isolated from each other. At that point, the question is whether the OS web view is more performant than Chromium. Across many apps, our experience is that bundling Chromium and Node.js enables us to build better and more performant experiences.
#### Why bundle Chromium and Node.js
Electron aims to enable the apps it supports to deliver the best possible user experience, followed by the best possible developer experience. Chromium is currently the best cross-platform rendering stack available. Node.js uses Chromiums JavaScript engine V8, allowing us to combine the powers of both.
- **Native code when you want it**: Thanks to Node.js mature native addon system, you can always write native code. There is no system API out of reach for you. Whatever macOS, Windows, or Linux feature youll want to integrate with —as long as you can do it in C, C++, Objective-C, Rust, or another native language, youll be able to do it in Electron. Again, this gives you, the developer, maximum control. With Electron, you can use web technologies without choosing _only_ web technologies.
### Developer experience
To summarize, we aim to build an Electron that is mature, enterprise-grade, and ready for mission-critical applications. We prioritize reliability, stability, security, and performance. That said, you might also choose Electron for its developer experience:
- **Powerful ecosystem**: Anything you find on npm will run inside Electron. Any resource available to you about how to work with Node.js also applies to Electron. In addition, Electron itself has a [thriving ecosystem](https://www.npmjs.com/search?q=electron) — including plenty of choices for installers, updaters, deeper operating system-integration, and more.
- **Plenty of built-in capabilities:** Over the last ten years, Electrons core has gained plenty of native capabilities that you might need to build your application. Written in C++ and Objective-C, Electron has [dozens of easy-to-use APIs for deeper operating-system integration](https://www.electronjs.org/docs/latest/api/app) — like advanced window customization for transparent or oddly shaped widgets, receiving push notifications from the Apple Push Notification Network, or handling a custom URL protocol for your app.
- **Open source**: The entire stack is open source and open to your inspection. This ensures your freedom to add any feature or fix any bug you might encounter in the future.
- **Native code when you need it:** It bears repeating that Electron allows you to mix and match web technologies and C++, C, Objective-C, Rust, and other native languages. Whether it be SQLite, a whole LLM, or just the ability to call one specific native API, Electron will make it easy.
---
## Why choose something else
As outlined above, the web is an amazing platform for building interfaces. That doesnt mean that we, the maintainers, would build _everything_ with HTML and CSS. Here are some notable exceptions:
**Resource-Constrained Environments and IoT:** In scenarios with very limited memory or processing power (say, one megabyte of memory and 100MHz of processing power on a low-powered ARM Cortex-M), you will likely need to use a low-level language to directly talk to the display to output basic text and images. Even on slightly higher-powered single-chip devices you might want to consider an embedded UI framework. A classic example is a smart watch.
**Small Disk Footprint**: Zipped Electron apps are usually around 80 to 100 Megabytes. If a smaller disk footprint is a hard requirement, youll have to use something else.
**Operating System UI Frameworks and Libraries**: By allowing you to write native code, Electron can do anything a native application can do, including the use of the operating systems UI components, like WinUI, SwiftUI, or AppKit. In practice, most Electron apps make rare use of that ability. If you want the majority of your app to be built with operating system-provided interface components, youll likely be better off building fully native apps for each operating system youd like to target. Its not that its impossible with Electron, itll just likely be an overall easier development process.
**Games and Real-Time Graphics:** If you're building a high-performance game or application requiring complex real-time 3D graphics, native frameworks like Unity, Unreal Engine, or DirectX/OpenGL will provide better performance and more direct access to graphics hardware. Web fans might point out caveats, like the fact that even Unreal Engine ships with Chromium — or that WebGPU and WebGL are developing rapidly and many game engines, including the ones listed here, can now output their games in a format that runs in a browser. That said, if you asked us to build the next AAA game, wed likely use something else than just web technologies.
**Embedding Lightweight Websites**: Electron apps typically are mostly web apps with native code sprinkled in where useful. Processing-heavy Electron applications tend to write the UI in HTML/CSS and build the backend in Rust, C++, or another native language. If youre planning to build a primarily native application that also wants to display a little website in a specific view, you might be better off using the OS-provided web view or something like [ultralight](https://ultralig.ht/).

View File

@@ -133,8 +133,6 @@ auto_filenames = {
"docs/api/structures/segmented-control-segment.md",
"docs/api/structures/serial-port.md",
"docs/api/structures/service-worker-info.md",
"docs/api/structures/shared-dictionary-info.md",
"docs/api/structures/shared-dictionary-usage-info.md",
"docs/api/structures/shared-worker-info.md",
"docs/api/structures/sharing-item.md",
"docs/api/structures/shortcut-details.md",

View File

@@ -507,10 +507,6 @@ filenames = {
"shell/browser/ui/devtools_manager_delegate.h",
"shell/browser/ui/devtools_ui.cc",
"shell/browser/ui/devtools_ui.h",
"shell/browser/ui/devtools_ui_bundle_data_source.cc",
"shell/browser/ui/devtools_ui_bundle_data_source.h",
"shell/browser/ui/devtools_ui_theme_data_source.cc",
"shell/browser/ui/devtools_ui_theme_data_source.h",
"shell/browser/ui/drag_util.cc",
"shell/browser/ui/drag_util.h",
"shell/browser/ui/electron_menu_model.cc",

View File

@@ -236,7 +236,6 @@ libcxx_headers = [
"//third_party/libc++/src/include/__bit/rotate.h",
"//third_party/libc++/src/include/__bit_reference",
"//third_party/libc++/src/include/__charconv/chars_format.h",
"//third_party/libc++/src/include/__charconv/from_chars_floating_point.h",
"//third_party/libc++/src/include/__charconv/from_chars_integral.h",
"//third_party/libc++/src/include/__charconv/from_chars_result.h",
"//third_party/libc++/src/include/__charconv/tables.h",
@@ -970,6 +969,7 @@ libcxx_headers = [
"//third_party/libc++/src/include/limits",
"//third_party/libc++/src/include/list",
"//third_party/libc++/src/include/locale",
"//third_party/libc++/src/include/locale.h",
"//third_party/libc++/src/include/map",
"//third_party/libc++/src/include/math.h",
"//third_party/libc++/src/include/mdspan",
@@ -1000,6 +1000,7 @@ libcxx_headers = [
"//third_party/libc++/src/include/stdbool.h",
"//third_party/libc++/src/include/stddef.h",
"//third_party/libc++/src/include/stdexcept",
"//third_party/libc++/src/include/stdint.h",
"//third_party/libc++/src/include/stdio.h",
"//third_party/libc++/src/include/stdlib.h",
"//third_party/libc++/src/include/stop_token",

View File

@@ -37,33 +37,6 @@ BrowserWindow.prototype._init = function (this: BWT) {
app.emit('browser-window-focus', event, this);
});
let unresponsiveEvent: NodeJS.Timeout | null = null;
const emitUnresponsiveEvent = () => {
unresponsiveEvent = null;
if (!this.isDestroyed() && this.isEnabled()) { this.emit('unresponsive'); }
};
this.webContents.on('unresponsive', () => {
if (!unresponsiveEvent) { unresponsiveEvent = setTimeout(emitUnresponsiveEvent, 50); }
});
this.webContents.on('responsive', () => {
if (unresponsiveEvent) {
clearTimeout(unresponsiveEvent);
unresponsiveEvent = null;
}
this.emit('responsive');
});
this.on('close', (event) => {
queueMicrotask(() => {
if (!unresponsiveEvent && !event.defaultPrevented) {
unresponsiveEvent = setTimeout(emitUnresponsiveEvent, 5000);
}
});
});
this.webContents.on('destroyed', () => {
if (unresponsiveEvent) clearTimeout(unresponsiveEvent);
unresponsiveEvent = null;
});
// Subscribe to visibilityState changes and pass to renderer process.
let isVisible = this.isVisible() && !this.isMinimized();
const visibilityChanged = () => {

View File

@@ -514,9 +514,9 @@ WebContents.prototype.canGoForward = function () {
};
const canGoToOffsetDeprecated = deprecate.warnOnce('webContents.canGoToOffset', 'webContents.navigationHistory.canGoToOffset');
WebContents.prototype.canGoToOffset = function (index: number) {
WebContents.prototype.canGoToOffset = function () {
canGoToOffsetDeprecated();
return this._canGoToOffset(index);
return this._canGoToOffset();
};
const clearHistoryDeprecated = deprecate.warnOnce('webContents.clearHistory', 'webContents.navigationHistory.clear');
@@ -549,6 +549,8 @@ WebContents.prototype.goToOffset = function (index: number) {
return this._goToOffset(index);
};
const consoleMessageDeprecated = deprecate.warnOnceMessage('\'console-message\' arguments are deprecated and will be removed. Please use Event<WebContentsConsoleMessageEventParams> object instead.');
// Add JavaScript wrappers for WebContents class.
WebContents.prototype._init = function () {
const prefs = this.getLastWebPreferences() || {};
@@ -909,11 +911,13 @@ WebContents.prototype._init = function () {
openDialogs.clear();
});
this.on('-unresponsive' as any, (event: Electron.Event<any>) => {
const shouldEmit = !event.shouldIgnore && event.visible && event.rendererInitialized;
if (shouldEmit) {
this.emit('unresponsive', event);
// TODO(samuelmaddock): remove deprecated 'console-message' arguments
this.on('-console-message' as any, (event: Electron.Event<Electron.WebContentsConsoleMessageEventParams>) => {
const hasDeprecatedListener = this.listeners('console-message').some(listener => listener.length > 1);
if (hasDeprecatedListener) {
consoleMessageDeprecated();
}
this.emit('console-message', event, (event as any)._level, event.message, event.lineNumber, event.sourceId);
});
app.emit('web-contents-created', { sender: this, preventDefault () {}, get defaultPrevented () { return false; } }, this);

View File

@@ -6,7 +6,7 @@ wrapFsWithAsar(require('fs'));
// See ElectronRendererClient::DidCreateScriptContext.
if ((globalThis as any).blinkfetch) {
const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers', 'EventSource'];
const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers'];
for (const key of keys) {
(globalThis as any)[key] = (globalThis as any)[`blink${key}`];
}

View File

@@ -15,7 +15,7 @@ export const windowSetup = (isWebView: boolean, isHiddenPage: boolean) => {
// But we do not support prompt().
window.prompt = function () {
throw new Error('prompt() is not supported.');
throw new Error('prompt() is and will not be supported.');
};
if (contextIsolationEnabled) internalContextBridge.overrideGlobalValueFromIsolatedWorld(['prompt'], window.prompt);

View File

@@ -19,7 +19,7 @@ global.require = makeRequireFunction(global.module);
// See WebWorkerObserver::WorkerScriptReadyForEvaluation.
if ((globalThis as any).blinkfetch) {
const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers', 'EventSource'];
const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers'];
for (const key of keys) {
(globalThis as any)[key] = (globalThis as any)[`blink${key}`];
}

View File

@@ -39,13 +39,14 @@
"folder-hash": "^2.1.1",
"got": "^11.8.5",
"husky": "^8.0.1",
"lint": "^1.1.2",
"lint-staged": "^10.2.11",
"markdownlint-cli2": "^0.13.0",
"minimist": "^1.2.8",
"null-loader": "^4.0.1",
"pre-flight": "^2.0.0",
"process": "^0.11.10",
"remark-cli": "^10.0.0",
"remark-cli": "^12.0.1",
"remark-preset-lint-markdown-style-guide": "^4.0.0",
"semver": "^7.6.3",
"shx": "^0.3.4",
@@ -57,7 +58,7 @@
"ts-node": "6.2.0",
"typescript": "^5.6.2",
"url": "^0.11.4",
"webpack": "^5.94.0",
"webpack": "^5.95.0",
"webpack-cli": "^5.1.4",
"wrapper-webpack-plugin": "^2.2.0"
},

View File

@@ -20,10 +20,10 @@ index 7de8923518dbfb69fef62d7781f906b30cf62155..7a4310d6d8e85f07f0ae6c97726d909c
case ssl_open_record_error:
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc
index f52030b8cd97d24d805963fd86a9e2b0da15af48..59cb15d5daa22fb87aa9012e25732e90bf5778a4 100644
index f0b3872e95d21646e6fb943f012a11287c1cf5a8..1f7bd4b503f6f4406248c1b48c2dc87f84e903c6 100644
--- a/ssl/ssl_lib.cc
+++ b/ssl/ssl_lib.cc
@@ -1339,7 +1339,7 @@ int SSL_get_error(const SSL *ssl, int ret_code) {
@@ -1337,7 +1337,7 @@ int SSL_get_error(const SSL *ssl, int ret_code) {
}
if (ret_code == 0) {
@@ -32,7 +32,7 @@ index f52030b8cd97d24d805963fd86a9e2b0da15af48..59cb15d5daa22fb87aa9012e25732e90
return SSL_ERROR_ZERO_RETURN;
}
// An EOF was observed which violates the protocol, and the underlying
@@ -2711,13 +2711,7 @@ void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) {
@@ -2709,13 +2709,7 @@ void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) {
return CRYPTO_get_ex_data(&ctx->ex_data, idx);
}

View File

@@ -133,7 +133,4 @@ osr_shared_texture_remove_keyed_mutex_on_win_dxgi.patch
feat_allow_usage_of_sccontentsharingpicker_on_supported_platforms.patch
chore_partial_revert_of.patch
fix_software_compositing_infinite_loop.patch
refactor_unfilter_unresponsive_events.patch
support_bstr_pkey_appusermodel_id_in_windows_shortcuts.patch
cherry-pick-1282289030ab.patch
cherry-pick-3dc17c461b12.patch
ui_add_missing_shortcut_text_for_vkey_command_on_linux.patch

View File

@@ -10,7 +10,7 @@ This patch makes three changes to Accelerator::GetShortcutText to improve shortc
3. Ctrl-Shift-= and Ctrl-Plus show up as such
diff --git a/ui/base/accelerators/accelerator.cc b/ui/base/accelerators/accelerator.cc
index 3bcdf9fccf4c391e4239e87a83194f04e683a02c..c6b110eced004ae755a2dfc555b0ceb43bf574fa 100644
index dc4bea32e76b41521240ad14e313aa2492539e30..32a3fc0843656eaa87b85dd63ac1ade6d83b6e5b 100644
--- a/ui/base/accelerators/accelerator.cc
+++ b/ui/base/accelerators/accelerator.cc
@@ -12,6 +12,7 @@
@@ -19,9 +19,9 @@ index 3bcdf9fccf4c391e4239e87a83194f04e683a02c..c6b110eced004ae755a2dfc555b0ceb4
#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/types/cxx23_to_underlying.h"
#include "build/build_config.h"
@@ -188,6 +189,11 @@ std::u16string Accelerator::GetShortcutText() const {
#include "build/chromeos_buildflags.h"
@@ -184,6 +185,11 @@ std::u16string Accelerator::GetShortcutText() const {
#endif
if (shortcut.empty()) {
@@ -33,7 +33,7 @@ index 3bcdf9fccf4c391e4239e87a83194f04e683a02c..c6b110eced004ae755a2dfc555b0ceb4
#if BUILDFLAG(IS_WIN)
// Our fallback is to try translate the key code to a regular character
// unless it is one of digits (VK_0 to VK_9). Some keyboard
@@ -212,6 +218,10 @@ std::u16string Accelerator::GetShortcutText() const {
@@ -207,6 +213,10 @@ std::u16string Accelerator::GetShortcutText() const {
shortcut +=
static_cast<std::u16string::value_type>(base::ToUpperASCII(c));
#endif
@@ -44,7 +44,7 @@ index 3bcdf9fccf4c391e4239e87a83194f04e683a02c..c6b110eced004ae755a2dfc555b0ceb4
}
#if BUILDFLAG(IS_MAC)
@@ -396,7 +406,7 @@ std::u16string Accelerator::ApplyLongFormModifiers(
@@ -391,7 +401,7 @@ std::u16string Accelerator::ApplyLongFormModifiers(
const std::u16string& shortcut) const {
std::u16string result = shortcut;
@@ -53,7 +53,7 @@ index 3bcdf9fccf4c391e4239e87a83194f04e683a02c..c6b110eced004ae755a2dfc555b0ceb4
result = ApplyModifierToAcceleratorString(result, IDS_APP_SHIFT_KEY);
// Note that we use 'else-if' in order to avoid using Ctrl+Alt as a shortcut.
@@ -404,7 +414,7 @@ std::u16string Accelerator::ApplyLongFormModifiers(
@@ -399,7 +409,7 @@ std::u16string Accelerator::ApplyLongFormModifiers(
// more information.
if (IsCtrlDown())
result = ApplyModifierToAcceleratorString(result, IDS_APP_CTRL_KEY);
@@ -63,7 +63,7 @@ index 3bcdf9fccf4c391e4239e87a83194f04e683a02c..c6b110eced004ae755a2dfc555b0ceb4
if (IsCmdDown()) {
diff --git a/ui/base/accelerators/accelerator.h b/ui/base/accelerators/accelerator.h
index 276f7ded0d6e60b65e461872e23b1f3380542037..94a60d9df75790c85ec93313dada260cdd65f947 100644
index d5fe7062b4d7932782a0b46371f316f8bf9b499d..adfc3b796379c65bd3406374a44b169560ca8795 100644
--- a/ui/base/accelerators/accelerator.h
+++ b/ui/base/accelerators/accelerator.h
@@ -16,6 +16,7 @@
@@ -74,7 +74,7 @@ index 276f7ded0d6e60b65e461872e23b1f3380542037..94a60d9df75790c85ec93313dada260c
#include "base/time/time.h"
#include "build/build_config.h"
#include "ui/events/event_constants.h"
@@ -132,6 +133,8 @@ class COMPONENT_EXPORT(UI_BASE) Accelerator {
@@ -130,6 +131,8 @@ class COMPONENT_EXPORT(UI_BASE) Accelerator {
return interrupted_by_mouse_event_;
}

View File

@@ -33,10 +33,10 @@ index 59ab3b746782c71f7d9401c13a7c866e6e7a823d..f95842da98d3a1d853633b53c745be9c
client->PostSandboxInitialized();
}
diff --git a/content/public/gpu/content_gpu_client.h b/content/public/gpu/content_gpu_client.h
index 351b97676ea1b928bedbb8a211d175684a166742..c54c452ef7a248982fa58dcd3b6b6f37bee4d13c 100644
index 3020e59f491f95740983b01c16e2a5be01d60f67..b25140275ce636717ca60a3cb17eb2f35f50d8be 100644
--- a/content/public/gpu/content_gpu_client.h
+++ b/content/public/gpu/content_gpu_client.h
@@ -31,6 +31,10 @@ class CONTENT_EXPORT ContentGpuClient {
@@ -30,6 +30,10 @@ class CONTENT_EXPORT ContentGpuClient {
public:
virtual ~ContentGpuClient() {}

View File

@@ -23,10 +23,10 @@ index ad0092ef2e13853e4bb8b923481559a043b00ab7..1c2dfd23f18733e21312992877ae1499
int32_t world_id) {}
virtual void DidClearWindowObject() {}
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 3d0544422f05e2edc02921fc39335bf10184028e..bf44c1ffef7df44448ee7b5b176c33348599f0be 100644
index 6e8b3fbcc9c553a725bbd8e5a710be6be239a88b..ba7cb724f30582b51fd53cad99271b0651eff08c 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -4792,6 +4792,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
@@ -4781,6 +4781,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
observer.DidCreateScriptContext(context, world_id);
}
@@ -40,7 +40,7 @@ index 3d0544422f05e2edc02921fc39335bf10184028e..bf44c1ffef7df44448ee7b5b176c3334
int world_id) {
for (auto& observer : observers_)
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 0980dad73ed2d5cbcbabee8f7d6fc827bb31b623..fcc651f75677ad1ae25e4edc5e2ae9a82ddd31d0 100644
index 764763cb6967cb365882083fc4c0572869cc962a..85d682d3233bd10fbe54a050280649e3a82f9a00 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -651,6 +651,8 @@ class CONTENT_EXPORT RenderFrameImpl
@@ -53,10 +53,10 @@ index 0980dad73ed2d5cbcbabee8f7d6fc827bb31b623..fcc651f75677ad1ae25e4edc5e2ae9a8
int world_id) override;
void DidChangeScrollOffset() override;
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h
index 403d654e9a5c1196ac11cccce45c8c53b03275f3..2e03b5f2fea36d9bdf71b4bb15c604de2dc3cf5c 100644
index 8ebdaf39d5cc0539b24b843d82937adbe12a51d1..201d2bfaf21a92274d475d9a790ca9334ffbdd92 100644
--- a/third_party/blink/public/web/web_local_frame_client.h
+++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -665,6 +665,9 @@ class BLINK_EXPORT WebLocalFrameClient {
@@ -664,6 +664,9 @@ class BLINK_EXPORT WebLocalFrameClient {
virtual void DidCreateScriptContext(v8::Local<v8::Context>,
int32_t world_id) {}
@@ -79,7 +79,7 @@ index f7e0144c74f879e9b29871d7c372b99e127966bb..c3cd7b77ed282f212a56d151dc3fbec3
if (World().IsMainWorld()) {
probe::DidCreateMainWorldContext(GetFrame());
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h
index d4fe8d76a94eeb27aed8f2261394edc0acdf5694..5af657a1f20949fb4df7b101aa27ed0cd29c89ca 100644
index 4864efd047b38c19ac4b35cf4a2a46218347433c..4abcf88eba9e8e52f4041e0826094a8015915eaf 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client.h
+++ b/third_party/blink/renderer/core/frame/local_frame_client.h
@@ -301,6 +301,8 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
@@ -92,7 +92,7 @@ index d4fe8d76a94eeb27aed8f2261394edc0acdf5694..5af657a1f20949fb4df7b101aa27ed0c
int32_t world_id) = 0;
virtual bool AllowScriptExtensions() = 0;
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
index 0975fc371a20d21df2dd9d08986c665237d6d38f..63c365ed8dd65f6b15b3d887aa2d7f2f18111eb7 100644
index bb6090802668ec1886083eaf2645c8745c0ee8c3..0679fabb71a1717f0676a8a08a91a853f617e46f 100644
--- a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
@@ -294,6 +294,13 @@ void LocalFrameClientImpl::DidCreateScriptContext(
@@ -110,7 +110,7 @@ index 0975fc371a20d21df2dd9d08986c665237d6d38f..63c365ed8dd65f6b15b3d887aa2d7f2f
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 526a61b4e9ecb3f0343dcafa6b17e7b24c8db830..5b16f232c651c428ebc150b427dedd73fcd25e2f 100644
index b9aff56f283b10e899c2291f90615cbd3795454c..59f040cead445b02442404c787c1015cc3029b94 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
@@ -83,6 +83,8 @@ class CORE_EXPORT LocalFrameClientImpl final : public LocalFrameClient {
@@ -123,7 +123,7 @@ index 526a61b4e9ecb3f0343dcafa6b17e7b24c8db830..5b16f232c651c428ebc150b427dedd73
int32_t world_id) override;
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h
index fb56366d4d8cf46dee3403081be752f86d0713c8..4e5954fe78c3a240dba043b4746b706c1de981cd 100644
index 3756c89c0ae70a802506aeac66ea26093831d88f..0d65071421e21edd77de0d2463061e6a05049121 100644
--- a/third_party/blink/renderer/core/loader/empty_clients.h
+++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -415,6 +415,8 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {

View File

@@ -7,10 +7,10 @@ Ensure that licenses for the dependencies introduced by Electron
are included in `LICENSES.chromium.html`
diff --git a/tools/licenses/licenses.py b/tools/licenses/licenses.py
index 2a65975667a9fbedc0f9f108abb67dc6038eaf47..d6205d9fd0eea97d5ed85c2c4994d20c174379a7 100755
index f72e5cdb2a889775e7d72b8dea992ac562c5dde3..03dda85dd9b390ee1ad69c1a5325e7588cfcd741 100755
--- a/tools/licenses/licenses.py
+++ b/tools/licenses/licenses.py
@@ -336,6 +336,31 @@ SPECIAL_CASES = {
@@ -335,6 +335,31 @@ SPECIAL_CASES = {
"License": "Apache 2.0",
"License File": ["//third_party/dawn/third_party/khronos/LICENSE"],
},

View File

@@ -8,7 +8,7 @@ decorations in maximized mode where needed, preventing empty space caused
by decoration shadows and rounded titlebars around the window while maximized.
diff --git a/ui/gtk/gtk_ui.cc b/ui/gtk/gtk_ui.cc
index 771c253082e2ab1103fd22218d56bf1a8d5ba7ab..d50528171925436a34ddd61ff7a0e7dee998d10c 100644
index 69fdf309dbb71e1d2a2d258d15df1ffde3b14841..57052ded8b7d52932b1a217c2f6cb97abd65c2a5 100644
--- a/ui/gtk/gtk_ui.cc
+++ b/ui/gtk/gtk_ui.cc
@@ -584,11 +584,12 @@ std::unique_ptr<ui::NavButtonProvider> GtkUi::CreateNavButtonProvider() {

View File

@@ -10,7 +10,7 @@ usage of BrowserList and Browser as we subclass related methods and use our
WindowList.
diff --git a/chrome/browser/ui/webui/accessibility/accessibility_ui.cc b/chrome/browser/ui/webui/accessibility/accessibility_ui.cc
index 12fdd6a6d47b9e2778d9d136f016c942b9e1fc4e..3660d4685f888de1a0610a09fe70c74c8540a3f5 100644
index 12066e1449141a1d498d6f17d3a18feda94f56b8..0af673fb8c2fcaa37876d1e2c658233e08007056 100644
--- a/chrome/browser/ui/webui/accessibility/accessibility_ui.cc
+++ b/chrome/browser/ui/webui/accessibility/accessibility_ui.cc
@@ -48,6 +48,7 @@
@@ -62,7 +62,7 @@ index 12fdd6a6d47b9e2778d9d136f016c942b9e1fc4e..3660d4685f888de1a0610a09fe70c74c
data.Set(kBrowsersField, std::move(browser_list));
base::Value::List widgets_list;
@@ -645,7 +646,8 @@ void AccessibilityUIMessageHandler::SetGlobalString(
@@ -646,7 +647,8 @@ void AccessibilityUIMessageHandler::SetGlobalString(
const std::string value = CheckJSValue(data.FindString(kValueField));
if (string_name == kApiTypeField) {
@@ -72,7 +72,7 @@ index 12fdd6a6d47b9e2778d9d136f016c942b9e1fc4e..3660d4685f888de1a0610a09fe70c74c
pref->SetString(prefs::kShownAccessibilityApiType, value);
}
}
@@ -698,7 +700,8 @@ void AccessibilityUIMessageHandler::RequestWebContentsTree(
@@ -699,7 +701,8 @@ void AccessibilityUIMessageHandler::RequestWebContentsTree(
AXPropertyFilter::ALLOW_EMPTY);
AddPropertyFilters(property_filters, deny, AXPropertyFilter::DENY);
@@ -82,7 +82,7 @@ index 12fdd6a6d47b9e2778d9d136f016c942b9e1fc4e..3660d4685f888de1a0610a09fe70c74c
ui::AXApiType::Type api_type =
ui::AXApiType::From(pref->GetString(prefs::kShownAccessibilityApiType));
std::string accessibility_contents =
@@ -725,6 +728,7 @@ void AccessibilityUIMessageHandler::RequestNativeUITree(
@@ -726,6 +729,7 @@ void AccessibilityUIMessageHandler::RequestNativeUITree(
AXPropertyFilter::ALLOW_EMPTY);
AddPropertyFilters(property_filters, deny, AXPropertyFilter::DENY);
@@ -90,7 +90,7 @@ index 12fdd6a6d47b9e2778d9d136f016c942b9e1fc4e..3660d4685f888de1a0610a09fe70c74c
for (Browser* browser : *BrowserList::GetInstance()) {
if (browser->session_id().id() == session_id) {
base::Value::Dict result = BuildTargetDescriptor(browser);
@@ -737,6 +741,7 @@ void AccessibilityUIMessageHandler::RequestNativeUITree(
@@ -738,6 +742,7 @@ void AccessibilityUIMessageHandler::RequestNativeUITree(
return;
}
}
@@ -98,7 +98,7 @@ index 12fdd6a6d47b9e2778d9d136f016c942b9e1fc4e..3660d4685f888de1a0610a09fe70c74c
#endif // !BUILDFLAG(IS_ANDROID)
// No browser with the specified |session_id| was found.
base::Value::Dict result;
@@ -805,11 +810,13 @@ void AccessibilityUIMessageHandler::StopRecording(
@@ -806,11 +811,13 @@ void AccessibilityUIMessageHandler::StopRecording(
}
ui::AXApiType::Type AccessibilityUIMessageHandler::GetRecordingApiType() {
@@ -115,7 +115,7 @@ index 12fdd6a6d47b9e2778d9d136f016c942b9e1fc4e..3660d4685f888de1a0610a09fe70c74c
// Check to see if it is in the supported types list.
if (std::find(supported_types.begin(), supported_types.end(), api_type) ==
supported_types.end()) {
@@ -879,8 +886,11 @@ void AccessibilityUIMessageHandler::RequestAccessibilityEvents(
@@ -880,8 +887,11 @@ void AccessibilityUIMessageHandler::RequestAccessibilityEvents(
// static
void AccessibilityUIMessageHandler::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {

View File

@@ -23,10 +23,10 @@ index e392efaf2e1ac3cfbef2d787ba40f0491b67f3cc..d45c7570484a7c1bfca25c860a1ddd2d
return receiver_.BindNewEndpointAndPassDedicatedRemote();
}
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index 4675bec818108c5c28f582d3bcffac0b760ff266..c201a7e44ac992e38ed85456be9d69bfc0a843a3 100644
index b1196c76de2092b41c139b040cef0915b9a1015e..5583bcd62964a2d9d5ed6223034b4201d5bc7932 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -754,6 +754,11 @@ void RenderViewHostImpl::SetBackgroundOpaque(bool opaque) {
@@ -760,6 +760,11 @@ void RenderViewHostImpl::SetBackgroundOpaque(bool opaque) {
GetWidget()->GetAssociatedFrameWidget()->SetBackgroundOpaque(opaque);
}
@@ -39,7 +39,7 @@ index 4675bec818108c5c28f582d3bcffac0b760ff266..c201a7e44ac992e38ed85456be9d69bf
return is_active();
}
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h
index 5fb8a3dc69dc5fc5bfa08e01d8f03707a23c9274..41774b60b8cb7e0a22cedc597dc07ad15c96988c 100644
index 961e55732d9c3aa5437e9cc6eca7a2c8d06bd335..f0fc8d303dc9de2419d5f5d769657faf98caa22a 100644
--- a/content/browser/renderer_host/render_view_host_impl.h
+++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -135,6 +135,7 @@ class CONTENT_EXPORT RenderViewHostImpl
@@ -51,10 +51,10 @@ index 5fb8a3dc69dc5fc5bfa08e01d8f03707a23c9274..41774b60b8cb7e0a22cedc597dc07ad1
void SendRendererPreferencesToRenderer(
const blink::RendererPreferences& preferences);
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index b8c1377d3144031f108bc79dc49d81a4ffbdb68d..1f9d5dde9099232ecb48557a28d545b2ec6f8f2e 100644
index dff505e44145b630c03715bf4c2e5ff8a264602e..233a352c5c2cb5ce66fc67989a0d93a3d08523c6 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -586,8 +586,8 @@ void RenderWidgetHostViewAura::ShowImpl(PageVisibilityState page_visibility) {
@@ -585,8 +585,8 @@ void RenderWidgetHostViewAura::ShowImpl(PageVisibilityState page_visibility) {
// OnShowWithPageVisibility will not call NotifyHostAndDelegateOnWasShown,
// which updates `visibility_`, unless the host is hidden. Make sure no update
// is needed.
@@ -104,10 +104,10 @@ index c980f3f76a37a4207bb54f18fbcdb8d0950c8856..91a9dfe56fbbcd1cc873add438947dd2
+ SetSchedulerThrottling(bool allowed);
};
diff --git a/third_party/blink/public/web/web_view.h b/third_party/blink/public/web/web_view.h
index 083af135d890c2837e72c314e170e81931bd2a20..5245ea88441ef84c15b8052a9011ce70b8e9b848 100644
index 746af7113a66d26de389237ebd90ec9e6a569cc3..f2f14184eafc919a303da6679a516bdd3a825a51 100644
--- a/third_party/blink/public/web/web_view.h
+++ b/third_party/blink/public/web/web_view.h
@@ -371,6 +371,7 @@ class BLINK_EXPORT WebView {
@@ -368,6 +368,7 @@ class BLINK_EXPORT WebView {
// Scheduling -----------------------------------------------------------
virtual PageScheduler* Scheduler() const = 0;
@@ -116,10 +116,10 @@ index 083af135d890c2837e72c314e170e81931bd2a20..5245ea88441ef84c15b8052a9011ce70
// 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 ad134361e0b9c9a9db4cec06c429102d5dbe0c4e..82aef58c0a3c00c818e0d60df9a5296162c57cc3 100644
index b5281ba47164159d10ca16b7641cfdc8a4bfbbef..734c055e1828d790f2abb80243bc10fa1f4d6e5e 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -2456,6 +2456,10 @@ void WebViewImpl::SetPageLifecycleStateInternal(
@@ -2447,6 +2447,10 @@ void WebViewImpl::SetPageLifecycleStateInternal(
TRACE_EVENT2("navigation", "WebViewImpl::SetPageLifecycleStateInternal",
"old_state", old_state, "new_state", new_state);
@@ -130,7 +130,7 @@ index ad134361e0b9c9a9db4cec06c429102d5dbe0c4e..82aef58c0a3c00c818e0d60df9a52961
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 &&
@@ -3988,10 +3992,23 @@ PageScheduler* WebViewImpl::Scheduler() const {
@@ -3969,10 +3973,23 @@ PageScheduler* WebViewImpl::Scheduler() const {
return GetPage()->GetPageScheduler();
}
@@ -155,7 +155,7 @@ index ad134361e0b9c9a9db4cec06c429102d5dbe0c4e..82aef58c0a3c00c818e0d60df9a52961
// Do not throttle if the page should be painting.
bool is_visible =
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h
index e4784453b357e2a9c18ccf5acfde43f5afd583ae..2c5a9f08ac34ae4106f25c42dca04f78ae703618 100644
index bd7c22360193d52e1acf5a8dc82e3da34285ea37..78aabb76e02b7713d47242c28b0b7a3818faf6e9 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.h
+++ b/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -448,6 +448,7 @@ class CORE_EXPORT WebViewImpl final : public WebView,
@@ -166,7 +166,7 @@ index e4784453b357e2a9c18ccf5acfde43f5afd583ae..2c5a9f08ac34ae4106f25c42dca04f78
void SetVisibilityState(mojom::blink::PageVisibilityState visibility_state,
bool is_initial_state) override;
mojom::blink::PageVisibilityState GetVisibilityState() override;
@@ -936,6 +937,8 @@ class CORE_EXPORT WebViewImpl final : public WebView,
@@ -929,6 +930,8 @@ class CORE_EXPORT WebViewImpl final : public WebView,
// If true, we send IPC messages when |preferred_size_| changes.
bool send_preferred_size_changes_ = false;

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