Compare commits

..

2 Commits

Author SHA1 Message Date
Sam Maddock
73f6452fec Update lib/node/asar-fs-wrapper.ts 2025-03-18 11:24:35 -04:00
Shelley Vohr
b5feaf9ba7 fix: asar handling of package.json 2025-03-18 10:33:46 +01:00
1052 changed files with 17008 additions and 35315 deletions

View File

@@ -1,5 +1,4 @@
{ {
"name": "Electron Core Development Environment",
"dockerComposeFile": "docker-compose.yml", "dockerComposeFile": "docker-compose.yml",
"service": "buildtools", "service": "buildtools",
"onCreateCommand": ".devcontainer/on-create-command.sh", "onCreateCommand": ".devcontainer/on-create-command.sh",
@@ -34,15 +33,27 @@
"surajbarkale.ninja", "surajbarkale.ninja",
"ms-vscode.cpptools", "ms-vscode.cpptools",
"mutantdino.resourcemonitor", "mutantdino.resourcemonitor",
"dsanders11.vscode-electron-build-tools",
"dbaeumer.vscode-eslint", "dbaeumer.vscode-eslint",
"shakram02.bash-beautify", "shakram02.bash-beautify",
"marshallofsound.gnls-electron" "marshallofsound.gnls-electron",
], ],
"settings": { "settings": {
"editor.tabSize": 2, "editor.tabSize": 2,
"bashBeautify.tabSize": 2, "bashBeautify.tabSize": 2,
"typescript.tsdk": "node_modules/typescript/lib", "typescript.tsdk": "node_modules/typescript/lib",
"[gn]": {
"editor.formatOnSave": true
},
"[javascript]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
},
"[typescript]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
},
"javascript.preferences.quoteStyle": "single", "javascript.preferences.quoteStyle": "single",
"typescript.preferences.quoteStyle": "single" "typescript.preferences.quoteStyle": "single"
} }

View File

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

View File

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

View File

@@ -58,16 +58,6 @@ body:
label: Last Known Working Electron version label: Last Known Working Electron version
description: What is the last version of Electron this worked in, if applicable? description: What is the last version of Electron this worked in, if applicable?
placeholder: 16.0.0 placeholder: 16.0.0
- type: dropdown
attributes:
label: Does the issue also appear in Chromium / Google Chrome?
description: If it does, please report the issue in the [Chromium issue tracker](https://issues.chromium.org/issues), not against Electron. Electron will inherit the fix once Chromium resolves the issue.
options:
- I don't know how to test
- "Yes"
- "No"
validations:
required: true
- type: textarea - type: textarea
attributes: attributes:
label: Expected Behavior label: Expected Behavior
@@ -83,7 +73,7 @@ body:
- type: input - type: input
attributes: attributes:
label: Testcase Gist URL label: Testcase Gist URL
description: Electron maintainers need a standalone test case to reproduce and fix your issue. Please use [Electron Fiddle](https://github.com/electron/fiddle) to create one and to publish it as a [GitHub gist](https://gist.github.com). Then put the gist URL here. Issues without testcase gists receive less attention and might be closed without a maintainer taking a closer look. To maximize how much attention your issue receives, please include a testcase gist right from the start. description: If you can reproduce the issue in a standalone test case, please use [Electron Fiddle](https://github.com/electron/fiddle) to create one and to publish it as a [GitHub gist](https://gist.github.com) and put the gist URL here. This is **the best way** to ensure this issue is triaged quickly.
placeholder: https://gist.github.com/... placeholder: https://gist.github.com/...
- type: textarea - type: textarea
attributes: attributes:

View File

@@ -17,6 +17,9 @@ inputs:
is-release: is-release:
description: 'Is release build' description: 'Is release build'
required: true required: true
strip-binaries:
description: 'Strip binaries (Linux only)'
required: false
generate-symbols: generate-symbols:
description: 'Generate symbols' description: 'Generate symbols'
required: true required: true
@@ -35,15 +38,6 @@ runs:
run: | run: |
GN_APPENDED_ARGS="$GN_EXTRA_ARGS target_cpu=\"x64\" v8_snapshot_toolchain=\"//build/toolchain/mac:clang_x64\"" GN_APPENDED_ARGS="$GN_EXTRA_ARGS target_cpu=\"x64\" v8_snapshot_toolchain=\"//build/toolchain/mac:clang_x64\""
echo "GN_EXTRA_ARGS=$GN_APPENDED_ARGS" >> $GITHUB_ENV echo "GN_EXTRA_ARGS=$GN_APPENDED_ARGS" >> $GITHUB_ENV
- name: Set GN_EXTRA_ARGS for Windows
shell: bash
if: ${{inputs.target-arch != 'x64' && inputs.target-platform == 'win' }}
run: |
GN_APPENDED_ARGS="$GN_EXTRA_ARGS target_cpu=\"${{ inputs.target-arch }}\""
echo "GN_EXTRA_ARGS=$GN_APPENDED_ARGS" >> $GITHUB_ENV
- name: Add Clang problem matcher
shell: bash
run: echo "::add-matcher::src/electron/.github/problem-matchers/clang.json"
- name: Build Electron ${{ inputs.step-suffix }} - name: Build Electron ${{ inputs.step-suffix }}
shell: bash shell: bash
run: | run: |
@@ -60,14 +54,22 @@ runs:
sudo launchctl limit maxfiles 65536 200000 sudo launchctl limit maxfiles 65536 200000
fi fi
NINJA_SUMMARIZE_BUILD=1 e build NINJA_SUMMARIZE_BUILD=1 e build -j $NUMBER_OF_NINJA_PROCESSES
cp out/Default/.ninja_log out/electron_ninja_log cp out/Default/.ninja_log out/electron_ninja_log
node electron/script/check-symlinks.js node electron/script/check-symlinks.js
- name: Strip Electron Binaries ${{ inputs.step-suffix }}
shell: bash
if: ${{ inputs.strip-binaries == 'true' }}
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/add-debug-link.py --target-cpu="${{ inputs.target-arch }}" --debug-dir=out/Default/debug
- name: Build Electron dist.zip ${{ inputs.step-suffix }} - name: Build Electron dist.zip ${{ inputs.step-suffix }}
shell: bash shell: bash
run: | run: |
cd src cd src
e build --target electron:electron_dist_zip e build --target electron:electron_dist_zip -j $NUMBER_OF_NINJA_PROCESSES -d explain
if [ "${{ inputs.is-asan }}" != "true" ]; then if [ "${{ inputs.is-asan }}" != "true" ]; then
target_os=${{ inputs.target-platform == 'macos' && 'mac' || inputs.target-platform }} target_os=${{ inputs.target-platform == 'macos' && 'mac' || inputs.target-platform }}
if [ "${{ inputs.artifact-platform }}" = "mas" ]; then if [ "${{ inputs.artifact-platform }}" = "mas" ]; then
@@ -79,7 +81,7 @@ runs:
shell: bash shell: bash
run: | run: |
cd src cd src
e build --target electron:electron_mksnapshot_zip 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 ELECTRON_DEPOT_TOOLS_DISABLE_LOG=1 e d gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
# Remove unused args from mksnapshot_args # Remove unused args from mksnapshot_args
SEDOPTION="-i" SEDOPTION="-i"
@@ -89,6 +91,20 @@ runs:
sed $SEDOPTION '/.*builtins-pgo/d' out/Default/mksnapshot_args sed $SEDOPTION '/.*builtins-pgo/d' out/Default/mksnapshot_args
sed $SEDOPTION '/--turbo-profiling-input/d' out/Default/mksnapshot_args sed $SEDOPTION '/--turbo-profiling-input/d' out/Default/mksnapshot_args
if [ "${{ inputs.target-platform }}" = "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
elif [ "${{ inputs.target-arch }}" = "arm64" ]; then
electron/script/strip-binaries.py --file $PWD/out/Default/clang_x64_v8_arm64/mksnapshot
electron/script/strip-binaries.py --file $PWD/out/Default/clang_x64_v8_arm64/v8_context_snapshot_generator
else
electron/script/strip-binaries.py --file $PWD/out/Default/mksnapshot
electron/script/strip-binaries.py --file $PWD/out/Default/v8_context_snapshot_generator
fi
fi
e build --target electron:electron_mksnapshot_zip -j $NUMBER_OF_NINJA_PROCESSES
if [ "${{ inputs.target-platform }}" = "win" ]; then if [ "${{ inputs.target-platform }}" = "win" ]; then
cd out/Default cd out/Default
powershell Compress-Archive -update mksnapshot_args mksnapshot.zip powershell Compress-Archive -update mksnapshot_args mksnapshot.zip
@@ -122,15 +138,8 @@ runs:
shell: bash shell: bash
run: | run: |
cd src cd src
e build --target electron:electron_chromedriver -j $NUMBER_OF_NINJA_PROCESSES
e build --target electron:electron_chromedriver_zip e build --target electron:electron_chromedriver_zip
if [ "${{ inputs.is-asan }}" != "true" ]; then
target_os=${{ inputs.target-platform == 'macos' && 'mac' || inputs.target-platform }}
if [ "${{ inputs.artifact-platform }}" = "mas" ]; then
target_os="${target_os}_mas"
fi
electron/script/zip_manifests/check-zip-manifest.py out/Default/chromedriver.zip electron/script/zip_manifests/chromedriver_zip.$target_os.${{ inputs.target-arch }}.manifest
fi
- name: Build Node.js headers ${{ inputs.step-suffix }} - name: Build Node.js headers ${{ inputs.step-suffix }}
shell: bash shell: bash
run: | run: |
@@ -176,23 +185,20 @@ runs:
if: ${{ inputs.is-release == 'true' }} if: ${{ inputs.is-release == 'true' }}
run: | run: |
cd src cd src
gn gen out/ffmpeg --args="import(\"//electron/build/args/ffmpeg.gn\") use_remoteexec=true use_siso=true $GN_EXTRA_ARGS" gn gen out/ffmpeg --args="import(\"//electron/build/args/ffmpeg.gn\") use_remoteexec=true $GN_EXTRA_ARGS"
e build --target electron:electron_ffmpeg_zip -C ../../out/ffmpeg e build --target electron:electron_ffmpeg_zip -C ../../out/ffmpeg -j $NUMBER_OF_NINJA_PROCESSES
- name: Generate Hunspell Dictionaries ${{ inputs.step-suffix }} - name: Generate Hunspell Dictionaries ${{ inputs.step-suffix }}
shell: bash shell: bash
if: ${{ inputs.is-release == 'true' && inputs.target-platform == 'linux' }} if: ${{ inputs.is-release == 'true' && inputs.target-platform == 'linux' }}
run: | run: |
e build --target electron:hunspell_dictionaries_zip e build --target electron:hunspell_dictionaries_zip -j $NUMBER_OF_NINJA_PROCESSES
- name: Generate Libcxx ${{ inputs.step-suffix }} - name: Generate Libcxx ${{ inputs.step-suffix }}
shell: bash shell: bash
if: ${{ inputs.is-release == 'true' && inputs.target-platform == 'linux' }} if: ${{ inputs.is-release == 'true' && inputs.target-platform == 'linux' }}
run: | run: |
e build --target electron:libcxx_headers_zip e build --target electron:libcxx_headers_zip -j $NUMBER_OF_NINJA_PROCESSES
e build --target electron:libcxxabi_headers_zip e build --target electron:libcxxabi_headers_zip -j $NUMBER_OF_NINJA_PROCESSES
e build --target electron:libcxx_objects_zip e build --target electron:libcxx_objects_zip -j $NUMBER_OF_NINJA_PROCESSES
- name: Remove Clang problem matcher
shell: bash
run: echo "::remove-matcher owner=clang::"
- name: Generate TypeScript Definitions ${{ inputs.step-suffix }} - name: Generate TypeScript Definitions ${{ inputs.step-suffix }}
if: ${{ inputs.is-release == 'true' }} if: ${{ inputs.is-release == 'true' }}
shell: bash shell: bash
@@ -212,29 +218,7 @@ runs:
echo 'Uploading Electron release distribution to GitHub releases' echo 'Uploading Electron release distribution to GitHub releases'
script/release/uploaders/upload.py --verbose script/release/uploaders/upload.py --verbose
fi fi
- name: Generate siso report
if: ${{ inputs.target-platform != 'win' && !cancelled() }}
shell: bash
run: |
cd src
e d siso report -C out/Default > siso_report.txt
SISO_REPORT_PATH=$(grep -o '/.*siso-report-[^ ]*' siso_report.txt)
echo "SISO_REPORT_PATH=$SISO_REPORT_PATH" >> $GITHUB_ENV
cat siso_report.txt
echo "SISO REPORT AT $SISO_REPORT_PATH"
- name: Generate siso report (Windows)
if: ${{ inputs.target-platform == 'win' && !cancelled() }}
shell: powershell
run: |
cd src
e d siso report -C out\Default > siso_report.txt
$SISO_REPORT_PATH = Get-Content "siso_report.txt" | Select-String "report file:\s*(.+)" | ForEach-Object {
$_.Matches.Groups[1].Value.Trim()
}
echo "SISO_REPORT_PATH=$SISO_REPORT_PATH"
echo "SISO_REPORT_PATH=$SISO_REPORT_PATH" >> $env:GITHUB_ENV
- name: Generate Artifact Key - name: Generate Artifact Key
if: always() && !cancelled()
shell: bash shell: bash
run: | run: |
if [ "${{ inputs.is-asan }}" = "true" ]; then if [ "${{ inputs.is-asan }}" = "true" ]; then
@@ -246,11 +230,9 @@ runs:
# The current generated_artifacts_<< artifact.key >> name was taken from CircleCI # The current generated_artifacts_<< artifact.key >> name was taken from CircleCI
# to ensure we don't break anything, but we may be able to improve that. # to ensure we don't break anything, but we may be able to improve that.
- name: Move all Generated Artifacts to Upload Folder ${{ inputs.step-suffix }} - name: Move all Generated Artifacts to Upload Folder ${{ inputs.step-suffix }}
if: always() && !cancelled()
shell: bash shell: bash
run: ./src/electron/script/actions/move-artifacts.sh run: ./src/electron/script/actions/move-artifacts.sh
- name: Upload Generated Artifacts ${{ inputs.step-suffix }} - name: Upload Generated Artifacts ${{ inputs.step-suffix }}
if: always() && !cancelled()
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
with: with:
name: generated_artifacts_${{ env.ARTIFACT_KEY }} name: generated_artifacts_${{ env.ARTIFACT_KEY }}

View File

@@ -1,83 +0,0 @@
name: 'Build Git Cache'
description: 'Runs a gclient sync to build the git cache for Electron'
inputs:
target-platform:
description: 'Target platform, should be linux, win, macos'
runs:
using: "composite"
steps:
- name: Set GIT_CACHE_PATH to make gclient to use the cache
shell: bash
run: |
echo "GIT_CACHE_PATH=$(pwd)/git-cache" >> $GITHUB_ENV
- name: Set Chromium Git Cookie
uses: ./src/electron/.github/actions/set-chromium-cookie
- name: Install Build Tools
uses: ./src/electron/.github/actions/install-build-tools
- name: Set up cache drive
shell: bash
run: |
if [ "${{ inputs.target-platform }}" = "win" ]; then
echo "CACHE_DRIVE=/mnt/win-cache" >> $GITHUB_ENV
else
echo "CACHE_DRIVE=/mnt/cross-instance-cache" >> $GITHUB_ENV
fi
- name: Check cross instance cache disk space
shell: bash
run: |
# if there is less than 35 GB free space then creating the cache might fail so exit early
freespace=`df -m $CACHE_DRIVE | grep -w $CACHE_DRIVE | awk '{print $4}'`
freespace_human=`df -h $CACHE_DRIVE | grep -w $CACHE_DRIVE | awk '{print $4}'`
if [ $freespace -le 35000 ]; 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"
fi
- name: Restore gitcache
shell: bash
run: |
GIT_CACHE_TAR="$CACHE_DRIVE/gitcache.tar"
if [ ! -f "$GIT_CACHE_TAR" ]; then
echo "Git cache tar file does not exist, skipping restore"
exit 0
fi
echo "Restoring git cache from $GIT_CACHE_TAR to $GIT_CACHE_PATH"
mkdir -p $GIT_CACHE_PATH
tar -xf $GIT_CACHE_TAR -C $GIT_CACHE_PATH
- name: Gclient Sync
shell: bash
run: |
e d 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 --nohooks -vv
- name: Compress Git Cache Directory
shell: bash
run: |
echo "Uncompressed gitcache size: $(du -sh $GIT_CACHE_PATH | cut -f1 -d' ')"
cd $GIT_CACHE_PATH
tar -cf ../gitcache.tar .
cd ..
echo "Compressed gitcache to $(du -sh gitcache.tar | cut -f1 -d' ')"
# remove the old cache file if it exists
if [ -f $CACHE_DRIVE/gitcache.tar ]; then
echo "Removing old gitcache.tar from $CACHE_DRIVE"
rm $CACHE_DRIVE/gitcache.tar
fi
cp ./gitcache.tar $CACHE_DRIVE/
- name: Wait for active SSH sessions
shell: bash
if: always() && !cancelled()
run: |
while [ -f /var/.ssh-lock ]
do
sleep 60
done

View File

@@ -9,8 +9,6 @@ inputs:
description: 'Whether to persist the cache to the shared drive' description: 'Whether to persist the cache to the shared drive'
required: false required: false
default: 'true' default: 'true'
target-platform:
description: 'Target platform, should be linux, win, macos'
runs: runs:
using: "composite" using: "composite"
steps: steps:
@@ -20,34 +18,40 @@ runs:
echo "GIT_CACHE_PATH=$(pwd)/git-cache" >> $GITHUB_ENV echo "GIT_CACHE_PATH=$(pwd)/git-cache" >> $GITHUB_ENV
- name: Install Dependencies - name: Install Dependencies
uses: ./src/electron/.github/actions/install-dependencies uses: ./src/electron/.github/actions/install-dependencies
- name: Set Chromium Git Cookie
uses: ./src/electron/.github/actions/set-chromium-cookie
- name: Install Build Tools - name: Install Build Tools
uses: ./src/electron/.github/actions/install-build-tools uses: ./src/electron/.github/actions/install-build-tools
- name: Set Chromium Git Cookie
uses: ./src/electron/.github/actions/set-chromium-cookie
- 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
# Ensure depot_tools does not update.
test -d depot_tools && cd depot_tools
touch .disable_auto_update
fi
- name: Add Depot Tools to PATH
shell: bash
run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
- name: Generate DEPS Hash - name: Generate DEPS Hash
shell: bash shell: bash
run: | run: |
node src/electron/script/generate-deps-hash.js node src/electron/script/generate-deps-hash.js
DEPSHASH="v1-src-cache-$(cat src/electron/.depshash)" echo "DEPSHASH=v1-src-cache-$(cat src/electron/.depshash)" >> $GITHUB_ENV
echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
echo "CACHE_FILE=$DEPSHASH.tar" >> $GITHUB_ENV
if [ "${{ inputs.target-platform }}" = "win" ]; then
echo "CACHE_DRIVE=/mnt/win-cache" >> $GITHUB_ENV
else
echo "CACHE_DRIVE=/mnt/cross-instance-cache" >> $GITHUB_ENV
fi
- name: Generate SAS Key - name: Generate SAS Key
if: ${{ inputs.generate-sas-token == 'true' }} if: ${{ inputs.generate-sas-token == 'true' }}
shell: bash shell: bash
run: | run: |
curl --unix-socket /var/run/sas/sas.sock --fail "http://foo/$CACHE_FILE?platform=${{ inputs.target-platform }}&getAccountName=true" > sas-token curl --unix-socket /var/run/sas/sas.sock --fail "http://foo/$DEPSHASH.tar" > sas-token
- name: Save SAS Key - name: Save SAS Key
if: ${{ inputs.generate-sas-token == 'true' }} if: ${{ inputs.generate-sas-token == 'true' }}
uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57
with: with:
path: sas-token path: |
key: sas-key-${{ inputs.target-platform }}-${{ github.run_number }}-${{ github.run_attempt }} sas-token
enableCrossOsArchive: true key: sas-key-${{ github.run_number }}-${{ github.run_attempt }}
- name: Check If Cache Exists - name: Check If Cache Exists
id: check-cache id: check-cache
shell: bash shell: bash
@@ -56,7 +60,7 @@ runs:
echo "Not using cache this time..." echo "Not using cache this time..."
echo "cache_exists=false" >> $GITHUB_OUTPUT echo "cache_exists=false" >> $GITHUB_OUTPUT
else else
cache_path=$CACHE_DRIVE/$CACHE_FILE cache_path=/mnt/cross-instance-cache/$DEPSHASH.tar
echo "Using cache key: $DEPSHASH" echo "Using cache key: $DEPSHASH"
echo "Checking for cache in: $cache_path" echo "Checking for cache in: $cache_path"
if [ ! -f "$cache_path" ] || [ `du $cache_path | cut -f1` = "0" ]; then if [ ! -f "$cache_path" ] || [ `du $cache_path | cut -f1` = "0" ]; then
@@ -72,29 +76,14 @@ runs:
shell: bash shell: bash
run: | run: |
# if there is less than 35 GB free space then creating the cache might fail so exit early # if there is less than 35 GB free space then creating the cache might fail so exit early
freespace=`df -m $CACHE_DRIVE | grep -w $CACHE_DRIVE | awk '{print $4}'` freespace=`df -m /mnt/cross-instance-cache | grep -w /mnt/cross-instance-cache | awk '{print $4}'`
freespace_human=`df -h $CACHE_DRIVE | grep -w $CACHE_DRIVE | awk '{print $4}'` freespace_human=`df -h /mnt/cross-instance-cache | grep -w /mnt/cross-instance-cache | awk '{print $4}'`
if [ $freespace -le 35000 ]; then if [ $freespace -le 35000 ]; then
echo "The cross mount cache has $freespace_human free space which is not enough - exiting" echo "The cross mount cache has $freespace_human free space which is not enough - exiting"
exit 1 exit 1
else else
echo "The cross mount cache has $freespace_human free space - continuing" echo "The cross mount cache has $freespace_human free space - continuing"
fi fi
- name: Add patch conflict problem matcher
shell: bash
run: echo "::add-matcher::src/electron/.github/problem-matchers/patch-conflict.json"
- name: Restore gitcache
if: steps.check-cache.outputs.cache_exists == 'false'
shell: bash
run: |
GIT_CACHE_TAR="$CACHE_DRIVE/gitcache.tar"
if [ ! -f "$GIT_CACHE_TAR" ]; then
echo "Git cache tar file does not exist, skipping restore"
exit 0
fi
echo "Restoring git cache from $GIT_CACHE_TAR to $GIT_CACHE_PATH"
mkdir -p $GIT_CACHE_PATH
tar -xf $GIT_CACHE_TAR -C $GIT_CACHE_PATH
- name: Gclient Sync - name: Gclient Sync
if: steps.check-cache.outputs.cache_exists == 'false' if: steps.check-cache.outputs.cache_exists == 'false'
shell: bash shell: bash
@@ -110,14 +99,19 @@ runs:
fi 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 e d gclient sync --with_branch_heads --with_tags -vv
if [[ "${{ inputs.is-release }}" != "true" ]]; then if [[ "${{ inputs.is-release }}" != "true" && -n "${{ env.PATCH_UP_APP_CREDS }}" ]]; then
# Re-export all the patches to check if there were changes. # Re-export all the patches to check if there were changes.
python3 src/electron/script/export_all_patches.py src/electron/patches/config.json python3 src/electron/script/export_all_patches.py src/electron/patches/config.json
cd src/electron cd src/electron
git update-index --refresh || true git update-index --refresh || true
if ! git diff-index --quiet HEAD --; then if ! git diff-index --quiet HEAD --; then
# There are changes to the patches. Make a git commit with the updated patches # There are changes to the patches. Make a git commit with the updated patches
if node ./script/patch-up.js; then git add patches
GIT_COMMITTER_NAME="PatchUp" GIT_COMMITTER_EMAIL="73610968+patchup[bot]@users.noreply.github.com" git commit -m "chore: update patches" --author="PatchUp <73610968+patchup[bot]@users.noreply.github.com>"
# Export it
mkdir -p ../../patches
git format-patch -1 --stdout --keep-subject --no-stat --full-index > ../../patches/update-patches.patch
if node ./script/push-patch.js; then
echo echo
echo "======================================================================" echo "======================================================================"
echo "Changes to the patches when applying, we have auto-pushed the diff to the current branch" echo "Changes to the patches when applying, we have auto-pushed the diff to the current branch"
@@ -125,11 +119,6 @@ runs:
echo "======================================================================" echo "======================================================================"
exit 1 exit 1
else else
git add patches
GIT_COMMITTER_NAME="PatchUp" GIT_COMMITTER_EMAIL="73610968+patchup[bot]@users.noreply.github.com" git commit -m "chore: update patches" --author="PatchUp <73610968+patchup[bot]@users.noreply.github.com>"
# Export it
mkdir -p ../../patches
git format-patch -1 --stdout --keep-subject --no-stat --full-index > ../../patches/update-patches.patch
echo echo
echo "======================================================================" echo "======================================================================"
echo "There were changes to the patches when applying." echo "There were changes to the patches when applying."
@@ -143,16 +132,7 @@ runs:
echo "No changes to patches detected" echo "No changes to patches detected"
fi fi
fi fi
- name: Remove patch conflict problem matcher
shell: bash
run: |
echo "::remove-matcher owner=merge-conflict::"
echo "::remove-matcher owner=patch-conflict::"
- name: Upload patches stats
if: ${{ inputs.target-platform == 'linux' && github.ref == 'refs/heads/main' }}
shell: bash
run: |
npx node src/electron/script/patches-stats.mjs --upload-stats || true
# delete all .git directories under src/ except for # delete all .git directories under src/ except for
# third_party/angle/ and third_party/dawn/ because of build time generation of files # third_party/angle/ and third_party/dawn/ because of build time generation of files
# gen/angle/commit.h depends on third_party/angle/.git/HEAD # gen/angle/commit.h depends on third_party/angle/.git/HEAD
@@ -172,6 +152,7 @@ runs:
run: | run: |
rm -rf src/android_webview rm -rf src/android_webview
rm -rf src/ios/chrome rm -rf src/ios/chrome
rm -rf src/third_party/blink/web_tests
rm -rf src/third_party/blink/perf_tests rm -rf src/third_party/blink/perf_tests
rm -rf src/chrome/test/data/xr/webvr_info rm -rf src/chrome/test/data/xr/webvr_info
rm -rf src/third_party/angle/third_party/VK-GL-CTS/src rm -rf src/third_party/angle/third_party/VK-GL-CTS/src
@@ -186,14 +167,14 @@ runs:
shell: bash shell: bash
run: | run: |
echo "Uncompressed src size: $(du -sh src | cut -f1 -d' ')" echo "Uncompressed src size: $(du -sh src | cut -f1 -d' ')"
tar -cf $CACHE_FILE src tar -cf $DEPSHASH.tar src
echo "Compressed src to $(du -sh $CACHE_FILE | cut -f1 -d' ')" echo "Compressed src to $(du -sh $DEPSHASH.tar | cut -f1 -d' ')"
cp ./$CACHE_FILE $CACHE_DRIVE/ cp ./$DEPSHASH.tar /mnt/cross-instance-cache/
- name: Persist Src 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' && inputs.use-cache == 'true' }}
shell: bash shell: bash
run: | run: |
final_cache_path=$CACHE_DRIVE/$CACHE_FILE final_cache_path=/mnt/cross-instance-cache/$DEPSHASH.tar
echo "Using cache key: $DEPSHASH" echo "Using cache key: $DEPSHASH"
echo "Checking path: $final_cache_path" echo "Checking path: $final_cache_path"
if [ ! -f "$final_cache_path" ]; then if [ ! -f "$final_cache_path" ]; then
@@ -202,11 +183,3 @@ runs:
else else
echo "Cache key persisted in $final_cache_path" echo "Cache key persisted in $final_cache_path"
fi fi
- name: Wait for active SSH sessions
shell: bash
if: always() && !cancelled()
run: |
while [ -f /var/.ssh-lock ]
do
sleep 60
done

View File

@@ -1,51 +0,0 @@
name: 'CIPD install'
description: 'Installs the specified CIPD package'
inputs:
cipd-root-prefix-path:
description: 'Path to prepend to installation directory'
default: ''
dependency:
description: 'Name of dependency to install'
deps-file:
description: 'Location of DEPS file that defines the dependency'
installation-dir:
description: 'Location to install dependency'
target-platform:
description: 'Target platform, should be linux, win, macos'
package:
description: 'Package to install'
dependency-version:
description: 'Version of the dependency to install'
default: ''
runs:
using: "composite"
steps:
- name: Delete wrong ${{ inputs.dependency }}
shell: bash
run : |
rm -rf ${{ inputs.cipd-root-prefix-path }}${{ inputs.installation-dir }}
- name: Create ensure file for ${{ inputs.dependency }}
if: ${{ inputs.dependency-version == '' }}
shell: bash
run: |
echo '${{ inputs.package }}' `e d gclient getdep --deps-file=${{ inputs.deps-file }} -r '${{ inputs.installation-dir }}:${{ inputs.package }}'` > ${{ inputs.dependency }}_ensure_file
cat ${{ inputs.dependency }}_ensure_file
- name: Create ensure file for ${{ inputs.dependency }} from dependency-version
if: ${{ inputs.dependency-version != '' }}
shell: bash
run: |
echo '${{ inputs.package }} ${{ inputs.dependency-version }}' > ${{ inputs.dependency }}_ensure_file
cat ${{ inputs.dependency }}_ensure_file
- name: CIPD installation of ${{ inputs.dependency }} (macOS)
if: ${{ inputs.target-platform != 'win' }}
shell: bash
run: |
echo "ensuring ${{ inputs.dependency }}"
e d cipd ensure --root ${{ inputs.cipd-root-prefix-path }}${{ inputs.installation-dir }} -ensure-file ${{ inputs.dependency }}_ensure_file
- name: CIPD installation of ${{ inputs.dependency }} (Windows)
if: ${{ inputs.target-platform == 'win' }}
shell: powershell
run: |
echo "ensuring ${{ inputs.dependency }} on Windows"
e d cipd ensure --root ${{ inputs.cipd-root-prefix-path }}${{ inputs.installation-dir }} -ensure-file ${{ inputs.dependency }}_ensure_file

View File

@@ -0,0 +1,61 @@
name: 'Fix Sync macOS'
description: 'Checks out Electron and stores it in the AKS Cache'
runs:
using: "composite"
steps:
- name: Fix Sync
shell: bash
# This step is required to correct for differences between "gclient sync"
# on Linux and the expected state on macOS. This requires:
# 1. Fixing Clang Install (wrong binary)
# 2. Fixing esbuild (wrong binary)
# 3. Fixing rustc (wrong binary)
# 4. Fixing gn (wrong binary)
# 5. Fix reclient (wrong binary)
# 6. Fixing dsymutil (wrong binary)
# 7. Ensuring we are using the correct ninja and adding it to PATH
# 8. Fixing angle (wrong remote)
run : |
SEDOPTION="-i ''"
rm -rf src/third_party/llvm-build
python3 src/tools/clang/scripts/update.py
echo 'infra/3pp/tools/esbuild/${platform}' `gclient getdep --deps-file=src/third_party/devtools-frontend/src/DEPS -r 'third_party/esbuild:infra/3pp/tools/esbuild/${platform}'` > esbuild_ensure_file
# Remove extra output from calling gclient getdep which always calls update_depot_tools
sed -i '' "s/Updating depot_tools... //g" esbuild_ensure_file
cipd ensure --root src/third_party/devtools-frontend/src/third_party/esbuild -ensure-file esbuild_ensure_file
rm -rf src/third_party/rust-toolchain
python3 src/tools/rust/update_rust.py
# Prevent calling gclient getdep which always calls update_depot_tools
echo 'gn/gn/mac-${arch}' `gclient getdep --deps-file=src/DEPS -r 'src/buildtools/mac:gn/gn/mac-${arch}'` > gn_ensure_file
sed -i '' "s/Updating depot_tools... //g" gn_ensure_file
cipd ensure --root src/buildtools/mac -ensure-file gn_ensure_file
# Prevent calling gclient getdep which always calls update_depot_tools
echo 'infra/rbe/client/${platform}' `gclient getdep --deps-file=src/DEPS -r 'src/buildtools/reclient:infra/rbe/client/${platform}'` > gn_ensure_file
sed -i '' "s/Updating depot_tools... //g" gn_ensure_file
cipd ensure --root src/buildtools/reclient -ensure-file gn_ensure_file
python3 src/buildtools/reclient_cfgs/configure_reclient_cfgs.py --rbe_instance "projects/rbe-chrome-untrusted/instances/default_instance" --reproxy_cfg_template reproxy.cfg.template --rewrapper_cfg_project "" --skip_remoteexec_cfg_fetch
if [ "${{ env.TARGET_ARCH }}" == "arm64" ]; then
DSYM_SHA_FILE=src/tools/clang/dsymutil/bin/dsymutil.arm64.sha1
else
DSYM_SHA_FILE=src/tools/clang/dsymutil/bin/dsymutil.x64.sha1
fi
python3 src/third_party/depot_tools/download_from_google_storage.py --no_resume --no_auth --bucket chromium-browser-clang -s $DSYM_SHA_FILE -o src/tools/clang/dsymutil/bin/dsymutil
echo 'infra/3pp/tools/ninja/${platform}' `gclient getdep --deps-file=src/DEPS -r 'src/third_party/ninja:infra/3pp/tools/ninja/${platform}'` > ninja_ensure_file
sed $SEDOPTION "s/Updating depot_tools... //g" ninja_ensure_file
cipd ensure --root src/third_party/ninja -ensure-file ninja_ensure_file
echo "$(pwd)/src/third_party/ninja" >> $GITHUB_PATH
cd src/third_party/angle
rm -f .git/objects/info/alternates
git remote set-url origin https://chromium.googlesource.com/angle/angle.git
cp .git/config .git/config.backup
git remote remove origin
mv .git/config.backup .git/config
git fetch

View File

@@ -1,138 +0,0 @@
name: 'Fix Sync'
description: 'Ensures proper binaries are in place'
# This action is required to correct for differences between "gclient sync"
# on Linux and the expected state on macOS/windows. This requires:
# 1. Fixing Clang Install (wrong binary)
# 2. Fixing esbuild (wrong binary)
# 3. Fixing rustc (wrong binary)
# 4. Fixing gn (wrong binary)
# 5. Fix reclient (wrong binary)
# 6. Fixing dsymutil (wrong binary)
# 7. Ensuring we are using the correct ninja and adding it to PATH
# 8. Fixing angle (wrong remote)
# 9. Install windows toolchain on Windows
# 10. Fix node binary on Windows
# 11. Fix rc binary on Windows
inputs:
target-platform:
description: 'Target platform, should be linux, win, macos'
runs:
using: "composite"
steps:
- name: Fix llvm toolchain
if: ${{ inputs.target-platform != 'linux' }}
shell: bash
run : |
rm -rf src/third_party/llvm-build
python3 src/tools/clang/scripts/update.py
# Refs https://chromium-review.googlesource.com/c/chromium/src/+/6667681
python3 src/tools/clang/scripts/update.py --package objdump
- name: Fix esbuild
if: ${{ inputs.target-platform != 'linux' }}
uses: ./src/electron/.github/actions/cipd-install
with:
cipd-root-prefix-path: src/third_party/devtools-frontend/src/
dependency: esbuild
deps-file: src/third_party/devtools-frontend/src/DEPS
installation-dir: third_party/esbuild
target-platform: ${{ inputs.target-platform }}
package: infra/3pp/tools/esbuild/${platform}
- name: Fix rustc
if: ${{ inputs.target-platform != 'linux' }}
shell: bash
run : |
rm -rf src/third_party/rust-toolchain
python3 src/tools/rust/update_rust.py
- name: Fix gn (macOS)
if: ${{ inputs.target-platform == 'macos' }}
uses: ./src/electron/.github/actions/cipd-install
with:
dependency: gn
deps-file: src/DEPS
installation-dir: src/buildtools/mac
target-platform: ${{ inputs.target-platform }}
package: gn/gn/mac-${arch}
- name: Fix gn (Windows)
if: ${{ inputs.target-platform == 'win' }}
uses: ./src/electron/.github/actions/cipd-install
with:
dependency: gn
deps-file: src/DEPS
installation-dir: src/buildtools/win
target-platform: ${{ inputs.target-platform }}
package: gn/gn/windows-amd64
- name: Fix reclient
if: ${{ inputs.target-platform != 'linux' }}
uses: ./src/electron/.github/actions/cipd-install
with:
dependency: reclient
deps-file: src/DEPS
installation-dir: src/buildtools/reclient
target-platform: ${{ inputs.target-platform }}
package: infra/rbe/client/${platform}
- name: Configure reclient configs
if: ${{ inputs.target-platform != 'linux' }}
shell: bash
run : |
python3 src/buildtools/reclient_cfgs/configure_reclient_cfgs.py --rbe_instance "projects/rbe-chrome-untrusted/instances/default_instance" --reproxy_cfg_template reproxy.cfg.template --rewrapper_cfg_project "" --skip_remoteexec_cfg_fetch
- name: Fix dsymutil (macOS)
if: ${{ inputs.target-platform == 'macos' }}
shell: bash
run : |
# Fix dsymutil
if [ "${{ inputs.target-platform }}" = "macos" ]; then
if [ "${{ env.TARGET_ARCH }}" == "arm64" ]; then
DSYM_SHA_FILE=src/tools/clang/dsymutil/bin/dsymutil.arm64.sha1
else
DSYM_SHA_FILE=src/tools/clang/dsymutil/bin/dsymutil.x64.sha1
fi
python3 src/third_party/depot_tools/download_from_google_storage.py --no_resume --no_auth --bucket chromium-browser-clang -s $DSYM_SHA_FILE -o src/tools/clang/dsymutil/bin/dsymutil
fi
- name: Fix ninja
if: ${{ inputs.target-platform != 'linux' }}
uses: ./src/electron/.github/actions/cipd-install
with:
dependency: ninja
deps-file: src/DEPS
installation-dir: src/third_party/ninja
target-platform: ${{ inputs.target-platform }}
package: infra/3pp/tools/ninja/${platform}
- name: Set ninja in path
if: ${{ inputs.target-platform != 'linux' }}
shell: bash
run : |
echo "$(pwd)/src/third_party/ninja" >> $GITHUB_PATH
- name: Fix siso
uses: ./src/electron/.github/actions/cipd-install
with:
dependency: siso
deps-file: src/DEPS
installation-dir: src/third_party/siso/cipd
target-platform: ${{ inputs.target-platform }}
package: build/siso/${platform}
- name: Fixup angle git
if: ${{ inputs.target-platform != 'linux' }}
shell: bash
run : |
cd src/third_party/angle
rm -f .git/objects/info/alternates
git remote set-url origin https://chromium.googlesource.com/angle/angle.git
cp .git/config .git/config.backup
git remote remove origin
mv .git/config.backup .git/config
git fetch
- name: Get Windows toolchain
if: ${{ inputs.target-platform == 'win' }}
shell: powershell
run: e d vpython3 src\build\vs_toolchain.py update --force
- name: Download nodejs
if: ${{ inputs.target-platform == 'win' }}
shell: powershell
run: |
$nodedeps = e d gclient getdep --deps-file=src/DEPS -r src/third_party/node/win | ConvertFrom-JSON
python3 src\third_party\depot_tools\download_from_google_storage.py --no_resume --no_auth --bucket chromium-nodejs -o src\third_party\node\win\node.exe $nodedeps.object_name
- name: Install rc
if: ${{ inputs.target-platform == 'win' }}
shell: bash
run: |
python3 src/third_party/depot_tools/download_from_google_storage.py --no_resume --no_auth --bucket chromium-browser-clang/rc -s src/build/toolchain/win/rc/win/rc.exe.sha1

View File

@@ -6,8 +6,6 @@ runs:
- name: Free Space on MacOS - name: Free Space on MacOS
shell: bash shell: bash
run: | run: |
echo "Disk usage before cleanup:"
df -h
sudo mkdir -p $TMPDIR/del-target sudo mkdir -p $TMPDIR/del-target
tmpify() { tmpify() {
@@ -59,21 +57,9 @@ runs:
sudo rm -rf $TMPDIR/del-target sudo rm -rf $TMPDIR/del-target
sudo rm -rf /Applications/Safari.app sudo rm -rf /Applications/Safari.app
sudo rm -rf /Applications/Xcode_16.1.app
sudo rm -rf /Applications/Xcode_16.3.app
sudo rm -rf /Applications/Xcode_16.2.app
sudo rm -rf /Applications/Google Chrome.app
sudo rm -rf /Applications/Xcode_16.4.app
sudo rm -rf /Applications/Google Chrome for Testing.app
sudo rm -rf /Applications/Firefox.app
sudo rm -rf ~/project/src/third_party/catapult/tracing/test_data sudo rm -rf ~/project/src/third_party/catapult/tracing/test_data
sudo rm -rf ~/project/src/third_party/angle/third_party/VK-GL-CTS sudo rm -rf ~/project/src/third_party/angle/third_party/VK-GL-CTS
sudo rm -rf /Users/runner/Library/Android
sudo rm -rf $JAVA_HOME_11_arm64
sudo rm -rf $JAVA_HOME_17_arm64
sudo rm -rf $JAVA_HOME_21_arm64
# lipo off some huge binaries arm64 versions to save space # lipo off some huge binaries arm64 versions to save space
strip_universal_deep $(xcode-select -p)/../SharedFrameworks strip_universal_deep $(xcode-select -p)/../SharedFrameworks
# strip_arm_deep /System/Volumes/Data/Library/Developer/CommandLineTools/usr # strip_arm_deep /System/Volumes/Data/Library/Developer/CommandLineTools/usr
sudo mdutil -a -i off

View File

@@ -10,23 +10,11 @@ runs:
git config --global core.filemode false git config --global core.filemode false
git config --global core.autocrlf false git config --global core.autocrlf false
git config --global branch.autosetuprebase always git config --global branch.autosetuprebase always
git config --global core.fscache true
git config --global core.longpaths true
git config --global core.preloadindex true
git config --global core.longpaths true
fi fi
export BUILD_TOOLS_SHA=706147b2376f55078f718576b28129a0457f1795 export BUILD_TOOLS_SHA=8246e57791b0af4ae5975eb96f09855f9269b1cd
npm i -g @electron/build-tools npm i -g @electron/build-tools
# Update depot_tools to ensure python
e d update_depot_tools
e auto-update disable e auto-update disable
# Disable further updates of depot_tools
e d auto-update disable
if [ "$(expr substr $(uname -s) 1 10)" == "MSYS_NT-10" ]; then if [ "$(expr substr $(uname -s) 1 10)" == "MSYS_NT-10" ]; then
e d cipd.bat --version e d cipd.bat --version
cp "C:\Python311\python.exe" "C:\Python311\python3.exe" cp "C:\Python311\python.exe" "C:\Python311\python3.exe"
echo "C:\Users\ContainerAdministrator\.electron_build_tools\third_party\depot_tools" >> $GITHUB_PATH
else
echo "$HOME/.electron_build_tools/third_party/depot_tools" >> $GITHUB_PATH
echo "$HOME/.electron_build_tools/third_party/depot_tools/python-bin" >> $GITHUB_PATH
fi fi

View File

@@ -7,7 +7,7 @@ runs:
shell: bash shell: bash
id: yarn-cache-dir-path id: yarn-cache-dir-path
run: echo "dir=$(node src/electron/script/yarn cache dir)" >> $GITHUB_OUTPUT run: echo "dir=$(node src/electron/script/yarn cache dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57
id: yarn-cache id: yarn-cache
with: with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }} path: ${{ steps.yarn-cache-dir-path.outputs.dir }}

View File

@@ -1,20 +1,12 @@
name: 'Restore Cache AKS' name: 'Restore Cache AKS'
description: 'Restores Electron src cache via AKS' description: 'Restores Electron src cache via AKS'
inputs:
target-platform:
description: 'Target platform, should be linux, win, macos'
runs: runs:
using: "composite" using: "composite"
steps: steps:
- name: Restore and Ensure Src Cache - name: Restore and Ensure Src Cache
shell: bash shell: bash
run: | run: |
if [ "${{ inputs.target-platform }}" = "win" ]; then cache_path=/mnt/cross-instance-cache/$DEPSHASH.tar
cache_path=/mnt/win-cache/$DEPSHASH.tar
else
cache_path=/mnt/cross-instance-cache/$DEPSHASH.tar
fi
echo "Using cache key: $DEPSHASH" echo "Using cache key: $DEPSHASH"
echo "Checking for cache in: $cache_path" echo "Checking for cache in: $cache_path"
if [ ! -f "$cache_path" ]; then if [ ! -f "$cache_path" ]; then

View File

@@ -1,25 +1,22 @@
name: 'Restore Cache AZCopy' name: 'Restore Cache AZCopy'
description: 'Restores Electron src cache via AZCopy' description: 'Restores Electron src cache via AZCopy'
inputs:
target-platform:
description: 'Target platform, should be linux, win, macos'
runs: runs:
using: "composite" using: "composite"
steps: steps:
- name: Obtain SAS Key - name: Obtain SAS Key
continue-on-error: true continue-on-error: true
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57
with: with:
path: sas-token path: |
key: sas-key-${{ inputs.target-platform }}-${{ github.run_number }}-1 sas-token
enableCrossOsArchive: true key: sas-key-${{ github.run_number }}-1
- name: Obtain SAS Key - name: Obtain SAS Key
continue-on-error: true continue-on-error: true
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57
with: with:
path: sas-token path: |
key: sas-key-${{ inputs.target-platform }}-${{ github.run_number }}-${{ github.run_attempt }} sas-token
enableCrossOsArchive: true key: sas-key-${{ github.run_number }}-${{ github.run_attempt }}
- name: Download Src Cache from AKS - name: Download Src Cache from AKS
# The cache will always exist here as a result of the checkout job # The cache will always exist here as a result of the checkout job
# Either it was uploaded to Azure in the checkout job for this commit # Either it was uploaded to Azure in the checkout job for this commit
@@ -29,31 +26,21 @@ runs:
timeout_minutes: 30 timeout_minutes: 30
max_attempts: 3 max_attempts: 3
retry_on: error retry_on: error
shell: bash
command: | command: |
sas_token=$(cat sas-token) sas_token=$(cat sas-token)
if [ -z "$sas_token" ]; then if [ -z $sas-token ]; then
echo "SAS Token not found; exiting src cache download early..." echo "SAS Token not found; exiting src cache download early..."
exit 1 exit 1
else
sas_token=$(jq -r '.sasToken' sas-token)
account_name=$(jq -r '.accountName' sas-token)
if [ "${{ inputs.target-platform }}" = "win" ]; then
azcopy copy --log-level=ERROR \
"https://$account_name.file.core.windows.net/${{ env.AZURE_AKS_WIN_CACHE_SHARE_NAME }}/${{ env.CACHE_PATH }}?$sas_token" $DEPSHASH.tar
else
azcopy copy --log-level=ERROR \
"https://$account_name.file.core.windows.net/${{ env.AZURE_AKS_CACHE_SHARE_NAME }}/${{ env.CACHE_PATH }}?$sas_token" $DEPSHASH.tar
fi
fi fi
azcopy copy --log-level=ERROR \
"https://${{ env.AZURE_AKS_CACHE_STORAGE_ACCOUNT }}.file.core.windows.net/${{ env.AZURE_AKS_CACHE_SHARE_NAME }}/${{ env.CACHE_PATH }}?$sas_token" $DEPSHASH.tar
env: env:
AZURE_AKS_CACHE_SHARE_NAME: linux-cache AZURE_AKS_CACHE_STORAGE_ACCOUNT: f723719aa87a34622b5f7f3
AZURE_AKS_WIN_CACHE_SHARE_NAME: windows-cache AZURE_AKS_CACHE_SHARE_NAME: pvc-f6a4089f-b082-4bee-a3f9-c3e1c0c02d8f
- name: Clean SAS Key - name: Clean SAS Key
shell: bash shell: bash
run: rm -f sas-token run: rm -f sas-token
- name: Unzip and Ensure Src Cache - name: Unzip and Ensure Src Cache
if: ${{ inputs.target-platform == 'macos' }}
shell: bash shell: bash
run: | run: |
echo "Downloaded cache is $(du -sh $DEPSHASH.tar | cut -f1)" echo "Downloaded cache is $(du -sh $DEPSHASH.tar | cut -f1)"
@@ -82,44 +69,3 @@ runs:
echo "Wiping Electron Directory" echo "Wiping Electron Directory"
rm -rf src/electron rm -rf src/electron
- name: Unzip and Ensure Src Cache (Windows)
if: ${{ inputs.target-platform == 'win' }}
shell: powershell
run: |
$src_cache = "$env:DEPSHASH.tar"
$cache_size = $(Get-Item $src_cache).length
Write-Host "Downloaded cache is $cache_size"
if ($cache_size -eq 0) {
Write-Host "Cache is empty - exiting"
exit 1
}
$TEMP_DIR=New-Item -ItemType Directory -Path temp-cache
$TEMP_DIR_PATH = $TEMP_DIR.FullName
C:\ProgramData\Chocolatey\bin\7z.exe -y -snld20 x $src_cache -o"$TEMP_DIR_PATH"
- name: Move Src Cache (Windows)
if: ${{ inputs.target-platform == 'win' }}
uses: nick-fields/retry@7152eba30c6575329ac0576536151aca5a72780e # v3.0.0
with:
timeout_minutes: 30
max_attempts: 3
retry_on: error
shell: powershell
command: |
if (Test-Path "temp-cache\src") {
Write-Host "Relocating Cache"
Remove-Item -Recurse -Force src
Move-Item temp-cache\src src
Write-Host "Deleting zip file"
Remove-Item -Force $src_cache
}
if (-Not (Test-Path "src\third_party\blink")) {
Write-Host "Cache was not correctly restored - exiting"
exit 1
}
Write-Host "Wiping Electron Directory"
Remove-Item -Recurse -Force src\electron

View File

@@ -4,14 +4,9 @@ runs:
using: "composite" using: "composite"
steps: steps:
- name: Set the git cookie from chromium.googlesource.com (Unix) - name: Set the git cookie from chromium.googlesource.com (Unix)
if: ${{ runner.os != 'Windows' }} if: ${{ runner.os != 'Windows' && env.CHROMIUM_GIT_COOKIE }}
shell: bash shell: bash
run: | run: |
if [[ -z "${{ env.CHROMIUM_GIT_COOKIE }}" ]]; then
echo "CHROMIUM_GIT_COOKIE is not set - cannot authenticate."
exit 0
fi
eval 'set +o history' 2>/dev/null || setopt HIST_IGNORE_SPACE 2>/dev/null eval 'set +o history' 2>/dev/null || setopt HIST_IGNORE_SPACE 2>/dev/null
touch ~/.gitcookies touch ~/.gitcookies
chmod 0600 ~/.gitcookies chmod 0600 ~/.gitcookies
@@ -22,37 +17,10 @@ runs:
${{ env.CHROMIUM_GIT_COOKIE }} ${{ env.CHROMIUM_GIT_COOKIE }}
__END__ __END__
eval 'set -o history' 2>/dev/null || unsetopt HIST_IGNORE_SPACE 2>/dev/null eval 'set -o history' 2>/dev/null || unsetopt HIST_IGNORE_SPACE 2>/dev/null
RESPONSE=$(curl -s -b ~/.gitcookies https://chromium-review.googlesource.com/a/accounts/self)
if [[ $RESPONSE == ")]}'"* ]]; then
# Extract account email for verification
EMAIL=$(echo "$RESPONSE" | tail -c +5 | jq -r '.email // "No email found"')
echo "Cookie authentication successful - authenticated as: $EMAIL"
else
echo "Cookie authentication failed - ensure CHROMIUM_GIT_COOKIE is set correctly"
echo $RESPONSE
fi
- name: Set the git cookie from chromium.googlesource.com (Windows) - name: Set the git cookie from chromium.googlesource.com (Windows)
if: ${{ runner.os == 'Windows' }} if: ${{ runner.os == 'Windows' && env.CHROMIUM_GIT_COOKIE_WINDOWS_STRING }}
shell: cmd shell: cmd
run: | run: |
if "%CHROMIUM_GIT_COOKIE_WINDOWS_STRING%"=="" (
echo CHROMIUM_GIT_COOKIE_WINDOWS_STRING is not set - cannot authenticate.
exit /b 0
)
git config --global http.cookiefile "%USERPROFILE%\.gitcookies" git config --global http.cookiefile "%USERPROFILE%\.gitcookies"
powershell -noprofile -nologo -command Write-Output "${{ env.CHROMIUM_GIT_COOKIE_WINDOWS_STRING }}" >>"%USERPROFILE%\.gitcookies" powershell -noprofile -nologo -command Write-Output "${{ env.CHROMIUM_GIT_COOKIE_WINDOWS_STRING }}" >>"%USERPROFILE%\.gitcookies"
curl -s -b "%USERPROFILE%\.gitcookies" https://chromium-review.googlesource.com/a/accounts/self > response.txt
findstr /B /C:")]}'" response.txt > nul
if %ERRORLEVEL% EQU 0 (
echo Cookie authentication successful
powershell -NoProfile -Command "& {$content = Get-Content -Raw response.txt; $content = $content.Substring(4); try { $json = ConvertFrom-Json $content; if($json.email) { Write-Host 'Authenticated as:' $json.email } else { Write-Host 'No email found in response' } } catch { Write-Host 'Error parsing JSON:' $_ }}"
) else (
echo Cookie authentication failed - ensure CHROMIUM_GIT_COOKIE_WINDOWS_STRING is set correctly
type response.txt
)
del response.txt

View File

@@ -1,20 +0,0 @@
name: Debug via SSH
description: Setup a SSH server with a tunnel to access it to debug via SSH.
inputs:
tunnel:
description: 'Enable SSH tunneling via cloudflared'
required: true
default: 'false'
timeout:
description: 'SSH session timeout in seconds'
required: false
type: number
default: 3600
runs:
using: composite
steps:
- run: $GITHUB_ACTION_PATH/setup-ssh.sh
shell: bash
env:
TUNNEL: ${{ inputs.tunnel }}
TIMEOUT: ${{ inputs.timeout }}

View File

@@ -1,4 +0,0 @@
# If we're in an interactive SSH session and we're not already in tmux and there's no explicit SSH command, auto attach tmux
if [ -n "$SSH_TTY" ] && [ -z "$TMUX" ] && [ -z "$SSH_ORIGINAL_COMMAND" ]; then
exec tmux attach || exec tmux
fi

View File

@@ -1,146 +0,0 @@
#!/bin/bash -e
if [ "${TUNNEL}" != "true" ]; then
echo "SSH tunneling is disabled. Set enable-tunnel: true to enable remote access."
echo "Local SSH server would be available on localhost:2222 if this were a local environment."
exit 0
fi
echo ::group::Configuring Tunnel
echo "SSH tunneling enabled. Setting up remote access..."
EXTERNAL_DEPS="curl jq ssh-keygen"
for dep in $EXTERNAL_DEPS; do
if ! command -v "${dep}" > /dev/null 2>&1; then
echo "Command ${dep} not installed on the system!" >&2
exit 1
fi
done
cd "$GITHUB_ACTION_PATH"
bashrc_path=$(pwd)/bashrc
# Source `bashrc` to auto start tmux on SSH login.
if ! grep -q "${bashrc_path}" ~/.bash_profile; then
echo >> ~/.bash_profile # On macOS runner there's no newline at the end of the file
echo "source \"${bashrc_path}\"" >> ~/.bash_profile
fi
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
if [ "${ARCH}" = "x86_64" ]; then
ARCH="amd64"
elif [ "${ARCH}" = "aarch64" ]; then
ARCH="arm64"
fi
if [ "${OS}" = "darwin" ] && ! command -v tmux > /dev/null 2>&1; then
echo "Installing tmux..."
brew install tmux
fi
if [ "$OS" = "darwin" ]; then
cloudflared_url="https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-${OS}-${ARCH}.tgz"
echo "Downloading \`cloudflared\` from <$cloudflared_url>..."
curl --location --silent --output cloudflared.tgz "${cloudflared_url}"
tar xf cloudflared.tgz
rm cloudflared.tgz
fi
chmod +x cloudflared
echo 'Creating SSH server key...'
ssh-keygen -q -f ssh_host_rsa_key -N ''
echo 'Creating SSH server config...'
sed "s,\$PWD,${PWD},;s,\$USER,${USER}," sshd_config.template > sshd_config
echo 'Starting SSH server...'
sudo /usr/sbin/sshd -f sshd_config -D &
sshd_pid=$!
echo "SSH server started successfully (PID: ${sshd_pid})"
echo 'Starting tmux session...'
(cd "${GITHUB_WORKSPACE}" && tmux new-session -d -s debug)
mkdir ~/.cloudflared
CLEAN_TUNNEL_CERT=$(printf '%s\n' "${CLOUDFLARE_TUNNEL_CERT}" | tr -d '\r' | sed '/^[[:space:]]*$/d')
echo "${CLEAN_TUNNEL_CERT}" > ~/.cloudflared/cert.pem
CLEAN_USER_CA_CERT=$(printf '%s\n' "${CLOUDFLARE_USER_CA_CERT}" | tr -d '\r' | sed '/^[[:space:]]*$/d')
echo "${CLEAN_USER_CA_CERT}" | sudo tee /etc/ssh/ca.pub > /dev/null
sudo chmod 644 /etc/ssh/ca.pub
random_suffix=$(openssl rand -hex 5 | cut -c1-10)
tunnel_name="${GITHUB_SHA}-${GITHUB_RUN_ID}-${random_suffix}"
tunnel_url="${tunnel_name}.${CLOUDFLARE_TUNNEL_HOSTNAME}"
if ./cloudflared tunnel list | grep -q "${tunnel_name}"; then
echo "Deleting existing tunnel: ${tunnel_name}"
./cloudflared tunnel delete ${tunnel_name}
fi
echo "Creating new cloudflare tunnel: ${tunnel_name}"
./cloudflared tunnel create ${tunnel_name}
credentials_file=$(find ~/.cloudflared -name "*.json" | head -n 1)
if [ -z "${credentials_file}" ]; then
echo "Error: Could not find tunnel credentials file"
exit 1
fi
echo "Found credentials file: ${credentials_file}"
echo 'Creating tunnel configuration...'
cat > tunnel_config.yml << EOF
tunnel: ${tunnel_name}
credentials-file: ${credentials_file}
ingress:
- hostname: ${tunnel_url}
service: ssh://localhost:2222
- service: http_status:404
EOF
echo 'Setting up DNS routing for tunnel...'
./cloudflared tunnel route dns ${tunnel_name} ${tunnel_url}
echo 'Running cloudflare tunnel...'
./cloudflared tunnel --no-autoupdate --config tunnel_config.yml run 2>&1 | tee cloudflared.log | sed -u 's/^/cloudflared: /' &
cloudflared_pid=$!
echo ::endgroup::
echo ::notice title=SSH Debug Session Ready::ssh ${tunnel_url}
(
echo ' '
echo ' '
echo '🔗 SSH Debug Session Ready!'
echo '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'
echo ' '
echo '📋 Infra WG can copy and run this command to connect:'
echo ' '
echo "ssh ${tunnel_url}"
echo ' '
echo "⏰ Session expires automatically in ${TIMEOUT} seconds"
echo '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'
echo ' '
echo ' '
) | cat
echo ::group::Starting Background Session
echo 'Starting SSH session in background...'
./ssh-session.sh "${sshd_pid}" "${cloudflared_pid}" "${TIMEOUT}" "${tunnel_name}" &
echo 'SSH session is running in background. GitHub Action will continue.'
echo 'Session will auto-cleanup after timeout or when processes end.'
echo ::endgroup::

View File

@@ -1,52 +0,0 @@
#!/bin/bash
SSHD_PID=$1
CLOUDFLARED_PID=$2
SESSION_TIMEOUT=${3:-10000}
TUNNEL_NAME=$4
cleanup() {
# Kill processes.
for pid in "$SLEEP_PID" "$SSHD_PID" "$CLOUDFLARED_PID"; do
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
kill "$pid" 2>/dev/null || true
fi
done
# Clean up tunnel.
if [ -n "$TUNNEL_NAME" ]; then
cd "$GITHUB_ACTION_PATH"
./cloudflared tunnel delete "$TUNNEL_NAME" 2>/dev/null || {
echo "Failed to delete tunnel"
}
fi
echo "Session ended at $(date)"
exit 0
}
# Trap signals to ensure cleanup.
trap cleanup SIGTERM SIGINT SIGQUIT SIGHUP EXIT
# Wait for timeout or until processes die.
sleep "$SESSION_TIMEOUT" &
SLEEP_PID=$!
# Monitor processes
while kill -0 "$SLEEP_PID" 2>/dev/null; do
# Check SSH daemon.
if ! kill -0 "$SSHD_PID" 2>/dev/null; then
echo "SSH daemon died at $(date)"
break
fi
# Check cloudflared,
if ! kill -0 "$CLOUDFLARED_PID" 2>/dev/null; then
echo "Cloudflared died at $(date)"
break
fi
sleep 10
done
cleanup

View File

@@ -1,25 +0,0 @@
Port 2222
HostKey $PWD/ssh_host_rsa_key
PidFile $PWD/sshd.pid
# Connection settings
ClientAliveInterval 30
ClientAliveCountMax 10
MaxStartups 10
LoginGraceTime 120
# Allow TCP forwarding for tunneling
AllowTcpForwarding yes
# Try to prevent timeouts
TCPKeepAlive yes
# Security
TrustedUserCAKeys /etc/ssh/ca.pub
PubkeyAuthentication yes
PasswordAuthentication no
AuthorizedPrincipalsCommand /bin/bash -c "echo '%t %k' | ssh-keygen -L -f - | grep -A1 Principals"
AuthorizedPrincipalsCommandUser nobody
PubkeyAcceptedKeyTypes ssh-rsa,ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com

View File

@@ -1,18 +0,0 @@
{
"problemMatcher": [
{
"owner": "clang",
"fromPath": "src/out/Default/args.gn",
"pattern": [
{
"regexp": "^(.+)[(:](\\d+)[:,](\\d+)\\)?:\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
]
}
]
}

View File

@@ -1,22 +0,0 @@
{
"problemMatcher": [
{
"owner": "eslint-stylish",
"pattern": [
{
"regexp": "^\\s*([^\\s].*)$",
"file": 1
},
{
"regexp": "^\\s+(\\d+):(\\d+)\\s+(error|warning|info)\\s+(.*)\\s\\s+(.*)$",
"line": 1,
"column": 2,
"severity": 3,
"message": 4,
"code": 5,
"loop": true
}
]
}
]
}

View File

@@ -1,24 +0,0 @@
{
"problemMatcher": [
{
"owner": "merge-conflict",
"pattern": [
{
"regexp": "^CONFLICT\\s\\(\\S+\\): (Merge conflict in \\S+)$",
"message": 1
}
]
},
{
"owner": "patch-conflict",
"pattern": [
{
"regexp": "^error: (patch failed: (\\S+):(\\d+))$",
"message": 1,
"file": 2,
"line": 3
}
]
}
]
}

View File

@@ -13,9 +13,9 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Setup Node.js/npm - name: Setup Node.js/npm
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a
with: with:
node-version: 20.19.x node-version: 20.11.x
- name: Setting Up Dig Site - name: Setting Up Dig Site
run: | run: |
echo "remote: ${{ github.event.pull_request.head.repo.clone_url }}" echo "remote: ${{ github.event.pull_request.head.repo.clone_url }}"
@@ -41,7 +41,7 @@ jobs:
sha-file: .dig-old sha-file: .dig-old
filename: electron.old.d.ts filename: electron.old.d.ts
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #v4.6.2 uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 #v4.6.1
with: with:
name: artifacts name: artifacts
path: electron/artifacts path: electron/artifacts

View File

@@ -1,150 +0,0 @@
name: Audit CI on Branches
on:
workflow_dispatch:
schedule:
# Run every 2 hours
- cron: '0 */2 * * *'
permissions: {}
jobs:
audit_branch_ci:
name: Audit CI on Branches
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Setup Node.js
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
with:
node-version: 22.17.x
- run: npm install @actions/cache@4.0.3 @electron/fiddle-core@2.0.1
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
id: audit-errors
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const cache = require('@actions/cache');
const { ElectronVersions } = require('@electron/fiddle-core');
const runsWithErrors = [];
// Only want the most recent workflow run that wasn't skipped or cancelled
const isValidWorkflowRun = (run) => !['skipped', 'cancelled'].includes(run.conclusion);
const versions = await ElectronVersions.create({ ignoreCache: true });
const branches = versions.supportedMajors.map((branch) => `${branch}-x-y`);
for (const branch of ["main", ...branches]) {
const latestCheckRuns = new Map();
const allCheckRuns = await github.paginate(github.rest.checks.listForRef, {
owner: "electron",
repo: "electron",
ref: branch,
status: 'completed',
});
// Sort the check runs by completed_at so that multiple check runs on the
// same ref (like a scheduled workflow) only looks at the most recent one
for (const checkRun of allCheckRuns.filter(
(run) => !['skipped', 'cancelled'].includes(run.conclusion),
).sort((a, b) => new Date(b.completed_at) - new Date(a.completed_at))) {
if (!latestCheckRuns.has(checkRun.name)) {
latestCheckRuns.set(checkRun.name, checkRun);
}
}
// Check for runs which had error annotations
for (const checkRun of Array.from(latestCheckRuns.values())) {
if (checkRun.name === "Audit CI on Branches") {
continue; // Skip the audit workflow itself
}
const annotations = (await github.rest.checks.listAnnotations({
owner: "electron",
repo: "electron",
check_run_id: checkRun.id,
})).data ?? [];
if (
annotations.find(
({ annotation_level, message }) =>
annotation_level === "failure" &&
!message.startsWith("Process completed with exit code") &&
!message.startsWith("Response status code does not indicate success") &&
!message.startsWith("The hosted runner lost communication with the server") &&
!/Unable to make request/.test(message) &&
!/The requested URL returned error/.test(message),
)
) {
checkRun.hasErrorAnnotations = true;
} else {
continue;
}
// Check if this is a known failure from a previous audit run
const cacheKey = `check-run-error-annotations-${checkRun.id}`;
const cacheHit =
(await cache.restoreCache(['/dev/null'], cacheKey, undefined, {
lookupOnly: true,
})) !== undefined;
if (cacheHit) {
checkRun.isStale = true;
}
checkRun.branch = branch;
runsWithErrors.push(checkRun);
// Create a cache entry (only the name matters) to keep track of
// failures we've seen from previous runs to mark them as stale
if (!cacheHit) {
await cache.saveCache(['/dev/null'], cacheKey);
}
}
}
if (runsWithErrors.length > 0) {
core.summary.addHeading('⚠️ Runs with Errors');
core.summary.addTable([
[
{ data: 'Branch', header: true },
{ data: 'Workflow Run', header: true },
{ data: 'Status', header: true },
],
...runsWithErrors
.sort(
(a, b) =>
a.branch.localeCompare(b.branch) ||
a.name.localeCompare(b.name),
)
.map((run) => [
run.branch,
`<a href="${run.html_url}">${run.name}</a>`,
run.isStale
? '📅 Stale'
: run.hasErrorAnnotations
? '⚠️ Errors'
: '✅ Succeeded',
]),
]);
// Set this as failed so it's easy to scan runs to find failures
if (runsWithErrors.find((run) => !run.isStale)) {
core.setOutput('errorsFound', true);
process.exitCode = 1;
}
} else {
core.summary.addRaw('🎉 No runs with errors');
}
await core.summary.write();
- name: Send Slack message if errors
if: ${{ always() && steps.audit-errors.outputs.errorsFound && github.ref == 'refs/heads/main' }}
uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1
with:
payload: |
link: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
webhook: ${{ secrets.CI_ERRORS_SLACK_WEBHOOK_URL }}
webhook-type: webhook-trigger

View File

@@ -75,7 +75,7 @@ jobs:
org: electron org: electron
- name: Generate Release Project Board Metadata - name: Generate Release Project Board Metadata
if: ${{ steps.check-major-version.outputs.MAJOR }} if: ${{ steps.check-major-version.outputs.MAJOR }}
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
id: generate-project-metadata id: generate-project-metadata
with: with:
script: | script: |

View File

@@ -1,74 +0,0 @@
name: Build Git Cache
# This workflow updates git cache on the cross-instance cache volumes
# It runs daily at midnight.
on:
schedule:
- cron: "0 0 * * *"
jobs:
build-git-cache-linux:
runs-on: electron-arc-centralus-linux-amd64-32core
container:
image: ghcr.io/electron/build:bc2f48b2415a670de18d13605b1cf0eb5fdbaae1
options: --user root
volumes:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
env:
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
steps:
- name: Checkout Electron
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
path: src/electron
fetch-depth: 0
- name: Build Git Cache
uses: ./src/electron/.github/actions/build-git-cache
with:
target-platform: linux
build-git-cache-windows:
runs-on: electron-arc-centralus-linux-amd64-32core
container:
image: ghcr.io/electron/build:bc2f48b2415a670de18d13605b1cf0eb5fdbaae1
options: --user root --device /dev/fuse --cap-add SYS_ADMIN
volumes:
- /mnt/win-cache:/mnt/win-cache
env:
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_win=True'
TARGET_OS: 'win'
steps:
- name: Checkout Electron
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
path: src/electron
fetch-depth: 0
- name: Build Git Cache
uses: ./src/electron/.github/actions/build-git-cache
with:
target-platform: win
build-git-cache-macos:
runs-on: electron-arc-centralus-linux-amd64-32core
# This job updates the same git cache as linux, so it needs to run after the linux one.
needs: build-git-cache-linux
container:
image: ghcr.io/electron/build:bc2f48b2415a670de18d13605b1cf0eb5fdbaae1
options: --user root
volumes:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
env:
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
steps:
- name: Checkout Electron
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
path: src/electron
fetch-depth: 0
- name: Build Git Cache
uses: ./src/electron/.github/actions/build-git-cache
with:
target-platform: macos

View File

@@ -6,7 +6,7 @@ on:
build-image-sha: build-image-sha:
type: string type: string
description: 'SHA for electron/build image' description: 'SHA for electron/build image'
default: '933c7d6ff6802706875270bec2e3c891cf8add3f' default: 'bc2f48b2415a670de18d13605b1cf0eb5fdbaae1'
required: true required: true
skip-macos: skip-macos:
type: boolean type: boolean
@@ -28,11 +28,6 @@ on:
description: 'Skip lint check' description: 'Skip lint check'
default: false default: false
required: false required: false
enable-ssh:
description: 'Enable SSH debugging'
required: false
type: boolean
default: false
push: push:
branches: branches:
- main - main
@@ -69,7 +64,7 @@ jobs:
id: set-output id: set-output
run: | run: |
if [ -z "${{ inputs.build-image-sha }}" ]; then if [ -z "${{ inputs.build-image-sha }}" ]; then
echo "build-image-sha=933c7d6ff6802706875270bec2e3c891cf8add3f" >> "$GITHUB_OUTPUT" echo "build-image-sha=bc2f48b2415a670de18d13605b1cf0eb5fdbaae1" >> "$GITHUB_OUTPUT"
else else
echo "build-image-sha=${{ inputs.build-image-sha }}" >> "$GITHUB_OUTPUT" echo "build-image-sha=${{ inputs.build-image-sha }}" >> "$GITHUB_OUTPUT"
fi fi
@@ -86,18 +81,18 @@ jobs:
# Docs Only Jobs # Docs Only Jobs
docs-only: docs-only:
needs: [setup, checkout-linux] needs: setup
if: ${{ needs.setup.outputs.docs-only == 'true' }} if: ${{ needs.setup.outputs.docs-only == 'true' }}
uses: ./.github/workflows/pipeline-electron-docs-only.yml uses: ./.github/workflows/pipeline-electron-docs-only.yml
with: with:
container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}' container: '{"image":"ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}","options":"--user root"}'
secrets: inherit secrets: inherit
# Checkout Jobs # Checkout Jobs
checkout-macos: checkout-macos:
needs: setup needs: setup
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-macos}} if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-macos}}
runs-on: electron-arc-centralus-linux-amd64-32core runs-on: electron-arc-linux-amd64-32core
container: container:
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }} image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
options: --user root options: --user root
@@ -120,12 +115,11 @@ jobs:
uses: ./src/electron/.github/actions/checkout uses: ./src/electron/.github/actions/checkout
with: with:
generate-sas-token: 'true' generate-sas-token: 'true'
target-platform: macos
checkout-linux: checkout-linux:
needs: setup needs: setup
if: ${{ !inputs.skip-linux}} if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-linux}}
runs-on: electron-arc-centralus-linux-amd64-32core runs-on: electron-arc-linux-amd64-32core
container: container:
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }} image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
options: --user root options: --user root
@@ -134,7 +128,6 @@ jobs:
- /var/run/sas:/var/run/sas - /var/run/sas:/var/run/sas
env: env:
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }} CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
DD_API_KEY: ${{ secrets.DD_API_KEY }}
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True' GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
PATCH_UP_APP_CREDS: ${{ secrets.PATCH_UP_APP_CREDS }} PATCH_UP_APP_CREDS: ${{ secrets.PATCH_UP_APP_CREDS }}
outputs: outputs:
@@ -148,19 +141,16 @@ jobs:
ref: ${{ github.event.pull_request.head.sha }} ref: ${{ github.event.pull_request.head.sha }}
- name: Checkout & Sync & Save - name: Checkout & Sync & Save
uses: ./src/electron/.github/actions/checkout uses: ./src/electron/.github/actions/checkout
with:
target-platform: linux
checkout-windows: checkout-windows:
needs: setup needs: setup
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }} if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }}
runs-on: electron-arc-centralus-linux-amd64-32core runs-on: electron-arc-linux-amd64-32core
container: container:
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }} image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
options: --user root --device /dev/fuse --cap-add SYS_ADMIN options: --user root --device /dev/fuse --cap-add SYS_ADMIN
volumes: volumes:
- /mnt/win-cache:/mnt/win-cache - /mnt/cross-instance-cache:/mnt/cross-instance-cache
- /var/run/sas:/var/run/sas
env: env:
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }} CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
CHROMIUM_GIT_COOKIE_WINDOWS_STRING: ${{ secrets.CHROMIUM_GIT_COOKIE_WINDOWS_STRING }} CHROMIUM_GIT_COOKIE_WINDOWS_STRING: ${{ secrets.CHROMIUM_GIT_COOKIE_WINDOWS_STRING }}
@@ -178,9 +168,6 @@ jobs:
ref: ${{ github.event.pull_request.head.sha }} ref: ${{ github.event.pull_request.head.sha }}
- name: Checkout & Sync & Save - name: Checkout & Sync & Save
uses: ./src/electron/.github/actions/checkout uses: ./src/electron/.github/actions/checkout
with:
generate-sas-token: 'true'
target-platform: win
# GN Check Jobs # GN Check Jobs
macos-gn-check: macos-gn-check:
@@ -196,11 +183,10 @@ jobs:
linux-gn-check: linux-gn-check:
uses: ./.github/workflows/pipeline-segment-electron-gn-check.yml uses: ./.github/workflows/pipeline-segment-electron-gn-check.yml
needs: checkout-linux needs: checkout-linux
if: ${{ needs.setup.outputs.src == 'true' }}
with: with:
target-platform: linux target-platform: linux
target-archs: x64 arm arm64 target-archs: x64 arm arm64
check-runs-on: electron-arc-centralus-linux-amd64-8core 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"]}' 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 gn-build-type: testing
secrets: inherit secrets: inherit
@@ -211,8 +197,8 @@ jobs:
with: with:
target-platform: win target-platform: win
target-archs: x64 x86 arm64 target-archs: x64 x86 arm64
check-runs-on: electron-arc-centralus-linux-amd64-8core 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/win-cache:/mnt/win-cache"]}' 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 gn-build-type: testing
secrets: inherit secrets: inherit
@@ -226,14 +212,13 @@ jobs:
needs: checkout-macos needs: checkout-macos
with: with:
build-runs-on: macos-14-xlarge build-runs-on: macos-14-xlarge
test-runs-on: macos-15-large test-runs-on: macos-13
target-platform: macos target-platform: macos
target-arch: x64 target-arch: x64
is-release: false is-release: false
gn-build-type: testing gn-build-type: testing
generate-symbols: false generate-symbols: false
upload-to-storage: '0' upload-to-storage: '0'
enable-ssh: ${{ inputs.enable-ssh || false }}
secrets: inherit secrets: inherit
macos-arm64: macos-arm64:
@@ -245,14 +230,13 @@ jobs:
needs: checkout-macos needs: checkout-macos
with: with:
build-runs-on: macos-14-xlarge build-runs-on: macos-14-xlarge
test-runs-on: macos-15 test-runs-on: macos-14
target-platform: macos target-platform: macos
target-arch: arm64 target-arch: arm64
is-release: false is-release: false
gn-build-type: testing gn-build-type: testing
generate-symbols: false generate-symbols: false
upload-to-storage: '0' upload-to-storage: '0'
enable-ssh: ${{ inputs.enable-ssh || false }}
secrets: inherit secrets: inherit
linux-x64: linux-x64:
@@ -262,10 +246,9 @@ jobs:
pull-requests: read pull-requests: read
uses: ./.github/workflows/pipeline-electron-build-and-test-and-nan.yml uses: ./.github/workflows/pipeline-electron-build-and-test-and-nan.yml
needs: checkout-linux needs: checkout-linux
if: ${{ needs.setup.outputs.src == 'true' }}
with: with:
build-runs-on: electron-arc-centralus-linux-amd64-32core build-runs-on: electron-arc-linux-amd64-32core
test-runs-on: electron-arc-centralus-linux-amd64-4core 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"]}' 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"}' test-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init"}'
target-platform: linux target-platform: linux
@@ -283,10 +266,9 @@ jobs:
pull-requests: read pull-requests: read
uses: ./.github/workflows/pipeline-electron-build-and-test.yml uses: ./.github/workflows/pipeline-electron-build-and-test.yml
needs: checkout-linux needs: checkout-linux
if: ${{ needs.setup.outputs.src == 'true' }}
with: with:
build-runs-on: electron-arc-centralus-linux-amd64-32core build-runs-on: electron-arc-linux-amd64-32core
test-runs-on: electron-arc-centralus-linux-amd64-4core 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"]}' 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"}' test-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init"}'
target-platform: linux target-platform: linux
@@ -305,10 +287,9 @@ jobs:
pull-requests: read pull-requests: read
uses: ./.github/workflows/pipeline-electron-build-and-test.yml uses: ./.github/workflows/pipeline-electron-build-and-test.yml
needs: checkout-linux needs: checkout-linux
if: ${{ needs.setup.outputs.src == 'true' }}
with: with:
build-runs-on: electron-arc-centralus-linux-amd64-32core build-runs-on: electron-arc-linux-amd64-32core
test-runs-on: electron-arc-centralus-linux-arm64-4core 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"]}' build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
test-container: '{"image":"ghcr.io/electron/test:arm32v7-${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init","volumes":["/home/runner/externals:/mnt/runner-externals"]}' test-container: '{"image":"ghcr.io/electron/test:arm32v7-${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init","volumes":["/home/runner/externals:/mnt/runner-externals"]}'
target-platform: linux target-platform: linux
@@ -326,10 +307,9 @@ jobs:
pull-requests: read pull-requests: read
uses: ./.github/workflows/pipeline-electron-build-and-test.yml uses: ./.github/workflows/pipeline-electron-build-and-test.yml
needs: checkout-linux needs: checkout-linux
if: ${{ needs.setup.outputs.src == 'true' }}
with: with:
build-runs-on: electron-arc-centralus-linux-amd64-32core build-runs-on: electron-arc-linux-amd64-32core
test-runs-on: ubuntu-22.04-arm 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"]}' 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"}' test-container: '{"image":"ghcr.io/electron/test:arm64v8-${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init"}'
target-platform: linux target-platform: linux
@@ -346,10 +326,10 @@ jobs:
issues: read issues: read
pull-requests: read pull-requests: read
uses: ./.github/workflows/pipeline-electron-build-and-test.yml uses: ./.github/workflows/pipeline-electron-build-and-test.yml
needs: checkout-windows needs: setup
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }} if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }}
with: with:
build-runs-on: electron-arc-centralus-windows-amd64-16core build-runs-on: electron-arc-windows-amd64-16core
test-runs-on: windows-latest test-runs-on: windows-latest
target-platform: win target-platform: win
target-arch: x64 target-arch: x64
@@ -365,10 +345,10 @@ jobs:
issues: read issues: read
pull-requests: read pull-requests: read
uses: ./.github/workflows/pipeline-electron-build-and-test.yml uses: ./.github/workflows/pipeline-electron-build-and-test.yml
needs: checkout-windows needs: setup
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }} if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }}
with: with:
build-runs-on: electron-arc-centralus-windows-amd64-16core build-runs-on: electron-arc-windows-amd64-16core
test-runs-on: windows-latest test-runs-on: windows-latest
target-platform: win target-platform: win
target-arch: x86 target-arch: x86
@@ -384,11 +364,11 @@ jobs:
issues: read issues: read
pull-requests: read pull-requests: read
uses: ./.github/workflows/pipeline-electron-build-and-test.yml uses: ./.github/workflows/pipeline-electron-build-and-test.yml
needs: checkout-windows needs: setup
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }} if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }}
with: with:
build-runs-on: electron-arc-centralus-windows-amd64-16core build-runs-on: electron-arc-windows-amd64-16core
test-runs-on: windows-11-arm test-runs-on: electron-hosted-windows-arm64-4core
target-platform: win target-platform: win
target-arch: arm64 target-arch: arm64
is-release: false is-release: false

View File

@@ -10,13 +10,12 @@ on:
jobs: jobs:
clean-src-cache: clean-src-cache:
runs-on: electron-arc-centralus-linux-amd64-32core runs-on: electron-arc-linux-amd64-32core
container: container:
image: ghcr.io/electron/build:bc2f48b2415a670de18d13605b1cf0eb5fdbaae1 image: ghcr.io/electron/build:bc2f48b2415a670de18d13605b1cf0eb5fdbaae1
options: --user root options: --user root
volumes: volumes:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache - /mnt/cross-instance-cache:/mnt/cross-instance-cache
- /mnt/win-cache:/mnt/win-cache
steps: steps:
- name: Cleanup Source Cache - name: Cleanup Source Cache
shell: bash shell: bash
@@ -24,6 +23,3 @@ jobs:
df -h /mnt/cross-instance-cache df -h /mnt/cross-instance-cache
find /mnt/cross-instance-cache -type f -mtime +15 -delete find /mnt/cross-instance-cache -type f -mtime +15 -delete
df -h /mnt/cross-instance-cache df -h /mnt/cross-instance-cache
df -h /mnt/win-cache
find /mnt/win-cache -type f -mtime +15 -delete
df -h /mnt/win-cache

View File

@@ -10,24 +10,15 @@ permissions: {}
jobs: jobs:
issue-commented: issue-commented:
name: Remove blocked/{need-info,need-repro} on comment name: Remove blocked/{need-info,need-repro} on comment
if: ${{ (contains(github.event.issue.labels.*.name, 'blocked/need-repro') || contains(github.event.issue.labels.*.name, 'blocked/need-info ❌')) && github.event.comment.user.type != 'Bot' }} if: ${{ (contains(github.event.issue.labels.*.name, 'blocked/need-repro') || contains(github.event.issue.labels.*.name, 'blocked/need-info ❌')) && !contains(fromJSON('["MEMBER", "OWNER", "COLLABORATOR"]'), github.event.comment.author_association) && github.event.comment.user.type != 'Bot' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Get author association
id: get-author-association
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
AUTHOR_ASSOCIATION=$(gh api /repos/electron/electron/issues/comments/${{ github.event.comment.id }} --jq '.author_association')
echo "author_association=$AUTHOR_ASSOCIATION" >> "$GITHUB_OUTPUT"
- name: Generate GitHub App token - name: Generate GitHub App token
uses: electron/github-app-auth-action@384fd19694fe7b6dcc9a684746c6976ad78228ae # v1.1.1 uses: electron/github-app-auth-action@384fd19694fe7b6dcc9a684746c6976ad78228ae # v1.1.1
if: ${{ !contains(fromJSON('["MEMBER", "OWNER", "COLLABORATOR"]'), steps.get-author-association.outputs.author_association) }}
id: generate-token id: generate-token
with: with:
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }} creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
- name: Remove label - name: Remove label
if: ${{ !contains(fromJSON('["MEMBER", "OWNER", "COLLABORATOR"]'), steps.get-author-association.outputs.author_association) }}
env: env:
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
ISSUE_URL: ${{ github.event.issue.html_url }} ISSUE_URL: ${{ github.event.issue.html_url }}

View File

@@ -72,7 +72,7 @@ jobs:
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }} creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
- name: Create comment - name: Create comment
if: ${{ steps.check-for-comment.outputs.SHOULD_COMMENT }} if: ${{ steps.check-for-comment.outputs.SHOULD_COMMENT }}
uses: actions-cool/issues-helper@50068f49b7b2b3857270ead65e2d02e4459b022c # v3.6.2 uses: actions-cool/issues-helper@a610082f8ac0cf03e357eb8dd0d5e2ba075e017e # v3.6.0
with: with:
actions: 'create-comment' actions: 'create-comment'
token: ${{ steps.generate-token.outputs.token }} token: ${{ steps.generate-token.outputs.token }}

View File

@@ -37,7 +37,7 @@ jobs:
org: electron org: electron
- run: npm install @electron/fiddle-core@1.3.3 mdast-util-from-markdown@2.0.0 unist-util-select@5.1.0 semver@7.6.0 - run: npm install @electron/fiddle-core@1.3.3 mdast-util-from-markdown@2.0.0 unist-util-select@5.1.0 semver@7.6.0
- name: Add labels - name: Add labels
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
id: add-labels id: add-labels
env: env:
ISSUE_BODY: ${{ github.event.issue.body }} ISSUE_BODY: ${{ github.event.issue.body }}
@@ -60,8 +60,6 @@ jobs:
// It's possible for multiple versions to be listed - // It's possible for multiple versions to be listed -
// for now check for comma or space separated version. // for now check for comma or space separated version.
const versions = electronVersion.split(/, | /); const versions = electronVersion.split(/, | /);
let hasSupportedVersion = false;
for (const version of versions) { for (const version of versions) {
const major = semver.coerce(version, { loose: true })?.major; const major = semver.coerce(version, { loose: true })?.major;
if (major) { if (major) {
@@ -77,20 +75,19 @@ jobs:
labelExists = true; labelExists = true;
} catch {} } catch {}
const { ElectronVersions } = await import('${{ github.workspace }}/node_modules/@electron/fiddle-core/dist/index.js'); if (labelExists) {
const electronVersions = await ElectronVersions.create(undefined, { ignoreCache: true }); // Check if it's an unsupported major
const validVersions = [...electronVersions.supportedMajors, ...electronVersions.prereleaseMajors]; const { ElectronVersions } = await import('${{ github.workspace }}/node_modules/@electron/fiddle-core/dist/index.js');
const versions = await ElectronVersions.create(undefined, { ignoreCache: true });
if (validVersions.includes(major)) { const validVersions = [...versions.supportedMajors, ...versions.prereleaseMajors];
hasSupportedVersion = true; if (validVersions.includes(major)) {
if (labelExists) {
labels.push(versionLabel); labels.push(versionLabel);
} }
} }
} }
} }
if (labels.length === 0) {
if (!hasSupportedVersion) {
core.setOutput('unsupportedMajor', true); core.setOutput('unsupportedMajor', true);
labels.push('blocked/need-info ❌'); labels.push('blocked/need-info ❌');
} }
@@ -134,7 +131,7 @@ jobs:
} }
- name: Create unsupported major comment - name: Create unsupported major comment
if: ${{ steps.add-labels.outputs.unsupportedMajor }} if: ${{ steps.add-labels.outputs.unsupportedMajor }}
uses: actions-cool/issues-helper@50068f49b7b2b3857270ead65e2d02e4459b022c # v3.6.2 uses: actions-cool/issues-helper@a610082f8ac0cf03e357eb8dd0d5e2ba075e017e # v3.6.0
with: with:
actions: 'create-comment' actions: 'create-comment'
token: ${{ steps.generate-token.outputs.token }} token: ${{ steps.generate-token.outputs.token }}

View File

@@ -6,7 +6,7 @@ on:
build-image-sha: build-image-sha:
type: string type: string
description: 'SHA for electron/build image' description: 'SHA for electron/build image'
default: '933c7d6ff6802706875270bec2e3c891cf8add3f' default: 'bc2f48b2415a670de18d13605b1cf0eb5fdbaae1'
upload-to-storage: upload-to-storage:
description: 'Uploads to Azure storage' description: 'Uploads to Azure storage'
required: false required: false
@@ -19,7 +19,7 @@ on:
jobs: jobs:
checkout-linux: checkout-linux:
runs-on: electron-arc-centralus-linux-amd64-32core runs-on: electron-arc-linux-amd64-32core
container: container:
image: ghcr.io/electron/build:${{ inputs.build-image-sha }} image: ghcr.io/electron/build:${{ inputs.build-image-sha }}
options: --user root options: --user root
@@ -27,7 +27,6 @@ jobs:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache - /mnt/cross-instance-cache:/mnt/cross-instance-cache
- /var/run/sas:/var/run/sas - /var/run/sas:/var/run/sas
env: env:
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True' GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
steps: steps:
- name: Checkout Electron - name: Checkout Electron
@@ -43,13 +42,14 @@ jobs:
needs: checkout-linux needs: checkout-linux
with: with:
environment: production-release environment: production-release
build-runs-on: electron-arc-centralus-linux-amd64-32core build-runs-on: electron-arc-linux-amd64-32core
build-container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}' build-container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
target-platform: linux target-platform: linux
target-arch: x64 target-arch: x64
is-release: true is-release: true
gn-build-type: release gn-build-type: release
generate-symbols: true generate-symbols: true
strip-binaries: true
upload-to-storage: ${{ inputs.upload-to-storage }} upload-to-storage: ${{ inputs.upload-to-storage }}
secrets: inherit secrets: inherit
@@ -58,13 +58,14 @@ jobs:
needs: checkout-linux needs: checkout-linux
with: with:
environment: production-release environment: production-release
build-runs-on: electron-arc-centralus-linux-amd64-32core build-runs-on: electron-arc-linux-amd64-32core
build-container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}' build-container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
target-platform: linux target-platform: linux
target-arch: arm target-arch: arm
is-release: true is-release: true
gn-build-type: release gn-build-type: release
generate-symbols: true generate-symbols: true
strip-binaries: true
upload-to-storage: ${{ inputs.upload-to-storage }} upload-to-storage: ${{ inputs.upload-to-storage }}
secrets: inherit secrets: inherit
@@ -73,12 +74,13 @@ jobs:
needs: checkout-linux needs: checkout-linux
with: with:
environment: production-release environment: production-release
build-runs-on: electron-arc-centralus-linux-amd64-32core build-runs-on: electron-arc-linux-amd64-32core
build-container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}' build-container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
target-platform: linux target-platform: linux
target-arch: arm64 target-arch: arm64
is-release: true is-release: true
gn-build-type: release gn-build-type: release
generate-symbols: true generate-symbols: true
strip-binaries: true
upload-to-storage: ${{ inputs.upload-to-storage }} upload-to-storage: ${{ inputs.upload-to-storage }}
secrets: inherit secrets: inherit

View File

@@ -6,7 +6,7 @@ on:
build-image-sha: build-image-sha:
type: string type: string
description: 'SHA for electron/build image' description: 'SHA for electron/build image'
default: '933c7d6ff6802706875270bec2e3c891cf8add3f' default: 'bc2f48b2415a670de18d13605b1cf0eb5fdbaae1'
required: true required: true
upload-to-storage: upload-to-storage:
description: 'Uploads to Azure storage' description: 'Uploads to Azure storage'
@@ -20,7 +20,7 @@ on:
jobs: jobs:
checkout-macos: checkout-macos:
runs-on: electron-arc-centralus-linux-amd64-32core runs-on: electron-arc-linux-amd64-32core
container: container:
image: ghcr.io/electron/build:${{ inputs.build-image-sha }} image: ghcr.io/electron/build:${{ inputs.build-image-sha }}
options: --user root options: --user root
@@ -28,7 +28,6 @@ jobs:
- /mnt/cross-instance-cache:/mnt/cross-instance-cache - /mnt/cross-instance-cache:/mnt/cross-instance-cache
- /var/run/sas:/var/run/sas - /var/run/sas:/var/run/sas
env: env:
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac' GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
steps: steps:
- name: Checkout Electron - name: Checkout Electron
@@ -40,7 +39,6 @@ jobs:
uses: ./src/electron/.github/actions/checkout uses: ./src/electron/.github/actions/checkout
with: with:
generate-sas-token: 'true' generate-sas-token: 'true'
target-platform: macos
publish-x64-darwin: publish-x64-darwin:
uses: ./.github/workflows/pipeline-segment-electron-build.yml uses: ./.github/workflows/pipeline-segment-electron-build.yml

View File

@@ -1,40 +1,30 @@
name: Check for Disallowed Non-Maintainer Change name: Check for Non-Maintainer Dependency Change
on: on:
pull_request_target: pull_request_target:
paths: paths:
- 'yarn.lock' - 'yarn.lock'
- 'spec/yarn.lock' - 'spec/yarn.lock'
- '.github/workflows/**'
- '.github/actions/**'
permissions: {} permissions: {}
jobs: jobs:
check-for-non-maintainer-dependency-change: check-for-non-maintainer-dependency-change:
name: Check for disallowed non-maintainer change name: Check for non-maintainer dependency change
if: ${{ github.event.pull_request.user.type != 'Bot' && !github.event.pull_request.draft }} if: ${{ !contains(fromJSON('["MEMBER", "OWNER"]'), github.event.pull_request.author_association) && github.event.pull_request.user.type != 'Bot' && !github.event.pull_request.draft }}
permissions: permissions:
contents: read contents: read
pull-requests: write pull-requests: write
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Get author association
id: get-author-association
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
AUTHOR_ASSOCIATION=$(gh api /repos/electron/electron/pulls/${{ github.event.pull_request.number }} --jq '.author_association')
echo "author_association=$AUTHOR_ASSOCIATION" >> "$GITHUB_OUTPUT"
- name: Check for existing review - name: Check for existing review
id: check-for-review id: check-for-review
if: ${{ !contains(fromJSON('["MEMBER", "OWNER"]'), steps.get-author-association.outputs.author_association) }}
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_URL: ${{ github.event.pull_request.html_url }} PR_URL: ${{ github.event.pull_request.html_url }}
run: | run: |
set -eo pipefail set -eo pipefail
REVIEW_COUNT=$(gh pr view $PR_URL --json reviews | jq '[ .reviews[] | select(.author.login == "github-actions") | select(.body | startswith("<!-- disallowed-non-maintainer-change -->")) ] | length') REVIEW_COUNT=$(gh pr view $PR_URL --json reviews | jq '[ .reviews[] | select(.author.login == "github-actions") | select(.body | startswith("<!-- no-dependency-change -->")) ] | length')
if [[ $REVIEW_COUNT -eq 0 ]]; then if [[ $REVIEW_COUNT -eq 0 ]]; then
echo "SHOULD_REVIEW=1" >> "$GITHUB_OUTPUT" echo "SHOULD_REVIEW=1" >> "$GITHUB_OUTPUT"
fi fi
@@ -44,4 +34,4 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_URL: ${{ github.event.pull_request.html_url }} PR_URL: ${{ github.event.pull_request.html_url }}
run: | run: |
printf "<!-- disallowed-non-maintainer-change -->\n\nHello @${{ github.event.pull_request.user.login }}! It looks like this pull request touches one of our dependency or CI files, and per [our contribution policy](https://github.com/electron/electron/blob/main/CONTRIBUTING.md#dependencies-upgrades-policy) we do not accept these types of changes in PRs." | gh pr review $PR_URL -r --body-file=- printf "<!-- no-dependency-change -->\n\nHello @${{ github.event.pull_request.user.login }}! It looks like this pull request touches one of our dependency files, and per [our contribution policy](https://github.com/electron/electron/blob/main/CONTRIBUTING.md#dependencies-upgrades-policy) we do not accept these types of changes in PRs." | gh pr review $PR_URL -r --body-file=-

View File

@@ -54,11 +54,6 @@ on:
required: false required: false
type: boolean type: boolean
default: false default: false
enable-ssh:
description: 'Enable SSH debugging'
required: false
type: boolean
default: false
concurrency: concurrency:
group: electron-build-and-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref_protected == true && github.run_id || github.ref }} group: electron-build-and-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref_protected == true && github.run_id || github.ref }}
@@ -81,8 +76,7 @@ jobs:
gn-build-type: ${{ inputs.gn-build-type }} gn-build-type: ${{ inputs.gn-build-type }}
generate-symbols: ${{ inputs.generate-symbols }} generate-symbols: ${{ inputs.generate-symbols }}
upload-to-storage: ${{ inputs.upload-to-storage }} upload-to-storage: ${{ inputs.upload-to-storage }}
is-asan: ${{ inputs.is-asan }} is-asan: ${{ inputs.is-asan}}
enable-ssh: ${{ inputs.enable-ssh }}
secrets: inherit secrets: inherit
test: test:
uses: ./.github/workflows/pipeline-segment-electron-test.yml uses: ./.github/workflows/pipeline-segment-electron-test.yml
@@ -92,6 +86,5 @@ jobs:
target-platform: ${{ inputs.target-platform }} target-platform: ${{ inputs.target-platform }}
test-runs-on: ${{ inputs.test-runs-on }} test-runs-on: ${{ inputs.test-runs-on }}
test-container: ${{ inputs.test-container }} test-container: ${{ inputs.test-container }}
is-asan: ${{ inputs.is-asan }} is-asan: ${{ inputs.is-asan}}
enable-ssh: ${{ inputs.enable-ssh }}
secrets: inherit secrets: inherit

View File

@@ -12,32 +12,13 @@ concurrency:
group: electron-docs-only-${{ github.ref }} group: electron-docs-only-${{ github.ref }}
cancel-in-progress: true cancel-in-progress: true
env:
GCLIENT_EXTRA_ARGS: --custom-var=checkout_arm=True --custom-var=checkout_arm64=True
jobs: jobs:
docs-only: docs-only:
name: Docs Only Compile name: Docs Only Compile
runs-on: electron-arc-centralus-linux-amd64-4core runs-on: electron-arc-linux-amd64-4core
timeout-minutes: 20 timeout-minutes: 20
container: ${{ fromJSON(inputs.container) }} container: ${{ fromJSON(inputs.container) }}
steps: steps:
- name: Checkout Electron
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
path: src/electron
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Generate DEPS Hash
run: |
node src/electron/script/generate-deps-hash.js
DEPSHASH=v1-src-cache-$(cat src/electron/.depshash)
echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
echo "CACHE_PATH=$DEPSHASH.tar" >> $GITHUB_ENV
- name: Restore src cache via AKS
uses: ./src/electron/.github/actions/restore-cache-aks
with:
target-platform: linux
- name: Checkout Electron - name: Checkout Electron
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with: with:

View File

@@ -18,7 +18,7 @@ env:
jobs: jobs:
lint: lint:
name: Lint name: Lint
runs-on: electron-arc-centralus-linux-amd64-4core runs-on: electron-arc-linux-amd64-4core
timeout-minutes: 20 timeout-minutes: 20
container: ${{ fromJSON(inputs.container) }} container: ${{ fromJSON(inputs.container) }}
steps: steps:
@@ -61,9 +61,6 @@ jobs:
curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/buildtools/DEPS?format=TEXT" | base64 -d > src/buildtools/DEPS curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/buildtools/DEPS?format=TEXT" | base64 -d > src/buildtools/DEPS
gclient sync --spec="solutions=[{'name':'src/buildtools','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':True},'managed':False}]" gclient sync --spec="solutions=[{'name':'src/buildtools','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':True},'managed':False}]"
- name: Add ESLint problem matcher
shell: bash
run: echo "::add-matcher::src/electron/.github/problem-matchers/eslint-stylish.json"
- name: Run Lint - name: Run Lint
shell: bash shell: bash
run: | run: |

View File

@@ -48,16 +48,17 @@ on:
required: true required: true
type: string type: string
default: '0' default: '0'
strip-binaries:
description: 'Strip the binaries before release (Linux only)'
required: false
type: boolean
default: false
is-asan: is-asan:
description: 'Building the Address Sanitizer (ASan) Linux build' description: 'Building the Address Sanitizer (ASan) Linux build'
required: false required: false
type: boolean type: boolean
default: false default: false
enable-ssh:
description: 'Enable SSH debugging'
required: false
type: boolean
default: false
concurrency: concurrency:
group: electron-build-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ inputs.target-variant }}-${{ inputs.is-asan }}-${{ github.ref_protected == true && github.run_id || github.ref }} group: electron-build-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ inputs.target-variant }}-${{ inputs.is-asan }}-${{ github.ref_protected == true && github.run_id || github.ref }}
@@ -72,7 +73,6 @@ env:
SUDOWOODO_EXCHANGE_TOKEN: ${{ secrets.SUDOWOODO_EXCHANGE_TOKEN }} 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' || inputs.target-platform == 'win' && '--custom-var=checkout_win=True' || '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True' }}
ELECTRON_OUT_DIR: Default ELECTRON_OUT_DIR: Default
ACTIONS_STEP_DEBUG: ${{ secrets.ACTIONS_STEP_DEBUG }}
jobs: jobs:
build: build:
@@ -94,17 +94,6 @@ jobs:
path: src/electron path: src/electron
fetch-depth: 0 fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }} ref: ${{ github.event.pull_request.head.sha }}
- name: Setup SSH Debugging
if: ${{ inputs.target-platform == 'macos' && (inputs.enable-ssh || env.ACTIONS_STEP_DEBUG == 'true') }}
uses: ./src/electron/.github/actions/ssh-debug
with:
tunnel: 'true'
env:
CLOUDFLARE_TUNNEL_CERT: ${{ secrets.CLOUDFLARE_TUNNEL_CERT }}
CLOUDFLARE_TUNNEL_HOSTNAME: ${{ vars.CLOUDFLARE_TUNNEL_HOSTNAME }}
CLOUDFLARE_USER_CA_CERT: ${{ secrets.CLOUDFLARE_USER_CA_CERT }}
AUTHORIZED_USERS: ${{ secrets.SSH_DEBUG_AUTHORIZED_USERS }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Free up space (macOS) - name: Free up space (macOS)
if: ${{ inputs.target-platform == 'macos' }} if: ${{ inputs.target-platform == 'macos' }}
uses: ./src/electron/.github/actions/free-space-macos uses: ./src/electron/.github/actions/free-space-macos
@@ -113,9 +102,9 @@ jobs:
run: df -h run: df -h
- name: Setup Node.js/npm - name: Setup Node.js/npm
if: ${{ inputs.target-platform == 'macos' }} if: ${{ inputs.target-platform == 'macos' }}
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a
with: with:
node-version: 20.19.x node-version: 20.11.x
cache: yarn cache: yarn
cache-dependency-path: src/electron/yarn.lock cache-dependency-path: src/electron/yarn.lock
- name: Install Dependencies - name: Install Dependencies
@@ -140,8 +129,24 @@ jobs:
echo "GN_EXTRA_ARGS=$GN_EXTRA_ARGS" >> $GITHUB_ENV echo "GN_EXTRA_ARGS=$GN_EXTRA_ARGS" >> $GITHUB_ENV
- name: Set Chromium Git Cookie - name: Set Chromium Git Cookie
uses: ./src/electron/.github/actions/set-chromium-cookie uses: ./src/electron/.github/actions/set-chromium-cookie
- name: Install Build Tools - name: Get Depot Tools
uses: ./src/electron/.github/actions/install-build-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
touch .disable_auto_update
- name: Add Depot Tools to PATH
run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
- name: Generate DEPS Hash - name: Generate DEPS Hash
run: | run: |
node src/electron/script/generate-deps-hash.js node src/electron/script/generate-deps-hash.js
@@ -149,29 +154,27 @@ jobs:
echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
echo "CACHE_PATH=$DEPSHASH.tar" >> $GITHUB_ENV echo "CACHE_PATH=$DEPSHASH.tar" >> $GITHUB_ENV
- name: Restore src cache via AZCopy - name: Restore src cache via AZCopy
if: ${{ inputs.target-platform != 'linux' }} if: ${{ inputs.target-platform == 'macos' }}
uses: ./src/electron/.github/actions/restore-cache-azcopy uses: ./src/electron/.github/actions/restore-cache-azcopy
with:
target-platform: ${{ inputs.target-platform }}
- name: Restore src cache via AKS - name: Restore src cache via AKS
if: ${{ inputs.target-platform == 'linux' }} if: ${{ inputs.target-platform == 'linux' }}
uses: ./src/electron/.github/actions/restore-cache-aks 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 - name: Checkout Electron
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with: with:
path: src/electron path: src/electron
fetch-depth: 0 fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }} ref: ${{ github.event.pull_request.head.sha }}
- name: Fix Sync - name: Install Build Tools
if: ${{ inputs.target-platform != 'linux' }} uses: ./src/electron/.github/actions/install-build-tools
uses: ./src/electron/.github/actions/fix-sync
with:
target-platform: ${{ inputs.target-platform }}
env:
ELECTRON_DEPOT_TOOLS_DISABLE_LOG: true
- name: Init Build Tools - name: Init Build Tools
run: | run: |
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} --import ${{ inputs.gn-build-type }} --target-cpu ${{ inputs.target-arch }} --remote-build siso 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 - name: Run Electron Only Hooks
run: | run: |
e d gclient runhooks --spec="solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]" e d gclient runhooks --spec="solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]"
@@ -181,6 +184,12 @@ jobs:
echo "DEPSHASH=$(cat src/electron/.depshash)" >> $GITHUB_ENV echo "DEPSHASH=$(cat src/electron/.depshash)" >> $GITHUB_ENV
- name: Add CHROMIUM_BUILDTOOLS_PATH to env - name: Add CHROMIUM_BUILDTOOLS_PATH to env
run: echo "CHROMIUM_BUILDTOOLS_PATH=$(pwd)/src/buildtools" >> $GITHUB_ENV run: echo "CHROMIUM_BUILDTOOLS_PATH=$(pwd)/src/buildtools" >> $GITHUB_ENV
- name: Fix Sync (macOS)
if: ${{ inputs.target-platform == 'macos' }}
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
- name: Free up space (macOS) - name: Free up space (macOS)
if: ${{ inputs.target-platform == 'macos' }} if: ${{ inputs.target-platform == 'macos' }}
uses: ./src/electron/.github/actions/free-space-macos uses: ./src/electron/.github/actions/free-space-macos
@@ -193,6 +202,7 @@ jobs:
artifact-platform: ${{ inputs.target-platform == 'macos' && 'darwin' || inputs.target-platform }} artifact-platform: ${{ inputs.target-platform == 'macos' && 'darwin' || inputs.target-platform }}
is-release: '${{ inputs.is-release }}' is-release: '${{ inputs.is-release }}'
generate-symbols: '${{ inputs.generate-symbols }}' generate-symbols: '${{ inputs.generate-symbols }}'
strip-binaries: '${{ inputs.strip-binaries }}'
upload-to-storage: '${{ inputs.upload-to-storage }}' upload-to-storage: '${{ inputs.upload-to-storage }}'
is-asan: '${{ inputs.is-asan }}' is-asan: '${{ inputs.is-asan }}'
- name: Set GN_EXTRA_ARGS for MAS Build - name: Set GN_EXTRA_ARGS for MAS Build

View File

@@ -66,8 +66,6 @@ jobs:
- name: Check disk space after freeing up space - name: Check disk space after freeing up space
if: ${{ inputs.target-platform == 'macos' }} if: ${{ inputs.target-platform == 'macos' }}
run: df -h run: df -h
- name: Set Chromium Git Cookie
uses: ./src/electron/.github/actions/set-chromium-cookie
- name: Install Build Tools - name: Install Build Tools
uses: ./src/electron/.github/actions/install-build-tools uses: ./src/electron/.github/actions/install-build-tools
- name: Enable windows toolchain - name: Enable windows toolchain
@@ -83,13 +81,9 @@ jobs:
- name: Restore src cache via AZCopy - name: Restore src cache via AZCopy
if: ${{ inputs.target-platform == 'macos' }} if: ${{ inputs.target-platform == 'macos' }}
uses: ./src/electron/.github/actions/restore-cache-azcopy uses: ./src/electron/.github/actions/restore-cache-azcopy
with:
target-platform: ${{ inputs.target-platform }}
- name: Restore src cache via AKS - name: Restore src cache via AKS
if: ${{ inputs.target-platform == 'linux' || inputs.target-platform == 'win' }} if: ${{ inputs.target-platform == 'linux' || inputs.target-platform == 'win' }}
uses: ./src/electron/.github/actions/restore-cache-aks uses: ./src/electron/.github/actions/restore-cache-aks
with:
target-platform: ${{ inputs.target-platform }}
- name: Run Electron Only Hooks - name: Run Electron Only Hooks
run: | run: |
echo "solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]" > tmpgclient echo "solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]" > tmpgclient

View File

@@ -25,11 +25,6 @@ on:
required: false required: false
type: boolean type: boolean
default: false default: false
enable-ssh:
description: 'Enable SSH debugging'
required: false
type: boolean
default: false
concurrency: concurrency:
group: electron-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ inputs.is-asan }}-${{ github.ref_protected == true && github.run_id || github.ref }} group: electron-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ inputs.is-asan }}-${{ github.ref_protected == true && github.run_id || github.ref }}
@@ -45,7 +40,6 @@ env:
CHROMIUM_GIT_COOKIE_WINDOWS_STRING: ${{ secrets.CHROMIUM_GIT_COOKIE_WINDOWS_STRING }} CHROMIUM_GIT_COOKIE_WINDOWS_STRING: ${{ secrets.CHROMIUM_GIT_COOKIE_WINDOWS_STRING }}
ELECTRON_OUT_DIR: Default ELECTRON_OUT_DIR: Default
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }} ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
ACTIONS_STEP_DEBUG: ${{ secrets.ACTIONS_STEP_DEBUG }}
jobs: jobs:
test: test:
@@ -68,15 +62,29 @@ jobs:
if: ${{ inputs.target-arch == 'arm' && inputs.target-platform == 'linux' }} if: ${{ inputs.target-arch == 'arm' && inputs.target-platform == 'linux' }}
run: | run: |
cp $(which node) /mnt/runner-externals/node20/bin/ 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
cp "C:\Python311\python.exe" "C:\Python311\python3.exe"
- name: Setup Node.js/npm - name: Setup Node.js/npm
if: ${{ inputs.target-platform == 'win' }} if: ${{ inputs.target-platform == 'win' }}
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a
with: with:
node-version: 20.19.x node-version: 20.11.x
- name: Add TCC permissions on macOS - name: Add TCC permissions on macOS
if: ${{ inputs.target-platform == 'macos' }} if: ${{ inputs.target-platform == 'macos' }}
run: | run: |
epochdate=$(($(date +'%s * 1000 + %-N / 1000000')))
configure_user_tccdb () { configure_user_tccdb () {
local values=$1 local values=$1
local dbPath="$HOME/Library/Application Support/com.apple.TCC/TCC.db" local dbPath="$HOME/Library/Application Support/com.apple.TCC/TCC.db"
@@ -92,17 +100,14 @@ jobs:
} }
userValuesArray=( userValuesArray=(
"'kTCCServiceMicrophone','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159"
"'kTCCServiceCamera','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159" "'kTCCServiceCamera','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159"
"'kTCCServiceBluetoothAlways','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159" "'kTCCServiceBluetoothAlways','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159"
"'kTCCServiceAppleEvents','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159"
"'kTCCServiceCamera','/opt/hca/hosted-compute-agent',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159"
"'kTCCServiceBluetoothAlways','/opt/hca/hosted-compute-agent',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159"
"'kTCCServiceScreenCapture','/bin/bash',1,2,3,1,NULL,NULL,NULL,'UNUSED',NULL,0,$epochdate"
) )
for values in "${userValuesArray[@]}"; do for values in "${userValuesArray[@]}"; do
# Sonoma and higher have a few extra values # Sonoma and higher have a few extra values
# Ref: https://github.com/actions/runner-images/blob/main/images/macos/scripts/build/configure-tccdb-macos.sh # Ref: https://github.com/actions/runner-images/blob/main/images/macos/scripts/build/configure-tccdb-macos.sh
if [ "$OSTYPE" = "darwin23" ] || [ "$OSTYPE" = "darwin24" ]; then if [ "$OSTYPE" = "darwin23" ]; then
configure_user_tccdb "$values,NULL,NULL,'UNUSED',${values##*,}" configure_user_tccdb "$values,NULL,NULL,'UNUSED',${values##*,}"
configure_sys_tccdb "$values,NULL,NULL,'UNUSED',${values##*,}" configure_sys_tccdb "$values,NULL,NULL,'UNUSED',${values##*,}"
else else
@@ -113,32 +118,12 @@ jobs:
- name: Turn off the unexpectedly quit dialog on macOS - name: Turn off the unexpectedly quit dialog on macOS
if: ${{ inputs.target-platform == 'macos' }} if: ${{ inputs.target-platform == 'macos' }}
run: defaults write com.apple.CrashReporter DialogType server run: defaults write com.apple.CrashReporter DialogType server
- name: Set xcode to 16.4
if: ${{ inputs.target-platform == 'macos' }}
run: sudo xcode-select --switch /Applications/Xcode_16.4.app
- name: Checkout Electron - name: Checkout Electron
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with: with:
path: src/electron path: src/electron
fetch-depth: 0 fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }} ref: ${{ github.event.pull_request.head.sha }}
- name: Turn off screenshot nag on macOS
if: ${{ inputs.target-platform == 'macos' }}
run: |
defaults write ~/Library/Group\ Containers/group.com.apple.replayd/ScreenCaptureApprovals.plist "/bin/bash" -date "3024-09-23 12:00:00 +0000"
src/electron/script/actions/screencapture-nag-remover.sh -a $(which bash)
src/electron/script/actions/screencapture-nag-remover.sh -a /opt/hca/hosted-compute-agent
- name: Setup SSH Debugging
if: ${{ inputs.target-platform == 'macos' && (inputs.enable-ssh || env.ACTIONS_STEP_DEBUG == 'true') }}
uses: ./src/electron/.github/actions/ssh-debug
with:
tunnel: 'true'
env:
CLOUDFLARE_TUNNEL_CERT: ${{ secrets.CLOUDFLARE_TUNNEL_CERT }}
CLOUDFLARE_TUNNEL_HOSTNAME: ${{ vars.CLOUDFLARE_TUNNEL_HOSTNAME }}
CLOUDFLARE_USER_CA_CERT: ${{ secrets.CLOUDFLARE_USER_CA_CERT }}
AUTHORIZED_USERS: ${{ secrets.SSH_DEBUG_AUTHORIZED_USERS }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install Dependencies - name: Install Dependencies
uses: ./src/electron/.github/actions/install-dependencies uses: ./src/electron/.github/actions/install-dependencies
- name: Set Chromium Git Cookie - name: Set Chromium Git Cookie
@@ -149,10 +134,6 @@ jobs:
git config --global core.filemode false git config --global core.filemode false
git config --global core.autocrlf false git config --global core.autocrlf false
git config --global branch.autosetuprebase always git config --global branch.autosetuprebase always
git config --global core.fscache true
git config --global core.longpaths true
git config --global core.preloadindex true
git config --global core.longpaths true
git clone --filter=tree:0 https://chromium.googlesource.com/chromium/tools/depot_tools.git git clone --filter=tree:0 https://chromium.googlesource.com/chromium/tools/depot_tools.git
# Ensure depot_tools does not update. # Ensure depot_tools does not update.
test -d depot_tools && cd depot_tools test -d depot_tools && cd depot_tools
@@ -166,35 +147,39 @@ jobs:
echo "DISABLE_CRASH_REPORTER_TESTS=true" >> $GITHUB_ENV echo "DISABLE_CRASH_REPORTER_TESTS=true" >> $GITHUB_ENV
echo "IS_ASAN=true" >> $GITHUB_ENV echo "IS_ASAN=true" >> $GITHUB_ENV
- name: Download Generated Artifacts - name: Download Generated Artifacts
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806
with: with:
name: generated_artifacts_${{ env.ARTIFACT_KEY }} name: generated_artifacts_${{ env.ARTIFACT_KEY }}
path: ./generated_artifacts_${{ matrix.build-type }}_${{ inputs.target-arch }} path: ./generated_artifacts_${{ matrix.build-type }}_${{ inputs.target-arch }}
- name: Download Src Artifacts - name: Download Src Artifacts
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806
with: with:
name: src_artifacts_${{ env.ARTIFACT_KEY }} name: src_artifacts_${{ env.ARTIFACT_KEY }}
path: ./src_artifacts_${{ matrix.build-type }}_${{ inputs.target-arch }} path: ./src_artifacts_${{ matrix.build-type }}_${{ inputs.target-arch }}
- name: Restore Generated Artifacts - name: Restore Generated Artifacts
run: ./src/electron/script/actions/restore-artifacts.sh run: ./src/electron/script/actions/restore-artifacts.sh
- name: Unzip Dist (win) - name: Unzip Dist, Mksnapshot & Chromedriver (win)
if: ${{ inputs.target-platform == 'win' }} if: ${{ inputs.target-platform == 'win' }}
shell: powershell shell: powershell
run: | run: |
Set-ExecutionPolicy Bypass -Scope Process -Force Set-ExecutionPolicy Bypass -Scope Process -Force
cd src/out/Default cd src/out/Default
Expand-Archive -Force dist.zip -DestinationPath ./ Expand-Archive -Force dist.zip -DestinationPath ./
- name: Unzip Dist (unix) Expand-Archive -Force chromedriver.zip -DestinationPath ./
Expand-Archive -Force mksnapshot.zip -DestinationPath ./
- name: Unzip Dist, Mksnapshot & Chromedriver (unix)
if: ${{ inputs.target-platform != 'win' }} if: ${{ inputs.target-platform != 'win' }}
run: | run: |
cd src/out/Default cd src/out/Default
unzip -:o dist.zip unzip -:o dist.zip
#- name: Import & Trust Self-Signed Codesigning Cert on MacOS unzip -:o chromedriver.zip
# if: ${{ inputs.target-platform == 'macos' && inputs.target-arch == 'x64' }} unzip -:o mksnapshot.zip
# run: | - name: Import & Trust Self-Signed Codesigning Cert on MacOS
# sudo security authorizationdb write com.apple.trust-settings.admin allow if: ${{ inputs.target-platform == 'macos' && inputs.target-arch == 'x64' }}
# cd src/electron run: |
# ./script/codesign/generate-identity.sh sudo security authorizationdb write com.apple.trust-settings.admin allow
cd src/electron
./script/codesign/generate-identity.sh
- name: Install Datadog CLI - name: Install Datadog CLI
run: | run: |
cd src/electron cd src/electron
@@ -205,6 +190,7 @@ jobs:
MOCHA_REPORTER: mocha-multi-reporters MOCHA_REPORTER: mocha-multi-reporters
MOCHA_MULTI_REPORTERS: mocha-junit-reporter, tap MOCHA_MULTI_REPORTERS: mocha-junit-reporter, tap
ELECTRON_DISABLE_SECURITY_WARNINGS: 1 ELECTRON_DISABLE_SECURITY_WARNINGS: 1
ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
DISPLAY: ':99.0' DISPLAY: ':99.0'
NPM_CONFIG_MSVS_VERSION: '2022' NPM_CONFIG_MSVS_VERSION: '2022'
run: | run: |
@@ -224,7 +210,7 @@ jobs:
export ELECTRON_FORCE_TEST_SUITE_EXIT="true" export ELECTRON_FORCE_TEST_SUITE_EXIT="true"
fi fi
fi fi
node script/yarn test --runners=main --enableRerun=3 --trace-uncaught --enable-logging --files $tests_files node script/yarn test --runners=main --trace-uncaught --enable-logging --files $tests_files
else else
chown :builduser .. && chmod g+w .. chown :builduser .. && chmod g+w ..
chown -R :builduser . && chmod -R g+w . chown -R :builduser . && chmod -R g+w .
@@ -261,7 +247,7 @@ jobs:
if: always() && !cancelled() if: always() && !cancelled()
- name: Upload Test Artifacts - name: Upload Test Artifacts
if: always() && !cancelled() if: always() && !cancelled()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1
with: with:
name: test_artifacts_${{ env.ARTIFACT_KEY }}_${{ matrix.shard }} name: test_artifacts_${{ env.ARTIFACT_KEY }}_${{ matrix.shard }}
path: src/electron/spec/artifacts path: src/electron/spec/artifacts

View File

@@ -38,7 +38,7 @@ env:
jobs: jobs:
node-tests: node-tests:
name: Run Node.js Tests name: Run Node.js Tests
runs-on: electron-arc-centralus-linux-amd64-8core runs-on: electron-arc-linux-amd64-8core
timeout-minutes: 30 timeout-minutes: 30
env: env:
TARGET_ARCH: ${{ inputs.target-arch }} TARGET_ARCH: ${{ inputs.target-arch }}
@@ -51,8 +51,6 @@ jobs:
path: src/electron path: src/electron
fetch-depth: 0 fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }} ref: ${{ github.event.pull_request.head.sha }}
- name: Set Chromium Git Cookie
uses: ./src/electron/.github/actions/set-chromium-cookie
- name: Install Build Tools - name: Install Build Tools
uses: ./src/electron/.github/actions/install-build-tools uses: ./src/electron/.github/actions/install-build-tools
- name: Init Build Tools - name: Init Build Tools
@@ -60,13 +58,24 @@ jobs:
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} --import ${{ inputs.gn-build-type }} --target-cpu ${{ inputs.target-arch }} e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} --import ${{ inputs.gn-build-type }} --target-cpu ${{ inputs.target-arch }}
- name: Install Dependencies - name: Install Dependencies
uses: ./src/electron/.github/actions/install-dependencies uses: ./src/electron/.github/actions/install-dependencies
- name: Set Chromium Git Cookie
uses: ./src/electron/.github/actions/set-chromium-cookie
- name: Get Depot Tools
timeout-minutes: 5
run: |
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
touch .disable_auto_update
- name: Add Depot Tools to PATH
run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
- name: Download Generated Artifacts - name: Download Generated Artifacts
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806
with: with:
name: generated_artifacts_${{ env.BUILD_TYPE }}_${{ env.TARGET_ARCH }} name: generated_artifacts_${{ env.BUILD_TYPE }}_${{ env.TARGET_ARCH }}
path: ./generated_artifacts_${{ env.BUILD_TYPE }}_${{ env.TARGET_ARCH }} path: ./generated_artifacts_${{ env.BUILD_TYPE }}_${{ env.TARGET_ARCH }}
- name: Download Src Artifacts - name: Download Src Artifacts
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806
with: with:
name: src_artifacts_linux_${{ env.TARGET_ARCH }} name: src_artifacts_linux_${{ env.TARGET_ARCH }}
path: ./src_artifacts_linux_${{ env.TARGET_ARCH }} path: ./src_artifacts_linux_${{ env.TARGET_ARCH }}
@@ -92,7 +101,7 @@ jobs:
done done
nan-tests: nan-tests:
name: Run Nan Tests name: Run Nan Tests
runs-on: electron-arc-centralus-linux-amd64-4core runs-on: electron-arc-linux-amd64-4core
timeout-minutes: 30 timeout-minutes: 30
env: env:
TARGET_ARCH: ${{ inputs.target-arch }} TARGET_ARCH: ${{ inputs.target-arch }}
@@ -105,8 +114,6 @@ jobs:
path: src/electron path: src/electron
fetch-depth: 0 fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }} ref: ${{ github.event.pull_request.head.sha }}
- name: Set Chromium Git Cookie
uses: ./src/electron/.github/actions/set-chromium-cookie
- name: Install Build Tools - name: Install Build Tools
uses: ./src/electron/.github/actions/install-build-tools uses: ./src/electron/.github/actions/install-build-tools
- name: Init Build Tools - name: Init Build Tools
@@ -114,13 +121,24 @@ jobs:
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }}
- name: Install Dependencies - name: Install Dependencies
uses: ./src/electron/.github/actions/install-dependencies uses: ./src/electron/.github/actions/install-dependencies
- name: Set Chromium Git Cookie
uses: ./src/electron/.github/actions/set-chromium-cookie
- name: Get Depot Tools
timeout-minutes: 5
run: |
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
touch .disable_auto_update
- name: Add Depot Tools to PATH
run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
- name: Download Generated Artifacts - name: Download Generated Artifacts
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806
with: with:
name: generated_artifacts_${{ env.BUILD_TYPE }}_${{ env.TARGET_ARCH }} name: generated_artifacts_${{ env.BUILD_TYPE }}_${{ env.TARGET_ARCH }}
path: ./generated_artifacts_${{ env.BUILD_TYPE }}_${{ env.TARGET_ARCH }} path: ./generated_artifacts_${{ env.BUILD_TYPE }}_${{ env.TARGET_ARCH }}
- name: Download Src Artifacts - name: Download Src Artifacts
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806
with: with:
name: src_artifacts_linux_${{ env.TARGET_ARCH }} name: src_artifacts_linux_${{ env.TARGET_ARCH }}
path: ./src_artifacts_linux_${{ env.TARGET_ARCH }} path: ./src_artifacts_linux_${{ env.TARGET_ARCH }}

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Trigger Slack workflow - name: Trigger Slack workflow
uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1 uses: slackapi/slack-github-action@485a9d42d3a73031f12ec201c457e2162c45d02d # v2.0.0
with: with:
webhook: ${{ secrets.BACKPORT_REQUESTED_SLACK_WEBHOOK_URL }} webhook: ${{ secrets.BACKPORT_REQUESTED_SLACK_WEBHOOK_URL }}
webhook-type: webhook-trigger webhook-type: webhook-trigger

View File

@@ -28,7 +28,7 @@ jobs:
# This is a pre-submit / pre-release. # This is a pre-submit / pre-release.
- name: "Run analysis" - name: "Run analysis"
uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2 uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
with: with:
results_file: results.sarif results_file: results.sarif
results_format: sarif results_format: sarif
@@ -42,7 +42,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab. # format to the repository Actions tab.
- name: "Upload artifact" - name: "Upload artifact"
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
with: with:
name: SARIF file name: SARIF file
path: results.sarif path: results.sarif
@@ -50,6 +50,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard. # Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning" - name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.29.5 uses: github/codeql-action/upload-sarif@6bb031afdd8eb862ea3fc1848194185e076637e5 # v3.28.11
with: with:
sarif_file: results.sarif sarif_file: results.sarif

View File

@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: semantic-pull-request - name: semantic-pull-request
uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1 uses: amannn/action-semantic-pull-request@0723387faaf9b38adef4775cd42cfd5155ed6017 # v5.5.3
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with: with:

View File

@@ -16,7 +16,7 @@ jobs:
id: generate-token id: generate-token
with: with:
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }} creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
- uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # tag: v10.1.0 - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # tag: v9.1.0
with: with:
repo-token: ${{ steps.generate-token.outputs.token }} repo-token: ${{ steps.generate-token.outputs.token }}
days-before-stale: 90 days-before-stale: 90
@@ -27,7 +27,7 @@ jobs:
This issue has been automatically marked as stale. **If this issue is still affecting you, please leave any comment** (for example, "bump"), and we'll keep it open. If you have any new additional information—in particular, if this is still reproducible in the [latest version of Electron](https://www.electronjs.org/releases/stable) or in the [beta](https://www.electronjs.org/releases/beta)—please include it with your comment! This issue has been automatically marked as stale. **If this issue is still affecting you, please leave any comment** (for example, "bump"), and we'll keep it open. If you have any new additional information—in particular, if this is still reproducible in the [latest version of Electron](https://www.electronjs.org/releases/stable) or in the [beta](https://www.electronjs.org/releases/beta)—please include it with your comment!
close-issue-message: > close-issue-message: >
This issue has been closed due to inactivity, and will not be monitored. If this is a bug and you can reproduce this issue on a [supported version of Electron](https://www.electronjs.org/docs/latest/tutorial/electron-timelines#timeline) please open a new issue and include instructions for reproducing the issue. This issue has been closed due to inactivity, and will not be monitored. If this is a bug and you can reproduce this issue on a [supported version of Electron](https://www.electronjs.org/docs/latest/tutorial/electron-timelines#timeline) please open a new issue and include instructions for reproducing the issue.
exempt-issue-labels: "discussion,security \U0001F512,enhancement :sparkles:,status/confirmed,stale-exempt,upgrade-follow-up" exempt-issue-labels: "discussion,security \U0001F512,enhancement :sparkles:,status/confirmed,stale-exempt"
only-pr-labels: not-a-real-label only-pr-labels: not-a-real-label
pending-repro: pending-repro:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -39,7 +39,7 @@ jobs:
id: generate-token id: generate-token
with: with:
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }} creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
- uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # tag: v10.1.0 - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # tag: v9.1.0
with: with:
repo-token: ${{ steps.generate-token.outputs.token }} repo-token: ${{ steps.generate-token.outputs.token }}
days-before-stale: -1 days-before-stale: -1

View File

@@ -6,7 +6,7 @@ on:
build-image-sha: build-image-sha:
type: string type: string
description: 'SHA for electron/build image' description: 'SHA for electron/build image'
default: '933c7d6ff6802706875270bec2e3c891cf8add3f' default: 'bc2f48b2415a670de18d13605b1cf0eb5fdbaae1'
required: true required: true
upload-to-storage: upload-to-storage:
description: 'Uploads to Azure storage' description: 'Uploads to Azure storage'
@@ -20,15 +20,13 @@ on:
jobs: jobs:
checkout-windows: checkout-windows:
runs-on: electron-arc-centralus-linux-amd64-32core runs-on: electron-arc-linux-amd64-32core
container: container:
image: ghcr.io/electron/build:${{ inputs.build-image-sha }} image: ghcr.io/electron/build:${{ inputs.build-image-sha }}
options: --user root --device /dev/fuse --cap-add SYS_ADMIN options: --user root --device /dev/fuse --cap-add SYS_ADMIN
volumes: volumes:
- /mnt/win-cache:/mnt/win-cache - /mnt/cross-instance-cache:/mnt/cross-instance-cache
- /var/run/sas:/var/run/sas
env: env:
CHROMIUM_GIT_COOKIE_WINDOWS_STRING: ${{ secrets.CHROMIUM_GIT_COOKIE_WINDOWS_STRING }}
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_win=True' GCLIENT_EXTRA_ARGS: '--custom-var=checkout_win=True'
TARGET_OS: 'win' TARGET_OS: 'win'
ELECTRON_DEPOT_TOOLS_WIN_TOOLCHAIN: '1' ELECTRON_DEPOT_TOOLS_WIN_TOOLCHAIN: '1'
@@ -42,16 +40,13 @@ jobs:
fetch-depth: 0 fetch-depth: 0
- name: Checkout & Sync & Save - name: Checkout & Sync & Save
uses: ./src/electron/.github/actions/checkout uses: ./src/electron/.github/actions/checkout
with:
generate-sas-token: 'true'
target-platform: win
publish-x64-win: publish-x64-win:
uses: ./.github/workflows/pipeline-segment-electron-build.yml uses: ./.github/workflows/pipeline-segment-electron-build.yml
needs: checkout-windows needs: checkout-windows
with: with:
environment: production-release environment: production-release
build-runs-on: electron-arc-centralus-windows-amd64-16core build-runs-on: electron-arc-windows-amd64-16core
target-platform: win target-platform: win
target-arch: x64 target-arch: x64
is-release: true is-release: true
@@ -65,7 +60,7 @@ jobs:
needs: checkout-windows needs: checkout-windows
with: with:
environment: production-release environment: production-release
build-runs-on: electron-arc-centralus-windows-amd64-16core build-runs-on: electron-arc-windows-amd64-16core
target-platform: win target-platform: win
target-arch: arm64 target-arch: arm64
is-release: true is-release: true
@@ -79,7 +74,7 @@ jobs:
needs: checkout-windows needs: checkout-windows
with: with:
environment: production-release environment: production-release
build-runs-on: electron-arc-centralus-windows-amd64-16core build-runs-on: electron-arc-windows-amd64-16core
target-platform: win target-platform: win
target-arch: x86 target-arch: x86
is-release: true is-release: true

View File

@@ -1 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm run precommit npm run precommit

View File

@@ -1 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm run prepack npm run prepack

View File

@@ -1,7 +1,6 @@
{ {
"config": { "config": {
"extends": "@electron/lint-roller/configs/markdownlint.json", "extends": "@electron/lint-roller/configs/markdownlint.json",
"descriptive-link-text": false,
"link-image-style": { "link-image-style": {
"autolink": false, "autolink": false,
"shortcut": false "shortcut": false
@@ -21,14 +20,12 @@
"ul", "ul",
"unknown", "unknown",
"Tabs", "Tabs",
"TabItem", "TabItem"
"DocCardList",
"kbd"
] ]
}, },
"no-newline-in-links": true "no-newline-in-links": true
}, },
"customRules": [ "customRules": [
"./node_modules/@electron/lint-roller/markdownlint-rules/index.mjs" "@electron/lint-roller/markdownlint-rules/"
] ]
} }

2
.nvmrc
View File

@@ -1 +1 @@
22 20

143
BUILD.gn
View File

@@ -4,9 +4,9 @@ import("//build/config/win/manifest.gni")
import("//components/os_crypt/sync/features.gni") import("//components/os_crypt/sync/features.gni")
import("//components/spellcheck/spellcheck_build_features.gni") import("//components/spellcheck/spellcheck_build_features.gni")
import("//content/public/app/mac_helpers.gni") import("//content/public/app/mac_helpers.gni")
import("//content/public/common/features.gni")
import("//extensions/buildflags/buildflags.gni") import("//extensions/buildflags/buildflags.gni")
import("//pdf/features.gni") import("//pdf/features.gni")
import("//ppapi/buildflags/buildflags.gni")
import("//printing/buildflags/buildflags.gni") import("//printing/buildflags/buildflags.gni")
import("//testing/test.gni") import("//testing/test.gni")
import("//third_party/electron_node/node.gni") import("//third_party/electron_node/node.gni")
@@ -17,19 +17,19 @@ import("//tools/grit/repack.gni")
import("//tools/v8_context_snapshot/v8_context_snapshot.gni") import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
import("//v8/gni/snapshot_toolchain.gni") import("//v8/gni/snapshot_toolchain.gni")
import("build/asar.gni") import("build/asar.gni")
import("build/electron_paks.gni")
import("build/extract_symbols.gni") import("build/extract_symbols.gni")
import("build/js2c_toolchain.gni")
import("build/npm.gni") import("build/npm.gni")
import("build/templated_file.gni") import("build/templated_file.gni")
import("build/tsc.gni") import("build/tsc.gni")
import("build/webpack/webpack.gni") import("build/webpack/webpack.gni")
import("buildflags/buildflags.gni") import("buildflags/buildflags.gni")
import("electron_paks.gni")
import("filenames.auto.gni") import("filenames.auto.gni")
import("filenames.gni") import("filenames.gni")
import("filenames.hunspell.gni") import("filenames.hunspell.gni")
import("filenames.libcxx.gni") import("filenames.libcxx.gni")
import("filenames.libcxxabi.gni") import("filenames.libcxxabi.gni")
import("js2c_toolchain.gni")
if (is_mac) { if (is_mac) {
import("//build/config/mac/rules.gni") import("//build/config/mac/rules.gni")
@@ -38,13 +38,12 @@ if (is_mac) {
import("build/rules.gni") import("build/rules.gni")
assert( assert(
mac_deployment_target == "12.0", mac_deployment_target == "11.0",
"Chromium has updated the mac_deployment_target, please update this assert and flag this as a breaking change (docs/breaking-changes.md)") "Chromium has updated the mac_deployment_target, please update this assert, update the supported versions documentation (docs/tutorial/support.md) and flag this as a breaking change")
} }
if (is_linux) { if (is_linux) {
import("//build/config/linux/pkg_config.gni") import("//build/config/linux/pkg_config.gni")
import("//electron/build/linux/strip_binary.gni")
import("//tools/generate_stubs/rules.gni") import("//tools/generate_stubs/rules.gni")
pkg_config("gio_unix") { pkg_config("gio_unix") {
@@ -315,7 +314,7 @@ asar("default_app_asar") {
} }
grit("resources") { grit("resources") {
source = "build/electron_resources.grd" source = "electron_resources.grd"
outputs = [ outputs = [
"grit/electron_resources.h", "grit/electron_resources.h",
@@ -453,7 +452,7 @@ source_set("electron_lib") {
"//components/certificate_transparency", "//components/certificate_transparency",
"//components/compose:buildflags", "//components/compose:buildflags",
"//components/embedder_support:user_agent", "//components/embedder_support:user_agent",
"//components/input", "//components/input:input",
"//components/language/core/browser", "//components/language/core/browser",
"//components/net_log", "//components/net_log",
"//components/network_hints/browser", "//components/network_hints/browser",
@@ -486,7 +485,7 @@ source_set("electron_lib") {
"//net:extras", "//net:extras",
"//net:net_resources", "//net:net_resources",
"//printing/buildflags", "//printing/buildflags",
"//services/device/public/cpp/bluetooth", "//services/device/public/cpp/bluetooth:bluetooth",
"//services/device/public/cpp/geolocation", "//services/device/public/cpp/geolocation",
"//services/device/public/cpp/hid", "//services/device/public/cpp/hid",
"//services/device/public/mojom", "//services/device/public/mojom",
@@ -519,10 +518,6 @@ source_set("electron_lib") {
"//v8:v8_libplatform", "//v8:v8_libplatform",
] ]
if (v8_use_external_startup_data && use_v8_context_snapshot) {
deps += [ ":mksnapshot_checksum_gen" ]
}
public_deps = [ public_deps = [
"//base", "//base",
"//base:i18n", "//base:i18n",
@@ -655,7 +650,6 @@ source_set("electron_lib") {
"//ui/events/devices/x11", "//ui/events/devices/x11",
"//ui/events/platform/x11", "//ui/events/platform/x11",
"//ui/gtk:gtk_config", "//ui/gtk:gtk_config",
"//ui/linux:display_server_utils",
"//ui/linux:linux_ui", "//ui/linux:linux_ui",
"//ui/linux:linux_ui_factory", "//ui/linux:linux_ui_factory",
"//ui/wm", "//ui/wm",
@@ -676,8 +670,6 @@ source_set("electron_lib") {
sources += [ sources += [
"shell/browser/certificate_manager_model.cc", "shell/browser/certificate_manager_model.cc",
"shell/browser/certificate_manager_model.h", "shell/browser/certificate_manager_model.h",
"shell/browser/linux/x11_util.cc",
"shell/browser/linux/x11_util.h",
"shell/browser/ui/gtk_util.cc", "shell/browser/ui/gtk_util.cc",
"shell/browser/ui/gtk_util.h", "shell/browser/ui/gtk_util.h",
] ]
@@ -688,7 +680,7 @@ source_set("electron_lib") {
deps += [ deps += [
"//components/app_launch_prefetch", "//components/app_launch_prefetch",
"//components/crash/core/app:crash_export_thunks", "//components/crash/core/app:crash_export_thunks",
"//third_party/libxml:xml_writer", "//ui/native_theme:native_theme_browser",
"//ui/wm", "//ui/wm",
"//ui/wm/public", "//ui/wm/public",
] ]
@@ -733,7 +725,7 @@ source_set("electron_lib") {
"shell/common/extensions/api:extensions_features", "shell/common/extensions/api:extensions_features",
"//chrome/browser/resources:component_extension_resources", "//chrome/browser/resources:component_extension_resources",
"//components/guest_view/common:mojom", "//components/guest_view/common:mojom",
"//components/update_client", "//components/update_client:update_client",
"//components/zoom", "//components/zoom",
"//extensions/browser", "//extensions/browser",
"//extensions/browser/api:api_provider", "//extensions/browser/api:api_provider",
@@ -778,18 +770,6 @@ source_set("electron_lib") {
} }
} }
action("mksnapshot_checksum_gen") {
script = "build/checksum_header.py"
outputs = [ "$target_gen_dir/snapshot_checksum.h" ]
inputs = [ "$root_out_dir/$v8_context_snapshot_filename" ]
args = rebase_path(inputs)
args += rebase_path(outputs)
deps = [ "//tools/v8_context_snapshot" ]
}
electron_paks("packed_resources") { electron_paks("packed_resources") {
if (is_mac) { if (is_mac) {
output_dir = "$root_gen_dir/electron_repack" output_dir = "$root_gen_dir/electron_repack"
@@ -833,7 +813,7 @@ if (is_mac) {
sources = [] sources = []
public_deps = [] public_deps = []
sources += [ "$root_out_dir/libffmpeg.dylib" ] sources += [ "$root_out_dir/libffmpeg.dylib" ]
public_deps += [ "//third_party/ffmpeg" ] public_deps += [ "//third_party/ffmpeg:ffmpeg" ]
outputs = [ "{{bundle_contents_dir}}/Libraries/{{source_file_part}}" ] outputs = [ "{{bundle_contents_dir}}/Libraries/{{source_file_part}}" ]
} }
} else { } else {
@@ -1248,7 +1228,7 @@ if (is_mac) {
} }
if (use_v8_context_snapshot) { if (use_v8_context_snapshot) {
public_deps = [ "//tools/v8_context_snapshot" ] public_deps = [ "//tools/v8_context_snapshot:v8_context_snapshot" ]
} }
if (is_linux) { if (is_linux) {
@@ -1266,7 +1246,7 @@ if (is_mac) {
"//components/crash/core/app:run_as_crashpad_handler", "//components/crash/core/app:run_as_crashpad_handler",
] ]
ldflags = [ "/DELAYLOAD:ffmpeg.dll" ] ldflags = []
libs = [ libs = [
"comctl32.lib", "comctl32.lib",
@@ -1427,18 +1407,6 @@ dist_zip("electron_dist_zip") {
":licenses", ":licenses",
] ]
if (is_linux) { if (is_linux) {
if (is_official_build) {
data_deps += [
":strip_chrome_crashpad_handler",
":strip_chrome_sandbox",
":strip_electron_binary",
":strip_libEGL_shlib",
":strip_libGLESv2_shlib",
":strip_libffmpeg_shlib",
":strip_libvk_swiftshader_shlib",
]
}
data_deps += [ "//sandbox/linux:chrome_sandbox" ] data_deps += [ "//sandbox/linux:chrome_sandbox" ]
} }
deps = data_deps deps = data_deps
@@ -1484,16 +1452,6 @@ group("electron_mksnapshot") {
dist_zip("electron_mksnapshot_zip") { dist_zip("electron_mksnapshot_zip") {
data_deps = mksnapshot_deps data_deps = mksnapshot_deps
if (is_linux && is_official_build) {
data_deps += [
":strip_libEGL_shlib",
":strip_libGLESv2_shlib",
":strip_libffmpeg_shlib",
":strip_libvk_swiftshader_shlib",
":strip_mksnapshot_binary",
":strip_v8_context_snapshot_generator_binary",
]
}
deps = data_deps deps = data_deps
outputs = [ "$root_build_dir/mksnapshot.zip" ] outputs = [ "$root_build_dir/mksnapshot.zip" ]
} }
@@ -1618,78 +1576,3 @@ group("copy_node_headers") {
group("node_headers") { group("node_headers") {
public_deps = [ ":tar_node_headers" ] public_deps = [ ":tar_node_headers" ]
} }
if (is_linux && is_official_build) {
strip_binary("strip_electron_binary") {
binary_input = "$root_out_dir/$electron_project_name"
symbol_output = "$root_out_dir/debug/$electron_project_name.debug"
compress_debug_sections = true
deps = [ ":electron_app" ]
}
strip_binary("strip_chrome_crashpad_handler") {
binary_input = "$root_out_dir/chrome_crashpad_handler"
symbol_output = "$root_out_dir/debug/chrome_crashpad_handler.debug"
compress_debug_sections = true
deps = [ "//components/crash/core/app:chrome_crashpad_handler" ]
}
strip_binary("strip_chrome_sandbox") {
binary_input = "$root_out_dir/chrome_sandbox"
symbol_output = "$root_out_dir/debug/chrome-sandbox.debug"
compress_debug_sections = true
deps = [ "//sandbox/linux:chrome_sandbox" ]
}
strip_binary("strip_libEGL_shlib") {
binary_input = "$root_out_dir/libEGL.so"
symbol_output = "$root_out_dir/debug/libEGL.so.debug"
compress_debug_sections = true
deps = [ "//third_party/angle:libEGL" ]
}
strip_binary("strip_libGLESv2_shlib") {
binary_input = "$root_out_dir/libGLESv2.so"
symbol_output = "$root_out_dir/debug/libGLESv2.so.debug"
compress_debug_sections = true
deps = [ "//third_party/angle:libGLESv2" ]
}
strip_binary("strip_libffmpeg_shlib") {
binary_input = "$root_out_dir/libffmpeg.so"
symbol_output = "$root_out_dir/debug/libffmpeg.so.debug"
compress_debug_sections = true
deps = [ "//third_party/ffmpeg" ]
}
strip_binary("strip_libvk_swiftshader_shlib") {
binary_input = "$root_out_dir/libvk_swiftshader.so"
symbol_output = "$root_out_dir/debug/libvk_swiftshader.so.debug"
compress_debug_sections = true
deps = [ "//third_party/swiftshader/src/Vulkan:swiftshader_libvulkan" ]
}
strip_binary("strip_mksnapshot_binary") {
_binary_path = rebase_path(
get_label_info(
":v8_context_snapshot_generator($v8_snapshot_toolchain)",
"root_out_dir") + "/mksnapshot",
root_build_dir)
binary_input = "$root_out_dir/$_binary_path"
symbol_output = "$root_out_dir/debug/${_binary_path}.debug"
compress_debug_sections = true
deps = mksnapshot_deps
}
strip_binary("strip_v8_context_snapshot_generator_binary") {
_binary_path = rebase_path(
get_label_info(
":v8_context_snapshot_generator($v8_snapshot_toolchain)",
"root_out_dir") + "/v8_context_snapshot_generator",
root_build_dir)
binary_input = "$root_out_dir/$_binary_path"
symbol_output = "$root_out_dir/debug/${_binary_path}.debug"
compress_debug_sections = true
deps = mksnapshot_deps
}
}

6
DEPS
View File

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

View File

@@ -44,17 +44,29 @@ Each Electron release provides binaries for macOS, Windows, and Linux.
* Fedora 32 and newer * Fedora 32 and newer
* Debian 10 and newer * Debian 10 and newer
## Electron Fiddle ## Quick start & Electron Fiddle
Use [`Electron Fiddle`](https://github.com/electron/fiddle) Use [`Electron Fiddle`](https://github.com/electron/fiddle)
to build, run, and package small Electron experiments, to see code examples for all of Electron's APIs, and to build, run, and package small Electron experiments, to see code examples for all of Electron's APIs, and
to try out different versions of Electron. It's designed to make the start of your journey with to try out different versions of Electron. It's designed to make the start of your journey with
Electron easier. Electron easier.
Alternatively, clone and run the
[electron/electron-quick-start](https://github.com/electron/electron-quick-start)
repository to see a minimal Electron app in action:
```sh
git clone https://github.com/electron/electron-quick-start
cd electron-quick-start
npm install
npm start
```
## Resources for learning Electron ## Resources for learning Electron
* [electronjs.org/docs](https://electronjs.org/docs) - All of Electron's documentation * [electronjs.org/docs](https://electronjs.org/docs) - All of Electron's documentation
* [electron/fiddle](https://github.com/electron/fiddle) - A tool to build, run, and package small Electron experiments * [electron/fiddle](https://github.com/electron/fiddle) - A tool to build, run, and package small Electron experiments
* [electron/electron-quick-start](https://github.com/electron/electron-quick-start) - A very basic starter Electron app
* [electronjs.org/community#boilerplates](https://electronjs.org/community#boilerplates) - Sample starter apps created by the community * [electronjs.org/community#boilerplates](https://electronjs.org/community#boilerplates) - Sample starter apps created by the community
## Programmatic usage ## Programmatic usage

View File

@@ -8,12 +8,6 @@ The Electron team will send a response indicating the next steps in handling you
Report security bugs in third-party modules to the person or team maintaining the module. You can also report a vulnerability through the [npm contact form](https://www.npmjs.com/support) by selecting "I'm reporting a security vulnerability". Report security bugs in third-party modules to the person or team maintaining the module. You can also report a vulnerability through the [npm contact form](https://www.npmjs.com/support) by selecting "I'm reporting a security vulnerability".
## Escalation
If you do not receive an acknowledgement of your report within 6 business days, or if you cannot find a private security contact for the project, you may escalate to the OpenJS Foundation CNA at `security@lists.openjsf.org`.
If the project acknowledges your report but does not provide any further response or engagement within 14 days, escalation is also appropriate.
## The Electron Security Notification Process ## The Electron Security Notification Process
For context on Electron's security notification process, please see the [Notifications](https://github.com/electron/governance/blob/main/wg-security/membership-and-notifications.md#notifications) section of the Security WG's [Membership and Notifications](https://github.com/electron/governance/blob/main/wg-security/membership-and-notifications.md) Governance document. For context on Electron's security notification process, please see the [Notifications](https://github.com/electron/governance/blob/main/wg-security/membership-and-notifications.md#notifications) section of the Security WG's [Membership and Notifications](https://github.com/electron/governance/blob/main/wg-security/membership-and-notifications.md) Governance document.

View File

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

View File

@@ -2,7 +2,7 @@ is_electron_build = true
root_extra_deps = [ "//electron" ] root_extra_deps = [ "//electron" ]
# Registry of NMVs --> https://github.com/nodejs/node/blob/main/doc/abi_version_registry.json # Registry of NMVs --> https://github.com/nodejs/node/blob/main/doc/abi_version_registry.json
node_module_version = 140 node_module_version = 135
v8_promise_internal_field_count = 1 v8_promise_internal_field_count = 1
v8_embedder_string = "-electron.0" v8_embedder_string = "-electron.0"
@@ -70,8 +70,6 @@ v8_expose_public_symbols = true
# sensitive content by enterprise users. # sensitive content by enterprise users.
enterprise_cloud_content_analysis = false enterprise_cloud_content_analysis = false
# We don't use anything from here, and it causes target collisions # TODO: remove dependency on legacy ipc
enable_linux_installer = false # https://issues.chromium.org/issues/40943039
content_enable_legacy_ipc = true
# Disable "Save to Drive" feature in PDF viewer
enable_pdf_save_to_drive = false

View File

@@ -1,37 +0,0 @@
#!/usr/bin/env python3
import os
import sys
import hashlib
dir_path = os.path.dirname(os.path.realpath(__file__))
TEMPLATE_H = """
#ifndef ELECTRON_SNAPSHOT_CHECKSUM_H_
#define ELECTRON_SNAPSHOT_CHECKSUM_H_
namespace electron::snapshot_checksum {
inline constexpr std::string_view kChecksum = "{checksum}";
} // namespace electron::snapshot_checksum
#endif // ELECTRON_SNAPSHOT_CHECKSUM_H_
"""
def calculate_sha256(filepath):
sha256_hash = hashlib.sha256()
with open(filepath, "rb") as f:
for byte_block in iter(lambda: f.read(4096), b""):
sha256_hash.update(byte_block)
return sha256_hash.hexdigest()
input_file = sys.argv[1]
output_file = sys.argv[2]
checksum = calculate_sha256(input_file)
checksum_h = TEMPLATE_H.replace("{checksum}", checksum)
with open(output_file, 'w') as f:
f.write(checksum_h)

View File

@@ -1,70 +0,0 @@
# Copyright 2021 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This has been adapted from https://source.chromium.org/chromium/chromium/src/+/main:build/linux/strip_binary.gni;drc=c220a41e0422d45f1657c28146d32e99cc53640b
# The notable difference is it has an option to compress the debug sections
import("//build/config/clang/clang.gni")
import("//build/toolchain/toolchain.gni")
# Extracts symbols from a binary into a symbol file.
#
# Args:
# binary_input: Path to the binary containing symbols to extract, e.g.:
# "$root_out_dir/chrome"
# symbol_output: Desired output file for symbols, e.g.:
# "$root_out_dir/chrome.debug"
# stripped_binary_output: Desired output file for stripped file, e.g.:
# "$root_out_dir/chrome.stripped"
# compress_debug_sections: If true, compress the extracted debug sections
template("strip_binary") {
forward_variables_from(invoker,
[
"deps",
"testonly",
])
action("${target_name}") {
llvm_strip_binary = "${clang_base_path}/bin/llvm-strip"
llvm_objcopy_binary = "${clang_base_path}/bin/llvm-objcopy"
script = "//electron/build/linux/strip_binary.py"
if (defined(invoker.stripped_binary_output)) {
stripped_binary_output = invoker.stripped_binary_output
} else {
stripped_binary_output = invoker.binary_input + ".stripped"
}
if (defined(invoker.symbol_output)) {
symbol_output = invoker.symbol_output
} else {
symbol_output = invoker.binary_input + ".debug"
}
inputs = [
invoker.binary_input,
llvm_strip_binary,
llvm_objcopy_binary,
]
outputs = [
symbol_output,
stripped_binary_output,
]
args = [
"--llvm-strip-binary-path",
rebase_path(llvm_strip_binary, root_build_dir),
"--llvm-objcopy-binary-path",
rebase_path(llvm_objcopy_binary, root_build_dir),
"--symbol-output",
rebase_path(symbol_output, root_build_dir),
"--stripped-binary-output",
rebase_path(stripped_binary_output, root_build_dir),
"--binary-input",
rebase_path(invoker.binary_input, root_build_dir),
]
if (defined(invoker.compress_debug_sections) &&
invoker.compress_debug_sections) {
args += [ "--compress-debug-sections" ]
}
}
}

View File

@@ -1,63 +0,0 @@
#!/usr/bin/env python3
#
# Copyright 2021 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This has been adapted from https://source.chromium.org/chromium/chromium/src/+/main:build/linux/strip_binary.py;drc=c220a41e0422d45f1657c28146d32e99cc53640b
# The notable difference is it has an option to compress the debug sections
import argparse
import subprocess
import sys
def main() -> int:
parser = argparse.ArgumentParser(description="Strip binary using LLVM tools.")
parser.add_argument("--llvm-strip-binary-path",
help="Path to llvm-strip executable.")
parser.add_argument("--llvm-objcopy-binary-path",
required=True,
help="Path to llvm-objcopy executable.")
parser.add_argument("--binary-input", help="Input ELF binary.")
parser.add_argument("--symbol-output",
help="File to write extracted debug info (.debug).")
parser.add_argument("--compress-debug-sections",
action="store_true",
help="Compress extracted debug info.")
parser.add_argument("--stripped-binary-output",
help="File to write stripped binary.")
args = parser.parse_args()
# Replicate the behavior of:
# eu-strip <binary_input> -o <stripped_binary_output> -f <symbol_output>
objcopy_args = [
"--only-keep-debug",
args.binary_input,
args.symbol_output,
]
if args.compress_debug_sections:
objcopy_args.insert(0, "--compress-debug-sections")
subprocess.check_output([args.llvm_objcopy_binary_path] + objcopy_args)
subprocess.check_output([
args.llvm_strip_binary_path,
"--strip-debug",
"--strip-unneeded",
"-o",
args.stripped_binary_output,
args.binary_input,
])
subprocess.check_output([
args.llvm_objcopy_binary_path,
f"--add-gnu-debuglink={args.symbol_output}",
args.stripped_binary_output,
])
return 0
if __name__ == "__main__":
sys.exit(main())

View File

@@ -67,6 +67,10 @@ template("mac_xib_bundle_data") {
ibtool_flags = [ ibtool_flags = [
"--minimum-deployment-target", "--minimum-deployment-target",
mac_deployment_target, mac_deployment_target,
# TODO(rsesek): Enable this once all the bots are on Xcode 7+.
# "--target-device",
# "mac",
] ]
} }

View File

@@ -1,21 +0,0 @@
# -*- bazel-starlark -*-
load("@builtin//struct.star", "module")
def __platform_properties(ctx):
container_image = "docker://gcr.io/chops-public-images-prod/rbe/siso-chromium/linux@sha256:d7cb1ab14a0f20aa669c23f22c15a9dead761dcac19f43985bf9dd5f41fbef3a"
return {
"default": {
"OSFamily": "Linux",
"container-image": container_image,
},
"large": {
"OSFamily": "Linux",
"container-image": container_image,
},
}
backend = module(
"backend",
platform_properties = __platform_properties,
)

View File

@@ -1,66 +0,0 @@
load("@builtin//encoding.star", "json")
load("@builtin//path.star", "path")
load("@builtin//runtime.star", "runtime")
load("@builtin//struct.star", "module")
load("@config//main.star", upstream_init = "init")
load("@config//win_sdk.star", "win_sdk")
load("@config//gn_logs.star", "gn_logs")
def init(ctx):
mod = upstream_init(ctx)
step_config = json.decode(mod.step_config)
# Buildbarn doesn't support input_root_absolute_path so disable that
for rule in step_config["rules"]:
input_root_absolute_path = rule.get("input_root_absolute_path", False)
if input_root_absolute_path:
rule.pop("input_root_absolute_path", None)
# Only wrap clang rules with a remote wrapper if not on Linux. These are currently only
# needed for X-Compile builds, which run on Windows and Mac.
if runtime.os != "linux":
for rule in step_config["rules"]:
if rule["name"].startswith("clang/") or rule["name"].startswith("clang-cl/"):
rule["remote_wrapper"] = "../../buildtools/reclient_cfgs/chromium-browser-clang/clang_remote_wrapper"
if "inputs" not in rule:
rule["inputs"] = []
rule["inputs"].append("buildtools/reclient_cfgs/chromium-browser-clang/clang_remote_wrapper")
rule["inputs"].append("third_party/llvm-build/Release+Asserts_linux/bin/clang")
if "executables" not in step_config:
step_config["executables"] = []
step_config["executables"].append("buildtools/reclient_cfgs/chromium-browser-clang/clang_remote_wrapper")
step_config["executables"].append("third_party/llvm-build/Release+Asserts_linux/bin/clang")
if runtime.os == "darwin":
# Update platforms to match our default siso config instead of reclient configs.
step_config["platforms"].update({
"clang": step_config["platforms"]["default"],
"clang_large": step_config["platforms"]["default"],
})
if runtime.os == "windows":
# Add additional Windows SDK headers needed by Electron
win_toolchain_dir = win_sdk.toolchain_dir(ctx)
if win_toolchain_dir:
sdk_version = gn_logs.read(ctx).get("windows_sdk_version")
step_config["input_deps"][win_toolchain_dir + ":headers"].extend([
# third_party/electron_node/deps/uv/include/uv/win.h includes mswsock.h
path.join(win_toolchain_dir, "Windows Kits/10/Include", sdk_version, "um/mswsock.h"),
# third_party/electron_node/src/debug_utils.cc includes lm.h
path.join(win_toolchain_dir, "Windows Kits/10/Include", sdk_version, "um/Lm.h"),
])
# Update platforms to match our default siso config instead of reclient configs.
step_config["platforms"].update({
"clang-cl": step_config["platforms"]["default"],
"clang-cl_large": step_config["platforms"]["default"],
"lld-link": step_config["platforms"]["default"],
})
return module(
"config",
step_config = json.encode(step_config),
filegroups = mod.filegroups,
handlers = mod.handlers,
)

View File

@@ -121,7 +121,6 @@ if ((globalThis.process || binding.process).argv.includes("--profile-electron-in
'electron/main$': electronAPIFile, 'electron/main$': electronAPIFile,
'electron/renderer$': electronAPIFile, 'electron/renderer$': electronAPIFile,
'electron/common$': electronAPIFile, 'electron/common$': electronAPIFile,
'electron/utility$': electronAPIFile,
// Force timers to resolve to our dependency that doesn't use window.postMessage // Force timers to resolve to our dependency that doesn't use window.postMessage
timers: path.resolve(electronRoot, 'node_modules', 'timers-browserify', 'main.js') timers: path.resolve(electronRoot, 'node_modules', 'timers-browserify', 'main.js')
}, },
@@ -144,9 +143,7 @@ if ((globalThis.process || binding.process).argv.includes("--profile-electron-in
transpileOnly: onlyPrintingGraph, transpileOnly: onlyPrintingGraph,
ignoreDiagnostics: [ ignoreDiagnostics: [
// File '{0}' is not under 'rootDir' '{1}'. // File '{0}' is not under 'rootDir' '{1}'.
6059, 6059
// Private field '{0}' must be declared in an enclosing class.
1111
] ]
} }
}] }]

View File

@@ -41,8 +41,6 @@ PATHS_TO_SKIP = [
'resources/inspector', 'resources/inspector',
'gen/third_party/devtools-frontend/src', 'gen/third_party/devtools-frontend/src',
'gen/ui/webui', 'gen/ui/webui',
# Skip because these get zipped separately in script/zip-symbols.py
'debug',
] ]
def skip_path(dep, dist_zip, target_cpu): def skip_path(dep, dist_zip, target_cpu):
@@ -82,11 +80,6 @@ def main(argv):
dep = dep.strip() dep = dep.strip()
if not skip_path(dep, dist_zip, target_cpu): if not skip_path(dep, dist_zip, target_cpu):
dist_files.add(dep) dist_files.add(dep)
# On Linux, filter out any files which have a .stripped companion
if sys.platform == 'linux':
dist_files = {
dep for dep in dist_files if f"{dep.removeprefix('./')}.stripped" not in dist_files
}
if sys.platform == 'darwin' and not should_flatten: if sys.platform == 'darwin' and not should_flatten:
execute(['zip', '-r', '-y', dist_zip] + list(dist_files)) execute(['zip', '-r', '-y', dist_zip] + list(dist_files))
else: else:
@@ -103,13 +96,10 @@ def main(argv):
dirname = os.path.dirname(dep) dirname = os.path.dirname(dep)
arcname = ( arcname = (
os.path.join(dirname, 'chrome-sandbox') os.path.join(dirname, 'chrome-sandbox')
if basename.removesuffix('.stripped') == 'chrome_sandbox' if basename == 'chrome_sandbox'
else dep else dep
) )
name_to_write = arcname name_to_write = arcname
# On Linux, strip the .stripped suffix from the name before zipping
if sys.platform == 'linux':
name_to_write = name_to_write.removesuffix('.stripped')
if should_flatten: if should_flatten:
if flatten_relative_to: if flatten_relative_to:
if name_to_write.startswith(flatten_relative_to): if name_to_write.startswith(flatten_relative_to):

View File

@@ -23,8 +23,6 @@ static_library("chrome") {
"//chrome/browser/browser_process.h", "//chrome/browser/browser_process.h",
"//chrome/browser/devtools/devtools_contents_resizing_strategy.cc", "//chrome/browser/devtools/devtools_contents_resizing_strategy.cc",
"//chrome/browser/devtools/devtools_contents_resizing_strategy.h", "//chrome/browser/devtools/devtools_contents_resizing_strategy.h",
"//chrome/browser/devtools/devtools_dispatch_http_request_params.cc",
"//chrome/browser/devtools/devtools_dispatch_http_request_params.h",
"//chrome/browser/devtools/devtools_embedder_message_dispatcher.cc", "//chrome/browser/devtools/devtools_embedder_message_dispatcher.cc",
"//chrome/browser/devtools/devtools_embedder_message_dispatcher.h", "//chrome/browser/devtools/devtools_embedder_message_dispatcher.h",
"//chrome/browser/devtools/devtools_eye_dropper.cc", "//chrome/browser/devtools/devtools_eye_dropper.cc",
@@ -68,8 +66,6 @@ static_library("chrome") {
"//chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker.h", "//chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker.h",
"//chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker_observer.cc", "//chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker_observer.cc",
"//chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker_observer.h", "//chrome/browser/picture_in_picture/picture_in_picture_occlusion_tracker_observer.h",
"//chrome/browser/picture_in_picture/picture_in_picture_widget_fade_animator.cc",
"//chrome/browser/picture_in_picture/picture_in_picture_widget_fade_animator.h",
"//chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc", "//chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc",
"//chrome/browser/picture_in_picture/picture_in_picture_window_manager.h", "//chrome/browser/picture_in_picture/picture_in_picture_window_manager.h",
"//chrome/browser/picture_in_picture/picture_in_picture_window_manager_uma_helper.cc", "//chrome/browser/picture_in_picture/picture_in_picture_window_manager_uma_helper.cc",
@@ -78,13 +74,17 @@ static_library("chrome") {
"//chrome/browser/picture_in_picture/scoped_picture_in_picture_occlusion_observation.h", "//chrome/browser/picture_in_picture/scoped_picture_in_picture_occlusion_observation.h",
"//chrome/browser/platform_util.cc", "//chrome/browser/platform_util.cc",
"//chrome/browser/platform_util.h", "//chrome/browser/platform_util.h",
"//chrome/browser/predictors/preconnect_manager.cc",
"//chrome/browser/predictors/preconnect_manager.h",
"//chrome/browser/predictors/predictors_features.cc", "//chrome/browser/predictors/predictors_features.cc",
"//chrome/browser/predictors/predictors_features.h", "//chrome/browser/predictors/predictors_features.h",
"//chrome/browser/predictors/proxy_lookup_client_impl.cc",
"//chrome/browser/predictors/proxy_lookup_client_impl.h",
"//chrome/browser/predictors/resolve_host_client_impl.cc",
"//chrome/browser/predictors/resolve_host_client_impl.h",
"//chrome/browser/process_singleton.h", "//chrome/browser/process_singleton.h",
"//chrome/browser/process_singleton_internal.cc", "//chrome/browser/process_singleton_internal.cc",
"//chrome/browser/process_singleton_internal.h", "//chrome/browser/process_singleton_internal.h",
"//chrome/browser/serial/serial_blocklist.cc",
"//chrome/browser/serial/serial_blocklist.h",
"//chrome/browser/themes/browser_theme_pack.cc", "//chrome/browser/themes/browser_theme_pack.cc",
"//chrome/browser/themes/browser_theme_pack.h", "//chrome/browser/themes/browser_theme_pack.h",
"//chrome/browser/themes/custom_theme_supplier.cc", "//chrome/browser/themes/custom_theme_supplier.cc",
@@ -126,12 +126,8 @@ static_library("chrome") {
"//chrome/browser/ui/views/overlay/hang_up_button.h", "//chrome/browser/ui/views/overlay/hang_up_button.h",
"//chrome/browser/ui/views/overlay/minimize_button.cc", "//chrome/browser/ui/views/overlay/minimize_button.cc",
"//chrome/browser/ui/views/overlay/minimize_button.h", "//chrome/browser/ui/views/overlay/minimize_button.h",
"//chrome/browser/ui/views/overlay/overlay_controls_fade_animation.cc",
"//chrome/browser/ui/views/overlay/overlay_controls_fade_animation.h",
"//chrome/browser/ui/views/overlay/overlay_window_image_button.cc", "//chrome/browser/ui/views/overlay/overlay_window_image_button.cc",
"//chrome/browser/ui/views/overlay/overlay_window_image_button.h", "//chrome/browser/ui/views/overlay/overlay_window_image_button.h",
"//chrome/browser/ui/views/overlay/overlay_window_live_caption_button.cc",
"//chrome/browser/ui/views/overlay/overlay_window_live_caption_button.h",
"//chrome/browser/ui/views/overlay/playback_image_button.cc", "//chrome/browser/ui/views/overlay/playback_image_button.cc",
"//chrome/browser/ui/views/overlay/playback_image_button.h", "//chrome/browser/ui/views/overlay/playback_image_button.h",
"//chrome/browser/ui/views/overlay/resize_handle_button.cc", "//chrome/browser/ui/views/overlay/resize_handle_button.cc",
@@ -146,14 +142,8 @@ static_library("chrome") {
"//chrome/browser/ui/views/overlay/toggle_microphone_button.h", "//chrome/browser/ui/views/overlay/toggle_microphone_button.h",
"//chrome/browser/ui/views/overlay/video_overlay_window_views.cc", "//chrome/browser/ui/views/overlay/video_overlay_window_views.cc",
"//chrome/browser/ui/views/overlay/video_overlay_window_views.h", "//chrome/browser/ui/views/overlay/video_overlay_window_views.h",
"//chrome/browser/ui/views/picture_in_picture/picture_in_picture_bounds_change_animation.cc",
"//chrome/browser/ui/views/picture_in_picture/picture_in_picture_bounds_change_animation.h",
"//chrome/browser/ui/views/picture_in_picture/picture_in_picture_tucker.cc",
"//chrome/browser/ui/views/picture_in_picture/picture_in_picture_tucker.h",
"//chrome/browser/ui/webui/accessibility/accessibility_ui.cc", "//chrome/browser/ui/webui/accessibility/accessibility_ui.cc",
"//chrome/browser/ui/webui/accessibility/accessibility_ui.h", "//chrome/browser/ui/webui/accessibility/accessibility_ui.h",
"//chrome/browser/usb/usb_blocklist.cc",
"//chrome/browser/usb/usb_blocklist.h",
"//extensions/browser/app_window/size_constraints.cc", "//extensions/browser/app_window/size_constraints.cc",
"//extensions/browser/app_window/size_constraints.h", "//extensions/browser/app_window/size_constraints.h",
"//ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.cc", "//ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.cc",
@@ -213,7 +203,7 @@ static_library("chrome") {
"//components/enterprise/common/proto:connectors_proto", "//components/enterprise/common/proto:connectors_proto",
"//components/enterprise/obfuscation/core:enterprise_obfuscation", "//components/enterprise/obfuscation/core:enterprise_obfuscation",
"//components/safe_browsing/core/browser/db:safebrowsing_proto", "//components/safe_browsing/core/browser/db:safebrowsing_proto",
"//components/vector_icons", "//components/vector_icons:vector_icons",
"//ui/base/accelerators/global_accelerator_listener", "//ui/base/accelerators/global_accelerator_listener",
"//ui/snapshot", "//ui/snapshot",
"//ui/views/controls/webview", "//ui/views/controls/webview",
@@ -223,8 +213,8 @@ static_library("chrome") {
sources += [ sources += [
"//chrome/browser/platform_util_aura.cc", "//chrome/browser/platform_util_aura.cc",
"//chrome/browser/ui/views/eye_dropper/eye_dropper_aura.cc", "//chrome/browser/ui/views/eye_dropper/eye_dropper_aura.cc",
"//ui/native_window_tracker/native_window_tracker_aura.cc", "//ui/views/native_window_tracker_aura.cc",
"//ui/native_window_tracker/native_window_tracker_aura.h", "//ui/views/native_window_tracker_aura.h",
] ]
deps += [ "//components/eye_dropper" ] deps += [ "//components/eye_dropper" ]
} }
@@ -280,8 +270,6 @@ static_library("chrome") {
"//chrome/browser/process_singleton_mac.mm", "//chrome/browser/process_singleton_mac.mm",
"//chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.h", "//chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.h",
"//chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm", "//chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm",
"//chrome/browser/ui/views/overlay/video_overlay_window_native_widget_mac.h",
"//chrome/browser/ui/views/overlay/video_overlay_window_native_widget_mac.mm",
] ]
deps += [ ":system_media_capture_permissions_mac_conflict" ] deps += [ ":system_media_capture_permissions_mac_conflict" ]
} }
@@ -504,17 +492,15 @@ source_set("chrome_spellchecker") {
] ]
} }
if (is_mac) { # These sources create an object file conflict with one in |:chrome|, so they
# These sources create an object file conflict with one in |:chrome|, so they # must live in a separate target.
# must live in a separate target. # Conflicting sources:
# Conflicting sources: # //chrome/browser/media/webrtc/system_media_capture_permissions_stats_mac.mm
# //chrome/browser/media/webrtc/system_media_capture_permissions_stats_mac.mm # //chrome/browser/permissions/system/system_media_capture_permissions_mac.mm
# //chrome/browser/permissions/system/system_media_capture_permissions_mac.mm source_set("system_media_capture_permissions_mac_conflict") {
source_set("system_media_capture_permissions_mac_conflict") { sources = [
sources = [ "//chrome/browser/permissions/system/system_media_capture_permissions_mac.h",
"//chrome/browser/permissions/system/system_media_capture_permissions_mac.h", "//chrome/browser/permissions/system/system_media_capture_permissions_mac.mm",
"//chrome/browser/permissions/system/system_media_capture_permissions_mac.mm", ]
] deps = [ "//chrome/common" ]
deps = [ "//chrome/common" ]
}
} }

View File

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

View File

@@ -1,35 +0,0 @@
{
"extends": "standard",
"plugins": [
"import",
"markdown"
],
"overrides": [
{
"files": ["*.md", "**/*.md"],
"processor": "markdown/markdown"
}
],
"rules": {
"@typescript-eslint/no-unused-vars": "off",
"import/order": ["error", {
"alphabetize": {
"order": "asc"
},
"newlines-between": "always",
"pathGroups": [
{
"pattern": "{electron,electron/**}",
"group": "builtin",
"position": "before"
}
],
"pathGroupsExcludedImportTypes": []
}],
"n/no-callback-literal": "off",
"no-undef": "off",
"no-unused-expressions": "off",
"no-unused-vars": "off",
"import/enforce-node-protocol-usage": ["error", "always"]
}
}

View File

@@ -96,9 +96,8 @@ These individual tutorials expand on topics discussed in the guide above.
* [Chrome Extensions Support](api/extensions.md) * [Chrome Extensions Support](api/extensions.md)
* [Breaking API Changes](breaking-changes.md) * [Breaking API Changes](breaking-changes.md)
### Custom Web Features: ### Custom DOM Elements:
* [`-electron-corner-smoothing` CSS Rule](api/corner-smoothing-css.md)
* [`<webview>` Tag](api/webview-tag.md) * [`<webview>` Tag](api/webview-tag.md)
* [`window.open` Function](api/window-open.md) * [`window.open` Function](api/window-open.md)
@@ -113,7 +112,6 @@ These individual tutorials expand on topics discussed in the guide above.
* [dialog](api/dialog.md) * [dialog](api/dialog.md)
* [globalShortcut](api/global-shortcut.md) * [globalShortcut](api/global-shortcut.md)
* [inAppPurchase](api/in-app-purchase.md) * [inAppPurchase](api/in-app-purchase.md)
* [ImageView](api/image-view.md)
* [ipcMain](api/ipc-main.md) * [ipcMain](api/ipc-main.md)
* [Menu](api/menu.md) * [Menu](api/menu.md)
* [MenuItem](api/menu-item.md) * [MenuItem](api/menu-item.md)

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

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

View File

@@ -9,7 +9,6 @@ closed:
```js ```js
const { app } = require('electron') const { app } = require('electron')
app.on('window-all-closed', () => { app.on('window-all-closed', () => {
app.quit() app.quit()
}) })
@@ -42,10 +41,9 @@ that was used to open the application, if it was launched from Notification Cent
You can also call `app.isReady()` to check if this event has already fired and `app.whenReady()` You can also call `app.isReady()` to check if this event has already fired and `app.whenReady()`
to get a Promise that is fulfilled when Electron is initialized. to get a Promise that is fulfilled when Electron is initialized.
> [!NOTE] **Note**: The `ready` event is only fired after the main process has finished running the first
> The `ready` event is only fired after the main process has finished running the first tick of the event loop. If an Electron API needs to be called before the `ready` event, ensure
> tick of the event loop. If an Electron API needs to be called before the `ready` event, ensure that it is called synchronously in the top-level context of the main process.
> that it is called synchronously in the top-level context of the main process.
### Event: 'window-all-closed' ### Event: 'window-all-closed'
@@ -68,14 +66,12 @@ Emitted before the application starts closing its windows.
Calling `event.preventDefault()` will prevent the default behavior, which is Calling `event.preventDefault()` will prevent the default behavior, which is
terminating the application. terminating the application.
> [!NOTE] **Note:** If application quit was initiated by `autoUpdater.quitAndInstall()`,
> If application quit was initiated by `autoUpdater.quitAndInstall()`, then `before-quit` is emitted _after_ emitting `close` event on all windows and
> then `before-quit` is emitted _after_ emitting `close` event on all windows and closing them.
> closing them.
> [!NOTE] **Note:** On Windows, this event will not be emitted if the app is closed due
> On Windows, this event will not be emitted if the app is closed due to a shutdown/restart of the system or a user logout.
> to a shutdown/restart of the system or a user logout.
### Event: 'will-quit' ### Event: 'will-quit'
@@ -90,9 +86,8 @@ terminating the application.
See the description of the `window-all-closed` event for the differences between See the description of the `window-all-closed` event for the differences between
the `will-quit` and `window-all-closed` events. the `will-quit` and `window-all-closed` events.
> [!NOTE] **Note:** On Windows, this event will not be emitted if the app is closed due
> On Windows, this event will not be emitted if the app is closed due to a shutdown/restart of the system or a user logout.
> to a shutdown/restart of the system or a user logout.
### Event: 'quit' ### Event: 'quit'
@@ -103,9 +98,8 @@ Returns:
Emitted when the application is quitting. Emitted when the application is quitting.
> [!NOTE] **Note:** On Windows, this event will not be emitted if the app is closed due
> On Windows, this event will not be emitted if the app is closed due to a shutdown/restart of the system or a user logout.
> to a shutdown/restart of the system or a user logout.
### Event: 'open-file' _macOS_ ### Event: 'open-file' _macOS_
@@ -476,28 +470,24 @@ and `workingDirectory` is its current working directory. Usually
applications respond to this by making their primary window focused and applications respond to this by making their primary window focused and
non-minimized. non-minimized.
> [!NOTE] **Note:** `argv` will not be exactly the same list of arguments as those passed
> `argv` will not be exactly the same list of arguments as those passed to the second instance. The order might change and additional arguments might be appended.
> to the second instance. The order might change and additional arguments might be appended. If you need to maintain the exact same arguments, it's advised to use `additionalData` instead.
> If you need to maintain the exact same arguments, it's advised to use `additionalData` instead.
> [!NOTE] **Note:** If the second instance is started by a different user than the first, the `argv` array will not include the arguments.
> If the second instance is started by a different user than the first, the `argv` array will not include the arguments.
This event is guaranteed to be emitted after the `ready` event of `app` This event is guaranteed to be emitted after the `ready` event of `app`
gets emitted. gets emitted.
> [!NOTE] **Note:** Extra command line arguments might be added by Chromium,
> Extra command line arguments might be added by Chromium, such as `--original-process-start-time`.
> such as `--original-process-start-time`.
## Methods ## Methods
The `app` object has the following methods: The `app` object has the following methods:
> [!NOTE] **Note:** Some methods are only available on specific operating systems and are
> Some methods are only available on specific operating systems and are labeled as such.
> labeled as such.
### `app.quit()` ### `app.quit()`
@@ -602,7 +592,6 @@ Returns `string` - The current application directory.
* `%APPDATA%` on Windows * `%APPDATA%` on Windows
* `$XDG_CONFIG_HOME` or `~/.config` on Linux * `$XDG_CONFIG_HOME` or `~/.config` on Linux
* `~/Library/Application Support` on macOS * `~/Library/Application Support` on macOS
* `assets` The directory where app assets such as `resources.pak` are stored. By default this is the same as the folder containing the `exe` path. Available on Windows and Linux only.
* `userData` The directory for storing your app's configuration files, which * `userData` The directory for storing your app's configuration files, which
by default is the `appData` directory appended with your app's name. By by default is the `appData` directory appended with your app's name. By
convention files storing user data should be written to this directory, and convention files storing user data should be written to this directory, and
@@ -617,7 +606,7 @@ Returns `string` - The current application directory.
directory. directory.
* `temp` Temporary directory. * `temp` Temporary directory.
* `exe` The current executable file. * `exe` The current executable file.
* `module` The location of the Chromium module. By default this is synonymous with `exe`. * `module` The `libchromiumcontent` library.
* `desktop` The current user's Desktop directory. * `desktop` The current user's Desktop directory.
* `documents` Directory for a user's "My Documents". * `documents` Directory for a user's "My Documents".
* `downloads` Directory for a user's downloads. * `downloads` Directory for a user's downloads.
@@ -690,8 +679,7 @@ preferred over `name` by Electron.
Overrides the current application's name. Overrides the current application's name.
> [!NOTE] **Note:** This function overrides the name used internally by Electron; it does not affect the name that the OS uses.
> This function overrides the name used internally by Electron; it does not affect the name that the OS uses.
### `app.getLocale()` ### `app.getLocale()`
@@ -700,22 +688,18 @@ Possible return values are documented [here](https://source.chromium.org/chromiu
To set the locale, you'll want to use a command line switch at app startup, which may be found [here](command-line-switches.md). To set the locale, you'll want to use a command line switch at app startup, which may be found [here](command-line-switches.md).
> [!NOTE] **Note:** When distributing your packaged app, you have to also ship the
> When distributing your packaged app, you have to also ship the `locales` folder.
> `locales` folder.
> [!NOTE] **Note:** This API must be called after the `ready` event is emitted.
> This API must be called after the `ready` event is emitted.
> [!NOTE] **Note:** To see example return values of this API compared to other locale and language APIs, see [`app.getPreferredSystemLanguages()`](#appgetpreferredsystemlanguages).
> To see example return values of this API compared to other locale and language APIs, see [`app.getPreferredSystemLanguages()`](#appgetpreferredsystemlanguages).
### `app.getLocaleCountryCode()` ### `app.getLocaleCountryCode()`
Returns `string` - User operating system's locale two-letter [ISO 3166](https://www.iso.org/iso-3166-country-codes.html) country code. The value is taken from native OS APIs. Returns `string` - User operating system's locale two-letter [ISO 3166](https://www.iso.org/iso-3166-country-codes.html) country code. The value is taken from native OS APIs.
> [!NOTE] **Note:** When unable to detect locale country code, it returns empty string.
> When unable to detect locale country code, it returns empty string.
### `app.getSystemLocale()` ### `app.getSystemLocale()`
@@ -728,11 +712,9 @@ Different operating systems also use the regional data differently:
Therefore, this API can be used for purposes such as choosing a format for rendering dates and times in a calendar app, especially when the developer wants the format to be consistent with the OS. Therefore, this API can be used for purposes such as choosing a format for rendering dates and times in a calendar app, especially when the developer wants the format to be consistent with the OS.
> [!NOTE] **Note:** This API must be called after the `ready` event is emitted.
> This API must be called after the `ready` event is emitted.
> [!NOTE] **Note:** To see example return values of this API compared to other locale and language APIs, see [`app.getPreferredSystemLanguages()`](#appgetpreferredsystemlanguages).
> To see example return values of this API compared to other locale and language APIs, see [`app.getPreferredSystemLanguages()`](#appgetpreferredsystemlanguages).
### `app.getPreferredSystemLanguages()` ### `app.getPreferredSystemLanguages()`
@@ -777,22 +759,6 @@ bar, and on macOS, you can visit it from dock menu.
Clears the recent documents list. Clears the recent documents list.
### `app.getRecentDocuments()` _macOS_ _Windows_
Returns `string[]` - An array containing documents in the most recent documents list.
```js
const { app } = require('electron')
const path = require('node:path')
const file = path.join(app.getPath('desktop'), 'foo.txt')
app.addRecentDocument(file)
const recents = app.getRecentDocuments()
console.log(recents) // ['/path/to/desktop/foo.txt'}
```
### `app.setAsDefaultProtocolClient(protocol[, path, args])` ### `app.setAsDefaultProtocolClient(protocol[, path, args])`
* `protocol` string - The name of your protocol, without `://`. For example, * `protocol` string - The name of your protocol, without `://`. For example,
@@ -811,18 +777,16 @@ Once registered, all links with `your-protocol://` will be opened with the
current executable. The whole link, including protocol, will be passed to your current executable. The whole link, including protocol, will be passed to your
application as a parameter. application as a parameter.
> [!NOTE] **Note:** On macOS, you can only register protocols that have been added to
> On macOS, you can only register protocols that have been added to your app's `info.plist`, which cannot be modified at runtime. However, you can
> your app's `info.plist`, which cannot be modified at runtime. However, you can change the file during build time via [Electron Forge][electron-forge],
> change the file during build time via [Electron Forge][electron-forge], [Electron Packager][electron-packager], or by editing `info.plist` with a text
> [Electron Packager][electron-packager], or by editing `info.plist` with a text editor. Please refer to [Apple's documentation][CFBundleURLTypes] for details.
> editor. Please refer to [Apple's documentation][CFBundleURLTypes] for details.
> [!NOTE] **Note:** In a Windows Store environment (when packaged as an `appx`) this API
> In a Windows Store environment (when packaged as an `appx`) this API will return `true` for all calls but the registry key it sets won't be accessible
> will return `true` for all calls but the registry key it sets won't be accessible by other applications. In order to register your Windows Store application
> by other applications. In order to register your Windows Store application as a default protocol handler you must [declare the protocol in your manifest](https://learn.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-uap-protocol).
> as a default protocol handler you must [declare the protocol in your manifest](https://learn.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-uap-protocol).
The API uses the Windows Registry and `LSSetDefaultHandlerForURLScheme` internally. The API uses the Windows Registry and `LSSetDefaultHandlerForURLScheme` internally.
@@ -846,12 +810,11 @@ protocol (aka URI scheme). If so, it will remove the app as the default handler.
Returns `boolean` - Whether the current executable is the default handler for a Returns `boolean` - Whether the current executable is the default handler for a
protocol (aka URI scheme). protocol (aka URI scheme).
> [!NOTE] **Note:** On macOS, you can use this method to check if the app has been
> On macOS, you can use this method to check if the app has been registered as the default protocol handler for a protocol. You can also verify
> registered as the default protocol handler for a protocol. You can also verify this by checking `~/Library/Preferences/com.apple.LaunchServices.plist` on the
> this by checking `~/Library/Preferences/com.apple.LaunchServices.plist` on the macOS machine. Please refer to
> macOS machine. Please refer to [Apple's documentation][LSCopyDefaultHandlerForURLScheme] for details.
> [Apple's documentation][LSCopyDefaultHandlerForURLScheme] for details.
The API uses the Windows Registry and `LSCopyDefaultHandlerForURLScheme` internally. The API uses the Windows Registry and `LSCopyDefaultHandlerForURLScheme` internally.
@@ -895,9 +858,8 @@ Adds `tasks` to the [Tasks][tasks] category of the Jump List on Windows.
Returns `boolean` - Whether the call succeeded. Returns `boolean` - Whether the call succeeded.
> [!NOTE] **Note:** If you'd like to customize the Jump List even more use
> If you'd like to customize the Jump List even more use `app.setJumpList(categories)` instead.
> `app.setJumpList(categories)` instead.
### `app.getJumpListSettings()` _Windows_ ### `app.getJumpListSettings()` _Windows_
@@ -935,24 +897,21 @@ following strings:
If `categories` is `null` the previously set custom Jump List (if any) will be If `categories` is `null` the previously set custom Jump List (if any) will be
replaced by the standard Jump List for the app (managed by Windows). replaced by the standard Jump List for the app (managed by Windows).
> [!NOTE] **Note:** If a `JumpListCategory` object has neither the `type` nor the `name`
> If a `JumpListCategory` object has neither the `type` nor the `name` property set then its `type` is assumed to be `tasks`. If the `name` property
> property set then its `type` is assumed to be `tasks`. If the `name` property
is set but the `type` property is omitted then the `type` is assumed to be is set but the `type` property is omitted then the `type` is assumed to be
`custom`. `custom`.
> [!NOTE] **Note:** Users can remove items from custom categories, and Windows will not
> Users can remove items from custom categories, and Windows will not allow a removed item to be added back into a custom category until **after**
> allow a removed item to be added back into a custom category until **after** the next successful call to `app.setJumpList(categories)`. Any attempt to
> the next successful call to `app.setJumpList(categories)`. Any attempt to re-add a removed item to a custom category earlier than that will result in the
> re-add a removed item to a custom category earlier than that will result in the entire custom category being omitted from the Jump List. The list of removed
> entire custom category being omitted from the Jump List. The list of removed items can be obtained using `app.getJumpListSettings()`.
> items can be obtained using `app.getJumpListSettings()`.
> [!NOTE] **Note:** The maximum length of a Jump List item's `description` property is
> The maximum length of a Jump List item's `description` property is 260 characters. Beyond this limit, the item will not be added to the Jump
> 260 characters. Beyond this limit, the item will not be added to the Jump List, nor will it be displayed.
> List, nor will it be displayed.
Here's a very simple example of creating a custom Jump List: Here's a very simple example of creating a custom Jump List:
@@ -1041,7 +1000,6 @@ starts:
```js ```js
const { app, BrowserWindow } = require('electron') const { app, BrowserWindow } = require('electron')
let myWindow = null let myWindow = null
const additionalData = { myKey: 'myValue' } const additionalData = { myKey: 'myValue' }
@@ -1152,11 +1110,6 @@ indicates success while any other value indicates failure according to Chromium
resolver will attempt to use the system's DNS settings to do DNS lookups resolver will attempt to use the system's DNS settings to do DNS lookups
itself. Enabled by default on macOS, disabled by default on Windows and itself. Enabled by default on macOS, disabled by default on Windows and
Linux. Linux.
* `enableHappyEyeballs` boolean (optional) - Whether the
[Happy Eyeballs V3][happy-eyeballs-v3] algorithm should be used in creating
network connections. When enabled, hostnames resolving to multiple IP
addresses will be attempted in parallel to have a chance at establishing a
connection more quickly.
* `secureDnsMode` string (optional) - Can be 'off', 'automatic' or 'secure'. * `secureDnsMode` string (optional) - Can be 'off', 'automatic' or 'secure'.
Configures the DNS-over-HTTP mode. When 'off', no DoH lookups will be Configures the DNS-over-HTTP mode. When 'off', no DoH lookups will be
performed. When 'automatic', DoH lookups will be performed first if DoH is performed. When 'automatic', DoH lookups will be performed first if DoH is
@@ -1230,8 +1183,7 @@ Returns [`ProcessMetric[]`](structures/process-metric.md): Array of `ProcessMetr
Returns [`GPUFeatureStatus`](structures/gpu-feature-status.md) - The Graphics Feature Status from `chrome://gpu/`. Returns [`GPUFeatureStatus`](structures/gpu-feature-status.md) - The Graphics Feature Status from `chrome://gpu/`.
> [!NOTE] **Note:** This information is only usable after the `gpu-info-update` event is emitted.
> This information is only usable after the `gpu-info-update` event is emitted.
### `app.getGPUInfo(infoType)` ### `app.getGPUInfo(infoType)`
@@ -1245,8 +1197,6 @@ For `infoType` equal to `complete`:
For `infoType` equal to `basic`: For `infoType` equal to `basic`:
Promise is fulfilled with `Object` containing fewer attributes than when requested with `complete`. Here's an example of basic response: Promise is fulfilled with `Object` containing fewer attributes than when requested with `complete`. Here's an example of basic response:
<!-- eslint-skip -->
```js ```js
{ {
auxAttributes: auxAttributes:
@@ -1287,13 +1237,11 @@ badge.
On macOS, it shows on the dock icon. On Linux, it only works for Unity launcher. On macOS, it shows on the dock icon. On Linux, it only works for Unity launcher.
> [!NOTE] **Note:** Unity launcher requires a `.desktop` file to work. For more information,
> Unity launcher requires a `.desktop` file to work. For more information, please read the [Unity integration documentation][unity-requirement].
> please read the [Unity integration documentation][unity-requirement].
> [!NOTE] **Note:** On macOS, you need to ensure that your application has the permission
> On macOS, you need to ensure that your application has the permission to display notifications for this method to work.
> to display notifications for this method to work.
### `app.getBadgeCount()` _Linux_ _macOS_ ### `app.getBadgeCount()` _Linux_ _macOS_
@@ -1360,7 +1308,6 @@ latest version.
``` js ``` js
const { app } = require('electron') const { app } = require('electron')
const path = require('node:path') const path = require('node:path')
const appFolder = path.dirname(process.execPath) const appFolder = path.dirname(process.execPath)
@@ -1396,8 +1343,7 @@ details. Disabled by default.
This API must be called after the `ready` event is emitted. This API must be called after the `ready` event is emitted.
> [!NOTE] **Note:** Rendering accessibility tree can significantly affect the performance of your app. It should not be enabled by default.
> Rendering accessibility tree can significantly affect the performance of your app. It should not be enabled by default.
### `app.showAboutPanel()` ### `app.showAboutPanel()`
@@ -1435,7 +1381,6 @@ Returns `Function` - This function **must** be called once you have finished acc
```js ```js
const { app, dialog } = require('electron') const { app, dialog } = require('electron')
const fs = require('node:fs') const fs = require('node:fs')
let filepath let filepath
@@ -1526,8 +1471,7 @@ By using this API, important information such as password and other sensitive in
See [Apple's documentation](https://developer.apple.com/library/archive/technotes/tn2150/_index.html) for more See [Apple's documentation](https://developer.apple.com/library/archive/technotes/tn2150/_index.html) for more
details. details.
> [!NOTE] **Note:** Enable `Secure Keyboard Entry` only when it is needed and disable it when it is no longer needed.
> Enable `Secure Keyboard Entry` only when it is needed and disable it when it is no longer needed.
### `app.setProxy(config)` ### `app.setProxy(config)`
@@ -1541,7 +1485,7 @@ and internal requests made by the runtime (ex: geolocation queries).
This method can only be called after app is ready. This method can only be called after app is ready.
### `app.resolveProxy(url)` #### `app.resolveProxy(url)`
* `url` URL * `url` URL
@@ -1589,8 +1533,7 @@ See [Chromium's accessibility docs](https://www.chromium.org/developers/design-d
This API must be called after the `ready` event is emitted. This API must be called after the `ready` event is emitted.
> [!NOTE] **Note:** Rendering accessibility tree can significantly affect the performance of your app. It should not be enabled by default.
> Rendering accessibility tree can significantly affect the performance of your app. It should not be enabled by default.
### `app.applicationMenu` ### `app.applicationMenu`
@@ -1603,13 +1546,11 @@ An `Integer` property that returns the badge count for current app. Setting the
On macOS, setting this with any nonzero integer shows on the dock icon. On Linux, this property only works for Unity launcher. On macOS, setting this with any nonzero integer shows on the dock icon. On Linux, this property only works for Unity launcher.
> [!NOTE] **Note:** Unity launcher requires a `.desktop` file to work. For more information,
> Unity launcher requires a `.desktop` file to work. For more information, please read the [Unity integration documentation][unity-requirement].
> please read the [Unity integration documentation][unity-requirement].
> [!NOTE] **Note:** On macOS, you need to ensure that your application has the permission
> On macOS, you need to ensure that your application has the permission to display notifications for this property to take effect.
> to display notifications for this property to take effect.
### `app.commandLine` _Readonly_ ### `app.commandLine` _Readonly_
@@ -1618,8 +1559,8 @@ command line arguments that Chromium uses.
### `app.dock` _macOS_ _Readonly_ ### `app.dock` _macOS_ _Readonly_
A `Dock | undefined` property ([`Dock`](./dock.md) on macOS, `undefined` on all other A [`Dock`](./dock.md) `| undefined` object that allows you to perform actions on your app icon in the user's
platforms) that allows you to perform actions on your app icon in the user's dock. dock on macOS.
### `app.isPackaged` _Readonly_ ### `app.isPackaged` _Readonly_
@@ -1638,7 +1579,6 @@ A `boolean` property that returns `true` if the app is packaged, `false` otherw
[Squirrel-Windows]: https://github.com/Squirrel/Squirrel.Windows [Squirrel-Windows]: https://github.com/Squirrel/Squirrel.Windows
[JumpListBeginListMSDN]: https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-icustomdestinationlist-beginlist [JumpListBeginListMSDN]: https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-icustomdestinationlist-beginlist
[about-panel-options]: https://developer.apple.com/reference/appkit/nsapplication/1428479-orderfrontstandardaboutpanelwith?language=objc [about-panel-options]: https://developer.apple.com/reference/appkit/nsapplication/1428479-orderfrontstandardaboutpanelwith?language=objc
[happy-eyeballs-v3]: https://datatracker.ietf.org/doc/draft-pauly-happy-happyeyeballs-v3/
### `app.name` ### `app.name`

View File

@@ -26,9 +26,8 @@ requirements, you can read [Server Support][server-support]. Note that
update process. Apps that need to disable ATS can add the update process. Apps that need to disable ATS can add the
`NSAllowsArbitraryLoads` key to their app's plist. `NSAllowsArbitraryLoads` key to their app's plist.
> [!IMPORTANT] **Note:** Your application must be signed for automatic updates on macOS.
> Your application must be signed for automatic updates on macOS. This is a requirement of `Squirrel.Mac`.
> This is a requirement of `Squirrel.Mac`.
### Windows ### Windows
@@ -94,9 +93,8 @@ Emitted when an update has been downloaded.
On Windows only `releaseName` is available. On Windows only `releaseName` is available.
> [!NOTE] **Note:** It is not strictly necessary to handle this event. A successfully
> It is not strictly necessary to handle this event. A successfully downloaded update will still be applied the next time the application starts.
> downloaded update will still be applied the next time the application starts.
### Event: 'before-quit-for-update' ### Event: 'before-quit-for-update'
@@ -127,9 +125,8 @@ Returns `string` - The current update feed URL.
Asks the server whether there is an update. You must call `setFeedURL` before Asks the server whether there is an update. You must call `setFeedURL` before
using this API. using this API.
> [!NOTE] **Note:** If an update is available it will be downloaded automatically.
> If an update is available it will be downloaded automatically. Calling `autoUpdater.checkForUpdates()` twice will download the update two times.
> Calling `autoUpdater.checkForUpdates()` twice will download the update two times.
### `autoUpdater.quitAndInstall()` ### `autoUpdater.quitAndInstall()`
@@ -140,10 +137,9 @@ Under the hood calling `autoUpdater.quitAndInstall()` will close all application
windows first, and automatically call `app.quit()` after all windows have been windows first, and automatically call `app.quit()` after all windows have been
closed. closed.
> [!NOTE] **Note:** It is not strictly necessary to call this function to apply an update,
> It is not strictly necessary to call this function to apply an update, as a successfully downloaded update will always be applied the next time the
> as a successfully downloaded update will always be applied the next time the application starts.
> application starts.
[squirrel-mac]: https://github.com/Squirrel/Squirrel.Mac [squirrel-mac]: https://github.com/Squirrel/Squirrel.Mac
[server-support]: https://github.com/Squirrel/Squirrel.Mac#server-support [server-support]: https://github.com/Squirrel/Squirrel.Mac#server-support

View File

@@ -4,7 +4,7 @@
Process: [Main](../glossary.md#main-process) Process: [Main](../glossary.md#main-process)
> [!NOTE] > **Note**
> `BaseWindow` provides a flexible way to compose multiple web views in a > `BaseWindow` provides a flexible way to compose multiple web views in a
> single window. For windows with only a single, full-size web view, the > single window. For windows with only a single, full-size web view, the
> [`BrowserWindow`](browser-window.md) class may be a simpler option. > [`BrowserWindow`](browser-window.md) class may be a simpler option.
@@ -99,10 +99,6 @@ Process: [Main](../glossary.md#main-process)
It creates a new `BaseWindow` with native properties as set by the `options`. It creates a new `BaseWindow` with native properties as set by the `options`.
> [!WARNING]
> Electron's built-in classes cannot be subclassed in user code.
> For more information, see [the FAQ](../faq.md#class-inheritance-does-not-work-with-electron-built-in-modules).
### `new BaseWindow([options])` ### `new BaseWindow([options])`
* `options` [BaseWindowConstructorOptions](structures/base-window-options.md?inline) (optional) * `options` [BaseWindowConstructorOptions](structures/base-window-options.md?inline) (optional)
@@ -111,9 +107,8 @@ It creates a new `BaseWindow` with native properties as set by the `options`.
Objects created with `new BaseWindow` emit the following events: Objects created with `new BaseWindow` emit the following events:
> [!NOTE] **Note:** Some events are only available on specific operating systems and are
> Some events are only available on specific operating systems and are labeled as such.
> labeled as such.
#### Event: 'close' #### Event: 'close'
@@ -142,11 +137,7 @@ window.onbeforeunload = (e) => {
} }
``` ```
> [!NOTE] _**Note**: There is a subtle difference between the behaviors of `window.onbeforeunload = handler` and `window.addEventListener('beforeunload', handler)`. It is recommended to always set the `event.returnValue` explicitly, instead of only returning a value, as the former works more consistently within Electron._
> There is a subtle difference between the behaviors of `window.onbeforeunload = handler` and
> `window.addEventListener('beforeunload', handler)`. It is recommended to always set the
> `event.returnValue` explicitly, instead of only returning a value, as the former works more
> consistently within Electron.
#### Event: 'closed' #### Event: 'closed'
@@ -261,8 +252,7 @@ Emitted when the window is being moved to a new position.
Emitted once when the window is moved to a new position. Emitted once when the window is moved to a new position.
> [!NOTE] **Note**: On macOS this event is an alias of `move`.
> On macOS, this event is an alias of `move`.
#### Event: 'enter-full-screen' #### Event: 'enter-full-screen'
@@ -298,7 +288,6 @@ e.g. `APPCOMMAND_BROWSER_BACKWARD` is emitted as `browser-backward`.
```js ```js
const { BaseWindow } = require('electron') const { BaseWindow } = require('electron')
const win = new BaseWindow() const win = new BaseWindow()
win.on('app-command', (e, cmd) => { win.on('app-command', (e, cmd) => {
// Navigate the window back when the user hits their mouse back button // Navigate the window back when the user hits their mouse back button
@@ -353,12 +342,12 @@ Emitted when the window has closed a sheet.
Emitted when the native new tab button is clicked. Emitted when the native new tab button is clicked.
#### Event: 'system-context-menu' _Windows_ _Linux_ #### Event: 'system-context-menu' _Windows_
Returns: Returns:
* `event` Event * `event` Event
* `point` [Point](structures/point.md) - The screen coordinates where the context menu was triggered. * `point` [Point](structures/point.md) - The screen coordinates the context menu was triggered at
Emitted when the system context menu is triggered on the window, this is Emitted when the system context menu is triggered on the window, this is
normally only triggered when the user right clicks on the non-client area normally only triggered when the user right clicks on the non-client area
@@ -367,8 +356,6 @@ as `-webkit-app-region: drag` in a frameless window.
Calling `event.preventDefault()` will prevent the menu from being displayed. Calling `event.preventDefault()` will prevent the menu from being displayed.
To convert `point` to DIP, use [`screen.screenToDipPoint(point)`](./screen.md#screenscreentodippointpoint-windows-linux).
### Static Methods ### Static Methods
The `BaseWindow` class has the following static methods: The `BaseWindow` class has the following static methods:
@@ -409,7 +396,7 @@ A `View` property for the content view of the window.
A `string` (optional) property that is equal to the `tabbingIdentifier` passed to the `BrowserWindow` constructor or `undefined` if none was set. A `string` (optional) property that is equal to the `tabbingIdentifier` passed to the `BrowserWindow` constructor or `undefined` if none was set.
#### `win.autoHideMenuBar` _Linux_ _Windows_ #### `win.autoHideMenuBar`
A `boolean` property that determines whether the window menu bar should hide itself automatically. Once set, the menu bar will only show when users press the single `Alt` key. A `boolean` property that determines whether the window menu bar should hide itself automatically. Once set, the menu bar will only show when users press the single `Alt` key.
@@ -432,8 +419,7 @@ A `boolean` property that determines whether the window is focusable.
A `boolean` property that determines whether the window is visible on all workspaces. A `boolean` property that determines whether the window is visible on all workspaces.
> [!NOTE] **Note:** Always returns false on Windows.
> Always returns false on Windows.
#### `win.shadow` #### `win.shadow`
@@ -443,8 +429,7 @@ A `boolean` property that determines whether the window has a shadow.
A `boolean` property that determines whether the menu bar should be visible. A `boolean` property that determines whether the menu bar should be visible.
> [!NOTE] **Note:** If the menu bar is auto-hide, users can still bring up the menu bar by pressing the single `Alt` key.
> If the menu bar is auto-hide, users can still bring up the menu bar by pressing the single `Alt` key.
#### `win.kiosk` #### `win.kiosk`
@@ -465,8 +450,7 @@ and the icon of the file will show in window's title bar.
A `string` property that determines the title of the native window. A `string` property that determines the title of the native window.
> [!NOTE] **Note:** The title of the web page can be different from the title of the native window.
> The title of the web page can be different from the title of the native window.
#### `win.minimizable` _macOS_ _Windows_ #### `win.minimizable` _macOS_ _Windows_
@@ -507,7 +491,6 @@ A `boolean` property that determines whether the window is excluded from the app
```js @ts-expect-error=[12] ```js @ts-expect-error=[12]
const { Menu, BaseWindow } = require('electron') const { Menu, BaseWindow } = require('electron')
const win = new BaseWindow({ height: 600, width: 600 }) const win = new BaseWindow({ height: 600, width: 600 })
const template = [ const template = [
@@ -528,17 +511,12 @@ A `string` property that defines an alternative title provided only to
accessibility tools such as screen readers. This string is not directly accessibility tools such as screen readers. This string is not directly
visible to users. visible to users.
#### `win.snapped` _Windows_ _Readonly_
A `boolean` property that indicates whether the window is arranged via [Snap.](https://support.microsoft.com/en-us/windows/snap-your-windows-885a9b1e-a983-a3b1-16cd-c531795e6241)
### Instance Methods ### Instance Methods
Objects created with `new BaseWindow` have the following instance methods: Objects created with `new BaseWindow` have the following instance methods:
> [!NOTE] **Note:** Some methods are only available on specific operating systems and are
> Some methods are only available on specific operating systems and are labeled as such.
> labeled as such.
#### `win.setContentView(view)` #### `win.setContentView(view)`
@@ -630,8 +608,7 @@ Returns `boolean` - Whether the window is minimized.
Sets whether the window should be in fullscreen mode. Sets whether the window should be in fullscreen mode.
> [!NOTE] **Note:** On macOS, fullscreen transitions take place asynchronously. If further actions depend on the fullscreen state, use the ['enter-full-screen'](base-window.md#event-enter-full-screen) or ['leave-full-screen'](base-window.md#event-leave-full-screen) events.
> On macOS, fullscreen transitions take place asynchronously. If further actions depend on the fullscreen state, use the ['enter-full-screen'](base-window.md#event-enter-full-screen) or > ['leave-full-screen'](base-window.md#event-leave-full-screen) events.
#### `win.isFullScreen()` #### `win.isFullScreen()`
@@ -733,7 +710,6 @@ Resizes and moves the window to the supplied bounds. Any properties that are not
```js ```js
const { BaseWindow } = require('electron') const { BaseWindow } = require('electron')
const win = new BaseWindow() const win = new BaseWindow()
// set all bounds properties // set all bounds properties
@@ -746,15 +722,13 @@ win.setBounds({ width: 100 })
console.log(win.getBounds()) console.log(win.getBounds())
``` ```
> [!NOTE] **Note:** On macOS, the y-coordinate value cannot be smaller than the [Tray](tray.md) height. The tray height has changed over time and depends on the operating system, but is between 20-40px. Passing a value lower than the tray height will result in a window that is flush to the tray.
> On macOS, the y-coordinate value cannot be smaller than the [Tray](tray.md) height. The tray height has changed over time and depends on the operating system, but is between 20-40px. Passing a value lower than the tray height will result in a window that is flush to the tray.
#### `win.getBounds()` #### `win.getBounds()`
Returns [`Rectangle`](structures/rectangle.md) - The `bounds` of the window as `Object`. Returns [`Rectangle`](structures/rectangle.md) - The `bounds` of the window as `Object`.
> [!NOTE] **Note:** On macOS, the y-coordinate value returned will be at minimum the [Tray](tray.md) height. For example, calling `win.setBounds({ x: 25, y: 20, width: 800, height: 600 })` with a tray height of 38 means that `win.getBounds()` will return `{ x: 25, y: 38, width: 800, height: 600 }`.
> On macOS, the y-coordinate value returned will be at minimum the [Tray](tray.md) height. For example, calling `win.setBounds({ x: 25, y: 20, width: 800, height: 600 })` with a tray height of 38 means that `win.getBounds()` will return `{ x: 25, y: 38, width: 800, height: 600 }`.
#### `win.getBackgroundColor()` #### `win.getBackgroundColor()`
@@ -762,8 +736,7 @@ Returns `string` - Gets the background color of the window in Hex (`#RRGGBB`) fo
See [Setting `backgroundColor`](browser-window.md#setting-the-backgroundcolor-property). See [Setting `backgroundColor`](browser-window.md#setting-the-backgroundcolor-property).
> [!NOTE] **Note:** The alpha value is _not_ returned alongside the red, green, and blue values.
> The alpha value is _not_ returned alongside the red, green, and blue values.
#### `win.setContentBounds(bounds[, animate])` #### `win.setContentBounds(bounds[, animate])`
@@ -781,8 +754,7 @@ Returns [`Rectangle`](structures/rectangle.md) - The `bounds` of the window's cl
Returns [`Rectangle`](structures/rectangle.md) - Contains the window bounds of the normal state Returns [`Rectangle`](structures/rectangle.md) - Contains the window bounds of the normal state
> [!NOTE] **Note:** whatever the current state of the window : maximized, minimized or in fullscreen, this function always returns the position and size of the window in normal state. In normal state, getBounds and getNormalBounds returns the same [`Rectangle`](structures/rectangle.md).
> Whatever the current state of the window : maximized, minimized or in fullscreen, this function always returns the position and size of the window in normal state. In normal state, getBounds and getNormalBounds returns the same [`Rectangle`](structures/rectangle.md).
#### `win.setEnabled(enable)` #### `win.setEnabled(enable)`
@@ -979,9 +951,8 @@ Changes the title of native window to `title`.
Returns `string` - The title of the native window. Returns `string` - The title of the native window.
> [!NOTE] **Note:** The title of the web page can be different from the title of the native
> The title of the web page can be different from the title of the native window.
> window.
#### `win.setSheetOffset(offsetY[, offsetX])` _macOS_ #### `win.setSheetOffset(offsetY[, offsetX])` _macOS_
@@ -994,7 +965,6 @@ a HTML-rendered toolbar. For example:
```js ```js
const { BaseWindow } = require('electron') const { BaseWindow } = require('electron')
const win = new BaseWindow() const win = new BaseWindow()
const toolbarRect = document.getElementById('toolbar').getBoundingClientRect() const toolbarRect = document.getElementById('toolbar').getBoundingClientRect()
@@ -1256,46 +1226,8 @@ in the taskbar.
Sets the properties for the window's taskbar button. Sets the properties for the window's taskbar button.
> [!NOTE] **Note:** `relaunchCommand` and `relaunchDisplayName` must always be set
> `relaunchCommand` and `relaunchDisplayName` must always be set together. If one of those properties is not set, then neither will be used.
> together. If one of those properties is not set, then neither will be used.
#### `win.setAccentColor(accentColor)` _Windows_
* `accentColor` boolean | string - The accent color for the window. By default, follows user preference in System Settings.
Sets the system accent color and highlighting of active window border.
The `accentColor` parameter accepts the following values:
* **Color string** - Sets a custom accent color using standard CSS color formats (Hex, RGB, RGBA, HSL, HSLA, or named colors). Alpha values in RGBA/HSLA formats are ignored and the color is treated as fully opaque.
* **`true`** - Uses the system's default accent color from user preferences in System Settings.
* **`false`** - Explicitly disables accent color highlighting for the window.
Examples:
```js
const win = new BrowserWindow({ frame: false })
// Set red accent color.
win.setAccentColor('#ff0000')
// RGB format (alpha ignored if present).
win.setAccentColor('rgba(255,0,0,0.5)')
// Use system accent color.
win.setAccentColor(true)
// Disable accent color.
win.setAccentColor(false)
```
#### `win.getAccentColor()` _Windows_
Returns `string | boolean` - the system accent color and highlighting of active window border in Hex RGB format.
If a color has been set for the window that differs from the system accent color, the window accent color will
be returned. Otherwise, a boolean will be returned, with `true` indicating that the window uses the global system accent color, and `false` indicating that accent color highlighting is disabled for this window.
#### `win.setIcon(icon)` _Windows_ _Linux_ #### `win.setIcon(icon)` _Windows_ _Linux_
@@ -1332,13 +1264,6 @@ Sets whether the menu bar should be visible. If the menu bar is auto-hide, users
Returns `boolean` - Whether the menu bar is visible. Returns `boolean` - Whether the menu bar is visible.
#### `win.isSnapped()` _Windows_
Returns `boolean` - whether the window is arranged via [Snap.](https://support.microsoft.com/en-us/windows/snap-your-windows-885a9b1e-a983-a3b1-16cd-c531795e6241)
The window is snapped via buttons shown when the mouse is hovered over window
maximize button, or by dragging it to the edges of the screen.
#### `win.setVisibleOnAllWorkspaces(visible[, options])` _macOS_ _Linux_ #### `win.setVisibleOnAllWorkspaces(visible[, options])` _macOS_ _Linux_
* `visible` boolean * `visible` boolean
@@ -1355,15 +1280,13 @@ maximize button, or by dragging it to the edges of the screen.
Sets whether the window should be visible on all workspaces. Sets whether the window should be visible on all workspaces.
> [!NOTE] **Note:** This API does nothing on Windows.
> This API does nothing on Windows.
#### `win.isVisibleOnAllWorkspaces()` _macOS_ _Linux_ #### `win.isVisibleOnAllWorkspaces()` _macOS_ _Linux_
Returns `boolean` - Whether the window is visible on all workspaces. Returns `boolean` - Whether the window is visible on all workspaces.
> [!NOTE] **Note:** This API always returns false on Windows.
> This API always returns false on Windows.
#### `win.setIgnoreMouseEvents(ignore[, options])` #### `win.setIgnoreMouseEvents(ignore[, options])`
@@ -1391,10 +1314,6 @@ On Windows it calls SetWindowDisplayAffinity with `WDA_EXCLUDEFROMCAPTURE`.
For Windows 10 version 2004 and up the window will be removed from capture entirely, For Windows 10 version 2004 and up the window will be removed from capture entirely,
older Windows versions behave as if `WDA_MONITOR` is applied capturing a black window. older Windows versions behave as if `WDA_MONITOR` is applied capturing a black window.
#### `win.isContentProtected()` _macOS_ _Windows_
Returns `boolean` - whether or not content protection is currently enabled.
#### `win.setFocusable(focusable)` _macOS_ _Windows_ #### `win.setFocusable(focusable)` _macOS_ _Windows_
* `focusable` boolean * `focusable` boolean
@@ -1484,8 +1403,7 @@ This method sets the browser window's system-drawn background material, includin
See the [Windows documentation](https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwm_systembackdrop_type) for more details. See the [Windows documentation](https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwm_systembackdrop_type) for more details.
> [!NOTE] **Note:** This method is only supported on Windows 11 22H2 and up.
> This method is only supported on Windows 11 22H2 and up.
#### `win.setWindowButtonPosition(position)` _macOS_ #### `win.setWindowButtonPosition(position)` _macOS_
@@ -1507,9 +1425,8 @@ Sets the touchBar layout for the current window. Specifying `null` or
`undefined` clears the touch bar. This method only has an effect if the `undefined` clears the touch bar. This method only has an effect if the
machine has a touch bar. machine has a touch bar.
> [!NOTE] **Note:** The TouchBar API is currently experimental and may change or be
> The TouchBar API is currently experimental and may change or be removed in future Electron releases.
> removed in future Electron releases.
#### `win.setTitleBarOverlay(options)` _Windows_ _Linux_ #### `win.setTitleBarOverlay(options)` _Windows_ _Linux_

View File

@@ -8,7 +8,7 @@ deprecated:
``` ```
--> -->
> [!NOTE] > **Note**
> The `BrowserView` class is deprecated, and replaced by the new > The `BrowserView` class is deprecated, and replaced by the new
> [`WebContentsView`](web-contents-view.md) class. > [`WebContentsView`](web-contents-view.md) class.
@@ -29,7 +29,7 @@ deprecated:
> Create and control views. > Create and control views.
> [!NOTE] > **Note**
> The `BrowserView` class is deprecated, and replaced by the new > The `BrowserView` class is deprecated, and replaced by the new
> [`WebContentsView`](web-contents-view.md) class. > [`WebContentsView`](web-contents-view.md) class.
@@ -38,10 +38,6 @@ Process: [Main](../glossary.md#main-process)
This module cannot be used until the `ready` event of the `app` This module cannot be used until the `ready` event of the `app`
module is emitted. module is emitted.
> [!WARNING]
> Electron's built-in classes cannot be subclassed in user code.
> For more information, see [the FAQ](../faq.md#class-inheritance-does-not-work-with-electron-built-in-modules).
### Example ### Example
```js ```js
@@ -180,5 +176,4 @@ Examples of valid `color` values:
* Similar to CSS Color Module Level 3 keywords, but case-sensitive. * Similar to CSS Color Module Level 3 keywords, but case-sensitive.
* e.g. `blueviolet` or `red` * e.g. `blueviolet` or `red`
> [!NOTE] **Note:** Hex format with alpha takes `AARRGGBB` or `ARGB`, _not_ `RRGGBBAA` or `RGB`.
> Hex format with alpha takes `AARRGGBB` or `ARGB`, _not_ `RRGGBBAA` or `RGB`.

View File

@@ -40,7 +40,6 @@ the window after this event will have no visual flash:
```js ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ show: false }) const win = new BrowserWindow({ show: false })
win.once('ready-to-show', () => { win.once('ready-to-show', () => {
win.show() win.show()
@@ -151,10 +150,6 @@ Process: [Main](../glossary.md#main-process)
It creates a new `BrowserWindow` with native properties as set by the `options`. It creates a new `BrowserWindow` with native properties as set by the `options`.
> [!WARNING]
> Electron's built-in classes cannot be subclassed in user code.
> For more information, see [the FAQ](../faq.md#class-inheritance-does-not-work-with-electron-built-in-modules).
### `new BrowserWindow([options])` ### `new BrowserWindow([options])`
* `options` [BrowserWindowConstructorOptions](structures/browser-window-options.md?inline) (optional) * `options` [BrowserWindowConstructorOptions](structures/browser-window-options.md?inline) (optional)
@@ -163,8 +158,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
Objects created with `new BrowserWindow` emit the following events: Objects created with `new BrowserWindow` emit the following events:
> [!NOTE] **Note:** Some events are only available on specific operating systems and are
> Some events are only available on specific operating systems and are
labeled as such. labeled as such.
#### Event: 'page-title-updated' #### Event: 'page-title-updated'
@@ -206,11 +200,7 @@ window.onbeforeunload = (e) => {
} }
``` ```
> [!NOTE] _**Note**: There is a subtle difference between the behaviors of `window.onbeforeunload = handler` and `window.addEventListener('beforeunload', handler)`. It is recommended to always set the `event.returnValue` explicitly, instead of only returning a value, as the former works more consistently within Electron._
> There is a subtle difference between the behaviors of `window.onbeforeunload = handler` and
> `window.addEventListener('beforeunload', handler)`. It is recommended to always set the
> `event.returnValue` explicitly, instead of only returning a value, as the former works more
> consistently within Electron.
#### Event: 'closed' #### Event: 'closed'
@@ -333,8 +323,7 @@ Emitted when the window is being moved to a new position.
Emitted once when the window is moved to a new position. Emitted once when the window is moved to a new position.
> [!NOTE] **Note**: On macOS this event is an alias of `move`.
> On macOS, this event is an alias of `move`.
#### Event: 'enter-full-screen' #### Event: 'enter-full-screen'
@@ -378,7 +367,6 @@ e.g. `APPCOMMAND_BROWSER_BACKWARD` is emitted as `browser-backward`.
```js ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()
win.on('app-command', (e, cmd) => { win.on('app-command', (e, cmd) => {
// Navigate the window back when the user hits their mouse back button // Navigate the window back when the user hits their mouse back button
@@ -433,12 +421,12 @@ Emitted when the window has closed a sheet.
Emitted when the native new tab button is clicked. Emitted when the native new tab button is clicked.
#### Event: 'system-context-menu' _Windows_ _Linux_ #### Event: 'system-context-menu' _Windows_
Returns: Returns:
* `event` Event * `event` Event
* `point` [Point](structures/point.md) - The screen coordinates where the context menu was triggered. * `point` [Point](structures/point.md) - The screen coordinates the context menu was triggered at
Emitted when the system context menu is triggered on the window, this is Emitted when the system context menu is triggered on the window, this is
normally only triggered when the user right clicks on the non-client area normally only triggered when the user right clicks on the non-client area
@@ -447,8 +435,6 @@ as `-webkit-app-region: drag` in a frameless window.
Calling `event.preventDefault()` will prevent the menu from being displayed. Calling `event.preventDefault()` will prevent the menu from being displayed.
To convert `point` to DIP, use [`screen.screenToDipPoint(point)`](./screen.md#screenscreentodippointpoint-windows-linux).
### Static Methods ### Static Methods
The `BrowserWindow` class has the following static methods: The `BrowserWindow` class has the following static methods:
@@ -472,7 +458,7 @@ or `null` if the contents are not owned by a window.
* `browserView` [BrowserView](browser-view.md) * `browserView` [BrowserView](browser-view.md)
> [!NOTE] > **Note**
> The `BrowserView` class is deprecated, and replaced by the new > The `BrowserView` class is deprecated, and replaced by the new
> [`WebContentsView`](web-contents-view.md) class. > [`WebContentsView`](web-contents-view.md) class.
@@ -511,7 +497,7 @@ A `Integer` property representing the unique ID of the window. Each ID is unique
A `string` (optional) property that is equal to the `tabbingIdentifier` passed to the `BrowserWindow` constructor or `undefined` if none was set. A `string` (optional) property that is equal to the `tabbingIdentifier` passed to the `BrowserWindow` constructor or `undefined` if none was set.
#### `win.autoHideMenuBar` _Linux_ _Windows_ #### `win.autoHideMenuBar`
A `boolean` property that determines whether the window menu bar should hide itself automatically. Once set, the menu bar will only show when users press the single `Alt` key. A `boolean` property that determines whether the window menu bar should hide itself automatically. Once set, the menu bar will only show when users press the single `Alt` key.
@@ -534,8 +520,7 @@ A `boolean` property that determines whether the window is focusable.
A `boolean` property that determines whether the window is visible on all workspaces. A `boolean` property that determines whether the window is visible on all workspaces.
> [!NOTE] **Note:** Always returns false on Windows.
> Always returns false on Windows.
#### `win.shadow` #### `win.shadow`
@@ -545,8 +530,7 @@ A `boolean` property that determines whether the window has a shadow.
A `boolean` property that determines whether the menu bar should be visible. A `boolean` property that determines whether the menu bar should be visible.
> [!NOTE] **Note:** If the menu bar is auto-hide, users can still bring up the menu bar by pressing the single `Alt` key.
> If the menu bar is auto-hide, users can still bring up the menu bar by pressing the single `Alt` key.
#### `win.kiosk` #### `win.kiosk`
@@ -567,8 +551,7 @@ and the icon of the file will show in window's title bar.
A `string` property that determines the title of the native window. A `string` property that determines the title of the native window.
> [!NOTE] **Note:** The title of the web page can be different from the title of the native window.
> The title of the web page can be different from the title of the native window.
#### `win.minimizable` _macOS_ _Windows_ #### `win.minimizable` _macOS_ _Windows_
@@ -628,17 +611,12 @@ A `string` property that defines an alternative title provided only to
accessibility tools such as screen readers. This string is not directly accessibility tools such as screen readers. This string is not directly
visible to users. visible to users.
#### `win.snapped` _Windows_ _Readonly_
A `boolean` property that indicates whether the window is arranged via [Snap.](https://support.microsoft.com/en-us/windows/snap-your-windows-885a9b1e-a983-a3b1-16cd-c531795e6241)
### Instance Methods ### Instance Methods
Objects created with `new BrowserWindow` have the following instance methods: Objects created with `new BrowserWindow` have the following instance methods:
> [!NOTE] **Note:** Some methods are only available on specific operating systems and are
> Some methods are only available on specific operating systems and are labeled as such.
> labeled as such.
#### `win.destroy()` #### `win.destroy()`
@@ -720,15 +698,13 @@ Returns `boolean` - Whether the window is minimized.
Sets whether the window should be in fullscreen mode. Sets whether the window should be in fullscreen mode.
> [!NOTE] **Note:** On macOS, fullscreen transitions take place asynchronously. If further actions depend on the fullscreen state, use the ['enter-full-screen'](browser-window.md#event-enter-full-screen) or ['leave-full-screen'](browser-window.md#event-leave-full-screen) events.
> On macOS, fullscreen transitions take place asynchronously. If further actions depend on the fullscreen state, use the ['enter-full-screen'](browser-window.md#event-enter-full-screen) or ['leave-full-screen'](browser-window.md#event-leave-full-screen) events.
#### `win.isFullScreen()` #### `win.isFullScreen()`
Returns `boolean` - Whether the window is in fullscreen mode. Returns `boolean` - Whether the window is in fullscreen mode.
> [!NOTE] **Note:** On macOS, fullscreen transitions take place asynchronously. When querying for a BrowserWindow's fullscreen status, you should ensure that either the ['enter-full-screen'](browser-window.md#event-enter-full-screen) or ['leave-full-screen'](browser-window.md#event-leave-full-screen) events have been emitted.
> On macOS, fullscreen transitions take place asynchronously. When querying for a BrowserWindow's fullscreen status, you should ensure that either the ['enter-full-screen'](browser-window.md#event-enter-full-screen) or ['leave-full-screen'](browser-window.md#event-leave-full-screen) events have been emitted.
#### `win.setSimpleFullScreen(flag)` _macOS_ #### `win.setSimpleFullScreen(flag)` _macOS_
@@ -826,7 +802,6 @@ Resizes and moves the window to the supplied bounds. Any properties that are not
```js ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()
// set all bounds properties // set all bounds properties
@@ -839,15 +814,13 @@ win.setBounds({ width: 100 })
console.log(win.getBounds()) console.log(win.getBounds())
``` ```
> [!NOTE] **Note:** On macOS, the y-coordinate value cannot be smaller than the [Tray](tray.md) height. The tray height has changed over time and depends on the operating system, but is between 20-40px. Passing a value lower than the tray height will result in a window that is flush to the tray.
> On macOS, the y-coordinate value cannot be smaller than the [Tray](tray.md) height. The tray height has changed over time and depends on the operating system, but is between 20-40px. Passing a value lower than the tray height will result in a window that is flush to the tray.
#### `win.getBounds()` #### `win.getBounds()`
Returns [`Rectangle`](structures/rectangle.md) - The `bounds` of the window as `Object`. Returns [`Rectangle`](structures/rectangle.md) - The `bounds` of the window as `Object`.
> [!NOTE] **Note:** On macOS, the y-coordinate value returned will be at minimum the [Tray](tray.md) height. For example, calling `win.setBounds({ x: 25, y: 20, width: 800, height: 600 })` with a tray height of 38 means that `win.getBounds()` will return `{ x: 25, y: 38, width: 800, height: 600 }`.
> On macOS, the y-coordinate value returned will be at minimum the [Tray](tray.md) height. For example, calling `win.setBounds({ x: 25, y: 20, width: 800, height: 600 })` with a tray height of 38 means that `win.getBounds()` will return `{ x: 25, y: 38, width: 800, height: 600 }`.
#### `win.getBackgroundColor()` #### `win.getBackgroundColor()`
@@ -855,8 +828,7 @@ Returns `string` - Gets the background color of the window in Hex (`#RRGGBB`) fo
See [Setting `backgroundColor`](#setting-the-backgroundcolor-property). See [Setting `backgroundColor`](#setting-the-backgroundcolor-property).
> [!NOTE] **Note:** The alpha value is _not_ returned alongside the red, green, and blue values.
> The alpha value is _not_ returned alongside the red, green, and blue values.
#### `win.setContentBounds(bounds[, animate])` #### `win.setContentBounds(bounds[, animate])`
@@ -874,8 +846,7 @@ Returns [`Rectangle`](structures/rectangle.md) - The `bounds` of the window's cl
Returns [`Rectangle`](structures/rectangle.md) - Contains the window bounds of the normal state Returns [`Rectangle`](structures/rectangle.md) - Contains the window bounds of the normal state
> [!NOTE] **Note:** whatever the current state of the window : maximized, minimized or in fullscreen, this function always returns the position and size of the window in normal state. In normal state, getBounds and getNormalBounds returns the same [`Rectangle`](structures/rectangle.md).
> Whatever the current state of the window (maximized, minimized or in fullscreen), this function always returns the position and size of the window in normal state. In normal state, `getBounds` and `getNormalBounds` return the same [`Rectangle`](structures/rectangle.md).
#### `win.setEnabled(enable)` #### `win.setEnabled(enable)`
@@ -1072,9 +1043,8 @@ Changes the title of native window to `title`.
Returns `string` - The title of the native window. Returns `string` - The title of the native window.
> [!NOTE] **Note:** The title of the web page can be different from the title of the native
> The title of the web page can be different from the title of the native window.
> window.
#### `win.setSheetOffset(offsetY[, offsetX])` _macOS_ #### `win.setSheetOffset(offsetY[, offsetX])` _macOS_
@@ -1087,7 +1057,6 @@ a HTML-rendered toolbar. For example:
```js ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()
const toolbarRect = document.getElementById('toolbar').getBoundingClientRect() const toolbarRect = document.getElementById('toolbar').getBoundingClientRect()
@@ -1240,10 +1209,9 @@ method:
```js ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()
const url = require('node:url').format({ const url = require('url').format({
protocol: 'file', protocol: 'file',
slashes: true, slashes: true,
pathname: require('node:path').join(__dirname, 'index.html') pathname: require('node:path').join(__dirname, 'index.html')
@@ -1257,7 +1225,6 @@ the following:
```js ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()
win.loadURL('http://localhost:8000/post', { win.loadURL('http://localhost:8000/post', {
@@ -1436,46 +1403,8 @@ in the taskbar.
Sets the properties for the window's taskbar button. Sets the properties for the window's taskbar button.
> [!NOTE] **Note:** `relaunchCommand` and `relaunchDisplayName` must always be set
> `relaunchCommand` and `relaunchDisplayName` must always be set together. If one of those properties is not set, then neither will be used.
> together. If one of those properties is not set, then neither will be used.
#### `win.setAccentColor(accentColor)` _Windows_
* `accentColor` boolean | string - The accent color for the window. By default, follows user preference in System Settings.
Sets the system accent color and highlighting of active window border.
The `accentColor` parameter accepts the following values:
* **Color string** - Sets a custom accent color using standard CSS color formats (Hex, RGB, RGBA, HSL, HSLA, or named colors). Alpha values in RGBA/HSLA formats are ignored and the color is treated as fully opaque.
* **`true`** - Uses the system's default accent color from user preferences in System Settings.
* **`false`** - Explicitly disables accent color highlighting for the window.
Examples:
```js
const win = new BrowserWindow({ frame: false })
// Set red accent color.
win.setAccentColor('#ff0000')
// RGB format (alpha ignored if present).
win.setAccentColor('rgba(255,0,0,0.5)')
// Use system accent color.
win.setAccentColor(true)
// Disable accent color.
win.setAccentColor(false)
```
#### `win.getAccentColor()` _Windows_
Returns `string | boolean` - the system accent color and highlighting of active window border in Hex RGB format.
If a color has been set for the window that differs from the system accent color, the window accent color will
be returned. Otherwise, a boolean will be returned, with `true` indicating that the window uses the global system accent color, and `false` indicating that accent color highlighting is disabled for this window.
#### `win.showDefinitionForSelection()` _macOS_ #### `win.showDefinitionForSelection()` _macOS_
@@ -1516,13 +1445,6 @@ Sets whether the menu bar should be visible. If the menu bar is auto-hide, users
Returns `boolean` - Whether the menu bar is visible. Returns `boolean` - Whether the menu bar is visible.
#### `win.isSnapped()` _Windows_
Returns `boolean` - whether the window is arranged via [Snap.](https://support.microsoft.com/en-us/windows/snap-your-windows-885a9b1e-a983-a3b1-16cd-c531795e6241)
The window is snapped via buttons shown when the mouse is hovered over window
maximize button, or by dragging it to the edges of the screen.
#### `win.setVisibleOnAllWorkspaces(visible[, options])` _macOS_ _Linux_ #### `win.setVisibleOnAllWorkspaces(visible[, options])` _macOS_ _Linux_
* `visible` boolean * `visible` boolean
@@ -1539,15 +1461,13 @@ maximize button, or by dragging it to the edges of the screen.
Sets whether the window should be visible on all workspaces. Sets whether the window should be visible on all workspaces.
> [!NOTE] **Note:** This API does nothing on Windows.
> This API does nothing on Windows.
#### `win.isVisibleOnAllWorkspaces()` _macOS_ _Linux_ #### `win.isVisibleOnAllWorkspaces()` _macOS_ _Linux_
Returns `boolean` - Whether the window is visible on all workspaces. Returns `boolean` - Whether the window is visible on all workspaces.
> [!NOTE] **Note:** This API always returns false on Windows.
> This API always returns false on Windows.
#### `win.setIgnoreMouseEvents(ignore[, options])` #### `win.setIgnoreMouseEvents(ignore[, options])`
@@ -1570,22 +1490,11 @@ events.
Prevents the window contents from being captured by other apps. Prevents the window contents from being captured by other apps.
On Windows, it calls [`SetWindowDisplayAffinity`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowdisplayaffinity) with `WDA_EXCLUDEFROMCAPTURE`. On macOS it sets the NSWindow's sharingType to NSWindowSharingNone.
On Windows it calls SetWindowDisplayAffinity with `WDA_EXCLUDEFROMCAPTURE`.
For Windows 10 version 2004 and up the window will be removed from capture entirely, For Windows 10 version 2004 and up the window will be removed from capture entirely,
older Windows versions behave as if `WDA_MONITOR` is applied capturing a black window. older Windows versions behave as if `WDA_MONITOR` is applied capturing a black window.
On macOS, it sets the `NSWindow`'s
[`sharingType`](https://developer.apple.com/documentation/appkit/nswindow/sharingtype-swift.property?language=objc)
to
[`NSWindowSharingNone`](https://developer.apple.com/documentation/appkit/nswindow/sharingtype-swift.enum/none?language=objc).
Unfortunately, due to an intentional change in macOS, newer Mac applications that use
`ScreenCaptureKit` will capture your window despite `win.setContentProtection(true)`.
See [here](https://github.com/electron/electron/issues/48258#issuecomment-3269893618).
#### `win.isContentProtected()` _macOS_ _Windows_
Returns `boolean` - whether or not content protection is currently enabled.
#### `win.setFocusable(focusable)` _macOS_ _Windows_ #### `win.setFocusable(focusable)` _macOS_ _Windows_
* `focusable` boolean * `focusable` boolean
@@ -1679,8 +1588,7 @@ This method sets the browser window's system-drawn background material, includin
See the [Windows documentation](https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwm_systembackdrop_type) for more details. See the [Windows documentation](https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwm_systembackdrop_type) for more details.
> [!NOTE] **Note:** This method is only supported on Windows 11 22H2 and up.
> This method is only supported on Windows 11 22H2 and up.
#### `win.setWindowButtonPosition(position)` _macOS_ #### `win.setWindowButtonPosition(position)` _macOS_
@@ -1702,9 +1610,8 @@ Sets the touchBar layout for the current window. Specifying `null` or
`undefined` clears the touch bar. This method only has an effect if the `undefined` clears the touch bar. This method only has an effect if the
machine has a touch bar. machine has a touch bar.
> [!NOTE] **Note:** The TouchBar API is currently experimental and may change or be
> The TouchBar API is currently experimental and may change or be removed in future Electron releases.
> removed in future Electron releases.
#### `win.setBrowserView(browserView)` _Experimental_ _Deprecated_ #### `win.setBrowserView(browserView)` _Experimental_ _Deprecated_
@@ -1712,7 +1619,7 @@ machine has a touch bar.
If there are other `BrowserView`s attached, they will be removed from If there are other `BrowserView`s attached, they will be removed from
this window. this window.
> [!WARNING] > **Note**
> The `BrowserView` class is deprecated, and replaced by the new > The `BrowserView` class is deprecated, and replaced by the new
> [`WebContentsView`](web-contents-view.md) class. > [`WebContentsView`](web-contents-view.md) class.
@@ -1721,7 +1628,7 @@ this window.
Returns `BrowserView | null` - The `BrowserView` attached to `win`. Returns `null` Returns `BrowserView | null` - The `BrowserView` attached to `win`. Returns `null`
if one is not attached. Throws an error if multiple `BrowserView`s are attached. if one is not attached. Throws an error if multiple `BrowserView`s are attached.
> [!WARNING] > **Note**
> The `BrowserView` class is deprecated, and replaced by the new > The `BrowserView` class is deprecated, and replaced by the new
> [`WebContentsView`](web-contents-view.md) class. > [`WebContentsView`](web-contents-view.md) class.
@@ -1731,7 +1638,7 @@ if one is not attached. Throws an error if multiple `BrowserView`s are attached.
Replacement API for setBrowserView supporting work with multi browser views. Replacement API for setBrowserView supporting work with multi browser views.
> [!WARNING] > **Note**
> The `BrowserView` class is deprecated, and replaced by the new > The `BrowserView` class is deprecated, and replaced by the new
> [`WebContentsView`](web-contents-view.md) class. > [`WebContentsView`](web-contents-view.md) class.
@@ -1739,7 +1646,7 @@ Replacement API for setBrowserView supporting work with multi browser views.
* `browserView` [BrowserView](browser-view.md) * `browserView` [BrowserView](browser-view.md)
> [!WARNING] > **Note**
> The `BrowserView` class is deprecated, and replaced by the new > The `BrowserView` class is deprecated, and replaced by the new
> [`WebContentsView`](web-contents-view.md) class. > [`WebContentsView`](web-contents-view.md) class.
@@ -1750,7 +1657,7 @@ Replacement API for setBrowserView supporting work with multi browser views.
Raises `browserView` above other `BrowserView`s attached to `win`. Raises `browserView` above other `BrowserView`s attached to `win`.
Throws an error if `browserView` is not attached to `win`. Throws an error if `browserView` is not attached to `win`.
> [!WARNING] > **Note**
> The `BrowserView` class is deprecated, and replaced by the new > The `BrowserView` class is deprecated, and replaced by the new
> [`WebContentsView`](web-contents-view.md) class. > [`WebContentsView`](web-contents-view.md) class.
@@ -1759,7 +1666,7 @@ Throws an error if `browserView` is not attached to `win`.
Returns `BrowserView[]` - a sorted by z-index array of all BrowserViews that have been attached Returns `BrowserView[]` - a sorted by z-index array of all BrowserViews that have been attached
with `addBrowserView` or `setBrowserView`. The top-most BrowserView is the last element of the array. with `addBrowserView` or `setBrowserView`. The top-most BrowserView is the last element of the array.
> [!WARNING] > **Note**
> The `BrowserView` class is deprecated, and replaced by the new > The `BrowserView` class is deprecated, and replaced by the new
> [`WebContentsView`](web-contents-view.md) class. > [`WebContentsView`](web-contents-view.md) class.

View File

@@ -60,10 +60,6 @@ following properties:
`strict-origin-when-cross-origin`. `strict-origin-when-cross-origin`.
* `cache` string (optional) - can be `default`, `no-store`, `reload`, * `cache` string (optional) - can be `default`, `no-store`, `reload`,
`no-cache`, `force-cache` or `only-if-cached`. `no-cache`, `force-cache` or `only-if-cached`.
* `priority` string (optional) - can be `throttled`, `idle`, `lowest`,
`low`, `medium`, or `highest`. Defaults to `idle`.
* `priorityIncremental` boolean (optional) - the incremental loading flag as part
of HTTP extensible priorities (RFC 9218). Default is `true`.
`options` properties such as `protocol`, `host`, `hostname`, `port` and `path` `options` properties such as `protocol`, `host`, `hostname`, `port` and `path`
strictly follow the Node.js model as described in the strictly follow the Node.js model as described in the

View File

@@ -4,12 +4,6 @@
Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process) (non-sandboxed only) Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process) (non-sandboxed only)
> [!IMPORTANT]
> If you want to call this API from a renderer process with context isolation enabled,
> place the API call in your preload script and
> [expose](../tutorial/context-isolation.md#after-context-isolation-enabled) it using the
> [`contextBridge`](context-bridge.md) API.
On Linux, there is also a `selection` clipboard. To manipulate it On Linux, there is also a `selection` clipboard. To manipulate it
you need to pass `selection` to each method: you need to pass `selection` to each method:
@@ -24,8 +18,7 @@ console.log(clipboard.readText('selection'))
The `clipboard` module has the following methods: The `clipboard` module has the following methods:
> [!NOTE] **Note:** Experimental APIs are marked as such and could be removed in future.
> Experimental APIs are marked as such and could be removed in future.
### `clipboard.readText([type])` ### `clipboard.readText([type])`
@@ -148,10 +141,9 @@ bookmark is unavailable. The `title` value will always be empty on Windows.
Writes the `title` (macOS only) and `url` into the clipboard as a bookmark. Writes the `title` (macOS only) and `url` into the clipboard as a bookmark.
> [!NOTE] **Note:** Most apps on Windows don't support pasting bookmarks into them so
> Most apps on Windows don't support pasting bookmarks into them so you can use `clipboard.write` to write both a bookmark and fallback text to the
> you can use `clipboard.write` to write both a bookmark and fallback text to the clipboard.
> clipboard.
```js ```js
const { clipboard } = require('electron') const { clipboard } = require('electron')

View File

@@ -8,7 +8,6 @@ is emitted:
```js ```js
const { app } = require('electron') const { app } = require('electron')
app.commandLine.appendSwitch('remote-debugging-port', '8315') app.commandLine.appendSwitch('remote-debugging-port', '8315')
app.commandLine.appendSwitch('host-rules', 'MAP * 127.0.0.1') app.commandLine.appendSwitch('host-rules', 'MAP * 127.0.0.1')
@@ -74,8 +73,7 @@ Passing `--enable-logging=file` will result in logs being saved to the file
specified by `--log-file=...`, or to `electron_debug.log` in the user-data specified by `--log-file=...`, or to `electron_debug.log` in the user-data
directory if `--log-file` is not specified. directory if `--log-file` is not specified.
> [!NOTE] > **Note:** On Windows, logs from child processes cannot be sent to stderr.
> On Windows, logs from child processes cannot be sent to stderr.
> Logging to a file is the most reliable way to collect logs on Windows. > Logging to a file is the most reliable way to collect logs on Windows.
See also `--log-file`, `--log-level`, `--v`, and `--vmodule`. See also `--log-file`, `--log-level`, `--v`, and `--vmodule`.
@@ -86,7 +84,7 @@ Field trials to be forcefully enabled or disabled.
For example: `WebRTC-Audio-Red-For-Opus/Enabled/` For example: `WebRTC-Audio-Red-For-Opus/Enabled/`
### --host-rules=`rules` _Deprecated_ ### --host-rules=`rules`
A comma-separated list of `rules` that control how hostnames are mapped. A comma-separated list of `rules` that control how hostnames are mapped.
@@ -104,23 +102,9 @@ These mappings apply to the endpoint host in a net request (the TCP connect
and host resolver in a direct connection, and the `CONNECT` in an HTTP proxy and host resolver in a direct connection, and the `CONNECT` in an HTTP proxy
connection, and the endpoint host in a `SOCKS` proxy connection). connection, and the endpoint host in a `SOCKS` proxy connection).
**Deprecated:** Use the `--host-resolver-rules` switch instead.
### --host-resolver-rules=`rules` ### --host-resolver-rules=`rules`
A comma-separated list of `rules` that control how hostnames are mapped. Like `--host-rules` but these `rules` only apply to the host resolver.
For example:
* `MAP * 127.0.0.1` Forces all hostnames to be mapped to 127.0.0.1
* `MAP *.google.com proxy` Forces all google.com subdomains to be resolved to
"proxy".
* `MAP test.com [::1]:77` Forces "test.com" to resolve to IPv6 loopback. Will
also force the port of the resulting socket address to be 77.
* `MAP * baz, EXCLUDE www.google.com` Remaps everything to "baz", except for
"www.google.com".
These `rules` only apply to the host resolver.
### --ignore-certificate-errors ### --ignore-certificate-errors
@@ -193,11 +177,6 @@ Disables the Chromium [sandbox](https://www.chromium.org/developers/design-docum
Forces renderer process and Chromium helper processes to run un-sandboxed. Forces renderer process and Chromium helper processes to run un-sandboxed.
Should only be used for testing. Should only be used for testing.
### --no-stdio-init
Disable stdio initialization during node initialization.
Used to avoid node initialization crash when the nul device is disabled on Windows platform.
### --proxy-bypass-list=`hosts` ### --proxy-bypass-list=`hosts`
Instructs Electron to bypass the proxy server for the given semi-colon-separated Instructs Electron to bypass the proxy server for the given semi-colon-separated
@@ -208,7 +187,6 @@ For example:
```js ```js
const { app } = require('electron') const { app } = require('electron')
app.commandLine.appendSwitch('proxy-bypass-list', '<local>;*.google.com;*foo.com;1.2.3.4:5678') app.commandLine.appendSwitch('proxy-bypass-list', '<local>;*.google.com;*foo.com;1.2.3.4:5678')
``` ```
@@ -274,10 +252,9 @@ the required version is unavailable. Current default is set to `3`.
Electron supports some of the [CLI flags][node-cli] supported by Node.js. Electron supports some of the [CLI flags][node-cli] supported by Node.js.
> [!NOTE] **Note:** Passing unsupported command line switches to Electron when it is not running in `ELECTRON_RUN_AS_NODE` will have no effect.
> Passing unsupported command line switches to Electron when it is not running in `ELECTRON_RUN_AS_NODE` will have no effect.
### `--inspect-brk[=[host:]port]` ### `--inspect-brk\[=\[host:]port]`
Activate inspector on host:port and break at start of user script. Default host:port is 127.0.0.1:9229. Activate inspector on host:port and break at start of user script. Default host:port is 127.0.0.1:9229.
@@ -289,13 +266,13 @@ Activate inspector on `host:port` and break at start of the first internal
JavaScript script executed when the inspector is available. JavaScript script executed when the inspector is available.
Default `host:port` is `127.0.0.1:9229`. Default `host:port` is `127.0.0.1:9229`.
### `--inspect-port=[host:]port` ### `--inspect-port=\[host:]port`
Set the `host:port` to be used when the inspector is activated. Useful when activating the inspector by sending the SIGUSR1 signal. Default host is `127.0.0.1`. Set the `host:port` to be used when the inspector is activated. Useful when activating the inspector by sending the SIGUSR1 signal. Default host is `127.0.0.1`.
Aliased to `--debug-port=[host:]port`. Aliased to `--debug-port=[host:]port`.
### `--inspect[=[host:]port]` ### `--inspect\[=\[host:]port]`
Activate inspector on `host:port`. Default is `127.0.0.1:9229`. Activate inspector on `host:port`. Default is `127.0.0.1:9229`.
@@ -311,10 +288,6 @@ Specify ways of the inspector web socket url exposure.
By default inspector websocket url is available in stderr and under /json/list endpoint on `http://host:port/json/list`. By default inspector websocket url is available in stderr and under /json/list endpoint on `http://host:port/json/list`.
### `--experimental-network-inspection`
Enable support for devtools network inspector events, for visibility into requests made by the nodejs `http` and `https` modules.
### `--no-deprecation` ### `--no-deprecation`
Silence deprecation warnings. Silence deprecation warnings.
@@ -346,26 +319,6 @@ Set the directory to which all Node.js diagnostic output files are written. Defa
Affects the default output directory of [v8.setHeapSnapshotNearHeapLimit](https://nodejs.org/docs/latest/api/v8.html#v8setheapsnapshotnearheaplimitlimit). Affects the default output directory of [v8.setHeapSnapshotNearHeapLimit](https://nodejs.org/docs/latest/api/v8.html#v8setheapsnapshotnearheaplimitlimit).
### `--no-experimental-global-navigator`
Disable exposition of [Navigator API][] on the global scope from Node.js.
## Chromium Flags
There isn't a documented list of all Chromium switches, but there are a few ways to find them.
The easiest way is through Chromium's flags page, which you can access at `about://flags`. These flags don't directly match switch names, but they show up in the process's command-line arguments.
To see these arguments, enable a flag in `about://flags`, then go to `about://version` in Chromium. You'll find a list of command-line arguments, including `--flag-switches-begin --your --list --flag-switches-end`, which contains the list of your flag enabled switches.
Most flags are included as part of `--enable-features=`, but some are standalone switches, like `--enable-experimental-web-platform-features`.
A complete list of flags exists in [Chromium's flag metadata page](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/flag-metadata.json), but this list includes platform, environment and GPU specific, expired and potentially non-functional flags, so many of them might not always work in every situation.
Keep in mind that standalone switches can sometimes be split into individual features, so there's no fully complete list of switches.
Finally, you'll need to ensure that the version of Chromium in Electron matches the version of the browser you're using to cross-reference the switches.
[app]: app.md [app]: app.md
[append-switch]: command-line.md#commandlineappendswitchswitch-value [append-switch]: command-line.md#commandlineappendswitchswitch-value
[debugging-main-process]: ../tutorial/debugging-main-process.md [debugging-main-process]: ../tutorial/debugging-main-process.md
@@ -374,4 +327,3 @@ Finally, you'll need to ensure that the version of Chromium in Electron matches
[play-silent-audio]: https://github.com/atom/atom/pull/9485/files [play-silent-audio]: https://github.com/atom/atom/pull/9485/files
[ready]: app.md#event-ready [ready]: app.md#event-ready
[severities]: https://source.chromium.org/chromium/chromium/src/+/main:base/logging.h?q=logging::LogSeverity&ss=chromium [severities]: https://source.chromium.org/chromium/chromium/src/+/main:base/logging.h?q=logging::LogSeverity&ss=chromium
[Navigator API]: https://github.com/nodejs/node/blob/main/doc/api/globals.md#navigator

View File

@@ -9,7 +9,6 @@ The following example shows how to check if the `--disable-gpu` flag is set.
```js ```js
const { app } = require('electron') const { app } = require('electron')
app.commandLine.hasSwitch('disable-gpu') app.commandLine.hasSwitch('disable-gpu')
``` ```
@@ -21,91 +20,45 @@ document.
#### `commandLine.appendSwitch(switch[, value])` #### `commandLine.appendSwitch(switch[, value])`
* `switch` string - A command-line switch, without the leading `--`. * `switch` string - A command-line switch, without the leading `--`
* `value` string (optional) - A value for the given switch. * `value` string (optional) - A value for the given switch
Append a switch (with optional `value`) to Chromium's command line. Append a switch (with optional `value`) to Chromium's command line.
> [!NOTE] **Note:** This will not affect `process.argv`. The intended usage of this function is to
> This will not affect `process.argv`. The intended usage of this function is to control Chromium's behavior.
> control Chromium's behavior.
```js
const { app } = require('electron')
app.commandLine.appendSwitch('remote-debugging-port', '8315')
```
#### `commandLine.appendArgument(value)` #### `commandLine.appendArgument(value)`
* `value` string - The argument to append to the command line. * `value` string - The argument to append to the command line
Append an argument to Chromium's command line. The argument will be quoted Append an argument to Chromium's command line. The argument will be quoted
correctly. Switches will precede arguments regardless of appending order. correctly. Switches will precede arguments regardless of appending order.
If you're appending an argument like `--switch=value`, consider using `appendSwitch('switch', 'value')` instead. If you're appending an argument like `--switch=value`, consider using `appendSwitch('switch', 'value')` instead.
```js **Note:** This will not affect `process.argv`. The intended usage of this function is to
const { app } = require('electron') control Chromium's behavior.
app.commandLine.appendArgument('--enable-experimental-web-platform-features')
```
> [!NOTE]
> This will not affect `process.argv`. The intended usage of this function is to
> control Chromium's behavior.
#### `commandLine.hasSwitch(switch)` #### `commandLine.hasSwitch(switch)`
* `switch` string - A command-line switch. * `switch` string - A command-line switch
Returns `boolean` - Whether the command-line switch is present. Returns `boolean` - Whether the command-line switch is present.
```js
const { app } = require('electron')
app.commandLine.appendSwitch('remote-debugging-port', '8315')
const hasPort = app.commandLine.hasSwitch('remote-debugging-port')
console.log(hasPort) // true
```
#### `commandLine.getSwitchValue(switch)` #### `commandLine.getSwitchValue(switch)`
* `switch` string - A command-line switch. * `switch` string - A command-line switch
Returns `string` - The command-line switch value. Returns `string` - The command-line switch value.
This function is meant to obtain Chromium command line switches. It is not **Note:** When the switch is not present or has no value, it returns empty string.
meant to be used for application-specific command line arguments. For the
latter, please use `process.argv`.
```js
const { app } = require('electron')
app.commandLine.appendSwitch('remote-debugging-port', '8315')
const portValue = app.commandLine.getSwitchValue('remote-debugging-port')
console.log(portValue) // '8315'
```
> [!NOTE]
> When the switch is not present or has no value, it returns empty string.
#### `commandLine.removeSwitch(switch)` #### `commandLine.removeSwitch(switch)`
* `switch` string - A command-line switch. * `switch` string - A command-line switch
Removes the specified switch from Chromium's command line. Removes the specified switch from Chromium's command line.
```js **Note:** This will not affect `process.argv`. The intended usage of this function is to
const { app } = require('electron') control Chromium's behavior.
app.commandLine.appendSwitch('remote-debugging-port', '8315')
console.log(app.commandLine.hasSwitch('remote-debugging-port')) // true
app.commandLine.removeSwitch('remote-debugging-port')
console.log(app.commandLine.hasSwitch('remote-debugging-port')) // false
```
> [!NOTE]
> This will not affect `process.argv`. The intended usage of this function is to
> control Chromium's behavior.

View File

@@ -7,9 +7,8 @@ Process: [Main](../glossary.md#main-process)
This module does not include a web interface. To view recorded traces, use This module does not include a web interface. To view recorded traces, use
[trace viewer][], available at `chrome://tracing` in Chrome. [trace viewer][], available at `chrome://tracing` in Chrome.
> [!NOTE] **Note:** You should not use this module until the `ready` event of the app
> You should not use this module until the `ready` event of the app module is emitted.
> module is emitted.
```js ```js
const { app, contentTracing } = require('electron') const { app, contentTracing } = require('electron')

View File

@@ -157,7 +157,6 @@ has been included below for completeness:
| [Cloneable Types](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) | Simple | ✅ | ✅ | See the linked document on cloneable types | | [Cloneable Types](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) | Simple | ✅ | ✅ | See the linked document on cloneable types |
| `Element` | Complex | ✅ | ✅ | Prototype modifications are dropped. Sending custom elements will not work. | | `Element` | Complex | ✅ | ✅ | Prototype modifications are dropped. Sending custom elements will not work. |
| `Blob` | Complex | ✅ | ✅ | N/A | | `Blob` | Complex | ✅ | ✅ | N/A |
| `VideoFrame` | Complex | ✅ | ✅ | N/A |
| `Symbol` | N/A | ❌ | ❌ | Symbols cannot be copied across contexts so they are dropped | | `Symbol` | N/A | ❌ | ❌ | Symbols cannot be copied across contexts so they are dropped |
If the type you care about is not in the above table, it is probably not supported. If the type you care about is not in the above table, it is probably not supported.
@@ -190,9 +189,7 @@ Be very cautious about which globals and APIs you expose to untrusted remote con
```js ```js
const { contextBridge } = require('electron') const { contextBridge } = require('electron')
const crypto = require('node:crypto') const crypto = require('node:crypto')
contextBridge.exposeInMainWorld('nodeCrypto', { contextBridge.exposeInMainWorld('nodeCrypto', {
sha256sum (data) { sha256sum (data) {
const hash = crypto.createHash('sha256') const hash = crypto.createHash('sha256')

View File

@@ -1,76 +0,0 @@
## CSS Rule: `-electron-corner-smoothing`
> Smoothes out the corner rounding of the `border-radius` CSS rule.
The rounded corners of elements with [the `border-radius` CSS rule](https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius) can be smoothed out using the `-electron-corner-smoothing` CSS rule. This smoothness is very similar to Apple's "continuous" rounded corners in SwiftUI and Figma's "corner smoothing" control on design elements.
![There is a black rectangle on the left using simple rounded corners, and a blue rectangle on the right using smooth rounded corners. In between those rectangles is a magnified view of the same corner from both rectangles overlapping to show the subtle difference in shape.](../images/corner-smoothing-summary.svg)
Integrating with the operating system and its design language is important to many desktop applications. The shape of a rounded corner can be a subtle detail to many users. However, aligning closely to the system's design language that users are familiar with makes the application's design feel familiar too. Beyond matching the design language of macOS, designers may decide to use smoother round corners for many other reasons.
`-electron-corner-smoothing` affects the shape of borders, outlines, and shadows on the target element. Mirroring the behavior of `border-radius`, smoothing will gradually back off if an element's size is too small for the chosen value.
The `-electron-corner-smoothing` CSS rule is **only implemented for Electron** and has no effect in browsers. Avoid using this rule outside of Electron. This CSS rule is considered experimental and may require migration in the future if replaced by a CSS standard.
### Example
The following example shows the effect of corner smoothing at different percents.
```css
.box {
width: 128px;
height: 128px;
background-color: cornflowerblue;
border-radius: 24px;
-electron-corner-smoothing: var(--percent); /* Column header in table below. */
}
```
| 0% | 30% | 60% | 100% |
| --- | --- | --- | --- |
| ![A rectangle with round corners at 0% smoothness](../images/corner-smoothing-example-0.svg) | ![A rectangle with round corners at 30% smoothness](../images/corner-smoothing-example-30.svg) | ![A rectangle with round corners at 60% smoothness](../images/corner-smoothing-example-60.svg) | ![A rectangle with round corners at 100% smoothness](../images/corner-smoothing-example-100.svg) |
### Matching the system UI
Use the `system-ui` keyword to match the smoothness to the OS design language.
```css
.box {
width: 128px;
height: 128px;
background-color: cornflowerblue;
border-radius: 24px;
-electron-corner-smoothing: system-ui; /* Match the system UI design. */
}
```
| OS: | macOS | Windows, Linux |
| --- | --- | --- |
| Value: | `60%` | `0%` |
| Example: | ![A rectangle with round corners whose smoothness matches macOS](../images/corner-smoothing-example-60.svg) | ![A rectangle with round corners whose smoothness matches Windows and Linux](../images/corner-smoothing-example-0.svg) |
### Controlling availibility
This CSS rule can be disabled using the Blink feature flag `ElectronCSSCornerSmoothing`.
```js
const myWindow = new BrowserWindow({
// [...]
webPreferences: {
disableBlinkFeatures: 'ElectronCSSCornerSmoothing' // Disables the `-electron-corner-smoothing` CSS rule
}
})
```
### Formal reference
* **Initial value**: `0%`
* **Inherited**: No
* **Animatable**: No
* **Computed value**: As specified
```css
-electron-corner-smoothing =
<percentage [0,100]> |
system-ui
```

View File

@@ -4,12 +4,6 @@
Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process) Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process)
> [!IMPORTANT]
> If you want to call this API from a renderer process with context isolation enabled,
> place the API call in your preload script and
> [expose](../tutorial/context-isolation.md#after-context-isolation-enabled) it using the
> [`contextBridge`](context-bridge.md) API.
The following is an example of setting up Electron to automatically submit The following is an example of setting up Electron to automatically submit
crash reports to a remote server: crash reports to a remote server:
@@ -25,8 +19,7 @@ following projects:
* [socorro](https://github.com/mozilla-services/socorro) * [socorro](https://github.com/mozilla-services/socorro)
* [mini-breakpad-server](https://github.com/electron/mini-breakpad-server) * [mini-breakpad-server](https://github.com/electron/mini-breakpad-server)
> [!NOTE] > **Note:** Electron uses Crashpad, not Breakpad, to collect and upload
> Electron uses Crashpad, not Breakpad, to collect and upload
> crashes, but for the time being, the [upload protocol is the same](https://chromium.googlesource.com/crashpad/crashpad/+/HEAD/doc/overview_design.md#Upload-to-collection-server). > crashes, but for the time being, the [upload protocol is the same](https://chromium.googlesource.com/crashpad/crashpad/+/HEAD/doc/overview_design.md#Upload-to-collection-server).
Or use a 3rd party hosted solution: Or use a 3rd party hosted solution:
@@ -69,7 +62,7 @@ The `crashReporter` module has the following methods:
* `extra` Record\<string, string\> (optional) - Extra string key/value * `extra` Record\<string, string\> (optional) - Extra string key/value
annotations that will be sent along with crash reports that are generated annotations that will be sent along with crash reports that are generated
in the main process. Only string values are supported. Crashes generated in in the main process. Only string values are supported. Crashes generated in
child processes will not include these extra parameters. To add extra child processes will not contain these extra
parameters to crash reports generated from child processes, call parameters to crash reports generated from child processes, call
[`addExtraParameter`](#crashreporteraddextraparameterkey-value) from the [`addExtraParameter`](#crashreporteraddextraparameterkey-value) from the
child process. child process.
@@ -91,23 +84,19 @@ before `app.on('ready')`. If the crash reporter is not initialized at the time
a renderer process is created, then that renderer process will not be monitored a renderer process is created, then that renderer process will not be monitored
by the crash reporter. by the crash reporter.
> [!NOTE] **Note:** You can test out the crash reporter by generating a crash using
> You can test out the crash reporter by generating a crash using `process.crash()`.
> `process.crash()`.
> [!NOTE] **Note:** If you need to send additional/updated `extra` parameters after your
> If you need to send additional/updated `extra` parameters after your first call `start` you can call `addExtraParameter`.
> first call `start` you can call `addExtraParameter`.
> [!NOTE] **Note:** Parameters passed in `extra`, `globalExtra` or set with
> Parameters passed in `extra`, `globalExtra` or set with `addExtraParameter` have limits on the length of the keys and values. Key names
> `addExtraParameter` have limits on the length of the keys and values. Key names must be at most 39 bytes long, and values must be no longer than 127 bytes.
> must be at most 39 bytes long, and values must be no longer than 127 bytes. Keys with names longer than the maximum will be silently ignored. Key values
> Keys with names longer than the maximum will be silently ignored. Key values longer than the maximum length will be truncated.
> longer than the maximum length will be truncated.
> [!NOTE] **Note:** This method is only available in the main process.
> This method is only available in the main process.
### `crashReporter.getLastCrashReport()` ### `crashReporter.getLastCrashReport()`
@@ -116,8 +105,7 @@ last crash report. Only crash reports that have been uploaded will be returned;
even if a crash report is present on disk it will not be returned until it is even if a crash report is present on disk it will not be returned until it is
uploaded. In the case that there are no uploaded reports, `null` is returned. uploaded. In the case that there are no uploaded reports, `null` is returned.
> [!NOTE] **Note:** This method is only available in the main process.
> This method is only available in the main process.
### `crashReporter.getUploadedReports()` ### `crashReporter.getUploadedReports()`
@@ -126,16 +114,14 @@ Returns [`CrashReport[]`](structures/crash-report.md):
Returns all uploaded crash reports. Each report contains the date and uploaded Returns all uploaded crash reports. Each report contains the date and uploaded
ID. ID.
> [!NOTE] **Note:** This method is only available in the main process.
> This method is only available in the main process.
### `crashReporter.getUploadToServer()` ### `crashReporter.getUploadToServer()`
Returns `boolean` - Whether reports should be submitted to the server. Set through Returns `boolean` - Whether reports should be submitted to the server. Set through
the `start` method or `setUploadToServer`. the `start` method or `setUploadToServer`.
> [!NOTE] **Note:** This method is only available in the main process.
> This method is only available in the main process.
### `crashReporter.setUploadToServer(uploadToServer)` ### `crashReporter.setUploadToServer(uploadToServer)`
@@ -144,8 +130,7 @@ the `start` method or `setUploadToServer`.
This would normally be controlled by user preferences. This has no effect if This would normally be controlled by user preferences. This has no effect if
called before `start` is called. called before `start` is called.
> [!NOTE] **Note:** This method is only available in the main process.
> This method is only available in the main process.
### `crashReporter.addExtraParameter(key, value)` ### `crashReporter.addExtraParameter(key, value)`
@@ -163,11 +148,10 @@ with crashes from renderer or other child processes. Similarly, adding extra
parameters in a renderer process will not result in those parameters being sent parameters in a renderer process will not result in those parameters being sent
with crashes that occur in other renderer processes or in the main process. with crashes that occur in other renderer processes or in the main process.
> [!NOTE] **Note:** Parameters have limits on the length of the keys and values. Key
> Parameters have limits on the length of the keys and values. Key names must be no longer than 39 bytes, and values must be no longer than 20320
> names must be no longer than 39 bytes, and values must be no longer than 20320 bytes. Keys with names longer than the maximum will be silently ignored. Key
> bytes. Keys with names longer than the maximum will be silently ignored. Key values longer than the maximum length will be truncated.
> values longer than the maximum length will be truncated.
### `crashReporter.removeExtraParameter(key)` ### `crashReporter.removeExtraParameter(key)`

View File

@@ -10,7 +10,6 @@ runtime that allows interacting with pages and instrumenting them.
```js ```js
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()
try { try {

View File

@@ -70,9 +70,8 @@ stopButton.addEventListener('click', () => {
See [`navigator.mediaDevices.getDisplayMedia`](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia) for more information. See [`navigator.mediaDevices.getDisplayMedia`](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia) for more information.
> [!NOTE] **Note:** `navigator.mediaDevices.getDisplayMedia` does not permit the use of `deviceId` for
> `navigator.mediaDevices.getDisplayMedia` does not permit the use of `deviceId` for selection of a source - see [specification](https://w3c.github.io/mediacapture-screen-share/#constraints).
> selection of a source - see [specification](https://w3c.github.io/mediacapture-screen-share/#constraints).
## Methods ## Methods
@@ -93,9 +92,8 @@ The `desktopCapturer` module has the following methods:
Returns `Promise<DesktopCapturerSource[]>` - Resolves with an array of [`DesktopCapturerSource`](structures/desktop-capturer-source.md) objects, each `DesktopCapturerSource` represents a screen or an individual window that can be captured. Returns `Promise<DesktopCapturerSource[]>` - Resolves with an array of [`DesktopCapturerSource`](structures/desktop-capturer-source.md) objects, each `DesktopCapturerSource` represents a screen or an individual window that can be captured.
> [!NOTE] **Note** Capturing the screen contents requires user consent on macOS 10.15 Catalina or higher,
> Capturing the screen contents requires user consent on macOS 10.15 Catalina or higher, which can detected by [`systemPreferences.getMediaAccessStatus`][].
> which can detected by [`systemPreferences.getMediaAccessStatus`][].
[`navigator.mediaDevices.getUserMedia`]: https://developer.mozilla.org/en/docs/Web/API/MediaDevices/getUserMedia [`navigator.mediaDevices.getUserMedia`]: https://developer.mozilla.org/en/docs/Web/API/MediaDevices/getUserMedia
[`systemPreferences.getMediaAccessStatus`]: system-preferences.md#systempreferencesgetmediaaccessstatusmediatype-windows-macos [`systemPreferences.getMediaAccessStatus`]: system-preferences.md#systempreferencesgetmediaaccessstatusmediatype-windows-macos

View File

@@ -8,7 +8,6 @@ An example of showing a dialog to select multiple files:
```js ```js
const { dialog } = require('electron') const { dialog } = require('electron')
console.log(dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'] })) console.log(dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'] }))
``` ```
@@ -53,8 +52,6 @@ The `window` argument allows the dialog to attach itself to a parent window, mak
The `filters` specifies an array of file types that can be displayed or The `filters` specifies an array of file types that can be displayed or
selected when you want to limit the user to a specific type. For example: selected when you want to limit the user to a specific type. For example:
<!-- eslint-skip -->
```js ```js
{ {
filters: [ filters: [
@@ -70,11 +67,10 @@ The `extensions` array should contain extensions without wildcards or dots (e.g.
`'png'` is good but `'.png'` and `'*.png'` are bad). To show all files, use the `'png'` is good but `'.png'` and `'*.png'` are bad). To show all files, use the
`'*'` wildcard (no other wildcard is supported). `'*'` wildcard (no other wildcard is supported).
> [!NOTE] **Note:** On Windows and Linux an open dialog can not be both a file selector
> On Windows and Linux an open dialog can not be both a file selector and a directory selector, so if you set `properties` to
> and a directory selector, so if you set `properties` to `['openFile', 'openDirectory']` on these platforms, a directory selector will be
> `['openFile', 'openDirectory']` on these platforms, a directory selector will be shown.
> shown.
```js @ts-type={mainWindow:Electron.BaseWindow} ```js @ts-type={mainWindow:Electron.BaseWindow}
dialog.showOpenDialogSync(mainWindow, { dialog.showOpenDialogSync(mainWindow, {
@@ -82,11 +78,10 @@ dialog.showOpenDialogSync(mainWindow, {
}) })
``` ```
> [!NOTE] **Note:** On Linux `defaultPath` is not supported when using portal file chooser
> 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`
> 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)
> [command-line switch](./command-line-switches.md#--xdg-portal-required-versionversion) to force gtk or kde dialogs.
> to force gtk or kde dialogs.
### `dialog.showOpenDialog([window, ]options)` ### `dialog.showOpenDialog([window, ]options)`
@@ -129,8 +124,6 @@ The `window` argument allows the dialog to attach itself to a parent window, mak
The `filters` specifies an array of file types that can be displayed or The `filters` specifies an array of file types that can be displayed or
selected when you want to limit the user to a specific type. For example: selected when you want to limit the user to a specific type. For example:
<!-- eslint-skip -->
```js ```js
{ {
filters: [ filters: [
@@ -146,11 +139,10 @@ The `extensions` array should contain extensions without wildcards or dots (e.g.
`'png'` is good but `'.png'` and `'*.png'` are bad). To show all files, use the `'png'` is good but `'.png'` and `'*.png'` are bad). To show all files, use the
`'*'` wildcard (no other wildcard is supported). `'*'` wildcard (no other wildcard is supported).
> [!NOTE] **Note:** On Windows and Linux an open dialog can not be both a file selector
> On Windows and Linux an open dialog can not be both a file selector and a directory selector, so if you set `properties` to
> and a directory selector, so if you set `properties` to `['openFile', 'openDirectory']` on these platforms, a directory selector will be
> `['openFile', 'openDirectory']` on these platforms, a directory selector will be shown.
> shown.
```js @ts-type={mainWindow:Electron.BaseWindow} ```js @ts-type={mainWindow:Electron.BaseWindow}
dialog.showOpenDialog(mainWindow, { dialog.showOpenDialog(mainWindow, {
@@ -163,11 +155,10 @@ dialog.showOpenDialog(mainWindow, {
}) })
``` ```
> [!NOTE] **Note:** On Linux `defaultPath` is not supported when using portal file chooser
> 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`
> 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)
> [command-line switch](./command-line-switches.md#--xdg-portal-required-versionversion) to force gtk or kde dialogs.
> to force gtk or kde dialogs.
### `dialog.showSaveDialogSync([window, ]options)` ### `dialog.showSaveDialogSync([window, ]options)`
@@ -234,9 +225,8 @@ The `window` argument allows the dialog to attach itself to a parent window, mak
The `filters` specifies an array of file types that can be displayed, see The `filters` specifies an array of file types that can be displayed, see
`dialog.showOpenDialog` for an example. `dialog.showOpenDialog` for an example.
> [!NOTE] **Note:** On macOS, using the asynchronous version is recommended to avoid issues when
> On macOS, using the asynchronous version is recommended to avoid issues when expanding and collapsing the dialog.
> expanding and collapsing the dialog.
### `dialog.showMessageBoxSync([window, ]options)` ### `dialog.showMessageBoxSync([window, ]options)`

View File

@@ -5,8 +5,12 @@
Process: [Main](../glossary.md#main-process)<br /> Process: [Main](../glossary.md#main-process)<br />
_This class is not exported from the `'electron'` module. It is only available as a return value of other methods in the Electron API._ _This class is not exported from the `'electron'` module. It is only available as a return value of other methods in the Electron API._
> [!TIP] The following example shows how to bounce your icon on the dock.
> See also: [A detailed guide about how to implement Dock menus](../tutorial/macos-dock.md).
```js
const { app } = require('electron')
app.dock.bounce()
```
### Instance Methods ### Instance Methods
@@ -24,8 +28,7 @@ When `informational` is passed, the dock icon will bounce for one second.
However, the request remains active until either the application becomes active However, the request remains active until either the application becomes active
or the request is canceled. or the request is canceled.
> [!NOTE] **Note:** This method can only be used while the app is not focused; when the app is focused it will return -1.
> This method can only be used while the app is not focused; when the app is focused it will return -1.
#### `dock.cancelBounce(id)` _macOS_ #### `dock.cancelBounce(id)` _macOS_
@@ -45,9 +48,6 @@ Bounces the Downloads stack if the filePath is inside the Downloads folder.
Sets the string to be displayed in the docks badging area. Sets the string to be displayed in the docks badging area.
> [!IMPORTANT]
> You need to ensure that your application has the permission to display notifications for this method to work.
#### `dock.getBadge()` _macOS_ #### `dock.getBadge()` _macOS_
Returns `string` - The badge string of the dock. Returns `string` - The badge string of the dock.

View File

@@ -12,7 +12,6 @@ control the download item.
```js ```js
// In the main process. // In the main process.
const { BrowserWindow } = require('electron') const { BrowserWindow } = require('electron')
const win = new BrowserWindow() const win = new BrowserWindow()
win.webContents.session.on('will-download', (event, item, webContents) => { win.webContents.session.on('will-download', (event, item, webContents) => {
// Set the save path, making Electron not to prompt a save dialog. // Set the save path, making Electron not to prompt a save dialog.
@@ -116,8 +115,7 @@ Returns `boolean` - Whether the download is paused.
Resumes the download that has been paused. Resumes the download that has been paused.
> [!NOTE] **Note:** To enable resumable downloads the server you are downloading from must support range requests and provide both `Last-Modified` and `ETag` header values. Otherwise `resume()` will dismiss previously received bytes and restart the download from the beginning.
> To enable resumable downloads the server you are downloading from must support range requests and provide both `Last-Modified` and `ETag` header values. Otherwise `resume()` will dismiss previously received bytes and restart the download from the beginning.
#### `downloadItem.canResume()` #### `downloadItem.canResume()`
@@ -143,10 +141,9 @@ Returns `boolean` - Whether the download has user gesture.
Returns `string` - The file name of the download item. Returns `string` - The file name of the download item.
> [!NOTE] **Note:** The file name is not always the same as the actual one saved in local
> The file name is not always the same as the actual one saved in local disk. If user changes the file name in a prompted download saving dialog, the
> disk. If user changes the file name in a prompted download saving dialog, the actual name of saved file will be different.
> actual name of saved file will be different.
#### `downloadItem.getCurrentBytesPerSecond()` #### `downloadItem.getCurrentBytesPerSecond()`
@@ -175,9 +172,8 @@ header.
Returns `string` - The current state. Can be `progressing`, `completed`, `cancelled` or `interrupted`. Returns `string` - The current state. Can be `progressing`, `completed`, `cancelled` or `interrupted`.
> [!NOTE] **Note:** The following methods are useful specifically to resume a
> The following methods are useful specifically to resume a `cancelled` item when session is restarted.
> `cancelled` item when session is restarted.
#### `downloadItem.getURLChain()` #### `downloadItem.getURLChain()`

View File

@@ -104,7 +104,7 @@ you would when running the normal Node.js executable, with the exception of the
These flags are disabled owing to the fact that Electron uses BoringSSL instead of OpenSSL when building Node.js' These flags are disabled owing to the fact that Electron uses BoringSSL instead of OpenSSL when building Node.js'
`crypto` module, and so will not work as designed. `crypto` module, and so will not work as designed.
If the [`runAsNode` fuse](../tutorial/fuses.md#runasnode) is disabled, `ELECTRON_RUN_AS_NODE` will be ignored. If the [`runAsNode` fuse](../tutorial/fuses.md#L13) is disabled, `ELECTRON_RUN_AS_NODE` will be ignored.
### `ELECTRON_NO_ATTACH_CONSOLE` _Windows_ ### `ELECTRON_NO_ATTACH_CONSOLE` _Windows_
@@ -125,6 +125,16 @@ Options:
* `kioclient5` * `kioclient5`
* `kioclient` * `kioclient`
### `ELECTRON_OZONE_PLATFORM_HINT` _Linux_
Selects the preferred platform backend used on Linux. The default one is `x11`. `auto` selects Wayland if possible, X11 otherwise.
Options:
* `auto`
* `wayland`
* `x11`
## Development Variables ## Development Variables
The following environment variables are intended primarily for development and The following environment variables are intended primarily for development and

View File

@@ -77,7 +77,6 @@ extension to be loaded.
```js ```js
const { app, session } = require('electron') const { app, session } = require('electron')
const path = require('node:path') const path = require('node:path')
app.whenReady().then(async () => { app.whenReady().then(async () => {
@@ -93,13 +92,11 @@ app.whenReady().then(async () => {
This API does not support loading packed (.crx) extensions. This API does not support loading packed (.crx) extensions.
> [!NOTE] **Note:** This API cannot be called before the `ready` event of the `app` module
> This API cannot be called before the `ready` event of the `app` module is emitted.
> is emitted.
> [!NOTE] **Note:** Loading extensions into in-memory (non-persistent) sessions is not
> Loading extensions into in-memory (non-persistent) sessions is not supported and will throw an error.
> supported and will throw an error.
#### `extensions.removeExtension(extensionId)` #### `extensions.removeExtension(extensionId)`
@@ -107,9 +104,8 @@ This API does not support loading packed (.crx) extensions.
Unloads an extension. Unloads an extension.
> [!NOTE] **Note:** This API cannot be called before the `ready` event of the `app` module
> This API cannot be called before the `ready` event of the `app` module is emitted.
> is emitted.
#### `extensions.getExtension(extensionId)` #### `extensions.getExtension(extensionId)`
@@ -117,14 +113,12 @@ Unloads an extension.
Returns `Extension | null` - The loaded extension with the given ID. Returns `Extension | null` - The loaded extension with the given ID.
> [!NOTE] **Note:** This API cannot be called before the `ready` event of the `app` module
> This API cannot be called before the `ready` event of the `app` module is emitted.
> is emitted.
#### `extensions.getAllExtensions()` #### `extensions.getAllExtensions()`
Returns `Extension[]` - A list of all loaded extensions. Returns `Extension[]` - A list of all loaded extensions.
> [!NOTE] **Note:** This API cannot be called before the `ready` event of the `app` module
> This API cannot be called before the `ready` event of the `app` module is emitted.
> is emitted.

View File

@@ -6,8 +6,7 @@ but it also happens to support some other extension capabilities.
[chrome-extensions-api-index]: https://developer.chrome.com/extensions/api_index [chrome-extensions-api-index]: https://developer.chrome.com/extensions/api_index
> [!NOTE] > **Note:** Electron does not support arbitrary Chrome extensions from the
> Electron does not support arbitrary Chrome extensions from the
> store, and it is a **non-goal** of the Electron project to be perfectly > store, and it is a **non-goal** of the Electron project to be perfectly
> compatible with Chrome's implementation of Extensions. > compatible with Chrome's implementation of Extensions.
@@ -161,8 +160,7 @@ The following methods of `chrome.tabs` are supported:
- `chrome.tabs.update` (partial support) - `chrome.tabs.update` (partial support)
- supported properties: `url`, `muted`. - supported properties: `url`, `muted`.
> [!NOTE] > **Note:** In Chrome, passing `-1` as a tab ID signifies the "currently active
> In Chrome, passing `-1` as a tab ID signifies the "currently active
> tab". Since Electron has no such concept, passing `-1` as a tab ID is not > tab". Since Electron has no such concept, passing `-1` as a tab ID is not
> supported and will raise an error. > supported and will raise an error.
@@ -172,7 +170,6 @@ See [official documentation](https://developer.chrome.com/docs/extensions/refere
All features of this API are supported. All features of this API are supported.
> [!NOTE] > **NOTE:** Electron's [`webRequest`](web-request.md) module takes precedence over `chrome.webRequest` if there are conflicting handlers.
> Electron's [`webRequest`](web-request.md) module takes precedence over `chrome.webRequest` if there are conflicting handlers.
See [official documentation](https://developer.chrome.com/docs/extensions/reference/webRequest) for more information. See [official documentation](https://developer.chrome.com/docs/extensions/reference/webRequest) for more information.

View File

@@ -8,13 +8,13 @@ The `globalShortcut` module can register/unregister a global keyboard shortcut
with the operating system so that you can customize the operations for various with the operating system so that you can customize the operations for various
shortcuts. shortcuts.
> [!NOTE] **Note:** The shortcut is global; it will work even if the app does
> The shortcut is global; it will work even if the app does not have the keyboard focus. This module cannot be used before the `ready`
> not have the keyboard focus. This module cannot be used before the `ready` event of the app module is emitted.
> event of the app module is emitted.
> Please also note that it is also possible to use Chromium's Please also note that it is also possible to use Chromium's
> `GlobalShortcutsPortal` implementation, which allows apps to bind global `GlobalShortcutsPortal` implementation, which allows apps to bind global
> shortcuts when running within a Wayland session. shortcuts when running within a Wayland session.
```js ```js
const { app, globalShortcut } = require('electron') const { app, globalShortcut } = require('electron')
@@ -46,16 +46,13 @@ app.on('will-quit', () => {
}) })
``` ```
> [!TIP]
> See also: [A detailed guide on Keyboard Shortcuts](../tutorial/keyboard-shortcuts.md).
## Methods ## Methods
The `globalShortcut` module has the following methods: The `globalShortcut` module has the following methods:
### `globalShortcut.register(accelerator, callback)` ### `globalShortcut.register(accelerator, callback)`
* `accelerator` string - An [accelerator](../tutorial/keyboard-shortcuts.md#accelerators) shortcut. * `accelerator` [Accelerator](accelerator.md)
* `callback` Function * `callback` Function
Returns `boolean` - Whether or not the shortcut was registered successfully. Returns `boolean` - Whether or not the shortcut was registered successfully.
@@ -77,7 +74,7 @@ the app has been authorized as a [trusted accessibility client](https://develope
### `globalShortcut.registerAll(accelerators, callback)` ### `globalShortcut.registerAll(accelerators, callback)`
* `accelerators` string[] - An array of [accelerator](../tutorial/keyboard-shortcuts.md#accelerators) shortcuts. * `accelerators` [Accelerator](accelerator.md)[] - an array of [Accelerator](accelerator.md)s.
* `callback` Function * `callback` Function
Registers a global shortcut of all `accelerator` items in `accelerators`. The `callback` is called when any of the registered shortcuts are pressed by the user. Registers a global shortcut of all `accelerator` items in `accelerators`. The `callback` is called when any of the registered shortcuts are pressed by the user.
@@ -96,7 +93,7 @@ the app has been authorized as a [trusted accessibility client](https://develope
### `globalShortcut.isRegistered(accelerator)` ### `globalShortcut.isRegistered(accelerator)`
* `accelerator` string - An [accelerator](../tutorial/keyboard-shortcuts.md#accelerators) shortcut. * `accelerator` [Accelerator](accelerator.md)
Returns `boolean` - Whether this application has registered `accelerator`. Returns `boolean` - Whether this application has registered `accelerator`.
@@ -106,7 +103,7 @@ don't want applications to fight for global shortcuts.
### `globalShortcut.unregister(accelerator)` ### `globalShortcut.unregister(accelerator)`
* `accelerator` string - An [accelerator](../tutorial/keyboard-shortcuts.md#accelerators) shortcut. * `accelerator` [Accelerator](accelerator.md)
Unregisters the global shortcut of `accelerator`. Unregisters the global shortcut of `accelerator`.

View File

@@ -1,66 +0,0 @@
# ImageView
> A View that displays an image.
Process: [Main](../glossary.md#main-process)
This module cannot be used until the `ready` event of the `app`
module is emitted.
Useful for showing splash screens that will be swapped for `WebContentsView`s
when the content finishes loading.
Note that `ImageView` is experimental and may be changed or removed in the future.
```js
const { BaseWindow, ImageView, nativeImage, WebContentsView } = require('electron')
const path = require('node:path')
const win = new BaseWindow({ width: 800, height: 600 })
// Create a "splash screen" image to display while the WebContentsView loads
const splashView = new ImageView()
const splashImage = nativeImage.createFromPath(path.join(__dirname, 'loading.png'))
splashView.setImage(splashImage)
win.setContentView(splashView)
const webContentsView = new WebContentsView()
webContentsView.webContents.once('did-finish-load', () => {
// Now that the WebContentsView has loaded, swap out the "splash screen" ImageView
win.setContentView(webContentsView)
})
webContentsView.webContents.loadURL('https://electronjs.org')
```
## Class: ImageView extends `View`
> A View that displays an image.
Process: [Main](../glossary.md#main-process)
`ImageView` inherits from [`View`](view.md).
`ImageView` is an [EventEmitter][event-emitter].
> [!WARNING]
> Electron's built-in classes cannot be subclassed in user code.
> For more information, see [the FAQ](../faq.md#class-inheritance-does-not-work-with-electron-built-in-modules).
### `new ImageView()` _Experimental_
Creates an ImageView.
### Instance Methods
The following methods are available on instances of the `ImageView` class, in
addition to those inherited from [View](view.md):
#### `image.setImage(image)` _Experimental_
* `image` NativeImage
Sets the image for this `ImageView`. Note that only image formats supported by
`NativeImage` can be used with an `ImageView`.
[event-emitter]: https://nodejs.org/api/events.html#events_class_eventemitter

View File

@@ -11,10 +11,6 @@ Process: [Main](../glossary.md#main-process)
<!-- TODO(samuelmaddock): refactor doc gen to allow generics to reduce duplication --> <!-- TODO(samuelmaddock): refactor doc gen to allow generics to reduce duplication -->
> [!WARNING]
> Electron's built-in classes cannot be subclassed in user code.
> For more information, see [the FAQ](../faq.md#class-inheritance-does-not-work-with-electron-built-in-modules).
### Instance Methods ### Instance Methods
#### `ipcMainServiceWorker.on(channel, listener)` #### `ipcMainServiceWorker.on(channel, listener)`

View File

@@ -20,12 +20,6 @@ changes:
Process: [Renderer](../glossary.md#renderer-process) Process: [Renderer](../glossary.md#renderer-process)
> [!IMPORTANT]
> If you want to call this API from a renderer process with context isolation enabled,
> place the API call in your preload script and
> [expose](../tutorial/context-isolation.md#after-context-isolation-enabled) it using the
> [`contextBridge`](context-bridge.md) API.
The `ipcRenderer` module is an [EventEmitter][event-emitter]. It provides a few The `ipcRenderer` module is an [EventEmitter][event-emitter]. It provides a few
methods so you can send synchronous and asynchronous messages from the render methods so you can send synchronous and asynchronous messages from the render
process (web page) to the main process. You can also receive replies from the process (web page) to the main process. You can also receive replies from the
@@ -162,7 +156,7 @@ If you need to transfer a [`MessagePort`][] to the main process, use [`ipcRender
If you do not need a response to the message, consider using [`ipcRenderer.send`](#ipcrenderersendchannel-args). If you do not need a response to the message, consider using [`ipcRenderer.send`](#ipcrenderersendchannel-args).
> [!NOTE] > **Note**
> Sending non-standard JavaScript types such as DOM objects or > Sending non-standard JavaScript types such as DOM objects or
> special Electron objects will throw an exception. > special Electron objects will throw an exception.
> >
@@ -171,7 +165,7 @@ If you do not need a response to the message, consider using [`ipcRenderer.send`
> Electron's IPC to the main process, as the main process would have no way to decode > Electron's IPC to the main process, as the main process would have no way to decode
> them. Attempting to send such objects over IPC will result in an error. > them. Attempting to send such objects over IPC will result in an error.
> [!NOTE] > **Note**
> If the handler in the main process throws an error, > If the handler in the main process throws an error,
> the promise returned by `invoke` will reject. > the promise returned by `invoke` will reject.
> However, the `Error` object in the renderer process > However, the `Error` object in the renderer process
@@ -201,8 +195,7 @@ throw an exception.
The main process handles it by listening for `channel` with [`ipcMain`](./ipc-main.md) module, The main process handles it by listening for `channel` with [`ipcMain`](./ipc-main.md) module,
and replies by setting `event.returnValue`. and replies by setting `event.returnValue`.
> [!WARNING] > :warning: **WARNING**: Sending a synchronous message will block the whole
> Sending a synchronous message will block the whole
> renderer process until the reply is received, so use this method only as a > renderer process until the reply is received, so use this method only as a
> last resort. It's much better to use the asynchronous version, > last resort. It's much better to use the asynchronous version,
> [`invoke()`](./ipc-renderer.md#ipcrendererinvokechannel-args). > [`invoke()`](./ipc-renderer.md#ipcrendererinvokechannel-args).

View File

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

View File

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

View File

@@ -15,12 +15,9 @@ Process: [Main](../glossary.md#main-process)
Example: Example:
<!-- eslint-disable import/order -->
```js ```js
// Main process // Main process
const { BrowserWindow, MessageChannelMain } = require('electron') const { BrowserWindow, MessageChannelMain } = require('electron')
const w = new BrowserWindow() const w = new BrowserWindow()
const { port1, port2 } = new MessageChannelMain() const { port1, port2 } = new MessageChannelMain()
w.webContents.postMessage('port', null, [port2]) w.webContents.postMessage('port', null, [port2])
@@ -28,7 +25,6 @@ port1.postMessage({ some: 'message' })
// Renderer process // Renderer process
const { ipcRenderer } = require('electron') const { ipcRenderer } = require('electron')
ipcRenderer.on('port', (e) => { ipcRenderer.on('port', (e) => {
// e.ports is a list of ports sent along with this message // e.ports is a list of ports sent along with this message
e.ports[0].onmessage = (messageEvent) => { e.ports[0].onmessage = (messageEvent) => {
@@ -37,10 +33,6 @@ ipcRenderer.on('port', (e) => {
}) })
``` ```
> [!WARNING]
> Electron's built-in classes cannot be subclassed in user code.
> For more information, see [the FAQ](../faq.md#class-inheritance-does-not-work-with-electron-built-in-modules).
### Instance Properties ### Instance Properties
#### `channel.port1` #### `channel.port1`

View File

@@ -4,12 +4,6 @@
Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process) Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process)
> [!IMPORTANT]
> If you want to call this API from a renderer process with context isolation enabled,
> place the API call in your preload script and
> [expose](../tutorial/context-isolation.md#after-context-isolation-enabled) it using the
> [`contextBridge`](context-bridge.md) API.
The `nativeImage` module provides a unified interface for manipulating The `nativeImage` module provides a unified interface for manipulating
system images. These can be handy if you want to provide multiple scaled system images. These can be handy if you want to provide multiple scaled
versions of the same icon or take advantage of macOS [template images][template-image]. versions of the same icon or take advantage of macOS [template images][template-image].
@@ -92,7 +86,6 @@ images/
```js title='Main Process' ```js title='Main Process'
const { Tray } = require('electron') const { Tray } = require('electron')
const appTray = new Tray('/Users/somebody/images/icon.png') const appTray = new Tray('/Users/somebody/images/icon.png')
``` ```
@@ -141,8 +134,7 @@ Creates an empty `NativeImage` instance.
Returns `Promise<NativeImage>` - fulfilled with the file's thumbnail preview image, which is a [NativeImage](native-image.md). Returns `Promise<NativeImage>` - fulfilled with the file's thumbnail preview image, which is a [NativeImage](native-image.md).
> [!NOTE] Note: The Windows implementation will ignore `size.height` and scale the height according to `size.width`.
> Windows implementation will ignore `size.height` and scale the height according to `size.width`.
### `nativeImage.createFromPath(path)` ### `nativeImage.createFromPath(path)`
@@ -150,8 +142,8 @@ Returns `Promise<NativeImage>` - fulfilled with the file's thumbnail preview ima
Returns `NativeImage` Returns `NativeImage`
Creates a new `NativeImage` instance from an image file (e.g., PNG or JPEG) located at `path`. Creates a new `NativeImage` instance from a file located at `path`. This method
This method returns an empty image if the `path` does not exist, cannot be read, or is not returns an empty image if the `path` does not exist, cannot be read, or is not
a valid image. a valid image.
```js ```js
@@ -279,12 +271,16 @@ changes:
Returns `string` - The [Data URL][data-url] of the image. Returns `string` - The [Data URL][data-url] of the image.
#### `image.getBitmap([options])` _Deprecated_ #### `image.getBitmap([options])`
* `options` Object (optional) * `options` Object (optional)
* `scaleFactor` Number (optional) - Defaults to 1.0. * `scaleFactor` Number (optional) - Defaults to 1.0.
Legacy alias for `image.toBitmap()`. Returns `Buffer` - A [Buffer][buffer] that contains the image's raw bitmap pixel data.
The difference between `getBitmap()` and `toBitmap()` is that `getBitmap()` does not
copy the bitmap data, so you have to use the returned Buffer immediately in
current event loop tick; otherwise the data might be changed or destroyed.
#### `image.getNativeHandle()` _macOS_ #### `image.getNativeHandle()` _macOS_

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