mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
140 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9049d01bd6 | ||
|
|
42c8938c9a | ||
|
|
b5f8c7554a | ||
|
|
0b34f5b45e | ||
|
|
2b7f32428f | ||
|
|
2d7cfd3de2 | ||
|
|
06c84f35bd | ||
|
|
cfb7237c6c | ||
|
|
fa4462341a | ||
|
|
19069ead12 | ||
|
|
6da5666aa5 | ||
|
|
fcdf08ce75 | ||
|
|
fe9e90af7b | ||
|
|
ef9cd3464d | ||
|
|
51f771224a | ||
|
|
23d574152e | ||
|
|
4bee1eaded | ||
|
|
88f4deb3a3 | ||
|
|
165ea64314 | ||
|
|
8961eb074b | ||
|
|
b194cb1486 | ||
|
|
470a82869c | ||
|
|
a19f617ab0 | ||
|
|
f008b0d0b2 | ||
|
|
ce2f471e9d | ||
|
|
5cda3d226c | ||
|
|
30358180c7 | ||
|
|
e151aae7a3 | ||
|
|
bc9b5af26e | ||
|
|
952b9c0b46 | ||
|
|
5705ce1d6e | ||
|
|
c8ac7b0efd | ||
|
|
dbeed26c0d | ||
|
|
99e589c2cf | ||
|
|
3782fe51ff | ||
|
|
be7b06108e | ||
|
|
6b956d036d | ||
|
|
370ffe0df5 | ||
|
|
14456ecfbc | ||
|
|
974c8f5150 | ||
|
|
ac5b5995e8 | ||
|
|
5ccd41cf5c | ||
|
|
060cfb94e9 | ||
|
|
587e115527 | ||
|
|
a56b2acadd | ||
|
|
58479848b2 | ||
|
|
ba2cad1670 | ||
|
|
f98501308a | ||
|
|
1d9f1a4cd4 | ||
|
|
7d01169091 | ||
|
|
ad496c9958 | ||
|
|
b04c4505c4 | ||
|
|
c3fd3afa24 | ||
|
|
4516469312 | ||
|
|
b4bb928224 | ||
|
|
4ed1ac6ab0 | ||
|
|
289a1861fc | ||
|
|
b19995e623 | ||
|
|
47ab952bb1 | ||
|
|
0c73c66438 | ||
|
|
289168a1ad | ||
|
|
9f27479a11 | ||
|
|
01b8069ada | ||
|
|
31a95f7857 | ||
|
|
70b354643e | ||
|
|
4fdfc66706 | ||
|
|
9d7c3a65fe | ||
|
|
66d1227cc4 | ||
|
|
ccb7fc05b3 | ||
|
|
d507cf63d1 | ||
|
|
95bce0bce1 | ||
|
|
727e218c47 | ||
|
|
16cb1e46c8 | ||
|
|
435facd8e4 | ||
|
|
75ce54614e | ||
|
|
de958d0dab | ||
|
|
0af85fc5f0 | ||
|
|
f927d1dd92 | ||
|
|
f2ec3763c2 | ||
|
|
c8c5f9c986 | ||
|
|
c1c9c1d001 | ||
|
|
3b89a5e183 | ||
|
|
e2042de483 | ||
|
|
dd5def7f46 | ||
|
|
6210a9e82c | ||
|
|
eb7216be1c | ||
|
|
32830de5b6 | ||
|
|
a9f3754d22 | ||
|
|
eb7a5c2548 | ||
|
|
cb1c7b447b | ||
|
|
d33905c5d9 | ||
|
|
ddc7afd3f0 | ||
|
|
d04491dff0 | ||
|
|
88286e8f16 | ||
|
|
a6eb660a3d | ||
|
|
bb6d76a07a | ||
|
|
27349fc233 | ||
|
|
c1a9e79d08 | ||
|
|
b3bb3c5be0 | ||
|
|
882bcb9435 | ||
|
|
d2fce89969 | ||
|
|
78adaed2c6 | ||
|
|
bba618f4d3 | ||
|
|
b83b8ef851 | ||
|
|
e4df33053c | ||
|
|
dc149e6d3f | ||
|
|
c1918f96cb | ||
|
|
9fe5f566a4 | ||
|
|
3053e33739 | ||
|
|
d857946d6e | ||
|
|
082d43e022 | ||
|
|
18ee5c25c6 | ||
|
|
69333ae82f | ||
|
|
614c987401 | ||
|
|
2ce5fdbec8 | ||
|
|
54e5f1d8b2 | ||
|
|
5ccd987f61 | ||
|
|
754ac14e78 | ||
|
|
608d89e447 | ||
|
|
45f633e0f9 | ||
|
|
505e02284b | ||
|
|
1472c5b090 | ||
|
|
61cddcaf76 | ||
|
|
0fed0b74e0 | ||
|
|
af9ea0b422 | ||
|
|
a41a0b1c1d | ||
|
|
600551766d | ||
|
|
c538aa8e6c | ||
|
|
2d6dd64a5e | ||
|
|
bb616ba5ca | ||
|
|
4a1c029f94 | ||
|
|
a1816f3587 | ||
|
|
db84f39e5e | ||
|
|
7ecb8ad7a5 | ||
|
|
973c344f1b | ||
|
|
01c5db032a | ||
|
|
2c22507dfb | ||
|
|
41c1161dd9 | ||
|
|
b36aaf36e7 | ||
|
|
5728e6dc81 |
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -6,6 +6,9 @@ yarn.lock text eol=lf
|
||||
script/zip_manifests/*.manifest text eol=lf
|
||||
patches/**/.patches merge=union
|
||||
|
||||
# Patch file line ending exceptions (patches that affect CRLF files)
|
||||
reland_lzma_sdk_update_to_24_09.patch -text
|
||||
|
||||
# Source code and markdown files should always use LF as line ending.
|
||||
*.c text eol=lf
|
||||
*.cc text eol=lf
|
||||
|
||||
23
.github/actions/build-electron/action.yml
vendored
23
.github/actions/build-electron/action.yml
vendored
@@ -108,7 +108,9 @@ runs:
|
||||
if [ "${{ inputs.target-platform }}" = "win" ]; then
|
||||
cd out/Default
|
||||
powershell Compress-Archive -update mksnapshot_args mksnapshot.zip
|
||||
powershell Compress-Archive -update gen/v8/embedded.S mksnapshot.zip
|
||||
powershell mkdir mktmp\\gen\\v8
|
||||
powershell Copy-Item gen\\v8\\embedded.S mktmp\\gen\\v8
|
||||
powershell Compress-Archive -update -Path mktmp\\gen mksnapshot.zip
|
||||
else
|
||||
(cd out/Default; zip mksnapshot.zip mksnapshot_args gen/v8/embedded.S)
|
||||
fi
|
||||
@@ -143,6 +145,25 @@ runs:
|
||||
run: |
|
||||
cd src
|
||||
e build --target electron:node_headers
|
||||
- name: Create installed_software.json ${{ inputs.step-suffix }}
|
||||
shell: powershell
|
||||
if: ${{ inputs.is-release == 'true' && inputs.target-platform == 'win' }}
|
||||
run: |
|
||||
cd src
|
||||
Get-CimInstance -Namespace root\cimv2 -Class Win32_product | Select vendor, description, @{l='install_location';e='InstallLocation'}, @{l='install_date';e='InstallDate'}, @{l='install_date_2';e='InstallDate2'}, caption, version, name, @{l='sku_number';e='SKUNumber'} | ConvertTo-Json | Out-File -Encoding utf8 -FilePath .\installed_software.json
|
||||
- name: Profile Windows Toolchain ${{ inputs.step-suffix }}
|
||||
shell: bash
|
||||
if: ${{ inputs.is-release == 'true' && inputs.target-platform == 'win' }}
|
||||
run: |
|
||||
cd src
|
||||
python3 electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
|
||||
- name: Add msdia140.dll to Path ${{ inputs.step-suffix }}
|
||||
shell: bash
|
||||
if: ${{ inputs.is-release == 'true' && inputs.target-platform == 'win' }}
|
||||
run: |
|
||||
# Needed for msdia140.dll on 64-bit windows
|
||||
cd src
|
||||
export PATH="$PATH:$(pwd)/third_party/llvm-build/Release+Asserts/bin"
|
||||
- name: Generate & Zip Symbols ${{ inputs.step-suffix }}
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
58
.github/actions/checkout/action.yml
vendored
58
.github/actions/checkout/action.yml
vendored
@@ -9,6 +9,8 @@ inputs:
|
||||
description: 'Whether to persist the cache to the shared drive'
|
||||
required: false
|
||||
default: 'true'
|
||||
target-platform:
|
||||
description: 'Target platform, should be linux, win, macos'
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
@@ -18,38 +20,34 @@ runs:
|
||||
echo "GIT_CACHE_PATH=$(pwd)/git-cache" >> $GITHUB_ENV
|
||||
- name: 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
|
||||
uses: ./src/electron/.github/actions/install-build-tools
|
||||
- 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
|
||||
shell: bash
|
||||
run: |
|
||||
node src/electron/script/generate-deps-hash.js
|
||||
echo "DEPSHASH=v1-src-cache-$(cat src/electron/.depshash)" >> $GITHUB_ENV
|
||||
DEPSHASH="v1-src-cache-$(cat src/electron/.depshash)"
|
||||
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
|
||||
if: ${{ inputs.generate-sas-token == 'true' }}
|
||||
shell: bash
|
||||
run: |
|
||||
curl --unix-socket /var/run/sas/sas.sock --fail "http://foo/$DEPSHASH.tar" > sas-token
|
||||
curl --unix-socket /var/run/sas/sas.sock --fail "http://foo/$CACHE_FILE?platform=${{ inputs.target-platform }}" > sas-token
|
||||
- name: Save SAS Key
|
||||
if: ${{ inputs.generate-sas-token == 'true' }}
|
||||
uses: actions/cache/save@v4
|
||||
uses: actions/cache/save@d4323d4df104b026a6aa633fdb11d772146be0bf
|
||||
with:
|
||||
path: |
|
||||
sas-token
|
||||
key: sas-key-${{ github.run_number }}-${{ github.run_attempt }}
|
||||
path: sas-token
|
||||
key: sas-key-${{ inputs.target-platform }}-${{ github.run_number }}-${{ github.run_attempt }}
|
||||
enableCrossOsArchive: true
|
||||
- name: Check If Cache Exists
|
||||
id: check-cache
|
||||
shell: bash
|
||||
@@ -58,7 +56,7 @@ runs:
|
||||
echo "Not using cache this time..."
|
||||
echo "cache_exists=false" >> $GITHUB_OUTPUT
|
||||
else
|
||||
cache_path=/mnt/cross-instance-cache/$DEPSHASH.tar
|
||||
cache_path=$CACHE_DRIVE/$CACHE_FILE
|
||||
echo "Using cache key: $DEPSHASH"
|
||||
echo "Checking for cache in: $cache_path"
|
||||
if [ ! -f "$cache_path" ] || [ `du $cache_path | cut -f1` = "0" ]; then
|
||||
@@ -73,10 +71,10 @@ runs:
|
||||
if: steps.check-cache.outputs.cache_exists == 'false' && inputs.use-cache == 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
# if there is less than 20 GB free space then creating the cache might fail so exit early
|
||||
freespace=`df -m /mnt/cross-instance-cache | grep -w /mnt/cross-instance-cache | awk '{print $4}'`
|
||||
freespace_human=`df -h /mnt/cross-instance-cache | grep -w /mnt/cross-instance-cache | awk '{print $4}'`
|
||||
if [ $freespace -le 20000 ]; then
|
||||
# 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
|
||||
@@ -97,7 +95,7 @@ runs:
|
||||
fi
|
||||
|
||||
ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES=1 e d gclient sync --with_branch_heads --with_tags -vv
|
||||
if [ "${{ inputs.is-release }}" != "true" && -n "${{ env.PATCH_UP_APP_CREDS }}" ]; then
|
||||
if [[ "${{ inputs.is-release }}" != "true" ]]; then
|
||||
# Re-export all the patches to check if there were changes.
|
||||
python3 src/electron/script/export_all_patches.py src/electron/patches/config.json
|
||||
cd src/electron
|
||||
@@ -126,6 +124,8 @@ runs:
|
||||
cat ../../patches/update-patches.patch
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "No changes to patches detected"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -163,14 +163,14 @@ runs:
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Uncompressed src size: $(du -sh src | cut -f1 -d' ')"
|
||||
tar -cf $DEPSHASH.tar src
|
||||
echo "Compressed src to $(du -sh $DEPSHASH.tar | cut -f1 -d' ')"
|
||||
cp ./$DEPSHASH.tar /mnt/cross-instance-cache/
|
||||
tar -cf $CACHE_FILE src
|
||||
echo "Compressed src to $(du -sh $CACHE_FILE | cut -f1 -d' ')"
|
||||
cp ./$CACHE_FILE $CACHE_DRIVE/
|
||||
- name: Persist Src Cache
|
||||
if: ${{ steps.check-cache.outputs.cache_exists == 'false' && inputs.use-cache == 'true' }}
|
||||
shell: bash
|
||||
run: |
|
||||
final_cache_path=/mnt/cross-instance-cache/$DEPSHASH.tar
|
||||
final_cache_path=$CACHE_DRIVE/$CACHE_FILE
|
||||
echo "Using cache key: $DEPSHASH"
|
||||
echo "Checking path: $final_cache_path"
|
||||
if [ ! -f "$final_cache_path" ]; then
|
||||
|
||||
40
.github/actions/cipd-install/action.yml
vendored
Normal file
40
.github/actions/cipd-install/action.yml
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
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'
|
||||
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 }}
|
||||
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: CIPD installation of ${{ inputs.dependency }} (macOS)
|
||||
if: ${{ inputs.target-platform == 'macos' }}
|
||||
shell: bash
|
||||
run: |
|
||||
echo "ensuring ${{ inputs.dependency }} on macOS"
|
||||
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
|
||||
61
.github/actions/fix-sync-macos/action.yml
vendored
61
.github/actions/fix-sync-macos/action.yml
vendored
@@ -1,61 +0,0 @@
|
||||
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
|
||||
120
.github/actions/fix-sync/action.yml
vendored
Normal file
120
.github/actions/fix-sync/action.yml
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
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 clang
|
||||
shell: bash
|
||||
run : |
|
||||
rm -rf src/third_party/llvm-build
|
||||
python3 src/tools/clang/scripts/update.py
|
||||
- name: Fix esbuild
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
shell: bash
|
||||
run : |
|
||||
echo "$(pwd)/src/third_party/ninja" >> $GITHUB_PATH
|
||||
- name: Fixup angle git
|
||||
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
|
||||
@@ -14,7 +14,9 @@ runs:
|
||||
export BUILD_TOOLS_SHA=8246e57791b0af4ae5975eb96f09855f9269b1cd
|
||||
npm i -g @electron/build-tools
|
||||
e auto-update disable
|
||||
e d auto-update disable
|
||||
if [ "$(expr substr $(uname -s) 1 10)" == "MSYS_NT-10" ]; then
|
||||
e d cipd.bat --version
|
||||
cp "C:\Python37\python.exe" "C:\Python37\python3.exe"
|
||||
cp "C:\Python311\python.exe" "C:\Python311\python3.exe"
|
||||
fi
|
||||
echo "$HOME/.electron_build_tools/third_party/depot_tools" >> $GITHUB_PATH
|
||||
|
||||
@@ -7,7 +7,7 @@ runs:
|
||||
shell: bash
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "dir=$(node src/electron/script/yarn cache dir)" >> $GITHUB_OUTPUT
|
||||
- uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9
|
||||
- uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57
|
||||
id: yarn-cache
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
|
||||
10
.github/actions/restore-cache-aks/action.yml
vendored
10
.github/actions/restore-cache-aks/action.yml
vendored
@@ -1,12 +1,20 @@
|
||||
name: 'Restore Cache AKS'
|
||||
description: 'Restores Electron src cache via AKS'
|
||||
inputs:
|
||||
target-platform:
|
||||
description: 'Target platform, should be linux, win, macos'
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Restore and Ensure Src Cache
|
||||
shell: bash
|
||||
run: |
|
||||
cache_path=/mnt/cross-instance-cache/$DEPSHASH.tar
|
||||
if [ "${{ inputs.target-platform }}" = "win" ]; then
|
||||
cache_path=/mnt/win-cache/$DEPSHASH.tar
|
||||
else
|
||||
cache_path=/mnt/cross-instance-cache/$DEPSHASH.tar
|
||||
fi
|
||||
|
||||
echo "Using cache key: $DEPSHASH"
|
||||
echo "Checking for cache in: $cache_path"
|
||||
if [ ! -f "$cache_path" ]; then
|
||||
|
||||
75
.github/actions/restore-cache-azcopy/action.yml
vendored
75
.github/actions/restore-cache-azcopy/action.yml
vendored
@@ -1,22 +1,25 @@
|
||||
name: 'Restore Cache AZCopy'
|
||||
description: 'Restores Electron src cache via AZCopy'
|
||||
inputs:
|
||||
target-platform:
|
||||
description: 'Target platform, should be linux, win, macos'
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Obtain SAS Key
|
||||
continue-on-error: true
|
||||
uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9
|
||||
uses: actions/cache/restore@d4323d4df104b026a6aa633fdb11d772146be0bf
|
||||
with:
|
||||
path: |
|
||||
sas-token
|
||||
key: sas-key-${{ github.run_number }}-1
|
||||
path: sas-token
|
||||
key: sas-key-${{ inputs.target-platform }}-${{ github.run_number }}-1
|
||||
enableCrossOsArchive: true
|
||||
- name: Obtain SAS Key
|
||||
continue-on-error: true
|
||||
uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9
|
||||
uses: actions/cache/restore@d4323d4df104b026a6aa633fdb11d772146be0bf
|
||||
with:
|
||||
path: |
|
||||
sas-token
|
||||
key: sas-key-${{ github.run_number }}-${{ github.run_attempt }}
|
||||
path: sas-token
|
||||
key: sas-key-${{ inputs.target-platform }}-${{ github.run_number }}-${{ github.run_attempt }}
|
||||
enableCrossOsArchive: true
|
||||
- name: Download Src Cache from AKS
|
||||
# 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
|
||||
@@ -26,21 +29,30 @@ runs:
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
retry_on: error
|
||||
shell: bash
|
||||
command: |
|
||||
sas_token=$(cat sas-token)
|
||||
if [ -z $sas-token ]; then
|
||||
echo "SAS Token not found; exiting src cache download early..."
|
||||
exit 1
|
||||
else
|
||||
if [ "${{ inputs.target-platform }}" = "win" ]; then
|
||||
azcopy copy --log-level=ERROR \
|
||||
"https://${{ env.AZURE_AKS_CACHE_STORAGE_ACCOUNT }}.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://${{ env.AZURE_AKS_CACHE_STORAGE_ACCOUNT }}.file.core.windows.net/${{ env.AZURE_AKS_CACHE_SHARE_NAME }}/${{ env.CACHE_PATH }}?$sas_token" $DEPSHASH.tar
|
||||
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:
|
||||
AZURE_AKS_CACHE_STORAGE_ACCOUNT: f723719aa87a34622b5f7f3
|
||||
AZURE_AKS_CACHE_SHARE_NAME: pvc-f6a4089f-b082-4bee-a3f9-c3e1c0c02d8f
|
||||
AZURE_AKS_WIN_CACHE_SHARE_NAME: pvc-71dec4f2-0d44-4fd1-a2c3-add049d70bdf
|
||||
- name: Clean SAS Key
|
||||
shell: bash
|
||||
run: rm -f sas-token
|
||||
- name: Unzip and Ensure Src Cache
|
||||
if: ${{ inputs.target-platform == 'macos' }}
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Downloaded cache is $(du -sh $DEPSHASH.tar | cut -f1)"
|
||||
@@ -68,4 +80,45 @@ runs:
|
||||
fi
|
||||
|
||||
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 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
|
||||
|
||||
26
.github/actions/set-chromium-cookie/action.yml
vendored
Normal file
26
.github/actions/set-chromium-cookie/action.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
name: 'Set Chromium Git Cookie'
|
||||
description: 'Sets an authenticated cookie from Chromium to allow for a higher request limit'
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Set the git cookie from chromium.googlesource.com (Unix)
|
||||
if: ${{ runner.os != 'Windows' && env.CHROMIUM_GIT_COOKIE }}
|
||||
shell: bash
|
||||
run: |
|
||||
eval 'set +o history' 2>/dev/null || setopt HIST_IGNORE_SPACE 2>/dev/null
|
||||
touch ~/.gitcookies
|
||||
chmod 0600 ~/.gitcookies
|
||||
|
||||
git config --global http.cookiefile ~/.gitcookies
|
||||
|
||||
tr , \\t <<\__END__ >>~/.gitcookies
|
||||
${{ env.CHROMIUM_GIT_COOKIE }}
|
||||
__END__
|
||||
eval 'set -o history' 2>/dev/null || unsetopt HIST_IGNORE_SPACE 2>/dev/null
|
||||
- name: Set the git cookie from chromium.googlesource.com (Windows)
|
||||
if: ${{ runner.os == 'Windows' && env.CHROMIUM_GIT_COOKIE_WINDOWS_STRING }}
|
||||
shell: cmd
|
||||
run: |
|
||||
git config --global http.cookiefile "%USERPROFILE%\.gitcookies"
|
||||
powershell -noprofile -nologo -command Write-Output "${{ env.CHROMIUM_GIT_COOKIE_WINDOWS_STRING }}" >>"%USERPROFILE%\.gitcookies"
|
||||
|
||||
19
.github/workflows/build.yml
vendored
19
.github/workflows/build.yml
vendored
@@ -100,6 +100,7 @@ jobs:
|
||||
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
|
||||
- /var/run/sas:/var/run/sas
|
||||
env:
|
||||
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
|
||||
outputs:
|
||||
build-image-sha: ${{ needs.setup.outputs.build-image-sha }}
|
||||
@@ -114,6 +115,7 @@ jobs:
|
||||
uses: ./src/electron/.github/actions/checkout
|
||||
with:
|
||||
generate-sas-token: 'true'
|
||||
target-platform: macos
|
||||
|
||||
checkout-linux:
|
||||
needs: setup
|
||||
@@ -126,6 +128,7 @@ jobs:
|
||||
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
|
||||
- /var/run/sas:/var/run/sas
|
||||
env:
|
||||
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||
PATCH_UP_APP_CREDS: ${{ secrets.PATCH_UP_APP_CREDS }}
|
||||
outputs:
|
||||
@@ -148,8 +151,11 @@ jobs:
|
||||
image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
|
||||
options: --user root --device /dev/fuse --cap-add SYS_ADMIN
|
||||
volumes:
|
||||
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
|
||||
- /mnt/win-cache:/mnt/win-cache
|
||||
- /var/run/sas:/var/run/sas
|
||||
env:
|
||||
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
|
||||
CHROMIUM_GIT_COOKIE_WINDOWS_STRING: ${{ secrets.CHROMIUM_GIT_COOKIE_WINDOWS_STRING }}
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_win=True'
|
||||
TARGET_OS: 'win'
|
||||
ELECTRON_DEPOT_TOOLS_WIN_TOOLCHAIN: '1'
|
||||
@@ -164,6 +170,9 @@ jobs:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Checkout & Sync & Save
|
||||
uses: ./src/electron/.github/actions/checkout
|
||||
with:
|
||||
generate-sas-token: 'true'
|
||||
target-platform: win
|
||||
|
||||
# GN Check Jobs
|
||||
macos-gn-check:
|
||||
@@ -194,7 +203,7 @@ jobs:
|
||||
target-platform: win
|
||||
target-archs: x64 x86 arm64
|
||||
check-runs-on: electron-arc-linux-amd64-8core
|
||||
check-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-windows.outputs.build-image-sha }}","options":"--user root --device /dev/fuse --cap-add SYS_ADMIN","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
|
||||
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"]}'
|
||||
gn-build-type: testing
|
||||
secrets: inherit
|
||||
|
||||
@@ -322,7 +331,7 @@ jobs:
|
||||
issues: read
|
||||
pull-requests: read
|
||||
uses: ./.github/workflows/pipeline-electron-build-and-test.yml
|
||||
needs: setup
|
||||
needs: checkout-windows
|
||||
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }}
|
||||
with:
|
||||
build-runs-on: electron-arc-windows-amd64-16core
|
||||
@@ -341,7 +350,7 @@ jobs:
|
||||
issues: read
|
||||
pull-requests: read
|
||||
uses: ./.github/workflows/pipeline-electron-build-and-test.yml
|
||||
needs: setup
|
||||
needs: checkout-windows
|
||||
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }}
|
||||
with:
|
||||
build-runs-on: electron-arc-windows-amd64-16core
|
||||
@@ -360,7 +369,7 @@ jobs:
|
||||
issues: read
|
||||
pull-requests: read
|
||||
uses: ./.github/workflows/pipeline-electron-build-and-test.yml
|
||||
needs: setup
|
||||
needs: checkout-windows
|
||||
if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-windows }}
|
||||
with:
|
||||
build-runs-on: electron-arc-windows-amd64-16core
|
||||
|
||||
12
.github/workflows/clean-src-cache.yml
vendored
12
.github/workflows/clean-src-cache.yml
vendored
@@ -1,8 +1,12 @@
|
||||
name: Clean Source Cache
|
||||
|
||||
description: |
|
||||
This workflow cleans up the source cache on the cross-instance cache volume
|
||||
to free up space. It runs daily at midnight and clears files older than 15 days.
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * SUN" # Run at midnight every Sunday
|
||||
- cron: "0 0 * * *"
|
||||
|
||||
jobs:
|
||||
clean-src-cache:
|
||||
@@ -12,10 +16,14 @@ jobs:
|
||||
options: --user root
|
||||
volumes:
|
||||
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
|
||||
- /mnt/win-cache:/mnt/win-cache
|
||||
steps:
|
||||
- name: Cleanup Source Cache
|
||||
shell: bash
|
||||
run: |
|
||||
df -h /mnt/cross-instance-cache
|
||||
find /mnt/cross-instance-cache -type f -mtime +30 -delete
|
||||
find /mnt/cross-instance-cache -type f -mtime +15 -delete
|
||||
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
|
||||
|
||||
1
.github/workflows/macos-publish.yml
vendored
1
.github/workflows/macos-publish.yml
vendored
@@ -39,6 +39,7 @@ jobs:
|
||||
uses: ./src/electron/.github/actions/checkout
|
||||
with:
|
||||
generate-sas-token: 'true'
|
||||
target-platform: macos
|
||||
|
||||
publish-x64-darwin:
|
||||
uses: ./.github/workflows/pipeline-segment-electron-build.yml
|
||||
|
||||
@@ -56,8 +56,8 @@ on:
|
||||
default: false
|
||||
|
||||
concurrency:
|
||||
group: electron-build-and-test-and-nan-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !endsWith(github.ref, '-x-y') }}
|
||||
group: electron-build-and-test-and-nan-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref_protected == true && github.run_id || github.ref }}
|
||||
cancel-in-progress: ${{ github.ref_protected != true }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
@@ -56,8 +56,8 @@ on:
|
||||
default: false
|
||||
|
||||
concurrency:
|
||||
group: electron-build-and-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !endsWith(github.ref, '-x-y') }}
|
||||
group: electron-build-and-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref_protected == true && github.run_id || github.ref }}
|
||||
cancel-in-progress: ${{ github.ref_protected != true }}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
9
.github/workflows/pipeline-electron-lint.yml
vendored
9
.github/workflows/pipeline-electron-lint.yml
vendored
@@ -9,8 +9,11 @@ on:
|
||||
type: string
|
||||
|
||||
concurrency:
|
||||
group: electron-lint-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !endsWith(github.ref, '-x-y') }}
|
||||
group: electron-lint-${{ github.ref_protected == true && github.run_id || github.ref }}
|
||||
cancel-in-progress: ${{ github.ref_protected != true }}
|
||||
|
||||
env:
|
||||
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
@@ -27,6 +30,8 @@ jobs:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Install Dependencies
|
||||
uses: ./src/electron/.github/actions/install-dependencies
|
||||
- name: Set Chromium Git Cookie
|
||||
uses: ./src/electron/.github/actions/set-chromium-cookie
|
||||
- name: Setup third_party Depot Tools
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
@@ -13,7 +13,7 @@ on:
|
||||
required: true
|
||||
target-arch:
|
||||
type: string
|
||||
description: 'Arch to build for, can be x64, arm64 or arm'
|
||||
description: 'Arch to build for, can be x64, arm64, ia32 or arm'
|
||||
required: true
|
||||
target-variant:
|
||||
type: string
|
||||
@@ -61,10 +61,12 @@ on:
|
||||
|
||||
|
||||
concurrency:
|
||||
group: electron-build-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ inputs.target-variant }}-${{ inputs.is-asan }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !endsWith(github.ref, '-x-y') }}
|
||||
group: electron-build-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ inputs.target-variant }}-${{ inputs.is-asan }}-${{ github.ref_protected == true && github.run_id || github.ref }}
|
||||
cancel-in-progress: ${{ github.ref_protected != true }}
|
||||
|
||||
env:
|
||||
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
|
||||
CHROMIUM_GIT_COOKIE_WINDOWS_STRING: ${{ secrets.CHROMIUM_GIT_COOKIE_WINDOWS_STRING }}
|
||||
ELECTRON_ARTIFACTS_BLOB_STORAGE: ${{ secrets.ELECTRON_ARTIFACTS_BLOB_STORAGE }}
|
||||
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
|
||||
SUDOWOODO_EXCHANGE_URL: ${{ secrets.SUDOWOODO_EXCHANGE_URL }}
|
||||
@@ -125,24 +127,10 @@ jobs:
|
||||
GN_EXTRA_ARGS='is_asan=true'
|
||||
fi
|
||||
echo "GN_EXTRA_ARGS=$GN_EXTRA_ARGS" >> $GITHUB_ENV
|
||||
- name: Get Depot Tools
|
||||
timeout-minutes: 5
|
||||
run: |
|
||||
git clone --filter=tree:0 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
|
||||
SEDOPTION="-i"
|
||||
if [ "`uname`" = "Darwin" ]; then
|
||||
SEDOPTION="-i ''"
|
||||
fi
|
||||
|
||||
# remove ninjalog_uploader_wrapper.py from autoninja since we don't use it and it causes problems
|
||||
sed $SEDOPTION '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
|
||||
|
||||
# Ensure depot_tools does not update.
|
||||
test -d depot_tools && cd depot_tools
|
||||
touch .disable_auto_update
|
||||
- name: Add Depot Tools to PATH
|
||||
run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
|
||||
- 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: Generate DEPS Hash
|
||||
run: |
|
||||
node src/electron/script/generate-deps-hash.js
|
||||
@@ -150,24 +138,26 @@ jobs:
|
||||
echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
|
||||
echo "CACHE_PATH=$DEPSHASH.tar" >> $GITHUB_ENV
|
||||
- name: Restore src cache via AZCopy
|
||||
if: ${{ inputs.target-platform == 'macos' }}
|
||||
if: ${{ inputs.target-platform != 'linux' }}
|
||||
uses: ./src/electron/.github/actions/restore-cache-azcopy
|
||||
with:
|
||||
target-platform: ${{ inputs.target-platform }}
|
||||
- name: Restore src cache via AKS
|
||||
if: ${{ inputs.target-platform == 'linux' }}
|
||||
uses: ./src/electron/.github/actions/restore-cache-aks
|
||||
- name: Checkout src via gclient sync
|
||||
if: ${{ inputs.target-platform == 'win' }}
|
||||
uses: ./src/electron/.github/actions/checkout
|
||||
with:
|
||||
use-cache: 'false'
|
||||
- name: Checkout Electron
|
||||
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
|
||||
with:
|
||||
path: src/electron
|
||||
fetch-depth: 0
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Install Build Tools
|
||||
uses: ./src/electron/.github/actions/install-build-tools
|
||||
- name: Fix Sync
|
||||
if: ${{ inputs.target-platform != 'linux' }}
|
||||
uses: ./src/electron/.github/actions/fix-sync
|
||||
with:
|
||||
target-platform: ${{ inputs.target-platform }}
|
||||
env:
|
||||
ELECTRON_DEPOT_TOOLS_DISABLE_LOG: true
|
||||
- name: Init Build Tools
|
||||
run: |
|
||||
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} --import ${{ inputs.gn-build-type }} --target-cpu ${{ inputs.target-arch }}
|
||||
@@ -180,9 +170,6 @@ jobs:
|
||||
echo "DEPSHASH=$(cat src/electron/.depshash)" >> $GITHUB_ENV
|
||||
- name: Add CHROMIUM_BUILDTOOLS_PATH to 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
|
||||
|
||||
@@ -65,7 +65,9 @@ jobs:
|
||||
sudo rm -rf $TMPDIR/del-target
|
||||
- name: Check disk space after freeing up space
|
||||
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
|
||||
uses: ./src/electron/.github/actions/install-build-tools
|
||||
- name: Enable windows toolchain
|
||||
@@ -81,9 +83,13 @@ jobs:
|
||||
- name: Restore src cache via AZCopy
|
||||
if: ${{ inputs.target-platform == 'macos' }}
|
||||
uses: ./src/electron/.github/actions/restore-cache-azcopy
|
||||
with:
|
||||
target-platform: ${{ inputs.target-platform }}
|
||||
- name: Restore src cache via AKS
|
||||
if: ${{ inputs.target-platform == 'linux' || inputs.target-platform == 'win' }}
|
||||
uses: ./src/electron/.github/actions/restore-cache-aks
|
||||
with:
|
||||
target-platform: ${{ inputs.target-platform }}
|
||||
- name: Run Electron Only Hooks
|
||||
run: |
|
||||
echo "solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]" > tmpgclient
|
||||
|
||||
@@ -27,8 +27,8 @@ on:
|
||||
default: false
|
||||
|
||||
concurrency:
|
||||
group: electron-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ inputs.is-asan }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !endsWith(github.ref, '-x-y') }}
|
||||
group: electron-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ inputs.is-asan }}-${{ github.ref_protected == true && github.run_id || github.ref }}
|
||||
cancel-in-progress: ${{ github.ref_protected != true }}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -36,6 +36,8 @@ permissions:
|
||||
pull-requests: read
|
||||
|
||||
env:
|
||||
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
|
||||
CHROMIUM_GIT_COOKIE_WINDOWS_STRING: ${{ secrets.CHROMIUM_GIT_COOKIE_WINDOWS_STRING }}
|
||||
ELECTRON_OUT_DIR: Default
|
||||
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
|
||||
|
||||
@@ -74,6 +76,7 @@ jobs:
|
||||
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
|
||||
if: ${{ inputs.target-platform == 'win' }}
|
||||
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6
|
||||
@@ -120,6 +123,8 @@ jobs:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: 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: |
|
||||
|
||||
@@ -27,10 +27,11 @@ on:
|
||||
default: testing
|
||||
|
||||
concurrency:
|
||||
group: electron-node-nan-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !endsWith(github.ref, '-x-y') }}
|
||||
group: electron-node-nan-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref_protected == true && github.run_id || github.ref }}
|
||||
cancel-in-progress: ${{ github.ref_protected != true }}
|
||||
|
||||
env:
|
||||
CHROMIUM_GIT_COOKIE: ${{ secrets.CHROMIUM_GIT_COOKIE }}
|
||||
ELECTRON_OUT_DIR: Default
|
||||
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
|
||||
|
||||
@@ -38,7 +39,7 @@ jobs:
|
||||
node-tests:
|
||||
name: Run Node.js Tests
|
||||
runs-on: electron-arc-linux-amd64-8core
|
||||
timeout-minutes: 20
|
||||
timeout-minutes: 30
|
||||
env:
|
||||
TARGET_ARCH: ${{ inputs.target-arch }}
|
||||
BUILD_TYPE: linux
|
||||
@@ -50,6 +51,8 @@ jobs:
|
||||
path: src/electron
|
||||
fetch-depth: 0
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- 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: Init Build Tools
|
||||
@@ -57,15 +60,6 @@ jobs:
|
||||
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} --import ${{ inputs.gn-build-type }} --target-cpu ${{ inputs.target-arch }}
|
||||
- name: Install Dependencies
|
||||
uses: ./src/electron/.github/actions/install-dependencies
|
||||
- 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
|
||||
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
|
||||
with:
|
||||
@@ -99,7 +93,7 @@ jobs:
|
||||
nan-tests:
|
||||
name: Run Nan Tests
|
||||
runs-on: electron-arc-linux-amd64-4core
|
||||
timeout-minutes: 20
|
||||
timeout-minutes: 30
|
||||
env:
|
||||
TARGET_ARCH: ${{ inputs.target-arch }}
|
||||
BUILD_TYPE: linux
|
||||
@@ -111,6 +105,8 @@ jobs:
|
||||
path: src/electron
|
||||
fetch-depth: 0
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- 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: Init Build Tools
|
||||
@@ -118,15 +114,6 @@ jobs:
|
||||
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }}
|
||||
- name: Install Dependencies
|
||||
uses: ./src/electron/.github/actions/install-dependencies
|
||||
- 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
|
||||
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16
|
||||
with:
|
||||
|
||||
4
.github/workflows/pull-request-labeled.yml
vendored
4
.github/workflows/pull-request-labeled.yml
vendored
@@ -15,12 +15,12 @@ jobs:
|
||||
- name: Trigger Slack workflow
|
||||
uses: slackapi/slack-github-action@37ebaef184d7626c5f204ab8d3baff4262dd30f0 # v1.27.0
|
||||
with:
|
||||
webhook: ${{ secrets.BACKPORT_REQUESTED_SLACK_WEBHOOK_URL }}
|
||||
webhook-type: webhook-trigger
|
||||
payload: |
|
||||
{
|
||||
"url": "${{ github.event.pull_request.html_url }}"
|
||||
}
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.BACKPORT_REQUESTED_SLACK_WEBHOOK_URL }}
|
||||
pull-request-labeled-deprecation-review-complete:
|
||||
name: deprecation-review/complete label added
|
||||
if: github.event.label.name == 'deprecation-review/complete ✅'
|
||||
|
||||
78
.github/workflows/update_appveyor_image.yml
vendored
78
.github/workflows/update_appveyor_image.yml
vendored
@@ -1,78 +0,0 @@
|
||||
name: Update AppVeyor Image
|
||||
|
||||
# Run chron daily Mon-Fri
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 8 * * 1-5' # runs 8:00 every business day (see https://crontab.guru)
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
bake-appveyor-image:
|
||||
name: Bake AppVeyor Image
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@384fd19694fe7b6dcc9a684746c6976ad78228ae # v1.1.1
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.APPVEYOR_UPDATER_GH_APP_CREDS }}
|
||||
- name: Checkout
|
||||
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||
with:
|
||||
node-version: 20.11.x
|
||||
- name: Yarn install
|
||||
run: |
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
- name: Set Repo for Commit
|
||||
run: git config --global --add safe.directory $GITHUB_WORKSPACE
|
||||
- name: Check AppVeyor Image
|
||||
env:
|
||||
APPVEYOR_TOKEN: ${{ secrets.APPVEYOR_TOKEN }}
|
||||
run: |
|
||||
node ./script/prepare-appveyor
|
||||
if [ -f ./image_version.txt ]; then
|
||||
echo "APPVEYOR_IMAGE_VERSION="$(cat image_version.txt)"" >> $GITHUB_ENV
|
||||
rm image_version.txt
|
||||
fi
|
||||
- name: (Optionally) Update Appveyor Image
|
||||
if: ${{ env.APPVEYOR_IMAGE_VERSION }}
|
||||
uses: mikefarah/yq@bbdd97482f2d439126582a59689eb1c855944955 # v4.44.3
|
||||
with:
|
||||
cmd: |
|
||||
yq '.image = "${{ env.APPVEYOR_IMAGE_VERSION }}"' "appveyor.yml" > "appveyor2.yml"
|
||||
yq '.image = "${{ env.APPVEYOR_IMAGE_VERSION }}"' "appveyor-woa.yml" > "appveyor-woa2.yml"
|
||||
- name: (Optionally) Generate Commit Diff
|
||||
if: ${{ env.APPVEYOR_IMAGE_VERSION }}
|
||||
run: |
|
||||
diff -w -B appveyor.yml appveyor2.yml > appveyor.diff || true
|
||||
patch -f appveyor.yml < appveyor.diff
|
||||
rm appveyor2.yml appveyor.diff
|
||||
git add appveyor.yml
|
||||
- name: (Optionally) Generate Commit Diff for WOA
|
||||
if: ${{ env.APPVEYOR_IMAGE_VERSION }}
|
||||
run: |
|
||||
diff -w -B appveyor-woa.yml appveyor-woa2.yml > appveyor-woa.diff || true
|
||||
patch -f appveyor-woa.yml < appveyor-woa.diff
|
||||
rm appveyor-woa2.yml appveyor-woa.diff
|
||||
git add appveyor-woa.yml
|
||||
- name: (Optionally) Commit to Branch
|
||||
if: ${{ env.APPVEYOR_IMAGE_VERSION }}
|
||||
uses: dsanders11/github-app-commit-action@43de6da2f4d927e997c0784c7a0b61bd19ad6aac # v1.5.0
|
||||
with:
|
||||
message: 'build: update appveyor image to latest version'
|
||||
ref: bump-appveyor-image
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
- name: (Optionally) Create Pull Request
|
||||
if: ${{ env.APPVEYOR_IMAGE_VERSION }}
|
||||
run: |
|
||||
printf "This PR updates appveyor.yml to the latest baked image, ${{ env.APPVEYOR_IMAGE_VERSION }}.\n\nNotes: none" | gh pr create --head bump-appveyor-image --label no-backport --label semver/none --title 'build: update appveyor image to latest version' --body-file=-
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
|
||||
88
.github/workflows/windows-publish.yml
vendored
Normal file
88
.github/workflows/windows-publish.yml
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
name: Publish Windows
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
build-image-sha:
|
||||
type: string
|
||||
description: 'SHA for electron/build image'
|
||||
default: 'bc2f48b2415a670de18d13605b1cf0eb5fdbaae1'
|
||||
required: true
|
||||
upload-to-storage:
|
||||
description: 'Uploads to Azure storage'
|
||||
required: false
|
||||
default: '1'
|
||||
type: string
|
||||
run-windows-publish:
|
||||
description: 'Run the publish jobs vs just the build jobs'
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
checkout-windows:
|
||||
runs-on: electron-arc-linux-amd64-32core
|
||||
container:
|
||||
image: ghcr.io/electron/build:${{ inputs.build-image-sha }}
|
||||
options: --user root --device /dev/fuse --cap-add SYS_ADMIN
|
||||
volumes:
|
||||
- /mnt/win-cache:/mnt/win-cache
|
||||
- /var/run/sas:/var/run/sas
|
||||
env:
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_win=True'
|
||||
TARGET_OS: 'win'
|
||||
ELECTRON_DEPOT_TOOLS_WIN_TOOLCHAIN: '1'
|
||||
outputs:
|
||||
build-image-sha: ${{ inputs.build-image-sha }}
|
||||
steps:
|
||||
- name: Checkout Electron
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
|
||||
with:
|
||||
path: src/electron
|
||||
fetch-depth: 0
|
||||
- name: Checkout & Sync & Save
|
||||
uses: ./src/electron/.github/actions/checkout
|
||||
with:
|
||||
generate-sas-token: 'true'
|
||||
target-platform: win
|
||||
|
||||
publish-x64-win:
|
||||
uses: ./.github/workflows/pipeline-segment-electron-build.yml
|
||||
needs: checkout-windows
|
||||
with:
|
||||
environment: production-release
|
||||
build-runs-on: electron-arc-windows-amd64-16core
|
||||
target-platform: win
|
||||
target-arch: x64
|
||||
is-release: true
|
||||
gn-build-type: release
|
||||
generate-symbols: true
|
||||
upload-to-storage: ${{ inputs.upload-to-storage }}
|
||||
secrets: inherit
|
||||
|
||||
publish-arm64-win:
|
||||
uses: ./.github/workflows/pipeline-segment-electron-build.yml
|
||||
needs: checkout-windows
|
||||
with:
|
||||
environment: production-release
|
||||
build-runs-on: electron-arc-windows-amd64-16core
|
||||
target-platform: win
|
||||
target-arch: arm64
|
||||
is-release: true
|
||||
gn-build-type: release
|
||||
generate-symbols: true
|
||||
upload-to-storage: ${{ inputs.upload-to-storage }}
|
||||
secrets: inherit
|
||||
|
||||
publish-x86-win:
|
||||
uses: ./.github/workflows/pipeline-segment-electron-build.yml
|
||||
needs: checkout-windows
|
||||
with:
|
||||
environment: production-release
|
||||
build-runs-on: electron-arc-windows-amd64-16core
|
||||
target-platform: win
|
||||
target-arch: x86
|
||||
is-release: true
|
||||
gn-build-type: release
|
||||
generate-symbols: true
|
||||
upload-to-storage: ${{ inputs.upload-to-storage }}
|
||||
secrets: inherit
|
||||
3
BUILD.gn
3
BUILD.gn
@@ -427,6 +427,7 @@ source_set("electron_lib") {
|
||||
"chromium_src:chrome_spellchecker",
|
||||
"shell/common:mojo",
|
||||
"shell/common:plugin",
|
||||
"shell/common:web_contents_utility",
|
||||
"shell/services/node/public/mojom",
|
||||
"//base:base_static",
|
||||
"//base/allocator:buildflags",
|
||||
@@ -1230,7 +1231,7 @@ if (is_mac) {
|
||||
"//components/crash/core/app:run_as_crashpad_handler",
|
||||
]
|
||||
|
||||
ldflags = []
|
||||
ldflags = [ "/DELAYLOAD:ffmpeg.dll" ]
|
||||
|
||||
libs = [
|
||||
"comctl32.lib",
|
||||
|
||||
4
DEPS
4
DEPS
@@ -2,9 +2,9 @@ gclient_gn_args_from = 'src'
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'132.0.6834.83',
|
||||
'132.0.6834.210',
|
||||
'node_version':
|
||||
'v20.18.1',
|
||||
'v20.18.3',
|
||||
'nan_version':
|
||||
'e14bdcd1f72d62bca1d541b66da43130384ec213',
|
||||
'squirrel.mac_version':
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
# The config is used to bake appveyor images, not for running CI jobs.
|
||||
# The config expects the following environment variables to be set:
|
||||
# - "APPVEYOR_BAKE_IMAGE" e.g. 'electron-99.0.4767.0'. Name of the image to be baked.
|
||||
# Typically named after the Chromium version on which the image is built.
|
||||
# This can be set dynamically in the prepare-appveyor script.
|
||||
|
||||
version: 1.0.{build}
|
||||
build_cloud: electronhq-16-core
|
||||
image: base-bake-image
|
||||
environment:
|
||||
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
|
||||
ELECTRON_OUT_DIR: Default
|
||||
ELECTRON_ENABLE_STACK_DUMPING: 1
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
MOCHA_MULTI_REPORTERS: mocha-appveyor-reporter, tap
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN: 0
|
||||
PYTHONIOENCODING: UTF-8
|
||||
|
||||
# The following lines are needed when baking from a completely new image (eg MicrosoftWindowsServer:WindowsServer:2019-Datacenter:latest via image: base-windows-server2019)
|
||||
# init:
|
||||
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
# - appveyor version
|
||||
# - ps: $ErrorActionPreference = 'Stop'
|
||||
# - ps: 'Write-Host "OS Build: $((Get-CimInstance Win32_OperatingSystem).BuildNumber)"'
|
||||
|
||||
# clone_folder: '%USERPROFILE%\image-bake-scripts'
|
||||
|
||||
# clone_script:
|
||||
# - ps: Invoke-WebRequest "https://github.com/appveyor/build-images/archive/1f90d94e74c8243c909a09b994e527584dfcb838.zip" -OutFile "$env:temp\scripts.zip"
|
||||
# - ps: Expand-Archive -Path "$env:temp\scripts.zip" -DestinationPath "$env:temp\scripts" -Force
|
||||
# - ps: Copy-Item -Path "$env:temp\scripts\build-images-1f90d94e74c8243c909a09b994e527584dfcb838\scripts\Windows\*" -Destination $env:APPVEYOR_BUILD_FOLDER -Recurse
|
||||
|
||||
build_script:
|
||||
# The following lines are needed when baking from a completely new image (eg MicrosoftWindowsServer:WindowsServer:2019-Datacenter:latest via image: base-windows-server2019)
|
||||
# - ps: .\init_server.ps1
|
||||
# - ps: .\extend_system_volume.ps1
|
||||
|
||||
# # Restart VM
|
||||
# - ps: Start-Sleep -s 5; Restart-Computer
|
||||
# - ps: Start-Sleep -s 5
|
||||
|
||||
# - appveyor version
|
||||
# - ps: .\install_path_utils.ps1
|
||||
# - ps: .\install_powershell_core.ps1
|
||||
# - ps: .\install_powershell_get.ps1
|
||||
# - ps: .\install_7zip.ps1
|
||||
# - ps: .\install_chocolatey.ps1
|
||||
# - ps: .\install_webpi.ps1
|
||||
# - ps: .\install_nuget.ps1
|
||||
# - ps: .\install_pstools.ps1
|
||||
|
||||
# - ps: .\install_git.ps1
|
||||
# - ps: .\install_git_lfs.ps1
|
||||
|
||||
# # Restart VM
|
||||
# - ps: Start-Sleep -s 5; Restart-Computer
|
||||
# - ps: Start-Sleep -s 5
|
||||
# END LINES FOR COMPLETELY NEW IMAGE
|
||||
|
||||
- git config --global core.longpaths true
|
||||
- ps: >-
|
||||
if (-not (Test-Path -Path C:\projects\src)) {
|
||||
New-Item -Path C:\projects\src -ItemType Directory
|
||||
}
|
||||
- cd C:\projects\
|
||||
- git clone -q --branch=%APPVEYOR_REPO_BRANCH% https://github.com/electron/electron.git C:\projects\src\electron
|
||||
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
|
||||
- update_depot_tools.bat
|
||||
# Uncomment the following line if windows deps change
|
||||
- src\electron\script\setup-win-for-dev.bat
|
||||
- >-
|
||||
gclient config
|
||||
--name "src\electron"
|
||||
--unmanaged
|
||||
%GCLIENT_EXTRA_ARGS%
|
||||
"https://github.com/electron/electron"
|
||||
- ps: cd src\electron
|
||||
- ps: node script\generate-deps-hash.js
|
||||
- ps: $depshash = Get-Content .\.depshash -Raw
|
||||
- ps: Copy-Item -path .\.depshash -destination ..\.depshash
|
||||
- ps: cd ..\..
|
||||
- gclient sync --with_branch_heads --with_tags --nohooks
|
||||
- ps: regsvr32 /s "C:\Program Files\Microsoft Visual Studio\2022\Community\DIA SDK\bin\amd64\msdia140.dll"
|
||||
- ps: set vs2022_install="C:\Program Files\Microsoft Visual Studio\2022\Community"
|
||||
|
||||
# The following lines are needed when baking from a completely new image (eg MicrosoftWindowsServer:WindowsServer:2019-Datacenter:latest via image: base-windows-server2019)
|
||||
# # Restart VM
|
||||
# - ps: Start-Sleep -s 5; Restart-Computer
|
||||
# - ps: Start-Sleep -s 5
|
||||
|
||||
# - cd %USERPROFILE%\image-bake-scripts
|
||||
# - appveyor version
|
||||
# - ps: .\optimize_dotnet_runtime.ps1
|
||||
# - ps: .\disable_windows_background_services.ps1
|
||||
# - ps: .\enforce_windows_firewall.ps1
|
||||
# - ps: .\cleanup_windows.ps1
|
||||
# END LINES FOR COMPLETELY NEW IMAGE
|
||||
on_image_bake:
|
||||
- ps: >-
|
||||
echo "Baking image: $env:APPVEYOR_BAKE_IMAGE at dir $PWD"
|
||||
- ps: Remove-Item -Recurse -Force C:\projects\depot_tools
|
||||
- ps: Remove-Item -Recurse -Force C:\projects\src\electron
|
||||
# Uncomment these lines and set APPVEYOR_RDP_PASSWORD in project settings to enable RDP after bake is done
|
||||
# # on_finish:
|
||||
# - ps: >-
|
||||
# $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
352
appveyor-woa.yml
352
appveyor-woa.yml
@@ -1,352 +0,0 @@
|
||||
# NOTE IF CHANGING THIS FILE, ALSO APPLY THE CHANGE TO appveyor.yml
|
||||
# IF APPLICABLE!!!!
|
||||
#
|
||||
#
|
||||
# The config expects the following environment variables to be set:
|
||||
# - "GN_CONFIG" Build type. One of {'testing', 'release'}.
|
||||
# - "GN_EXTRA_ARGS" Additional gn arguments for a build config,
|
||||
# e.g. 'target_cpu="x86"' to build for a 32bit platform.
|
||||
# https://gn.googlesource.com/gn/+/main/docs/reference.md#var_target_cpu
|
||||
# Don't forget to set up "NPM_CONFIG_ARCH" and "TARGET_ARCH" accordingly
|
||||
# if you pass a custom value for 'target_cpu'.
|
||||
# - "ELECTRON_RELEASE" Set it to '1' upload binaries on success.
|
||||
# - "NPM_CONFIG_ARCH" E.g. 'x86'. Is used to build native Node.js modules.
|
||||
# Must match 'target_cpu' passed to "GN_EXTRA_ARGS" and "TARGET_ARCH" value.
|
||||
# - "TARGET_ARCH" Choose from {'ia32', 'x64', 'arm', 'arm64'}.
|
||||
# Is used in some publishing scripts, but does NOT affect the Electron binary.
|
||||
# Must match 'target_cpu' passed to "GN_EXTRA_ARGS" and "NPM_CONFIG_ARCH" value.
|
||||
# - "UPLOAD_TO_STORAGE" Set it to '1' upload a release to the Azure bucket.
|
||||
# Otherwise the release will be uploaded to the GitHub Releases.
|
||||
# (The value is only checked if "ELECTRON_RELEASE" is defined.)
|
||||
#
|
||||
# The publishing scripts expect access tokens to be defined as env vars,
|
||||
# but those are not covered here.
|
||||
#
|
||||
# AppVeyor docs on variables:
|
||||
# https://www.appveyor.com/docs/environment-variables/
|
||||
# https://www.appveyor.com/docs/build-configuration/#secure-variables
|
||||
# https://www.appveyor.com/docs/build-configuration/#custom-environment-variables
|
||||
|
||||
version: 1.0.{build}
|
||||
build_cloud: electronhq-16-core
|
||||
image: e-132.0.6824.0
|
||||
environment:
|
||||
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
|
||||
ELECTRON_OUT_DIR: Default
|
||||
ELECTRON_ENABLE_STACK_DUMPING: 1
|
||||
ELECTRON_ALSO_LOG_TO_STDERR: 1
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
MOCHA_MULTI_REPORTERS: "@marshallofsound/mocha-appveyor-reporter, mocha-junit-reporter, tap"
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN: 1
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN_BASE_URL: "https://dev-cdn.electronjs.org/windows-toolchains/_"
|
||||
GYP_MSVS_HASH_7393122652: 3ba76c5c20
|
||||
PYTHONIOENCODING: UTF-8
|
||||
|
||||
matrix:
|
||||
|
||||
- job_name: Build Arm on X64 Windows
|
||||
- job_name: Test On Windows On Arm Hardware 1
|
||||
job_depends_on: Build Arm on X64 Windows
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: base-woa
|
||||
APPVEYOR_BUILD_WORKER_CLOUD: electronhq-woa
|
||||
shard: 1
|
||||
- job_name: Test On Windows On Arm Hardware 2
|
||||
job_depends_on: Build Arm on X64 Windows
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: base-woa
|
||||
APPVEYOR_BUILD_WORKER_CLOUD: electronhq-woa
|
||||
shard: 2
|
||||
|
||||
clone_script:
|
||||
- ps: git clone -q $("--branch=" + $Env:APPVEYOR_REPO_BRANCH) $("https://github.com/" + $Env:APPVEYOR_REPO_NAME + ".git") $Env:APPVEYOR_BUILD_FOLDER
|
||||
- ps: if (!$Env:APPVEYOR_PULL_REQUEST_NUMBER) {$("git checkout -qf " + $Env:APPVEYOR_REPO_COMMIT)}
|
||||
- ps: if ($Env:APPVEYOR_PULL_REQUEST_NUMBER) {git fetch -q origin +refs/pull/$($Env:APPVEYOR_PULL_REQUEST_NUMBER)/head; git checkout -qf FETCH_HEAD}
|
||||
|
||||
clone_folder: C:\projects\src\electron
|
||||
|
||||
skip_branch_with_pr: true
|
||||
|
||||
# the first failed job cancels other jobs and fails entire build
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
for:
|
||||
|
||||
- matrix:
|
||||
only:
|
||||
- job_name: Build Arm on X64 Windows
|
||||
|
||||
build_script:
|
||||
# TODO: Remove --ignore-engines once WOA image is up to node 20
|
||||
- ps: |
|
||||
node script/yarn.js install --frozen-lockfile --ignore-engines
|
||||
node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER
|
||||
$env:SHOULD_SKIP_ARTIFACT_VALIDATION = "false"
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-warning "Skipping build for doc-only change"
|
||||
$env:SHOULD_SKIP_ARTIFACT_VALIDATION = "true"
|
||||
Exit-AppveyorBuild
|
||||
} else {
|
||||
$global:LASTEXITCODE = 0
|
||||
}
|
||||
- cd ..
|
||||
- ps: Write-Host "Building $env:GN_CONFIG build"
|
||||
- git config --global core.longpaths true
|
||||
- ps: >-
|
||||
if (Test-Path -Path "$pwd\depot_tools") {
|
||||
Remove-Item -Recurse -Force $pwd\depot_tools
|
||||
}
|
||||
- ps: >-
|
||||
if (Test-Path -Path "$pwd\build-tools") {
|
||||
Remove-Item -Recurse -Force $pwd\build-tools
|
||||
}
|
||||
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
- ps: New-Item -Name depot_tools\.disable_auto_update -ItemType File
|
||||
- depot_tools\bootstrap\win_tools.bat
|
||||
- ps: |
|
||||
Set-Content -Path $pwd\depot_tools\build_telemetry.cfg -Value '{"user": "info@electronjs.org", "status": "opt-out", "countdown": 10, "version": 1}'
|
||||
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
|
||||
- ps: >-
|
||||
if (Test-Path -Path "$pwd\src\electron") {
|
||||
Remove-Item -Recurse -Force $pwd\src\electron
|
||||
}
|
||||
- git clone https://github.com/electron/build-tools.git
|
||||
- cd build-tools
|
||||
- npx yarn --ignore-engines
|
||||
- mkdir third_party
|
||||
- ps: >-
|
||||
node -e "require('./src/utils/reclient.js').downloadAndPrepare({})"
|
||||
- ps: $env:RECLIENT_HELPER = node -p "require('./src/utils/reclient.js').helperPath({})"
|
||||
- ps: >-
|
||||
& $env:RECLIENT_HELPER login
|
||||
- ps: >-
|
||||
$env:RBE_service = node -e "console.log(require('./src/utils/reclient.js').serviceAddress)"
|
||||
- ps: >-
|
||||
$env:RBE_credentials_helper = $env:RECLIENT_HELPER
|
||||
- ps: >-
|
||||
$env:RBE_credentials_helper_args = "print"
|
||||
- ps: >-
|
||||
if ($env:ELECTRON_RBE_JWT -eq '') {
|
||||
$env:RBE_fail_early_min_action_count = "0"
|
||||
$env:RBE_fail_early_min_fallback_ratio = "0"
|
||||
}
|
||||
- cd ..\..
|
||||
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -ne 'release') {
|
||||
$env:NINJA_STATUS="[%r processes, %f/%t @ %o/s : %es] "
|
||||
}
|
||||
- gclient config --name "src\electron" --unmanaged %GCLIENT_EXTRA_ARGS% "https://github.com/electron/electron"
|
||||
# Patches are applied in the image bake. Check depshash to see if patches have changed.
|
||||
- ps: $env:RUN_GCLIENT_SYNC="false"
|
||||
- ps: $depshash_baked = Get-Content .\src\.depshash -Raw
|
||||
- ps: cd src\electron
|
||||
- ps: node script\generate-deps-hash.js
|
||||
- ps: $depshash = Get-Content .\.depshash -Raw
|
||||
- ps: cd ..\..
|
||||
- ps: >-
|
||||
if ($depshash_baked -ne $depshash) {
|
||||
$env:RUN_GCLIENT_SYNC="true"
|
||||
}
|
||||
- if "%RUN_GCLIENT_SYNC%"=="true" ( gclient sync --with_branch_heads --with_tags ) else ( gclient runhooks )
|
||||
- cd src
|
||||
- ps: $env:PATH="$pwd\third_party\ninja;$env:PATH"
|
||||
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
|
||||
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") use_remoteexec=true %GN_EXTRA_ARGS% "
|
||||
- gn check out/Default //electron:electron_lib
|
||||
- gn check out/Default //electron:electron_app
|
||||
- gn check out/Default //electron/shell/common:mojo
|
||||
- gn check out/Default //electron/shell/common:plugin
|
||||
- autoninja -j 300 -C out/Default electron:electron_app
|
||||
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
|
||||
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") use_remoteexec=true %GN_EXTRA_ARGS%"
|
||||
- autoninja -C out/ffmpeg electron:electron_ffmpeg_zip
|
||||
- autoninja -C out/Default electron:electron_dist_zip
|
||||
- gn desc out/Default v8:run_mksnapshot_default args > out/Default/default_mksnapshot_args
|
||||
# Remove unused args from mksnapshot_args
|
||||
- ps: >-
|
||||
Get-Content out/Default/default_mksnapshot_args | Where-Object { -not $_.Contains('--turbo-profiling-input') -And -not $_.Contains('builtins-pgo') } | Set-Content out/Default/mksnapshot_args
|
||||
- autoninja -C out/Default electron:electron_mksnapshot_zip
|
||||
- cd out\Default
|
||||
- 7z a mksnapshot.zip mksnapshot_args gen\v8\embedded.S
|
||||
- cd ..\..
|
||||
- autoninja -C out/Default electron:hunspell_dictionaries_zip
|
||||
- autoninja -C out/Default electron:electron_chromedriver_zip
|
||||
- autoninja -C out/Default electron:node_headers
|
||||
- ps: >-
|
||||
Get-CimInstance -Namespace root\cimv2 -Class Win32_product | Select vendor, description, @{l='install_location';e='InstallLocation'}, @{l='install_date';e='InstallDate'}, @{l='install_date_2';e='InstallDate2'}, caption, version, name, @{l='sku_number';e='SKUNumber'} | ConvertTo-Json | Out-File -Encoding utf8 -FilePath .\installed_software.json
|
||||
- python3 electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
|
||||
- 7z a node_headers.zip out\Default\gen\node_headers
|
||||
- 7z a nan.zip third_party\nan
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
# Needed for msdia140.dll on 64-bit windows
|
||||
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
|
||||
}
|
||||
- if "%GN_CONFIG%"=="release" ( autoninja -C out/Default electron:electron_symbols )
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
python3 electron\script\zip-symbols.py
|
||||
appveyor-retry appveyor PushArtifact out/Default/symbols.zip
|
||||
} else {
|
||||
# It's useful to have pdb files when debugging testing builds that are
|
||||
# built on CI.
|
||||
7z a pdb.zip out\Default\*.pdb
|
||||
}
|
||||
- ps: |
|
||||
$manifest_file = "electron/script/zip_manifests/dist_zip.win.$env:TARGET_ARCH.manifest"
|
||||
python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip $manifest_file
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Zip contains files not listed in the manifest $manifest_file"
|
||||
}
|
||||
- ps: |
|
||||
cd C:\projects\src
|
||||
$missing_artifacts = $false
|
||||
if ($env:SHOULD_SKIP_ARTIFACT_VALIDATION -eq 'true') {
|
||||
Write-warning "Skipping artifact validation for doc-only $env:APPVEYOR_PROJECT_NAME"
|
||||
} else {
|
||||
$artifacts_to_validate = 'dist.zip','windows_toolchain_profile.json','chromedriver.zip','ffmpeg.zip','node_headers.zip','mksnapshot.zip','electron.lib','hunspell_dictionaries.zip','nan.zip'
|
||||
foreach($artifact_name in $artifacts_to_validate) {
|
||||
if ($artifact_name -eq 'ffmpeg.zip') {
|
||||
$artifact_file = "out\ffmpeg\ffmpeg.zip"
|
||||
} elseif (
|
||||
$artifact_name -eq 'node_headers.zip') {
|
||||
$artifact_file = $artifact_name
|
||||
} elseif (
|
||||
$artifact_name -eq 'nan.zip') {
|
||||
$artifact_file = $artifact_name
|
||||
} else {
|
||||
$artifact_file = "out\Default\$artifact_name"
|
||||
}
|
||||
if (-not(Test-Path $artifact_file)) {
|
||||
Write-warning "$artifact_name is missing and cannot be added to artifacts"
|
||||
$missing_artifacts = $true
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($missing_artifacts) {
|
||||
throw "Build failed due to missing artifacts"
|
||||
}
|
||||
|
||||
deploy_script:
|
||||
- cd electron
|
||||
- ps: >-
|
||||
if (Test-Path Env:\ELECTRON_RELEASE) {
|
||||
if (Test-Path Env:\UPLOAD_TO_STORAGE) {
|
||||
Write-Output "Uploading Electron release distribution to azure"
|
||||
& python3 script\release\uploaders\upload.py --verbose --upload_to_storage
|
||||
} else {
|
||||
Write-Output "Uploading Electron release distribution to github releases"
|
||||
& python3 script\release\uploaders\upload.py --verbose
|
||||
}
|
||||
}
|
||||
on_finish:
|
||||
# Uncomment this lines to enable RDP
|
||||
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
- cd C:\projects\src
|
||||
- if exist out\Default\windows_toolchain_profile.json ( appveyor-retry appveyor PushArtifact out\Default\windows_toolchain_profile.json )
|
||||
- if exist out\Default\dist.zip (appveyor-retry appveyor PushArtifact out\Default\dist.zip)
|
||||
- if exist out\Default\chromedriver.zip (appveyor-retry appveyor PushArtifact out\Default\chromedriver.zip)
|
||||
- if exist out\ffmpeg\ffmpeg.zip (appveyor-retry appveyor PushArtifact out\ffmpeg\ffmpeg.zip)
|
||||
- if exist node_headers.zip (appveyor-retry appveyor PushArtifact node_headers.zip)
|
||||
- if exist nan.zip (appveyor-retry appveyor PushArtifact nan.zip)
|
||||
- if exist out\Default\mksnapshot.zip (appveyor-retry appveyor PushArtifact out\Default\mksnapshot.zip)
|
||||
- if exist out\Default\hunspell_dictionaries.zip (appveyor-retry appveyor PushArtifact out\Default\hunspell_dictionaries.zip)
|
||||
- if exist out\Default\electron.lib (appveyor-retry appveyor PushArtifact out\Default\electron.lib)
|
||||
- ps: >-
|
||||
if ((Test-Path "pdb.zip") -And ($env:GN_CONFIG -ne 'release')) {
|
||||
appveyor-retry appveyor PushArtifact pdb.zip
|
||||
}
|
||||
- matrix:
|
||||
only:
|
||||
- job_name: Test On Windows On Arm Hardware 1
|
||||
- job_name: Test On Windows On Arm Hardware 2
|
||||
|
||||
environment:
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: C:\projects\src\electron\junit
|
||||
MOCHA_MULTI_REPORTERS: "@marshallofsound/mocha-appveyor-reporter, mocha-junit-reporter, tap"
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
|
||||
DD_ENV: ci
|
||||
DD_SERVICE: electron
|
||||
DD_CIVISIBILITY_LOGS_ENABLED: true
|
||||
DD_GIT_REPOSITORY_URL: "https://github.com/electron/electron.git"
|
||||
|
||||
build_script:
|
||||
- ps: |
|
||||
node script/yarn.js install --frozen-lockfile --ignore-engines
|
||||
node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-warning "Skipping build for doc only change"
|
||||
Exit-AppveyorBuild
|
||||
} else {
|
||||
$global:LASTEXITCODE = 0
|
||||
}
|
||||
- ps: Invoke-WebRequest -Uri "https://github.com/DataDog/datadog-ci/releases/latest/download/datadog-ci_win-x64" -OutFile "C:\projects\src\electron\datadog-ci.exe"
|
||||
- cd ..
|
||||
- mkdir out\Default
|
||||
- cd ..
|
||||
- ps: |
|
||||
# Download build artifacts
|
||||
$apiUrl = 'https://ci.appveyor.com/api'
|
||||
$build_info = Invoke-RestMethod -Method Get -Uri "$apiUrl/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/builds/$env:APPVEYOR_BUILD_ID"
|
||||
$artifacts_to_download = @('dist.zip','ffmpeg.zip','node_headers.zip','electron.lib', 'nan.zip')
|
||||
foreach ($job in $build_info.build.jobs) {
|
||||
if ($job.name -eq "Build Arm on X64 Windows") {
|
||||
$jobId = $job.jobId
|
||||
foreach($artifact_name in $artifacts_to_download) {
|
||||
if ($artifact_name -eq 'electron.lib') {
|
||||
$outfile = "src\out\Default\$artifact_name"
|
||||
} else {
|
||||
$outfile = $artifact_name
|
||||
}
|
||||
Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts/$artifact_name" -OutFile $outfile
|
||||
}
|
||||
# Uncomment the following lines to download the pdb.zip to show real stacktraces when crashes happen during testing
|
||||
Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts/pdb.zip" -OutFile pdb.zip
|
||||
7z x -y -osrc pdb.zip
|
||||
}
|
||||
}
|
||||
- ps: |
|
||||
$out_default_zips = @('dist.zip')
|
||||
foreach($zip_name in $out_default_zips) {
|
||||
7z x -y -osrc\out\Default $zip_name
|
||||
}
|
||||
- ps: 7z x -y -osrc\out\ffmpeg ffmpeg.zip
|
||||
- ps: 7z x -y -osrc node_headers.zip
|
||||
- ps: 7z x -y -osrc nan.zip
|
||||
|
||||
test_script:
|
||||
# Workaround for https://github.com/appveyor/ci/issues/2420
|
||||
- set "PATH=%PATH%;C:\Program Files\Git\mingw64\libexec\git-core"
|
||||
- ps: |
|
||||
cd src
|
||||
New-Item .\out\Default\gen\node_headers\Release -Type directory
|
||||
Copy-Item -path .\out\Default\electron.lib -destination .\out\Default\gen\node_headers\Release\node.lib
|
||||
- set npm_config_nodedir=%cd%\out\Default\gen\node_headers
|
||||
- set npm_config_arch=arm64
|
||||
- cd electron
|
||||
# Explicitly set npm_config_arch because the .env doesn't persist
|
||||
- ps: >-
|
||||
if ($env:TARGET_ARCH -eq 'ia32') {
|
||||
$env:npm_config_arch = "ia32"
|
||||
}
|
||||
- ps: $env:tests_files=node script\split-tests $env:shard 2
|
||||
- echo "Running shard %shard% specs %tests_files%"
|
||||
- echo Running main test suite & node script/yarn test --runners=main --enable-logging --disable-features=CalculateNativeWinOcclusion --files %tests_files%
|
||||
- cd ..
|
||||
- echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
|
||||
|
||||
on_finish:
|
||||
# Uncomment these lines to enable RDP
|
||||
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
- if exist electron\junit\test-results-main.xml ( appveyor-retry appveyor PushArtifact electron\junit\test-results-main.xml )
|
||||
- ps: |
|
||||
if ($env:DD_API_KEY) {
|
||||
$env:DD_GIT_COMMIT_SHA = $env:APPVEYOR_REPO_COMMIT
|
||||
$env:DD_GIT_BRANCH = $env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH
|
||||
$env:DD_TAGS = "os.architecture:$env:TARGET_ARCH,os.family:windows,os.platform:win32"
|
||||
if (Test-Path -Path "C:\projects\src\electron\junit\test-results-main.xml") {
|
||||
C:\projects\src\electron\datadog-ci.exe junit upload --verbose C:\projects\src\electron\junit\test-results-main.xml
|
||||
}
|
||||
}
|
||||
350
appveyor.yml
350
appveyor.yml
@@ -1,350 +0,0 @@
|
||||
# NOTE IF CHANGING THIS FILE, ALSO APPLY THE CHANGE TO appveyor-woa.yml
|
||||
# IF APPLICABLE!!!!
|
||||
#
|
||||
#
|
||||
# The config expects the following environment variables to be set:
|
||||
# - "GN_CONFIG" Build type. One of {'testing', 'release'}.
|
||||
# - "GN_EXTRA_ARGS" Additional gn arguments for a build config,
|
||||
# e.g. 'target_cpu="x86"' to build for a 32bit platform.
|
||||
# https://gn.googlesource.com/gn/+/main/docs/reference.md#var_target_cpu
|
||||
# Don't forget to set up "NPM_CONFIG_ARCH" and "TARGET_ARCH" accordingly
|
||||
# if you pass a custom value for 'target_cpu'.
|
||||
# - "ELECTRON_RELEASE" Set it to '1' upload binaries on success.
|
||||
# - "NPM_CONFIG_ARCH" E.g. 'x86'. Is used to build native Node.js modules.
|
||||
# Must match 'target_cpu' passed to "GN_EXTRA_ARGS" and "TARGET_ARCH" value.
|
||||
# - "TARGET_ARCH" Choose from {'ia32', 'x64', 'arm', 'arm64'}.
|
||||
# Is used in some publishing scripts, but does NOT affect the Electron binary.
|
||||
# Must match 'target_cpu' passed to "GN_EXTRA_ARGS" and "NPM_CONFIG_ARCH" value.
|
||||
# - "UPLOAD_TO_STORAGE" Set it to '1' upload a release to the Azure bucket.
|
||||
# Otherwise the release will be uploaded to the GitHub Releases.
|
||||
# (The value is only checked if "ELECTRON_RELEASE" is defined.)
|
||||
#
|
||||
# The publishing scripts expect access tokens to be defined as env vars,
|
||||
# but those are not covered here.
|
||||
#
|
||||
# AppVeyor docs on variables:
|
||||
# https://www.appveyor.com/docs/environment-variables/
|
||||
# https://www.appveyor.com/docs/build-configuration/#secure-variables
|
||||
# https://www.appveyor.com/docs/build-configuration/#custom-environment-variables
|
||||
|
||||
version: 1.0.{build}
|
||||
build_cloud: electronhq-16-core
|
||||
image: e-132.0.6824.0
|
||||
environment:
|
||||
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
|
||||
ELECTRON_OUT_DIR: Default
|
||||
ELECTRON_ENABLE_STACK_DUMPING: 1
|
||||
ELECTRON_ALSO_LOG_TO_STDERR: 1
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
MOCHA_MULTI_REPORTERS: "@marshallofsound/mocha-appveyor-reporter, mocha-junit-reporter, tap"
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN: 1
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN_BASE_URL: "https://dev-cdn.electronjs.org/windows-toolchains/_"
|
||||
GYP_MSVS_HASH_7393122652: 3ba76c5c20
|
||||
PYTHONIOENCODING: UTF-8
|
||||
|
||||
matrix:
|
||||
|
||||
- job_name: Build
|
||||
- job_name: Test 1
|
||||
job_depends_on: Build
|
||||
shard: 1
|
||||
- job_name: Test 2
|
||||
job_depends_on: Build
|
||||
shard: 2
|
||||
|
||||
clone_script:
|
||||
- ps: git clone -q $("--branch=" + $Env:APPVEYOR_REPO_BRANCH) $("https://github.com/" + $Env:APPVEYOR_REPO_NAME + ".git") $Env:APPVEYOR_BUILD_FOLDER
|
||||
- ps: if (!$Env:APPVEYOR_PULL_REQUEST_NUMBER) {$("git checkout -qf " + $Env:APPVEYOR_REPO_COMMIT)}
|
||||
- ps: if ($Env:APPVEYOR_PULL_REQUEST_NUMBER) {git fetch -q origin +refs/pull/$($Env:APPVEYOR_PULL_REQUEST_NUMBER)/head; git checkout -qf FETCH_HEAD}
|
||||
|
||||
clone_folder: C:\projects\src\electron
|
||||
|
||||
skip_branch_with_pr: true
|
||||
|
||||
# the first failed job cancels other jobs and fails entire build
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
for:
|
||||
|
||||
- matrix:
|
||||
only:
|
||||
- job_name: Build
|
||||
|
||||
build_script:
|
||||
- ps: |
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER
|
||||
$env:SHOULD_SKIP_ARTIFACT_VALIDATION = "false"
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-warning "Skipping build for doc-only change"
|
||||
$env:SHOULD_SKIP_ARTIFACT_VALIDATION = "true"
|
||||
Exit-AppveyorBuild
|
||||
} else {
|
||||
$global:LASTEXITCODE = 0
|
||||
}
|
||||
- cd ..
|
||||
- ps: Write-Host "Building $env:GN_CONFIG build"
|
||||
- git config --global core.longpaths true
|
||||
- ps: >-
|
||||
if (Test-Path -Path "$pwd\depot_tools") {
|
||||
Remove-Item -Recurse -Force $pwd\depot_tools
|
||||
}
|
||||
- ps: >-
|
||||
if (Test-Path -Path "$pwd\build-tools") {
|
||||
Remove-Item -Recurse -Force $pwd\build-tools
|
||||
}
|
||||
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
- ps: New-Item -Name depot_tools\.disable_auto_update -ItemType File
|
||||
- depot_tools\bootstrap\win_tools.bat
|
||||
- ps: |
|
||||
Set-Content -Path $pwd\depot_tools\build_telemetry.cfg -Value '{"user": "info@electronjs.org", "status": "opt-out", "countdown": 10, "version": 1}'
|
||||
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
|
||||
- ps: >-
|
||||
if (Test-Path -Path "$pwd\src\electron") {
|
||||
Remove-Item -Recurse -Force $pwd\src\electron
|
||||
}
|
||||
- git clone https://github.com/electron/build-tools.git
|
||||
- cd build-tools
|
||||
- npx yarn --ignore-engines
|
||||
- mkdir third_party
|
||||
- ps: >-
|
||||
node -e "require('./src/utils/reclient.js').downloadAndPrepare({})"
|
||||
- ps: $env:RECLIENT_HELPER = node -p "require('./src/utils/reclient.js').helperPath({})"
|
||||
- ps: >-
|
||||
& $env:RECLIENT_HELPER login
|
||||
- ps: >-
|
||||
$env:RBE_service = node -e "console.log(require('./src/utils/reclient.js').serviceAddress)"
|
||||
- ps: >-
|
||||
$env:RBE_credentials_helper = $env:RECLIENT_HELPER
|
||||
- ps: >-
|
||||
$env:RBE_credentials_helper_args = "print"
|
||||
- ps: >-
|
||||
if ($env:ELECTRON_RBE_JWT -eq '') {
|
||||
$env:RBE_fail_early_min_action_count = "0"
|
||||
$env:RBE_fail_early_min_fallback_ratio = "0"
|
||||
}
|
||||
- cd ..\..
|
||||
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -ne 'release') {
|
||||
$env:NINJA_STATUS="[%r processes, %f/%t @ %o/s : %es] "
|
||||
}
|
||||
- gclient config --name "src\electron" --unmanaged %GCLIENT_EXTRA_ARGS% "https://github.com/electron/electron"
|
||||
# Patches are applied in the image bake. Check depshash to see if patches have changed.
|
||||
- ps: $env:RUN_GCLIENT_SYNC="false"
|
||||
- ps: $depshash_baked = Get-Content .\src\.depshash -Raw
|
||||
- ps: cd src\electron
|
||||
- ps: node script\generate-deps-hash.js
|
||||
- ps: $depshash = Get-Content .\.depshash -Raw
|
||||
- ps: cd ..\..
|
||||
- ps: >-
|
||||
if ($depshash_baked -ne $depshash) {
|
||||
$env:RUN_GCLIENT_SYNC="true"
|
||||
}
|
||||
- if "%RUN_GCLIENT_SYNC%"=="true" ( gclient sync --with_branch_heads --with_tags ) else ( gclient runhooks )
|
||||
- cd src
|
||||
- ps: $env:PATH="$pwd\third_party\ninja;$env:PATH"
|
||||
- set BUILD_CONFIG_PATH=//electron/build/args/%GN_CONFIG%.gn
|
||||
- gn gen out/Default "--args=import(\"%BUILD_CONFIG_PATH%\") use_remoteexec=true %GN_EXTRA_ARGS% "
|
||||
- gn check out/Default //electron:electron_lib
|
||||
- gn check out/Default //electron:electron_app
|
||||
- gn check out/Default //electron/shell/common:mojo
|
||||
- gn check out/Default //electron/shell/common:plugin
|
||||
- autoninja -j 300 -C out/Default electron:electron_app
|
||||
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
|
||||
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") use_remoteexec=true %GN_EXTRA_ARGS%"
|
||||
- autoninja -C out/ffmpeg electron:electron_ffmpeg_zip
|
||||
- autoninja -C out/Default electron:electron_dist_zip
|
||||
- gn desc out/Default v8:run_mksnapshot_default args > out/Default/default_mksnapshot_args
|
||||
# Remove unused args from mksnapshot_args
|
||||
- ps: >-
|
||||
Get-Content out/Default/default_mksnapshot_args | Where-Object { -not $_.Contains('--turbo-profiling-input') -And -not $_.Contains('builtins-pgo') } | Set-Content out/Default/mksnapshot_args
|
||||
- autoninja -C out/Default electron:electron_mksnapshot_zip
|
||||
- cd out\Default
|
||||
- 7z a mksnapshot.zip mksnapshot_args gen\v8\embedded.S
|
||||
- cd ..\..
|
||||
- autoninja -C out/Default electron:hunspell_dictionaries_zip
|
||||
- autoninja -C out/Default electron:electron_chromedriver_zip
|
||||
- autoninja -C out/Default electron:node_headers
|
||||
- ps: >-
|
||||
Get-CimInstance -Namespace root\cimv2 -Class Win32_product | Select vendor, description, @{l='install_location';e='InstallLocation'}, @{l='install_date';e='InstallDate'}, @{l='install_date_2';e='InstallDate2'}, caption, version, name, @{l='sku_number';e='SKUNumber'} | ConvertTo-Json | Out-File -Encoding utf8 -FilePath .\installed_software.json
|
||||
- python3 electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
|
||||
- 7z a node_headers.zip out\Default\gen\node_headers
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
# Needed for msdia140.dll on 64-bit windows
|
||||
$env:Path += ";$pwd\third_party\llvm-build\Release+Asserts\bin"
|
||||
}
|
||||
- if "%GN_CONFIG%"=="release" ( autoninja -C out/Default electron:electron_symbols )
|
||||
- ps: >-
|
||||
if ($env:GN_CONFIG -eq 'release') {
|
||||
python3 electron\script\zip-symbols.py
|
||||
appveyor-retry appveyor PushArtifact out/Default/symbols.zip
|
||||
} else {
|
||||
# It's useful to have pdb files when debugging testing builds that are
|
||||
# built on CI.
|
||||
7z a pdb.zip out\Default\*.pdb
|
||||
}
|
||||
- ps: |
|
||||
if ($env:TARGET_ARCH -eq 'ia32') {
|
||||
$env:MANIFEST_ARCH = "x86"
|
||||
} else {
|
||||
$env:MANIFEST_ARCH = $env:TARGET_ARCH
|
||||
}
|
||||
$manifest_file = "electron/script/zip_manifests/dist_zip.win.$env:MANIFEST_ARCH.manifest"
|
||||
python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip $manifest_file
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Zip contains files not listed in the manifest $manifest_file"
|
||||
}
|
||||
- ps: |
|
||||
cd C:\projects\src
|
||||
$missing_artifacts = $false
|
||||
if ($env:SHOULD_SKIP_ARTIFACT_VALIDATION -eq 'true') {
|
||||
Write-warning "Skipping artifact validation for doc-only $env:APPVEYOR_PROJECT_NAME"
|
||||
} else {
|
||||
$artifacts_to_validate = 'dist.zip','windows_toolchain_profile.json','chromedriver.zip','ffmpeg.zip','node_headers.zip','mksnapshot.zip','electron.lib','hunspell_dictionaries.zip'
|
||||
foreach($artifact_name in $artifacts_to_validate) {
|
||||
if ($artifact_name -eq 'ffmpeg.zip') {
|
||||
$artifact_file = "out\ffmpeg\ffmpeg.zip"
|
||||
} elseif (
|
||||
$artifact_name -eq 'node_headers.zip') {
|
||||
$artifact_file = $artifact_name
|
||||
} else {
|
||||
$artifact_file = "out\Default\$artifact_name"
|
||||
}
|
||||
if (-not(Test-Path $artifact_file)) {
|
||||
Write-warning "$artifact_name is missing and cannot be added to artifacts"
|
||||
$missing_artifacts = $true
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($missing_artifacts) {
|
||||
throw "Build failed due to missing artifacts"
|
||||
}
|
||||
|
||||
deploy_script:
|
||||
- cd electron
|
||||
- ps: >-
|
||||
if (Test-Path Env:\ELECTRON_RELEASE) {
|
||||
if (Test-Path Env:\UPLOAD_TO_STORAGE) {
|
||||
Write-Output "Uploading Electron release distribution to azure"
|
||||
& python3 script\release\uploaders\upload.py --verbose --upload_to_storage
|
||||
} else {
|
||||
Write-Output "Uploading Electron release distribution to github releases"
|
||||
& python3 script\release\uploaders\upload.py --verbose
|
||||
}
|
||||
}
|
||||
on_finish:
|
||||
# Uncomment this lines to enable RDP
|
||||
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
- cd C:\projects\src
|
||||
- if exist out\Default\windows_toolchain_profile.json ( appveyor-retry appveyor PushArtifact out\Default\windows_toolchain_profile.json )
|
||||
- if exist out\Default\dist.zip (appveyor-retry appveyor PushArtifact out\Default\dist.zip)
|
||||
- if exist out\Default\chromedriver.zip (appveyor-retry appveyor PushArtifact out\Default\chromedriver.zip)
|
||||
- if exist out\ffmpeg\ffmpeg.zip (appveyor-retry appveyor PushArtifact out\ffmpeg\ffmpeg.zip)
|
||||
- if exist node_headers.zip (appveyor-retry appveyor PushArtifact node_headers.zip)
|
||||
- if exist out\Default\mksnapshot.zip (appveyor-retry appveyor PushArtifact out\Default\mksnapshot.zip)
|
||||
- if exist out\Default\hunspell_dictionaries.zip (appveyor-retry appveyor PushArtifact out\Default\hunspell_dictionaries.zip)
|
||||
- if exist out\Default\electron.lib (appveyor-retry appveyor PushArtifact out\Default\electron.lib)
|
||||
- ps: >-
|
||||
if ((Test-Path "pdb.zip") -And ($env:GN_CONFIG -ne 'release')) {
|
||||
appveyor-retry appveyor PushArtifact pdb.zip
|
||||
}
|
||||
- matrix:
|
||||
only:
|
||||
- job_name: Test 1
|
||||
- job_name: Test 2
|
||||
|
||||
environment:
|
||||
DD_ENV: ci
|
||||
DD_SERVICE: electron
|
||||
DD_CIVISIBILITY_LOGS_ENABLED: true
|
||||
DD_GIT_REPOSITORY_URL: "https://github.com/electron/electron.git"
|
||||
ELECTRON_TEST_RESULTS_DIR: C:\projects\src\electron\junit
|
||||
|
||||
init:
|
||||
- ps: |
|
||||
if ($env:RUN_TESTS -ne 'true') {
|
||||
Write-warning "Skipping tests for $env:APPVEYOR_PROJECT_NAME"; Exit-AppveyorBuild
|
||||
}
|
||||
build_script:
|
||||
- ps: |
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-warning "Skipping build for doc only change"
|
||||
Exit-AppveyorBuild
|
||||
} else {
|
||||
$global:LASTEXITCODE = 0
|
||||
}
|
||||
- npm install -g @datadog/datadog-ci
|
||||
- cd ..
|
||||
- mkdir out\Default
|
||||
- cd ..
|
||||
- ps: |
|
||||
# Download build artifacts
|
||||
$apiUrl = 'https://ci.appveyor.com/api'
|
||||
$build_info = Invoke-RestMethod -Method Get -Uri "$apiUrl/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/builds/$env:APPVEYOR_BUILD_ID"
|
||||
$artifacts_to_download = @('dist.zip','chromedriver.zip','ffmpeg.zip','node_headers.zip','mksnapshot.zip','electron.lib')
|
||||
foreach ($job in $build_info.build.jobs) {
|
||||
if ($job.name -eq "Build") {
|
||||
$jobId = $job.jobId
|
||||
foreach($artifact_name in $artifacts_to_download) {
|
||||
if ($artifact_name -eq 'electron.lib') {
|
||||
$outfile = "src\out\Default\$artifact_name"
|
||||
} else {
|
||||
$outfile = $artifact_name
|
||||
}
|
||||
Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts/$artifact_name" -OutFile $outfile
|
||||
}
|
||||
# Uncomment the following lines to download the pdb.zip to show real stacktraces when crashes happen during testing
|
||||
Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts/pdb.zip" -OutFile pdb.zip
|
||||
7z x -y -osrc pdb.zip
|
||||
}
|
||||
}
|
||||
- ps: |
|
||||
$out_default_zips = @('dist.zip','chromedriver.zip','mksnapshot.zip')
|
||||
foreach($zip_name in $out_default_zips) {
|
||||
7z x -y -osrc\out\Default $zip_name
|
||||
}
|
||||
- ps: 7z x -y -osrc\out\ffmpeg ffmpeg.zip
|
||||
- ps: 7z x -y -osrc node_headers.zip
|
||||
|
||||
test_script:
|
||||
# Workaround for https://github.com/appveyor/ci/issues/2420
|
||||
- set "PATH=%PATH%;C:\Program Files\Git\mingw64\libexec\git-core"
|
||||
- ps: |
|
||||
cd src
|
||||
New-Item .\out\Default\gen\node_headers\Release -Type directory
|
||||
Copy-Item -path .\out\Default\electron.lib -destination .\out\Default\gen\node_headers\Release\node.lib
|
||||
- cd electron
|
||||
# Explicitly set npm_config_arch because the .env doesn't persist
|
||||
- ps: >-
|
||||
if ($env:TARGET_ARCH -eq 'ia32') {
|
||||
$env:npm_config_arch = "ia32"
|
||||
}
|
||||
- ps: $env:tests_files=node script\split-tests $env:shard 2
|
||||
- echo "Running shard %shard% specs %tests_files%"
|
||||
- echo Running main test suite & node script/yarn test -- --trace-uncaught --runners=main --enable-logging --files %tests_files%
|
||||
- cd ..
|
||||
- echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
|
||||
- echo "About to verify mksnapshot"
|
||||
- echo Verifying mksnapshot & python electron\script\verify-mksnapshot.py --build-dir out\Default --source-root %cd%
|
||||
- echo "Done verifying mksnapshot"
|
||||
- echo Verifying chromedriver & python electron\script\verify-chromedriver.py --build-dir out\Default --source-root %cd%
|
||||
- echo "Done verifying chromedriver"
|
||||
|
||||
on_finish:
|
||||
# Uncomment these lines to enable RDP
|
||||
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
- if exist electron\junit\test-results-main.xml ( appveyor-retry appveyor PushArtifact electron\junit\test-results-main.xml )
|
||||
- ps: |
|
||||
if ($env:RUN_TESTS -eq 'true' -And $env:DD_API_KEY) {
|
||||
$env:DD_GIT_COMMIT_SHA = $env:APPVEYOR_REPO_COMMIT
|
||||
$env:DD_GIT_BRANCH = $env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH
|
||||
$env:DD_TAGS = "os.architecture:$env:TARGET_ARCH,os.family:windows,os.platform:win32"
|
||||
if (Test-Path -Path "C:\projects\src\electron\junit\test-results-main.xml") {
|
||||
C:\Users\appveyor\AppData\Roaming\npm\datadog-ci.ps1 junit upload --verbose C:\projects\src\electron\junit\test-results-main.xml
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,6 @@ an issue:
|
||||
### Getting started
|
||||
|
||||
* [Introduction](tutorial/introduction.md)
|
||||
* [Quick Start](tutorial/quick-start.md)
|
||||
* [Process Model](tutorial/process-model.md)
|
||||
|
||||
### Learning the basics
|
||||
|
||||
@@ -313,6 +313,12 @@ Set the default value of the `verbatim` parameter in the Node.js [`dns.lookup()`
|
||||
|
||||
The default is `verbatim` and `dns.setDefaultResultOrder()` have higher priority than `--dns-result-order`.
|
||||
|
||||
### `--diagnostic-dir=directory`
|
||||
|
||||
Set the directory to which all Node.js diagnostic output files are written. Defaults to current working directory.
|
||||
|
||||
Affects the default output directory of [v8.setHeapSnapshotNearHeapLimit](https://nodejs.org/docs/latest/api/v8.html#v8setheapsnapshotnearheaplimitlimit).
|
||||
|
||||
[app]: app.md
|
||||
[append-switch]: command-line.md#commandlineappendswitchswitch-value
|
||||
[debugging-main-process]: ../tutorial/debugging-main-process.md
|
||||
|
||||
@@ -41,6 +41,16 @@ The `ipcRenderer` module has the following method to listen for events and send
|
||||
Listens to `channel`, when a new message arrives `listener` would be called with
|
||||
`listener(event, args...)`.
|
||||
|
||||
:::warning
|
||||
Do not expose the `event` argument to the renderer for security reasons! Wrap any
|
||||
callback that you receive from the renderer in another function like this:
|
||||
`ipcRenderer.on('my-channel', (event, ...args) => callback(...args))`.
|
||||
Not wrapping the callback in such a function would expose dangerous Electron APIs
|
||||
to the renderer process. See the
|
||||
[security guide](../tutorial/security.md#20-do-not-expose-electron-apis-to-untrusted-web-content)
|
||||
for more info.
|
||||
:::
|
||||
|
||||
### `ipcRenderer.off(channel, listener)`
|
||||
|
||||
* `channel` string
|
||||
|
||||
@@ -5,7 +5,16 @@
|
||||
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._
|
||||
|
||||
Each navigation entry corresponds to a specific page. The indexing system follows a sequential order, where the first available navigation entry is at index 0, representing the earliest visited page, and the latest navigation entry is at index N, representing the most recent page. Maintaining this ordered list of navigation entries enables seamless navigation both backward and forward through the user's browsing history.
|
||||
Each [NavigationEntry](./structures/navigation-entry.md) corresponds to a specific visited page.
|
||||
The indexing system follows a sequential order, where the entry for the earliest visited
|
||||
page is at index 0 and the entry for the most recent visited page is at index N.
|
||||
|
||||
Some APIs in this class also accept an _offset_, which is an integer representing the relative
|
||||
position of an index from the current entry according to the above indexing system (i.e. an offset
|
||||
value of `1` would represent going forward in history by one page).
|
||||
|
||||
Maintaining this ordered list of navigation entries enables seamless navigation both backward and
|
||||
forward through the user's browsing history.
|
||||
|
||||
### Instance Methods
|
||||
|
||||
@@ -21,7 +30,7 @@ Returns `boolean` - Whether the browser can go forward to next web page.
|
||||
|
||||
* `offset` Integer
|
||||
|
||||
Returns `boolean` - Whether the web page can go to the specified `offset` from the current entry.
|
||||
Returns `boolean` - Whether the web page can go to the specified relative `offset` from the current entry.
|
||||
|
||||
#### `navigationHistory.clear()`
|
||||
|
||||
@@ -57,7 +66,7 @@ Navigates browser to the specified absolute web page index.
|
||||
|
||||
* `offset` Integer
|
||||
|
||||
Navigates to the specified offset from the current entry.
|
||||
Navigates to the specified relative offset from the current entry.
|
||||
|
||||
#### `navigationHistory.length()`
|
||||
|
||||
@@ -74,3 +83,22 @@ Returns `boolean` - Whether the navigation entry was removed from the webContent
|
||||
#### `navigationHistory.getAllEntries()`
|
||||
|
||||
Returns [`NavigationEntry[]`](structures/navigation-entry.md) - WebContents complete history.
|
||||
|
||||
#### `navigationHistory.restore(options)`
|
||||
|
||||
Restores navigation history and loads the given entry in the in stack. Will make a best effort
|
||||
to restore not just the navigation stack but also the state of the individual pages - for instance
|
||||
including HTML form values or the scroll position. It's recommended to call this API before any
|
||||
navigation entries are created, so ideally before you call `loadURL()` or `loadFile()` on the
|
||||
`webContents` object.
|
||||
|
||||
This API allows you to create common flows that aim to restore, recreate, or clone other webContents.
|
||||
|
||||
* `options` Object
|
||||
* `entries` [NavigationEntry[]](structures/navigation-entry.md) - Result of a prior `getAllEntries()` call
|
||||
* `index` Integer (optional) - Index of the stack that should be loaded. If you set it to `0`, the webContents will load the first (oldest) entry. If you leave it undefined, Electron will automatically load the last (newest) entry.
|
||||
|
||||
Returns `Promise<void>` - the promise will resolve when the page has finished loading the selected navigation entry
|
||||
(see [`did-finish-load`](web-contents.md#event-did-finish-load)), and rejects
|
||||
if the page fails to load (see
|
||||
[`did-fail-load`](web-contents.md#event-did-fail-load)). A noop rejection handler is already attached, which avoids unhandled rejection errors.
|
||||
|
||||
@@ -26,7 +26,10 @@ Emitted when system changes to battery power.
|
||||
|
||||
### Event: 'thermal-state-change' _macOS_
|
||||
|
||||
* `state` string - The system's new thermal state. Can be `unknown`, `nominal`, `fair`, `serious`, `critical`.
|
||||
Returns:
|
||||
|
||||
* `details` Event\<\>
|
||||
* `state` string - The system's new thermal state. Can be `unknown`, `nominal`, `fair`, `serious`, `critical`.
|
||||
|
||||
Emitted when the thermal state of the system changes. Notification of a change
|
||||
in the thermal status of the system, such as entering a critical temperature
|
||||
@@ -42,7 +45,8 @@ See https://developer.apple.com/library/archive/documentation/Performance/Concep
|
||||
|
||||
### Event: 'speed-limit-change' _macOS_ _Windows_
|
||||
|
||||
* `limit` number - The operating system's advertised speed limit for CPUs, in percent.
|
||||
* `details` Event\<\>
|
||||
* `limit` number - The operating system's advertised speed limit for CPUs, in percent.
|
||||
|
||||
Notification of a change in the operating system's advertised speed limit for
|
||||
CPUs, in percent. Values below 100 indicate that the system is impairing
|
||||
|
||||
@@ -46,4 +46,7 @@ See: https://developer.apple.com/documentation/appkit/nsapplication/1428476-regi
|
||||
### `pushNotifications.unregisterForAPNSNotifications()` _macOS_
|
||||
|
||||
Unregisters the app from notifications received from APNS.
|
||||
|
||||
Apps unregistered through this method can always reregister.
|
||||
|
||||
See: https://developer.apple.com/documentation/appkit/nsapplication/1428747-unregisterforremotenotifications?language=objc
|
||||
|
||||
@@ -933,6 +933,7 @@ session.fromPartition('some-partition').setPermissionRequestHandler((webContents
|
||||
* `storage-access` - Allows content loaded in a third-party context to request access to third-party cookies using the [Storage Access API](https://developer.mozilla.org/en-US/docs/Web/API/Storage_Access_API).
|
||||
* `top-level-storage-access` - Allow top-level sites to request third-party cookie access on behalf of embedded content originating from another site in the same related website set using the [Storage Access API](https://developer.mozilla.org/en-US/docs/Web/API/Storage_Access_API).
|
||||
* `usb` - Expose non-standard Universal Serial Bus (USB) compatible devices services to the web with the [WebUSB API](https://developer.mozilla.org/en-US/docs/Web/API/WebUSB_API).
|
||||
* `deprecated-sync-clipboard-read` _Deprecated_ - Request access to run `document.execCommand("paste")`
|
||||
* `requestingOrigin` string - The origin URL of the permission check
|
||||
* `details` Object - Some properties are only available on certain permission types.
|
||||
* `embeddingOrigin` string (optional) - The origin of the frame embedding the frame that made the permission check. Only set for cross-origin sub frames making permission checks.
|
||||
|
||||
@@ -97,9 +97,10 @@
|
||||
* `height` Integer (optional) - The height of the title bar and Window Controls Overlay in pixels. Default is system height.
|
||||
* `trafficLightPosition` [Point](point.md) (optional) _macOS_ -
|
||||
Set a custom position for the traffic light buttons in frameless windows.
|
||||
* `roundedCorners` boolean (optional) _macOS_ - Whether frameless window
|
||||
should have rounded corners on macOS. Default is `true`. Setting this property
|
||||
to `false` will prevent the window from being fullscreenable.
|
||||
* `roundedCorners` boolean (optional) _macOS_ _Windows_ - Whether frameless window
|
||||
should have rounded corners. Default is `true`. Setting this property
|
||||
to `false` will prevent the window from being fullscreenable on macOS.
|
||||
On Windows versions older than Windows 11 Build 22000 this property has no effect, and frameless windows will not have rounded corners.
|
||||
* `thickFrame` boolean (optional) - Use `WS_THICKFRAME` style for frameless windows on
|
||||
Windows, which adds standard window frame. Setting it to `false` will remove
|
||||
window shadow and window animations. Default is `true`.
|
||||
|
||||
@@ -2,3 +2,6 @@
|
||||
|
||||
* `url` string
|
||||
* `title` string
|
||||
* `pageState` string (optional) - A base64 encoded data string containing Chromium page state
|
||||
including information like the current scroll position or form values. It is committed by
|
||||
Chromium before a navigation event and on a regular interval.
|
||||
|
||||
@@ -148,6 +148,7 @@
|
||||
this will cause the `preferred-size-changed` event to be emitted on the
|
||||
`WebContents` when the preferred size changes. Default is `false`.
|
||||
* `transparent` boolean (optional) - Whether to enable background transparency for the guest page. Default is `true`. **Note:** The guest page's text and background colors are derived from the [color scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/color-scheme) of its root element. When transparency is enabled, the text color will still change accordingly but the background will remain transparent.
|
||||
* `enableDeprecatedPaste` boolean (optional) _Deprecated_ - Whether to enable the `paste` [execCommand](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand). Default is `false`.
|
||||
|
||||
[chrome-content-scripts]: https://developer.chrome.com/extensions/content_scripts#execution-environment
|
||||
[runtime-enabled-features]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/runtime_enabled_features.json5
|
||||
|
||||
@@ -106,6 +106,12 @@ Examples of valid `color` values:
|
||||
|
||||
* `visible` boolean - If false, the view will be hidden from display.
|
||||
|
||||
#### `view.getVisible()`
|
||||
|
||||
Returns `boolean` - Whether the view should be drawn. Note that this is
|
||||
different from whether the view is visible on screen—it may still be obscured
|
||||
or out of view.
|
||||
|
||||
### Instance Properties
|
||||
|
||||
Objects created with `new View` have the following properties:
|
||||
|
||||
@@ -39,6 +39,15 @@ This brings the behavior to parity with Linux. Prior behavior: Menu bar is still
|
||||
|
||||
## Planned Breaking API Changes (33.0)
|
||||
|
||||
### Deprecated: `document.execCommand("paste")`
|
||||
|
||||
The synchronous clipboard read API [document.execCommand("paste")](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Interact_with_the_clipboard) has been
|
||||
deprecated in favor of [async clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API). This is to align with the browser defaults.
|
||||
|
||||
The `enableDeprecatedPaste` option on `WebPreferences` that triggers the permission
|
||||
checks for this API and the associated permission type `deprecated-sync-clipboard-read`
|
||||
are also deprecated.
|
||||
|
||||
### Behavior Changed: frame properties may retrieve detached WebFrameMain instances or none at all
|
||||
|
||||
APIs which provide access to a `WebFrameMain` instance may return an instance
|
||||
@@ -111,6 +120,16 @@ macOS 10.15 (Catalina) is no longer supported by [Chromium](https://chromium-rev
|
||||
Older versions of Electron will continue to run on Catalina, but macOS 11 (Big Sur)
|
||||
or later will be required to run Electron v33.0.0 and higher.
|
||||
|
||||
### Behavior Changed: Native modules now require C++20
|
||||
|
||||
Due to changes made upstream, both
|
||||
[V8](https://chromium-review.googlesource.com/c/v8/v8/+/5587859) and
|
||||
[Node.js](https://github.com/nodejs/node/pull/45427) now require C++20 as a
|
||||
minimum version. Developers using native node modules should build their
|
||||
modules with `--std=c++20` rather than `--std=c++17`. Images using gcc9 or
|
||||
lower may need to update to gcc10 in order to compile. See
|
||||
[#43555](https://github.com/electron/electron/pull/43555) for more details.
|
||||
|
||||
### Deprecated: `systemPreferences.accessibilityDisplayShouldReduceTransparency`
|
||||
|
||||
The `systemPreferences.accessibilityDisplayShouldReduceTransparency` property is now deprecated in favor of the new `nativeTheme.prefersReducedTransparency`, which provides identical information and works cross-platform.
|
||||
@@ -182,6 +201,14 @@ win.webContents.navigationHistory.canGoToOffset()
|
||||
win.webContents.navigationHistory.goToOffset(index)
|
||||
```
|
||||
|
||||
### Behavior changed: Directory `databases` in `userData` will be deleted
|
||||
|
||||
If you have a directory called `databases` in the directory returned by
|
||||
`app.getPath('userData')`, it will be deleted when Electron 32 is first run.
|
||||
The `databases` directory was used by WebSQL, which was removed in Electron 31.
|
||||
Chromium now performs a cleanup that deletes this directory. See
|
||||
[issue #45396](https://github.com/electron/electron/issues/45396).
|
||||
|
||||
## Planned Breaking API Changes (31.0)
|
||||
|
||||
### Removed: `WebSQL` support
|
||||
|
||||
@@ -14,7 +14,7 @@ To configure a local keyboard shortcut, you need to specify an [`accelerator`][]
|
||||
property when creating a [MenuItem][] within the [Menu][] module.
|
||||
|
||||
Starting with a working application from the
|
||||
[Quick Start Guide](quick-start.md), update the `main.js` to be:
|
||||
[tutorial starter code][tutorial-starter-code], update the `main.js` to be:
|
||||
|
||||
```fiddle docs/fiddles/features/keyboard-shortcuts/local
|
||||
const { app, BrowserWindow, Menu, MenuItem } = require('electron/main')
|
||||
@@ -75,7 +75,7 @@ module to detect keyboard events even when the application does not have
|
||||
keyboard focus.
|
||||
|
||||
Starting with a working application from the
|
||||
[Quick Start Guide](quick-start.md), update the `main.js` to be:
|
||||
[tutorial starter code][tutorial-starter-code], update the `main.js` to be:
|
||||
|
||||
```fiddle docs/fiddles/features/keyboard-shortcuts/global
|
||||
const { app, BrowserWindow, globalShortcut } = require('electron/main')
|
||||
@@ -144,7 +144,7 @@ is emitted before dispatching `keydown` and `keyup` events in the page. It can
|
||||
be used to catch and handle custom shortcuts that are not visible in the menu.
|
||||
|
||||
Starting with a working application from the
|
||||
[Quick Start Guide](quick-start.md), update the `main.js` file with the
|
||||
[tutorial starter code][tutorial-starter-code], update the `main.js` file with the
|
||||
following lines:
|
||||
|
||||
```fiddle docs/fiddles/features/keyboard-shortcuts/interception-from-main
|
||||
@@ -207,3 +207,4 @@ Mousetrap.bind('up up down down left right left right b a enter', () => {
|
||||
[mousetrap]: https://github.com/ccampbell/mousetrap
|
||||
[dom-events]: https://developer.mozilla.org/en-US/docs/Web/Events
|
||||
[addEventListener-api]: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
|
||||
[tutorial-starter-code]: tutorial-2-first-app.md#final-starter-code
|
||||
|
||||
@@ -22,12 +22,9 @@ In `preload.js` use the [`contextBridge`][] to inject a method `window.electron.
|
||||
|
||||
```js
|
||||
const { contextBridge, ipcRenderer } = require('electron')
|
||||
const path = require('node:path')
|
||||
|
||||
contextBridge.exposeInMainWorld('electron', {
|
||||
startDrag: (fileName) => {
|
||||
ipcRenderer.send('ondragstart', path.join(process.cwd(), fileName))
|
||||
}
|
||||
startDrag: (fileName) => ipcRenderer.send('ondragstart', fileName)
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
@@ -69,8 +69,25 @@ if (navigationHistory.canGoToOffset(2)) {
|
||||
}
|
||||
```
|
||||
|
||||
## Restoring history
|
||||
|
||||
A common flow is that you want to restore the history of a webContents - for instance to implement an "undo close tab" feature. To do so, you can call `navigationHistory.restore({ index, entries })`. This will restore the webContent's navigation history and the webContents location in said history, meaning that `goBack()` and `goForward()` navigate you through the stack as expected.
|
||||
|
||||
```js @ts-type={navigationHistory:Electron.NavigationHistory}
|
||||
|
||||
const firstWindow = new BrowserWindow()
|
||||
|
||||
// Later, you want a second window to have the same history and navigation position
|
||||
async function restore () {
|
||||
const entries = firstWindow.webContents.navigationHistory.getAllEntries()
|
||||
const index = firstWindow.webContents.navigationHistory.getActiveIndex()
|
||||
|
||||
const secondWindow = new BrowserWindow()
|
||||
await secondWindow.webContents.navigationHistory.restore({ index, entries })
|
||||
}
|
||||
```
|
||||
|
||||
Here's a full example that you can open with Electron Fiddle:
|
||||
|
||||
```fiddle docs/fiddles/features/navigation-history
|
||||
|
||||
```
|
||||
|
||||
@@ -86,7 +86,7 @@ The main process also controls your application's lifecycle through Electron's
|
||||
that you can use to add custom application behavior (for instance, programmatically
|
||||
quitting your application, modifying the application dock, or showing an About panel).
|
||||
|
||||
As a practical example, the app shown in the [quick start guide][quick-start-lifecycle]
|
||||
As a practical example, the app shown in the [tutorial starter code][tutorial-lifecycle]
|
||||
uses `app` APIs to create a more native application window experience.
|
||||
|
||||
```js title='main.js'
|
||||
@@ -97,7 +97,7 @@ app.on('window-all-closed', () => {
|
||||
```
|
||||
|
||||
[app]: ../api/app.md
|
||||
[quick-start-lifecycle]: ../tutorial/quick-start.md#manage-your-windows-lifecycle
|
||||
[tutorial-lifecycle]: ../tutorial/tutorial-2-first-app.md#quit-the-app-when-all-windows-are-closed-windows--linux
|
||||
|
||||
### Native APIs
|
||||
|
||||
|
||||
@@ -1,513 +0,0 @@
|
||||
# Quick Start
|
||||
|
||||
This guide will step you through the process of creating a barebones Hello World app in
|
||||
Electron, similar to [`electron/electron-quick-start`][quick-start].
|
||||
|
||||
By the end of this tutorial, your app will open a browser window that displays a web page
|
||||
with information about which Chromium, Node.js, and Electron versions are running.
|
||||
|
||||
[quick-start]: https://github.com/electron/electron-quick-start
|
||||
|
||||
## Prerequisites
|
||||
|
||||
To use Electron, you need to install [Node.js][node-download]. We recommend that you
|
||||
use the latest `LTS` version available.
|
||||
|
||||
> Please install Node.js using pre-built installers for your platform.
|
||||
> You may encounter incompatibility issues with different development tools otherwise.
|
||||
|
||||
To check that Node.js was installed correctly, type the following commands in your
|
||||
terminal client:
|
||||
|
||||
```sh
|
||||
node -v
|
||||
npm -v
|
||||
```
|
||||
|
||||
The commands should print the versions of Node.js and npm accordingly.
|
||||
|
||||
**Note:** Since Electron embeds Node.js into its binary, the version of Node.js running
|
||||
your code is unrelated to the version running on your system.
|
||||
|
||||
[node-download]: https://nodejs.org/en/download/
|
||||
|
||||
## Create your application
|
||||
|
||||
### Scaffold the project
|
||||
|
||||
Electron apps follow the same general structure as other Node.js projects.
|
||||
Start by creating a folder and initializing an npm package.
|
||||
|
||||
```sh npm2yarn
|
||||
mkdir my-electron-app && cd my-electron-app
|
||||
npm init
|
||||
```
|
||||
|
||||
The interactive `init` command will prompt you to set some fields in your config.
|
||||
There are a few rules to follow for the purposes of this tutorial:
|
||||
|
||||
* `entry point` should be `main.js`.
|
||||
* `author` and `description` can be any value, but are necessary for
|
||||
[app packaging](#package-and-distribute-your-application).
|
||||
|
||||
Your `package.json` file should look something like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-electron-app",
|
||||
"version": "1.0.0",
|
||||
"description": "Hello World!",
|
||||
"main": "main.js",
|
||||
"author": "Jane Doe",
|
||||
"license": "MIT"
|
||||
}
|
||||
```
|
||||
|
||||
Then, install the `electron` package into your app's `devDependencies`.
|
||||
|
||||
```sh npm2yarn
|
||||
npm install --save-dev electron
|
||||
```
|
||||
|
||||
> Note: If you're encountering any issues with installing Electron, please
|
||||
> refer to the [Advanced Installation][advanced-installation] guide.
|
||||
|
||||
Finally, you want to be able to execute Electron. In the [`scripts`][package-scripts]
|
||||
field of your `package.json` config, add a `start` command like so:
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"start": "electron ."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This `start` command will let you open your app in development mode.
|
||||
|
||||
```sh npm2yarn
|
||||
npm start
|
||||
```
|
||||
|
||||
> Note: This script tells Electron to run on your project's root folder. At this stage,
|
||||
> your app will immediately throw an error telling you that it cannot find an app to run.
|
||||
|
||||
[advanced-installation]: ./installation.md
|
||||
[package-scripts]: https://docs.npmjs.com/cli/v7/using-npm/scripts
|
||||
|
||||
### Run the main process
|
||||
|
||||
The entry point of any Electron application is its `main` script. This script controls the
|
||||
**main process**, which runs in a full Node.js environment and is responsible for
|
||||
controlling your app's lifecycle, displaying native interfaces, performing privileged
|
||||
operations, and managing renderer processes (more on that later).
|
||||
|
||||
During execution, Electron will look for this script in the [`main`][package-json-main]
|
||||
field of the app's `package.json` config, which you should have configured during the
|
||||
[app scaffolding](#scaffold-the-project) step.
|
||||
|
||||
To initialize the `main` script, create an empty file named `main.js` in the root folder
|
||||
of your project.
|
||||
|
||||
> Note: If you run the `start` script again at this point, your app will no longer throw
|
||||
> any errors! However, it won't do anything yet because we haven't added any code into
|
||||
> `main.js`.
|
||||
|
||||
[package-json-main]: https://docs.npmjs.com/cli/v7/configuring-npm/package-json#main
|
||||
|
||||
### Create a web page
|
||||
|
||||
Before we can create a window for our application, we need to create the content that
|
||||
will be loaded into it. In Electron, each window displays web contents that can be loaded
|
||||
from either a local HTML file or a remote URL.
|
||||
|
||||
For this tutorial, you will be doing the former. Create an `index.html` file in the root
|
||||
folder of your project:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
|
||||
<title>Hello World!</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
We are using Node.js <span id="node-version"></span>,
|
||||
Chromium <span id="chrome-version"></span>,
|
||||
and Electron <span id="electron-version"></span>.
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
> Note: Looking at this HTML document, you can observe that the version numbers are
|
||||
> missing from the body text. We'll manually insert them later using JavaScript.
|
||||
|
||||
### Opening your web page in a browser window
|
||||
|
||||
Now that you have a web page, load it into an application window. To do so, you'll
|
||||
need two Electron modules:
|
||||
|
||||
* The [`app`][app] module, which controls your application's event lifecycle.
|
||||
* The [`BrowserWindow`][browser-window] module, which creates and manages application
|
||||
windows.
|
||||
|
||||
Because the main process runs Node.js, you can import these as [CommonJS][commonjs]
|
||||
modules at the top of your `main.js` file:
|
||||
|
||||
```js
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
```
|
||||
|
||||
Then, add a `createWindow()` function that loads `index.html` into a new `BrowserWindow`
|
||||
instance.
|
||||
|
||||
```js
|
||||
const createWindow = () => {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
```
|
||||
|
||||
Next, call this `createWindow()` function to open your window.
|
||||
|
||||
In Electron, browser windows can only be created after the `app` module's
|
||||
[`ready`][app-ready] event is fired. You can wait for this event by using the
|
||||
[`app.whenReady()`][app-when-ready] API. Call `createWindow()` after `whenReady()`
|
||||
resolves its Promise.
|
||||
|
||||
```js @ts-type={createWindow:()=>void}
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
})
|
||||
```
|
||||
|
||||
> Note: At this point, your Electron application should successfully
|
||||
> open a window that displays your web page!
|
||||
|
||||
[app]: ../api/app.md
|
||||
[browser-window]: ../api/browser-window.md
|
||||
[commonjs]: https://nodejs.org/docs/latest/api/modules.html#modules_modules_commonjs_modules
|
||||
[app-ready]: ../api/app.md#event-ready
|
||||
[app-when-ready]: ../api/app.md#appwhenready
|
||||
|
||||
### Manage your window's lifecycle
|
||||
|
||||
Although you can now open a browser window, you'll need some additional boilerplate code
|
||||
to make it feel more native to each platform. Application windows behave differently on
|
||||
each OS, and Electron puts the responsibility on developers to implement these
|
||||
conventions in their app.
|
||||
|
||||
In general, you can use the `process` global's [`platform`][node-platform] attribute
|
||||
to run code specifically for certain operating systems.
|
||||
|
||||
#### Quit the app when all windows are closed (Windows & Linux)
|
||||
|
||||
On Windows and Linux, exiting all windows generally quits an application entirely.
|
||||
|
||||
To implement this, listen for the `app` module's [`'window-all-closed'`][window-all-closed]
|
||||
event, and call [`app.quit()`][app-quit] if the user is not on macOS (`darwin`).
|
||||
|
||||
```js
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') app.quit()
|
||||
})
|
||||
```
|
||||
|
||||
[node-platform]: https://nodejs.org/api/process.html#process_process_platform
|
||||
[window-all-closed]: ../api/app.md#event-window-all-closed
|
||||
[app-quit]: ../api/app.md#appquit
|
||||
|
||||
#### Open a window if none are open (macOS)
|
||||
|
||||
Whereas Linux and Windows apps quit when they have no windows open, macOS apps generally
|
||||
continue running even without any windows open, and activating the app when no windows
|
||||
are available should open a new one.
|
||||
|
||||
To implement this feature, listen for the `app` module's [`activate`][activate]
|
||||
event, and call your existing `createWindow()` method if no browser windows are open.
|
||||
|
||||
Because windows cannot be created before the `ready` event, you should only listen for
|
||||
`activate` events after your app is initialized. Do this by attaching your event listener
|
||||
from within your existing `whenReady()` callback.
|
||||
|
||||
[activate]: ../api/app.md#event-activate-macos
|
||||
|
||||
```js @ts-type={createWindow:()=>void}
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) createWindow()
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
> Note: At this point, your window controls should be fully functional!
|
||||
|
||||
### Access Node.js from the renderer with a preload script
|
||||
|
||||
Now, the last thing to do is print out the version numbers for Electron and its
|
||||
dependencies onto your web page.
|
||||
|
||||
Accessing this information is trivial to do in the main process through Node's
|
||||
global `process` object. However, you can't just edit the DOM from the main
|
||||
process because it has no access to the renderer's `document` context.
|
||||
They're in entirely different processes!
|
||||
|
||||
> Note: If you need a more in-depth look at Electron processes, see the
|
||||
> [Process Model][] document.
|
||||
|
||||
This is where attaching a **preload** script to your renderer comes in handy.
|
||||
A preload script runs before the renderer process is loaded, and has access to both
|
||||
renderer globals (e.g. `window` and `document`) and a Node.js environment.
|
||||
|
||||
Create a new script named `preload.js` as such:
|
||||
|
||||
```js
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
const replaceText = (selector, text) => {
|
||||
const element = document.getElementById(selector)
|
||||
if (element) element.innerText = text
|
||||
}
|
||||
|
||||
for (const dependency of ['chrome', 'node', 'electron']) {
|
||||
replaceText(`${dependency}-version`, process.versions[dependency])
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
The above code accesses the Node.js `process.versions` object and runs a basic `replaceText`
|
||||
helper function to insert the version numbers into the HTML document.
|
||||
|
||||
To attach this script to your renderer process, pass in the path to your preload script
|
||||
to the `webPreferences.preload` option in your existing `BrowserWindow` constructor.
|
||||
|
||||
```js
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
// include the Node.js 'path' module at the top of your file
|
||||
const path = require('node:path')
|
||||
|
||||
// modify your existing createWindow() function
|
||||
const createWindow = () => {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, 'preload.js')
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
// ...
|
||||
```
|
||||
|
||||
There are two Node.js concepts that are used here:
|
||||
|
||||
* The [`__dirname`][dirname] string points to the path of the currently executing script
|
||||
(in this case, your project's root folder).
|
||||
* The [`path.join`][path-join] API joins multiple path segments together, creating a
|
||||
combined path string that works across all platforms.
|
||||
|
||||
We use a path relative to the currently executing JavaScript file so that your relative
|
||||
path will work in both development and packaged mode.
|
||||
|
||||
[Process Model]: ./process-model.md
|
||||
[dirname]: https://nodejs.org/api/modules.html#modules_dirname
|
||||
[path-join]: https://nodejs.org/api/path.html#path_path_join_paths
|
||||
|
||||
### Bonus: Add functionality to your web contents
|
||||
|
||||
At this point, you might be wondering how to add more functionality to your application.
|
||||
|
||||
For any interactions with your web contents, you want to add scripts to your
|
||||
renderer process. Because the renderer runs in a normal web environment, you can add a
|
||||
`<script>` tag right before your `index.html` file's closing `</body>` tag to include
|
||||
any arbitrary scripts you want:
|
||||
|
||||
```html
|
||||
<script src="./renderer.js"></script>
|
||||
```
|
||||
|
||||
The code contained in `renderer.js` can then use the same JavaScript APIs and tooling
|
||||
you use for typical front-end development, such as using [`webpack`][webpack] to bundle
|
||||
and minify your code or [React][react] to manage your user interfaces.
|
||||
|
||||
[webpack]: https://webpack.js.org
|
||||
[react]: https://reactjs.org
|
||||
|
||||
### Recap
|
||||
|
||||
After following the above steps, you should have a fully functional
|
||||
Electron application that looks like this:
|
||||
|
||||

|
||||
|
||||
<!--TODO(erickzhao): Remove the individual code blocks for static website -->
|
||||
The full code is available below:
|
||||
|
||||
```js
|
||||
// main.js
|
||||
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const path = require('node:path')
|
||||
|
||||
const createWindow = () => {
|
||||
// Create the browser window.
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, 'preload.js')
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
|
||||
app.on('activate', () => {
|
||||
// On macOS it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (BrowserWindow.getAllWindows().length === 0) createWindow()
|
||||
})
|
||||
})
|
||||
|
||||
// Quit when all windows are closed, except on macOS. There, it's common
|
||||
// for applications and their menu bar to stay active until the user quits
|
||||
// explicitly with Cmd + Q.
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') app.quit()
|
||||
})
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
```
|
||||
|
||||
```js
|
||||
// preload.js
|
||||
|
||||
// All the Node.js APIs are available in the preload process.
|
||||
// It has the same sandbox as a Chrome extension.
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
const replaceText = (selector, text) => {
|
||||
const element = document.getElementById(selector)
|
||||
if (element) element.innerText = text
|
||||
}
|
||||
|
||||
for (const dependency of ['chrome', 'node', 'electron']) {
|
||||
replaceText(`${dependency}-version`, process.versions[dependency])
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
```html
|
||||
<!--index.html-->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
|
||||
<title>Hello World!</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
We are using Node.js <span id="node-version"></span>,
|
||||
Chromium <span id="chrome-version"></span>,
|
||||
and Electron <span id="electron-version"></span>.
|
||||
|
||||
<!-- You can also require other files to run in this process -->
|
||||
<script src="./renderer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```fiddle docs/fiddles/quick-start
|
||||
```
|
||||
|
||||
To summarize all the steps we've done:
|
||||
|
||||
* We bootstrapped a Node.js application and added Electron as a dependency.
|
||||
* We created a `main.js` script that runs our main process, which controls our app
|
||||
and runs in a Node.js environment. In this script, we used Electron's `app` and
|
||||
`BrowserWindow` modules to create a browser window that displays web content
|
||||
in a separate process (the renderer).
|
||||
* In order to access certain Node.js functionality in the renderer, we attached
|
||||
a preload script to our `BrowserWindow` constructor.
|
||||
|
||||
## Package and distribute your application
|
||||
|
||||
The fastest way to distribute your newly created app is using
|
||||
[Electron Forge](https://www.electronforge.io).
|
||||
|
||||
:::info
|
||||
|
||||
To build an RPM package for Linux, you will need to [install its required system dependencies](https://www.electronforge.io/config/makers/rpm).
|
||||
|
||||
:::
|
||||
|
||||
1. Add a description to your `package.json` file, otherwise rpmbuild will fail. Blank description are not valid.
|
||||
2. Add Electron Forge as a development dependency of your app, and use its `import` command to set up
|
||||
Forge's scaffolding:
|
||||
|
||||
```sh npm2yarn
|
||||
npm install --save-dev @electron-forge/cli
|
||||
npx electron-forge import
|
||||
|
||||
✔ Checking your system
|
||||
✔ Initializing Git Repository
|
||||
✔ Writing modified package.json file
|
||||
✔ Installing dependencies
|
||||
✔ Writing modified package.json file
|
||||
✔ Fixing .gitignore
|
||||
|
||||
We have ATTEMPTED to convert your app to be in a format that electron-forge understands.
|
||||
|
||||
Thanks for using "electron-forge"!!!
|
||||
```
|
||||
|
||||
3. Create a distributable using Forge's `make` command:
|
||||
|
||||
```sh npm2yarn
|
||||
npm run make
|
||||
|
||||
> my-electron-app@1.0.0 make /my-electron-app
|
||||
> electron-forge make
|
||||
|
||||
✔ Checking your system
|
||||
✔ Resolving Forge Config
|
||||
We need to package your application before we can make it
|
||||
✔ Preparing to Package Application for arch: x64
|
||||
✔ Preparing native dependencies
|
||||
✔ Packaging Application
|
||||
Making for the following targets: zip
|
||||
✔ Making for target: zip - On platform: darwin - For arch: x64
|
||||
```
|
||||
|
||||
Electron Forge creates the `out` folder where your package will be located:
|
||||
|
||||
```plain
|
||||
// Example for macOS
|
||||
out/
|
||||
├── out/make/zip/darwin/x64/my-electron-app-darwin-x64-1.0.0.zip
|
||||
├── ...
|
||||
└── out/my-electron-app-darwin-x64/my-electron-app.app/Contents/MacOS/my-electron-app
|
||||
```
|
||||
@@ -116,6 +116,7 @@ You should at least follow these steps to improve the security of your applicati
|
||||
17. [Validate the `sender` of all IPC messages](#17-validate-the-sender-of-all-ipc-messages)
|
||||
18. [Avoid usage of the `file://` protocol and prefer usage of custom protocols](#18-avoid-usage-of-the-file-protocol-and-prefer-usage-of-custom-protocols)
|
||||
19. [Check which fuses you can change](#19-check-which-fuses-you-can-change)
|
||||
20. [Do not expose Electron APIs to untrusted web content](#20-do-not-expose-electron-apis-to-untrusted-web-content)
|
||||
|
||||
To automate the detection of misconfigurations and insecure patterns, it is
|
||||
possible to use
|
||||
@@ -229,7 +230,7 @@ API to remotely loaded content via the [contextBridge API](../api/context-bridge
|
||||
### 3. Enable Context Isolation
|
||||
|
||||
:::info
|
||||
This recommendation is the default behavior in Electron since 12.0.0.
|
||||
Context Isolation is the default behavior in Electron since 12.0.0.
|
||||
:::
|
||||
|
||||
Context isolation is an Electron feature that allows developers to run code
|
||||
@@ -804,6 +805,48 @@ flipping these fuses easy. Check out the README of that module for more details
|
||||
potential error cases, and refer to
|
||||
[How do I flip the fuses?](./fuses.md#how-do-i-flip-the-fuses) in our documentation.
|
||||
|
||||
### 20. Do not expose Electron APIs to untrusted web content
|
||||
|
||||
You should not directly expose Electron's APIs, especially IPC, to untrusted web content in your
|
||||
preload scripts.
|
||||
|
||||
### Why?
|
||||
|
||||
Exposing raw APIs like `ipcRenderer.on` is dangerous because it gives renderer processes direct
|
||||
access to the entire IPC event system, allowing them to listen for any IPC events, not just the ones
|
||||
intended for them.
|
||||
|
||||
To avoid that exposure, we also cannot pass callbacks directly through: The first
|
||||
argument to IPC event callbacks is an `IpcRendererEvent` object, which includes properties like `sender`
|
||||
that provide access to the underlying `ipcRenderer` instance. Even if you only listen for specific
|
||||
events, passing the callback directly means the renderer gets access to this event object.
|
||||
|
||||
In short, we want the untrusted web content to only have access to necessary information and APIs.
|
||||
|
||||
### How?
|
||||
|
||||
```js title='preload'.js'
|
||||
// Bad
|
||||
contextBridge.exposeInMainWorld('electronAPI', {
|
||||
on: ipcRenderer.on
|
||||
})
|
||||
|
||||
// Also bad
|
||||
contextBridge.exposeInMainWorld('electronAPI', {
|
||||
onUpdateCounter: (callback) => ipcRenderer.on('update-counter', callback)
|
||||
})
|
||||
|
||||
// Good
|
||||
contextBridge.exposeInMainWorld('electronAPI', {
|
||||
onUpdateCounter: (callback) => ipcRenderer.on('update-counter', (_event, value) => callback(value))
|
||||
})
|
||||
```
|
||||
|
||||
:::info
|
||||
For more information on what `contextIsolation` is and how to use it to secure your app,
|
||||
please see the [Context Isolation](context-isolation.md) document.
|
||||
:::
|
||||
|
||||
[breaking-changes]: ../breaking-changes.md
|
||||
[browser-window]: ../api/browser-window.md
|
||||
[webview-tag]: ../api/webview-tag.md
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
# Window Customization
|
||||
|
||||
The [`BrowserWindow`][] module is the foundation of your Electron application, and
|
||||
@@ -5,13 +7,15 @@ it exposes many APIs that let you customize the look and behavior of your app’
|
||||
This section covers how to implement various use cases for window customization on macOS,
|
||||
Windows, and Linux.
|
||||
|
||||
:::info
|
||||
`BrowserWindow` is a subclass of the [`BaseWindow`][] module. Both modules allow
|
||||
you to create and manage application windows in Electron, with the main difference
|
||||
being that `BrowserWindow` supports a single, full size web view while `BaseWindow`
|
||||
supports composing many web views. `BaseWindow` can be used interchangeably with `BrowserWindow`
|
||||
in the examples of the documents in this section.
|
||||
:::
|
||||
> [!NOTE]
|
||||
> `BrowserWindow` is a subclass of the [`BaseWindow`][] module. Both modules allow
|
||||
> you to create and manage application windows in Electron, with the main difference
|
||||
> being that `BrowserWindow` supports a single, full size web view while `BaseWindow`
|
||||
> supports composing many web views. `BaseWindow` can be used interchangeably with `BrowserWindow`
|
||||
> in the examples of the documents in this section.
|
||||
|
||||
<!-- markdownlint-disable-next-line MD033 -->
|
||||
<DocCardList />
|
||||
|
||||
[`BaseWindow`]: ../api/base-window.md
|
||||
[`BrowserWindow`]: ../api/browser-window.md
|
||||
|
||||
@@ -8,7 +8,7 @@ If your app doesn't use any native modules, then it's really easy to create an A
|
||||
|
||||
1. Make sure that your app's `node_modules` directory is empty.
|
||||
2. Using a _Command Prompt_, run `set npm_config_arch=arm64` before running `npm install`/`yarn install` as usual.
|
||||
3. [If you have Electron installed as a development dependency](quick-start.md#prerequisites), npm will download and unpack the arm64 version. You can then package and distribute your app as normal.
|
||||
3. [If you have Electron installed as a development dependency](tutorial-2-first-app.md#initializing-your-npm-project), npm will download and unpack the arm64 version. You can then package and distribute your app as normal.
|
||||
|
||||
## General considerations
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ To set user tasks for your application, you can use
|
||||
##### Set user tasks
|
||||
|
||||
Starting with a working application from the
|
||||
[Quick Start Guide](quick-start.md), update the `main.js` file with the
|
||||
[tutorial starter code][tutorial-starter-code], update the `main.js` file with the
|
||||
following lines:
|
||||
|
||||
```js
|
||||
@@ -121,7 +121,7 @@ To set thumbnail toolbar in your application, you need to use
|
||||
##### Set thumbnail toolbar
|
||||
|
||||
Starting with a working application from the
|
||||
[Quick Start Guide](quick-start.md), update the `main.js` file with the
|
||||
[tutorial starter code][tutorial-starter-code], update the `main.js` file with the
|
||||
following lines:
|
||||
|
||||
```js
|
||||
@@ -185,7 +185,7 @@ To set the overlay icon for a window, you need to use the
|
||||
#### Example
|
||||
|
||||
Starting with a working application from the
|
||||
[Quick Start Guide](quick-start.md), update the `main.js` file with the
|
||||
[tutorial starter code][tutorial-starter-code], update the `main.js` file with the
|
||||
following lines:
|
||||
|
||||
```js
|
||||
@@ -214,7 +214,7 @@ To flash the BrowserWindow taskbar button, you need to use the
|
||||
#### Example
|
||||
|
||||
Starting with a working application from the
|
||||
[Quick Start Guide](quick-start.md), update the `main.js` file with the
|
||||
[tutorial starter code][tutorial-starter-code], update the `main.js` file with the
|
||||
following lines:
|
||||
|
||||
```js
|
||||
@@ -231,10 +231,10 @@ In the above example, it is called when the window comes into focus,
|
||||
but you might use a timeout or some other event to disable it.
|
||||
|
||||
[msdn-flash-frame]: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-flashwindow#remarks
|
||||
|
||||
[setthumbarbuttons]: ../api/browser-window.md#winsetthumbarbuttonsbuttons-windows
|
||||
[setusertaskstasks]: ../api/app.md#appsetusertaskstasks-windows
|
||||
[setoverlayicon]: ../api/browser-window.md#winsetoverlayiconoverlay-description-windows
|
||||
[flashframe]: ../api/browser-window.md#winflashframeflag
|
||||
[recent-documents]: ./recent-documents.md
|
||||
[progress-bar]: ./progress-bar.md
|
||||
[tutorial-starter-code]: ../tutorial/tutorial-2-first-app.md#final-starter-code
|
||||
|
||||
103
docs/why-electron.md
Normal file
103
docs/why-electron.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Why Electron
|
||||
|
||||
Electron is a framework enabling developers to build cross-platform desktop applications for macOS, Windows, and Linux by combining web technologies (HTML, JavaScript, CSS) with Node.js and native code. It is open-source, MIT-licensed, and free for both commercial and personal use. In this document, we’ll explain why companies and developers choose Electron.
|
||||
|
||||
We can split up the benefits of Electron in two questions: First, why should you use web technologies to build your application? Then, why should you choose Electron as the framework to do so?
|
||||
|
||||
If you’re already using web technologies for your application, you can skip straight to the `Why Electron?` section below.
|
||||
|
||||
## Why choose web technologies
|
||||
|
||||
Web technologies include HTML, CSS, JavaScript, and WebAssembly. They’re the storefront of the modern Internet. Those technologies have emerged as the best choice for building user interfaces — both for consumer applications as well as mission-critical business applications. This is true both for applications that need to run in a browser as well as desktop applications that are not accessible from a browser. Our bold claim here is that this isn’t just true for cross-platform applications that need to run on multiple operating systems but true overall.
|
||||
|
||||
As an example, NASA’s actual [Mission Control](https://github.com/nasa/openmct) is written with web technologies. The [Bloomberg Terminal](https://en.wikipedia.org/wiki/Bloomberg_Terminal), the computer system found at every financial institution, is written with web technologies and runs inside Chromium. It costs $25,000 per user, per year. The McDonald’s ordering kiosk, powering the world’s biggest food retailer, is entirely built with Chromium. The [SpaceX’s Dragon 2 space capsule](https://old.reddit.com/r/spacex/comments/gxb7j1/we_are_the_spacex_software_team_ask_us_anything/ft62781/?context=3) uses Chromium to display its interface. You get the point: web technologies are a great tech stack to build user interfaces.
|
||||
|
||||
Here are the reasons we, the Electron maintainers, are betting on the web.
|
||||
|
||||
### Versatility
|
||||
|
||||
Modern versions of HTML and CSS enable your developers and designers to fully express themselves. The web’s showcase includes Google Earth, Netflix, Spotify, Gmail, Facebook, Airbnb, or GitHub. Whatever interface your application needs, you will be able to express it with HTML, CSS, and JavaScript.
|
||||
|
||||
If you want to focus on building a great product without figuring out how you can realize your designer’s vision in a specific UI framework, the web is a safe bet.
|
||||
|
||||
### Reliability
|
||||
|
||||
Web technologies are the most-used foundation for user interfaces on the planet. The have been hardened accordingly. Modern computers have been optimized from the CPU to the operating system to be good at running web technologies. The manufacturers of your user’s devices—be that an Android phone or the latest MacBook—will ensure that they can visit websites, play videos on YouTube, or display emails. In turn, they’ll also ensure that your app has a stable foundation, even if you have just one user.
|
||||
|
||||
If you want to focus on building a great product without debugging a weird quirk that nobody has found before, the web is a safe bet.
|
||||
|
||||
### Interoperability
|
||||
|
||||
Whatever provider or customer data you need to interact with, they will have probably thought of an integration path with the web. Depending on your technology choice, embedding a YouTube video either takes 30 seconds or requires you to hire a team devoted to streaming and hardware-accelerated video decoding. In the case of YouTube, using anything other than the provided players is actually against their terms and conditions, so you’ll likely embed a browser frame before you implement your own video streaming decoder.
|
||||
|
||||
There will be virtually no platform where your app cannot run if you build it with web technologies. Virtually all devices with a display—be that an ATM, a car infotainment system, a smart TV, a fridge, or a Nintendo Switch—come with means to display web technologies. The web is safe bet if you want to be cross-platform.
|
||||
|
||||
### Ubiquity
|
||||
|
||||
It’s easy to find developers with experience building with web technologies. If you’re a developer, it’ll be easy to find answers to your questions on Google, Stack Overflow, GitHub, or a coding AI of your choice. Whatever problem you need to solve, it’s likely that somebody has solved it well before—and that you can find the answer to the puzzle online.
|
||||
|
||||
If you want to focus on building a great product with ample access to resources and materials, the web is a safe bet.
|
||||
|
||||
## Why choose Electron
|
||||
|
||||
Electron combines Chromium, Node.js, and the ability to write custom native code into one framework for building powerful desktop applications. There are three main reasons to use Electron:
|
||||
|
||||
### Enterprise-grade
|
||||
|
||||
Electron is reliable, secure, stable, and mature. It is the premier choice for companies building their flagship product. We have a list of some of those companies on our homepage, but just among chat apps, Slack, Discord, and Skype are built with Electron. Among AI applications, both OpenAI’s ChatGPT and Anthropic’s Claude use Electron. Visual Studio Code, Loom, Canva, Notion, Docker, and countless other leading developers of software bet on Electron.
|
||||
|
||||
We did make it a priority to make Electron easy to work with and a delight for developers. That’s likely the main reason why Electron became as popular as it is today — but what keeps Electron alive and thriving is the maintainer’s focus on making Electron as stable, secure, performant, and capable of mission-critical use cases for end users as possible. We’re building an Electron that is ready to be used in scenarios where unfixable bugs, unpatched security holes, and outages of any kind are worst-case scenarios.
|
||||
|
||||
### Mature
|
||||
|
||||
Our current estimation is that most desktop computers on the planet run at least one Electron app. Electron has grown by prioritizing talent in its maintainer group, fostering excellent and sustainable engineering practices in managing the ongoing maintenance, and proactively inviting companies betting on Electron to directly contribute to the project. We’re an impact project with the OpenJS foundation, which is itself a part of the Linux foundation. We share resources and expertise with other foundation projects like Node.js, ESLint, Webpack - or the Linux Kernel or Kubernetes.
|
||||
|
||||
What does all of that mean for you, a developer, in practice?
|
||||
|
||||
- **Reliable release schedule**: Electron will release a new major version in lockstep with every second major Chromium release, usually on the same day as Chromium. A lot of work, both in the form of building processes and tools, but also in terms of raw invested hours every week, has to go into making that happen.
|
||||
- **No dictators**: Sometimes, betting on a technology also requires you to bet on a single person or company. In turn, it requires you to trust that the person or company never has a breakdown, starts fighting you directly, or does anything else drastic that’ll force you rethink your entire tech stack. Electron is maintained by a diverse set of companies (Microsoft, Slack/Salesforce, Notion, and more) and will continue to welcome more companies interested in ensuring their “seat at the decision-making table”.
|
||||
|
||||
### Stability, security, performance
|
||||
|
||||
Electron delivers the best experience on all target platforms (macOS, Windows, Linux) by bundling the latest version of Chromium, V8, and Node.js directly with the application binary. When it comes to running and rendering web content with upmost stability, security, and performance, we currently believe that stack to be “best in class”.
|
||||
|
||||
#### Why bundle anything at all
|
||||
|
||||
You might wonder why we bundle Chromium’s web stack with our apps when most modern operating systems already ship a browser and some form of web view. Bundling doesn’t just increase the amount of work for Electron maintainers dramatically, it also increases the total disk size of Electron apps (most apps are >100MB). Many Electron maintainers once developed applications that did make use of embedded web views — and have since accepted the increased disk size and maintainer work as a worthy trade-off.
|
||||
|
||||
When using an operating system's built-in web view, you're limited by the browser version included in the oldest operating system version you need to support. We have found the following problems with this approach:
|
||||
|
||||
- **Stability**: The modern web technology stack is complex, and as a result, you’ll sooner or later encounter bugs. If you use the operating system’s web view, your only recourse will be to ask your customers to upgrade their operating system. If no upgrade is available for that machine (because of no ability to upgrade to the latest macOS or Windows 11), you’ll have to ask them to buy a new computer. If you’re unlucky, you’re now losing a major customer because they will not upgrade their entire fleet of thousands of machines just because one team wanted to try your startup’s app. You have _no recourse_ in this situation. Even the risk of that happening is unacceptable to the companies that employ the Electron maintainers.
|
||||
- **Security:** Similar to how you can fix stability bugs by releasing an app update, you can also release security fixes to your application without asking your customer to upgrade their operating system. Even if operating system providers prioritize updates to their built-in browser, we have not seen them reliably update the built-in web views with similar urgency. Bundling a web renderer gives you, the developer, control.
|
||||
- **Performance:** For simple HTML documents, a built-in web view will sometimes use fewer resources than an app with a bundled framework. For bigger apps, it is our experience that we can deliver better performance with the latest version of Chromium than we can with built-in web views. You might think that the built-in view can share a lot of resources with other apps and the operating system— but for security reasons, apps have to run in their own sandboxes, isolated from each other. At that point, the question is whether the OS’ web view is more performant than Chromium. Across many apps, our experience is that bundling Chromium and Node.js enables us to build better and more performant experiences.
|
||||
|
||||
#### Why bundle Chromium and Node.js
|
||||
|
||||
Electron aims to enable the apps it supports to deliver the best possible user experience, followed by the best possible developer experience. Chromium is currently the best cross-platform rendering stack available. Node.js uses Chromium’s JavaScript engine V8, allowing us to combine the powers of both.
|
||||
|
||||
- **Native code when you want it**: Thanks to Node.js’ mature native addon system, you can always write native code. There is no system API out of reach for you. Whatever macOS, Windows, or Linux feature you’ll want to integrate with —as long as you can do it in C, C++, Objective-C, Rust, or another native language, you’ll be able to do it in Electron. Again, this gives you, the developer, maximum control. With Electron, you can use web technologies without choosing _only_ web technologies.
|
||||
|
||||
### Developer experience
|
||||
|
||||
To summarize, we aim to build an Electron that is mature, enterprise-grade, and ready for mission-critical applications. We prioritize reliability, stability, security, and performance. That said, you might also choose Electron for its developer experience:
|
||||
|
||||
- **Powerful ecosystem**: Anything you find on npm will run inside Electron. Any resource available to you about how to work with Node.js also applies to Electron. In addition, Electron itself has a [thriving ecosystem](https://www.npmjs.com/search?q=electron) — including plenty of choices for installers, updaters, deeper operating system-integration, and more.
|
||||
- **Plenty of built-in capabilities:** Over the last ten years, Electron’s core has gained plenty of native capabilities that you might need to build your application. Written in C++ and Objective-C, Electron has [dozens of easy-to-use APIs for deeper operating-system integration](https://www.electronjs.org/docs/latest/api/app) — like advanced window customization for transparent or oddly shaped widgets, receiving push notifications from the Apple Push Notification Network, or handling a custom URL protocol for your app.
|
||||
- **Open source**: The entire stack is open source and open to your inspection. This ensures your freedom to add any feature or fix any bug you might encounter in the future.
|
||||
- **Native code when you need it:** It bears repeating that Electron allows you to mix and match web technologies and C++, C, Objective-C, Rust, and other native languages. Whether it be SQLite, a whole LLM, or just the ability to call one specific native API, Electron will make it easy.
|
||||
|
||||
---
|
||||
|
||||
## Why choose something else
|
||||
|
||||
As outlined above, the web is an amazing platform for building interfaces. That doesn’t mean that we, the maintainers, would build _everything_ with HTML and CSS. Here are some notable exceptions:
|
||||
|
||||
**Resource-Constrained Environments and IoT:** In scenarios with very limited memory or processing power (say, one megabyte of memory and 100MHz of processing power on a low-powered ARM Cortex-M), you will likely need to use a low-level language to directly talk to the display to output basic text and images. Even on slightly higher-powered single-chip devices you might want to consider an embedded UI framework. A classic example is a smart watch.
|
||||
|
||||
**Small Disk Footprint**: Zipped Electron apps are usually around 80 to 100 Megabytes. If a smaller disk footprint is a hard requirement, you’ll have to use something else.
|
||||
|
||||
**Operating System UI Frameworks and Libraries**: By allowing you to write native code, Electron can do anything a native application can do, including the use of the operating system’s UI components, like WinUI, SwiftUI, or AppKit. In practice, most Electron apps make rare use of that ability. If you want the majority of your app to be built with operating system-provided interface components, you’ll likely be better off building fully native apps for each operating system you’d like to target. It’s not that it’s impossible with Electron, it’ll just likely be an overall easier development process.
|
||||
|
||||
**Games and Real-Time Graphics:** If you're building a high-performance game or application requiring complex real-time 3D graphics, native frameworks like Unity, Unreal Engine, or DirectX/OpenGL will provide better performance and more direct access to graphics hardware. Web fans might point out caveats, like the fact that even Unreal Engine ships with Chromium — or that WebGPU and WebGL are developing rapidly and many game engines, including the ones listed here, can now output their games in a format that runs in a browser. That said, if you asked us to build the next AAA game, we’d likely use something else than just web technologies.
|
||||
|
||||
**Embedding Lightweight Websites**: Electron apps typically are mostly web apps with native code sprinkled in where useful. Processing-heavy Electron applications tend to write the UI in HTML/CSS and build the backend in Rust, C++, or another native language. If you’re planning to build a primarily native application that also wants to display a little website in a specific view, you might be better off using the OS-provided web view or something like [ultralight](https://ultralig.ht/).
|
||||
@@ -456,8 +456,6 @@ filenames = {
|
||||
"shell/browser/net/system_network_context_manager.h",
|
||||
"shell/browser/net/url_loader_network_observer.cc",
|
||||
"shell/browser/net/url_loader_network_observer.h",
|
||||
"shell/browser/net/url_pipe_loader.cc",
|
||||
"shell/browser/net/url_pipe_loader.h",
|
||||
"shell/browser/net/web_request_api_interface.h",
|
||||
"shell/browser/network_hints_handler_impl.cc",
|
||||
"shell/browser/network_hints_handler_impl.h",
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as deprecate from '@electron/internal/common/deprecate';
|
||||
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';
|
||||
|
||||
import { app, ipcMain, session, webFrameMain, dialog } from 'electron/main';
|
||||
import type { BrowserWindowConstructorOptions, MessageBoxOptions } from 'electron/main';
|
||||
import type { BrowserWindowConstructorOptions, MessageBoxOptions, NavigationEntry } from 'electron/main';
|
||||
|
||||
import * as path from 'path';
|
||||
import * as url from 'url';
|
||||
@@ -343,8 +343,8 @@ WebContents.prototype.loadFile = function (filePath, options = {}) {
|
||||
|
||||
type LoadError = { errorCode: number, errorDescription: string, url: string };
|
||||
|
||||
WebContents.prototype.loadURL = function (url, options) {
|
||||
const p = new Promise<void>((resolve, reject) => {
|
||||
function _awaitNextLoad (this: Electron.WebContents, navigationUrl: string) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
const resolveAndCleanup = () => {
|
||||
removeListeners();
|
||||
resolve();
|
||||
@@ -402,7 +402,7 @@ WebContents.prototype.loadURL = function (url, options) {
|
||||
// the only one is with a bad scheme, perhaps ERR_INVALID_ARGUMENT
|
||||
// would be more appropriate.
|
||||
if (!error) {
|
||||
error = { errorCode: -2, errorDescription: 'ERR_FAILED', url };
|
||||
error = { errorCode: -2, errorDescription: 'ERR_FAILED', url: navigationUrl };
|
||||
}
|
||||
finishListener();
|
||||
};
|
||||
@@ -426,6 +426,10 @@ WebContents.prototype.loadURL = function (url, options) {
|
||||
this.on('did-stop-loading', stopLoadingListener);
|
||||
this.on('destroyed', stopLoadingListener);
|
||||
});
|
||||
};
|
||||
|
||||
WebContents.prototype.loadURL = function (url, options) {
|
||||
const p = _awaitNextLoad.call(this, url);
|
||||
// Add a no-op rejection handler to silence the unhandled rejection error.
|
||||
p.catch(() => {});
|
||||
this._loadURL(url, options ?? {});
|
||||
@@ -609,7 +613,27 @@ WebContents.prototype._init = function () {
|
||||
length: this._historyLength.bind(this),
|
||||
getEntryAtIndex: this._getNavigationEntryAtIndex.bind(this),
|
||||
removeEntryAtIndex: this._removeNavigationEntryAtIndex.bind(this),
|
||||
getAllEntries: this._getHistory.bind(this)
|
||||
getAllEntries: this._getHistory.bind(this),
|
||||
restore: ({ index, entries }: { index?: number, entries: NavigationEntry[] }) => {
|
||||
if (index === undefined) {
|
||||
index = entries.length - 1;
|
||||
}
|
||||
|
||||
if (index < 0 || !entries[index]) {
|
||||
throw new Error('Invalid index. Index must be a positive integer and within the bounds of the entries length.');
|
||||
}
|
||||
|
||||
const p = _awaitNextLoad.call(this, entries[index].url);
|
||||
p.catch(() => {});
|
||||
|
||||
try {
|
||||
this._restoreHistory(index, entries);
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
},
|
||||
writable: false,
|
||||
enumerable: true
|
||||
|
||||
@@ -84,7 +84,6 @@ feat_filter_out_non-shareable_windows_in_the_current_application_in.patch
|
||||
disable_freezing_flags_after_init_in_node.patch
|
||||
short-circuit_permissions_checks_in_mediastreamdevicescontroller.patch
|
||||
chore_add_electron_deps_to_gitignores.patch
|
||||
chore_allow_chromium_to_handle_synthetic_mouse_events_for_touch.patch
|
||||
add_maximized_parameter_to_linuxui_getwindowframeprovider.patch
|
||||
add_electron_deps_to_license_credits_file.patch
|
||||
fix_crash_loading_non-standard_schemes_in_iframes.patch
|
||||
@@ -128,7 +127,7 @@ fix_font_face_resolution_when_renderer_is_blocked.patch
|
||||
feat_enable_passing_exit_code_on_service_process_crash.patch
|
||||
chore_remove_reference_to_chrome_browser_themes.patch
|
||||
feat_enable_customizing_symbol_color_in_framecaptionbutton.patch
|
||||
build_expose_webplugininfo_interface_to_electron.patch
|
||||
build_allow_electron_mojom_interfaces_to_depend_on_blink.patch
|
||||
osr_shared_texture_remove_keyed_mutex_on_win_dxgi.patch
|
||||
feat_allow_usage_of_sccontentsharingpicker_on_supported_platforms.patch
|
||||
chore_partial_revert_of.patch
|
||||
@@ -137,3 +136,18 @@ refactor_unfilter_unresponsive_events.patch
|
||||
support_bstr_pkey_appusermodel_id_in_windows_shortcuts.patch
|
||||
cherry-pick-1282289030ab.patch
|
||||
cherry-pick-3dc17c461b12.patch
|
||||
ignore_parse_errors_for_pkey_appusermodel_toastactivatorclsid.patch
|
||||
feat_add_signals_when_embedder_cleanup_callbacks_run_for.patch
|
||||
feat_separate_content_settings_callback_for_sync_and_async_clipboard.patch
|
||||
cherry-pick-dd8e2822e507.patch
|
||||
fix_osr_stutter_in_both_cpu_and_gpu_capture_when_page_has_animation.patch
|
||||
reland_lzma_sdk_update_to_24_09.patch
|
||||
fix_drag_and_drop_icons_on_windows.patch
|
||||
cherry-pick-521faebc8a7c.patch
|
||||
cherry-pick-9dacf5694dfd.patch
|
||||
revert_blink_fix_over_invalidation_with_view_transitions.patch
|
||||
add_a_flag_to_enable_strict_js_compliance_in_audioworklet.patch
|
||||
remove_denormalenabler_from_scriptprocessornode.patch
|
||||
allow_denormal_flushing_to_outlive_scoped_object.patch
|
||||
fix_take_snapped_status_into_account_when_showing_a_window.patch
|
||||
chore_modify_chromium_handling_of_mouse_events.patch
|
||||
|
||||
@@ -0,0 +1,333 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Wilson <mjwilson@chromium.org>
|
||||
Date: Thu, 12 Dec 2024 08:45:53 -0800
|
||||
Subject: Add a flag to enable strict JS compliance in AudioWorklet
|
||||
|
||||
AudioWorklet and ScriptProcessorNode are not strictly JavaScript spec
|
||||
compliant because we disable denormal numbers for performance reasons.
|
||||
|
||||
This CL adds a flag to allow experimenting with enabling denormal
|
||||
numbers in AudioWorklet and ScriptProcessorNode, so that we can
|
||||
quantify the actual performance impact.
|
||||
|
||||
The flag can also be used as a server-side switch.
|
||||
|
||||
Bug: 382005099
|
||||
Change-Id: Ib41253cc42dd2f16c262036817cf3db4697f986f
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6077677
|
||||
Reviewed-by: Kentaro Hara <haraken@chromium.org>
|
||||
Commit-Queue: Michael Wilson <mjwilson@chromium.org>
|
||||
Reviewed-by: Hongchan Choi <hongchan@chromium.org>
|
||||
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1395444}
|
||||
|
||||
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
|
||||
index e7224e03e80f8351556b3d2d43650dad7e29edef..1b2b6128e69953be7f9f96853d76c5c0e16552fe 100644
|
||||
--- a/third_party/blink/common/features.cc
|
||||
+++ b/third_party/blink/common/features.cc
|
||||
@@ -2754,6 +2754,12 @@ BASE_FEATURE(kWebAppManifestLockScreen,
|
||||
"WebAppManifestLockScreen",
|
||||
base::FEATURE_DISABLED_BY_DEFAULT);
|
||||
|
||||
+// Allow denormals in AudioWorklet and ScriptProcessorNode, to enable strict
|
||||
+// JavaScript denormal compliance. See https://crbug.com/382005099.
|
||||
+BASE_FEATURE(kWebAudioAllowDenormalInProcessing,
|
||||
+ "WebAudioAllowDenormalInProcessing",
|
||||
+ base::FEATURE_DISABLED_BY_DEFAULT);
|
||||
+
|
||||
// Parameters can be used to control to which latency hints the feature is
|
||||
// applied.
|
||||
BASE_FEATURE_PARAM(bool,
|
||||
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h
|
||||
index e8f79c39e03f5777c1accd4446c97f18fb3e34de..0bc9302cd8f3f291949be328aba5df88e2ab0d03 100644
|
||||
--- a/third_party/blink/public/common/features.h
|
||||
+++ b/third_party/blink/public/common/features.h
|
||||
@@ -1791,6 +1791,7 @@ BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kWebAppEnableScopeExtensions);
|
||||
BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kWebAppEnableUrlHandlers);
|
||||
BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kWebAppManifestLockScreen);
|
||||
|
||||
+BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kWebAudioAllowDenormalInProcessing);
|
||||
// Parameters are used to control to which latency hints the feature is applied
|
||||
BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE_PARAM(
|
||||
bool,
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.cc
|
||||
index 0382f578a4f98cbac422d5f927c73a6b922c01b8..9a662e7730d3e01dcf8e69f66c4eafa9dd7dd031 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.cc
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.cc
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "third_party/blink/renderer/modules/webaudio/cross_thread_audio_worklet_processor_info.h"
|
||||
#include "third_party/blink/renderer/platform/audio/audio_bus.h"
|
||||
#include "third_party/blink/renderer/platform/audio/audio_utilities.h"
|
||||
+#include "third_party/blink/renderer/platform/audio/denormal_disabler.h"
|
||||
#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
|
||||
#include "third_party/blink/renderer/platform/heap/persistent.h"
|
||||
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
|
||||
@@ -52,7 +53,9 @@ AudioWorkletHandler::AudioWorkletHandler(
|
||||
const AudioWorkletNodeOptions* options)
|
||||
: AudioHandler(kNodeTypeAudioWorklet, node, sample_rate),
|
||||
name_(name),
|
||||
- param_handler_map_(param_handler_map) {
|
||||
+ param_handler_map_(param_handler_map),
|
||||
+ allow_denormal_in_processing_(base::FeatureList::IsEnabled(
|
||||
+ features::kWebAudioAllowDenormalInProcessing)) {
|
||||
DCHECK(IsMainThread());
|
||||
|
||||
for (const auto& param_name : param_handler_map_.Keys()) {
|
||||
@@ -112,7 +115,7 @@ scoped_refptr<AudioWorkletHandler> AudioWorkletHandler::Create(
|
||||
param_handler_map, options));
|
||||
}
|
||||
|
||||
-void AudioWorkletHandler::Process(uint32_t frames_to_process) {
|
||||
+void AudioWorkletHandler::ProcessInternal(uint32_t frames_to_process) {
|
||||
DCHECK(Context()->IsAudioThread());
|
||||
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("webaudio.audionode"),
|
||||
@@ -175,6 +178,15 @@ void AudioWorkletHandler::Process(uint32_t frames_to_process) {
|
||||
}
|
||||
}
|
||||
|
||||
+void AudioWorkletHandler::Process(uint32_t frames_to_process) {
|
||||
+ if (allow_denormal_in_processing_) {
|
||||
+ DenormalEnabler denormal_enabler;
|
||||
+ ProcessInternal(frames_to_process);
|
||||
+ } else {
|
||||
+ ProcessInternal(frames_to_process);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void AudioWorkletHandler::CheckNumberOfChannelsForInput(AudioNodeInput* input) {
|
||||
DCHECK(Context()->IsAudioThread());
|
||||
Context()->AssertGraphOwner();
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.h b/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.h
|
||||
index e6291f5e9e25433281646965f048a7f2abfc8c01..3ec80cd49a87a76ac03df105b37f1ae17437a328 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.h
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_handler.h
|
||||
@@ -68,6 +68,10 @@ class AudioWorkletHandler final : public AudioHandler {
|
||||
HashMap<String, scoped_refptr<AudioParamHandler>> param_handler_map,
|
||||
const AudioWorkletNodeOptions*);
|
||||
|
||||
+ // Used to avoid code duplication when using scoped objects that affect
|
||||
+ // `Process`.
|
||||
+ void ProcessInternal(uint32_t frames_to_process);
|
||||
+
|
||||
String name_;
|
||||
|
||||
double tail_time_ = std::numeric_limits<double>::infinity();
|
||||
@@ -102,6 +106,9 @@ class AudioWorkletHandler final : public AudioHandler {
|
||||
// when a processor stops invoking the user-defined `process()` callback.
|
||||
bool is_processor_active_ = true;
|
||||
|
||||
+ // Cached feature flag value
|
||||
+ const bool allow_denormal_in_processing_;
|
||||
+
|
||||
base::WeakPtrFactory<AudioWorkletHandler> weak_ptr_factory_{this};
|
||||
};
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/script_processor_handler.cc b/third_party/blink/renderer/modules/webaudio/script_processor_handler.cc
|
||||
index d3d44d2a4c87bf5d4191807ec31d87c7e597fef9..ea04e2cd2bfb553a58ba6fb9c63c70c5a2690442 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/script_processor_handler.cc
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/script_processor_handler.cc
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h"
|
||||
#include "third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.h"
|
||||
#include "third_party/blink/renderer/modules/webaudio/script_processor_node.h"
|
||||
+#include "third_party/blink/renderer/platform/audio/denormal_disabler.h"
|
||||
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
|
||||
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
|
||||
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_base.h"
|
||||
@@ -48,7 +49,9 @@ ScriptProcessorHandler::ScriptProcessorHandler(
|
||||
internal_input_bus_(AudioBus::Create(
|
||||
number_of_input_channels,
|
||||
node.context()->GetDeferredTaskHandler().RenderQuantumFrames(),
|
||||
- false)) {
|
||||
+ false)),
|
||||
+ allow_denormal_in_processing_(base::FeatureList::IsEnabled(
|
||||
+ features::kWebAudioAllowDenormalInProcessing)) {
|
||||
DCHECK_GE(buffer_size_,
|
||||
node.context()->GetDeferredTaskHandler().RenderQuantumFrames());
|
||||
DCHECK_LE(number_of_input_channels, BaseAudioContext::MaxNumberOfChannels());
|
||||
@@ -109,7 +112,7 @@ void ScriptProcessorHandler::Initialize() {
|
||||
AudioHandler::Initialize();
|
||||
}
|
||||
|
||||
-void ScriptProcessorHandler::Process(uint32_t frames_to_process) {
|
||||
+void ScriptProcessorHandler::ProcessInternal(uint32_t frames_to_process) {
|
||||
TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("webaudio.audionode"),
|
||||
"ScriptProcessorHandler::Process");
|
||||
|
||||
@@ -238,6 +241,15 @@ void ScriptProcessorHandler::Process(uint32_t frames_to_process) {
|
||||
"ScriptProcessorHandler::Process");
|
||||
}
|
||||
|
||||
+void ScriptProcessorHandler::Process(uint32_t frames_to_process) {
|
||||
+ if (allow_denormal_in_processing_) {
|
||||
+ DenormalEnabler denormal_enabler;
|
||||
+ ProcessInternal(frames_to_process);
|
||||
+ } else {
|
||||
+ ProcessInternal(frames_to_process);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void ScriptProcessorHandler::FireProcessEvent(uint32_t double_buffer_index) {
|
||||
DCHECK(IsMainThread());
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/script_processor_handler.h b/third_party/blink/renderer/modules/webaudio/script_processor_handler.h
|
||||
index 82ac7cebaefb515a04442e7a24896177d66fcb01..99103e947ade50f07a16a61bc8702d6097266296 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/script_processor_handler.h
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/script_processor_handler.h
|
||||
@@ -65,6 +65,11 @@ class ScriptProcessorHandler final : public AudioHandler {
|
||||
uint32_t number_of_output_channels,
|
||||
const HeapVector<Member<AudioBuffer>>& input_buffers,
|
||||
const HeapVector<Member<AudioBuffer>>& output_buffers);
|
||||
+
|
||||
+ // Used to avoid code duplication when using scoped objects that affect
|
||||
+ // `Process`.
|
||||
+ void ProcessInternal(uint32_t frames_to_process);
|
||||
+
|
||||
double TailTime() const override;
|
||||
double LatencyTime() const override;
|
||||
bool RequiresTailProcessing() const final;
|
||||
@@ -92,6 +97,9 @@ class ScriptProcessorHandler final : public AudioHandler {
|
||||
|
||||
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
|
||||
|
||||
+ // Cached feature flag value
|
||||
+ const bool allow_denormal_in_processing_;
|
||||
+
|
||||
base::WeakPtrFactory<ScriptProcessorHandler> weak_ptr_factory_{this};
|
||||
|
||||
FRIEND_TEST_ALL_PREFIXES(ScriptProcessorNodeTest, BufferLifetime);
|
||||
diff --git a/third_party/blink/renderer/platform/audio/denormal_disabler.h b/third_party/blink/renderer/platform/audio/denormal_disabler.h
|
||||
index e8fadf60eea81b017dc29b39c2d1cfe8c102999b..ac1cdfa026aa1f845a892e96200fd9de46a45c92 100644
|
||||
--- a/third_party/blink/renderer/platform/audio/denormal_disabler.h
|
||||
+++ b/third_party/blink/renderer/platform/audio/denormal_disabler.h
|
||||
@@ -52,28 +52,28 @@ namespace blink {
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_DENORMAL)
|
||||
-class DenormalDisabler {
|
||||
- DISALLOW_NEW();
|
||||
-
|
||||
+class DenormalModifier {
|
||||
public:
|
||||
- DenormalDisabler() { DisableDenormals(); }
|
||||
-
|
||||
- ~DenormalDisabler() { RestoreState(); }
|
||||
-
|
||||
- // This is a nop if we can flush denormals to zero in hardware.
|
||||
- static inline float FlushDenormalFloatToZero(float f) { return f; }
|
||||
+ virtual ~DenormalModifier() = default;
|
||||
|
||||
private:
|
||||
unsigned saved_csr_ = 0;
|
||||
|
||||
#if defined(COMPILER_GCC) && defined(ARCH_CPU_X86_FAMILY)
|
||||
+ protected:
|
||||
inline void DisableDenormals() {
|
||||
saved_csr_ = GetCSR();
|
||||
SetCSR(saved_csr_ | 0x8040);
|
||||
}
|
||||
|
||||
+ inline void EnableDenormals() {
|
||||
+ saved_csr_ = GetCSR();
|
||||
+ SetCSR(saved_csr_ & (~0x8040));
|
||||
+ }
|
||||
+
|
||||
inline void RestoreState() { SetCSR(saved_csr_); }
|
||||
|
||||
+ private:
|
||||
inline int GetCSR() {
|
||||
int result;
|
||||
asm volatile("stmxcsr %0" : "=m"(result));
|
||||
@@ -86,6 +86,7 @@ class DenormalDisabler {
|
||||
}
|
||||
|
||||
#elif BUILDFLAG(IS_WIN) && defined(COMPILER_MSVC)
|
||||
+ protected:
|
||||
inline void DisableDenormals() {
|
||||
// Save the current state, and set mode to flush denormals.
|
||||
//
|
||||
@@ -95,11 +96,18 @@ class DenormalDisabler {
|
||||
_controlfp_s(&unused, _DN_FLUSH, _MCW_DN);
|
||||
}
|
||||
|
||||
+ inline void EnableDenormals() {
|
||||
+ _controlfp_s(&saved_csr_, 0, 0);
|
||||
+ unsigned unused;
|
||||
+ _controlfp_s(&unused, _DN_SAVE, _MCW_DN);
|
||||
+ }
|
||||
+
|
||||
inline void RestoreState() {
|
||||
unsigned unused;
|
||||
_controlfp_s(&unused, saved_csr_, _MCW_DN);
|
||||
}
|
||||
#elif defined(ARCH_CPU_ARM_FAMILY)
|
||||
+ protected:
|
||||
inline void DisableDenormals() {
|
||||
saved_csr_ = GetStatusWord();
|
||||
// Bit 24 is the flush-to-zero mode control bit. Setting it to 1 flushes
|
||||
@@ -107,8 +115,14 @@ class DenormalDisabler {
|
||||
SetStatusWord(saved_csr_ | (1 << 24));
|
||||
}
|
||||
|
||||
+ inline void EnableDenormals() {
|
||||
+ saved_csr_ = GetStatusWord();
|
||||
+ SetStatusWord(saved_csr_ & (~(1 << 24)));
|
||||
+ }
|
||||
+
|
||||
inline void RestoreState() { SetStatusWord(saved_csr_); }
|
||||
|
||||
+ private:
|
||||
inline int GetStatusWord() {
|
||||
int result;
|
||||
#if defined(ARCH_CPU_ARM64)
|
||||
@@ -130,13 +144,33 @@ class DenormalDisabler {
|
||||
#endif
|
||||
};
|
||||
|
||||
+class DenormalDisabler final : public DenormalModifier {
|
||||
+ DISALLOW_NEW();
|
||||
+
|
||||
+ public:
|
||||
+ DenormalDisabler() { DisableDenormals(); }
|
||||
+ ~DenormalDisabler() final { RestoreState(); }
|
||||
+
|
||||
+ // This is a nop if we can flush denormals to zero in hardware.
|
||||
+ static inline float FlushDenormalFloatToZero(float f) { return f; }
|
||||
+};
|
||||
+
|
||||
+class DenormalEnabler final : public DenormalModifier {
|
||||
+ DISALLOW_NEW();
|
||||
+
|
||||
+ public:
|
||||
+ DenormalEnabler() { EnableDenormals(); }
|
||||
+ ~DenormalEnabler() final { RestoreState(); }
|
||||
+};
|
||||
+
|
||||
#else
|
||||
// FIXME: add implementations for other architectures and compilers
|
||||
class DenormalDisabler {
|
||||
STACK_ALLOCATED();
|
||||
|
||||
public:
|
||||
- DenormalDisabler() {}
|
||||
+ DenormalDisabler() = default;
|
||||
+ ~DenormalDisabler() = default;
|
||||
|
||||
// Assume the worst case that other architectures and compilers
|
||||
// need to flush denormals to zero manually.
|
||||
@@ -145,6 +179,14 @@ class DenormalDisabler {
|
||||
}
|
||||
};
|
||||
|
||||
+class DenormalEnabler {
|
||||
+ STACK_ALLOCATED();
|
||||
+
|
||||
+ public:
|
||||
+ DenormalEnabler() = default;
|
||||
+ ~DenormalEnabler() = default;
|
||||
+};
|
||||
+
|
||||
#endif
|
||||
|
||||
} // namespace blink
|
||||
@@ -23,7 +23,7 @@ index ad0092ef2e13853e4bb8b923481559a043b00ab7..1c2dfd23f18733e21312992877ae1499
|
||||
int32_t world_id) {}
|
||||
virtual void DidClearWindowObject() {}
|
||||
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
|
||||
index 3d0544422f05e2edc02921fc39335bf10184028e..bf44c1ffef7df44448ee7b5b176c33348599f0be 100644
|
||||
index 6f932370352cb64a218ab93fa04f70a00947c228..df0a2685638b8f9b75f97ec96dd4c8706c013e7e 100644
|
||||
--- a/content/renderer/render_frame_impl.cc
|
||||
+++ b/content/renderer/render_frame_impl.cc
|
||||
@@ -4792,6 +4792,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
|
||||
|
||||
@@ -0,0 +1,293 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Wilson <mjwilson@chromium.org>
|
||||
Date: Fri, 7 Feb 2025 13:33:40 -0800
|
||||
Subject: Allow denormal flushing to outlive scoped object
|
||||
|
||||
After this refactor we can disable or enable denormals for longer than
|
||||
a scoped object.
|
||||
|
||||
Use this new functionality in audio_worklet_global_scope.cc.
|
||||
|
||||
(cherry picked from commit 93c4f6fb0a0f10562ef9a637449605caae9200e6)
|
||||
|
||||
Bug: 382005099
|
||||
Change-Id: I54f4810a4ec035f639d50275e14dae03b726b876
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6226252
|
||||
Reviewed-by: Hongchan Choi <hongchan@chromium.org>
|
||||
Reviewed-by: Kentaro Hara <haraken@chromium.org>
|
||||
Commit-Queue: Michael Wilson <mjwilson@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1415886}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6242822
|
||||
Reviewed-by: Dave Tapuska <dtapuska@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/6998@{#221}
|
||||
Cr-Branched-From: de9c6fafd8ae5c6ea0438764076ca7d04a0b165d-refs/heads/main@{#1415337}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc
|
||||
index c9bd1e8934d7058cb4c8044aa5618033ec975cec..09de112b96b6062f702d57e6181dd39e681e99a1 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "third_party/blink/renderer/modules/webaudio/audio_worklet_processor.h"
|
||||
#include "third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.h"
|
||||
#include "third_party/blink/renderer/modules/webaudio/cross_thread_audio_worklet_processor_info.h"
|
||||
+#include "third_party/blink/renderer/platform/audio/denormal_disabler.h"
|
||||
#include "third_party/blink/renderer/platform/bindings/callback_method_retriever.h"
|
||||
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
|
||||
|
||||
@@ -34,6 +35,9 @@ AudioWorkletGlobalScope::AudioWorkletGlobalScope(
|
||||
: WorkletGlobalScope(std::move(creation_params),
|
||||
thread->GetWorkerReportingProxy(),
|
||||
thread) {
|
||||
+ // Disable denormals for performance.
|
||||
+ DenormalModifier::DisableDenormals();
|
||||
+
|
||||
// Audio is prone to jank introduced by e.g. the garbage collector. Workers
|
||||
// are generally put in a background mode (as they are non-visible). Audio is
|
||||
// an exception here, requiring low-latency behavior similar to any visible
|
||||
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn
|
||||
index ffb2cc23eb74da99ca5875293879659b4f171303..01366aa7b5b4438f9d62de4065623a1ede71cc41 100644
|
||||
--- a/third_party/blink/renderer/platform/BUILD.gn
|
||||
+++ b/third_party/blink/renderer/platform/BUILD.gn
|
||||
@@ -2142,6 +2142,7 @@ source_set("blink_platform_unittests_sources") {
|
||||
"animation/timing_function_test.cc",
|
||||
"audio/audio_destination_test.cc",
|
||||
"audio/audio_frame_stats_accumulator_test.cc",
|
||||
+ "audio/denormal_disabler_test.cc",
|
||||
"audio/push_pull_fifo_multithread_test.cc",
|
||||
"audio/push_pull_fifo_test.cc",
|
||||
"audio/vector_math_test.cc",
|
||||
diff --git a/third_party/blink/renderer/platform/audio/denormal_disabler.h b/third_party/blink/renderer/platform/audio/denormal_disabler.h
|
||||
index ac1cdfa026aa1f845a892e96200fd9de46a45c92..a50d7b884e8fdc65f4c1fbe6b5cab7a7801a3b62 100644
|
||||
--- a/third_party/blink/renderer/platform/audio/denormal_disabler.h
|
||||
+++ b/third_party/blink/renderer/platform/audio/denormal_disabler.h
|
||||
@@ -56,74 +56,65 @@ class DenormalModifier {
|
||||
public:
|
||||
virtual ~DenormalModifier() = default;
|
||||
|
||||
- private:
|
||||
- unsigned saved_csr_ = 0;
|
||||
-
|
||||
#if defined(COMPILER_GCC) && defined(ARCH_CPU_X86_FAMILY)
|
||||
- protected:
|
||||
- inline void DisableDenormals() {
|
||||
- saved_csr_ = GetCSR();
|
||||
- SetCSR(saved_csr_ | 0x8040);
|
||||
+ public:
|
||||
+ static void DisableDenormals() {
|
||||
+ unsigned old_csr = GetCsr();
|
||||
+ SetCsr(old_csr | 0x8040);
|
||||
}
|
||||
|
||||
- inline void EnableDenormals() {
|
||||
- saved_csr_ = GetCSR();
|
||||
- SetCSR(saved_csr_ & (~0x8040));
|
||||
+ static void EnableDenormals() {
|
||||
+ unsigned old_csr = GetCsr();
|
||||
+ SetCsr(old_csr & (~0x8040));
|
||||
}
|
||||
|
||||
- inline void RestoreState() { SetCSR(saved_csr_); }
|
||||
-
|
||||
- private:
|
||||
- inline int GetCSR() {
|
||||
+ protected:
|
||||
+ static inline unsigned GetCsr() {
|
||||
int result;
|
||||
asm volatile("stmxcsr %0" : "=m"(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
- inline void SetCSR(int a) {
|
||||
+ static inline void SetCsr(int a) {
|
||||
int temp = a;
|
||||
asm volatile("ldmxcsr %0" : : "m"(temp));
|
||||
}
|
||||
|
||||
#elif BUILDFLAG(IS_WIN) && defined(COMPILER_MSVC)
|
||||
+ public:
|
||||
+ static void DisableDenormals() { SetCsr(_DN_FLUSH); }
|
||||
+
|
||||
+ static void EnableDenormals() { SetCsr(_DN_SAVE); }
|
||||
+
|
||||
protected:
|
||||
- inline void DisableDenormals() {
|
||||
- // Save the current state, and set mode to flush denormals.
|
||||
- //
|
||||
- // http://stackoverflow.com/questions/637175/possible-bug-in-controlfp-s-may-not-restore-control-word-correctly
|
||||
- _controlfp_s(&saved_csr_, 0, 0);
|
||||
- unsigned unused;
|
||||
- _controlfp_s(&unused, _DN_FLUSH, _MCW_DN);
|
||||
+ static inline unsigned GetCsr() {
|
||||
+ unsigned result;
|
||||
+ _controlfp_s(&result, 0, 0);
|
||||
+ return result;
|
||||
}
|
||||
|
||||
- inline void EnableDenormals() {
|
||||
- _controlfp_s(&saved_csr_, 0, 0);
|
||||
+ static inline void SetCsr(unsigned a) {
|
||||
+ // http://stackoverflow.com/questions/637175/possible-bug-in-controlfp-s-may-not-restore-control-word-correctly
|
||||
unsigned unused;
|
||||
- _controlfp_s(&unused, _DN_SAVE, _MCW_DN);
|
||||
+ _controlfp_s(&unused, a, _MCW_DN);
|
||||
}
|
||||
|
||||
- inline void RestoreState() {
|
||||
- unsigned unused;
|
||||
- _controlfp_s(&unused, saved_csr_, _MCW_DN);
|
||||
- }
|
||||
#elif defined(ARCH_CPU_ARM_FAMILY)
|
||||
- protected:
|
||||
- inline void DisableDenormals() {
|
||||
- saved_csr_ = GetStatusWord();
|
||||
+ public:
|
||||
+ static void DisableDenormals() {
|
||||
+ unsigned old_csr = GetCsr();
|
||||
// Bit 24 is the flush-to-zero mode control bit. Setting it to 1 flushes
|
||||
// denormals to 0.
|
||||
- SetStatusWord(saved_csr_ | (1 << 24));
|
||||
+ SetCsr(old_csr | (1 << 24));
|
||||
}
|
||||
|
||||
- inline void EnableDenormals() {
|
||||
- saved_csr_ = GetStatusWord();
|
||||
- SetStatusWord(saved_csr_ & (~(1 << 24)));
|
||||
+ static void EnableDenormals() {
|
||||
+ unsigned old_csr = GetCsr();
|
||||
+ SetCsr(old_csr & (~(1 << 24)));
|
||||
}
|
||||
|
||||
- inline void RestoreState() { SetStatusWord(saved_csr_); }
|
||||
-
|
||||
- private:
|
||||
- inline int GetStatusWord() {
|
||||
+ protected:
|
||||
+ static inline unsigned GetCsr() {
|
||||
int result;
|
||||
#if defined(ARCH_CPU_ARM64)
|
||||
asm volatile("mrs %x[result], FPCR" : [result] "=r"(result));
|
||||
@@ -133,7 +124,7 @@ class DenormalModifier {
|
||||
return result;
|
||||
}
|
||||
|
||||
- inline void SetStatusWord(int a) {
|
||||
+ static inline void SetCsr(int a) {
|
||||
#if defined(ARCH_CPU_ARM64)
|
||||
asm volatile("msr FPCR, %x[src]" : : [src] "r"(a));
|
||||
#else
|
||||
@@ -148,24 +139,44 @@ class DenormalDisabler final : public DenormalModifier {
|
||||
DISALLOW_NEW();
|
||||
|
||||
public:
|
||||
- DenormalDisabler() { DisableDenormals(); }
|
||||
- ~DenormalDisabler() final { RestoreState(); }
|
||||
+ DenormalDisabler() {
|
||||
+ // Save the current state, and set mode to flush denormals.
|
||||
+ saved_csr_ = GetCsr();
|
||||
+ DisableDenormals();
|
||||
+ }
|
||||
+ ~DenormalDisabler() final { SetCsr(saved_csr_); }
|
||||
|
||||
// This is a nop if we can flush denormals to zero in hardware.
|
||||
static inline float FlushDenormalFloatToZero(float f) { return f; }
|
||||
+
|
||||
+ private:
|
||||
+ unsigned saved_csr_ = 0;
|
||||
};
|
||||
|
||||
class DenormalEnabler final : public DenormalModifier {
|
||||
DISALLOW_NEW();
|
||||
|
||||
public:
|
||||
- DenormalEnabler() { EnableDenormals(); }
|
||||
- ~DenormalEnabler() final { RestoreState(); }
|
||||
+ DenormalEnabler() {
|
||||
+ saved_csr_ = GetCsr();
|
||||
+ EnableDenormals();
|
||||
+ }
|
||||
+ ~DenormalEnabler() final { SetCsr(saved_csr_); }
|
||||
+
|
||||
+ private:
|
||||
+ unsigned saved_csr_ = 0;
|
||||
};
|
||||
|
||||
#else
|
||||
// FIXME: add implementations for other architectures and compilers
|
||||
-class DenormalDisabler {
|
||||
+class DenormalModifier final {
|
||||
+ public:
|
||||
+ virtual ~DenormalModifier() = default;
|
||||
+ static void DisableDenormals() {}
|
||||
+ static void EnableDenormals() {}
|
||||
+};
|
||||
+
|
||||
+class DenormalDisabler final {
|
||||
STACK_ALLOCATED();
|
||||
|
||||
public:
|
||||
@@ -179,7 +190,7 @@ class DenormalDisabler {
|
||||
}
|
||||
};
|
||||
|
||||
-class DenormalEnabler {
|
||||
+class DenormalEnabler final {
|
||||
STACK_ALLOCATED();
|
||||
|
||||
public:
|
||||
diff --git a/third_party/blink/renderer/platform/audio/denormal_disabler_test.cc b/third_party/blink/renderer/platform/audio/denormal_disabler_test.cc
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5083bbf2da9d4e0e12f1a4608d5e14e4ca910297
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/renderer/platform/audio/denormal_disabler_test.cc
|
||||
@@ -0,0 +1,51 @@
|
||||
+// Copyright 2025 The Chromium Authors
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+#include "third_party/blink/renderer/platform/audio/denormal_disabler.h"
|
||||
+
|
||||
+#include "testing/gtest/include/gtest/gtest.h"
|
||||
+
|
||||
+namespace blink {
|
||||
+
|
||||
+namespace {
|
||||
+
|
||||
+bool DenormalsAreFlushedToZero() {
|
||||
+ volatile double denorm = 2.225e-308;
|
||||
+ return !((denorm / 2.0) > 0.0);
|
||||
+}
|
||||
+
|
||||
+TEST(DenormalDisablerTest, DisableScoped) {
|
||||
+ const bool already_flushed = DenormalsAreFlushedToZero();
|
||||
+ if (!already_flushed) {
|
||||
+ DenormalDisabler scoped_disabler;
|
||||
+ EXPECT_TRUE(DenormalsAreFlushedToZero());
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+TEST(DenormalDisablerTest, EnableScoped) {
|
||||
+ const bool already_flushed = DenormalsAreFlushedToZero();
|
||||
+ if (!already_flushed) {
|
||||
+ DenormalDisabler scoped_disabler;
|
||||
+ EXPECT_TRUE(DenormalsAreFlushedToZero());
|
||||
+ {
|
||||
+ DenormalEnabler scoped_enabler;
|
||||
+ EXPECT_FALSE(DenormalsAreFlushedToZero());
|
||||
+ }
|
||||
+ EXPECT_TRUE(DenormalsAreFlushedToZero());
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+TEST(DenormalDisablerTest, ModifyUnscoped) {
|
||||
+ const bool already_flushed = DenormalsAreFlushedToZero();
|
||||
+ if (!already_flushed) {
|
||||
+ DenormalModifier::DisableDenormals();
|
||||
+ EXPECT_TRUE(DenormalsAreFlushedToZero());
|
||||
+ DenormalModifier::EnableDenormals();
|
||||
+ EXPECT_FALSE(DenormalsAreFlushedToZero());
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+} // namespace
|
||||
+
|
||||
+} // namespace blink
|
||||
@@ -1,20 +1,24 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: deepak1556 <hop2deep@gmail.com>
|
||||
Date: Fri, 9 Aug 2024 22:39:47 +0900
|
||||
Subject: build: expose webplugininfo interface to electron
|
||||
Subject: build: allow electron mojom interfaces to depend on blink
|
||||
mojom_platform
|
||||
|
||||
Allows implementing electron::mojom::ElectronPluginInfoHost interface
|
||||
which provides plugin details between browser<->renderer.
|
||||
Needed for:
|
||||
|
||||
1) //electron/shell/common:plugin
|
||||
2) //electron/shell/common:web_contents_utility
|
||||
|
||||
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn
|
||||
index b84e3a73036b0bc2b782d35c04359ba401521917..2d8b206a118592f15a93c2a7bcb2c37c80571cd8 100644
|
||||
index b84e3a73036b0bc2b782d35c04359ba401521917..0099cf78779215bcc85ce3fb57cb34827337111e 100644
|
||||
--- a/content/public/common/BUILD.gn
|
||||
+++ b/content/public/common/BUILD.gn
|
||||
@@ -377,6 +377,7 @@ mojom("interfaces") {
|
||||
@@ -377,6 +377,8 @@ mojom("interfaces") {
|
||||
"//content/common/*",
|
||||
"//extensions/common:mojom",
|
||||
"//extensions/common:mojom_blink",
|
||||
+ "//electron/shell/common:plugin",
|
||||
+ "//electron/shell/common:web_contents_utility",
|
||||
]
|
||||
|
||||
sources = [
|
||||
@@ -33,10 +33,10 @@ index 9580623c57cb02f7e924742c6cb1638676881115..ad80d8e63dfebbbdb8eaa63bfe38a6f8
|
||||
"//base",
|
||||
"//build:branding_buildflags",
|
||||
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
|
||||
index 3914cb63eed91e0e8a6eb8b64092c5dbe5348781..a6a24986f33fb79d3226840ffaa62448026f7383 100644
|
||||
index c2c22a92bccb2487319affed384cac10dbc839a8..d3bccc91ebe651d3075325aaf9d0c5114e238b85 100644
|
||||
--- a/chrome/browser/BUILD.gn
|
||||
+++ b/chrome/browser/BUILD.gn
|
||||
@@ -4525,7 +4525,7 @@ static_library("browser") {
|
||||
@@ -4524,7 +4524,7 @@ static_library("browser") {
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -9,10 +9,10 @@ potentially prevent a window from being created.
|
||||
TODO(loc): this patch is currently broken.
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
index 95b2ad64c83361c452f9256cf96873f2cd82b446..53f96ccd4954972bc78ebccf4bf479ac8564a8d3 100644
|
||||
index 469e49a552a2229e8686953d5b10b5d1ac974d4e..01367204ab9d872077547c2b2c33c58d9a1653b9 100644
|
||||
--- a/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
@@ -9179,6 +9179,7 @@ void RenderFrameHostImpl::CreateNewWindow(
|
||||
@@ -9188,6 +9188,7 @@ void RenderFrameHostImpl::CreateNewWindow(
|
||||
last_committed_origin_, params->window_container_type,
|
||||
params->target_url, params->referrer.To<Referrer>(),
|
||||
params->frame_name, params->disposition, *params->features,
|
||||
@@ -21,10 +21,10 @@ index 95b2ad64c83361c452f9256cf96873f2cd82b446..53f96ccd4954972bc78ebccf4bf479ac
|
||||
&no_javascript_access);
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index ea5a63ce49a1eb99792be2eafc64c44ad6da0a60..a722f77502e8b896fb5d55df7cb44d45d13df04f 100644
|
||||
index 62420958702cebe16423f0ea42ca200f5a93d45a..d35ae086793a52ea38da97b9236e073b806a67a6 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -4891,6 +4891,12 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
@@ -4895,6 +4895,12 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
SetPartitionedPopinOpenerOnNewWindowIfNeeded(new_contents_impl, params,
|
||||
opener);
|
||||
|
||||
@@ -37,7 +37,7 @@ index ea5a63ce49a1eb99792be2eafc64c44ad6da0a60..a722f77502e8b896fb5d55df7cb44d45
|
||||
// If the new frame has a name, make sure any SiteInstances that can find
|
||||
// this named frame have proxies for it. Must be called after
|
||||
// SetSessionStorageNamespace, since this calls CreateRenderView, which uses
|
||||
@@ -4932,12 +4938,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
@@ -4936,12 +4942,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
AddWebContentsDestructionObserver(new_contents_impl);
|
||||
}
|
||||
|
||||
@@ -148,10 +148,10 @@ index 77ee6ba6c65c95622e41f86906ea813be62f72e9..7f38098505afabe1887a6d98a705f1ad
|
||||
// typically happens when popups are created.
|
||||
virtual void WebContentsCreated(WebContents* source_contents,
|
||||
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
|
||||
index 6fed6b4c7ad72bd90aeb9f6eea7a3081972c88f8..3d0544422f05e2edc02921fc39335bf10184028e 100644
|
||||
index a0e45dfcf20ed570f2751a8f194b4a82b46c87b6..6f932370352cb64a218ab93fa04f70a00947c228 100644
|
||||
--- a/content/renderer/render_frame_impl.cc
|
||||
+++ b/content/renderer/render_frame_impl.cc
|
||||
@@ -6849,6 +6849,10 @@ WebView* RenderFrameImpl::CreateNewWindow(
|
||||
@@ -6865,6 +6865,10 @@ WebView* RenderFrameImpl::CreateNewWindow(
|
||||
request.HasUserGesture(), GetWebFrame()->IsAdFrame(),
|
||||
GetWebFrame()->IsAdScriptInStack());
|
||||
|
||||
@@ -210,10 +210,10 @@ index c576ace24e81cc877aa2595d40e0a13a7af9f6a2..210fb97d44c19c29af424cc7b9cb3169
|
||||
|
||||
} // namespace blink
|
||||
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
|
||||
index 00a4ed4f0625981e3bef338399957419d2cffdf0..d0db7f8727dc2fbe0a9ae0489a6aa4e278e1cb34 100644
|
||||
index ba53e2576ff7944071fd46c2d4d8635084738cb3..fb38a3b96cd32720096b106845f706d113f1794e 100644
|
||||
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
|
||||
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
|
||||
@@ -2234,6 +2234,8 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
|
||||
@@ -2235,6 +2235,8 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
|
||||
WebWindowFeatures window_features =
|
||||
GetWindowFeaturesFromString(features, entered_window);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 1282289030ab2026a8db4fb82dc6e20d3bf028be Mon Sep 17 00:00:00 2001
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Ellis <kevers@google.com>
|
||||
Date: Thu, 12 Dec 2024 06:47:30 -0800
|
||||
Subject: [PATCH] Prune superfluous calls to SetCompositorPending
|
||||
Subject: Prune superfluous calls to SetCompositorPending
|
||||
|
||||
We only need to call SetCompositorPending with the pending cancel
|
||||
reason if the animation is running on the compositor.
|
||||
@@ -17,13 +17,12 @@ Reviewed-by: Robert Flack <flackr@chromium.org>
|
||||
Commit-Queue: Kevin Ellis <kevers@chromium.org>
|
||||
Reviewed-by: Claire Chambers <clchambers@microsoft.com>
|
||||
Cr-Commit-Position: refs/heads/main@{#1395390}
|
||||
---
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/animation/animation.cc b/third_party/blink/renderer/core/animation/animation.cc
|
||||
index 9e162a6f..b58b017 100644
|
||||
index 1b384beef682c87b4bec3c9233d45529c5569b56..694ca51b1a59270289fabe70dbb381167fc89a83 100644
|
||||
--- a/third_party/blink/renderer/core/animation/animation.cc
|
||||
+++ b/third_party/blink/renderer/core/animation/animation.cc
|
||||
@@ -1271,14 +1271,7 @@
|
||||
@@ -1269,14 +1269,7 @@ void Animation::setEffect(AnimationEffect* new_effect) {
|
||||
ResolveTimelineOffsets(timeline_ ? timeline_->GetTimelineRange()
|
||||
: TimelineRange());
|
||||
|
||||
@@ -39,7 +38,7 @@ index 9e162a6f..b58b017 100644
|
||||
|
||||
// Notify of a potential state change.
|
||||
NotifyProbe();
|
||||
@@ -2375,6 +2368,26 @@
|
||||
@@ -2373,6 +2366,26 @@ void Animation::StartAnimationOnCompositor(
|
||||
timeline()->IsMonotonicallyIncreasing(), boundary_aligned);
|
||||
}
|
||||
|
||||
@@ -66,7 +65,7 @@ index 9e162a6f..b58b017 100644
|
||||
// TODO(crbug.com/960944): Rename to SetPendingCommit. This method handles both
|
||||
// composited and non-composited animations. The use of 'compositor' in the name
|
||||
// is confusing.
|
||||
@@ -2833,7 +2846,7 @@
|
||||
@@ -2831,7 +2844,7 @@ bool Animation::Update(TimingUpdateReason reason) {
|
||||
// After updating the animation time if the animation is no longer current
|
||||
// blink will no longer composite the element (see
|
||||
// CompositingReasonFinder::RequiresCompositingFor*Animation).
|
||||
@@ -75,7 +74,7 @@ index 9e162a6f..b58b017 100644
|
||||
SetCompositorPending(CompositorPendingReason::kPendingCancel);
|
||||
}
|
||||
}
|
||||
@@ -2874,6 +2887,9 @@
|
||||
@@ -2872,6 +2885,9 @@ void Animation::UpdateIfNecessary() {
|
||||
}
|
||||
|
||||
void Animation::EffectInvalidated() {
|
||||
@@ -85,7 +84,7 @@ index 9e162a6f..b58b017 100644
|
||||
SetOutdated();
|
||||
UpdateFinishedState(UpdateType::kContinuous, NotificationType::kAsync);
|
||||
// FIXME: Needs to consider groups when added.
|
||||
@@ -3381,15 +3397,22 @@
|
||||
@@ -3379,15 +3395,22 @@ bool Animation::IsInDisplayLockedSubtree() {
|
||||
}
|
||||
|
||||
void Animation::UpdateCompositedPaintStatus() {
|
||||
@@ -110,7 +109,7 @@ index 9e162a6f..b58b017 100644
|
||||
Element* target = keyframe_effect->EffectTarget();
|
||||
if (!target) {
|
||||
return;
|
||||
@@ -3398,14 +3421,7 @@
|
||||
@@ -3396,14 +3419,7 @@ void Animation::UpdateCompositedPaintStatus() {
|
||||
ElementAnimations* element_animations = target->GetElementAnimations();
|
||||
DCHECK(element_animations);
|
||||
|
||||
@@ -127,10 +126,10 @@ index 9e162a6f..b58b017 100644
|
||||
|
||||
void Animation::Trace(Visitor* visitor) const {
|
||||
diff --git a/third_party/blink/renderer/core/animation/animation.h b/third_party/blink/renderer/core/animation/animation.h
|
||||
index 61007d7..bc0a891 100644
|
||||
index c20180d785ca62417ba5e05417462fec5beeae5b..cfd2b44724c86b272982dee4db54ed5191e51d22 100644
|
||||
--- a/third_party/blink/renderer/core/animation/animation.h
|
||||
+++ b/third_party/blink/renderer/core/animation/animation.h
|
||||
@@ -393,6 +393,15 @@
|
||||
@@ -393,6 +393,15 @@ class CORE_EXPORT Animation : public EventTarget,
|
||||
start_time_ = start_time;
|
||||
}
|
||||
|
||||
@@ -146,7 +145,7 @@ index 61007d7..bc0a891 100644
|
||||
protected:
|
||||
DispatchEventResult DispatchEventInternal(Event&) override;
|
||||
void AddedEventListener(const AtomicString& event_type,
|
||||
@@ -583,6 +592,13 @@
|
||||
@@ -583,6 +592,13 @@ class CORE_EXPORT Animation : public EventTarget,
|
||||
|
||||
Member<Event> pending_remove_event_;
|
||||
|
||||
@@ -161,10 +160,10 @@ index 61007d7..bc0a891 100644
|
||||
// mutually exclusive pending_play_ and pending_pause_ flags.
|
||||
enum class CompositorAction { kNone, kStart, kCancel };
|
||||
diff --git a/third_party/blink/renderer/core/animation/element_animations.cc b/third_party/blink/renderer/core/animation/element_animations.cc
|
||||
index ca2864f..b1f3b32 100644
|
||||
index ca2864f2f7ef8b8969d63a25e85f23f5c9a97b74..b1f3b32332af4f948bb2598f1646f29c97660413 100644
|
||||
--- a/third_party/blink/renderer/core/animation/element_animations.cc
|
||||
+++ b/third_party/blink/renderer/core/animation/element_animations.cc
|
||||
@@ -97,43 +97,59 @@
|
||||
@@ -97,43 +97,59 @@ void ElementAnimations::RecalcCompositedStatusForKeyframeChange(
|
||||
Element& element,
|
||||
AnimationEffect* effect) {
|
||||
if (KeyframeEffect* keyframe_effect = DynamicTo<KeyframeEffect>(effect)) {
|
||||
@@ -251,10 +250,10 @@ index ca2864f..b1f3b32 100644
|
||||
element->GetLayoutObject()->SetShouldDoFullPaintInvalidation();
|
||||
// For clip paths, we also need to update the paint properties to switch
|
||||
diff --git a/third_party/blink/renderer/core/animation/element_animations.h b/third_party/blink/renderer/core/animation/element_animations.h
|
||||
index 624f542..3171061 100644
|
||||
index 624f542785befe6ce92e7f75eb8595a2015a77ef..3171061ceb1a0dad426481454d3698c1eee22fd0 100644
|
||||
--- a/third_party/blink/renderer/core/animation/element_animations.h
|
||||
+++ b/third_party/blink/renderer/core/animation/element_animations.h
|
||||
@@ -120,7 +120,7 @@
|
||||
@@ -120,7 +120,7 @@ class CORE_EXPORT ElementAnimations final
|
||||
|
||||
void RecalcCompositedStatusForKeyframeChange(Element& element,
|
||||
AnimationEffect* effect);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 3dc17c461b12fd735c1173a90a2ca62c086a4110 Mon Sep 17 00:00:00 2001
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Orko Garai <orko@igalia.com>
|
||||
Date: Fri, 29 Nov 2024 16:17:04 +0000
|
||||
Subject: [PATCH] Wayland IME: Underline composition text fallback
|
||||
Subject: Wayland IME: Underline composition text fallback
|
||||
|
||||
At this time text-input-v3 does not provide any styling information.
|
||||
As a quality-of-life improvement, ensure that a default composition
|
||||
@@ -17,13 +17,12 @@ Commit-Queue: Orko Garai <orko@igalia.com>
|
||||
Reviewed-by: Darren Shen <shend@chromium.org>
|
||||
Reviewed-by: Kramer Ge <fangzhoug@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1389833}
|
||||
---
|
||||
|
||||
diff --git a/ui/ozone/platform/wayland/host/wayland_input_method_context.cc b/ui/ozone/platform/wayland/host/wayland_input_method_context.cc
|
||||
index 715e181a..2cfa5cc 100644
|
||||
index a063ff09e6c388242b94dca73d31b586f12e80a1..23d9918afde6847a3776d810ed60738c59f80c30 100644
|
||||
--- a/ui/ozone/platform/wayland/host/wayland_input_method_context.cc
|
||||
+++ b/ui/ozone/platform/wayland/host/wayland_input_method_context.cc
|
||||
@@ -530,6 +530,7 @@
|
||||
@@ -552,6 +552,7 @@ void WaylandInputMethodContext::OnPreeditString(
|
||||
const gfx::Range& preedit_cursor) {
|
||||
CompositionText composition_text;
|
||||
composition_text.text = base::UTF8ToUTF16(text);
|
||||
@@ -31,7 +30,7 @@ index 715e181a..2cfa5cc 100644
|
||||
for (const auto& span : spans) {
|
||||
auto start_offset = OffsetFromUTF8Offset(text, span.index);
|
||||
if (!start_offset)
|
||||
@@ -540,9 +541,18 @@
|
||||
@@ -562,9 +563,18 @@ void WaylandInputMethodContext::OnPreeditString(
|
||||
const auto& style = span.style;
|
||||
if (!style.has_value())
|
||||
continue;
|
||||
@@ -51,10 +50,10 @@ index 715e181a..2cfa5cc 100644
|
||||
// This is the case if a preceding preedit_cursor event in text-input-v1 was
|
||||
// not received or an explicit negative value was requested to hide the
|
||||
diff --git a/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc b/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc
|
||||
index d005de4..dbb339d 100644
|
||||
index 7fed0c0a206c98764abbe2fc22110dc31b9fdbd8..24b90a83f2dad3a29634549fc4716980fe409d52 100644
|
||||
--- a/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc
|
||||
+++ b/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc
|
||||
@@ -1174,6 +1174,34 @@
|
||||
@@ -1174,6 +1174,34 @@ TEST_P(WaylandInputMethodContextTest, SetInputTypeAfterFocus) {
|
||||
});
|
||||
}
|
||||
|
||||
@@ -89,7 +88,7 @@ index d005de4..dbb339d 100644
|
||||
TEST_P(WaylandInputMethodContextTest, OnPreeditChanged) {
|
||||
constexpr std::string_view kPreeditString("PreeditString");
|
||||
constexpr gfx::Range kSelection{7, 13};
|
||||
@@ -1181,13 +1209,19 @@
|
||||
@@ -1181,13 +1209,19 @@ TEST_P(WaylandInputMethodContextTest, OnPreeditChanged) {
|
||||
kPreeditString,
|
||||
{{0,
|
||||
static_cast<uint32_t>(kPreeditString.size()),
|
||||
|
||||
32
patches/chromium/cherry-pick-521faebc8a7c.patch
Normal file
32
patches/chromium/cherry-pick-521faebc8a7c.patch
Normal file
@@ -0,0 +1,32 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Geoff Lang <geofflang@chromium.org>
|
||||
Date: Thu, 6 Mar 2025 19:39:37 -0800
|
||||
Subject: Disable setting primtive restart for WebGL in the cmd decoder.
|
||||
|
||||
Until it's blocked in ANGLE for WebGL contexts, disable it in the
|
||||
command decoder on the service side.
|
||||
|
||||
Bug: 401059730
|
||||
Change-Id: Ia9c7d951cbd122454afec2f884968e0a709cee77
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6334632
|
||||
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
Reviewed-by: Kenneth Russell <kbr@chromium.org>
|
||||
Commit-Queue: Kenneth Russell <kbr@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1429307}
|
||||
|
||||
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
|
||||
index 54310b8878fa7aeca45e6001cb884a794272138c..2cb2a3b4913a54373b84cebf9326ee09a98f6bcc 100644
|
||||
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
|
||||
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
|
||||
@@ -2160,6 +2160,11 @@ bool GLES2DecoderPassthroughImpl::IsIgnoredCap(GLenum cap) const {
|
||||
case GL_DEBUG_OUTPUT:
|
||||
return true;
|
||||
|
||||
+ case GL_PRIMITIVE_RESTART_FIXED_INDEX:
|
||||
+ // Disable setting primitive restart at the command decoder level until
|
||||
+ // it's blocked in ANGLE for WebGL contexts.
|
||||
+ return feature_info_->IsWebGLContext();
|
||||
+
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
94
patches/chromium/cherry-pick-9dacf5694dfd.patch
Normal file
94
patches/chromium/cherry-pick-9dacf5694dfd.patch
Normal file
@@ -0,0 +1,94 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Geoff Lang <geofflang@chromium.org>
|
||||
Date: Thu, 6 Mar 2025 16:02:41 -0800
|
||||
Subject: Move WebGL primitive restart state setting to the GPU process.
|
||||
|
||||
ANGLE will validate and initialize this state and errors are generated
|
||||
when the WebGL client also initializes it on startup.
|
||||
|
||||
Initialize it even in the passthrough command decoder temporarily so
|
||||
that ANGLE can roll without breaking WebGL tests.
|
||||
|
||||
Bug: 401059730
|
||||
Change-Id: I0bfee710673bbcea6f915ffc4fc9be20438a2654
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6330188
|
||||
Auto-Submit: Geoff Lang <geofflang@chromium.org>
|
||||
Commit-Queue: Kenneth Russell <kbr@chromium.org>
|
||||
Reviewed-by: Kenneth Russell <kbr@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1429228}
|
||||
|
||||
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
||||
index 03a26a5f81dee1cd1bba28621c1ecd30ea709df8..60447a8e71e056db01515db8bc6c56048537870f 100644
|
||||
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
||||
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
||||
@@ -3285,6 +3285,13 @@ gpu::ContextResult GLES2DecoderImpl::Initialize(
|
||||
}
|
||||
}
|
||||
|
||||
+ if (feature_info_->context_type() == CONTEXT_TYPE_WEBGL2) {
|
||||
+ // If WebGL 2, the PRIMITIVE_RESTART_FIXED_INDEX should be always enabled.
|
||||
+ // See the section <Primitive Restart is Always Enabled> in WebGL 2 spec:
|
||||
+ // https://www.khronos.org/registry/webgl/specs/latest/2.0/#4.1.4
|
||||
+ DoEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
|
||||
+ }
|
||||
+
|
||||
if (group_->gpu_preferences().enable_gpu_driver_debug_logging &&
|
||||
feature_info_->feature_flags().khr_debug) {
|
||||
InitializeGLDebugLogging(true, GLDebugMessageCallback, &logger_);
|
||||
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
|
||||
index 2cb2a3b4913a54373b84cebf9326ee09a98f6bcc..ee9ad4fa2838a22bc8b24185267a29687129f721 100644
|
||||
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
|
||||
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
|
||||
@@ -1065,6 +1065,17 @@ gpu::ContextResult GLES2DecoderPassthroughImpl::Initialize(
|
||||
api()->glDisableFn(GL_TEXTURE_RECTANGLE_ANGLE);
|
||||
#endif
|
||||
|
||||
+ // TEMPORARY: Set primitive restart to enabled by default for WebGL2. Clear
|
||||
+ // errors afterwards so that when this state is initialized and validated in
|
||||
+ // ANGLE, it will not generate errors during command buffer initialization.
|
||||
+ if (feature_info_->context_type() == CONTEXT_TYPE_WEBGL2) {
|
||||
+ // If WebGL 2, the PRIMITIVE_RESTART_FIXED_INDEX should be always enabled.
|
||||
+ // See the section <Primitive Restart is Always Enabled> in WebGL 2 spec:
|
||||
+ // https://www.khronos.org/registry/webgl/specs/latest/2.0/#4.1.4
|
||||
+ api()->glEnableFn(GL_PRIMITIVE_RESTART_FIXED_INDEX);
|
||||
+ CheckErrorCallbackState();
|
||||
+ }
|
||||
+
|
||||
// Register this object as a GPU switching observer.
|
||||
if (feature_info_->IsWebGLContext()) {
|
||||
ui::GpuSwitchingManager::GetInstance()->AddObserver(this);
|
||||
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
|
||||
index 1683b266f349d4b70ae2861cf4f05542380d8c44..0a0c1b3f6f9fe2caddf86602d2ae9978eff928f1 100644
|
||||
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
|
||||
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
|
||||
@@ -440,6 +440,13 @@ ContextResult GLES2DecoderTestBase::MaybeInitDecoderWithWorkarounds(
|
||||
}
|
||||
#endif
|
||||
|
||||
+ if (init.context_type == CONTEXT_TYPE_WEBGL2 &&
|
||||
+ group_->feature_info()->gl_version_info().is_es3) {
|
||||
+ EXPECT_CALL(*gl_, Enable(GL_PRIMITIVE_RESTART_FIXED_INDEX))
|
||||
+ .Times(1)
|
||||
+ .RetiresOnSaturation();
|
||||
+ }
|
||||
+
|
||||
if (context_->HasRobustness()) {
|
||||
EXPECT_CALL(*gl_, GetGraphicsResetStatusARB())
|
||||
.WillOnce(Return(init.lose_context_on_init ? GL_GUILTY_CONTEXT_RESET_ARB
|
||||
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
|
||||
index 6057cf83454f0deabc1904cb5e87b306bda4e788..304f4c7beb87212c70e91770d494254da7ed24bf 100644
|
||||
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
|
||||
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
|
||||
@@ -1432,12 +1432,6 @@ void WebGLRenderingContextBase::InitializeNewContext() {
|
||||
->GetCapabilities()
|
||||
.mesa_framebuffer_flip_y;
|
||||
|
||||
- // If WebGL 2, the PRIMITIVE_RESTART_FIXED_INDEX should be always enabled.
|
||||
- // See the section <Primitive Restart is Always Enabled> in WebGL 2 spec:
|
||||
- // https://www.khronos.org/registry/webgl/specs/latest/2.0/#4.1.4
|
||||
- if (IsWebGL2())
|
||||
- ContextGL()->Enable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
|
||||
-
|
||||
// This ensures that the context has a valid "lastFlushID" and won't be
|
||||
// mistakenly identified as the "least recently used" context.
|
||||
ContextGL()->Flush();
|
||||
71
patches/chromium/cherry-pick-dd8e2822e507.patch
Normal file
71
patches/chromium/cherry-pick-dd8e2822e507.patch
Normal file
@@ -0,0 +1,71 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Meenan <pmeenan@chromium.org>
|
||||
Date: Thu, 6 Feb 2025 07:41:40 -0800
|
||||
Subject: Set is_web_secure_context when initializing Service Worker from disk
|
||||
|
||||
The value of is_web_secure_context is not serialized to disk when
|
||||
storing the service worker registration (only a few select policies
|
||||
are).
|
||||
|
||||
When instantiating the policy container for an already-registered
|
||||
worker, it uses the default value (false) which is wrong.
|
||||
|
||||
Since Service Workers are guaranteed to ALWAYS be a web secure
|
||||
context, this change explicitly sets it to true when restoring a
|
||||
serialized policy.
|
||||
|
||||
See: https://w3c.github.io/webappsec-secure-contexts/#examples-service-workers
|
||||
|
||||
Bug: 387258077,383070811
|
||||
Change-Id: I75efe895662ab4e6d68cacace6d05e004c5dfd33
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6236205
|
||||
Reviewed-by: Hiroki Nakagawa <nhiroki@chromium.org>
|
||||
Reviewed-by: Dave Tapuska <dtapuska@chromium.org>
|
||||
Commit-Queue: Patrick Meenan <pmeenan@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1416795}
|
||||
|
||||
diff --git a/content/browser/renderer_host/policy_container_host.cc b/content/browser/renderer_host/policy_container_host.cc
|
||||
index b17c33c425da7bc98a6669c6595a7e6185a96644..9630f39ee4570d084c877f69658534affef226d2 100644
|
||||
--- a/content/browser/renderer_host/policy_container_host.cc
|
||||
+++ b/content/browser/renderer_host/policy_container_host.cc
|
||||
@@ -135,9 +135,11 @@ PolicyContainerPolicies::PolicyContainerPolicies(
|
||||
allow_cross_origin_isolation(allow_cross_origin_isolation) {}
|
||||
|
||||
PolicyContainerPolicies::PolicyContainerPolicies(
|
||||
- const blink::mojom::PolicyContainerPolicies& policies)
|
||||
+ const blink::mojom::PolicyContainerPolicies& policies,
|
||||
+ bool is_web_secure_context)
|
||||
: referrer_policy(policies.referrer_policy),
|
||||
ip_address_space(policies.ip_address_space),
|
||||
+ is_web_secure_context(is_web_secure_context),
|
||||
content_security_policies(
|
||||
mojo::Clone(policies.content_security_policies)),
|
||||
cross_origin_embedder_policy(policies.cross_origin_embedder_policy),
|
||||
diff --git a/content/browser/renderer_host/policy_container_host.h b/content/browser/renderer_host/policy_container_host.h
|
||||
index 394bd53bb5c1dfea5abe24b9047eb190884c2648..7add42348ef28079196b447feda78210815d1551 100644
|
||||
--- a/content/browser/renderer_host/policy_container_host.h
|
||||
+++ b/content/browser/renderer_host/policy_container_host.h
|
||||
@@ -49,7 +49,8 @@ struct CONTENT_EXPORT PolicyContainerPolicies {
|
||||
bool allow_cross_origin_isolation);
|
||||
|
||||
explicit PolicyContainerPolicies(
|
||||
- const blink::mojom::PolicyContainerPolicies& policies);
|
||||
+ const blink::mojom::PolicyContainerPolicies& policies,
|
||||
+ bool is_web_secure_context);
|
||||
|
||||
// Used when loading workers from network schemes.
|
||||
// WARNING: This does not populate referrer policy.
|
||||
diff --git a/content/browser/service_worker/service_worker_registry.cc b/content/browser/service_worker/service_worker_registry.cc
|
||||
index 8ce6875c21522032e8eb448338558c2a28f78613..efa037a599a38af655fd593767f35a601badd3a1 100644
|
||||
--- a/content/browser/service_worker/service_worker_registry.cc
|
||||
+++ b/content/browser/service_worker/service_worker_registry.cc
|
||||
@@ -1076,7 +1076,8 @@ ServiceWorkerRegistry::GetOrCreateRegistration(
|
||||
if (data.policy_container_policies) {
|
||||
version->set_policy_container_host(
|
||||
base::MakeRefCounted<PolicyContainerHost>(
|
||||
- PolicyContainerPolicies(*data.policy_container_policies)));
|
||||
+ PolicyContainerPolicies(*data.policy_container_policies,
|
||||
+ /*is_web_secure_context=*/true)));
|
||||
}
|
||||
if (data.router_rules && version->IsStaticRouterEnabled()) {
|
||||
auto error = version->SetupRouterEvaluator(*data.router_rules);
|
||||
@@ -1,11 +1,38 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: deepak1556 <hop2deep@gmail.com>
|
||||
Date: Fri, 29 Jul 2022 00:29:35 +0900
|
||||
Subject: chore: allow chromium to handle synthetic mouse events for touch
|
||||
Subject: chore: modify chromium handling of mouse events
|
||||
|
||||
With WCO, allow chromium to handle synthetic mouse events generated for touch
|
||||
This patch does the following:
|
||||
|
||||
1. When Windows Control Overlay is enabled, it allows chromium to handle synthetic mouse events generated for touch
|
||||
actions in the non-client caption area.
|
||||
2. It calls HandleMouseEvent on the delegate earlier in HandleMouseEventInternal, so that Electron can selectively disable
|
||||
draggable regions to allow events to propagate to the underlying renderer.
|
||||
|
||||
diff --git a/ui/events/event.h b/ui/events/event.h
|
||||
index 39b5a8fdd165efd74b00256552b51b5413107958..bfc4ef4f50efff4a77f2aef64335bb7e34c69f34 100644
|
||||
--- a/ui/events/event.h
|
||||
+++ b/ui/events/event.h
|
||||
@@ -587,6 +587,9 @@ class EVENTS_EXPORT MouseEvent : public LocatedEvent {
|
||||
|
||||
const PointerDetails& pointer_details() const { return pointer_details_; }
|
||||
|
||||
+ bool is_system_menu() const { return is_system_menu_; }
|
||||
+ void set_is_system_menu(bool is_menu) { is_system_menu_ = is_menu; }
|
||||
+
|
||||
// Event:
|
||||
std::string ToString() const override;
|
||||
std::unique_ptr<Event> Clone() const override;
|
||||
@@ -619,6 +622,8 @@ class EVENTS_EXPORT MouseEvent : public LocatedEvent {
|
||||
|
||||
// Structure for holding pointer details for implementing PointerEvents API.
|
||||
PointerDetails pointer_details_;
|
||||
+
|
||||
+ bool is_system_menu_ = false;
|
||||
};
|
||||
|
||||
class ScrollEvent;
|
||||
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
|
||||
index e2146f0a06fb70d16c48fe6e06d0615caf7d4619..f7d38f5d308eadc1dc27fd1dde706259b9197ad9 100644
|
||||
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
|
||||
@@ -34,10 +61,10 @@ index 1e2c5bb35cc314d44dba85a9bafc5e55bf2b5f14..d110d0a2f005888c4450262fc1887cbf
|
||||
Widget* GetWidget();
|
||||
const Widget* GetWidget() const;
|
||||
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
|
||||
index 9ac53e223aa095acdf90b68bc1e6bc81e3021ab9..026b0f9b404267b17e1ea6b61b5ebb188b9b0bed 100644
|
||||
index b5d8f82255764a42df816e58bfcbd588534de2e4..8ad548a445ff7f66a7fe61e0f18d04d08668a69b 100644
|
||||
--- a/ui/views/win/hwnd_message_handler.cc
|
||||
+++ b/ui/views/win/hwnd_message_handler.cc
|
||||
@@ -3042,15 +3042,19 @@ LRESULT HWNDMessageHandler::HandleMouseEventInternal(UINT message,
|
||||
@@ -3063,15 +3063,19 @@ LRESULT HWNDMessageHandler::HandleMouseEventInternal(UINT message,
|
||||
SetMsgHandled(FALSE);
|
||||
// We must let Windows handle the caption buttons if it's drawing them, or
|
||||
// they won't work.
|
||||
@@ -59,6 +86,25 @@ index 9ac53e223aa095acdf90b68bc1e6bc81e3021ab9..026b0f9b404267b17e1ea6b61b5ebb18
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3099,7 +3103,17 @@ LRESULT HWNDMessageHandler::HandleMouseEventInternal(UINT message,
|
||||
w_param = static_cast<WPARAM>(SendMessage(
|
||||
hwnd(), WM_NCHITTEST, 0, MAKELPARAM(screen_point.x, screen_point.y)));
|
||||
if (w_param == HTCAPTION || w_param == HTSYSMENU) {
|
||||
- ShowSystemMenuAtScreenPixelLocation(hwnd(), gfx::Point(screen_point));
|
||||
+ LONG message_time = GetMessageTime();
|
||||
+ CHROME_MSG msg = {hwnd(),
|
||||
+ message,
|
||||
+ w_param,
|
||||
+ l_param,
|
||||
+ static_cast<DWORD>(message_time),
|
||||
+ {CR_GET_X_LPARAM(l_param), CR_GET_Y_LPARAM(l_param)}};
|
||||
+ ui::MouseEvent event(msg);
|
||||
+ event.set_is_system_menu(true);
|
||||
+ if (!delegate_->HandleMouseEvent(&event))
|
||||
+ ShowSystemMenuAtScreenPixelLocation(hwnd(), gfx::Point(screen_point));
|
||||
return 0;
|
||||
}
|
||||
} else if (message == WM_NCLBUTTONDOWN &&
|
||||
diff --git a/ui/views/win/hwnd_message_handler_delegate.h b/ui/views/win/hwnd_message_handler_delegate.h
|
||||
index 04dea68d74ea4f559db60f716c919e555db9ec80..2f8bd1a3c156bb6c04663c74b7279bb59926fc3d 100644
|
||||
--- a/ui/views/win/hwnd_message_handler_delegate.h
|
||||
@@ -14,10 +14,10 @@ track down the source of this problem & figure out if we can fix it
|
||||
by changing something in Electron.
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index 5469931a7c4dc7ad8b98f5ac54c5538a7ba23a78..9bd28a4029de17833d5147986736747075ff35bc 100644
|
||||
index ce65cb2aec41faa58a1dfa43f5c1ac8e5bc66641..784a7536eec5a248e4725253c091b039047ff1ea 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -4817,9 +4817,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
@@ -4821,9 +4821,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
bool renderer_started_hidden =
|
||||
params.disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB;
|
||||
|
||||
|
||||
@@ -190,10 +190,10 @@ index 6c89a03712b9449e1a7b0e38ed9d019b30029c15..50b324ef3f1163e462ad145e58b42bf3
|
||||
void SetContentsBounds(content::WebContents* source,
|
||||
const gfx::Rect& bounds) override;
|
||||
diff --git a/components/offline_pages/content/background_loader/background_loader_contents.cc b/components/offline_pages/content/background_loader/background_loader_contents.cc
|
||||
index 072e7d0dde701a8f2d1de2704c8a056363324390..9e5ace2b1f32d5e5c542439f5365f9d9458cbf37 100644
|
||||
index e0e9a5a8c1d8c242d39935e2456052619af33cc6..80518793447c70e8fc1dae9b42a59d40427ae52b 100644
|
||||
--- a/components/offline_pages/content/background_loader/background_loader_contents.cc
|
||||
+++ b/components/offline_pages/content/background_loader/background_loader_contents.cc
|
||||
@@ -85,8 +85,7 @@ bool BackgroundLoaderContents::IsWebContentsCreationOverridden(
|
||||
@@ -89,8 +89,7 @@ bool BackgroundLoaderContents::IsWebContentsCreationOverridden(
|
||||
content::SiteInstance* source_site_instance,
|
||||
content::mojom::WindowContainerType window_container_type,
|
||||
const GURL& opener_url,
|
||||
@@ -218,10 +218,10 @@ index c6838c83ef971b88769b1f3fba8095025ae25464..2da6a4e08340e72ba7de5d03444c2f17
|
||||
content::WebContents* AddNewContents(
|
||||
content::WebContents* source,
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index 1f0b9a602a9e6cf565818ad584688b783fe3430b..1d1d761f8c7ff09cbd2c6a567e070ac41d3a1759 100644
|
||||
index d88c3b6a3625c2f4d0c67677777202f7db85ea88..71835a747d6732b963c5cdc289539665aa988c47 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -4786,8 +4786,7 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
@@ -4790,8 +4790,7 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
|
||||
if (delegate_ && delegate_->IsWebContentsCreationOverridden(
|
||||
source_site_instance, params.window_container_type,
|
||||
|
||||
@@ -24,10 +24,10 @@ This patch temporarily disables the metrics so we can have green CI, and we
|
||||
should continue seeking for a real fix.
|
||||
|
||||
diff --git a/content/browser/renderer_host/navigator.cc b/content/browser/renderer_host/navigator.cc
|
||||
index 53e54257aabbede66de278b0248c1c9959175143..69942e83c88d9c7eb99bd7b0eeae5c7b97356f17 100644
|
||||
index adbe15bbbde7096970ec4098b1aa4fbb5ba48df5..9207aff59ec5fc9733e1e161ba2688a614e8e069 100644
|
||||
--- a/content/browser/renderer_host/navigator.cc
|
||||
+++ b/content/browser/renderer_host/navigator.cc
|
||||
@@ -1435,6 +1435,7 @@ void Navigator::RecordNavigationMetrics(
|
||||
@@ -1450,6 +1450,7 @@ void Navigator::RecordNavigationMetrics(
|
||||
.InMilliseconds());
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ index 53e54257aabbede66de278b0248c1c9959175143..69942e83c88d9c7eb99bd7b0eeae5c7b
|
||||
// If this is a same-process navigation and we have timestamps for unload
|
||||
// durations, fill those metrics out as well.
|
||||
if (params.unload_start && params.unload_end &&
|
||||
@@ -1484,6 +1485,7 @@ void Navigator::RecordNavigationMetrics(
|
||||
@@ -1499,6 +1500,7 @@ void Navigator::RecordNavigationMetrics(
|
||||
first_before_unload_start_time)
|
||||
.InMilliseconds());
|
||||
}
|
||||
|
||||
@@ -33,10 +33,10 @@ index 0ab8187b0db8ae6db46d81738f653a2bc4c566f6..de3d55e85c22317f7f9375eb94d0d5d4
|
||||
|
||||
} // namespace net
|
||||
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
|
||||
index 4be02fdb03038ee4c30ea699cbbf56d1f5aaa7aa..b0a994b7c6d4be648d905bc1e4157bc03b56a428 100644
|
||||
index c5199a66320bfdb7abda0878b7ae24e02f49b420..4f043e19acecfd7defcb79d397538168bb6bd42a 100644
|
||||
--- a/services/network/network_context.cc
|
||||
+++ b/services/network/network_context.cc
|
||||
@@ -1793,6 +1793,13 @@ void NetworkContext::SetNetworkConditions(
|
||||
@@ -1796,6 +1796,13 @@ void NetworkContext::SetNetworkConditions(
|
||||
std::move(network_conditions));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: deepak1556 <hop2deep@gmail.com>
|
||||
Date: Wed, 29 Jan 2025 17:01:03 +0900
|
||||
Subject: feat: add signals when embedder cleanup callbacks run for
|
||||
gin::wrappable
|
||||
|
||||
Current setup of finalization callbacks does not work well with
|
||||
gin_helper::CleanedUpAtExit for wrappables specifically on environment
|
||||
shutdown leading to UAF in the second pass.
|
||||
|
||||
Details at https://github.com/microsoft/vscode/issues/192119#issuecomment-2375851531
|
||||
|
||||
The signals exposed in this patch does the following 2 things,
|
||||
|
||||
1) Fix weak state of the wrapped object when the finializer callbacks
|
||||
have not yet been processed
|
||||
2) Avoid calling into the second pass when the embedder has already
|
||||
destroyed the wrapped object via CleanedUpAtExit.
|
||||
|
||||
This patch is more of a bandaid fix to improve the lifetime
|
||||
management with existing finalizer callbacks. We should be able to
|
||||
remove this patch once gin::Wrappable can be managed by V8 Oilpan
|
||||
|
||||
Refs https://issues.chromium.org/issues/40210365 which is blocked
|
||||
on https://issues.chromium.org/issues/42203693
|
||||
|
||||
diff --git a/gin/isolate_holder.cc b/gin/isolate_holder.cc
|
||||
index e5ee2c6b3cb787ff9f8272d4344a1e18c44971e2..22469cf0ab1025eefcf94e2cd351087e52182130 100644
|
||||
--- a/gin/isolate_holder.cc
|
||||
+++ b/gin/isolate_holder.cc
|
||||
@@ -34,6 +34,8 @@ v8::ArrayBuffer::Allocator* g_array_buffer_allocator = nullptr;
|
||||
const intptr_t* g_reference_table = nullptr;
|
||||
v8::FatalErrorCallback g_fatal_error_callback = nullptr;
|
||||
v8::OOMErrorCallback g_oom_error_callback = nullptr;
|
||||
+bool g_initialized_microtasks_runner = false;
|
||||
+bool g_destroyed_microtasks_runner = false;
|
||||
|
||||
std::unique_ptr<v8::Isolate::CreateParams> getModifiedIsolateParams(
|
||||
std::unique_ptr<v8::Isolate::CreateParams> params,
|
||||
@@ -194,10 +196,26 @@ IsolateHolder::getDefaultIsolateParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
+// static
|
||||
+bool IsolateHolder::DestroyedMicrotasksRunner() {
|
||||
+ return g_initialized_microtasks_runner &&
|
||||
+ g_destroyed_microtasks_runner;
|
||||
+}
|
||||
+
|
||||
void IsolateHolder::EnableIdleTasks(
|
||||
std::unique_ptr<V8IdleTaskRunner> idle_task_runner) {
|
||||
DCHECK(isolate_data_.get());
|
||||
isolate_data_->EnableIdleTasks(std::move(idle_task_runner));
|
||||
}
|
||||
|
||||
+void IsolateHolder::WillCreateMicrotasksRunner() {
|
||||
+ DCHECK(!g_initialized_microtasks_runner);
|
||||
+ g_initialized_microtasks_runner = true;
|
||||
+}
|
||||
+
|
||||
+void IsolateHolder::WillDestroyMicrotasksRunner() {
|
||||
+ DCHECK(g_initialized_microtasks_runner);
|
||||
+ g_destroyed_microtasks_runner = true;
|
||||
+}
|
||||
+
|
||||
} // namespace gin
|
||||
diff --git a/gin/public/isolate_holder.h b/gin/public/isolate_holder.h
|
||||
index c22b0a7f9af621573e888a518ccdc22293ce07ef..d3e5ced425df54f42534cec5cc0c5bbfb9d79c6c 100644
|
||||
--- a/gin/public/isolate_holder.h
|
||||
+++ b/gin/public/isolate_holder.h
|
||||
@@ -130,6 +130,8 @@ class GIN_EXPORT IsolateHolder {
|
||||
// Should only be called after v8::IsolateHolder::Initialize() is invoked.
|
||||
static std::unique_ptr<v8::Isolate::CreateParams> getDefaultIsolateParams();
|
||||
|
||||
+ static bool DestroyedMicrotasksRunner();
|
||||
+
|
||||
v8::Isolate* isolate() { return isolate_; }
|
||||
|
||||
// This method returns if v8::Locker is needed to access isolate.
|
||||
@@ -143,6 +145,9 @@ class GIN_EXPORT IsolateHolder {
|
||||
|
||||
void EnableIdleTasks(std::unique_ptr<V8IdleTaskRunner> idle_task_runner);
|
||||
|
||||
+ void WillCreateMicrotasksRunner();
|
||||
+ void WillDestroyMicrotasksRunner();
|
||||
+
|
||||
// This method returns V8IsolateMemoryDumpProvider of this isolate, used for
|
||||
// testing.
|
||||
V8IsolateMemoryDumpProvider* isolate_memory_dump_provider_for_testing()
|
||||
diff --git a/gin/wrappable.cc b/gin/wrappable.cc
|
||||
index 402355cb836cea14e9ee725a142a4bad44fd5bed..7e7f028dcfb87c7b80adebabac19ced8791f642e 100644
|
||||
--- a/gin/wrappable.cc
|
||||
+++ b/gin/wrappable.cc
|
||||
@@ -13,6 +13,9 @@ namespace gin {
|
||||
WrappableBase::WrappableBase() = default;
|
||||
|
||||
WrappableBase::~WrappableBase() {
|
||||
+ if (!wrapper_.IsEmpty()) {
|
||||
+ wrapper_.ClearWeak();
|
||||
+ }
|
||||
wrapper_.Reset();
|
||||
}
|
||||
|
||||
@@ -28,15 +31,24 @@ const char* WrappableBase::GetTypeName() {
|
||||
void WrappableBase::FirstWeakCallback(
|
||||
const v8::WeakCallbackInfo<WrappableBase>& data) {
|
||||
WrappableBase* wrappable = data.GetParameter();
|
||||
- wrappable->dead_ = true;
|
||||
- wrappable->wrapper_.Reset();
|
||||
- data.SetSecondPassCallback(SecondWeakCallback);
|
||||
+ WrappableBase* wrappable_from_field =
|
||||
+ static_cast<WrappableBase*>(data.GetInternalField(1));
|
||||
+ if (wrappable && wrappable == wrappable_from_field) {
|
||||
+ wrappable->dead_ = true;
|
||||
+ wrappable->wrapper_.Reset();
|
||||
+ data.SetSecondPassCallback(SecondWeakCallback);
|
||||
+ }
|
||||
}
|
||||
|
||||
void WrappableBase::SecondWeakCallback(
|
||||
const v8::WeakCallbackInfo<WrappableBase>& data) {
|
||||
+ if (IsolateHolder::DestroyedMicrotasksRunner()) {
|
||||
+ return;
|
||||
+ }
|
||||
WrappableBase* wrappable = data.GetParameter();
|
||||
- delete wrappable;
|
||||
+ if (wrappable) {
|
||||
+ delete wrappable;
|
||||
+ }
|
||||
}
|
||||
|
||||
v8::MaybeLocal<v8::Object> WrappableBase::GetWrapperImpl(v8::Isolate* isolate,
|
||||
@@ -71,10 +83,16 @@ v8::MaybeLocal<v8::Object> WrappableBase::GetWrapperImpl(v8::Isolate* isolate,
|
||||
void* values[] = {info, this};
|
||||
wrapper->SetAlignedPointerInInternalFields(2, indices, values);
|
||||
wrapper_.Reset(isolate, wrapper);
|
||||
- wrapper_.SetWeak(this, FirstWeakCallback, v8::WeakCallbackType::kParameter);
|
||||
+ wrapper_.SetWeak(this, FirstWeakCallback, v8::WeakCallbackType::kInternalFields);
|
||||
return v8::MaybeLocal<v8::Object>(wrapper);
|
||||
}
|
||||
|
||||
+void WrappableBase::ClearWeak() {
|
||||
+ if (!wrapper_.IsEmpty()) {
|
||||
+ wrapper_.ClearWeak();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
namespace internal {
|
||||
|
||||
void* FromV8Impl(v8::Isolate* isolate, v8::Local<v8::Value> val,
|
||||
diff --git a/gin/wrappable.h b/gin/wrappable.h
|
||||
index 4e7115685a5bf6997e78edcc1851e28bd00b1aa2..ca51fe33605e855438e88969e3d3cc734ef4523e 100644
|
||||
--- a/gin/wrappable.h
|
||||
+++ b/gin/wrappable.h
|
||||
@@ -80,6 +80,13 @@ class GIN_EXPORT WrappableBase {
|
||||
v8::MaybeLocal<v8::Object> GetWrapperImpl(v8::Isolate* isolate,
|
||||
WrapperInfo* wrapper_info);
|
||||
|
||||
+ // Make this wrappable strong again. This is useful when the wrappable is
|
||||
+ // destroyed outside the finalizer callbacks and we want to avoid scheduling
|
||||
+ // the weak callbacks if they haven't been scheduled yet.
|
||||
+ // NOTE!!! this does not prevent finalization callbacks from running if they
|
||||
+ // have already been processed.
|
||||
+ void ClearWeak();
|
||||
+
|
||||
private:
|
||||
static void FirstWeakCallback(
|
||||
const v8::WeakCallbackInfo<WrappableBase>& data);
|
||||
@@ -14,10 +14,25 @@ It also:
|
||||
This may be partially upstreamed to Chromium in the future.
|
||||
|
||||
diff --git a/ui/gtk/select_file_dialog_linux_gtk.cc b/ui/gtk/select_file_dialog_linux_gtk.cc
|
||||
index b83f0177a2adb0a19be49684f865941e6708f626..f313c766ddc2b79f082e70138dd566a846f0d923 100644
|
||||
index b83f0177a2adb0a19be49684f865941e6708f626..a8c7032cfc122b97665c41da9e1191e747b95a33 100644
|
||||
--- a/ui/gtk/select_file_dialog_linux_gtk.cc
|
||||
+++ b/ui/gtk/select_file_dialog_linux_gtk.cc
|
||||
@@ -407,9 +407,11 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateFileOpenHelper(
|
||||
@@ -259,8 +259,12 @@ void SelectFileDialogLinuxGtk::SelectFileImpl(
|
||||
case SELECT_EXISTING_FOLDER:
|
||||
dialog = CreateSelectFolderDialog(type, title_string, default_path,
|
||||
owning_window);
|
||||
- connect("response",
|
||||
- &SelectFileDialogLinuxGtk::OnSelectSingleFolderDialogResponse);
|
||||
+ if (allow_multiple_selection())
|
||||
+ connect("response",
|
||||
+ &SelectFileDialogLinuxGtk::OnSelectMultiFolderDialogResponse);
|
||||
+ else
|
||||
+ connect("response",
|
||||
+ &SelectFileDialogLinuxGtk::OnSelectSingleFolderDialogResponse);
|
||||
break;
|
||||
case SELECT_OPEN_FILE:
|
||||
dialog = CreateFileOpenDialog(title_string, default_path, owning_window);
|
||||
@@ -407,9 +411,11 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateFileOpenHelper(
|
||||
const std::string& title,
|
||||
const base::FilePath& default_path,
|
||||
gfx::NativeWindow parent) {
|
||||
@@ -30,7 +45,7 @@ index b83f0177a2adb0a19be49684f865941e6708f626..f313c766ddc2b79f082e70138dd566a8
|
||||
SetGtkTransientForAura(dialog, parent);
|
||||
AddFilters(GTK_FILE_CHOOSER(dialog));
|
||||
|
||||
@@ -425,6 +427,7 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateFileOpenHelper(
|
||||
@@ -425,6 +431,7 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateFileOpenHelper(
|
||||
GtkFileChooserSetCurrentFolder(GTK_FILE_CHOOSER(dialog),
|
||||
*last_opened_path());
|
||||
}
|
||||
@@ -38,7 +53,7 @@ index b83f0177a2adb0a19be49684f865941e6708f626..f313c766ddc2b79f082e70138dd566a8
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@@ -440,11 +443,15 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateSelectFolderDialog(
|
||||
@@ -440,11 +447,15 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateSelectFolderDialog(
|
||||
? l10n_util::GetStringUTF8(IDS_SELECT_UPLOAD_FOLDER_DIALOG_TITLE)
|
||||
: l10n_util::GetStringUTF8(IDS_SELECT_FOLDER_DIALOG_TITLE);
|
||||
}
|
||||
@@ -59,7 +74,7 @@ index b83f0177a2adb0a19be49684f865941e6708f626..f313c766ddc2b79f082e70138dd566a8
|
||||
|
||||
GtkWidget* dialog = GtkFileChooserDialogNew(
|
||||
title_string.c_str(), nullptr, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
|
||||
@@ -466,7 +473,8 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateSelectFolderDialog(
|
||||
@@ -466,7 +477,8 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateSelectFolderDialog(
|
||||
gtk_file_filter_add_mime_type(only_folders, "inode/directory");
|
||||
gtk_file_filter_add_mime_type(only_folders, "text/directory");
|
||||
gtk_file_chooser_add_filter(chooser, only_folders);
|
||||
@@ -69,7 +84,7 @@ index b83f0177a2adb0a19be49684f865941e6708f626..f313c766ddc2b79f082e70138dd566a8
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@@ -503,10 +511,11 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateSaveAsDialog(
|
||||
@@ -503,10 +515,11 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateSaveAsDialog(
|
||||
std::string title_string =
|
||||
!title.empty() ? title
|
||||
: l10n_util::GetStringUTF8(IDS_SAVE_AS_DIALOG_TITLE);
|
||||
@@ -83,7 +98,7 @@ index b83f0177a2adb0a19be49684f865941e6708f626..f313c766ddc2b79f082e70138dd566a8
|
||||
GTK_RESPONSE_ACCEPT);
|
||||
SetGtkTransientForAura(dialog, parent);
|
||||
|
||||
@@ -532,9 +541,10 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateSaveAsDialog(
|
||||
@@ -532,9 +545,10 @@ GtkWidget* SelectFileDialogLinuxGtk::CreateSaveAsDialog(
|
||||
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE);
|
||||
// Overwrite confirmation is always enabled in GTK4.
|
||||
if (!GtkCheckVersion(4)) {
|
||||
@@ -96,6 +111,65 @@ index b83f0177a2adb0a19be49684f865941e6708f626..f313c766ddc2b79f082e70138dd566a8
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@@ -589,15 +603,29 @@ void SelectFileDialogLinuxGtk::OnSelectSingleFolderDialogResponse(
|
||||
void SelectFileDialogLinuxGtk::OnSelectMultiFileDialogResponse(
|
||||
GtkWidget* dialog,
|
||||
int response_id) {
|
||||
+ SelectMultiFileHelper(dialog, response_id, false);
|
||||
+}
|
||||
+
|
||||
+void SelectFileDialogLinuxGtk::OnSelectMultiFolderDialogResponse(
|
||||
+ GtkWidget* dialog,
|
||||
+ int response_id) {
|
||||
+ SelectMultiFileHelper(dialog, response_id, true);
|
||||
+}
|
||||
+
|
||||
+void SelectFileDialogLinuxGtk::SelectMultiFileHelper(GtkWidget* dialog,
|
||||
+ int response_id,
|
||||
+ bool allow_folder) {
|
||||
if (IsCancelResponse(response_id)) {
|
||||
FileNotSelected(dialog);
|
||||
return;
|
||||
}
|
||||
|
||||
auto filenames = GtkFileChooserGetFilenames(dialog);
|
||||
- std::erase_if(filenames, [this](const base::FilePath& path) {
|
||||
- return CallDirectoryExistsOnUIThread(path);
|
||||
+ std::erase_if(filenames, [this, &allow_folder](const base::FilePath& path) {
|
||||
+ bool directory_exists = CallDirectoryExistsOnUIThread(path);
|
||||
+ return !allow_folder && directory_exists;
|
||||
});
|
||||
+
|
||||
if (filenames.empty()) {
|
||||
FileNotSelected(dialog);
|
||||
return;
|
||||
diff --git a/ui/gtk/select_file_dialog_linux_gtk.h b/ui/gtk/select_file_dialog_linux_gtk.h
|
||||
index 213eaa5ec6d657a659726cb38103e8bd671fe907..f497447c598198bf690758b1d1c5c6fe4112627f 100644
|
||||
--- a/ui/gtk/select_file_dialog_linux_gtk.h
|
||||
+++ b/ui/gtk/select_file_dialog_linux_gtk.h
|
||||
@@ -108,6 +108,12 @@ class SelectFileDialogLinuxGtk : public ui::SelectFileDialogLinux,
|
||||
gint response_id,
|
||||
bool allow_folder);
|
||||
|
||||
+ // Common function for OnSelectMultiFileDialogResponse and
|
||||
+ // OnSelectMultiFolderDialogResponse.
|
||||
+ void SelectMultiFileHelper(GtkWidget* dialog,
|
||||
+ gint response_id,
|
||||
+ bool allow_folder);
|
||||
+
|
||||
// Common function for CreateFileOpenDialog and CreateMultiFileOpenDialog.
|
||||
GtkWidget* CreateFileOpenHelper(const std::string& title,
|
||||
const base::FilePath& default_path,
|
||||
@@ -122,6 +128,9 @@ class SelectFileDialogLinuxGtk : public ui::SelectFileDialogLinux,
|
||||
// Callback for when the user responds to a Open Multiple Files dialog.
|
||||
void OnSelectMultiFileDialogResponse(GtkWidget* dialog, int response_id);
|
||||
|
||||
+ // Callback for when the user responds to a Select Multiple Folders dialog.
|
||||
+ void OnSelectMultiFolderDialogResponse(GtkWidget* dialog, int response_id);
|
||||
+
|
||||
// Callback for when the file chooser gets destroyed.
|
||||
void OnFileChooserDestroy(GtkWidget* dialog);
|
||||
|
||||
diff --git a/ui/shell_dialogs/select_file_dialog.h b/ui/shell_dialogs/select_file_dialog.h
|
||||
index eb3d997598631b220c3566748f23a5cdac3e4692..b4b2f7294ce6e9349a4a8a05f614e93359eca25a 100644
|
||||
--- a/ui/shell_dialogs/select_file_dialog.h
|
||||
@@ -186,18 +260,118 @@ index 61683d0eddb04c494ca5e650e7d556b44968ec49..5492456a9138b250e97a5479838bb443
|
||||
|
||||
} // namespace ui
|
||||
diff --git a/ui/shell_dialogs/select_file_dialog_linux_kde.cc b/ui/shell_dialogs/select_file_dialog_linux_kde.cc
|
||||
index 64a79ebe2e2d21d5a6b4a98042d1cdb7b6edad52..16f2ae01a8d33e6341ed52638e963c340455ebf8 100644
|
||||
index 64a79ebe2e2d21d5a6b4a98042d1cdb7b6edad52..400cce91b020ecd5e48566f125515d2cfe3ea6af 100644
|
||||
--- a/ui/shell_dialogs/select_file_dialog_linux_kde.cc
|
||||
+++ b/ui/shell_dialogs/select_file_dialog_linux_kde.cc
|
||||
@@ -468,7 +468,7 @@ void SelectFileDialogLinuxKde::CreateSelectFolderDialog(
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <string_view>
|
||||
|
||||
#include "base/command_line.h"
|
||||
+#include "base/files/file_util.h"
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/functional/callback_helpers.h"
|
||||
#include "base/logging.h"
|
||||
@@ -154,9 +155,20 @@ class SelectFileDialogLinuxKde : public SelectFileDialogLinux {
|
||||
void OnSelectMultiFileDialogResponse(
|
||||
gfx::AcceleratedWidget parent,
|
||||
std::unique_ptr<KDialogOutputParams> results);
|
||||
+
|
||||
+ // Common function for OnSelectSingleFolderDialogResponse and
|
||||
+ // OnSelectMultiFileDialogResponse.
|
||||
+ void SelectMultiFileDialogHelper(
|
||||
+ bool allow_folder,
|
||||
+ gfx::AcceleratedWidget parent,
|
||||
+ std::unique_ptr<KDialogOutputParams> results);
|
||||
+
|
||||
void OnSelectSingleFolderDialogResponse(
|
||||
gfx::AcceleratedWidget parent,
|
||||
std::unique_ptr<KDialogOutputParams> results);
|
||||
+ void OnSelectMultiFolderDialogResponse(
|
||||
+ gfx::AcceleratedWidget parent,
|
||||
+ std::unique_ptr<KDialogOutputParams> results);
|
||||
|
||||
// Should be either DESKTOP_ENVIRONMENT_KDE3, KDE4, KDE5, or KDE6.
|
||||
base::nix::DesktopEnvironment desktop_;
|
||||
@@ -413,10 +425,16 @@ void SelectFileDialogLinuxKde::GetKDialogCommandLine(
|
||||
}
|
||||
command_line->AppendSwitch(type);
|
||||
// The path should never be empty. If it is, set it to PWD.
|
||||
- if (path.empty())
|
||||
- command_line->AppendArgPath(base::FilePath("."));
|
||||
- else
|
||||
+ auto pwd = base::FilePath(".");
|
||||
+ if (path.empty()) {
|
||||
+ command_line->AppendArgPath(pwd);
|
||||
+ } else if (path.IsAbsolute()) {
|
||||
command_line->AppendArgPath(path);
|
||||
+ } else {
|
||||
+ // KDialog won't set the default name in the Name field for relative paths.
|
||||
+ auto abs_path = base::MakeAbsoluteFilePathNoResolveSymbolicLinks(path);
|
||||
+ command_line->AppendArgPath(abs_path.value_or(pwd));
|
||||
+ }
|
||||
// Depending on the type of the operation we need, get the path to the
|
||||
// file/folder and set up mime type filters.
|
||||
if (file_operation)
|
||||
@@ -461,6 +479,7 @@ void SelectFileDialogLinuxKde::CreateSelectFolderDialog(
|
||||
int title_message_id = (type == SELECT_UPLOAD_FOLDER)
|
||||
? IDS_SELECT_UPLOAD_FOLDER_DIALOG_TITLE
|
||||
: IDS_SELECT_FOLDER_DIALOG_TITLE;
|
||||
+ bool multiple_selection = allow_multiple_selection();
|
||||
pipe_task_runner_->PostTaskAndReplyWithResult(
|
||||
FROM_HERE,
|
||||
base::BindOnce(
|
||||
@@ -468,10 +487,12 @@ void SelectFileDialogLinuxKde::CreateSelectFolderDialog(
|
||||
KDialogParams(
|
||||
"--getexistingdirectory", GetTitle(title, title_message_id),
|
||||
default_path.empty() ? *last_opened_path() : default_path, parent,
|
||||
- false, false)),
|
||||
+ false, allow_multiple_selection())),
|
||||
+ false, multiple_selection)),
|
||||
base::BindOnce(
|
||||
&SelectFileDialogLinuxKde::OnSelectSingleFolderDialogResponse, this,
|
||||
parent));
|
||||
- &SelectFileDialogLinuxKde::OnSelectSingleFolderDialogResponse, this,
|
||||
- parent));
|
||||
+ multiple_selection
|
||||
+ ? &SelectFileDialogLinuxKde::OnSelectMultiFolderDialogResponse
|
||||
+ : &SelectFileDialogLinuxKde::OnSelectSingleFolderDialogResponse,
|
||||
+ this, parent));
|
||||
}
|
||||
|
||||
void SelectFileDialogLinuxKde::CreateFileOpenDialog(
|
||||
@@ -561,7 +582,8 @@ void SelectFileDialogLinuxKde::OnSelectSingleFolderDialogResponse(
|
||||
SelectSingleFileHelper(true, std::move(results));
|
||||
}
|
||||
|
||||
-void SelectFileDialogLinuxKde::OnSelectMultiFileDialogResponse(
|
||||
+void SelectFileDialogLinuxKde::SelectMultiFileDialogHelper(
|
||||
+ bool allow_folder,
|
||||
gfx::AcceleratedWidget parent,
|
||||
std::unique_ptr<KDialogOutputParams> results) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
@@ -579,7 +601,7 @@ void SelectFileDialogLinuxKde::OnSelectMultiFileDialogResponse(
|
||||
base::SplitStringPiece(results->output, "\n", base::KEEP_WHITESPACE,
|
||||
base::SPLIT_WANT_NONEMPTY)) {
|
||||
base::FilePath path(line);
|
||||
- if (CallDirectoryExistsOnUIThread(path))
|
||||
+ if (!allow_folder && CallDirectoryExistsOnUIThread(path))
|
||||
continue;
|
||||
filenames_fp.push_back(path);
|
||||
}
|
||||
@@ -591,4 +613,16 @@ void SelectFileDialogLinuxKde::OnSelectMultiFileDialogResponse(
|
||||
MultiFilesSelected(filenames_fp);
|
||||
}
|
||||
|
||||
+void SelectFileDialogLinuxKde::OnSelectMultiFolderDialogResponse(
|
||||
+ gfx::AcceleratedWidget parent,
|
||||
+ std::unique_ptr<KDialogOutputParams> results) {
|
||||
+ SelectMultiFileDialogHelper(true, parent, std::move(results));
|
||||
+}
|
||||
+
|
||||
+void SelectFileDialogLinuxKde::OnSelectMultiFileDialogResponse(
|
||||
+ gfx::AcceleratedWidget parent,
|
||||
+ std::unique_ptr<KDialogOutputParams> results) {
|
||||
+ SelectMultiFileDialogHelper(false, parent, std::move(results));
|
||||
+}
|
||||
+
|
||||
} // namespace ui
|
||||
diff --git a/ui/shell_dialogs/select_file_dialog_linux_portal.cc b/ui/shell_dialogs/select_file_dialog_linux_portal.cc
|
||||
index 143f5fe1028e154192767599a1e68b45301a894d..132e670dc3ccd9a0f904a8869e516f4556fbf0af 100644
|
||||
--- a/ui/shell_dialogs/select_file_dialog_linux_portal.cc
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: deepak1556 <hop2deep@gmail.com>
|
||||
Date: Thu, 30 Jan 2025 20:28:38 +0900
|
||||
Subject: feat: separate content settings callback for sync and async clipboard
|
||||
|
||||
`AllowReadFromClipboard` is called from both the types without a way to differentiate.
|
||||
|
||||
[sync path] - third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
|
||||
[async path] - third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
|
||||
|
||||
This patch adds a new callback to separate these two paths so that we
|
||||
can have sync permission checks for the sync path.
|
||||
|
||||
Additionally, `blink::PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ`
|
||||
has been added to support type conversion in permission policy checks. We have extended
|
||||
`blink::PermissionType` in `electron::WebContentsPermissionHelper::PermissionType`
|
||||
but it is hard to import the latter into the content permission layer checks.
|
||||
|
||||
This patch will be removed when the deprecated sync api support is
|
||||
removed.
|
||||
|
||||
diff --git a/components/permissions/permission_util.cc b/components/permissions/permission_util.cc
|
||||
index d21e492cac6b6750dfab320e35c94841df54e2e4..3c05ae9bf223e9b3b6ca6d4c05be31c517e2a996 100644
|
||||
--- a/components/permissions/permission_util.cc
|
||||
+++ b/components/permissions/permission_util.cc
|
||||
@@ -364,6 +364,7 @@ ContentSettingsType PermissionUtil::PermissionTypeToContentSettingsTypeSafe(
|
||||
return ContentSettingsType::AUTOMATIC_FULLSCREEN;
|
||||
case PermissionType::WEB_APP_INSTALLATION:
|
||||
return ContentSettingsType::WEB_APP_INSTALLATION;
|
||||
+ case PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ:
|
||||
case PermissionType::NUM:
|
||||
break;
|
||||
}
|
||||
diff --git a/content/browser/permissions/permission_controller_impl.cc b/content/browser/permissions/permission_controller_impl.cc
|
||||
index 4e6b9b4073892051a72e40808365fe59c1e77903..e4403c1e95510b7846cc57f3c5a95a41480149f5 100644
|
||||
--- a/content/browser/permissions/permission_controller_impl.cc
|
||||
+++ b/content/browser/permissions/permission_controller_impl.cc
|
||||
@@ -94,6 +94,7 @@ PermissionToSchedulingFeature(PermissionType permission_name) {
|
||||
case PermissionType::POINTER_LOCK:
|
||||
case PermissionType::AUTOMATIC_FULLSCREEN:
|
||||
case PermissionType::WEB_APP_INSTALLATION:
|
||||
+ case PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ:
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
diff --git a/third_party/blink/common/permissions/permission_utils.cc b/third_party/blink/common/permissions/permission_utils.cc
|
||||
index baa74bd6c7bf6350f4ef06f00d94d1d517b43943..2d4f846f08383e22e42c55f783eb1041de4cd258 100644
|
||||
--- a/third_party/blink/common/permissions/permission_utils.cc
|
||||
+++ b/third_party/blink/common/permissions/permission_utils.cc
|
||||
@@ -99,6 +99,8 @@ std::string GetPermissionString(PermissionType permission) {
|
||||
return "AutomaticFullscreen";
|
||||
case PermissionType::WEB_APP_INSTALLATION:
|
||||
return "WebAppInstallation";
|
||||
+ case PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ:
|
||||
+ return "DeprecatedSyncClipboardRead";
|
||||
case PermissionType::NUM:
|
||||
NOTREACHED();
|
||||
}
|
||||
@@ -171,6 +173,7 @@ PermissionTypeToPermissionsPolicyFeature(PermissionType permission) {
|
||||
case PermissionType::NOTIFICATIONS:
|
||||
case PermissionType::KEYBOARD_LOCK:
|
||||
case PermissionType::POINTER_LOCK:
|
||||
+ case PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ:
|
||||
return std::nullopt;
|
||||
|
||||
case PermissionType::NUM:
|
||||
diff --git a/third_party/blink/public/common/permissions/permission_utils.h b/third_party/blink/public/common/permissions/permission_utils.h
|
||||
index ae03b7f099d30c157cfda7d1beb7c535d3615471..ca287e7a5271ee83c393de6c1fe347973f4292ba 100644
|
||||
--- a/third_party/blink/public/common/permissions/permission_utils.h
|
||||
+++ b/third_party/blink/public/common/permissions/permission_utils.h
|
||||
@@ -64,6 +64,7 @@ enum class PermissionType {
|
||||
AUTOMATIC_FULLSCREEN = 40,
|
||||
HAND_TRACKING = 41,
|
||||
WEB_APP_INSTALLATION = 42,
|
||||
+ DEPRECATED_SYNC_CLIPBOARD_READ = 43,
|
||||
|
||||
// Always keep this at the end.
|
||||
NUM,
|
||||
diff --git a/third_party/blink/public/platform/web_content_settings_client.h b/third_party/blink/public/platform/web_content_settings_client.h
|
||||
index 28f616f21f998c7cd1c794e58efaccf9e6c11e6e..c64896642209124e500db2ed6fe2357e426cd10b 100644
|
||||
--- a/third_party/blink/public/platform/web_content_settings_client.h
|
||||
+++ b/third_party/blink/public/platform/web_content_settings_client.h
|
||||
@@ -55,6 +55,9 @@ class WebContentSettingsClient {
|
||||
// Controls whether access to write the clipboard is allowed for this frame.
|
||||
virtual bool AllowWriteToClipboard() { return false; }
|
||||
|
||||
+ // Controls whether synchronous access to read the clipboard is allowed for this frame.
|
||||
+ virtual bool AllowReadFromClipboardSync() { return false; }
|
||||
+
|
||||
// Controls whether to enable MutationEvents for this frame.
|
||||
// The common use case of this method is actually to selectively disable
|
||||
// MutationEvents, but it's been named for consistency with the rest of the
|
||||
diff --git a/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc b/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
|
||||
index 20ebd3f2f5fa7b16ad1b2081ca41b007bc78a354..b248e3135182d36a6524c2e626157a0e4c759d14 100644
|
||||
--- a/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
|
||||
+++ b/third_party/blink/renderer/core/editing/commands/clipboard_commands.cc
|
||||
@@ -121,7 +121,7 @@ bool ClipboardCommands::CanReadClipboard(LocalFrame& frame,
|
||||
return true;
|
||||
}
|
||||
return frame.GetContentSettingsClient() &&
|
||||
- frame.GetContentSettingsClient()->AllowReadFromClipboard();
|
||||
+ frame.GetContentSettingsClient()->AllowReadFromClipboardSync();
|
||||
}
|
||||
|
||||
bool ClipboardCommands::CanWriteClipboard(LocalFrame& frame,
|
||||
@@ -300,7 +300,7 @@ bool ClipboardCommands::PasteSupported(LocalFrame* frame) {
|
||||
return true;
|
||||
}
|
||||
return frame->GetContentSettingsClient() &&
|
||||
- frame->GetContentSettingsClient()->AllowReadFromClipboard();
|
||||
+ frame->GetContentSettingsClient()->AllowReadFromClipboardSync();
|
||||
}
|
||||
|
||||
bool ClipboardCommands::ExecuteCopy(LocalFrame& frame,
|
||||
@@ -14,7 +14,7 @@ This patch likely can't be upstreamed as-is, as Chromium doesn't have
|
||||
this use case in mind currently.
|
||||
|
||||
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
|
||||
index fda18ecab7e982b3087c7667d36578177d370066..a949e73dabad71d2550e38b09dbcf45160b3a853 100644
|
||||
index 562532f5795ee833493614f3f16d35bda2654d8d..98a3365ce2b5ef4e34eb9edf66ef3f620af9ab1d 100644
|
||||
--- a/ui/views/win/hwnd_message_handler.cc
|
||||
+++ b/ui/views/win/hwnd_message_handler.cc
|
||||
@@ -908,13 +908,13 @@ void HWNDMessageHandler::FrameTypeChanged() {
|
||||
|
||||
161
patches/chromium/fix_drag_and_drop_icons_on_windows.patch
Normal file
161
patches/chromium/fix_drag_and_drop_icons_on_windows.patch
Normal file
@@ -0,0 +1,161 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: David Sanders <dsanders11@ucsbalum.com>
|
||||
Date: Fri, 21 Feb 2025 00:46:48 -0800
|
||||
Subject: fix: drag and drop icons on Windows
|
||||
|
||||
This is a backport from Chromium of
|
||||
https://chromium-review.googlesource.com/c/chromium/src/+/6279834
|
||||
|
||||
Change-Id: Ic642228f3a0a073b9b45fbec68de37be6cfd3934
|
||||
|
||||
diff --git a/chrome/browser/ui/views/tabs/tab_close_button.cc b/chrome/browser/ui/views/tabs/tab_close_button.cc
|
||||
index 281d6c6fcccbf3bfc3396056e495ee8d19424f5a..ac335a68f3fd0e3931cb37c915de51e410734850 100644
|
||||
--- a/chrome/browser/ui/views/tabs/tab_close_button.cc
|
||||
+++ b/chrome/browser/ui/views/tabs/tab_close_button.cc
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/metadata/metadata_impl_macros.h"
|
||||
#include "ui/base/pointer/touch_ui_controller.h"
|
||||
-#include "ui/compositor/layer.h"
|
||||
#include "ui/gfx/canvas.h"
|
||||
#include "ui/gfx/color_utils.h"
|
||||
#include "ui/gfx/geometry/insets.h"
|
||||
@@ -63,8 +62,6 @@ TabCloseButton::TabCloseButton(PressedCallback pressed_callback,
|
||||
views::InkDrop::Get(this)->GetInkDrop()->SetHoverHighlightFadeDuration(
|
||||
base::TimeDelta());
|
||||
|
||||
- image_container_view()->DestroyLayer();
|
||||
-
|
||||
// The ink drop highlight path is the same as the focus ring highlight path,
|
||||
// but needs to be explicitly mirrored for RTL.
|
||||
// TODO(http://crbug.com/1056490): Make ink drops in RTL work the same way as
|
||||
@@ -145,20 +142,6 @@ void TabCloseButton::OnGestureEvent(ui::GestureEvent* event) {
|
||||
event->SetHandled();
|
||||
}
|
||||
|
||||
-void TabCloseButton::AddLayerToRegion(ui::Layer* new_layer,
|
||||
- views::LayerRegion region) {
|
||||
- image_container_view()->SetPaintToLayer();
|
||||
- image_container_view()->layer()->SetFillsBoundsOpaquely(false);
|
||||
- ink_drop_container()->SetVisible(true);
|
||||
- ink_drop_container()->AddLayerToRegion(new_layer, region);
|
||||
-}
|
||||
-
|
||||
-void TabCloseButton::RemoveLayerFromRegions(ui::Layer* old_layer) {
|
||||
- ink_drop_container()->RemoveLayerFromRegions(old_layer);
|
||||
- ink_drop_container()->SetVisible(false);
|
||||
- image_container_view()->DestroyLayer();
|
||||
-}
|
||||
-
|
||||
gfx::Size TabCloseButton::CalculatePreferredSize(
|
||||
const views::SizeBounds& available_size) const {
|
||||
return kButtonSize;
|
||||
diff --git a/chrome/browser/ui/views/tabs/tab_close_button.h b/chrome/browser/ui/views/tabs/tab_close_button.h
|
||||
index f23bf862d987d8d6ba59aef781c51034e9a3debe..f688214ef883994d09b7a428b8af9b7f14c93af9 100644
|
||||
--- a/chrome/browser/ui/views/tabs/tab_close_button.h
|
||||
+++ b/chrome/browser/ui/views/tabs/tab_close_button.h
|
||||
@@ -46,9 +46,6 @@ class TabCloseButton : public views::LabelButton,
|
||||
void OnMouseReleased(const ui::MouseEvent& event) override;
|
||||
void OnMouseMoved(const ui::MouseEvent& event) override;
|
||||
void OnGestureEvent(ui::GestureEvent* event) override;
|
||||
- void AddLayerToRegion(ui::Layer* new_layer,
|
||||
- views::LayerRegion region) override;
|
||||
- void RemoveLayerFromRegions(ui::Layer* old_layer) override;
|
||||
|
||||
protected:
|
||||
// Set/reset the image models for the icon with new colors.
|
||||
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button.cc b/chrome/browser/ui/views/toolbar/toolbar_button.cc
|
||||
index 08c4a2164f25ca3b363c13558b04dc5c10855fb2..6d01c1077014bbc7d8bd6bf895825ce9be9a66ca 100644
|
||||
--- a/chrome/browser/ui/views/toolbar/toolbar_button.cc
|
||||
+++ b/chrome/browser/ui/views/toolbar/toolbar_button.cc
|
||||
@@ -128,6 +128,12 @@ ToolbarButton::ToolbarButton(PressedCallback callback,
|
||||
if (model_) {
|
||||
GetViewAccessibility().SetHasPopup(ax::mojom::HasPopup::kMenu);
|
||||
}
|
||||
+#if BUILDFLAG(IS_WIN)
|
||||
+ // Paint image(s) to a layer so that the canvas is snapped to pixel
|
||||
+ // boundaries.
|
||||
+ image_container_view()->SetPaintToLayer();
|
||||
+ image_container_view()->layer()->SetFillsBoundsOpaquely(false);
|
||||
+#endif
|
||||
}
|
||||
|
||||
ToolbarButton::~ToolbarButton() = default;
|
||||
@@ -724,6 +730,24 @@ ToolbarButton::GetActionViewInterface() {
|
||||
return std::make_unique<ToolbarButtonActionViewInterface>(this);
|
||||
}
|
||||
|
||||
+void ToolbarButton::AddLayerToRegion(ui::Layer* new_layer,
|
||||
+ views::LayerRegion region) {
|
||||
+#if !BUILDFLAG(IS_WIN)
|
||||
+ image_container_view()->SetPaintToLayer();
|
||||
+ image_container_view()->layer()->SetFillsBoundsOpaquely(false);
|
||||
+#endif
|
||||
+ ink_drop_container()->SetVisible(true);
|
||||
+ ink_drop_container()->AddLayerToRegion(new_layer, region);
|
||||
+}
|
||||
+
|
||||
+void ToolbarButton::RemoveLayerFromRegions(ui::Layer* old_layer) {
|
||||
+ ink_drop_container()->RemoveLayerFromRegions(old_layer);
|
||||
+ ink_drop_container()->SetVisible(false);
|
||||
+#if !BUILDFLAG(IS_WIN)
|
||||
+ image_container_view()->DestroyLayer();
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
ToolbarButtonActionViewInterface::ToolbarButtonActionViewInterface(
|
||||
ToolbarButton* action_view)
|
||||
: views::LabelButtonActionViewInterface(action_view),
|
||||
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button.h b/chrome/browser/ui/views/toolbar/toolbar_button.h
|
||||
index 9d46beda5f6811e728dad5c5e2ddf04fe52b24f5..602e966ec72fd026e0ab3c454e9f15c08ddf11c2 100644
|
||||
--- a/chrome/browser/ui/views/toolbar/toolbar_button.h
|
||||
+++ b/chrome/browser/ui/views/toolbar/toolbar_button.h
|
||||
@@ -132,6 +132,9 @@ class ToolbarButton : public views::LabelButton,
|
||||
void OnGestureEvent(ui::GestureEvent* event) override;
|
||||
std::u16string GetTooltipText(const gfx::Point& p) const override;
|
||||
std::unique_ptr<views::ActionViewInterface> GetActionViewInterface() override;
|
||||
+ void AddLayerToRegion(ui::Layer* new_layer,
|
||||
+ views::LayerRegion region) override;
|
||||
+ void RemoveLayerFromRegions(ui::Layer* old_layer) override;
|
||||
|
||||
// views::ContextMenuController:
|
||||
void ShowContextMenuForViewImpl(
|
||||
diff --git a/ui/views/controls/button/label_button.cc b/ui/views/controls/button/label_button.cc
|
||||
index f17cd72dbe014adc51301ef6e07d9a6ca94c5d67..5b675ae814e09eca55f9eea6772acc8f9a6b0a1e 100644
|
||||
--- a/ui/views/controls/button/label_button.cc
|
||||
+++ b/ui/views/controls/button/label_button.cc
|
||||
@@ -78,13 +78,6 @@ LabelButton::LabelButton(
|
||||
SetTextInternal(text);
|
||||
SetLayoutManager(std::make_unique<DelegatingLayoutManager>(this));
|
||||
GetViewAccessibility().SetIsDefault(is_default_);
|
||||
-
|
||||
-#if BUILDFLAG(IS_WIN)
|
||||
- // Paint image(s) to a layer so that the canvas is snapped to pixel
|
||||
- // boundaries.
|
||||
- image_container_view()->SetPaintToLayer();
|
||||
- image_container_view()->layer()->SetFillsBoundsOpaquely(false);
|
||||
-#endif
|
||||
}
|
||||
|
||||
LabelButton::~LabelButton() {
|
||||
@@ -508,10 +501,8 @@ void LabelButton::UpdateImage() {
|
||||
|
||||
void LabelButton::AddLayerToRegion(ui::Layer* new_layer,
|
||||
views::LayerRegion region) {
|
||||
-#if !BUILDFLAG(IS_WIN)
|
||||
image_container_view()->SetPaintToLayer();
|
||||
image_container_view()->layer()->SetFillsBoundsOpaquely(false);
|
||||
-#endif
|
||||
ink_drop_container()->SetVisible(true);
|
||||
ink_drop_container()->AddLayerToRegion(new_layer, region);
|
||||
}
|
||||
@@ -519,9 +510,7 @@ void LabelButton::AddLayerToRegion(ui::Layer* new_layer,
|
||||
void LabelButton::RemoveLayerFromRegions(ui::Layer* old_layer) {
|
||||
ink_drop_container()->RemoveLayerFromRegions(old_layer);
|
||||
ink_drop_container()->SetVisible(false);
|
||||
-#if !BUILDFLAG(IS_WIN)
|
||||
image_container_view()->DestroyLayer();
|
||||
-#endif
|
||||
}
|
||||
|
||||
std::unique_ptr<ActionViewInterface> LabelButton::GetActionViewInterface() {
|
||||
@@ -40,18 +40,18 @@ accessing uninitialized lower indexes can return garbage values that cannot be n
|
||||
Refer to v8::EmbedderDataSlot::store_aligned_pointer for context.
|
||||
|
||||
diff --git a/gin/public/gin_embedders.h b/gin/public/gin_embedders.h
|
||||
index 8d7c5631fd8f1499c67384286f0e3c4037673b32..99b2e2f63be8a46c5546dd53bc9b05e8c54e857c 100644
|
||||
index 8d7c5631fd8f1499c67384286f0e3c4037673b32..2b7bdfbac06a42e6bc51eb65e023c3673e6eb885 100644
|
||||
--- a/gin/public/gin_embedders.h
|
||||
+++ b/gin/public/gin_embedders.h
|
||||
@@ -18,6 +18,8 @@ namespace gin {
|
||||
enum GinEmbedder : uint16_t {
|
||||
kEmbedderNativeGin,
|
||||
@@ -20,6 +20,8 @@ enum GinEmbedder : uint16_t {
|
||||
kEmbedderBlink,
|
||||
+ kEmbedderElectron,
|
||||
+ kEmbedderBlinkTag,
|
||||
kEmbedderPDFium,
|
||||
kEmbedderFuchsia,
|
||||
+ kEmbedderElectron,
|
||||
+ kEmbedderBlinkTag,
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
diff --git a/third_party/blink/renderer/platform/bindings/script_state.cc b/third_party/blink/renderer/platform/bindings/script_state.cc
|
||||
index e4a27a24c83dd1a478b2ada8b6c8220076790791..c76dc818f38a62fff63852dbecbc85e304ac731d 100644
|
||||
--- a/third_party/blink/renderer/platform/bindings/script_state.cc
|
||||
@@ -86,7 +86,7 @@ index e4a27a24c83dd1a478b2ada8b6c8220076790791..c76dc818f38a62fff63852dbecbc85e3
|
||||
|
||||
// Cut the reference from ScriptState to V8 context.
|
||||
diff --git a/third_party/blink/renderer/platform/bindings/script_state.h b/third_party/blink/renderer/platform/bindings/script_state.h
|
||||
index b3cc8d819b06108386aed9465cab4f27a28b675f..a1757901e52360a9c2ec3c573adb20d03cd6ecae 100644
|
||||
index b3cc8d819b06108386aed9465cab4f27a28b675f..9c8818f10de59fdd2a3fd44d9cd23d40a93b53a7 100644
|
||||
--- a/third_party/blink/renderer/platform/bindings/script_state.h
|
||||
+++ b/third_party/blink/renderer/platform/bindings/script_state.h
|
||||
@@ -185,7 +185,12 @@ class PLATFORM_EXPORT ScriptState : public GarbageCollected<ScriptState> {
|
||||
@@ -112,14 +112,13 @@ index b3cc8d819b06108386aed9465cab4f27a28b675f..a1757901e52360a9c2ec3c573adb20d0
|
||||
static constexpr int kV8ContextPerContextDataIndex =
|
||||
static_cast<int>(gin::kPerContextDataStartIndex) +
|
||||
static_cast<int>(gin::kEmbedderBlink);
|
||||
@@ -271,6 +278,11 @@ class PLATFORM_EXPORT ScriptState : public GarbageCollected<ScriptState> {
|
||||
@@ -271,6 +278,10 @@ class PLATFORM_EXPORT ScriptState : public GarbageCollected<ScriptState> {
|
||||
// internals.idl.
|
||||
String last_compiled_script_file_name_;
|
||||
bool last_compiled_script_used_code_cache_ = false;
|
||||
+
|
||||
+ static constexpr int kV8ContextPerContextDataTagIndex =
|
||||
+ static_cast<int>(gin::kPerContextDataStartIndex) +
|
||||
+ static_cast<int>(gin::kEmbedderBlink) +
|
||||
+ static_cast<int>(gin::kEmbedderBlinkTag);
|
||||
};
|
||||
|
||||
|
||||
@@ -87,10 +87,10 @@ index 51522e60d6dc14f1113cc438558b6b393c3fe73a..153ed02f493a83ef9ca354cc18736f93
|
||||
// The view with active text input state, i.e., a focused <input> element.
|
||||
// It will be nullptr if no such view exists. Note that the active view
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index f8872945d67dacbdb9c3d610ff3719039eca7c94..5469931a7c4dc7ad8b98f5ac54c5538a7ba23a78 100644
|
||||
index ec55a5a2807bb9fc328b33d18ee10444f4b98126..ce65cb2aec41faa58a1dfa43f5c1ac8e5bc66641 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -9393,7 +9393,7 @@ void WebContentsImpl::OnFocusedElementChangedInFrame(
|
||||
@@ -9397,7 +9397,7 @@ void WebContentsImpl::OnFocusedElementChangedInFrame(
|
||||
"WebContentsImpl::OnFocusedElementChangedInFrame",
|
||||
"render_frame_host", frame);
|
||||
RenderWidgetHostViewBase* root_view =
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: reito <cnschwarzer@qq.com>
|
||||
Date: Wed, 12 Feb 2025 20:42:02 +0800
|
||||
Subject: fix: osr stutter in both cpu and gpu capture when page has animation.
|
||||
|
||||
https://crrev.org/c/6232721
|
||||
https://crbug.com/391118566
|
||||
There's bug in VideoCaptureOracle that cause stutter in both cpu and gpu capture when page has animation.
|
||||
The upstream has a fix, which will be available in Chromium M135.
|
||||
Backport this fix for Electron versions before that.
|
||||
|
||||
diff --git a/media/capture/content/video_capture_oracle.cc b/media/capture/content/video_capture_oracle.cc
|
||||
index dad9598799a670b3cfb14965bc8a7b4ea3b4f95f..05a82788ae1e5c304ee150a2390f346d7b454630 100644
|
||||
--- a/media/capture/content/video_capture_oracle.cc
|
||||
+++ b/media/capture/content/video_capture_oracle.cc
|
||||
@@ -118,8 +118,9 @@ void VideoCaptureOracle::SetCaptureSizeConstraints(
|
||||
void VideoCaptureOracle::SetAutoThrottlingEnabled(bool enabled) {
|
||||
const bool was_enabled =
|
||||
(capture_size_throttling_mode_ != kThrottlingDisabled);
|
||||
- if (was_enabled == enabled)
|
||||
+ if (was_enabled == enabled) {
|
||||
return;
|
||||
+ }
|
||||
capture_size_throttling_mode_ =
|
||||
enabled ? kThrottlingEnabled : kThrottlingDisabled;
|
||||
VLOG(1) << "Capture size auto-throttling is now "
|
||||
@@ -127,19 +128,22 @@ void VideoCaptureOracle::SetAutoThrottlingEnabled(bool enabled) {
|
||||
|
||||
// When not auto-throttling, have the CaptureResolutionChooser target the max
|
||||
// resolution within constraints.
|
||||
- if (!enabled)
|
||||
+ if (!enabled) {
|
||||
resolution_chooser_.SetTargetFrameArea(std::numeric_limits<int>::max());
|
||||
+ }
|
||||
|
||||
- if (next_frame_number_ > 0)
|
||||
+ if (next_frame_number_ > 0) {
|
||||
CommitCaptureSizeAndReset(GetFrameTimestamp(next_frame_number_ - 1));
|
||||
+ }
|
||||
}
|
||||
|
||||
void VideoCaptureOracle::SetSourceSize(const gfx::Size& source_size) {
|
||||
resolution_chooser_.SetSourceSize(source_size);
|
||||
// If the |resolution_chooser_| computed a new capture size, that will become
|
||||
// visible via a future call to ObserveEventAndDecideCapture().
|
||||
- source_size_change_time_ = (next_frame_number_ == 0) ?
|
||||
- base::TimeTicks() : GetFrameTimestamp(next_frame_number_ - 1);
|
||||
+ source_size_change_time_ = (next_frame_number_ == 0)
|
||||
+ ? base::TimeTicks()
|
||||
+ : GetFrameTimestamp(next_frame_number_ - 1);
|
||||
}
|
||||
|
||||
bool VideoCaptureOracle::ObserveEventAndDecideCapture(
|
||||
@@ -172,6 +176,15 @@ bool VideoCaptureOracle::ObserveEventAndDecideCapture(
|
||||
if (should_sample) {
|
||||
event_time = content_sampler_.frame_timestamp();
|
||||
duration_of_next_frame_ = content_sampler_.sampling_period();
|
||||
+ } else {
|
||||
+ // https://crbug.com/391118566
|
||||
+ // The content sampler may not sample the frame, if the
|
||||
+ // `detected_region_` does not match the `damage_rect`. In this case,
|
||||
+ // the capture may halt up to kNonAnimatingThreshold (250ms) and cause
|
||||
+ // the video stutter, until it recovers and do another animation
|
||||
+ // detection. To avoid this, we should use the smoothing sampler as a
|
||||
+ // fallback to prevent the bad output.
|
||||
+ should_sample = smoothing_sampler_.ShouldSample();
|
||||
}
|
||||
last_time_animation_was_detected_ = event_time;
|
||||
} else {
|
||||
@@ -198,8 +211,9 @@ bool VideoCaptureOracle::ObserveEventAndDecideCapture(
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
- if (!should_sample)
|
||||
+ if (!should_sample) {
|
||||
return false;
|
||||
+ }
|
||||
|
||||
// If the exact duration of the next frame has not been determined, estimate
|
||||
// it using the difference between the current and last frame.
|
||||
@@ -373,16 +387,18 @@ void VideoCaptureOracle::RecordConsumerFeedback(
|
||||
|
||||
// resource_utilization feedback.
|
||||
|
||||
- if (capture_size_throttling_mode_ == kThrottlingDisabled)
|
||||
+ if (capture_size_throttling_mode_ == kThrottlingDisabled) {
|
||||
return;
|
||||
+ }
|
||||
|
||||
if (!std::isfinite(feedback.resource_utilization)) {
|
||||
LOG(DFATAL) << "Non-finite utilization provided by consumer for frame #"
|
||||
<< frame_number << ": " << feedback.resource_utilization;
|
||||
return;
|
||||
}
|
||||
- if (feedback.resource_utilization <= 0.0)
|
||||
+ if (feedback.resource_utilization <= 0.0) {
|
||||
return; // Non-positive values are normal, meaning N/A.
|
||||
+ }
|
||||
|
||||
if (capture_size_throttling_mode_ != kThrottlingActive) {
|
||||
VLOG(1) << "Received consumer feedback at frame #" << frame_number
|
||||
@@ -553,12 +569,14 @@ int VideoCaptureOracle::AnalyzeForIncreasedArea(base::TimeTicks analyze_time) {
|
||||
const int current_area = capture_size_.GetArea();
|
||||
const int increased_area =
|
||||
resolution_chooser_.FindLargerFrameSize(current_area, 1).GetArea();
|
||||
- if (increased_area <= current_area)
|
||||
+ if (increased_area <= current_area) {
|
||||
return -1;
|
||||
+ }
|
||||
|
||||
// Determine whether the buffer pool could handle an increase in area.
|
||||
- if (!HasSufficientRecentFeedback(buffer_pool_utilization_, analyze_time))
|
||||
+ if (!HasSufficientRecentFeedback(buffer_pool_utilization_, analyze_time)) {
|
||||
return -1;
|
||||
+ }
|
||||
if (buffer_pool_utilization_.current() > 0.0) {
|
||||
const int buffer_capable_area = base::saturated_cast<int>(
|
||||
current_area / buffer_pool_utilization_.current());
|
||||
@@ -593,8 +611,9 @@ int VideoCaptureOracle::AnalyzeForIncreasedArea(base::TimeTicks analyze_time) {
|
||||
|
||||
// At this point, the system is currently under-utilized. Reset the start
|
||||
// time if the system was not under-utilized when the last analysis was made.
|
||||
- if (start_time_of_underutilization_.is_null())
|
||||
+ if (start_time_of_underutilization_.is_null()) {
|
||||
start_time_of_underutilization_ = analyze_time;
|
||||
+ }
|
||||
|
||||
// If the under-utilization started soon after the last source size change,
|
||||
// permit an immediate increase in the capture area. This allows the system
|
||||
diff --git a/media/capture/content/video_capture_oracle_unittest.cc b/media/capture/content/video_capture_oracle_unittest.cc
|
||||
index 066676fa998db6782270ddbf42fe176d88eb30d4..6cd7567e91bc8c496846a685aa1506c7548f3a21 100644
|
||||
--- a/media/capture/content/video_capture_oracle_unittest.cc
|
||||
+++ b/media/capture/content/video_capture_oracle_unittest.cc
|
||||
@@ -158,21 +158,26 @@ TEST(VideoCaptureOracleTest, TransitionsSmoothlyBetweenSamplers) {
|
||||
const bool provide_animated_content_event =
|
||||
(i % 100) >= 25 && (i % 100) < 75;
|
||||
|
||||
- // Only the few events that trigger the lock-out transition should be
|
||||
- // dropped, because the AnimatedContentSampler doesn't yet realize the
|
||||
- // animation ended. Otherwise, the oracle should always decide to sample
|
||||
- // because one of its samplers says to.
|
||||
- const bool require_oracle_says_sample = (i % 100) < 75 || (i % 100) >= 78;
|
||||
+ // https://crbug.com/391118566
|
||||
+ // Previously the AnimatedContentSampler has a bug that cause jank.
|
||||
+ // The oracle should always use SmoothEventSampler as a fallback. If
|
||||
+ // AnimatedContentSampler doesn't yet realize the animation ended or
|
||||
+ // doesn't keep up with the prediction it make, and it will wait for
|
||||
+ // kNonAnimatingThreshold before it lock-out and hand over to smooth
|
||||
+ // handler. This will cause the video to stutter and it is unacceptable.
|
||||
+ // So, when the AnimatedContentSampler goes into wrong state, we now
|
||||
+ // use SmoothEventSampler's decision as a fallback to prevent jank output
|
||||
+ // and still has a overall limit on capture frequency.
|
||||
const bool oracle_says_sample = oracle.ObserveEventAndDecideCapture(
|
||||
VideoCaptureOracle::kCompositorUpdate,
|
||||
provide_animated_content_event ? animation_damage_rect : gfx::Rect(),
|
||||
t);
|
||||
- if (require_oracle_says_sample)
|
||||
- ASSERT_TRUE(oracle_says_sample);
|
||||
- if (!oracle_says_sample) {
|
||||
- ASSERT_EQ(base::TimeDelta(), oracle.estimated_frame_duration());
|
||||
- continue;
|
||||
- }
|
||||
+
|
||||
+ // Because we now use SmoothEventSampler as a fallback, oracle should
|
||||
+ // always say sample. The previous AnimatedContentSampler lock-out
|
||||
+ // dropped frame are now revived by SmoothEventSampler, since this test's
|
||||
+ // capture frequency always meets min capture limit requirement.
|
||||
+ ASSERT_TRUE(oracle_says_sample);
|
||||
ASSERT_LT(base::TimeDelta(), oracle.estimated_frame_duration());
|
||||
|
||||
const int frame_number = oracle.next_frame_number();
|
||||
@@ -184,12 +189,9 @@ TEST(VideoCaptureOracleTest, TransitionsSmoothlyBetweenSamplers) {
|
||||
if (!last_frame_timestamp.is_null()) {
|
||||
const base::TimeDelta delta = frame_timestamp - last_frame_timestamp;
|
||||
EXPECT_LE(event_increment.InMicroseconds(), delta.InMicroseconds());
|
||||
- // Right after the AnimatedContentSampler lock-out transition, there were
|
||||
- // a few frames dropped, so allow a gap in the timestamps. Otherwise, the
|
||||
- // delta between frame timestamps should never be more than 2X the
|
||||
+ // The delta between frame timestamps should never be more than 2X the
|
||||
// |event_increment|.
|
||||
- const base::TimeDelta max_acceptable_delta =
|
||||
- (i % 100) == 78 ? event_increment * 5 : event_increment * 2;
|
||||
+ const base::TimeDelta max_acceptable_delta = event_increment * 2;
|
||||
EXPECT_GE(max_acceptable_delta.InMicroseconds(), delta.InMicroseconds());
|
||||
}
|
||||
last_frame_timestamp = frame_timestamp;
|
||||
@@ -444,9 +446,9 @@ void RunAutoThrottleTest(bool is_content_animating,
|
||||
// expect the resolution to remain constant. Repeat.
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
const gfx::Size starting_size = oracle.capture_size();
|
||||
- SCOPED_TRACE(::testing::Message() << "Stepping down from "
|
||||
- << starting_size.ToString()
|
||||
- << ", i=" << i);
|
||||
+ SCOPED_TRACE(::testing::Message()
|
||||
+ << "Stepping down from " << starting_size.ToString()
|
||||
+ << ", i=" << i);
|
||||
|
||||
gfx::Size stepped_down_size;
|
||||
end_t = t + base::Seconds(10);
|
||||
@@ -471,9 +473,10 @@ void RunAutoThrottleTest(bool is_content_animating,
|
||||
oracle.RecordCapture(with_consumer_feedback ? 0.25 : utilization);
|
||||
base::TimeTicks ignored;
|
||||
ASSERT_TRUE(oracle.CompleteCapture(frame_number, true, &ignored));
|
||||
- if (with_consumer_feedback)
|
||||
+ if (with_consumer_feedback) {
|
||||
oracle.RecordConsumerFeedback(frame_number,
|
||||
media::VideoCaptureFeedback(utilization));
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,9 +485,9 @@ void RunAutoThrottleTest(bool is_content_animating,
|
||||
// utilization and expect the resolution to remain constant. Repeat.
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
const gfx::Size starting_size = oracle.capture_size();
|
||||
- SCOPED_TRACE(::testing::Message() << "Stepping up from "
|
||||
- << starting_size.ToString()
|
||||
- << ", i=" << i);
|
||||
+ SCOPED_TRACE(::testing::Message()
|
||||
+ << "Stepping up from " << starting_size.ToString()
|
||||
+ << ", i=" << i);
|
||||
|
||||
gfx::Size stepped_up_size;
|
||||
end_t = t + base::Seconds(is_content_animating ? 90 : 10);
|
||||
@@ -513,9 +516,10 @@ void RunAutoThrottleTest(bool is_content_animating,
|
||||
oracle.RecordCapture(with_consumer_feedback ? 0.25 : utilization);
|
||||
base::TimeTicks ignored;
|
||||
ASSERT_TRUE(oracle.CompleteCapture(frame_number, true, &ignored));
|
||||
- if (with_consumer_feedback)
|
||||
+ if (with_consumer_feedback) {
|
||||
oracle.RecordConsumerFeedback(frame_number,
|
||||
media::VideoCaptureFeedback(utilization));
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ or resizing, but Electron does not seem to run into that issue
|
||||
for opaque frameless windows even with that block commented out.
|
||||
|
||||
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
|
||||
index 026b0f9b404267b17e1ea6b61b5ebb188b9b0bed..fda18ecab7e982b3087c7667d36578177d370066 100644
|
||||
index 9ac53e223aa095acdf90b68bc1e6bc81e3021ab9..562532f5795ee833493614f3f16d35bda2654d8d 100644
|
||||
--- a/ui/views/win/hwnd_message_handler.cc
|
||||
+++ b/ui/views/win/hwnd_message_handler.cc
|
||||
@@ -1736,7 +1736,23 @@ LRESULT HWNDMessageHandler::OnCreate(CREATESTRUCT* create_struct) {
|
||||
|
||||
@@ -10,10 +10,10 @@ process CompositingModeFallbackToSoftware IPC to disable GPU compositing.
|
||||
https://issues.chromium.org/345275130
|
||||
|
||||
diff --git a/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.cc b/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.cc
|
||||
index 001e931ba705a1a52dfbcb717fe8e30b7014fde8..c545a7257e561f86aecc336769c0dd22c9772465 100644
|
||||
index b2569e7ce111e9fd8ab76a0adebfa35c8487f53e..898528a7a0ffa279eda5ba9f81eb73b84431577b 100644
|
||||
--- a/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.cc
|
||||
+++ b/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.cc
|
||||
@@ -381,9 +381,13 @@ void LayerTreeView::DidFailToInitializeLayerTreeFrameSink() {
|
||||
@@ -387,9 +387,13 @@ void LayerTreeView::DidFailToInitializeLayerTreeFrameSink() {
|
||||
// unable to be killed after Chrome is closed.
|
||||
// https://issues.chromium.org/336164423
|
||||
if (!Platform::Current()->IsGpuRemoteDisconnected()) {
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Thu, 13 Mar 2025 10:47:00 +0100
|
||||
Subject: fix: take Snapped status into account when showing a window
|
||||
|
||||
Adjusts HWNDMessageHandler::Show to correctly restore windows that were
|
||||
in a snapped state prior to being hidden or maximized. From Windows
|
||||
documentation at
|
||||
https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-iswindowarranged:
|
||||
|
||||
> A snapped window (see Snap your windows) is considered to be arranged.
|
||||
> You should treat arranged as a window state similar to maximized. Arranged,
|
||||
> maximized, and minimized are mutually exclusive states.
|
||||
|
||||
The logic already took into account a window being maximized and
|
||||
correctly restored it, but if the window was snapped prior to this CL it
|
||||
would be removed from its snapped state when re-shown. This fixes that.
|
||||
|
||||
Upstreamed at https://chromium-review.googlesource.com/c/chromium/src/+/6330848.
|
||||
|
||||
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
|
||||
index 98a3365ce2b5ef4e34eb9edf66ef3f620af9ab1d..b5d8f82255764a42df816e58bfcbd588534de2e4 100644
|
||||
--- a/ui/views/win/hwnd_message_handler.cc
|
||||
+++ b/ui/views/win/hwnd_message_handler.cc
|
||||
@@ -656,7 +656,8 @@ void HWNDMessageHandler::Show(ui::mojom::WindowShowState show_state,
|
||||
SetWindowPlacement(hwnd(), &placement);
|
||||
native_show_state = SW_SHOWMAXIMIZED;
|
||||
} else {
|
||||
- const bool is_maximized = IsMaximized();
|
||||
+ const bool is_maximized_or_arranged =
|
||||
+ IsMaximized() || IsWindowArranged(hwnd());
|
||||
|
||||
// Use SW_SHOW/SW_SHOWNA instead of SW_SHOWNORMAL/SW_SHOWNOACTIVATE so that
|
||||
// the window is not restored to its original position if it is maximized.
|
||||
@@ -666,7 +667,8 @@ void HWNDMessageHandler::Show(ui::mojom::WindowShowState show_state,
|
||||
// position, some do not. See crbug.com/1296710
|
||||
switch (show_state) {
|
||||
case ui::mojom::WindowShowState::kInactive:
|
||||
- native_show_state = is_maximized ? SW_SHOWNA : SW_SHOWNOACTIVATE;
|
||||
+ native_show_state =
|
||||
+ is_maximized_or_arranged ? SW_SHOWNA : SW_SHOWNOACTIVATE;
|
||||
break;
|
||||
case ui::mojom::WindowShowState::kMaximized:
|
||||
native_show_state = SW_SHOWMAXIMIZED;
|
||||
@@ -677,9 +679,11 @@ void HWNDMessageHandler::Show(ui::mojom::WindowShowState show_state,
|
||||
case ui::mojom::WindowShowState::kNormal:
|
||||
if ((GetWindowLong(hwnd(), GWL_EXSTYLE) & WS_EX_TRANSPARENT) ||
|
||||
(GetWindowLong(hwnd(), GWL_EXSTYLE) & WS_EX_NOACTIVATE)) {
|
||||
- native_show_state = is_maximized ? SW_SHOWNA : SW_SHOWNOACTIVATE;
|
||||
+ native_show_state =
|
||||
+ is_maximized_or_arranged ? SW_SHOWNA : SW_SHOWNOACTIVATE;
|
||||
} else {
|
||||
- native_show_state = is_maximized ? SW_SHOW : SW_SHOWNORMAL;
|
||||
+ native_show_state =
|
||||
+ is_maximized_or_arranged ? SW_SHOW : SW_SHOWNORMAL;
|
||||
}
|
||||
break;
|
||||
case ui::mojom::WindowShowState::kFullscreen:
|
||||
@@ -0,0 +1,40 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?David=20L=C3=B6nnhager?= <dv.lnh.d@gmail.com>
|
||||
Date: Fri, 17 Jan 2025 14:30:48 +0100
|
||||
Subject: Ignore parse errors for PKEY_AppUserModel_ToastActivatorCLSID
|
||||
|
||||
Some shortcuts store this as a string UUID as opposed to VT_CLSID,
|
||||
hitting NOTREACHED() and sometimes breaking parsing in Electron.
|
||||
Ignore this error instead.
|
||||
|
||||
Bug: N/A
|
||||
Change-Id: I9fc472212b2d3afac2c8e18a2159bc2d50bbdf98
|
||||
|
||||
diff --git a/AUTHORS b/AUTHORS
|
||||
index 897b6678b6d583f3361c41f62b960e46165d288d..13afc62098608e79faf02d504b54d9d6326b8ed3 100644
|
||||
--- a/AUTHORS
|
||||
+++ b/AUTHORS
|
||||
@@ -336,6 +336,7 @@ David Futcher <david.mike.futcher@gmail.com>
|
||||
David Jin <davidjin@amazon.com>
|
||||
David Lechner <david@pybricks.com>
|
||||
David Leen <davileen@amazon.com>
|
||||
+David Lönnhager <dv.lnh.d@gmail.com>
|
||||
David Manouchehri <david@davidmanouchehri.com>
|
||||
David McAllister <mcdavid@amazon.com>
|
||||
David Michael Barr <david.barr@samsung.com>
|
||||
diff --git a/base/win/shortcut.cc b/base/win/shortcut.cc
|
||||
index 02f3e63d16c3324f546f6155d722900f0a81131a..1dfdb0c8dc5a7368382e73a0db1b4d135b4d2176 100644
|
||||
--- a/base/win/shortcut.cc
|
||||
+++ b/base/win/shortcut.cc
|
||||
@@ -342,8 +342,9 @@ bool ResolveShortcutProperties(const FilePath& shortcut_path,
|
||||
*(pv_toast_activator_clsid.get().puuid));
|
||||
break;
|
||||
default:
|
||||
- NOTREACHED() << "Unexpected variant type: "
|
||||
- << pv_toast_activator_clsid.get().vt;
|
||||
+ // Shortcuts may use strings to represent the CLSID. This case is
|
||||
+ // ignored.
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ This adds a callback from the network service that's used to implement
|
||||
session.setCertificateVerifyCallback.
|
||||
|
||||
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
|
||||
index cae84c27a26d6198d9da5913b008e748d6680037..4be02fdb03038ee4c30ea699cbbf56d1f5aaa7aa 100644
|
||||
index f03bc67fbd15625b4935c0333f1b3f129a8ce246..c5199a66320bfdb7abda0878b7ae24e02f49b420 100644
|
||||
--- a/services/network/network_context.cc
|
||||
+++ b/services/network/network_context.cc
|
||||
@@ -158,6 +158,11 @@
|
||||
@@ -122,7 +122,7 @@ index cae84c27a26d6198d9da5913b008e748d6680037..4be02fdb03038ee4c30ea699cbbf56d1
|
||||
constexpr uint32_t NetworkContext::kMaxOutstandingRequestsPerProcess;
|
||||
|
||||
NetworkContext::NetworkContextHttpAuthPreferences::
|
||||
@@ -1000,6 +1098,13 @@ void NetworkContext::SetClient(
|
||||
@@ -1003,6 +1101,13 @@ void NetworkContext::SetClient(
|
||||
client_.Bind(std::move(client));
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ index cae84c27a26d6198d9da5913b008e748d6680037..4be02fdb03038ee4c30ea699cbbf56d1
|
||||
void NetworkContext::CreateURLLoaderFactory(
|
||||
mojo::PendingReceiver<mojom::URLLoaderFactory> receiver,
|
||||
mojom::URLLoaderFactoryParamsPtr params) {
|
||||
@@ -2569,6 +2674,9 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext(
|
||||
@@ -2572,6 +2677,9 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext(
|
||||
std::move(cert_verifier));
|
||||
cert_verifier = std::move(cert_verifier_with_trust_anchors);
|
||||
#endif // BUILDFLAG(IS_CHROMEOS)
|
||||
|
||||
@@ -133,7 +133,7 @@ index 05d3a12dd84c7005d46cc73b312f97ef418d96f5..4765de982802541b3efc7211d106acc7
|
||||
const GURL& document_url,
|
||||
const WeakDocumentPtr& weak_document_ptr,
|
||||
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
|
||||
index 09b7137cd3e26a1aef2c93ff7f08641df56704c0..732978b9650cac5102007c27b9226ff053c92d4f 100644
|
||||
index 10a3e987def641bc3504d20a591cc95f1b9fe84f..eca2f5da88dd911ce64824479aac01320840cc22 100644
|
||||
--- a/content/browser/renderer_host/render_process_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_process_host_impl.cc
|
||||
@@ -2106,7 +2106,7 @@ void RenderProcessHostImpl::CreateNotificationService(
|
||||
|
||||
@@ -10,7 +10,7 @@ an about:blank check to this area.
|
||||
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/5403876
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
index 7b7e21c5b4b2e6657965c4433c6f9bc064a4ef9f..5abddf5b5cf2ab5e8e03066143b1824908257e87 100644
|
||||
index 2d82c283867cf78fc63275bffbd9eff4d8a606e9..7222a4475e77d4f44ee155825d5cb5238d22e107 100644
|
||||
--- a/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
@@ -784,8 +784,8 @@ void VerifyThatBrowserAndRendererCalculatedOriginsToCommitMatch(
|
||||
|
||||
@@ -653,7 +653,7 @@ index 3c2fdc9f9a6c60efc4b0afacbfb83eef55917791..8fd9aff538fa03da6c171927c316d4f6
|
||||
PrintingFailed(int32 cookie, PrintFailureReason reason);
|
||||
|
||||
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc
|
||||
index 423cea4420bc868baad6260fb7c6b33430eaaf95..2b105dc1fb2a7b06fe717df9edf897446aca606c 100644
|
||||
index 423cea4420bc868baad6260fb7c6b33430eaaf95..4a51a5156b9e15e2bbfac521cfbb3f397acaeccc 100644
|
||||
--- a/components/printing/renderer/print_render_frame_helper.cc
|
||||
+++ b/components/printing/renderer/print_render_frame_helper.cc
|
||||
@@ -52,6 +52,7 @@
|
||||
@@ -771,7 +771,7 @@ index 423cea4420bc868baad6260fb7c6b33430eaaf95..2b105dc1fb2a7b06fe717df9edf89744
|
||||
// Check if `this` is still valid.
|
||||
if (!self)
|
||||
return;
|
||||
@@ -2360,29 +2375,37 @@ void PrintRenderFrameHelper::IPCProcessed() {
|
||||
@@ -2360,29 +2375,44 @@ void PrintRenderFrameHelper::IPCProcessed() {
|
||||
}
|
||||
|
||||
bool PrintRenderFrameHelper::InitPrintSettings(blink::WebLocalFrame* frame,
|
||||
@@ -801,12 +801,22 @@ index 423cea4420bc868baad6260fb7c6b33430eaaf95..2b105dc1fb2a7b06fe717df9edf89744
|
||||
return false;
|
||||
}
|
||||
|
||||
bool center_on_paper = !IsPrintingPdfFrame(frame, node);
|
||||
- bool center_on_paper = !IsPrintingPdfFrame(frame, node);
|
||||
- settings.params->print_scaling_option =
|
||||
+ settings->params->print_scaling_option =
|
||||
center_on_paper ? mojom::PrintScalingOption::kCenterShrinkToFitPaper
|
||||
: mojom::PrintScalingOption::kSourceSize;
|
||||
- center_on_paper ? mojom::PrintScalingOption::kCenterShrinkToFitPaper
|
||||
- : mojom::PrintScalingOption::kSourceSize;
|
||||
- RecordDebugEvent(settings.params->printed_doc_type ==
|
||||
+ bool silent = new_settings.FindBool("silent").value_or(false);
|
||||
+ if (silent) {
|
||||
+ settings->params->print_scaling_option = mojom::PrintScalingOption::kFitToPrintableArea;
|
||||
+ } else {
|
||||
+ const auto plugin_node = delegate_->GetPdfElement(frame);
|
||||
+ const bool center_on_paper = !IsPrintingPdfFrame(frame, plugin_node);
|
||||
+ settings->params->print_scaling_option =
|
||||
+ center_on_paper ? mojom::PrintScalingOption::kCenterShrinkToFitPaper
|
||||
+ : mojom::PrintScalingOption::kSourceSize;
|
||||
+ }
|
||||
+
|
||||
+ RecordDebugEvent(settings->params->printed_doc_type ==
|
||||
mojom::SkiaDocumentType::kMSKP
|
||||
? DebugEvent::kSetPrintSettings5
|
||||
|
||||
@@ -44,10 +44,10 @@ index 886d70636aedfa714b29625f58420ad11ede9ffd..7906b94983733a9deb2365fb2a134619
|
||||
|
||||
void RenderWidgetHostImpl::ShowContextMenuAtPoint(
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index a722f77502e8b896fb5d55df7cb44d45d13df04f..1f0b9a602a9e6cf565818ad584688b783fe3430b 100644
|
||||
index d35ae086793a52ea38da97b9236e073b806a67a6..d88c3b6a3625c2f4d0c67677777202f7db85ea88 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -5616,6 +5616,11 @@ TextInputManager* WebContentsImpl::GetTextInputManager() {
|
||||
@@ -5620,6 +5620,11 @@ TextInputManager* WebContentsImpl::GetTextInputManager() {
|
||||
return text_input_manager_.get();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@ This CL removes these filters so the unresponsive event can still be
|
||||
accessed from our JS event. The filtering is moved into Electron's code.
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index 9bd28a4029de17833d5147986736747075ff35bc..140e94cd6dfba03260ff9e2cf4b38459cdaaf9ba 100644
|
||||
index 784a7536eec5a248e4725253c091b039047ff1ea..6939dbd68fbdde3710b13a4158893d859910034a 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -9527,25 +9527,13 @@ void WebContentsImpl::RendererUnresponsive(
|
||||
@@ -9531,25 +9531,13 @@ void WebContentsImpl::RendererUnresponsive(
|
||||
base::RepeatingClosure hang_monitor_restarter) {
|
||||
OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RendererUnresponsive",
|
||||
"render_widget_host", render_widget_host);
|
||||
|
||||
17462
patches/chromium/reland_lzma_sdk_update_to_24_09.patch
Normal file
17462
patches/chromium/reland_lzma_sdk_update_to_24_09.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,90 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Wilson <mjwilson@chromium.org>
|
||||
Date: Thu, 30 Jan 2025 14:09:57 -0800
|
||||
Subject: Remove DenormalEnabler from ScriptProcessorNode
|
||||
|
||||
This is a follow-up to https://crrev.com/c/6077677
|
||||
|
||||
After experimenting, ScriptProcessorNode JavaScript is already running
|
||||
in a complaint mode so the DenormalEnabler is not necessary.
|
||||
|
||||
Bug: 382005099
|
||||
Change-Id: If9774e60640446c567270a8f065500beecc8a40b
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6219685
|
||||
Commit-Queue: Michael Wilson <mjwilson@chromium.org>
|
||||
Reviewed-by: Alvin Ji <alvinji@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1413754}
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/script_processor_handler.cc b/third_party/blink/renderer/modules/webaudio/script_processor_handler.cc
|
||||
index ea04e2cd2bfb553a58ba6fb9c63c70c5a2690442..d3d44d2a4c87bf5d4191807ec31d87c7e597fef9 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/script_processor_handler.cc
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/script_processor_handler.cc
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h"
|
||||
#include "third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.h"
|
||||
#include "third_party/blink/renderer/modules/webaudio/script_processor_node.h"
|
||||
-#include "third_party/blink/renderer/platform/audio/denormal_disabler.h"
|
||||
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
|
||||
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
|
||||
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_base.h"
|
||||
@@ -49,9 +48,7 @@ ScriptProcessorHandler::ScriptProcessorHandler(
|
||||
internal_input_bus_(AudioBus::Create(
|
||||
number_of_input_channels,
|
||||
node.context()->GetDeferredTaskHandler().RenderQuantumFrames(),
|
||||
- false)),
|
||||
- allow_denormal_in_processing_(base::FeatureList::IsEnabled(
|
||||
- features::kWebAudioAllowDenormalInProcessing)) {
|
||||
+ false)) {
|
||||
DCHECK_GE(buffer_size_,
|
||||
node.context()->GetDeferredTaskHandler().RenderQuantumFrames());
|
||||
DCHECK_LE(number_of_input_channels, BaseAudioContext::MaxNumberOfChannels());
|
||||
@@ -112,7 +109,7 @@ void ScriptProcessorHandler::Initialize() {
|
||||
AudioHandler::Initialize();
|
||||
}
|
||||
|
||||
-void ScriptProcessorHandler::ProcessInternal(uint32_t frames_to_process) {
|
||||
+void ScriptProcessorHandler::Process(uint32_t frames_to_process) {
|
||||
TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("webaudio.audionode"),
|
||||
"ScriptProcessorHandler::Process");
|
||||
|
||||
@@ -241,15 +238,6 @@ void ScriptProcessorHandler::ProcessInternal(uint32_t frames_to_process) {
|
||||
"ScriptProcessorHandler::Process");
|
||||
}
|
||||
|
||||
-void ScriptProcessorHandler::Process(uint32_t frames_to_process) {
|
||||
- if (allow_denormal_in_processing_) {
|
||||
- DenormalEnabler denormal_enabler;
|
||||
- ProcessInternal(frames_to_process);
|
||||
- } else {
|
||||
- ProcessInternal(frames_to_process);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
void ScriptProcessorHandler::FireProcessEvent(uint32_t double_buffer_index) {
|
||||
DCHECK(IsMainThread());
|
||||
|
||||
diff --git a/third_party/blink/renderer/modules/webaudio/script_processor_handler.h b/third_party/blink/renderer/modules/webaudio/script_processor_handler.h
|
||||
index 99103e947ade50f07a16a61bc8702d6097266296..78deeb9219e3d5a98ac4d3b5cd4c98dd403407e3 100644
|
||||
--- a/third_party/blink/renderer/modules/webaudio/script_processor_handler.h
|
||||
+++ b/third_party/blink/renderer/modules/webaudio/script_processor_handler.h
|
||||
@@ -66,10 +66,6 @@ class ScriptProcessorHandler final : public AudioHandler {
|
||||
const HeapVector<Member<AudioBuffer>>& input_buffers,
|
||||
const HeapVector<Member<AudioBuffer>>& output_buffers);
|
||||
|
||||
- // Used to avoid code duplication when using scoped objects that affect
|
||||
- // `Process`.
|
||||
- void ProcessInternal(uint32_t frames_to_process);
|
||||
-
|
||||
double TailTime() const override;
|
||||
double LatencyTime() const override;
|
||||
bool RequiresTailProcessing() const final;
|
||||
@@ -97,9 +93,6 @@ class ScriptProcessorHandler final : public AudioHandler {
|
||||
|
||||
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
|
||||
|
||||
- // Cached feature flag value
|
||||
- const bool allow_denormal_in_processing_;
|
||||
-
|
||||
base::WeakPtrFactory<ScriptProcessorHandler> weak_ptr_factory_{this};
|
||||
|
||||
FRIEND_TEST_ALL_PREFIXES(ScriptProcessorNodeTest, BufferLifetime);
|
||||
@@ -0,0 +1,390 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Xianzhu Wang <wangxianzhu@chromium.org>
|
||||
Date: Fri, 14 Feb 2025 08:58:16 -0800
|
||||
Subject: Revert "blink: Fix over invalidation with view transitions"
|
||||
|
||||
This patch can be removed when we bump Chromium to 135.0.7019.0
|
||||
|
||||
This reverts commit bde2842dd31e89215d395470964797c92773819f.
|
||||
|
||||
Reason for revert: The CL caused crbug.com/391907157.
|
||||
|
||||
Original change's description:
|
||||
> blink: Fix over invalidation with view transitions
|
||||
>
|
||||
> View Transition conditionally generates the view transition effect node
|
||||
> for the LayoutView during the transition. This results in invalidation
|
||||
> of it's scrolling background layer at the start/end of the transition.
|
||||
>
|
||||
> Avoid this by always generating this node for the LayoutView. This is
|
||||
> not necessary for the child LayoutObjects. If they are composited, they
|
||||
> already have an EffectNode which avoids invalidation from paint property
|
||||
> node changes.
|
||||
>
|
||||
> Fixed: 361370195
|
||||
> Change-Id: I1c8c309dea5bb1d2572995bbaafb2fb8003be96e
|
||||
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5996658
|
||||
> Reviewed-by: Xianzhu Wang <wangxianzhu@chromium.org>
|
||||
> Auto-Submit: Khushal Sagar <khushalsagar@chromium.org>
|
||||
> Commit-Queue: Khushal Sagar <khushalsagar@chromium.org>
|
||||
> Cr-Commit-Position: refs/heads/main@{#1380843}
|
||||
|
||||
Bug: 391907157, 361370195
|
||||
Change-Id: Ifc7bb6fedb326867e5ed608b2c8152844ae2dd95
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6262017
|
||||
Auto-Submit: Xianzhu Wang <wangxianzhu@chromium.org>
|
||||
Commit-Queue: Vladimir Levin <vmpstr@chromium.org>
|
||||
Reviewed-by: Vladimir Levin <vmpstr@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1420533}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
|
||||
index 4dd99f130cb99355e4d58766a322e8db1e69bca9..9b9851dbb92977d76a842b0a943e969493231275 100644
|
||||
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
|
||||
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
|
||||
@@ -1834,32 +1834,25 @@ void FragmentPaintPropertyTreeBuilder::UpdateViewTransitionEffect() {
|
||||
properties_->ViewTransitionEffect()
|
||||
->SelfOrAncestorParticipatesInViewTransition();
|
||||
|
||||
- const bool is_view_transition_element =
|
||||
+ const bool needs_view_transition_effect =
|
||||
full_context_.direct_compositing_reasons &
|
||||
CompositingReason::kViewTransitionElement;
|
||||
|
||||
- const bool needs_view_transition_effect =
|
||||
- is_view_transition_element ||
|
||||
- (object_.IsLayoutView() && !IsInLocalSubframe(object_) &&
|
||||
- !object_.GetDocument().IsSVGDocument());
|
||||
-
|
||||
if (needs_view_transition_effect) {
|
||||
auto* transition =
|
||||
ViewTransitionUtils::GetTransition(object_.GetDocument());
|
||||
- DCHECK(!is_view_transition_element || transition);
|
||||
+ DCHECK(transition);
|
||||
|
||||
EffectPaintPropertyNode::State state;
|
||||
+ state.direct_compositing_reasons =
|
||||
+ CompositingReason::kViewTransitionElement;
|
||||
state.local_transform_space = context_.current.transform;
|
||||
state.output_clip = context_.current.clip;
|
||||
state.compositor_element_id = CompositorElementIdFromUniqueObjectId(
|
||||
object_.UniqueId(),
|
||||
CompositorElementIdNamespace::kViewTransitionElement);
|
||||
- if (is_view_transition_element) {
|
||||
- state.direct_compositing_reasons =
|
||||
- CompositingReason::kViewTransitionElement;
|
||||
- state.view_transition_element_resource_id =
|
||||
- transition->GetSnapshotId(object_);
|
||||
- }
|
||||
+ state.view_transition_element_resource_id =
|
||||
+ transition->GetSnapshotId(object_);
|
||||
|
||||
// The value isn't set on the root, since clipping rules are different for
|
||||
// the root view transition element.
|
||||
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
|
||||
index b3da3b381113fb6ea17d3d6de7bf2cf43e175362..aa57763835d2e8dbf4d021d58c14e1dd605d5cd6 100644
|
||||
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
|
||||
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
|
||||
@@ -77,17 +77,6 @@ const ScrollPaintPropertyNode* PaintPropertyTreeBuilderTest::DocScroll(
|
||||
return document->GetLayoutView()->FirstFragment().PaintProperties()->Scroll();
|
||||
}
|
||||
|
||||
-const EffectPaintPropertyNode* PaintPropertyTreeBuilderTest::DocEffect(
|
||||
- const Document* document) {
|
||||
- if (!document) {
|
||||
- document = &GetDocument();
|
||||
- }
|
||||
- return document->GetLayoutView()
|
||||
- ->FirstFragment()
|
||||
- .PaintProperties()
|
||||
- ->ViewTransitionEffect();
|
||||
-}
|
||||
-
|
||||
const ObjectPaintProperties*
|
||||
PaintPropertyTreeBuilderTest::PaintPropertiesForElement(const char* name) {
|
||||
return GetDocument()
|
||||
@@ -1058,7 +1047,8 @@ TEST_P(PaintPropertyTreeBuilderTest, EffectNodesInSVG) {
|
||||
PaintPropertiesForElement("groupWithOpacity");
|
||||
EXPECT_EQ(0.6f, group_with_opacity_properties->Effect()->Opacity());
|
||||
EXPECT_EQ(svg_clip, group_with_opacity_properties->Effect()->OutputClip());
|
||||
- EXPECT_EQ(DocEffect(), group_with_opacity_properties->Effect()->Parent());
|
||||
+ EXPECT_EQ(&EffectPaintPropertyNode::Root(),
|
||||
+ group_with_opacity_properties->Effect()->Parent());
|
||||
|
||||
EXPECT_EQ(nullptr, PaintPropertiesForElement("rectWithoutOpacity"));
|
||||
|
||||
@@ -4762,7 +4752,7 @@ TEST_P(PaintPropertyTreeBuilderTest, Reflection) {
|
||||
filter_properties->PaintOffsetTranslation()->Parent());
|
||||
EXPECT_EQ(gfx::Vector2dF(8, 8),
|
||||
filter_properties->PaintOffsetTranslation()->Get2dTranslation());
|
||||
- EXPECT_EQ(filter_properties->Filter()->Parent(), DocEffect());
|
||||
+ EXPECT_TRUE(filter_properties->Filter()->Parent()->IsRoot());
|
||||
EXPECT_EQ(filter_properties->PaintOffsetTranslation(),
|
||||
&filter_properties->Filter()->LocalTransformSpace());
|
||||
EXPECT_EQ(DocContentClip(), filter_properties->Filter()->OutputClip());
|
||||
@@ -4775,7 +4765,7 @@ TEST_P(PaintPropertyTreeBuilderTest, SimpleFilter) {
|
||||
const ObjectPaintProperties* filter_properties =
|
||||
GetLayoutObjectByElementId("filter")->FirstFragment().PaintProperties();
|
||||
EXPECT_FALSE(filter_properties->PaintOffsetTranslation());
|
||||
- EXPECT_EQ(filter_properties->Filter()->Parent(), DocEffect());
|
||||
+ EXPECT_TRUE(filter_properties->Filter()->Parent()->IsRoot());
|
||||
EXPECT_FALSE(filter_properties->PixelMovingFilterClipExpander());
|
||||
EXPECT_EQ(DocScrollTranslation(),
|
||||
&filter_properties->Filter()->LocalTransformSpace());
|
||||
@@ -4792,7 +4782,7 @@ TEST_P(PaintPropertyTreeBuilderTest, PixelMovingFilter) {
|
||||
|
||||
auto* filter = filter_properties->Filter();
|
||||
ASSERT_TRUE(filter);
|
||||
- EXPECT_EQ(filter->Parent(), DocEffect());
|
||||
+ EXPECT_TRUE(filter->Parent()->IsRoot());
|
||||
EXPECT_TRUE(filter->HasFilterThatMovesPixels());
|
||||
EXPECT_EQ(DocScrollTranslation(), &filter->LocalTransformSpace());
|
||||
EXPECT_EQ(DocContentClip(), filter->OutputClip());
|
||||
@@ -4847,7 +4837,7 @@ TEST_P(PaintPropertyTreeBuilderTest, FilterReparentClips) {
|
||||
GetLayoutObjectByElementId("clip")->FirstFragment().PaintProperties();
|
||||
const ObjectPaintProperties* filter_properties =
|
||||
GetLayoutObjectByElementId("filter")->FirstFragment().PaintProperties();
|
||||
- EXPECT_TRUE(DocEffect());
|
||||
+ EXPECT_TRUE(filter_properties->Filter()->Parent()->IsRoot());
|
||||
EXPECT_EQ(clip_properties->OverflowClip(),
|
||||
filter_properties->Filter()->OutputClip());
|
||||
EXPECT_EQ(DocScrollTranslation(),
|
||||
@@ -5089,7 +5079,7 @@ TEST_P(PaintPropertyTreeBuilderTest, MaskSimple) {
|
||||
|
||||
EXPECT_EQ(properties->Effect(),
|
||||
&target->FirstFragment().LocalBorderBoxProperties().Effect());
|
||||
- EXPECT_TRUE(DocEffect());
|
||||
+ EXPECT_TRUE(properties->Effect()->Parent()->IsRoot());
|
||||
EXPECT_EQ(SkBlendMode::kSrcOver, properties->Effect()->BlendMode());
|
||||
EXPECT_EQ(mask_clip->Parent(), properties->Effect()->OutputClip());
|
||||
|
||||
@@ -5118,7 +5108,7 @@ TEST_P(PaintPropertyTreeBuilderTest, MaskWithOutset) {
|
||||
|
||||
EXPECT_EQ(properties->Effect(),
|
||||
&target->FirstFragment().LocalBorderBoxProperties().Effect());
|
||||
- EXPECT_TRUE(DocEffect());
|
||||
+ EXPECT_TRUE(properties->Effect()->Parent()->IsRoot());
|
||||
EXPECT_EQ(SkBlendMode::kSrcOver, properties->Effect()->BlendMode());
|
||||
EXPECT_EQ(mask_clip->Parent(), properties->Effect()->OutputClip());
|
||||
|
||||
@@ -5172,7 +5162,7 @@ TEST_P(PaintPropertyTreeBuilderTest, MaskEscapeClip) {
|
||||
|
||||
EXPECT_EQ(target_properties->Effect(),
|
||||
&target->FirstFragment().LocalBorderBoxProperties().Effect());
|
||||
- EXPECT_TRUE(DocEffect());
|
||||
+ EXPECT_TRUE(target_properties->Effect()->Parent()->IsRoot());
|
||||
EXPECT_EQ(SkBlendMode::kSrcOver, target_properties->Effect()->BlendMode());
|
||||
EXPECT_EQ(nullptr, target_properties->Effect()->OutputClip());
|
||||
|
||||
@@ -5215,7 +5205,7 @@ TEST_P(PaintPropertyTreeBuilderTest, MaskInline) {
|
||||
|
||||
EXPECT_EQ(properties->Effect(),
|
||||
&target->FirstFragment().LocalBorderBoxProperties().Effect());
|
||||
- EXPECT_TRUE(DocEffect());
|
||||
+ EXPECT_TRUE(properties->Effect()->Parent()->IsRoot());
|
||||
EXPECT_EQ(SkBlendMode::kSrcOver, properties->Effect()->BlendMode());
|
||||
EXPECT_EQ(mask_clip->Parent(), properties->Effect()->OutputClip());
|
||||
|
||||
@@ -5316,7 +5306,8 @@ TEST_P(PaintPropertyTreeBuilderTest, SVGBlending) {
|
||||
ASSERT_TRUE(svg_root_properties->Effect());
|
||||
EXPECT_EQ(SkBlendMode::kSrcOver, svg_root_properties->Effect()->BlendMode());
|
||||
|
||||
- EXPECT_EQ(DocEffect(), svg_root_properties->Effect()->Parent());
|
||||
+ EXPECT_EQ(&EffectPaintPropertyNode::Root(),
|
||||
+ svg_root_properties->Effect()->Parent());
|
||||
EXPECT_EQ(svg_root_properties->Effect(), rect_properties->Effect()->Parent());
|
||||
}
|
||||
|
||||
@@ -5338,7 +5329,8 @@ TEST_P(PaintPropertyTreeBuilderTest, SVGRootBlending) {
|
||||
ASSERT_TRUE(svg_root_properties->Effect());
|
||||
EXPECT_EQ(SkBlendMode::kMultiply, svg_root_properties->Effect()->BlendMode());
|
||||
|
||||
- EXPECT_EQ(DocEffect(), html_properties->Effect()->Parent());
|
||||
+ EXPECT_EQ(&EffectPaintPropertyNode::Root(),
|
||||
+ html_properties->Effect()->Parent());
|
||||
EXPECT_EQ(html_properties->Effect(), svg_root_properties->Effect()->Parent());
|
||||
}
|
||||
|
||||
@@ -6454,7 +6446,7 @@ TEST_P(PaintPropertyTreeBuilderTest, SVGRootCompositedClipPathSimple) {
|
||||
|
||||
const auto* effect = properties->Effect();
|
||||
ASSERT_NE(nullptr, effect);
|
||||
- EXPECT_EQ(DocEffect(), effect->Parent());
|
||||
+ EXPECT_EQ(&EffectPaintPropertyNode::Root(), effect->Parent());
|
||||
EXPECT_EQ(transform, &effect->LocalTransformSpace());
|
||||
EXPECT_EQ(clip_path_clip, effect->OutputClip());
|
||||
EXPECT_EQ(SkBlendMode::kSrcOver, effect->BlendMode());
|
||||
@@ -6492,7 +6484,7 @@ TEST_P(PaintPropertyTreeBuilderTest, SVGRootCompositedClipPathComplex) {
|
||||
const auto* effect = properties->Effect();
|
||||
ASSERT_NE(nullptr, effect);
|
||||
EXPECT_TRUE(effect->HasDirectCompositingReasons());
|
||||
- EXPECT_EQ(DocEffect(), effect->Parent());
|
||||
+ EXPECT_EQ(&EffectPaintPropertyNode::Root(), effect->Parent());
|
||||
EXPECT_EQ(transform, &effect->LocalTransformSpace());
|
||||
EXPECT_EQ(clip_path_clip, effect->OutputClip());
|
||||
EXPECT_EQ(SkBlendMode::kSrcOver, effect->BlendMode());
|
||||
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.h b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.h
|
||||
index 7ab50dfc1dbfacba271f1a189f990e8dd78c4b21..252f6e568fbecb29c210e52bc8a43b34d002417d 100644
|
||||
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.h
|
||||
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.h
|
||||
@@ -34,7 +34,6 @@ class PaintPropertyTreeBuilderTest : public PaintControllerPaintTest {
|
||||
const Document* = nullptr);
|
||||
const ClipPaintPropertyNode* DocContentClip(const Document* = nullptr);
|
||||
const ScrollPaintPropertyNode* DocScroll(const Document* = nullptr);
|
||||
- const EffectPaintPropertyNode* DocEffect(const Document* = nullptr);
|
||||
|
||||
// Return the local border box's paint offset. For more details, see
|
||||
// ObjectPaintProperties::localBorderBoxProperties().
|
||||
diff --git a/third_party/blink/renderer/core/view_transition/view_transition_test.cc b/third_party/blink/renderer/core/view_transition/view_transition_test.cc
|
||||
index a6fa914af41568cde2fbbe59c7bbbb1de5f59d0f..bb0473719d38c049c0a92bd5f533a351e8cd8484 100644
|
||||
--- a/third_party/blink/renderer/core/view_transition/view_transition_test.cc
|
||||
+++ b/third_party/blink/renderer/core/view_transition/view_transition_test.cc
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "third_party/blink/renderer/core/dom/dom_token_list.h"
|
||||
#include "third_party/blink/renderer/core/dom/element.h"
|
||||
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
|
||||
+#include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h"
|
||||
#include "third_party/blink/renderer/core/dom/pseudo_element.h"
|
||||
#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
|
||||
#include "third_party/blink/renderer/core/html/html_element.h"
|
||||
@@ -32,7 +33,6 @@
|
||||
#include "third_party/blink/renderer/core/layout/physical_box_fragment.h"
|
||||
#include "third_party/blink/renderer/core/navigation_api/navigation_api.h"
|
||||
#include "third_party/blink/renderer/core/navigation_api/navigation_history_entry.h"
|
||||
-#include "third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.h"
|
||||
#include "third_party/blink/renderer/core/paint/paint_layer.h"
|
||||
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
|
||||
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
|
||||
@@ -706,100 +706,6 @@ TEST_P(ViewTransitionTest, ViewTransitionElementInvalidation) {
|
||||
UpdateAllLifecyclePhasesAndFinishDirectives();
|
||||
}
|
||||
|
||||
-namespace {
|
||||
-void AssertOnlyViewTransitionElementsInvalidated(
|
||||
- PaintArtifactCompositor* compositor) {
|
||||
- const char kViewTransition[] = "view-transition";
|
||||
- const char kLayoutViewTransition[] = "ViewTransition";
|
||||
- compositor->ForAllContentLayersForTesting(
|
||||
- [&](ContentLayerClientImpl* client) {
|
||||
- if (::testing::Matcher<std::string>(
|
||||
- ::testing::ContainsRegex(kViewTransition))
|
||||
- .Matches(client->Layer().DebugName())) {
|
||||
- return;
|
||||
- }
|
||||
- if (::testing::Matcher<std::string>(
|
||||
- ::testing::ContainsRegex(kLayoutViewTransition))
|
||||
- .Matches(client->Layer().DebugName())) {
|
||||
- return;
|
||||
- }
|
||||
- auto* tracking = client->GetRasterInvalidator().GetTracking();
|
||||
- EXPECT_FALSE(tracking->HasInvalidations())
|
||||
- << client->Layer().DebugName();
|
||||
- for (const auto& invalidation : tracking->Invalidations()) {
|
||||
- LOG(ERROR) << "Invalidation " << invalidation;
|
||||
- }
|
||||
- });
|
||||
-}
|
||||
-} // namespace
|
||||
-
|
||||
-TEST_P(ViewTransitionTest, NoInvalidationOnRoot) {
|
||||
- SetHtmlInnerHTML(R"HTML(
|
||||
- <style>
|
||||
- /* TODO(crbug.com/1336462): html.css is parsed before runtime flags are enabled */
|
||||
- html { view-transition-name: root; backgrond: grey; }
|
||||
- #element {
|
||||
- width: 100px;
|
||||
- height: 100px;
|
||||
- view-transition-name: shared;
|
||||
- will-change: transform;
|
||||
- }
|
||||
- </style>
|
||||
-
|
||||
- <div id=element></div>
|
||||
- <div>test</div>
|
||||
- )HTML");
|
||||
-
|
||||
- // Run all lifecycle phases to ensure paint is clean.
|
||||
- UpdateAllLifecyclePhasesForTest();
|
||||
-
|
||||
- GetDocument().View()->SetTracksRasterInvalidations(true);
|
||||
-
|
||||
- ScriptState* script_state = GetScriptState();
|
||||
- ScriptState::Scope scope(script_state);
|
||||
-
|
||||
- auto start_setup_lambda =
|
||||
- [](const v8::FunctionCallbackInfo<v8::Value>& info) {};
|
||||
-
|
||||
- // This callback sets the elements for the start phase of the transition.
|
||||
- auto start_setup_callback =
|
||||
- v8::Function::New(script_state->GetContext(), start_setup_lambda, {})
|
||||
- .ToLocalChecked();
|
||||
-
|
||||
- auto* compositor = GetLocalFrameView()->GetPaintArtifactCompositor();
|
||||
- auto* transition = ViewTransitionSupplement::startViewTransition(
|
||||
- script_state, GetDocument(),
|
||||
- V8ViewTransitionCallback::Create(start_setup_callback),
|
||||
- ASSERT_NO_EXCEPTION);
|
||||
-
|
||||
- UpdateAllLifecyclePhasesForTest();
|
||||
- {
|
||||
- SCOPED_TRACE("old dom capture");
|
||||
- AssertOnlyViewTransitionElementsInvalidated(compositor);
|
||||
- }
|
||||
-
|
||||
- // Finish the prepare phase, mutate the DOM and start the animation.
|
||||
- UpdateAllLifecyclePhasesAndFinishDirectives();
|
||||
- test::RunPendingTasks();
|
||||
- EXPECT_EQ(GetState(transition), State::kAnimating);
|
||||
-
|
||||
- // The start phase should generate pseudo elements for rendering new live
|
||||
- // content.
|
||||
- UpdateAllLifecyclePhasesAndFinishDirectives();
|
||||
- {
|
||||
- SCOPED_TRACE("animation started");
|
||||
- AssertOnlyViewTransitionElementsInvalidated(compositor);
|
||||
- }
|
||||
-
|
||||
- // Finish the animations which should remove the pseudo element tree.
|
||||
- FinishTransition();
|
||||
- UpdateAllLifecyclePhasesAndFinishDirectives();
|
||||
- {
|
||||
- SCOPED_TRACE("transition finished");
|
||||
- AssertOnlyViewTransitionElementsInvalidated(compositor);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
TEST_P(ViewTransitionTest, InspectorStyleResolver) {
|
||||
SetHtmlInnerHTML(R"HTML(
|
||||
<style>
|
||||
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
|
||||
index 4952082b87f80611b16a0730615bc0eaabe79791..d8568a1052ec82a8d56736aee7929ca9c4a4656c 100644
|
||||
--- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
|
||||
+++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
|
||||
@@ -1524,15 +1524,6 @@ void PaintArtifactCompositor::ShowDebugData() {
|
||||
}
|
||||
#endif
|
||||
|
||||
-void PaintArtifactCompositor::ForAllContentLayersForTesting(
|
||||
- base::FunctionRef<void(ContentLayerClientImpl*)> func) const {
|
||||
- for (auto& pending_layer : pending_layers_) {
|
||||
- if (auto* client = pending_layer.GetContentLayerClient()) {
|
||||
- func(client);
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
-
|
||||
ContentLayerClientImpl* PaintArtifactCompositor::ContentLayerClientForTesting(
|
||||
wtf_size_t i) const {
|
||||
for (auto& pending_layer : pending_layers_) {
|
||||
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h
|
||||
index fc4339bff1763d6dd6e99e3332e0e3bd1729e859..7d8a4526c9adcedf3ee0955aa2e7736a1d5e9e20 100644
|
||||
--- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h
|
||||
+++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h
|
||||
@@ -231,8 +231,6 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
|
||||
void ShowDebugData();
|
||||
#endif
|
||||
|
||||
- void ForAllContentLayersForTesting(
|
||||
- base::FunctionRef<void(ContentLayerClientImpl*)> func) const;
|
||||
// Returns the ith ContentLayerClientImpl for testing.
|
||||
ContentLayerClientImpl* ContentLayerClientForTesting(wtf_size_t i) const;
|
||||
|
||||
@@ -22,7 +22,7 @@ However, the patch would need to be reviewed by the security team, as it
|
||||
does touch a security-sensitive class.
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
|
||||
index 732978b9650cac5102007c27b9226ff053c92d4f..851eff886b5827e362b260f6a954a9081417b067 100644
|
||||
index eca2f5da88dd911ce64824479aac01320840cc22..12aa181c5dd8782c1901cc92b12039fd28e712b5 100644
|
||||
--- a/content/browser/renderer_host/render_process_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_process_host_impl.cc
|
||||
@@ -1754,6 +1754,10 @@ bool RenderProcessHostImpl::Init() {
|
||||
|
||||
@@ -9,10 +9,10 @@ is needed for OSR.
|
||||
Originally landed in https://github.com/electron/libchromiumcontent/pull/226.
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index 1d1d761f8c7ff09cbd2c6a567e070ac41d3a1759..50dd1fe97063a3d763461fe3ff7af340e7c4ad05 100644
|
||||
index 71835a747d6732b963c5cdc289539665aa988c47..e290f4fc3a85f55137d055958ca9bef4987fa3a7 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -3758,6 +3758,13 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params,
|
||||
@@ -3760,6 +3760,13 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params,
|
||||
params.main_frame_name, GetOpener(), primary_main_frame_policy,
|
||||
base::UnguessableToken::Create());
|
||||
|
||||
@@ -26,7 +26,7 @@ index 1d1d761f8c7ff09cbd2c6a567e070ac41d3a1759..50dd1fe97063a3d763461fe3ff7af340
|
||||
std::unique_ptr<WebContentsViewDelegate> delegate =
|
||||
GetContentClient()->browser()->GetWebContentsViewDelegate(this);
|
||||
|
||||
@@ -3768,6 +3775,7 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params,
|
||||
@@ -3770,6 +3777,7 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params,
|
||||
view_ = CreateWebContentsView(this, std::move(delegate),
|
||||
&render_view_host_delegate_view_);
|
||||
}
|
||||
|
||||
@@ -15,10 +15,10 @@ Note that we also need to manually update embedder's
|
||||
`api::WebContents::IsFullscreenForTabOrPending` value.
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
index 53f96ccd4954972bc78ebccf4bf479ac8564a8d3..7b7e21c5b4b2e6657965c4433c6f9bc064a4ef9f 100644
|
||||
index 01367204ab9d872077547c2b2c33c58d9a1653b9..2d82c283867cf78fc63275bffbd9eff4d8a606e9 100644
|
||||
--- a/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
@@ -8286,6 +8286,17 @@ void RenderFrameHostImpl::EnterFullscreen(
|
||||
@@ -8295,6 +8295,17 @@ void RenderFrameHostImpl::EnterFullscreen(
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,10 +37,10 @@ index 53f96ccd4954972bc78ebccf4bf479ac8564a8d3..7b7e21c5b4b2e6657965c4433c6f9bc0
|
||||
if (had_fullscreen_token && !GetView()->HasFocus())
|
||||
GetView()->Focus();
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index 50dd1fe97063a3d763461fe3ff7af340e7c4ad05..f8872945d67dacbdb9c3d610ff3719039eca7c94 100644
|
||||
index e290f4fc3a85f55137d055958ca9bef4987fa3a7..ec55a5a2807bb9fc328b33d18ee10444f4b98126 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -4015,21 +4015,25 @@ KeyboardEventProcessingResult WebContentsImpl::PreHandleKeyboardEvent(
|
||||
@@ -4017,21 +4017,25 @@ KeyboardEventProcessingResult WebContentsImpl::PreHandleKeyboardEvent(
|
||||
const input::NativeWebKeyboardEvent& event) {
|
||||
OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
|
||||
"WebContentsImpl::PreHandleKeyboardEvent");
|
||||
@@ -78,7 +78,7 @@ index 50dd1fe97063a3d763461fe3ff7af340e7c4ad05..f8872945d67dacbdb9c3d610ff371903
|
||||
}
|
||||
|
||||
bool WebContentsImpl::HandleMouseEvent(const blink::WebMouseEvent& event) {
|
||||
@@ -4188,7 +4192,7 @@ void WebContentsImpl::EnterFullscreenMode(
|
||||
@@ -4190,7 +4194,7 @@ void WebContentsImpl::EnterFullscreenMode(
|
||||
OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::EnterFullscreenMode");
|
||||
DCHECK(CanEnterFullscreenMode(requesting_frame));
|
||||
DCHECK(requesting_frame->IsActive());
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
expose_get_builtin_module_function.patch
|
||||
build_add_gn_build_files.patch
|
||||
fix_add_default_values_for_variables_in_common_gypi.patch
|
||||
fix_expose_tracing_agent_and_use_tracing_tracingcontroller_instead.patch
|
||||
pass_all_globals_through_require.patch
|
||||
build_modify_js2c_py_to_allow_injection_of_original-fs_and_custom_embedder_js.patch
|
||||
refactor_allow_embedder_overriding_of_internal_fs_calls.patch
|
||||
@@ -12,7 +11,6 @@ fix_crypto_tests_to_run_with_bssl.patch
|
||||
fix_account_for_debugger_agent_race_condition.patch
|
||||
fix_readbarrier_undefined_symbol_error_on_woa_arm64.patch
|
||||
fix_suppress_clang_-wdeprecated-declarations_in_libuv.patch
|
||||
fix_serdes_test.patch
|
||||
feat_add_uv_loop_interrupt_on_io_change_option_to_uv_loop_configure.patch
|
||||
support_v8_sandboxed_pointers.patch
|
||||
build_ensure_native_module_compilation_fails_if_not_using_a_new.patch
|
||||
@@ -49,9 +47,10 @@ src_do_not_use_soon-to-be-deprecated_v8_api.patch
|
||||
fix_add_property_query_interceptors.patch
|
||||
src_stop_using_deprecated_fields_of_fastapicallbackoptions.patch
|
||||
src_use_supported_api_to_get_stalled_tla_messages.patch
|
||||
build_don_t_redefine_win32_lean_and_mean.patch
|
||||
build_compile_with_c_20_support.patch
|
||||
add_v8_taskpirority_to_foreground_task_runner_signature.patch
|
||||
cli_remove_deprecated_v8_flag.patch
|
||||
build_restore_clang_as_default_compiler_on_macos.patch
|
||||
esm_drop_support_for_import_assertions.patch
|
||||
build_remove_explicit_linker_call_to_libm_on_macos.patch
|
||||
build_define_nominmax_in_common_gypi.patch
|
||||
|
||||
@@ -537,17 +537,21 @@ index 0e69d7383762f6b81c5b57698aa9d121d5a9c401..35bbeb37acc7ccb14b4b8a644ec3d4c7
|
||||
cflags_c = [
|
||||
"-mavx512vl",
|
||||
diff --git a/deps/cares/BUILD.gn b/deps/cares/BUILD.gn
|
||||
index ac19ac73ed1e24c61cb679f3851685b79cfc8b39..7f4885631a85a25692e8969991951be02e5d73f1 100644
|
||||
index ac19ac73ed1e24c61cb679f3851685b79cfc8b39..ef745c19f2b1cd433cc43c834a18db7eaa8e5162 100644
|
||||
--- a/deps/cares/BUILD.gn
|
||||
+++ b/deps/cares/BUILD.gn
|
||||
@@ -1,14 +1,175 @@
|
||||
@@ -1,14 +1,188 @@
|
||||
-##############################################################################
|
||||
-# #
|
||||
-# DO NOT EDIT THIS FILE! #
|
||||
-# #
|
||||
-##############################################################################
|
||||
+config("cares_config") {
|
||||
+ include_dirs = [ "include", "src/lib" ]
|
||||
+ include_dirs = [
|
||||
+ "include",
|
||||
+ "src/lib",
|
||||
+ "src/lib/include",
|
||||
+ ]
|
||||
+}
|
||||
+static_library("cares") {
|
||||
+ defines = [ "CARES_STATICLIB" ]
|
||||
@@ -563,20 +567,19 @@ index ac19ac73ed1e24c61cb679f3851685b79cfc8b39..7f4885631a85a25692e8969991951be0
|
||||
+
|
||||
+ sources = [
|
||||
+ "include/ares.h",
|
||||
+ "include/ares_build.h",
|
||||
+ "include/ares_dns.h",
|
||||
+ "include/ares_dns_record.h",
|
||||
+ "include/ares_nameser.h",
|
||||
+ "include/ares_version.h",
|
||||
+ "src/lib/ares__addrinfo2hostent.c",
|
||||
+ "src/lib/ares__addrinfo_localhost.c",
|
||||
+ "src/lib/ares__close_sockets.c",
|
||||
+ "src/lib/ares__hosts_file.c",
|
||||
+ "src/lib/ares__parse_into_addrinfo.c",
|
||||
+ "src/lib/ares__socket.c",
|
||||
+ "src/lib/ares__sortaddrinfo.c",
|
||||
+ "src/lib/ares_addrinfo2hostent.c",
|
||||
+ "src/lib/ares_addrinfo_localhost.c",
|
||||
+ "src/lib/ares_android.c",
|
||||
+ "src/lib/ares_android.h",
|
||||
+ "src/lib/ares_cancel.c",
|
||||
+ "src/lib/ares_close_sockets.c",
|
||||
+ "src/lib/ares_conn.c",
|
||||
+ "src/lib/ares_conn.h",
|
||||
+ "src/lib/ares_cookie.c",
|
||||
+ "src/lib/ares_data.c",
|
||||
+ "src/lib/ares_data.h",
|
||||
@@ -590,43 +593,43 @@ index ac19ac73ed1e24c61cb679f3851685b79cfc8b39..7f4885631a85a25692e8969991951be0
|
||||
+ "src/lib/ares_gethostbyaddr.c",
|
||||
+ "src/lib/ares_gethostbyname.c",
|
||||
+ "src/lib/ares_getnameinfo.c",
|
||||
+ "src/lib/ares_hosts_file.c",
|
||||
+ "src/lib/ares_inet_net_pton.h",
|
||||
+ "src/lib/ares_init.c",
|
||||
+ "src/lib/ares_ipv6.h",
|
||||
+ "src/lib/ares_library_init.c",
|
||||
+ "src/lib/ares_metrics.c",
|
||||
+ "src/lib/ares_options.c",
|
||||
+ "src/lib/ares_platform.c",
|
||||
+ "src/lib/ares_platform.h",
|
||||
+ "src/lib/ares_parse_into_addrinfo.c",
|
||||
+ "src/lib/ares_private.h",
|
||||
+ "src/lib/ares_process.c",
|
||||
+ "src/lib/ares_qcache.c",
|
||||
+ "src/lib/ares_query.c",
|
||||
+ "src/lib/ares_search.c",
|
||||
+ "src/lib/ares_send.c",
|
||||
+ "src/lib/ares_set_socket_functions.c",
|
||||
+ "src/lib/ares_setup.h",
|
||||
+ "src/lib/ares_socket.c",
|
||||
+ "src/lib/ares_socket.h",
|
||||
+ "src/lib/ares_sortaddrinfo.c",
|
||||
+ "src/lib/ares_strerror.c",
|
||||
+ "src/lib/ares_sysconfig.c",
|
||||
+ "src/lib/ares_sysconfig_files.c",
|
||||
+ "src/lib/ares_timeout.c",
|
||||
+ "src/lib/ares_update_servers.c",
|
||||
+ "src/lib/ares_version.c",
|
||||
+ "src/lib/dsa/ares__array.c",
|
||||
+ "src/lib/dsa/ares__array.h",
|
||||
+ "src/lib/dsa/ares__htable.c",
|
||||
+ "src/lib/dsa/ares__htable.h",
|
||||
+ "src/lib/dsa/ares__htable_asvp.c",
|
||||
+ "src/lib/dsa/ares__htable_asvp.h",
|
||||
+ "src/lib/dsa/ares__htable_strvp.c",
|
||||
+ "src/lib/dsa/ares__htable_strvp.h",
|
||||
+ "src/lib/dsa/ares__htable_szvp.c",
|
||||
+ "src/lib/dsa/ares__htable_szvp.h",
|
||||
+ "src/lib/dsa/ares__htable_vpvp.c",
|
||||
+ "src/lib/dsa/ares__htable_vpvp.h",
|
||||
+ "src/lib/dsa/ares__llist.c",
|
||||
+ "src/lib/dsa/ares__llist.h",
|
||||
+ "src/lib/dsa/ares__slist.c",
|
||||
+ "src/lib/dsa/ares__slist.h",
|
||||
+ "src/lib/dsa/ares_array.c",
|
||||
+ "src/lib/dsa/ares_htable.c",
|
||||
+ "src/lib/dsa/ares_htable.h",
|
||||
+ "src/lib/dsa/ares_htable_asvp.c",
|
||||
+ "src/lib/dsa/ares_htable_dict.c",
|
||||
+ "src/lib/dsa/ares_htable_strvp.c",
|
||||
+ "src/lib/dsa/ares_htable_szvp.c",
|
||||
+ "src/lib/dsa/ares_htable_vpstr.c",
|
||||
+ "src/lib/dsa/ares_htable_vpvp.c",
|
||||
+ "src/lib/dsa/ares_llist.c",
|
||||
+ "src/lib/dsa/ares_slist.c",
|
||||
+ "src/lib/dsa/ares_slist.h",
|
||||
+ "src/lib/event/ares_event.h",
|
||||
+ "src/lib/event/ares_event_configchg.c",
|
||||
+ "src/lib/event/ares_event_epoll.c",
|
||||
@@ -637,6 +640,17 @@ index ac19ac73ed1e24c61cb679f3851685b79cfc8b39..7f4885631a85a25692e8969991951be0
|
||||
+ "src/lib/event/ares_event_wake_pipe.c",
|
||||
+ "src/lib/event/ares_event_win32.c",
|
||||
+ "src/lib/event/ares_event_win32.h",
|
||||
+ "src/lib/include/ares_array.h",
|
||||
+ "src/lib/include/ares_buf.h",
|
||||
+ "src/lib/include/ares_htable_asvp.h",
|
||||
+ "src/lib/include/ares_htable_dict.h",
|
||||
+ "src/lib/include/ares_htable_strvp.h",
|
||||
+ "src/lib/include/ares_htable_szvp.h",
|
||||
+ "src/lib/include/ares_htable_vpstr.h",
|
||||
+ "src/lib/include/ares_htable_vpvp.h",
|
||||
+ "src/lib/include/ares_llist.h",
|
||||
+ "src/lib/include/ares_mem.h",
|
||||
+ "src/lib/include/ares_str.h",
|
||||
+ "src/lib/inet_net_pton.c",
|
||||
+ "src/lib/inet_ntop.c",
|
||||
+ "src/lib/legacy/ares_create_query.c",
|
||||
@@ -663,23 +677,22 @@ index ac19ac73ed1e24c61cb679f3851685b79cfc8b39..7f4885631a85a25692e8969991951be0
|
||||
+ "src/lib/record/ares_dns_private.h",
|
||||
+ "src/lib/record/ares_dns_record.c",
|
||||
+ "src/lib/record/ares_dns_write.c",
|
||||
+ "src/lib/str/ares__buf.c",
|
||||
+ "src/lib/str/ares__buf.h",
|
||||
+ "src/lib/str/ares_buf.c",
|
||||
+ "src/lib/str/ares_str.c",
|
||||
+ "src/lib/str/ares_str.h",
|
||||
+ "src/lib/str/ares_strcasecmp.c",
|
||||
+ "src/lib/str/ares_strcasecmp.h",
|
||||
+ "src/lib/str/ares_strsplit.c",
|
||||
+ "src/lib/str/ares_strsplit.h",
|
||||
+ "src/lib/util/ares__iface_ips.c",
|
||||
+ "src/lib/util/ares__iface_ips.h",
|
||||
+ "src/lib/util/ares__threads.c",
|
||||
+ "src/lib/util/ares__threads.h",
|
||||
+ "src/lib/util/ares__timeval.c",
|
||||
+ "src/lib/util/ares_iface_ips.c",
|
||||
+ "src/lib/util/ares_iface_ips.h",
|
||||
+ "src/lib/util/ares_math.c",
|
||||
+ "src/lib/util/ares_math.h",
|
||||
+ "src/lib/util/ares_rand.c",
|
||||
+ "src/tools/ares_getopt.c",
|
||||
+ "src/tools/ares_getopt.h",
|
||||
+ "src/lib/util/ares_rand.h",
|
||||
+ "src/lib/util/ares_threads.c",
|
||||
+ "src/lib/util/ares_threads.h",
|
||||
+ "src/lib/util/ares_time.h",
|
||||
+ "src/lib/util/ares_timeval.c",
|
||||
+ "src/lib/util/ares_uri.c",
|
||||
+ "src/lib/util/ares_uri.h",
|
||||
+ ]
|
||||
+
|
||||
+ if (!is_win) {
|
||||
@@ -2247,19 +2260,6 @@ index 706ea4f5cb90525c8ea56f794320a733c45a193f..c7ae7759595bfc7fdc31dab174a7514d
|
||||
}
|
||||
|
||||
} // namespace builtins
|
||||
diff --git a/src/node_builtins.h b/src/node_builtins.h
|
||||
index 1cb85b9058d06555382e565dc32192a9fa48ed9f..cec9be01abd107e8612f70daf19b4834e118ffcf 100644
|
||||
--- a/src/node_builtins.h
|
||||
+++ b/src/node_builtins.h
|
||||
@@ -74,6 +74,8 @@ using BuiltinCodeCacheMap =
|
||||
// Generated by tools/js2c.py as node_javascript.cc
|
||||
void RegisterExternalReferencesForInternalizedBuiltinCode(
|
||||
ExternalReferenceRegistry* registry);
|
||||
+void EmbedderRegisterExternalReferencesForInternalizedBuiltinCode(
|
||||
+ ExternalReferenceRegistry* registry);
|
||||
|
||||
// Handles compilation and caching of built-in JavaScript modules and
|
||||
// bootstrap scripts, whose source are bundled into the binary as static data.
|
||||
diff --git a/tools/generate_gn_filenames_json.py b/tools/generate_gn_filenames_json.py
|
||||
new file mode 100755
|
||||
index 0000000000000000000000000000000000000000..37c16859003e61636fe2f1a4040b1e904c472d0b
|
||||
@@ -2408,10 +2408,10 @@ index 0000000000000000000000000000000000000000..5259e6a7a1fd6b21df69dc461dee67d9
|
||||
+ transformed_contents = contents.replace('internal/fs/', 'internal/original-fs/').replace('require(\'fs', 'require(\'original-fs')
|
||||
+ transformed_f.write(transformed_contents)
|
||||
diff --git a/tools/install.py b/tools/install.py
|
||||
index b132c7bf26c02886a7ab341a1973bf449744ba0f..757e3e60a7be01fac55c5fbb010dbbae00b1bfca 100755
|
||||
index 2dceb5c39ea4a11034ce93899fa26dc406e0b5d0..a425de8ad7833f4d39c842fd896539c1f77468bc 100755
|
||||
--- a/tools/install.py
|
||||
+++ b/tools/install.py
|
||||
@@ -264,6 +264,7 @@ def headers(options, action):
|
||||
@@ -270,6 +270,7 @@ def headers(options, action):
|
||||
'include/v8-forward.h',
|
||||
'include/v8-function-callback.h',
|
||||
'include/v8-function.h',
|
||||
@@ -2419,7 +2419,7 @@ index b132c7bf26c02886a7ab341a1973bf449744ba0f..757e3e60a7be01fac55c5fbb010dbbae
|
||||
'include/v8-initialization.h',
|
||||
'include/v8-internal.h',
|
||||
'include/v8-isolate.h',
|
||||
@@ -284,6 +285,8 @@ def headers(options, action):
|
||||
@@ -290,6 +291,8 @@ def headers(options, action):
|
||||
'include/v8-promise.h',
|
||||
'include/v8-proxy.h',
|
||||
'include/v8-regexp.h',
|
||||
@@ -2428,7 +2428,7 @@ index b132c7bf26c02886a7ab341a1973bf449744ba0f..757e3e60a7be01fac55c5fbb010dbbae
|
||||
'include/v8-script.h',
|
||||
'include/v8-snapshot.h',
|
||||
'include/v8-statistics.h',
|
||||
@@ -390,7 +393,7 @@ def parse_options(args):
|
||||
@@ -396,7 +399,7 @@ def parse_options(args):
|
||||
parser.add_argument('--build-dir', help='the location of built binaries',
|
||||
default='out/Release')
|
||||
parser.add_argument('--v8-dir', help='the location of V8',
|
||||
|
||||
@@ -10,7 +10,7 @@ V8 requires C++20 support as of https://chromium-review.googlesource.com/c/v8/v8
|
||||
This can be removed when Electron upgrades to a version of Node.js containing the required V8 version.
|
||||
|
||||
diff --git a/common.gypi b/common.gypi
|
||||
index bdf1a1f33f3ea09d933757c7fee87c563cc833ab..2eb62610db2f0ebf68fa9a55ffba98291ecfe451 100644
|
||||
index 690068f093f12b6831f8ccce41289d02d7047a7a..5a3df388773ad288553bf036be42dc1a0ba75c09 100644
|
||||
--- a/common.gypi
|
||||
+++ b/common.gypi
|
||||
@@ -305,7 +305,7 @@
|
||||
|
||||
49
patches/node/build_define_nominmax_in_common_gypi.patch
Normal file
49
patches/node/build_define_nominmax_in_common_gypi.patch
Normal file
@@ -0,0 +1,49 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Mon, 3 Mar 2025 12:05:55 +0100
|
||||
Subject: build: define NOMINMAX in common.gypi
|
||||
|
||||
V8 and Node.js had defined NOMINMAX on Windows for a long time. In
|
||||
recent changes, V8 added std::numeric_limits::min usages in its
|
||||
header files which caused addons without NOMINMAX defines failed
|
||||
to compile.
|
||||
|
||||
Define NOMINMAX in common.gypi so that addons can be compiled with
|
||||
the latest V8 header files.
|
||||
|
||||
NAN includes uv.h before node.h, which makes
|
||||
these defines effectiveless. Nevertheless, the include order should not be
|
||||
significant.
|
||||
|
||||
PR-URL: https://github.com/nodejs/node/pull/52794
|
||||
|
||||
diff --git a/common.gypi b/common.gypi
|
||||
index 9bbf1b277eb17d78ca385643c3177638fd75866a..959ee74af88b44d31f2e6fa65c6f260820bd8c46 100644
|
||||
--- a/common.gypi
|
||||
+++ b/common.gypi
|
||||
@@ -480,6 +480,10 @@
|
||||
'_HAS_EXCEPTIONS=0',
|
||||
'BUILDING_V8_SHARED=1',
|
||||
'BUILDING_UV_SHARED=1',
|
||||
+ # Stop <windows.h> from defining macros that conflict with
|
||||
+ # std::min() and std::max(). We don't use <windows.h> (much)
|
||||
+ # but we still inherit it from uv.h.
|
||||
+ 'NOMINMAX',
|
||||
],
|
||||
}],
|
||||
[ 'OS in "linux freebsd openbsd solaris aix os400"', {
|
||||
diff --git a/node.gypi b/node.gypi
|
||||
index 46c7c7e353f29b8b3e5937ec80a5924020548980..212750978fb5c24fffe410cbdfe8dbdfe2ea8b42 100644
|
||||
--- a/node.gypi
|
||||
+++ b/node.gypi
|
||||
@@ -63,10 +63,6 @@
|
||||
'FD_SETSIZE=1024',
|
||||
# we need to use node's preferred "win32" rather than gyp's preferred "win"
|
||||
'NODE_PLATFORM="win32"',
|
||||
- # Stop <windows.h> from defining macros that conflict with
|
||||
- # std::min() and std::max(). We don't use <windows.h> (much)
|
||||
- # but we still inherit it from uv.h.
|
||||
- 'NOMINMAX',
|
||||
'_UNICODE=1',
|
||||
],
|
||||
'msvs_precompiled_header': 'tools/msvs/pch/node_pch.h',
|
||||
@@ -1,36 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Fri, 23 Aug 2024 16:50:19 +0200
|
||||
Subject: build: don't redefine WIN32_LEAN_AND_MEAN
|
||||
|
||||
https://github.com/nodejs/node/pull/53722 added a new define for WIN32_LEAN_AND_MEAN
|
||||
without first checking to see if it was defined - other areas in c-ares do this so
|
||||
we should here as well. Compilation errors occur otherwise:
|
||||
|
||||
../../third_party/electron_node/deps/cares/include\ares_build.h(168,11): error: 'WIN32_LEAN_AND_MEAN' macro redefined [-Werror,-Wmacro-redefined]
|
||||
168 | # define WIN32_LEAN_AND_MEAN
|
||||
| ^
|
||||
<command line>(25,9): note: previous definition is here
|
||||
25 | #define WIN32_LEAN_AND_MEAN 1
|
||||
| ^
|
||||
1 error generated.
|
||||
[287 processes, 49437/51449 @ 48.5/s : 1018.562s] CC obj/third_party/electron_node/deps/cares/cares/ares__socket.obj
|
||||
FAILED: obj/third_party/electron_node/deps/cares/cares/ares__socket.obj
|
||||
|
||||
This should be upstreamed.
|
||||
|
||||
diff --git a/deps/cares/include/ares_build.h b/deps/cares/include/ares_build.h
|
||||
index 18a92606a817145302c73b5081b4c989799bc620..bafd26d9210d2347fec41f028e9e65088b83c48c 100644
|
||||
--- a/deps/cares/include/ares_build.h
|
||||
+++ b/deps/cares/include/ares_build.h
|
||||
@@ -165,7 +165,9 @@
|
||||
# define CARES_TYPEOF_ARES_SOCKLEN_T int
|
||||
|
||||
#elif defined(_WIN32)
|
||||
-# define WIN32_LEAN_AND_MEAN
|
||||
+# ifndef WIN32_LEAN_AND_MEAN
|
||||
+# define WIN32_LEAN_AND_MEAN
|
||||
+# endif
|
||||
# define CARES_TYPEOF_ARES_SOCKLEN_T int
|
||||
# define CARES_HAVE_WINDOWS_H 1
|
||||
# define CARES_HAVE_SYS_TYPES_H 1
|
||||
@@ -7,7 +7,7 @@ Subject: build: ensure native module compilation fails if not using a new
|
||||
This should not be upstreamed, it is a quality-of-life patch for downstream module builders.
|
||||
|
||||
diff --git a/common.gypi b/common.gypi
|
||||
index 697b8bba6a55358924d6986f2eb347a99ff73889..bdf1a1f33f3ea09d933757c7fee87c563cc833ab 100644
|
||||
index 776a6dcf3a729a65b367fb5b4c5685f841089eea..690068f093f12b6831f8ccce41289d02d7047a7a 100644
|
||||
--- a/common.gypi
|
||||
+++ b/common.gypi
|
||||
@@ -86,6 +86,8 @@
|
||||
@@ -40,10 +40,10 @@ index 697b8bba6a55358924d6986f2eb347a99ff73889..bdf1a1f33f3ea09d933757c7fee87c56
|
||||
# list in v8/BUILD.gn.
|
||||
['v8_enable_v8_checks == 1', {
|
||||
diff --git a/configure.py b/configure.py
|
||||
index 0d089c35d1720e05c4c61d0226a2ebc276b65d6e..cf19b9d092698e1697508e8891926947bc2f7b12 100755
|
||||
index 0df90b176e9b5403efdb1393c0f2f37bb53dc6b2..ece665915ad4d6e02762ec3165cf7b987a87949d 100755
|
||||
--- a/configure.py
|
||||
+++ b/configure.py
|
||||
@@ -1585,6 +1585,7 @@ def configure_library(lib, output, pkgname=None):
|
||||
@@ -1595,6 +1595,7 @@ def configure_library(lib, output, pkgname=None):
|
||||
|
||||
|
||||
def configure_v8(o):
|
||||
@@ -52,7 +52,7 @@ index 0d089c35d1720e05c4c61d0226a2ebc276b65d6e..cf19b9d092698e1697508e8891926947
|
||||
o['variables']['v8_enable_javascript_promise_hooks'] = 1
|
||||
o['variables']['v8_enable_lite_mode'] = 1 if options.v8_lite_mode else 0
|
||||
diff --git a/src/node.h b/src/node.h
|
||||
index 4f2eb9d0aab88b70c86339e750799080e980d7da..df3fb3372d6357b5d77b4f683e309b8483998128 100644
|
||||
index ec5f6d0d25731dfb5ceeae3cd8749630298a8ba0..30accf975d00bfda5ef0afb8d15041c7e1ba8719 100644
|
||||
--- a/src/node.h
|
||||
+++ b/src/node.h
|
||||
@@ -22,6 +22,12 @@
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user