mirror of
https://github.com/electron/electron.git
synced 2026-02-26 03:01:17 -05:00
Compare commits
208 Commits
v26.0.0-al
...
v26.4.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4be7b10550 | ||
|
|
2270fc8d4d | ||
|
|
e861af712d | ||
|
|
ad34b4b793 | ||
|
|
2793539c9c | ||
|
|
677d05a3d6 | ||
|
|
b8f522b5f2 | ||
|
|
a4f9db0a56 | ||
|
|
0da1d6d4cc | ||
|
|
7985f82f87 | ||
|
|
1d845761f8 | ||
|
|
33c963dac3 | ||
|
|
6228c075f7 | ||
|
|
2ac8897896 | ||
|
|
589a6e427a | ||
|
|
040f3be041 | ||
|
|
d5020a4fff | ||
|
|
a55c4c65c0 | ||
|
|
7f53717e48 | ||
|
|
1091ba2bd2 | ||
|
|
59271e6182 | ||
|
|
d7da2b9561 | ||
|
|
f24346a979 | ||
|
|
13bdefa549 | ||
|
|
74f50e83a5 | ||
|
|
9c2984f7b5 | ||
|
|
0f8e9dec59 | ||
|
|
70231825c7 | ||
|
|
fbc2786c18 | ||
|
|
985f0a441d | ||
|
|
ee1f6c30e7 | ||
|
|
89bf5a2cdc | ||
|
|
1c3d6181a8 | ||
|
|
b9095f5ccf | ||
|
|
46b512407b | ||
|
|
53bf1f3f13 | ||
|
|
8e3189a8ba | ||
|
|
496577d9cd | ||
|
|
90a311dba2 | ||
|
|
77da40381c | ||
|
|
7aa860e938 | ||
|
|
10409ff7a1 | ||
|
|
4e9c583230 | ||
|
|
cbc345892c | ||
|
|
6ecae84da3 | ||
|
|
8d8751106b | ||
|
|
eda2ceda1e | ||
|
|
01aafab563 | ||
|
|
325549ffce | ||
|
|
ab272cb767 | ||
|
|
a3acea9fd6 | ||
|
|
c9d2d69397 | ||
|
|
65f2726851 | ||
|
|
937adf72e5 | ||
|
|
03dd4ae6bb | ||
|
|
b9aee8152c | ||
|
|
5fce729a14 | ||
|
|
3f1fee72b4 | ||
|
|
81bd81667c | ||
|
|
1ddffe909e | ||
|
|
ed6e4e3add | ||
|
|
a89482093f | ||
|
|
1b9842b9b5 | ||
|
|
deb02b9ec6 | ||
|
|
c14487ea98 | ||
|
|
bf1dbaffcc | ||
|
|
1e70e543ce | ||
|
|
a6649ffb61 | ||
|
|
5da1b91546 | ||
|
|
1047532f1d | ||
|
|
054b99634c | ||
|
|
6838404ecb | ||
|
|
ee01054bb5 | ||
|
|
51b074eb5e | ||
|
|
2e27e273ed | ||
|
|
86fc724d97 | ||
|
|
c676293bf4 | ||
|
|
1afcffef53 | ||
|
|
04994de9e6 | ||
|
|
9dea18c1db | ||
|
|
ad76ef17f0 | ||
|
|
3d760afa36 | ||
|
|
0f2df2bf9b | ||
|
|
64c5505b36 | ||
|
|
ad385bf1ce | ||
|
|
0a478f9ef0 | ||
|
|
92c4697662 | ||
|
|
ceb5230395 | ||
|
|
c09ebeac14 | ||
|
|
5f1ada46f5 | ||
|
|
ca899eb3cb | ||
|
|
c709e04bed | ||
|
|
f9e35e4aaa | ||
|
|
d2ca670f3f | ||
|
|
4930f71a76 | ||
|
|
1c458c5eaf | ||
|
|
9c028cd279 | ||
|
|
fd8d4a8b94 | ||
|
|
35126e06b6 | ||
|
|
3e239efd99 | ||
|
|
66f42b3256 | ||
|
|
4586a40bfd | ||
|
|
3c467224d5 | ||
|
|
759329dc62 | ||
|
|
ac867a1b95 | ||
|
|
75b1fd5b4c | ||
|
|
a800965ef6 | ||
|
|
53cb8f5e01 | ||
|
|
7c434a11e4 | ||
|
|
c5faab7a0d | ||
|
|
abd3acd380 | ||
|
|
76a9aab8b5 | ||
|
|
63a60b8eaa | ||
|
|
9a49ac1454 | ||
|
|
102eb176d9 | ||
|
|
87dfd83bf8 | ||
|
|
784b288de0 | ||
|
|
ef8c90a50a | ||
|
|
6771299fc2 | ||
|
|
b656337b43 | ||
|
|
fbfef19768 | ||
|
|
6b61917d4b | ||
|
|
d47fa5f787 | ||
|
|
9ee4cb49bc | ||
|
|
6a4bb4f6fd | ||
|
|
95855906d0 | ||
|
|
f184603992 | ||
|
|
26aa910d43 | ||
|
|
8655990d83 | ||
|
|
a175e1f69a | ||
|
|
038147b6bc | ||
|
|
03ed9531d4 | ||
|
|
24f2379892 | ||
|
|
9d5a25bf37 | ||
|
|
35a9d76531 | ||
|
|
54cd8e4827 | ||
|
|
a374f41528 | ||
|
|
a99fc5e40f | ||
|
|
77bfa2ad65 | ||
|
|
b7eb26c4df | ||
|
|
25c18637ed | ||
|
|
534cdbd538 | ||
|
|
689e3868cc | ||
|
|
6656001a62 | ||
|
|
6930ecea68 | ||
|
|
97825a3f09 | ||
|
|
459fe0e68d | ||
|
|
bd66a58fa7 | ||
|
|
db581a204d | ||
|
|
e7928ce519 | ||
|
|
5ab5427b6e | ||
|
|
d463bf9c16 | ||
|
|
4ba0fc8630 | ||
|
|
33376fba39 | ||
|
|
b0b87b098e | ||
|
|
13d224e816 | ||
|
|
96b2422f95 | ||
|
|
3cdd3d6518 | ||
|
|
2bab77a4e1 | ||
|
|
7ce73b5989 | ||
|
|
2b254b1d6d | ||
|
|
6452e5c992 | ||
|
|
28604db7a0 | ||
|
|
236272bf9f | ||
|
|
26e6252ac8 | ||
|
|
548f84df40 | ||
|
|
779a4e700d | ||
|
|
76f4291130 | ||
|
|
16aac6da13 | ||
|
|
479c2d8d4a | ||
|
|
6c05422a61 | ||
|
|
a6d76efc9e | ||
|
|
88408358ed | ||
|
|
1e3837f4c3 | ||
|
|
f8ed70b613 | ||
|
|
c2e362d2d3 | ||
|
|
b3a5ef767b | ||
|
|
94dba56d2c | ||
|
|
7ad80e414a | ||
|
|
e5419bcf5a | ||
|
|
8eeaacfafe | ||
|
|
582844c537 | ||
|
|
77d4ab0701 | ||
|
|
923ae840e1 | ||
|
|
50014e593f | ||
|
|
3a7e8d6a24 | ||
|
|
a55410576a | ||
|
|
cddfdf3ba2 | ||
|
|
e6a631f078 | ||
|
|
9d4debb791 | ||
|
|
0b181e7977 | ||
|
|
29d776400a | ||
|
|
0b7e2b6d91 | ||
|
|
744b8dfc31 | ||
|
|
9a64d47132 | ||
|
|
7acdcae772 | ||
|
|
b8d9a80dbb | ||
|
|
67f9b1f88d | ||
|
|
fc241977fe | ||
|
|
01faeef36a | ||
|
|
9d3c1d993a | ||
|
|
95f8fa8732 | ||
|
|
53b398d7c3 | ||
|
|
4d4191ed1a | ||
|
|
1facc6d304 | ||
|
|
455458ace8 | ||
|
|
0e2fd41733 | ||
|
|
dbc4e2d8d7 |
@@ -65,6 +65,9 @@ jobs:
|
||||
curl -fLSs https://raw.githubusercontent.com/CircleCI-Public/circleci-cli/main/install.sh | DESTDIR=$CIRCLECI_BINARY bash
|
||||
node build.js
|
||||
name: Pack config.yml
|
||||
- run:
|
||||
name: Set params
|
||||
command: node .circleci/config/params.js
|
||||
- continuation/continue:
|
||||
configuration_path: .circleci/config-staging/built.yml
|
||||
parameters: /tmp/pipeline-parameters.json
|
||||
|
||||
@@ -35,6 +35,16 @@ parameters:
|
||||
default: all
|
||||
enum: ["all", "osx-x64", "osx-arm64", "mas-x64", "mas-arm64"]
|
||||
|
||||
medium-linux-executor:
|
||||
type: enum
|
||||
default: electronjs/aks-linux-medium
|
||||
enum: ["electronjs/aks-linux-medium", "medium"]
|
||||
|
||||
large-linux-executor:
|
||||
type: enum
|
||||
default: electronjs/aks-linux-large
|
||||
enum: ["electronjs/aks-linux-large", "2xlarge"]
|
||||
|
||||
# Executors
|
||||
executors:
|
||||
linux-docker:
|
||||
@@ -42,7 +52,9 @@ executors:
|
||||
size:
|
||||
description: "Docker executor size"
|
||||
type: enum
|
||||
enum: ["medium", "xlarge", "2xlarge"]
|
||||
# aks-linux-large === 32 core
|
||||
# 2xlarge should not be used directly, use the pipeline param instead
|
||||
enum: ["medium", "electronjs/aks-linux-medium", "xlarge", "electronjs/aks-linux-large", "2xlarge"]
|
||||
docker:
|
||||
- image: ghcr.io/electron/build:e6bebd08a51a0d78ec23e5b3fd7e7c0846412328
|
||||
resource_class: << parameters.size >>
|
||||
@@ -252,19 +264,19 @@ step-depot-tools-get: &step-depot-tools-get
|
||||
cd depot_tools
|
||||
cat > gclient.diff \<< 'EOF'
|
||||
diff --git a/gclient.py b/gclient.py
|
||||
index 3a9c5c6..f222043 100755
|
||||
index c305c248..e6e0fbdc 100755
|
||||
--- a/gclient.py
|
||||
+++ b/gclient.py
|
||||
@@ -712,7 +712,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
|
||||
|
||||
if dep_type == 'cipd':
|
||||
cipd_root = self.GetCipdRoot()
|
||||
- for package in dep_value.get('packages', []):
|
||||
+ packages = dep_value.get('packages', [])
|
||||
+ for package in (x for x in packages if "infra/3pp/tools/swift-format" not in x.get('package')):
|
||||
deps_to_add.append(
|
||||
CipdDependency(
|
||||
parent=self,
|
||||
@@ -735,7 +735,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
|
||||
|
||||
if dep_type == 'cipd':
|
||||
cipd_root = self.GetCipdRoot()
|
||||
- for package in dep_value.get('packages', []):
|
||||
+ packages = dep_value.get('packages', [])
|
||||
+ for package in (x for x in packages if "infra/3pp/tools/swift-format" not in x.get('package')):
|
||||
deps_to_add.append(
|
||||
CipdDependency(parent=self,
|
||||
name=name,
|
||||
EOF
|
||||
git apply --3way gclient.diff
|
||||
fi
|
||||
@@ -352,7 +364,7 @@ step-setup-goma-for-build: &step-setup-goma-for-build
|
||||
exit 1
|
||||
fi
|
||||
echo 'export GN_GOMA_FILE='`node -e "console.log(require('./src/utils/goma.js').gnFilePath)"` >> $BASH_ENV
|
||||
echo 'export LOCAL_GOMA_DIR='`node -e "console.log(require('./src/utils/goma.js').dir)"` >> $BASH_ENV
|
||||
echo 'export GOMA_DIR='`node -e "console.log(require('./src/utils/goma.js').dir)"` >> $BASH_ENV
|
||||
echo 'export GOMA_FALLBACK_ON_AUTH_FAILURE=true' >> $BASH_ENV
|
||||
cd ..
|
||||
touch "${TMPDIR:=/tmp}"/.goma-ready
|
||||
@@ -723,8 +735,8 @@ step-show-goma-stats: &step-show-goma-stats
|
||||
command: |
|
||||
set +e
|
||||
set +o pipefail
|
||||
$LOCAL_GOMA_DIR/goma_ctl.py stat
|
||||
$LOCAL_GOMA_DIR/diagnose_goma_log.py
|
||||
python3 $GOMA_DIR/goma_ctl.py stat
|
||||
python3 $GOMA_DIR/diagnose_goma_log.py
|
||||
true
|
||||
when: always
|
||||
background: true
|
||||
@@ -876,14 +888,26 @@ step-touch-sync-done: &step-touch-sync-done
|
||||
step-maybe-restore-src-cache: &step-maybe-restore-src-cache
|
||||
restore_cache:
|
||||
keys:
|
||||
- v16-src-cache-{{ checksum "src/electron/.depshash" }}
|
||||
- v17-src-cache-{{ checksum "src/electron/.depshash" }}
|
||||
name: Restoring src cache
|
||||
step-maybe-restore-src-cache-marker: &step-maybe-restore-src-cache-marker
|
||||
restore_cache:
|
||||
keys:
|
||||
- v16-src-cache-marker-{{ checksum "src/electron/.depshash" }}
|
||||
- v17-src-cache-marker-{{ checksum "src/electron/.depshash" }}
|
||||
name: Restoring src cache marker
|
||||
|
||||
step-maybe-restore-src-cache-aks: &step-maybe-restore-src-cache-aks
|
||||
restore_cache_aks:
|
||||
step-name: Restoring src cache
|
||||
cache_key: v17-src-cache-$(shasum src/electron/.depshash | cut -f1 -d' ')
|
||||
cache_path: /var/portal
|
||||
|
||||
step-maybe-restore-src-cache-marker-aks: &step-maybe-restore-src-cache-marker-aks
|
||||
restore_cache_aks:
|
||||
step-name: Restoring src cache marker
|
||||
cache_key: v17-src-cache-marker-$(shasum src/electron/.depshash | cut -f1 -d' ')
|
||||
cache_path: "."
|
||||
|
||||
# Restore exact or closest git cache based on the hash of DEPS and .circle-sync-done
|
||||
# If the src cache was restored above then this will match an empty cache
|
||||
# If the src cache was not restored above then this will match a close git cache
|
||||
@@ -896,6 +920,12 @@ step-maybe-restore-git-cache: &step-maybe-restore-git-cache
|
||||
- v1-git-cache-{{ checksum "src/electron/.circle-sync-done" }}
|
||||
name: Conditionally restoring git cache
|
||||
|
||||
step-maybe-restore-git-cache-aks: &step-maybe-restore-git-cache-aks
|
||||
restore_cache_aks:
|
||||
step-name: Conditionally restoring git cache (aks)
|
||||
cache_key: v1-git-cache-$(shasum src/electron/.circle-sync-done | cut -f1 -d' ')-$(shasum src/electron/DEPS | cut -f1 -d' ') v1-git-cache-$(shasum src/electron/.circle-sync-done | cut -f1 -d' ')
|
||||
cache_path: git-cache
|
||||
|
||||
step-set-git-cache-path: &step-set-git-cache-path
|
||||
run:
|
||||
name: Set GIT_CACHE_PATH to make gclient to use the cache
|
||||
@@ -913,6 +943,12 @@ step-save-git-cache: &step-save-git-cache
|
||||
key: v1-git-cache-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
|
||||
name: Persisting git cache
|
||||
|
||||
step-save-git-cache-aks: &step-save-git-cache-aks
|
||||
save_cache_aks:
|
||||
step-name: Persisting git cache (AKS)
|
||||
cache_key: v1-git-cache-$(shasum src/electron/.circle-sync-done | cut -f1 -d' ')-$(shasum src/electron/DEPS | cut -f1 -d' ')
|
||||
cache_path: git-cache
|
||||
|
||||
step-run-electron-only-hooks: &step-run-electron-only-hooks
|
||||
run:
|
||||
name: Run Electron Only Hooks
|
||||
@@ -950,7 +986,7 @@ step-save-src-cache: &step-save-src-cache
|
||||
save_cache:
|
||||
paths:
|
||||
- /var/portal
|
||||
key: v16-src-cache-{{ checksum "/var/portal/src/electron/.depshash" }}
|
||||
key: v17-src-cache-{{ checksum "/var/portal/src/electron/.depshash" }}
|
||||
name: Persisting src cache
|
||||
step-make-src-cache-marker: &step-make-src-cache-marker
|
||||
run:
|
||||
@@ -960,7 +996,17 @@ step-save-src-cache-marker: &step-save-src-cache-marker
|
||||
save_cache:
|
||||
paths:
|
||||
- .src-cache-marker
|
||||
key: v16-src-cache-marker-{{ checksum "/var/portal/src/electron/.depshash" }}
|
||||
key: v17-src-cache-marker-{{ checksum "/var/portal/src/electron/.depshash" }}
|
||||
step-save-src-cache-aks: &step-save-src-cache-aks
|
||||
save_cache_aks:
|
||||
step-name: Persisting src cache (aks)
|
||||
cache_key: v17-src-cache-$(shasum /var/portal/src/electron/.depshash | cut -f1 -d' ')
|
||||
cache_path: /var/portal
|
||||
step-save-src-cache-marker-aks: &step-save-src-cache-marker-aks
|
||||
save_cache_aks:
|
||||
step-name: Persisting src cache marker (aks)
|
||||
cache_key: v17-src-cache-marker-$(shasum /var/portal/src/electron/.depshash | cut -f1 -d' ')
|
||||
cache_path: .src-cache-marker
|
||||
|
||||
step-maybe-early-exit-no-doc-change: &step-maybe-early-exit-no-doc-change
|
||||
run:
|
||||
@@ -986,15 +1032,6 @@ step-ts-compile: &step-ts-compile
|
||||
done
|
||||
|
||||
# List of all steps.
|
||||
steps-electron-gn-check: &steps-electron-gn-check
|
||||
steps:
|
||||
- *step-setup-goma-for-build
|
||||
- checkout-from-cache
|
||||
- *step-setup-env-for-build
|
||||
- *step-wait-for-goma
|
||||
- *step-gn-gen-default
|
||||
- *step-gn-check
|
||||
|
||||
steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-change
|
||||
steps:
|
||||
# Checkout - Copied from steps-checkout
|
||||
@@ -1006,11 +1043,92 @@ steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-cha
|
||||
|
||||
# Command Aliases
|
||||
commands:
|
||||
aks-specific-step:
|
||||
parameters:
|
||||
circle:
|
||||
type: steps
|
||||
aks:
|
||||
type: steps
|
||||
could-be-aks:
|
||||
type: boolean
|
||||
description: Only set this to true on linux hosts
|
||||
steps:
|
||||
- when:
|
||||
condition:
|
||||
or:
|
||||
- equal: [<< parameters.could-be-aks >>, false]
|
||||
- equal: [<< pipeline.parameters.large-linux-executor >>, 2xlarge]
|
||||
steps: << parameters.circle >>
|
||||
- when:
|
||||
condition:
|
||||
and:
|
||||
- equal: [<< parameters.could-be-aks >>, true]
|
||||
- equal: [<< pipeline.parameters.large-linux-executor >>, electronjs/aks-linux-large]
|
||||
steps: << parameters.aks >>
|
||||
save_cache_aks:
|
||||
parameters:
|
||||
step-name:
|
||||
type: string
|
||||
cache_key:
|
||||
type: string
|
||||
cache_path:
|
||||
type: string
|
||||
steps:
|
||||
- run:
|
||||
name: << parameters.step-name >>
|
||||
command: |
|
||||
cache_key="<< parameters.cache_key >>"
|
||||
final_cache_path=/mnt/cross-instance-cache/${cache_key}.tar
|
||||
echo "Using cache key: $cache_key"
|
||||
echo "Checking path: $final_cache_path"
|
||||
if [ ! -f "$final_cache_path" ]; then
|
||||
echo "Cache key not founding, storing tarball"
|
||||
tmp_container=/mnt/cross-instance-cache/tmp/$CIRCLE_WORKFLOW_JOB_ID
|
||||
tmp_cache_path=$tmp_container/${cache_key}.tar
|
||||
mkdir -p $tmp_container
|
||||
if [ -f "<< parameters.cache_path >>" ]; then
|
||||
tar -cf $tmp_cache_path -C $(dirname << parameters.cache_path >>) ./$(basename << parameters.cache_path >>)
|
||||
else
|
||||
tar -cf $tmp_cache_path -C << parameters.cache_path >>/ ./
|
||||
fi
|
||||
mv -vn $tmp_cache_path $final_cache_path
|
||||
rm -rf $tmp_container
|
||||
else
|
||||
echo "Cache key already exists, skipping.."
|
||||
fi
|
||||
restore_cache_aks:
|
||||
parameters:
|
||||
step-name:
|
||||
type: string
|
||||
cache_key:
|
||||
type: string
|
||||
cache_path:
|
||||
type: string
|
||||
steps:
|
||||
- run:
|
||||
name: << parameters.step-name >>
|
||||
command: |
|
||||
df -h
|
||||
for cache_key in << parameters.cache_key >>; do
|
||||
cache_path=/mnt/cross-instance-cache/${cache_key}.tar
|
||||
echo "Using cache key: $cache_key"
|
||||
echo "Checking path: $cache_path"
|
||||
if [ ! -f "$cache_path" ]; then
|
||||
echo "Cache key not found, nothing to restore..."
|
||||
else
|
||||
echo "Cache key found, restoring to path..."
|
||||
mkdir -p << parameters.cache_path >>/
|
||||
tar -xf /mnt/cross-instance-cache/${cache_key}.tar -C << parameters.cache_path >>/
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
maybe-restore-portaled-src-cache:
|
||||
parameters:
|
||||
halt-if-successful:
|
||||
type: boolean
|
||||
default: false
|
||||
could-be-aks:
|
||||
type: boolean
|
||||
steps:
|
||||
- run:
|
||||
name: Prepare for cross-OS sync restore
|
||||
@@ -1020,23 +1138,44 @@ commands:
|
||||
- when:
|
||||
condition: << parameters.halt-if-successful >>
|
||||
steps:
|
||||
- *step-maybe-restore-src-cache-marker
|
||||
- aks-specific-step:
|
||||
circle:
|
||||
- *step-maybe-restore-src-cache-marker
|
||||
aks:
|
||||
- *step-maybe-restore-src-cache-marker-aks
|
||||
could-be-aks: << parameters.could-be-aks >>
|
||||
- run:
|
||||
name: Halt the job early if the src cache exists
|
||||
command: |
|
||||
if [ -f ".src-cache-marker" ]; then
|
||||
circleci-agent step halt
|
||||
fi
|
||||
- *step-maybe-restore-src-cache
|
||||
- aks-specific-step:
|
||||
circle:
|
||||
- *step-maybe-restore-src-cache
|
||||
aks:
|
||||
- *step-maybe-restore-src-cache-aks
|
||||
could-be-aks: << parameters.could-be-aks >>
|
||||
- run:
|
||||
name: Fix the src cache restore point on macOS
|
||||
name: Fix the src cache restore point
|
||||
command: |
|
||||
if [ -d "/var/portal/src" ]; then
|
||||
echo Relocating Cache
|
||||
rm -rf src
|
||||
mv /var/portal/src ./
|
||||
fi
|
||||
|
||||
run-gn-check:
|
||||
parameters:
|
||||
could-be-aks:
|
||||
type: boolean
|
||||
steps:
|
||||
- *step-setup-goma-for-build
|
||||
- checkout-from-cache:
|
||||
could-be-aks: << parameters.could-be-aks >>
|
||||
- *step-setup-env-for-build
|
||||
- *step-wait-for-goma
|
||||
- *step-gn-gen-default
|
||||
- *step-gn-check
|
||||
build_and_save_artifacts:
|
||||
parameters:
|
||||
artifact-key:
|
||||
@@ -1150,12 +1289,16 @@ commands:
|
||||
mv_if_exist cross-arch-snapshots src
|
||||
|
||||
checkout-from-cache:
|
||||
parameters:
|
||||
could-be-aks:
|
||||
type: boolean
|
||||
steps:
|
||||
- *step-checkout-electron
|
||||
- *step-depot-tools-get
|
||||
- *step-depot-tools-add-to-path
|
||||
- *step-generate-deps-hash
|
||||
- maybe-restore-portaled-src-cache
|
||||
- maybe-restore-portaled-src-cache:
|
||||
could-be-aks: << parameters.could-be-aks >>
|
||||
- run:
|
||||
name: Ensure src checkout worked
|
||||
command: |
|
||||
@@ -1293,6 +1436,8 @@ commands:
|
||||
after-persist:
|
||||
type: steps
|
||||
default: []
|
||||
could-be-aks:
|
||||
type: boolean
|
||||
steps:
|
||||
- when:
|
||||
condition: << parameters.attach >>
|
||||
@@ -1310,7 +1455,8 @@ commands:
|
||||
- when:
|
||||
condition: << parameters.checkout-and-assume-cache >>
|
||||
steps:
|
||||
- checkout-from-cache
|
||||
- checkout-from-cache:
|
||||
could-be-aks: << parameters.could-be-aks >>
|
||||
- when:
|
||||
condition: << parameters.checkout >>
|
||||
steps:
|
||||
@@ -1326,8 +1472,15 @@ commands:
|
||||
steps:
|
||||
- maybe-restore-portaled-src-cache:
|
||||
halt-if-successful: << parameters.checkout-to-create-src-cache >>
|
||||
- *step-maybe-restore-git-cache
|
||||
could-be-aks: << parameters.could-be-aks >>
|
||||
- aks-specific-step:
|
||||
circle:
|
||||
- *step-maybe-restore-git-cache
|
||||
aks:
|
||||
- *step-maybe-restore-git-cache-aks
|
||||
could-be-aks: << parameters.could-be-aks >>
|
||||
- *step-set-git-cache-path
|
||||
- *step-fix-known-hosts-linux
|
||||
# This sync call only runs if .circle-sync-done is an EMPTY file
|
||||
- *step-gclient-sync
|
||||
- store_artifacts:
|
||||
@@ -1343,7 +1496,12 @@ commands:
|
||||
- when:
|
||||
condition: << parameters.save-git-cache >>
|
||||
steps:
|
||||
- *step-save-git-cache
|
||||
- aks-specific-step:
|
||||
circle:
|
||||
- *step-save-git-cache
|
||||
aks:
|
||||
- *step-save-git-cache-aks
|
||||
could-be-aks: << parameters.could-be-aks >>
|
||||
# Mark sync as done _after_ saving the git cache so that it is uploaded
|
||||
# only when the src cache was not present
|
||||
# Their are theoretically two cases for this cache key
|
||||
@@ -1393,9 +1551,19 @@ commands:
|
||||
sudo mkdir -p /var/portal
|
||||
sudo chown -R $(id -u):$(id -g) /var/portal
|
||||
mv ./src /var/portal
|
||||
- *step-save-src-cache
|
||||
- aks-specific-step:
|
||||
circle:
|
||||
- *step-save-src-cache
|
||||
aks:
|
||||
- *step-save-src-cache-aks
|
||||
could-be-aks: << parameters.could-be-aks >>
|
||||
- *step-make-src-cache-marker
|
||||
- *step-save-src-cache-marker
|
||||
- aks-specific-step:
|
||||
circle:
|
||||
- *step-save-src-cache-marker
|
||||
aks:
|
||||
- *step-save-src-cache-marker-aks
|
||||
could-be-aks: << parameters.could-be-aks >>
|
||||
|
||||
- when:
|
||||
condition: << parameters.build >>
|
||||
@@ -1447,6 +1615,18 @@ commands:
|
||||
condition: << parameters.build >>
|
||||
steps:
|
||||
- *step-maybe-notify-slack-failure
|
||||
- when:
|
||||
condition: << parameters.could-be-aks >>
|
||||
steps:
|
||||
- run:
|
||||
name: Wait for active debug sessions
|
||||
command: |
|
||||
while [ -f /var/.ssh-lock ]
|
||||
do
|
||||
sleep 60
|
||||
done
|
||||
no_output_timeout: 2h
|
||||
when: always
|
||||
|
||||
electron-tests:
|
||||
parameters:
|
||||
@@ -1575,6 +1755,7 @@ commands:
|
||||
- *step-minimize-workspace-size-from-checkout
|
||||
- *step-fix-sync
|
||||
- *step-setup-env-for-build
|
||||
- *step-fix-known-hosts-linux
|
||||
- *step-setup-goma-for-build
|
||||
- *step-wait-for-goma
|
||||
- *step-gn-gen-default
|
||||
@@ -1632,7 +1813,7 @@ jobs:
|
||||
linux-make-src-cache:
|
||||
executor:
|
||||
name: linux-docker
|
||||
size: xlarge
|
||||
size: << pipeline.parameters.large-linux-executor >>
|
||||
environment:
|
||||
<<: *env-linux-2xlarge
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||
@@ -1645,6 +1826,7 @@ jobs:
|
||||
checkout-to-create-src-cache: true
|
||||
artifact-key: 'nil'
|
||||
build-type: 'nil'
|
||||
could-be-aks: true
|
||||
|
||||
mac-checkout:
|
||||
executor:
|
||||
@@ -1664,6 +1846,7 @@ jobs:
|
||||
restore-src-cache: false
|
||||
artifact-key: 'nil'
|
||||
build-type: 'nil'
|
||||
could-be-aks: false
|
||||
|
||||
mac-make-src-cache:
|
||||
executor:
|
||||
@@ -1683,12 +1866,13 @@ jobs:
|
||||
checkout-to-create-src-cache: true
|
||||
artifact-key: 'nil'
|
||||
build-type: 'nil'
|
||||
could-be-aks: false
|
||||
|
||||
# Layer 2: Builds.
|
||||
linux-x64-testing:
|
||||
executor:
|
||||
name: linux-docker
|
||||
size: xlarge
|
||||
size: << pipeline.parameters.large-linux-executor >>
|
||||
environment:
|
||||
<<: *env-global
|
||||
<<: *env-testing-build
|
||||
@@ -1701,11 +1885,12 @@ jobs:
|
||||
checkout-and-assume-cache: true
|
||||
artifact-key: 'linux-x64'
|
||||
build-type: 'Linux'
|
||||
could-be-aks: true
|
||||
|
||||
linux-x64-testing-asan:
|
||||
executor:
|
||||
name: linux-docker
|
||||
size: 2xlarge
|
||||
size: << pipeline.parameters.large-linux-executor >>
|
||||
environment:
|
||||
<<: *env-global
|
||||
<<: *env-testing-build
|
||||
@@ -1716,15 +1901,17 @@ jobs:
|
||||
steps:
|
||||
- electron-build:
|
||||
persist: true
|
||||
checkout: true
|
||||
checkout: false
|
||||
checkout-and-assume-cache: true
|
||||
build-nonproprietary-ffmpeg: false
|
||||
artifact-key: 'linux-x64-asan'
|
||||
build-type: 'Linux'
|
||||
could-be-aks: true
|
||||
|
||||
linux-x64-testing-no-run-as-node:
|
||||
executor:
|
||||
name: linux-docker
|
||||
size: xlarge
|
||||
size: << pipeline.parameters.large-linux-executor >>
|
||||
environment:
|
||||
<<: *env-linux-2xlarge
|
||||
<<: *env-testing-build
|
||||
@@ -1737,21 +1924,24 @@ jobs:
|
||||
checkout: true
|
||||
artifact-key: 'linux-x64-no-run-as-node'
|
||||
build-type: 'Linux'
|
||||
could-be-aks: true
|
||||
|
||||
linux-x64-testing-gn-check:
|
||||
executor:
|
||||
name: linux-docker
|
||||
size: medium
|
||||
size: << pipeline.parameters.medium-linux-executor >>
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-testing-build
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||
<<: *steps-electron-gn-check
|
||||
steps:
|
||||
- run-gn-check:
|
||||
could-be-aks: true
|
||||
|
||||
linux-x64-publish:
|
||||
executor:
|
||||
name: linux-docker
|
||||
size: 2xlarge
|
||||
size: << pipeline.parameters.large-linux-executor >>
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-release-build
|
||||
@@ -1774,7 +1964,7 @@ jobs:
|
||||
linux-arm-testing:
|
||||
executor:
|
||||
name: linux-docker
|
||||
size: 2xlarge
|
||||
size: << pipeline.parameters.large-linux-executor >>
|
||||
environment:
|
||||
<<: *env-global
|
||||
<<: *env-arm
|
||||
@@ -1790,11 +1980,12 @@ jobs:
|
||||
checkout-and-assume-cache: true
|
||||
artifact-key: 'linux-arm'
|
||||
build-type: 'Linux ARM'
|
||||
could-be-aks: true
|
||||
|
||||
linux-arm-publish:
|
||||
executor:
|
||||
name: linux-docker
|
||||
size: 2xlarge
|
||||
size: << pipeline.parameters.large-linux-executor >>
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-arm
|
||||
@@ -1819,7 +2010,7 @@ jobs:
|
||||
linux-arm64-testing:
|
||||
executor:
|
||||
name: linux-docker
|
||||
size: 2xlarge
|
||||
size: << pipeline.parameters.large-linux-executor >>
|
||||
environment:
|
||||
<<: *env-global
|
||||
<<: *env-arm64
|
||||
@@ -1835,22 +2026,25 @@ jobs:
|
||||
checkout-and-assume-cache: true
|
||||
artifact-key: 'linux-arm64'
|
||||
build-type: 'Linux ARM64'
|
||||
could-be-aks: true
|
||||
|
||||
linux-arm64-testing-gn-check:
|
||||
executor:
|
||||
name: linux-docker
|
||||
size: medium
|
||||
size: << pipeline.parameters.medium-linux-executor >>
|
||||
environment:
|
||||
<<: *env-linux-medium
|
||||
<<: *env-arm64
|
||||
<<: *env-testing-build
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
|
||||
<<: *steps-electron-gn-check
|
||||
steps:
|
||||
- run-gn-check:
|
||||
could-be-aks: true
|
||||
|
||||
linux-arm64-publish:
|
||||
executor:
|
||||
name: linux-docker
|
||||
size: 2xlarge
|
||||
size: << pipeline.parameters.large-linux-executor >>
|
||||
environment:
|
||||
<<: *env-linux-2xlarge-release
|
||||
<<: *env-arm64
|
||||
@@ -1905,6 +2099,7 @@ jobs:
|
||||
root: .
|
||||
paths:
|
||||
- generated_artifacts_mas-x64
|
||||
could-be-aks: false
|
||||
|
||||
osx-testing-x64-gn-check:
|
||||
executor:
|
||||
@@ -1914,7 +2109,9 @@ jobs:
|
||||
<<: *env-machine-mac
|
||||
<<: *env-testing-build
|
||||
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
|
||||
<<: *steps-electron-gn-check
|
||||
steps:
|
||||
- run-gn-check:
|
||||
could-be-aks: false
|
||||
|
||||
osx-publish-x64:
|
||||
executor:
|
||||
@@ -1997,6 +2194,7 @@ jobs:
|
||||
root: .
|
||||
paths:
|
||||
- generated_artifacts_mas-arm64
|
||||
could-be-aks: false
|
||||
|
||||
mas-publish-x64:
|
||||
executor:
|
||||
|
||||
12
.circleci/config/params.js
Normal file
12
.circleci/config/params.js
Normal file
@@ -0,0 +1,12 @@
|
||||
const fs = require('fs');
|
||||
|
||||
const PARAMS_PATH = '/tmp/pipeline-parameters.json';
|
||||
|
||||
const content = JSON.parse(fs.readFileSync(PARAMS_PATH, 'utf-8'));
|
||||
|
||||
// Choose resource class for linux hosts
|
||||
const currentBranch = process.env.CIRCLE_BRANCH || '';
|
||||
content['large-linux-executor'] = /^pull\/[0-9-]+$/.test(currentBranch) ? '2xlarge' : 'electronjs/aks-linux-large';
|
||||
content['medium-linux-executor'] = /^pull\/[0-9-]+$/.test(currentBranch) ? 'medium' : 'electronjs/aks-linux-medium';
|
||||
|
||||
fs.writeFileSync(PARAMS_PATH, JSON.stringify(content));
|
||||
@@ -3,5 +3,6 @@
|
||||
set -e
|
||||
|
||||
mkdir -p ~/.ssh
|
||||
echo "|1|B3r+7aO0/x90IdefihIjxIoJrrk=|OJddGDfhbuLFc1bUyy84hhIw57M= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
|
||||
|1|rGlEvW55DtzNZp+pzw9gvyOyKi4=|LLWr+7qlkAlw3YGGVfLHHxB/kR0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==" >> ~/.ssh/known_hosts
|
||||
echo "github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
|
||||
github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
|
||||
github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=" >> ~/.ssh/known_hosts
|
||||
|
||||
@@ -4,37 +4,6 @@
|
||||
"onCreateCommand": ".devcontainer/on-create-command.sh",
|
||||
"updateContentCommand": ".devcontainer/update-content-command.sh",
|
||||
"workspaceFolder": "/workspaces/gclient/src/electron",
|
||||
"extensions": [
|
||||
"joeleinbinder.mojom-language",
|
||||
"rafaelmaiolla.diff",
|
||||
"surajbarkale.ninja",
|
||||
"ms-vscode.cpptools",
|
||||
"mutantdino.resourcemonitor",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"shakram02.bash-beautify",
|
||||
"marshallofsound.gnls-electron",
|
||||
"CircleCI.circleci"
|
||||
],
|
||||
"settings": {
|
||||
"editor.tabSize": 2,
|
||||
"bashBeautify.tabSize": 2,
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"[gn]": {
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[javascript]": {
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
}
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
}
|
||||
},
|
||||
"javascript.preferences.quoteStyle": "single",
|
||||
"typescript.preferences.quoteStyle": "single"
|
||||
},
|
||||
"forwardPorts": [8088, 6080, 5901],
|
||||
"portsAttributes": {
|
||||
"8088": {
|
||||
@@ -60,6 +29,38 @@
|
||||
"openFiles": [
|
||||
".devcontainer/README.md"
|
||||
]
|
||||
},
|
||||
"vscode": {
|
||||
"extensions": ["joeleinbinder.mojom-language",
|
||||
"rafaelmaiolla.diff",
|
||||
"surajbarkale.ninja",
|
||||
"ms-vscode.cpptools",
|
||||
"mutantdino.resourcemonitor",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"shakram02.bash-beautify",
|
||||
"marshallofsound.gnls-electron",
|
||||
"CircleCI.circleci"
|
||||
],
|
||||
"settings": {
|
||||
"editor.tabSize": 2,
|
||||
"bashBeautify.tabSize": 2,
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"[gn]": {
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[javascript]": {
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
}
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
}
|
||||
},
|
||||
"javascript.preferences.quoteStyle": "single",
|
||||
"typescript.preferences.quoteStyle": "single"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@ ln -s $buildtools_configs $buildtools/configs
|
||||
|
||||
# Write the gclient config if it does not already exist
|
||||
if [ ! -f $gclient_root/.gclient ]; then
|
||||
echo "Creating gclient config"
|
||||
|
||||
echo "solutions = [
|
||||
{ \"name\" : \"src/electron\",
|
||||
\"url\" : \"https://github.com/electron/electron\",
|
||||
@@ -32,6 +34,8 @@ fi
|
||||
# Write the default buildtools config file if it does
|
||||
# not already exist
|
||||
if [ ! -f $buildtools/configs/evm.testing.json ]; then
|
||||
echo "Creating build-tools testing config"
|
||||
|
||||
write_config() {
|
||||
echo "
|
||||
{
|
||||
@@ -53,7 +57,7 @@ if [ ! -f $buildtools/configs/evm.testing.json ]; then
|
||||
\"CHROMIUM_BUILDTOOLS_PATH\": \"/workspaces/gclient/src/buildtools\",
|
||||
\"GIT_CACHE_PATH\": \"/workspaces/gclient/.git-cache\"
|
||||
},
|
||||
\"$schema\": \"file:///home/builduser/.electron_build_tools/evm-config.schema.json\"
|
||||
\"\$schema\": \"file:///home/builduser/.electron_build_tools/evm-config.schema.json\"
|
||||
}
|
||||
" >$buildtools/configs/evm.testing.json
|
||||
}
|
||||
@@ -67,10 +71,12 @@ if [ ! -f $buildtools/configs/evm.testing.json ]; then
|
||||
# if it works we can use the goma cluster
|
||||
export NOTGOMA_CODESPACES_TOKEN=$GITHUB_TOKEN
|
||||
if e d goma_auth login; then
|
||||
echo "$GITHUB_USER has GOMA access - switching to cluster mode"
|
||||
write_config cluster
|
||||
fi
|
||||
else
|
||||
# Even if the config file existed we still need to re-auth with the goma
|
||||
# cluster
|
||||
echo "build-tools testing config already exists"
|
||||
|
||||
# Re-auth with the goma cluster regardless.
|
||||
NOTGOMA_CODESPACES_TOKEN=$GITHUB_TOKEN e d goma_auth login || true
|
||||
fi
|
||||
|
||||
22
BUILD.gn
22
BUILD.gn
@@ -544,6 +544,7 @@ source_set("electron_lib") {
|
||||
|
||||
if (is_mac) {
|
||||
deps += [
|
||||
":electron_lib_arc",
|
||||
"//components/remote_cocoa/app_shim",
|
||||
"//components/remote_cocoa/browser",
|
||||
"//content/browser:mac_helpers",
|
||||
@@ -778,6 +779,27 @@ source_set("electron_lib") {
|
||||
}
|
||||
}
|
||||
|
||||
if (is_mac) {
|
||||
source_set("electron_lib_arc") {
|
||||
include_dirs = [ "." ]
|
||||
sources = [
|
||||
"shell/browser/mac/dict_util.h",
|
||||
"shell/browser/mac/dict_util.mm",
|
||||
"shell/browser/mac/electron_application_delegate.h",
|
||||
"shell/browser/mac/electron_application_delegate.mm",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//base",
|
||||
"//skia",
|
||||
"//third_party/electron_node:node_lib",
|
||||
"//v8",
|
||||
]
|
||||
|
||||
configs += [ "//build/config/compiler:enable_arc" ]
|
||||
}
|
||||
}
|
||||
|
||||
electron_paks("packed_resources") {
|
||||
if (is_mac) {
|
||||
output_dir = "$root_gen_dir/electron_repack"
|
||||
|
||||
@@ -60,6 +60,10 @@ dependencies, and tools contained in the `electron/electron` repository.
|
||||
* [Step 11: Landing](https://electronjs.org/docs/development/pull-requests#step-11-landing)
|
||||
* [Continuous Integration Testing](https://electronjs.org/docs/development/pull-requests#continuous-integration-testing)
|
||||
|
||||
### Dependencies Upgrades Policy
|
||||
|
||||
Dependencies in Electron's `package.json` or `yarn.lock` files should only be altered by maintainers. For security reasons, we will not accept PRs that alter our `package.json` or `yarn.lock` files. We invite contributors to make requests updating these files in our issue tracker. If the change is significantly complicated, draft PRs are welcome, with the understanding that these PRs will be closed in favor of a duplicate PR submitted by an Electron maintainer.
|
||||
|
||||
## Style Guides
|
||||
|
||||
See [Coding Style](https://electronjs.org/docs/development/coding-style) for information about which standards Electron adheres to in different parts of its codebase.
|
||||
|
||||
4
DEPS
4
DEPS
@@ -2,9 +2,9 @@ gclient_gn_args_from = 'src'
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'116.0.5791.0',
|
||||
'116.0.5845.228',
|
||||
'node_version':
|
||||
'v18.16.0',
|
||||
'v18.16.1',
|
||||
'nan_version':
|
||||
'16fa32231e2ccd89d2804b3f765319128b20c4ac',
|
||||
'squirrel.mac_version':
|
||||
|
||||
@@ -78,7 +78,7 @@ binary. Use this to spawn Electron from Node scripts:
|
||||
|
||||
```javascript
|
||||
const electron = require('electron')
|
||||
const proc = require('child_process')
|
||||
const proc = require('node:child_process')
|
||||
|
||||
// will print something similar to /Users/maf/.../Electron
|
||||
console.log(electron)
|
||||
|
||||
@@ -49,6 +49,11 @@ environment:
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: base-woa
|
||||
APPVEYOR_BUILD_WORKER_CLOUD: electronhq-woa
|
||||
|
||||
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
|
||||
@@ -67,8 +72,10 @@ for:
|
||||
- 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"
|
||||
Write-warning "Skipping build for doc-only change"
|
||||
$env:SHOULD_SKIP_ARTIFACT_VALIDATION = "true"
|
||||
Exit-AppveyorBuild
|
||||
} else {
|
||||
$global:LASTEXITCODE = 0
|
||||
@@ -85,6 +92,8 @@ for:
|
||||
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: $env:PATH="$pwd\depot_tools;$env:PATH"
|
||||
- ps: >-
|
||||
if (Test-Path -Path "$pwd\src\electron") {
|
||||
@@ -107,7 +116,7 @@ for:
|
||||
- ps: .\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
|
||||
- ps: >-
|
||||
if (Test-Path 'env:RAW_GOMA_AUTH') {
|
||||
$goma_login = python $env:LOCAL_GOMA_DIR\goma_auth.py info
|
||||
$goma_login = python3 $env:LOCAL_GOMA_DIR\goma_auth.py info
|
||||
if ($goma_login -eq 'Login as Fermi Planck') {
|
||||
Write-warning "Goma authentication is correct";
|
||||
} else {
|
||||
@@ -157,7 +166,7 @@ for:
|
||||
- ninja -C out/Default electron:hunspell_dictionaries_zip
|
||||
- ninja -C out/Default electron:electron_chromedriver_zip
|
||||
- ninja -C out/Default third_party/electron_node:headers
|
||||
- python %LOCAL_GOMA_DIR%\goma_ctl.py stat
|
||||
- python3 %LOCAL_GOMA_DIR%\goma_ctl.py stat
|
||||
- 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
|
||||
@@ -178,6 +187,30 @@ for:
|
||||
7z a pdb.zip out\Default\*.pdb
|
||||
}
|
||||
- python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
|
||||
- ps: |
|
||||
cd C:\projects\src
|
||||
$missing_artifacts = $false
|
||||
if ($env:SHOULD_SKIP_ARTIFACT_VALIDATION -eq 'true') {
|
||||
Write-warning "Skipping artifact validation for doc-only PR"
|
||||
} else {
|
||||
$artifacts_to_validate = 'dist.zip','windows_toolchain_profile.json','shell_browser_ui_unittests.exe','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
|
||||
@@ -203,7 +236,7 @@ for:
|
||||
- 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)
|
||||
- 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
|
||||
@@ -236,7 +269,7 @@ for:
|
||||
# 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','pdb.zip','electron.lib')
|
||||
$artifacts_to_download = @('dist.zip','ffmpeg.zip','node_headers.zip','electron.lib')
|
||||
foreach ($job in $build_info.build.jobs) {
|
||||
if ($job.name -eq "Build Arm on X64 Windows") {
|
||||
$jobId = $job.jobId
|
||||
@@ -248,10 +281,13 @@ for:
|
||||
}
|
||||
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','pdb.zip')
|
||||
$out_default_zips = @('dist.zip')
|
||||
foreach($zip_name in $out_default_zips) {
|
||||
7z x -y -osrc\out\Default $zip_name
|
||||
}
|
||||
|
||||
44
appveyor.yml
44
appveyor.yml
@@ -47,6 +47,11 @@ environment:
|
||||
- job_name: Test
|
||||
job_depends_on: Build
|
||||
|
||||
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
|
||||
@@ -65,8 +70,10 @@ for:
|
||||
- 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"
|
||||
Write-warning "Skipping build for doc-only change"
|
||||
$env:SHOULD_SKIP_ARTIFACT_VALIDATION = "true"
|
||||
Exit-AppveyorBuild
|
||||
} else {
|
||||
$global:LASTEXITCODE = 0
|
||||
@@ -83,6 +90,8 @@ for:
|
||||
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: $env:PATH="$pwd\depot_tools;$env:PATH"
|
||||
- ps: >-
|
||||
if (Test-Path -Path "$pwd\src\electron") {
|
||||
@@ -105,7 +114,7 @@ for:
|
||||
- ps: .\src\electron\script\start-goma.ps1 -gomaDir $env:LOCAL_GOMA_DIR
|
||||
- ps: >-
|
||||
if (Test-Path 'env:RAW_GOMA_AUTH') {
|
||||
$goma_login = python $env:LOCAL_GOMA_DIR\goma_auth.py info
|
||||
$goma_login = python3 $env:LOCAL_GOMA_DIR\goma_auth.py info
|
||||
if ($goma_login -eq 'Login as Fermi Planck') {
|
||||
Write-warning "Goma authentication is correct";
|
||||
} else {
|
||||
@@ -155,7 +164,7 @@ for:
|
||||
- ninja -C out/Default electron:hunspell_dictionaries_zip
|
||||
- ninja -C out/Default electron:electron_chromedriver_zip
|
||||
- ninja -C out/Default third_party/electron_node:headers
|
||||
- python %LOCAL_GOMA_DIR%\goma_ctl.py stat
|
||||
- python3 %LOCAL_GOMA_DIR%\goma_ctl.py stat
|
||||
- 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
|
||||
@@ -176,6 +185,30 @@ for:
|
||||
7z a pdb.zip out\Default\*.pdb
|
||||
}
|
||||
- python3 electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.win.%TARGET_ARCH%.manifest
|
||||
- ps: |
|
||||
cd C:\projects\src
|
||||
$missing_artifacts = $false
|
||||
if ($env:SHOULD_SKIP_ARTIFACT_VALIDATION -eq 'true') {
|
||||
Write-warning "Skipping artifact validation for doc-only PR"
|
||||
} else {
|
||||
$artifacts_to_validate = 'dist.zip','windows_toolchain_profile.json','shell_browser_ui_unittests.exe','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
|
||||
@@ -201,7 +234,7 @@ for:
|
||||
- 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)
|
||||
- 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
|
||||
@@ -244,6 +277,9 @@ for:
|
||||
}
|
||||
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: |
|
||||
|
||||
@@ -105,16 +105,6 @@ static_library("chrome") {
|
||||
|
||||
if (is_mac) {
|
||||
sources += [
|
||||
"//chrome/browser/extensions/global_shortcut_listener_mac.h",
|
||||
"//chrome/browser/extensions/global_shortcut_listener_mac.mm",
|
||||
"//chrome/browser/icon_loader_mac.mm",
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_mac.h",
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm",
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_stats_mac.h",
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_stats_mac.mm",
|
||||
"//chrome/browser/media/webrtc/window_icon_util_mac.mm",
|
||||
"//chrome/browser/platform_util_mac.mm",
|
||||
"//chrome/browser/process_singleton_mac.mm",
|
||||
"//chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.h",
|
||||
"//chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm",
|
||||
]
|
||||
@@ -154,6 +144,7 @@ static_library("chrome") {
|
||||
|
||||
public_deps = [
|
||||
"//chrome/browser:dev_ui_browser_resources",
|
||||
"//chrome/browser/resources/accessibility:resources",
|
||||
"//chrome/browser/ui/color:mixers",
|
||||
"//chrome/common",
|
||||
"//chrome/common:version_header",
|
||||
@@ -186,6 +177,10 @@ static_library("chrome") {
|
||||
"//chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc",
|
||||
"//chrome/browser/ui/views/status_icons/status_icon_linux_dbus.h",
|
||||
]
|
||||
sources += [
|
||||
"//chrome/browser/ui/views/dark_mode_manager_linux.cc",
|
||||
"//chrome/browser/ui/views/dark_mode_manager_linux.h",
|
||||
]
|
||||
public_deps += [
|
||||
"//components/dbus/menu",
|
||||
"//components/dbus/thread_linux",
|
||||
@@ -200,6 +195,10 @@ static_library("chrome") {
|
||||
public_deps += [ "//chrome/services/util_win:lib" ]
|
||||
}
|
||||
|
||||
if (is_mac) {
|
||||
public_deps += [ ":chrome_lib_arc" ]
|
||||
}
|
||||
|
||||
if (enable_widevine) {
|
||||
sources += [
|
||||
"//chrome/renderer/media/chrome_key_systems.cc",
|
||||
@@ -348,6 +347,34 @@ static_library("chrome") {
|
||||
}
|
||||
}
|
||||
|
||||
if (is_mac) {
|
||||
source_set("chrome_lib_arc") {
|
||||
include_dirs = [ "." ]
|
||||
sources = [
|
||||
"//chrome/browser/extensions/global_shortcut_listener_mac.h",
|
||||
"//chrome/browser/extensions/global_shortcut_listener_mac.mm",
|
||||
"//chrome/browser/icon_loader_mac.mm",
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_mac.h",
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm",
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_stats_mac.h",
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_stats_mac.mm",
|
||||
"//chrome/browser/media/webrtc/window_icon_util_mac.mm",
|
||||
"//chrome/browser/platform_util_mac.mm",
|
||||
"//chrome/browser/process_singleton_mac.mm",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//base",
|
||||
"//skia",
|
||||
"//third_party/electron_node:node_lib",
|
||||
"//third_party/webrtc_overrides:webrtc_component",
|
||||
"//v8",
|
||||
]
|
||||
|
||||
configs += [ "//build/config/compiler:enable_arc" ]
|
||||
}
|
||||
}
|
||||
|
||||
source_set("plugins") {
|
||||
sources = []
|
||||
deps = []
|
||||
|
||||
@@ -55,7 +55,7 @@ The `Super` (or `Meta`) key is mapped to the `Windows` key on Windows and Linux
|
||||
* `0` to `9`
|
||||
* `A` to `Z`
|
||||
* `F1` to `F24`
|
||||
* Punctuation like `~`, `!`, `@`, `#`, `$`, etc.
|
||||
* Various Punctuation: `)`, `!`, `@`, `#`, `$`, `%`, `^`, `&`, `*`, `(`, `:`, `;`, `:`, `+`, `=`, `<`, `,`, `_`, `-`, `>`, `.`, `?`, `/`, `~`, `` ` ``, `{`, `]`, `[`, `|`, `\`, `}`, `"`
|
||||
* `Plus`
|
||||
* `Space`
|
||||
* `Tab`
|
||||
|
||||
@@ -413,18 +413,7 @@ Returns:
|
||||
|
||||
* `event` Event
|
||||
* `webContents` [WebContents](web-contents.md)
|
||||
* `details` Object
|
||||
* `reason` string - The reason the render process is gone. Possible values:
|
||||
* `clean-exit` - Process exited with an exit code of zero
|
||||
* `abnormal-exit` - Process exited with a non-zero exit code
|
||||
* `killed` - Process was sent a SIGTERM or otherwise killed externally
|
||||
* `crashed` - Process crashed
|
||||
* `oom` - Process ran out of memory
|
||||
* `launch-failed` - Process never successfully launched
|
||||
* `integrity-failure` - Windows code integrity checks failed
|
||||
* `exitCode` Integer - The exit code of the process, unless `reason` is
|
||||
`launch-failed`, in which case `exitCode` will be a platform-specific
|
||||
launch failure error code.
|
||||
* `details` [RenderProcessGoneDetails](structures/render-process-gone-details.md)
|
||||
|
||||
Emitted when the renderer process unexpectedly disappears. This is normally
|
||||
because it was crashed or killed.
|
||||
@@ -1146,11 +1135,11 @@ indicates success while any other value indicates failure according to Chromium
|
||||
resolver will attempt to use the system's DNS settings to do DNS lookups
|
||||
itself. Enabled by default on macOS, disabled by default on Windows and
|
||||
Linux.
|
||||
* `secureDnsMode` string (optional) - Can be "off", "automatic" or "secure".
|
||||
Configures the DNS-over-HTTP mode. When "off", no DoH lookups will be
|
||||
performed. When "automatic", DoH lookups will be performed first if DoH is
|
||||
* `secureDnsMode` string (optional) - Can be 'off', 'automatic' or 'secure'.
|
||||
Configures the DNS-over-HTTP mode. When 'off', no DoH lookups will be
|
||||
performed. When 'automatic', DoH lookups will be performed first if DoH is
|
||||
available, and insecure DNS lookups will be performed as a fallback. When
|
||||
"secure", only DoH lookups will be performed. Defaults to "automatic".
|
||||
'secure', only DoH lookups will be performed. Defaults to 'automatic'.
|
||||
* `secureDnsServers` string[] (optional) - A list of DNS-over-HTTP
|
||||
server templates. See [RFC8484 § 3][] for details on the template format.
|
||||
Most servers support the POST method; the template for such servers is
|
||||
@@ -1342,7 +1331,7 @@ application name. For example:
|
||||
|
||||
``` js
|
||||
const { app } = require('electron')
|
||||
const path = require('path')
|
||||
const path = require('node:path')
|
||||
|
||||
const appFolder = path.dirname(process.execPath)
|
||||
const updateExe = path.resolve(appFolder, '..', 'Update.exe')
|
||||
@@ -1413,7 +1402,7 @@ Returns `Function` - This function **must** be called once you have finished acc
|
||||
|
||||
```js
|
||||
const { app, dialog } = require('electron')
|
||||
const fs = require('fs')
|
||||
const fs = require('node:fs')
|
||||
|
||||
let filepath
|
||||
let bookmark
|
||||
|
||||
@@ -820,10 +820,14 @@ win.setBounds({ width: 100 })
|
||||
console.log(win.getBounds())
|
||||
```
|
||||
|
||||
**Note:** On macOS, the y-coordinate value cannot be smaller than the [Tray](tray.md) height. The tray height has changed over time and depends on the operating system, but is between 20-40px. Passing a value lower than the tray height will result in a window that is flush to the tray.
|
||||
|
||||
#### `win.getBounds()`
|
||||
|
||||
Returns [`Rectangle`](structures/rectangle.md) - The `bounds` of the window as `Object`.
|
||||
|
||||
**Note:** On macOS, the y-coordinate value returned will be at minimum the [Tray](tray.md) height. For example, calling `win.setBounds({ x: 25, y: 20, width: 800, height: 600 })` with a tray height of 38 means that `win.getBounds()` will return `{ x: 25, y: 38, width: 800, height: 600 }`.
|
||||
|
||||
#### `win.getBackgroundColor()`
|
||||
|
||||
Returns `string` - Gets the background color of the window in Hex (`#RRGGBB`) format.
|
||||
@@ -1207,7 +1211,7 @@ const win = new BrowserWindow()
|
||||
const url = require('url').format({
|
||||
protocol: 'file',
|
||||
slashes: true,
|
||||
pathname: require('path').join(__dirname, 'index.html')
|
||||
pathname: require('node:path').join(__dirname, 'index.html')
|
||||
})
|
||||
|
||||
win.loadURL(url)
|
||||
|
||||
@@ -116,14 +116,20 @@ Ignore the connections limit for `domains` list separated by `,`.
|
||||
|
||||
### --js-flags=`flags`
|
||||
|
||||
Specifies the flags passed to the Node.js engine. It has to be passed when starting
|
||||
Electron if you want to enable the `flags` in the main process.
|
||||
Specifies the flags passed to the [V8 engine](https://v8.dev). In order to enable the `flags` in the main process,
|
||||
this switch must be passed on startup.
|
||||
|
||||
```sh
|
||||
$ electron --js-flags="--harmony_proxies --harmony_collections" your-app
|
||||
```
|
||||
|
||||
See the [Node.js documentation][node-cli] or run `node --help` in your terminal for a list of available flags. Additionally, run `node --v8-options` to see a list of flags that specifically refer to Node.js's V8 JavaScript engine.
|
||||
Run `node --v8-options` or `electron --js-flags="--help"` in your terminal for the list of available flags. These can be used to enable early-stage JavaScript features, or log and manipulate garbage collection, among other things.
|
||||
|
||||
For example, to trace V8 optimization and deoptimization:
|
||||
|
||||
```sh
|
||||
$ electron --js-flags="--trace-opt --trace-deopt" your-app
|
||||
```
|
||||
|
||||
### --lang
|
||||
|
||||
@@ -241,19 +247,25 @@ Electron supports some of the [CLI flags][node-cli] supported by Node.js.
|
||||
|
||||
**Note:** Passing unsupported command line switches to Electron when it is not running in `ELECTRON_RUN_AS_NODE` will have no effect.
|
||||
|
||||
### --inspect-brk\[=\[host:]port]
|
||||
### `--inspect-brk\[=\[host:]port]`
|
||||
|
||||
Activate inspector on host:port and break at start of user script. Default host:port is 127.0.0.1:9229.
|
||||
|
||||
Aliased to `--debug-brk=[host:]port`.
|
||||
|
||||
### --inspect-port=\[host:]port
|
||||
#### `--inspect-brk-node[=[host:]port]`
|
||||
|
||||
Activate inspector on `host:port` and break at start of the first internal
|
||||
JavaScript script executed when the inspector is available.
|
||||
Default `host:port` is `127.0.0.1:9229`.
|
||||
|
||||
### `--inspect-port=\[host:]port`
|
||||
|
||||
Set the `host:port` to be used when the inspector is activated. Useful when activating the inspector by sending the SIGUSR1 signal. Default host is `127.0.0.1`.
|
||||
|
||||
Aliased to `--debug-port=[host:]port`.
|
||||
|
||||
### --inspect\[=\[host:]port]
|
||||
### `--inspect\[=\[host:]port]`
|
||||
|
||||
Activate inspector on `host:port`. Default is `127.0.0.1:9229`.
|
||||
|
||||
@@ -263,12 +275,37 @@ See the [Debugging the Main Process][debugging-main-process] guide for more deta
|
||||
|
||||
Aliased to `--debug[=[host:]port`.
|
||||
|
||||
### --inspect-publish-uid=stderr,http
|
||||
### `--inspect-publish-uid=stderr,http`
|
||||
|
||||
Specify ways of the inspector web socket url exposure.
|
||||
|
||||
By default inspector websocket url is available in stderr and under /json/list endpoint on http://host:port/json/list.
|
||||
|
||||
### `--no-deprecation`
|
||||
|
||||
Silence deprecation warnings.
|
||||
|
||||
### `--throw-deprecation`
|
||||
|
||||
Throw errors for deprecations.
|
||||
|
||||
### `--trace-deprecation`
|
||||
|
||||
Print stack traces for deprecations.
|
||||
|
||||
### `--trace-warnings`
|
||||
|
||||
Print stack traces for process warnings (including deprecations).
|
||||
|
||||
### `--dns-result-order=order`
|
||||
|
||||
Set the default value of the `verbatim` parameter in the Node.js [`dns.lookup()`](https://nodejs.org/api/dns.html#dnslookuphostname-options-callback) and [`dnsPromises.lookup()`](https://nodejs.org/api/dns.html#dnspromiseslookuphostname-options) functions. The value could be:
|
||||
|
||||
* `ipv4first`: sets default `verbatim` `false`.
|
||||
* `verbatim`: sets default `verbatim` `true`.
|
||||
|
||||
The default is `verbatim` and `dns.setDefaultResultOrder()` have higher priority than `--dns-result-order`.
|
||||
|
||||
[app]: app.md
|
||||
[append-switch]: command-line.md#commandlineappendswitchswitch-value
|
||||
[debugging-main-process]: ../tutorial/debugging-main-process.md
|
||||
|
||||
@@ -147,7 +147,7 @@ Be very cautious about which globals and APIs you expose to untrusted remote con
|
||||
|
||||
```javascript
|
||||
const { contextBridge } = require('electron')
|
||||
const crypto = require('crypto')
|
||||
const crypto = require('node:crypto')
|
||||
contextBridge.exposeInMainWorld('nodeCrypto', {
|
||||
sha256sum (data) {
|
||||
const hash = crypto.createHash('sha256')
|
||||
|
||||
@@ -119,4 +119,8 @@ Removes the cookies matching `url` and `name`
|
||||
|
||||
Returns `Promise<void>` - A promise which resolves when the cookie store has been flushed
|
||||
|
||||
Writes any unwritten cookies data to disk.
|
||||
Writes any unwritten cookies data to disk
|
||||
|
||||
Cookies written by any method will not be written to disk immediately, but will be written every 30 seconds or 512 operations
|
||||
|
||||
Calling this method can cause the cookie to be written to disk immediately.
|
||||
|
||||
@@ -91,7 +91,7 @@ The `desktopCapturer` module has the following methods:
|
||||
|
||||
* `options` Object
|
||||
* `types` string[] - An array of strings that lists the types of desktop sources
|
||||
to be captured, available types are `screen` and `window`.
|
||||
to be captured, available types can be `screen` and `window`.
|
||||
* `thumbnailSize` [Size](structures/size.md) (optional) - The size that the media source thumbnail
|
||||
should be scaled to. Default is `150` x `150`. Set width or height to 0 when you do not need
|
||||
the thumbnails. This will save the processing time required for capturing the content of each
|
||||
|
||||
@@ -40,18 +40,41 @@ We support the following extensions APIs, with some caveats. Other APIs may
|
||||
additionally be supported, but support for any APIs not listed here is
|
||||
provisional and may be removed.
|
||||
|
||||
### Supported Manifest Keys
|
||||
|
||||
- `name`
|
||||
- `version`
|
||||
- `author`
|
||||
- `permissions`
|
||||
- `content_scripts`
|
||||
- `default_locale`
|
||||
- `devtools_page`
|
||||
- `short_name`
|
||||
- `host_permissions` (Manifest V3)
|
||||
- `manifest_version`
|
||||
- `background` (Manifest V2)
|
||||
- `minimum_chrome_version`
|
||||
|
||||
See [Manifest file format](https://developer.chrome.com/docs/extensions/mv3/manifest/) for more information about the purpose of each possible key.
|
||||
|
||||
### `chrome.devtools.inspectedWindow`
|
||||
|
||||
All features of this API are supported.
|
||||
|
||||
See [official documentation](https://developer.chrome.com/docs/extensions/reference/devtools_inspectedWindow) for more information.
|
||||
|
||||
### `chrome.devtools.network`
|
||||
|
||||
All features of this API are supported.
|
||||
|
||||
See [official documentation](https://developer.chrome.com/docs/extensions/reference/devtools_network) for more information.
|
||||
|
||||
### `chrome.devtools.panels`
|
||||
|
||||
All features of this API are supported.
|
||||
|
||||
See [official documentation](https://developer.chrome.com/docs/extensions/reference/devtools_panels) for more information.
|
||||
|
||||
### `chrome.extension`
|
||||
|
||||
The following properties of `chrome.extension` are supported:
|
||||
@@ -63,6 +86,25 @@ The following methods of `chrome.extension` are supported:
|
||||
- `chrome.extension.getURL`
|
||||
- `chrome.extension.getBackgroundPage`
|
||||
|
||||
See [official documentation](https://developer.chrome.com/docs/extensions/reference/extension) for more information.
|
||||
|
||||
### `chrome.management`
|
||||
|
||||
The following methods of `chrome.management` are supported:
|
||||
|
||||
- `chrome.management.getAll`
|
||||
- `chrome.management.get`
|
||||
- `chrome.management.getSelf`
|
||||
- `chrome.management.getPermissionWarningsById`
|
||||
- `chrome.management.getPermissionWarningsByManifest`
|
||||
|
||||
The following events of `chrome.management` are supported:
|
||||
|
||||
- `chrome.management.onEnabled`
|
||||
- `chrome.management.onDisabled`
|
||||
|
||||
See [official documentation](https://developer.chrome.com/docs/extensions/reference/management) for more information.
|
||||
|
||||
### `chrome.runtime`
|
||||
|
||||
The following properties of `chrome.runtime` are supported:
|
||||
@@ -89,10 +131,23 @@ The following events of `chrome.runtime` are supported:
|
||||
- `chrome.runtime.onConnect`
|
||||
- `chrome.runtime.onMessage`
|
||||
|
||||
See [official documentation](https://developer.chrome.com/docs/extensions/reference/runtime) for more information.
|
||||
|
||||
### `chrome.scripting`
|
||||
|
||||
All features of this API are supported.
|
||||
|
||||
See [official documentation](https://developer.chrome.com/docs/extensions/reference/scripting) for more information.
|
||||
|
||||
### `chrome.storage`
|
||||
|
||||
Only `chrome.storage.local` is supported; `chrome.storage.sync` and
|
||||
`chrome.storage.managed` are not.
|
||||
The following methods of `chrome.storage` are supported:
|
||||
|
||||
- `chrome.storage.local`
|
||||
|
||||
`chrome.storage.sync` and `chrome.storage.managed` are **not** supported.
|
||||
|
||||
See [official documentation](https://developer.chrome.com/docs/extensions/reference/storage) for more information.
|
||||
|
||||
### `chrome.tabs`
|
||||
|
||||
@@ -101,6 +156,8 @@ The following methods of `chrome.tabs` are supported:
|
||||
- `chrome.tabs.sendMessage`
|
||||
- `chrome.tabs.reload`
|
||||
- `chrome.tabs.executeScript`
|
||||
- `chrome.tabs.query` (partial support)
|
||||
- supported properties: `url`, `title`, `audible`, `active`, `muted`.
|
||||
- `chrome.tabs.update` (partial support)
|
||||
- supported properties: `url`, `muted`.
|
||||
|
||||
@@ -108,20 +165,12 @@ The following methods of `chrome.tabs` are supported:
|
||||
> tab". Since Electron has no such concept, passing `-1` as a tab ID is not
|
||||
> supported and will raise an error.
|
||||
|
||||
### `chrome.management`
|
||||
|
||||
The following methods of `chrome.management` are supported:
|
||||
|
||||
- `chrome.management.getAll`
|
||||
- `chrome.management.get`
|
||||
- `chrome.management.getSelf`
|
||||
- `chrome.management.getPermissionWarningsById`
|
||||
- `chrome.management.getPermissionWarningsByManifest`
|
||||
- `chrome.management.onEnabled`
|
||||
- `chrome.management.onDisabled`
|
||||
See [official documentation](https://developer.chrome.com/docs/extensions/reference/tabs) for more information.
|
||||
|
||||
### `chrome.webRequest`
|
||||
|
||||
All features of this API are supported.
|
||||
|
||||
> **NOTE:** Electron's [`webRequest`](web-request.md) module takes precedence over `chrome.webRequest` if there are conflicting handlers.
|
||||
|
||||
See [official documentation](https://developer.chrome.com/docs/extensions/reference/webRequest) for more information.
|
||||
|
||||
@@ -72,7 +72,7 @@ Removes listeners of the specified `channel`.
|
||||
### `ipcMain.handle(channel, listener)`
|
||||
|
||||
* `channel` string
|
||||
* `listener` Function<Promise\<void> | any>
|
||||
* `listener` Function<Promise\<any> | any>
|
||||
* `event` [IpcMainInvokeEvent][ipc-main-invoke-event]
|
||||
* `...args` any[]
|
||||
|
||||
@@ -109,8 +109,8 @@ provided to the renderer process. Please refer to
|
||||
### `ipcMain.handleOnce(channel, listener)`
|
||||
|
||||
* `channel` string
|
||||
* `listener` Function<Promise\<void> | any>
|
||||
* `event` IpcMainInvokeEvent
|
||||
* `listener` Function<Promise\<any> | any>
|
||||
* `event` [IpcMainInvokeEvent][ipc-main-invoke-event]
|
||||
* `...args` any[]
|
||||
|
||||
Handles a single `invoke`able IPC message, then removes the listener. See
|
||||
@@ -122,17 +122,6 @@ Handles a single `invoke`able IPC message, then removes the listener. See
|
||||
|
||||
Removes any handler for `channel`, if present.
|
||||
|
||||
## IpcMainEvent object
|
||||
|
||||
The documentation for the `event` object passed to the `callback` can be found
|
||||
in the [`ipc-main-event`][ipc-main-event] structure docs.
|
||||
|
||||
## IpcMainInvokeEvent object
|
||||
|
||||
The documentation for the `event` object passed to `handle` callbacks can be
|
||||
found in the [`ipc-main-invoke-event`][ipc-main-invoke-event]
|
||||
structure docs.
|
||||
|
||||
[IPC tutorial]: ../tutorial/ipc.md
|
||||
[event-emitter]: https://nodejs.org/api/events.html#events_class_eventemitter
|
||||
[web-contents-send]: ../api/web-contents.md#contentssendchannel-args
|
||||
|
||||
@@ -26,7 +26,7 @@ The `ipcRenderer` module has the following method to listen for events and send
|
||||
|
||||
* `channel` string
|
||||
* `listener` Function
|
||||
* `event` IpcRendererEvent
|
||||
* `event` [IpcRendererEvent][ipc-renderer-event]
|
||||
* `...args` any[]
|
||||
|
||||
Listens to `channel`, when a new message arrives `listener` would be called with
|
||||
@@ -36,7 +36,7 @@ Listens to `channel`, when a new message arrives `listener` would be called with
|
||||
|
||||
* `channel` string
|
||||
* `listener` Function
|
||||
* `event` IpcRendererEvent
|
||||
* `event` [IpcRendererEvent][ipc-renderer-event]
|
||||
* `...args` any[]
|
||||
|
||||
Adds a one time `listener` function for the event. This `listener` is invoked
|
||||
@@ -208,12 +208,8 @@ Sends a message to a window with `webContentsId` via `channel`.
|
||||
Like `ipcRenderer.send` but the event will be sent to the `<webview>` element in
|
||||
the host page instead of the main process.
|
||||
|
||||
## Event object
|
||||
|
||||
The documentation for the `event` object passed to the `callback` can be found
|
||||
in the [`ipc-renderer-event`](./structures/ipc-renderer-event.md) structure docs.
|
||||
|
||||
[event-emitter]: https://nodejs.org/api/events.html#events_class_eventemitter
|
||||
[SCA]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
|
||||
[`window.postMessage`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
|
||||
[`MessagePort`]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort
|
||||
[ipc-renderer-event]: ./structures/ipc-renderer-event.md
|
||||
|
||||
@@ -80,6 +80,10 @@ The `menu` object has the following instance methods:
|
||||
* `positioningItem` number (optional) _macOS_ - The index of the menu item to
|
||||
be positioned under the mouse cursor at the specified coordinates. Default
|
||||
is -1.
|
||||
* `sourceType` string (optional) _Windows_ _Linux_ - This should map to the `menuSourceType`
|
||||
provided by the `context-menu` event. It is not recommended to set this value manually,
|
||||
only provide values you receive from other APIs or leave it `undefined`.
|
||||
Can be `none`, `mouse`, `keyboard`, `touch`, `touchMenu`, `longPress`, `longTap`, `touchHandle`, `stylus`, `adjustSelection`, or `adjustSelectionReset`.
|
||||
* `callback` Function (optional) - Called when menu is closed.
|
||||
|
||||
Pops up this menu as a context menu in the [`BrowserWindow`](browser-window.md).
|
||||
|
||||
@@ -306,7 +306,7 @@ Returns `NativeImage` - The cropped image.
|
||||
* `width` Integer (optional) - Defaults to the image's width.
|
||||
* `height` Integer (optional) - Defaults to the image's height.
|
||||
* `quality` string (optional) - The desired quality of the resize image.
|
||||
Possible values are `good`, `better`, or `best`. The default is `best`.
|
||||
Possible values include `good`, `better`, or `best`. The default is `best`.
|
||||
These values express a desired quality/speed tradeoff. They are translated
|
||||
into an algorithm-specific method that depends on the capabilities
|
||||
(CPU, GPU) of the underlying platform. It is possible for all three methods
|
||||
|
||||
@@ -85,6 +85,8 @@ Emitted when the notification is closed by manual intervention from the user.
|
||||
This event is not guaranteed to be emitted in all cases where the notification
|
||||
is closed.
|
||||
|
||||
On Windows, the `close` event can be emitted in one of three ways: programmatic dismissal with `notification.close()`, by the user closing the notification, or via system timeout. If a notification is in the Action Center after the initial `close` event is emitted, a call to `notification.close()` will remove the notification from the action center but the `close` event will not be emitted again.
|
||||
|
||||
#### Event: 'reply' _macOS_
|
||||
|
||||
Returns:
|
||||
@@ -127,6 +129,8 @@ shown notification and create a new one with identical properties.
|
||||
|
||||
Dismisses the notification.
|
||||
|
||||
On Windows, calling `notification.close()` while the notification is visible on screen will dismiss the notification and remove it from the Action Center. If `notification.close()` is called after the notification is no longer visible on screen, calling `notification.close()` will try remove it from the Action Center.
|
||||
|
||||
### Instance Properties
|
||||
|
||||
#### `notification.title`
|
||||
|
||||
@@ -49,6 +49,8 @@ is used.
|
||||
|
||||
Stops the specified power save blocker.
|
||||
|
||||
Returns `boolean` - Whether the specified `powerSaveBlocker` has been stopped.
|
||||
|
||||
### `powerSaveBlocker.isStarted(id)`
|
||||
|
||||
* `id` Integer - The power save blocker id returned by `powerSaveBlocker.start`.
|
||||
|
||||
@@ -33,7 +33,7 @@ to register it to that session explicitly.
|
||||
|
||||
```javascript
|
||||
const { app, BrowserWindow, net, protocol, session } = require('electron')
|
||||
const path = require('path')
|
||||
const path = require('node:path')
|
||||
const url = require('url')
|
||||
|
||||
app.whenReady().then(() => {
|
||||
@@ -122,7 +122,7 @@ Example:
|
||||
|
||||
```js
|
||||
const { app, net, protocol } = require('electron')
|
||||
const { join } = require('path')
|
||||
const { join } = require('node:path')
|
||||
const { pathToFileURL } = require('url')
|
||||
|
||||
protocol.registerSchemesAsPrivileged([
|
||||
|
||||
@@ -38,3 +38,28 @@ Returns `string` - the decrypted string. Decrypts the encrypted buffer
|
||||
obtained with `safeStorage.encryptString` back into a string.
|
||||
|
||||
This function will throw an error if decryption fails.
|
||||
|
||||
### `safeStorage.setUsePlainTextEncryption(usePlainText)`
|
||||
|
||||
* `usePlainText` boolean
|
||||
|
||||
This function on Linux will force the module to use an in memory password for creating
|
||||
symmetric key that is used for encrypt/decrypt functions when a valid OS password
|
||||
manager cannot be determined for the current active desktop environment. This function
|
||||
is a no-op on Windows and MacOS.
|
||||
|
||||
### `safeStorage.getSelectedStorageBackend()` _Linux_
|
||||
|
||||
Returns `string` - User friendly name of the password manager selected on Linux.
|
||||
|
||||
This function will return one of the following values:
|
||||
|
||||
* `basic_text` - When the desktop environment is not recognised or if the following
|
||||
command line flag is provided `--password-store="basic"`.
|
||||
* `gnome_libsecret` - When the desktop environment is `X-Cinnamon`, `Deepin`, `GNOME`, `Pantheon`, `XFCE`, `UKUI`, `unity` or if the following command line flag is provided `--password-store="gnome-libsecret"`.
|
||||
* `kwallet` - When the desktop session is `kde4` or if the following command line flag
|
||||
is provided `--password-store="kwallet"`.
|
||||
* `kwallet5` - When the desktop session is `kde5` or if the following command line flag
|
||||
is provided `--password-store="kwallet5"`.
|
||||
* `kwallet6` - When the desktop session is `kde6`.
|
||||
* `unknown` - When the function is called before app has emitted the `ready` event.
|
||||
|
||||
@@ -103,7 +103,7 @@ const { session } = require('electron')
|
||||
session.defaultSession.on('will-download', (event, item, webContents) => {
|
||||
event.preventDefault()
|
||||
require('got')(item.getURL()).then((response) => {
|
||||
require('fs').writeFileSync('/somewhere', response.body)
|
||||
require('node:fs').writeFileSync('/somewhere', response.body)
|
||||
})
|
||||
})
|
||||
```
|
||||
@@ -574,11 +574,11 @@ Clears the session’s HTTP cache.
|
||||
* `options` Object (optional)
|
||||
* `origin` string (optional) - Should follow `window.location.origin`’s representation
|
||||
`scheme://host:port`.
|
||||
* `storages` string[] (optional) - The types of storages to clear, can contain:
|
||||
* `storages` string[] (optional) - The types of storages to clear, can be
|
||||
`cookies`, `filesystem`, `indexdb`, `localstorage`,
|
||||
`shadercache`, `websql`, `serviceworkers`, `cachestorage`. If not
|
||||
specified, clear all storage types.
|
||||
* `quotas` string[] (optional) - The types of quotas to clear, can contain:
|
||||
* `quotas` string[] (optional) - The types of quotas to clear, can be
|
||||
`temporary`, `syncable`. If not specified, clear all quotas.
|
||||
|
||||
Returns `Promise<void>` - resolves when the storage data has been cleared.
|
||||
@@ -891,18 +891,19 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
|
||||
* `permission` string - The type of requested permission.
|
||||
* `clipboard-read` - Request access to read from the clipboard.
|
||||
* `clipboard-sanitized-write` - Request access to write to the clipboard.
|
||||
* `display-capture` - Request access to capture the screen via the [Screen Capture API](https://developer.mozilla.org/en-US/docs/Web/API/Screen_Capture_API).
|
||||
* `fullscreen` - Request control of the app's fullscreen state via the [Fullscreen API](https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API).
|
||||
* `geolocation` - Request access to the user's location via the [Geolocation API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API)
|
||||
* `idle-detection` - Request access to the user's idle state via the [IdleDetector API](https://developer.mozilla.org/en-US/docs/Web/API/IdleDetector).
|
||||
* `media` - Request access to media devices such as camera, microphone and speakers.
|
||||
* `display-capture` - Request access to capture the screen.
|
||||
* `mediaKeySystem` - Request access to DRM protected content.
|
||||
* `geolocation` - Request access to user's current location.
|
||||
* `notifications` - Request notification creation and the ability to display them in the user's system tray.
|
||||
* `midi` - Request MIDI access in the `webmidi` API.
|
||||
* `midiSysex` - Request the use of system exclusive messages in the `webmidi` API.
|
||||
* `pointerLock` - Request to directly interpret mouse movements as an input method. Click [here](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API) to know more. These requests always appear to originate from the main frame.
|
||||
* `fullscreen` - Request for the app to enter fullscreen mode.
|
||||
* `midi` - Request MIDI access in the [Web MIDI API](https://developer.mozilla.org/en-US/docs/Web/API/Web_MIDI_API).
|
||||
* `midiSysex` - Request the use of system exclusive messages in the [Web MIDI API](https://developer.mozilla.org/en-US/docs/Web/API/Web_MIDI_API).
|
||||
* `notifications` - Request notification creation and the ability to display them in the user's system tray using the [Notifications API](https://developer.mozilla.org/en-US/docs/Web/API/notification)
|
||||
* `pointerLock` - Request to directly interpret mouse movements as an input method via the [Pointer Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API). These requests always appear to originate from the main frame.
|
||||
* `openExternal` - Request to open links in external applications.
|
||||
* `window-management` - Request access to enumerate screens using the [`getScreenDetails`](https://developer.chrome.com/en/articles/multi-screen-window-placement/) API.
|
||||
* `unknown` - An unrecognized permission request
|
||||
* `unknown` - An unrecognized permission request.
|
||||
* `callback` Function
|
||||
* `permissionGranted` boolean - Allow or deny the permission.
|
||||
* `details` Object - Some properties are only available on certain permission types.
|
||||
@@ -934,7 +935,22 @@ session.fromPartition('some-partition').setPermissionRequestHandler((webContents
|
||||
|
||||
* `handler` Function\<boolean> | null
|
||||
* `webContents` ([WebContents](web-contents.md) | null) - WebContents checking the permission. Please note that if the request comes from a subframe you should use `requestingUrl` to check the request origin. All cross origin sub frames making permission checks will pass a `null` webContents to this handler, while certain other permission checks such as `notifications` checks will always pass `null`. You should use `embeddingOrigin` and `requestingOrigin` to determine what origin the owning frame and the requesting frame are on respectively.
|
||||
* `permission` string - Type of permission check. Valid values are `midiSysex`, `notifications`, `geolocation`, `media`,`mediaKeySystem`,`midi`, `pointerLock`, `fullscreen`, `openExternal`, `hid`, `serial`, or `usb`.
|
||||
* `permission` string - Type of permission check.
|
||||
* `clipboard-read` - Request access to read from the clipboard.
|
||||
* `clipboard-sanitized-write` - Request access to write to the clipboard.
|
||||
* `geolocation` - Access the user's geolocation data via the [Geolocation API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API)
|
||||
* `fullscreen` - Control of the app's fullscreen state via the [Fullscreen API](https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API).
|
||||
* `hid` - Access the HID protocol to manipulate HID devices via the [WebHID API](https://developer.mozilla.org/en-US/docs/Web/API/WebHID_API).
|
||||
* `idle-detection` - Access the user's idle state via the [IdleDetector API](https://developer.mozilla.org/en-US/docs/Web/API/IdleDetector).
|
||||
* `media` - Access to media devices such as camera, microphone and speakers.
|
||||
* `mediaKeySystem` - Access to DRM protected content.
|
||||
* `midi` - Enable MIDI access in the [Web MIDI API](https://developer.mozilla.org/en-US/docs/Web/API/Web_MIDI_API).
|
||||
* `midiSysex` - Use system exclusive messages in the [Web MIDI API](https://developer.mozilla.org/en-US/docs/Web/API/Web_MIDI_API).
|
||||
* `notifications` - Configure and display desktop notifications to the user with the [Notifications API](https://developer.mozilla.org/en-US/docs/Web/API/notification).
|
||||
* `openExternal` - Open links in external applications.
|
||||
* `pointerLock` - Directly interpret mouse movements as an input method via the [Pointer Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API). These requests always appear to originate from the main frame.
|
||||
* `serial` - Read from and write to serial devices with the [Web Serial API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Serial_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).
|
||||
* `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.
|
||||
@@ -1097,7 +1113,7 @@ app.whenReady().then(() => {
|
||||
|
||||
* `handler` Function\<string[]> | null
|
||||
* `details` Object
|
||||
* `protectedClasses` string[] - The current list of protected USB classes. Possible class values are:
|
||||
* `protectedClasses` string[] - The current list of protected USB classes. Possible class values include:
|
||||
* `audio`
|
||||
* `audio-video`
|
||||
* `hid`
|
||||
@@ -1177,7 +1193,7 @@ automatically. To clear the handler, call `setBluetoothPairingHandler(null)`.
|
||||
|
||||
```javascript
|
||||
const { app, BrowserWindow, session } = require('electron')
|
||||
const path = require('path')
|
||||
const path = require('node:path')
|
||||
|
||||
function createWindow () {
|
||||
let bluetoothPinCallback = null
|
||||
@@ -1284,16 +1300,18 @@ reused for new connections.
|
||||
|
||||
Returns `Promise<Buffer>` - resolves with blob data.
|
||||
|
||||
#### `ses.downloadURL(url)`
|
||||
#### `ses.downloadURL(url[, options])`
|
||||
|
||||
* `url` string
|
||||
* `options` Object (optional)
|
||||
* `headers` Record<string, string> (optional) - HTTP request headers.
|
||||
|
||||
Initiates a download of the resource at `url`.
|
||||
The API will generate a [DownloadItem](download-item.md) that can be accessed
|
||||
with the [will-download](#event-will-download) event.
|
||||
|
||||
**Note:** This does not perform any security checks that relate to a page's origin,
|
||||
unlike [`webContents.downloadURL`](web-contents.md#contentsdownloadurlurl).
|
||||
unlike [`webContents.downloadURL`](web-contents.md#contentsdownloadurlurl-options).
|
||||
|
||||
#### `ses.createInterruptedDownload(options)`
|
||||
|
||||
@@ -1439,7 +1457,7 @@ extension to be loaded.
|
||||
|
||||
```js
|
||||
const { app, session } = require('electron')
|
||||
const path = require('path')
|
||||
const path = require('node:path')
|
||||
|
||||
app.whenReady().then(async () => {
|
||||
await session.defaultSession.loadExtension(
|
||||
@@ -1473,7 +1491,7 @@ is emitted.
|
||||
|
||||
* `extensionId` string - ID of extension to query
|
||||
|
||||
Returns `Extension` | `null` - The loaded extension with the given ID.
|
||||
Returns `Extension | null` - The loaded extension with the given ID.
|
||||
|
||||
**Note:** This API cannot be called before the `ready` event of the `app` module
|
||||
is emitted.
|
||||
@@ -1526,7 +1544,7 @@ A [`Protocol`](protocol.md) object for this session.
|
||||
|
||||
```javascript
|
||||
const { app, session } = require('electron')
|
||||
const path = require('path')
|
||||
const path = require('node:path')
|
||||
|
||||
app.whenReady().then(() => {
|
||||
const protocol = session.fromPartition('some-partition').protocol
|
||||
|
||||
@@ -140,6 +140,16 @@ Possible values are:
|
||||
|
||||
* On Linux, possible types are `desktop`, `dock`, `toolbar`, `splash`,
|
||||
`notification`.
|
||||
* The `desktop` type places the window at the desktop background window level
|
||||
(kCGDesktopWindowLevel - 1). However, note that a desktop window will not
|
||||
receive focus, keyboard, or mouse events. You can still use globalShortcut to
|
||||
receive input sparingly.
|
||||
* The `dock` type creates a dock-like window behavior.
|
||||
* The `toolbar` type creates a window with a toolbar appearance.
|
||||
* The `splash` type behaves in a specific way. It is not
|
||||
draggable, even if the CSS styling of the window's body contains
|
||||
-webkit-app-region: drag. This type is commonly used for splash screens.
|
||||
* The `notification` type creates a window that behaves like a system notification.
|
||||
* On macOS, possible types are `desktop`, `textured`, `panel`.
|
||||
* The `textured` type adds metal gradient appearance
|
||||
(`NSWindowStyleMaskTexturedBackground`).
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
* `sender` [IpcRenderer](../ipc-renderer.md) - The `IpcRenderer` instance that emitted the event originally
|
||||
* `senderId` Integer - The `webContents.id` that sent the message, you can call `event.sender.sendTo(event.senderId, ...)` to reply to the message, see [ipcRenderer.sendTo][ipc-renderer-sendto] for more information. This only applies to messages sent from a different renderer. Messages sent directly from the main process set `event.senderId` to `0`.
|
||||
* `senderIsMainFrame` boolean (optional) - Whether the message sent via [ipcRenderer.sendTo][ipc-renderer-sendto] was sent by the main frame. This is relevant when `nodeIntegrationInSubFrames` is enabled in the originating `webContents`.
|
||||
* `ports` [MessagePort][][] - A list of MessagePorts that were transferred with this message
|
||||
|
||||
[ipc-renderer-sendto]: ../ipc-renderer.md#ipcrenderersendtowebcontentsid-channel-args
|
||||
|
||||
13
docs/api/structures/render-process-gone-details.md
Normal file
13
docs/api/structures/render-process-gone-details.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# RenderProcessGoneDetails Object
|
||||
|
||||
* `reason` string - The reason the render process is gone. Possible values:
|
||||
* `clean-exit` - Process exited with an exit code of zero
|
||||
* `abnormal-exit` - Process exited with a non-zero exit code
|
||||
* `killed` - Process was sent a SIGTERM or otherwise killed externally
|
||||
* `crashed` - Process crashed
|
||||
* `oom` - Process ran out of memory
|
||||
* `launch-failed` - Process never successfully launched
|
||||
* `integrity-failure` - Windows code integrity checks failed
|
||||
* `exitCode` Integer - The exit code of the process, unless `reason` is
|
||||
`launch-failed`, in which case `exitCode` will be a platform-specific
|
||||
launch failure error code.
|
||||
@@ -6,7 +6,7 @@ Process: [Main](../glossary.md#main-process)
|
||||
|
||||
```javascript
|
||||
const { systemPreferences } = require('electron')
|
||||
console.log(systemPreferences.isDarkMode())
|
||||
console.log(systemPreferences.isAeroGlassEnabled())
|
||||
```
|
||||
|
||||
## Events
|
||||
@@ -47,12 +47,6 @@ Returns:
|
||||
|
||||
## Methods
|
||||
|
||||
### `systemPreferences.isDarkMode()` _macOS_ _Windows_ _Deprecated_
|
||||
|
||||
Returns `boolean` - Whether the system is in Dark Mode.
|
||||
|
||||
**Deprecated:** Should use the new [`nativeTheme.shouldUseDarkColors`](native-theme.md#nativethemeshouldusedarkcolors-readonly) API.
|
||||
|
||||
### `systemPreferences.isSwipeTrackingFromScrollEventsEnabled()` _macOS_
|
||||
|
||||
Returns `boolean` - Whether the Swipe between pages setting is on.
|
||||
@@ -297,7 +291,7 @@ This API is only available on macOS 10.14 Mojave or newer.
|
||||
* `window-frame` - Window frame.
|
||||
* `window-text` - Text in windows.
|
||||
* On **macOS**
|
||||
* `alternate-selected-control-text` - The text on a selected surface in a list or table. _deprecated_
|
||||
* `alternate-selected-control-text` - The text on a selected surface in a list or table. _Deprecated_
|
||||
* `control-background` - The background of a large interface element, such as a browser or table.
|
||||
* `control` - The surface of a control.
|
||||
* `control-text` -The text of a control that isn’t disabled.
|
||||
@@ -356,18 +350,6 @@ Returns `string` - The standard system color formatted as `#RRGGBBAA`.
|
||||
|
||||
Returns one of several standard system colors that automatically adapt to vibrancy and changes in accessibility settings like 'Increase contrast' and 'Reduce transparency'. See [Apple Documentation](https://developer.apple.com/design/human-interface-guidelines/macos/visual-design/color#system-colors) for more details.
|
||||
|
||||
### `systemPreferences.isInvertedColorScheme()` _Windows_ _Deprecated_
|
||||
|
||||
Returns `boolean` - `true` if an inverted color scheme (a high contrast color scheme with light text and dark backgrounds) is active, `false` otherwise.
|
||||
|
||||
**Deprecated:** Should use the new [`nativeTheme.shouldUseInvertedColorScheme`](native-theme.md#nativethemeshoulduseinvertedcolorscheme-macos-windows-readonly) API.
|
||||
|
||||
### `systemPreferences.isHighContrastColorScheme()` _macOS_ _Windows_ _Deprecated_
|
||||
|
||||
Returns `boolean` - `true` if a high contrast theme is active, `false` otherwise.
|
||||
|
||||
**Deprecated:** Should use the new [`nativeTheme.shouldUseHighContrastColors`](native-theme.md#nativethemeshouldusehighcontrastcolors-macos-windows-readonly) API.
|
||||
|
||||
### `systemPreferences.getEffectiveAppearance()` _macOS_
|
||||
|
||||
Returns `string` - Can be `dark`, `light` or `unknown`.
|
||||
@@ -453,7 +435,11 @@ Returns an object with system animation settings.
|
||||
|
||||
## Properties
|
||||
|
||||
### `systemPreferences.appLevelAppearance` _macOS_
|
||||
### `systemPreferences.accessibilityDisplayShouldReduceTransparency()` _macOS_
|
||||
|
||||
A `boolean` property which determines whether the app avoids using semitransparent backgrounds. This maps to [NSWorkspace.accessibilityDisplayShouldReduceTransparency](https://developer.apple.com/documentation/appkit/nsworkspace/1533006-accessibilitydisplayshouldreduce)
|
||||
|
||||
### `systemPreferences.appLevelAppearance` _macOS_ _Deprecated_
|
||||
|
||||
A `string` property that can be `dark`, `light` or `unknown`. It determines the macOS appearance setting for
|
||||
your application. This maps to values in: [NSApplication.appearance](https://developer.apple.com/documentation/appkit/nsapplication/2967170-appearance?language=objc). Setting this will override the
|
||||
|
||||
@@ -239,9 +239,8 @@ Returns:
|
||||
|
||||
* `details` Event<>
|
||||
* `url` string - The URL the frame is navigating to.
|
||||
* `isSameDocument` boolean - Whether the navigation happened without changing
|
||||
document. Examples of same document navigations are reference fragment
|
||||
navigations, pushState/replaceState, and same page history navigation.
|
||||
* `isSameDocument` boolean - This event does not fire for same document navigations using window.history api and reference fragment navigations.
|
||||
This property is always set to `false` for this event.
|
||||
* `isMainFrame` boolean - True if the navigation is taking place in a main frame.
|
||||
* `frame` WebFrameMain - The frame to be navigated.
|
||||
* `initiator` WebFrameMain (optional) - The frame which initiated the
|
||||
@@ -273,6 +272,8 @@ Returns:
|
||||
|
||||
* `details` Event<>
|
||||
* `url` string - The URL the frame is navigating to.
|
||||
* `isSameDocument` boolean - This event does not fire for same document navigations using window.history api and reference fragment navigations.
|
||||
This property is always set to `false` for this event.
|
||||
* `isMainFrame` boolean - True if the navigation is taking place in a main frame.
|
||||
* `frame` WebFrameMain - The frame to be navigated.
|
||||
* `initiator` WebFrameMain (optional) - The frame which initiated the
|
||||
@@ -478,18 +479,7 @@ checking `reason === 'killed'` when you switch to that event.
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `details` Object
|
||||
* `reason` string - The reason the render process is gone. Possible values:
|
||||
* `clean-exit` - Process exited with an exit code of zero
|
||||
* `abnormal-exit` - Process exited with a non-zero exit code
|
||||
* `killed` - Process was sent a SIGTERM or otherwise killed externally
|
||||
* `crashed` - Process crashed
|
||||
* `oom` - Process ran out of memory
|
||||
* `launch-failed` - Process never successfully launched
|
||||
* `integrity-failure` - Windows code integrity checks failed
|
||||
* `exitCode` Integer - The exit code of the process, unless `reason` is
|
||||
`launch-failed`, in which case `exitCode` will be a platform-specific
|
||||
launch failure error code.
|
||||
* `details` [RenderProcessGoneDetails](structures/render-process-gone-details.md)
|
||||
|
||||
Emitted when the renderer process unexpectedly disappears. This is normally
|
||||
because it was crashed or killed.
|
||||
@@ -794,7 +784,7 @@ Returns:
|
||||
* `frameCharset` string - The character encoding of the frame on which the
|
||||
menu was invoked.
|
||||
* `inputFieldType` string - If the context menu was invoked on an input
|
||||
field, the type of that field. Possible values are `none`, `plainText`,
|
||||
field, the type of that field. Possible values include `none`, `plainText`,
|
||||
`password`, `other`.
|
||||
* `spellcheckEnabled` boolean - If the context is editable, whether or not spellchecking is enabled.
|
||||
* `menuSourceType` string - Input source that invoked the context menu.
|
||||
@@ -1056,9 +1046,11 @@ const win = new BrowserWindow()
|
||||
win.loadFile('src/index.html')
|
||||
```
|
||||
|
||||
#### `contents.downloadURL(url)`
|
||||
#### `contents.downloadURL(url[, options])`
|
||||
|
||||
* `url` string
|
||||
* `options` Object (optional)
|
||||
* `headers` Record<string, string> (optional) - HTTP request headers.
|
||||
|
||||
Initiates a download of the resource at `url` without navigating. The
|
||||
`will-download` event of `session` will be triggered.
|
||||
@@ -1219,7 +1211,7 @@ Returns `string` - The user agent for this web page.
|
||||
|
||||
* `css` string
|
||||
* `options` Object (optional)
|
||||
* `cssOrigin` string (optional) - Can be either 'user' or 'author'. Sets the [cascade origin](https://www.w3.org/TR/css3-cascade/#cascade-origin) of the inserted stylesheet. Default is 'author'.
|
||||
* `cssOrigin` string (optional) - Can be 'user' or 'author'. Sets the [cascade origin](https://www.w3.org/TR/css3-cascade/#cascade-origin) of the inserted stylesheet. Default is 'author'.
|
||||
|
||||
Returns `Promise<string>` - A promise that resolves with a key for the inserted CSS that can later be used to remove the CSS via `contents.removeInsertedCSS(key)`.
|
||||
|
||||
@@ -1466,11 +1458,11 @@ For a call of `win.webContents.adjustSelection({ start: 1, end: 5 })`
|
||||
|
||||
Before:
|
||||
|
||||
<img width="487" alt="Image Before Text Selection Adjustment" src="https://user-images.githubusercontent.com/2036040/231761306-cd4e7b15-c2ed-46cf-8e80-10811f6de83e.png">
|
||||
<img width="487" alt="Image Before Text Selection Adjustment" src="../images/web-contents-text-selection-before.png"/>
|
||||
|
||||
After:
|
||||
|
||||
<img width="487" alt="Image After Text Selection Adjustment" src="https://user-images.githubusercontent.com/2036040/231761169-887eb8ef-06fb-46e4-9efa-898bcb0d6a2b.png">
|
||||
<img width="487" alt="Image After Text Selection Adjustment" src="../images/web-contents-text-selection-after.png"/>
|
||||
|
||||
#### `contents.replace(text)`
|
||||
|
||||
@@ -1645,9 +1637,9 @@ An example of `webContents.printToPDF`:
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const os = require('os')
|
||||
const fs = require('node:fs')
|
||||
const path = require('node:path')
|
||||
const os = require('node:os')
|
||||
|
||||
const win = new BrowserWindow()
|
||||
win.loadURL('http://github.com')
|
||||
|
||||
@@ -113,7 +113,7 @@ webFrame.setSpellCheckProvider('en-US', {
|
||||
|
||||
* `css` string
|
||||
* `options` Object (optional)
|
||||
* `cssOrigin` string (optional) - Can be either 'user' or 'author'. Sets the [cascade origin](https://www.w3.org/TR/css3-cascade/#cascade-origin) of the inserted stylesheet. Default is 'author'.
|
||||
* `cssOrigin` string (optional) - Can be 'user' or 'author'. Sets the [cascade origin](https://www.w3.org/TR/css3-cascade/#cascade-origin) of the inserted stylesheet. Default is 'author'.
|
||||
|
||||
Returns `string` - A key for the inserted CSS that can later be used to remove
|
||||
the CSS via `webFrame.removeInsertedCSS(key)`.
|
||||
|
||||
@@ -280,9 +280,11 @@ if the page fails to load (see
|
||||
Loads the `url` in the webview, the `url` must contain the protocol prefix,
|
||||
e.g. the `http://` or `file://`.
|
||||
|
||||
### `<webview>.downloadURL(url)`
|
||||
### `<webview>.downloadURL(url[, options])`
|
||||
|
||||
* `url` string
|
||||
* `options` Object (optional)
|
||||
* `headers` Record<string, string> (optional) - HTTP request headers.
|
||||
|
||||
Initiates a download of the resource at `url` without navigating.
|
||||
|
||||
@@ -983,9 +985,22 @@ ipcRenderer.on('ping', () => {
|
||||
})
|
||||
```
|
||||
|
||||
### Event: 'crashed'
|
||||
### Event: 'crashed' _Deprecated_
|
||||
|
||||
Fired when the renderer process is crashed.
|
||||
Fired when the renderer process crashes or is killed.
|
||||
|
||||
**Deprecated:** This event is superceded by the `render-process-gone` event
|
||||
which contains more information about why the render process disappeared. It
|
||||
isn't always because it crashed.
|
||||
|
||||
### Event: 'render-process-gone'
|
||||
|
||||
Returns:
|
||||
|
||||
* `details` [RenderProcessGoneDetails](structures/render-process-gone-details.md)
|
||||
|
||||
Fired when the renderer process unexpectedly disappears. This is normally
|
||||
because it was crashed or killed.
|
||||
|
||||
### Event: 'plugin-crashed'
|
||||
|
||||
@@ -1091,7 +1106,7 @@ Returns:
|
||||
* `frameCharset` string - The character encoding of the frame on which the
|
||||
menu was invoked.
|
||||
* `inputFieldType` string - If the context menu was invoked on an input
|
||||
field, the type of that field. Possible values are `none`, `plainText`,
|
||||
field, the type of that field. Possible values include `none`, `plainText`,
|
||||
`password`, `other`.
|
||||
* `spellcheckEnabled` boolean - If the context is editable, whether or not spellchecking is enabled.
|
||||
* `menuSourceType` string - Input source that invoked the context menu.
|
||||
|
||||
@@ -59,7 +59,7 @@ window.open('https://github.com', '_blank', 'top=500,left=200,frame=false,nodeIn
|
||||
* Non-standard features (that are not handled by Chromium or Electron) given in
|
||||
`features` will be passed to any registered `webContents`'s
|
||||
`did-create-window` event handler in the `options` argument.
|
||||
* `frameName` follows the specification of `windowName` located in the [native documentation](https://developer.mozilla.org/en-US/docs/Web/API/Window/open#parameters).
|
||||
* `frameName` follows the specification of `target` located in the [native documentation](https://developer.mozilla.org/en-US/docs/Web/API/Window/open#parameters).
|
||||
* When opening `about:blank`, the child window's [`WebPreferences`](structures/web-preferences.md) will be copied
|
||||
from the parent window, and there is no way to override it because Chromium
|
||||
skips browser side navigation in this case.
|
||||
|
||||
@@ -12,6 +12,68 @@ This document uses the following convention to categorize breaking changes:
|
||||
* **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
|
||||
* **Removed:** An API or feature was removed, and is no longer supported by Electron.
|
||||
|
||||
## Planned Breaking API Changes (27.0)
|
||||
|
||||
### Removed: macOS 10.13 / 10.14 support
|
||||
|
||||
macOS 10.13 (High Sierra) and macOS 10.14 (Mojave) are no longer supported by [Chromium](https://chromium-review.googlesource.com/c/chromium/src/+/4629466).
|
||||
|
||||
Older versions of Electron will continue to run on these operating systems, but macOS 10.15 (Catalina)
|
||||
or later will be required to run Electron v27.0.0 and higher.
|
||||
|
||||
## Planned Breaking API Changes (26.0)
|
||||
|
||||
### Deprecated: `webContents.getPrinters`
|
||||
|
||||
The `webContents.getPrinters` method has been deprecated. Use
|
||||
`webContents.getPrintersAsync` instead.
|
||||
|
||||
```js
|
||||
const w = new BrowserWindow({ show: false })
|
||||
|
||||
// Deprecated
|
||||
console.log(w.webContents.getPrinters())
|
||||
// Replace with
|
||||
w.webContents.getPrintersAsync().then((printers) => {
|
||||
console.log(printers)
|
||||
})
|
||||
```
|
||||
|
||||
### Deprecated: `systemPreferences.{get,set}AppLevelAppearance` and `systemPreferences.appLevelAppearance`
|
||||
|
||||
The `systemPreferences.getAppLevelAppearance` and `systemPreferences.setAppLevelAppearance`
|
||||
methods have been deprecated, as well as the `systemPreferences.appLevelAppearance` property.
|
||||
Use the `nativeTheme` module instead.
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
systemPreferences.getAppLevelAppearance()
|
||||
// Replace with
|
||||
nativeTheme.shouldUseDarkColors
|
||||
|
||||
// Deprecated
|
||||
systemPreferences.appLevelAppearance
|
||||
// Replace with
|
||||
nativeTheme.shouldUseDarkColors
|
||||
|
||||
// Deprecated
|
||||
systemPreferences.setAppLevelAppearance('dark')
|
||||
// Replace with
|
||||
nativeTheme.themeSource = 'dark'
|
||||
```
|
||||
|
||||
### Deprecated: `alternate-selected-control-text` value for `systemPreferences.getColor`
|
||||
|
||||
The `alternate-selected-control-text` value for `systemPreferences.getColor`
|
||||
has been deprecated. Use `selected-content-background` instead.
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
systemPreferences.getColor('alternate-selected-control-text')
|
||||
// Replace with
|
||||
systemPreferences.getColor('selected-content-background')
|
||||
```
|
||||
|
||||
## Planned Breaking API Changes (25.0)
|
||||
|
||||
### Deprecated: `protocol.{register,intercept}{Buffer,String,Stream,File,Http}Protocol`
|
||||
@@ -533,6 +595,18 @@ to open synchronously scriptable child windows, among other incompatibilities.
|
||||
See the documentation for [window.open in Electron](api/window-open.md)
|
||||
for more details.
|
||||
|
||||
### Deprecated: `app.runningUnderRosettaTranslation`
|
||||
|
||||
The `app.runningUnderRosettaTranslation` property has been deprecated.
|
||||
Use `app.runningUnderARM64Translation` instead.
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
console.log(app.runningUnderRosettaTranslation)
|
||||
// Replace with
|
||||
console.log(app.runningUnderARM64Translation)
|
||||
```
|
||||
|
||||
## Planned Breaking API Changes (14.0)
|
||||
|
||||
### Removed: `remote` module
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
# Updating an Appveyor Azure Image
|
||||
|
||||
Electron CI on Windows uses AppVeyor, which in turn uses Azure VM images to run. Occasionally, these VM images need to be updated due to changes in Chromium requirements. In order to update you will need [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell?view=powershell-7.3&viewFallbackFrom=powershell-6) and the [Azure PowerShell module](https://learn.microsoft.com/en-us/powershell/azure/install-az-ps?view=azps-9.5.0&viewFallbackFrom=azps-1.8.0).
|
||||
|
||||
Occasionally we need to update these images owing to changes in Chromium or other miscellaneous build requirement changes.
|
||||
|
||||
Example Use Case:
|
||||
* We need `VS15.9` and we have `VS15.7` installed; this would require us to update an Azure image.
|
||||
|
||||
1. Identify the image you wish to modify.
|
||||
* In [appveyor.yml](https://github.com/electron/electron/blob/main/appveyor.yml), the image is identified by the property _image_.
|
||||
* The names used correspond to the _"images"_ defined for a build cloud, eg the [libcc-20 cloud](https://windows-ci.electronjs.org/build-clouds/8).
|
||||
* Find the image you wish to modify in the build cloud and make note of the **VHD Blob Path** for that image, which is the value for that corresponding key.
|
||||
* You will need this URI path to copy into a new image.
|
||||
* You will also need the storage account name which is labeled in AppVeyor as the **Disk Storage Account Name**
|
||||
|
||||
2. Get the Azure storage account key
|
||||
* Log into Azure using credentials stored in LastPass (under Azure Enterprise) and then find the storage account corresponding to the name found in AppVeyor.
|
||||
* Example, for `appveyorlibccbuilds` **Disk Storage Account Name** you'd look for `appveyorlibccbuilds` in the list of storage accounts @ Home < Storage Accounts
|
||||
* Click into it and look for `Access Keys`, and then you can use any of the keys present in the list.
|
||||
|
||||
3. Get the full virtual machine image URI from Azure
|
||||
* Navigate to Home < Storage Accounts < `$ACCT_NAME` < Blobs < Images
|
||||
* In the following list, look for the VHD path name you got from Appveyor and then click on it.
|
||||
* Copy the whole URL from the top of the subsequent window.
|
||||
|
||||
4. Copy the image using the [Copy Master Image PowerShell script](https://github.com/appveyor/ci/blob/master/scripts/enterprise/copy-master-image-azure.ps1).
|
||||
* It is essential to copy the VM because if you spin up a VM against an image that image cannot at the same time be used by AppVeyor.
|
||||
* Use the storage account name, key, and URI obtained from Azure to run this script.
|
||||
* See Step 3 for URI & when prompted, press enter to use same storage account as destination.
|
||||
* Use default destination container name `(images)`
|
||||
* Also, when naming the copy, use a name that indicates what the new image will contain (if that has changed) and date stamp.
|
||||
* Ex. `libcc-20core-vs2017-15.9-2019-04-15.vhd`
|
||||
* Go into Azure and get the URI for the newly created image as described in a previous step
|
||||
|
||||
5. Spin up a new VM using the [Create Master VM from VHD PowerShell](https://github.com/appveyor/ci/blob/master/scripts/enterprise/create_master_vm_from_vhd.ps1).
|
||||
* From PowerShell, execute `ps1` file with `./create_master_vm_from_vhd.ps1`
|
||||
* You will need the credential information available in the AppVeyor build cloud definition.
|
||||
* This includes:
|
||||
* Client ID
|
||||
* Client Secret
|
||||
* Tenant ID
|
||||
* Subscription ID
|
||||
* Resource Group
|
||||
* Virtual Network
|
||||
* You will also need to specify
|
||||
* Master VM name - just a unique name to identify the temporary VM
|
||||
* Master VM size - use `Standard_F32s_v2`
|
||||
* Master VHD URI - use URI obtained @ end of previous step
|
||||
* Location use `East US`
|
||||
|
||||
6. Log back into Azure and find the VM you just created in Home < Virtual Machines < `$YOUR_NEW_VM`
|
||||
* You can download a RDP (Remote Desktop) file to access the VM.
|
||||
|
||||
7. Using Microsoft Remote Desktop, click `Connect` to connect to the VM.
|
||||
* Credentials for logging into the VM are found in LastPass under the `AppVeyor Enterprise master VM` credentials.
|
||||
|
||||
8. Modify the VM as required.
|
||||
|
||||
9. Shut down the VM and then delete it in Azure.
|
||||
|
||||
10. Add the new image to the Appveyor Cloud settings or modify an existing image to point to the new VHD.
|
||||
BIN
docs/images/web-contents-text-selection-after.png
Normal file
BIN
docs/images/web-contents-text-selection-after.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
BIN
docs/images/web-contents-text-selection-before.png
Normal file
BIN
docs/images/web-contents-text-selection-before.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
@@ -42,14 +42,14 @@ $ asar list /path/to/example.asar
|
||||
Read a file in the ASAR archive:
|
||||
|
||||
```javascript
|
||||
const fs = require('fs')
|
||||
const fs = require('node:fs')
|
||||
fs.readFileSync('/path/to/example.asar/file.txt')
|
||||
```
|
||||
|
||||
List all files under the root of the archive:
|
||||
|
||||
```javascript
|
||||
const fs = require('fs')
|
||||
const fs = require('node:fs')
|
||||
fs.readdirSync('/path/to/example.asar')
|
||||
```
|
||||
|
||||
@@ -99,7 +99,7 @@ You can also set `process.noAsar` to `true` to disable the support for `asar` in
|
||||
the `fs` module:
|
||||
|
||||
```javascript
|
||||
const fs = require('fs')
|
||||
const fs = require('node:fs')
|
||||
process.noAsar = true
|
||||
fs.readFileSync('/path/to/example.asar')
|
||||
```
|
||||
|
||||
@@ -41,7 +41,9 @@ Valid `algorithm` values are currently `SHA256` only. The `hash` is a hash of t
|
||||
ASAR integrity checking is currently disabled by default and can be enabled by toggling a fuse. See [Electron Fuses](fuses.md) for more information on what Electron Fuses are and how they work. When enabling this fuse you typically also want to enable the `onlyLoadAppFromAsar` fuse otherwise the validity checking can be bypassed via the Electron app code search path.
|
||||
|
||||
```js @ts-nocheck
|
||||
require('@electron/fuses').flipFuses(
|
||||
const { flipFuses, FuseVersion, FuseV1Options } = require('@electron/fuses')
|
||||
|
||||
flipFuses(
|
||||
// E.g. /a/b/Foo.app
|
||||
pathToPackagedApp,
|
||||
{
|
||||
|
||||
@@ -260,7 +260,7 @@ To create a custom driver, we'll use Node.js' [`child_process`](https://nodejs.o
|
||||
The test suite will spawn the Electron process, then establish a simple messaging protocol:
|
||||
|
||||
```js title='testDriver.js' @ts-nocheck
|
||||
const childProcess = require('child_process')
|
||||
const childProcess = require('node:child_process')
|
||||
const electronPath = require('electron')
|
||||
|
||||
// spawn the process
|
||||
|
||||
@@ -136,7 +136,7 @@ Finally, the `main.js` file represents the main process and contains the actual
|
||||
|
||||
```js
|
||||
const { app, BrowserWindow, ipcMain, nativeTheme } = require('electron')
|
||||
const path = require('path')
|
||||
const path = require('node:path')
|
||||
|
||||
const createWindow = () => {
|
||||
const win = new BrowserWindow({
|
||||
|
||||
@@ -35,8 +35,8 @@ Using the [React Developer Tools][react-devtools] as an example:
|
||||
|
||||
```javascript
|
||||
const { app, session } = require('electron')
|
||||
const path = require('path')
|
||||
const os = require('os')
|
||||
const path = require('node:path')
|
||||
const os = require('node:os')
|
||||
|
||||
// on macOS
|
||||
const reactDevToolsPath = path.join(
|
||||
|
||||
@@ -9,10 +9,11 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
|
||||
|
||||
| Electron | Alpha | Beta | Stable | EOL | Chrome | Node | Supported |
|
||||
| ------- | ----- | ------- | ------ | ------ | ---- | ---- | ---- |
|
||||
| 26.0.0 | 2023-Jun-01 | 2023-Jun-27 | 2023-Aug-08 | TBD | M116 | TBD | ✅ |
|
||||
| 25.0.0 | 2023-Apr-10 | 2023-May-02 | 2023-May-30 | 2023-Dec-05 | M114 | TBD | ✅ |
|
||||
| 24.0.0 | 2022-Feb-09 | 2023-Mar-07 | 2023-Apr-04 | 2023-Oct-03 | M112 | v18.14 | ✅ |
|
||||
| 23.0.0 | 2022-Dec-01 | 2023-Jan-10 | 2023-Feb-07 | 2023-Aug-08 | M110 | v18.12 | ✅ |
|
||||
| 27.0.0 | 2023-Aug-17 | 2023-Sep-13 | 2023-Oct-10 | TBD | M118 | TBD | ✅ |
|
||||
| 26.0.0 | 2023-Jun-01 | 2023-Jun-27 | 2023-Aug-15 | 2024-Feb-27 | M116 | v18.16 | ✅ |
|
||||
| 25.0.0 | 2023-Apr-10 | 2023-May-02 | 2023-May-30 | 2024-Jan-02 | M114 | v18.15 | ✅ |
|
||||
| 24.0.0 | 2023-Feb-09 | 2023-Mar-07 | 2023-Apr-04 | 2023-Oct-10 | M112 | v18.14 | ✅ |
|
||||
| 23.0.0 | 2022-Dec-01 | 2023-Jan-10 | 2023-Feb-07 | 2023-Aug-15 | M110 | v18.12 | 🚫 |
|
||||
| 22.0.0 | 2022-Sep-29 | 2022-Oct-25 | 2022-Nov-29 | 2023-Oct-10 | M108 | v16.17 | ✅ |
|
||||
| 21.0.0 | 2022-Aug-04 | 2022-Aug-30 | 2022-Sep-27 | 2023-Apr-04 | M106 | v16.16 | 🚫 |
|
||||
| 20.0.0 | 2022-May-26 | 2022-Jun-21 | 2022-Aug-02 | 2023-Feb-07 | M104 | v16.15 | 🚫 |
|
||||
|
||||
@@ -4,15 +4,48 @@ Electron Forge is a tool for packaging and publishing Electron applications.
|
||||
It unifies Electron's build tooling ecosystem into
|
||||
a single extensible interface so that anyone can jump right into making Electron apps.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Alternative tooling</summary>
|
||||
|
||||
If you do not want to use Electron Forge for your project, there are other
|
||||
third-party tools you can use to distribute your app.
|
||||
|
||||
These tools are maintained by members of the Electron community,
|
||||
and do not come with official support from the Electron project.
|
||||
|
||||
**Electron Builder**
|
||||
|
||||
A "complete solution to package and build a ready-for-distribution Electron app"
|
||||
that focuses on an integrated experience. [`electron-builder`](https://github.com/electron-userland/electron-builder) adds a single dependency and manages all further requirements internally.
|
||||
|
||||
`electron-builder` replaces features and modules used by the Electron
|
||||
maintainers (such as the auto-updater) with custom ones.
|
||||
|
||||
**Hydraulic Conveyor**
|
||||
|
||||
A [desktop app deployment tool](https://hydraulic.dev) that supports
|
||||
cross-building/signing of all packages from any OS without the need for
|
||||
multi-platform CI, can do synchronous web-style updates on each start
|
||||
of the app, requires no code changes, can use plain HTTP servers for updates and
|
||||
which focuses on ease of use. Conveyor replaces the Electron auto-updaters
|
||||
with Sparkle on macOS, MSIX on Windows, and Linux package repositories.
|
||||
|
||||
Conveyor is a commercial tool that is free for open source projects. There's
|
||||
an example of [how to package GitHub Desktop](https://hydraulic.dev/blog/8-packaging-electron-apps.html)
|
||||
which can be used for learning.
|
||||
|
||||
</details>
|
||||
|
||||
## Getting started
|
||||
|
||||
The [Electron Forge docs][] contain detailed information on taking your application
|
||||
from source code to your end users' machines.
|
||||
This includes:
|
||||
|
||||
* Packaging your application [(package)][]
|
||||
* Generating executables and installers for each OS [(make)][], and,
|
||||
* Publishing these files to online platforms to download [(publish)][].
|
||||
- Packaging your application [(package)][]
|
||||
- Generating executables and installers for each OS [(make)][], and,
|
||||
- Publishing these files to online platforms to download [(publish)][].
|
||||
|
||||
For beginners, we recommend following through Electron's [tutorial][] to develop, build,
|
||||
package and publish your first Electron app. If you have already developed an app on your machine
|
||||
@@ -20,11 +53,11 @@ and want to start on packaging and distribution, start from [step 5][] of the tu
|
||||
|
||||
## Getting help
|
||||
|
||||
* If you need help with developing your app, our [community Discord server][discord] is a great place
|
||||
to get advice from other Electron app developers.
|
||||
* If you suspect you're running into a bug with Forge, please check the [GitHub issue tracker][]
|
||||
to see if any existing issues match your problem. If not, feel free to fill out our bug report
|
||||
template and submit a new issue.
|
||||
- If you need help with developing your app, our [community Discord server][discord] is a great place
|
||||
to get advice from other Electron app developers.
|
||||
- If you suspect you're running into a bug with Forge, please check the [GitHub issue tracker][]
|
||||
to see if any existing issues match your problem. If not, feel free to fill out our bug report
|
||||
template and submit a new issue.
|
||||
|
||||
[Electron Forge Docs]: https://www.electronforge.io/
|
||||
[step 5]: ./tutorial-5-packaging.md
|
||||
|
||||
@@ -68,7 +68,9 @@ The loadBrowserProcessSpecificV8Snapshot fuse changes which V8 snapshot file is
|
||||
We've made a handy module, [`@electron/fuses`](https://npmjs.com/package/@electron/fuses), to make flipping these fuses easy. Check out the README of that module for more details on usage and potential error cases.
|
||||
|
||||
```js @ts-nocheck
|
||||
require('@electron/fuses').flipFuses(
|
||||
const { flipFuses, FuseVersion, FuseV1Options } = require('@electron/fuses')
|
||||
|
||||
flipFuses(
|
||||
// Path to electron
|
||||
require('electron'),
|
||||
// Fuses to flip
|
||||
@@ -82,7 +84,7 @@ require('@electron/fuses').flipFuses(
|
||||
You can validate the fuses have been flipped or check the fuse status of an arbitrary Electron app using the fuses CLI.
|
||||
|
||||
```bash
|
||||
npx @electron/fuses read --app /Applications/Foo.app
|
||||
npx @electron/fuses read --app /Applications/Foo.app
|
||||
```
|
||||
|
||||
### The hard way
|
||||
|
||||
@@ -52,7 +52,7 @@ In the main process, set an IPC listener on the `set-title` channel with the `ip
|
||||
|
||||
```javascript {6-10,22} title='main.js (Main Process)'
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
const path = require('path')
|
||||
const path = require('node:path')
|
||||
|
||||
// ...
|
||||
|
||||
@@ -183,7 +183,7 @@ provided to the renderer process. Please refer to
|
||||
|
||||
```javascript {6-13,25} title='main.js (Main Process)'
|
||||
const { app, BrowserWindow, dialog, ipcMain } = require('electron')
|
||||
const path = require('path')
|
||||
const path = require('node:path')
|
||||
|
||||
// ...
|
||||
|
||||
@@ -378,7 +378,7 @@ target renderer.
|
||||
|
||||
```javascript {11-26} title='main.js (Main Process)'
|
||||
const { app, BrowserWindow, Menu, ipcMain } = require('electron')
|
||||
const path = require('path')
|
||||
const path = require('node:path')
|
||||
|
||||
function createWindow () {
|
||||
const mainWindow = new BrowserWindow({
|
||||
|
||||
@@ -27,7 +27,7 @@ control our application lifecycle and create a native browser window.
|
||||
|
||||
```javascript
|
||||
const { app, BrowserWindow, shell } = require('electron')
|
||||
const path = require('path')
|
||||
const path = require('node:path')
|
||||
```
|
||||
|
||||
Next, we will proceed to register our application to handle all "`electron-fiddle://`" protocols.
|
||||
@@ -63,9 +63,9 @@ const createWindow = () => {
|
||||
|
||||
In this next step, we will create our `BrowserWindow` and tell our application how to handle an event in which an external protocol is clicked.
|
||||
|
||||
This code will be different in Windows compared to MacOS and Linux. This is due to Windows requiring additional code in order to open the contents of the protocol link within the same Electron instance. Read more about this [here](../api/app.md#apprequestsingleinstancelockadditionaldata).
|
||||
This code will be different in Windows and Linux compared to MacOS. This is due to both platforms emitting the `second-instance` event rather than the `open-url` event and Windows requiring additional code in order to open the contents of the protocol link within the same Electron instance. Read more about this [here](../api/app.md#apprequestsingleinstancelockadditionaldata).
|
||||
|
||||
#### Windows code:
|
||||
#### Windows and Linux code:
|
||||
|
||||
```javascript @ts-type={mainWindow:Electron.BrowserWindow} @ts-type={createWindow:()=>void}
|
||||
const gotTheLock = app.requestSingleInstanceLock()
|
||||
@@ -80,8 +80,7 @@ if (!gotTheLock) {
|
||||
mainWindow.focus()
|
||||
}
|
||||
// the commandLine is array of strings in which last element is deep link url
|
||||
// the url str ends with /
|
||||
dialog.showErrorBox('Welcome Back', `You arrived from: ${commandLine.pop().slice(0, -1)}`)
|
||||
dialog.showErrorBox('Welcome Back', `You arrived from: ${commandLine.pop()}`)
|
||||
})
|
||||
|
||||
// Create mainWindow, load the rest of the app, etc...
|
||||
@@ -91,7 +90,7 @@ if (!gotTheLock) {
|
||||
}
|
||||
```
|
||||
|
||||
#### MacOS and Linux code:
|
||||
#### MacOS code:
|
||||
|
||||
```javascript @ts-type={createWindow:()=>void}
|
||||
// This method will be called when Electron has finished
|
||||
|
||||
@@ -150,7 +150,7 @@ renderer.
|
||||
|
||||
```js title='renderer.js (Renderer Process)' @ts-nocheck
|
||||
// elsewhere in your code to send a message to the other renderers message handler
|
||||
window.electronMessagePort.postmessage('ping')
|
||||
window.electronMessagePort.postMessage('ping')
|
||||
```
|
||||
|
||||
### Worker process
|
||||
@@ -303,7 +303,7 @@ without having to step through the isolated world.
|
||||
|
||||
```js title='main.js (Main Process)'
|
||||
const { BrowserWindow, app, MessageChannelMain } = require('electron')
|
||||
const path = require('path')
|
||||
const path = require('node:path')
|
||||
|
||||
app.whenReady().then(async () => {
|
||||
// Create a BrowserWindow with contextIsolation enabled.
|
||||
|
||||
@@ -22,7 +22,7 @@ In `preload.js` use the [`contextBridge`][] to inject a method `window.electron.
|
||||
|
||||
```js
|
||||
const { contextBridge, ipcRenderer } = require('electron')
|
||||
const path = require('path')
|
||||
const path = require('node:path')
|
||||
|
||||
contextBridge.exposeInMainWorld('electron', {
|
||||
startDrag: (fileName) => {
|
||||
|
||||
@@ -41,7 +41,7 @@ To enable this mode, GPU acceleration has to be disabled by calling the
|
||||
|
||||
```javascript fiddle='docs/fiddles/features/offscreen-rendering'
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const fs = require('fs')
|
||||
const fs = require('node:fs')
|
||||
|
||||
app.disableHardwareAcceleration()
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ equally fictitious `foo-parser` module. In traditional Node.js development,
|
||||
you might write code that eagerly loads dependencies:
|
||||
|
||||
```js title='parser.js' @ts-expect-error=[2]
|
||||
const fs = require('fs')
|
||||
const fs = require('node:fs')
|
||||
const fooParser = require('foo-parser')
|
||||
|
||||
class Parser {
|
||||
@@ -197,7 +197,7 @@ do this work a little later, when `getParsedFiles()` is actually called?
|
||||
|
||||
```js title='parser.js' @ts-expect-error=[20]
|
||||
// "fs" is likely already being loaded, so the `require()` call is cheap
|
||||
const fs = require('fs')
|
||||
const fs = require('node:fs')
|
||||
|
||||
class Parser {
|
||||
async getFiles () {
|
||||
|
||||
@@ -228,6 +228,23 @@ channel with a renderer process using [`MessagePort`][]s. An Electron app can
|
||||
always prefer the [UtilityProcess][] API over Node.js [`child_process.fork`][] API when
|
||||
there is need to fork a child process from the main process.
|
||||
|
||||
## Process-specific module aliases (TypeScript)
|
||||
|
||||
Electron's npm package also exports subpaths that contain a subset of
|
||||
Electron's TypeScript type definitions.
|
||||
|
||||
- `electron/main` includes types for all main process modules.
|
||||
- `electron/renderer` includes types for all renderer process modules.
|
||||
- `electron/common` includes types for modules that can run in main and renderer processes.
|
||||
|
||||
These aliases have no impact on runtime, but can be used for typechecking
|
||||
and autocomplete.
|
||||
|
||||
```js title="Usage example"
|
||||
const { app } = require('electron/main')
|
||||
const { shell } = require('electron/common')
|
||||
```
|
||||
|
||||
[window-mdn]: https://developer.mozilla.org/en-US/docs/Web/API/Window
|
||||
[`MessagePort`]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort
|
||||
[`child_process.fork`]: https://nodejs.org/dist/latest-v16.x/docs/api/child_process.html#child_processforkmodulepath-args-options
|
||||
|
||||
@@ -292,7 +292,7 @@ to the `webPreferences.preload` option in your existing `BrowserWindow` construc
|
||||
```js
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
// include the Node.js 'path' module at the top of your file
|
||||
const path = require('path')
|
||||
const path = require('node:path')
|
||||
|
||||
// modify your existing createWindow() function
|
||||
const createWindow = () => {
|
||||
@@ -358,7 +358,7 @@ The full code is available below:
|
||||
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const path = require('path')
|
||||
const path = require('node:path')
|
||||
|
||||
const createWindow = () => {
|
||||
// Create the browser window.
|
||||
|
||||
@@ -26,8 +26,8 @@ the application via JumpList or dock menu, respectively.
|
||||
|
||||
```javascript fiddle='docs/fiddles/features/recent-documents'
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const fs = require('node:fs')
|
||||
const path = require('node:path')
|
||||
|
||||
const createWindow = () => {
|
||||
const win = new BrowserWindow({
|
||||
|
||||
@@ -29,7 +29,7 @@ To set the represented file of window, you can use the
|
||||
|
||||
```javascript fiddle='docs/fiddles/features/represented-file'
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const os = require('os')
|
||||
const os = require('node:os')
|
||||
|
||||
const createWindow = () => {
|
||||
const win = new BrowserWindow({
|
||||
|
||||
@@ -51,6 +51,12 @@ but can only import a subset of Electron and Node's built-in modules:
|
||||
* [`timers`](https://nodejs.org/api/timers.html)
|
||||
* [`url`](https://nodejs.org/api/url.html)
|
||||
|
||||
[node: imports](https://nodejs.org/api/esm.html#node-imports) are supported as well:
|
||||
|
||||
* [`node:events`](https://nodejs.org/api/events.html)
|
||||
* [`node:timers`](https://nodejs.org/api/timers.html)
|
||||
* [`node:url`](https://nodejs.org/api/url.html)
|
||||
|
||||
In addition, the preload script also polyfills certain Node.js primitives as globals:
|
||||
|
||||
* [`Buffer`](https://nodejs.org/api/buffer.html)
|
||||
|
||||
@@ -222,14 +222,26 @@ with CommonJS module syntax:
|
||||
- [app][app], which controls your application's event lifecycle.
|
||||
- [BrowserWindow][browser-window], which creates and manages app windows.
|
||||
|
||||
:::info Capitalization conventions
|
||||
<details><summary>Module capitalization conventions</summary>
|
||||
|
||||
You might have noticed the capitalization difference between the **a**pp
|
||||
and **B**rowser**W**indow modules. Electron follows typical JavaScript conventions here,
|
||||
where PascalCase modules are instantiable class constructors (e.g. BrowserWindow, Tray,
|
||||
Notification) whereas camelCase modules are not instantiable (e.g. app, ipcRenderer, webContents).
|
||||
|
||||
:::
|
||||
</details>
|
||||
|
||||
<details><summary>Typed import aliases</summary>
|
||||
|
||||
For better type checking when writing TypeScript code, you can choose to import
|
||||
main process modules from <code>electron/main</code>.
|
||||
|
||||
```js
|
||||
const { app, BrowserWindow } = require('electron/main')
|
||||
```
|
||||
|
||||
For more information, see the [Process Model docs](../tutorial/process-model.md#process-specific-module-aliases-typescript).
|
||||
</details>
|
||||
|
||||
:::warning ES Modules in Electron
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ To attach this script to your renderer process, pass its path to the
|
||||
|
||||
```js {2,8-10} title="main.js"
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const path = require('path')
|
||||
const path = require('node:path')
|
||||
|
||||
const createWindow = () => {
|
||||
const win = new BrowserWindow({
|
||||
@@ -204,7 +204,7 @@ you send out the `invoke` call from the renderer.
|
||||
|
||||
```js {1,15} title="main.js"
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
const path = require('path')
|
||||
const path = require('node:path')
|
||||
|
||||
const createWindow = () => {
|
||||
const win = new BrowserWindow({
|
||||
|
||||
@@ -115,7 +115,7 @@ const win = new BrowserWindow({
|
||||
})
|
||||
```
|
||||
|
||||
On either platform `titleBarOverlay` can also be an object. On both macOS and Windows, the height of the overlay can be specified with the `height` property. On Windows, the color of the overlay and its symbols can be specified using the `color` and `symbolColor` properties respectively.
|
||||
On either platform `titleBarOverlay` can also be an object. On both macOS and Windows, the height of the overlay can be specified with the `height` property. On Windows, the color of the overlay and its symbols can be specified using the `color` and `symbolColor` properties respectively. `rgba()`, `hsla()`, and `#RRGGBBAA` color formats are supported to apply transparency.
|
||||
|
||||
If a color option is not specified, the color will default to its system color for the window control buttons. Similarly, if the height option is not specified it will default to the default height:
|
||||
|
||||
@@ -136,10 +136,6 @@ const win = new BrowserWindow({
|
||||
> color and dimension values from a renderer using a set of readonly
|
||||
> [JavaScript APIs][overlay-javascript-apis] and [CSS Environment Variables][overlay-css-env-vars].
|
||||
|
||||
### Limitations
|
||||
|
||||
* Transparent colors are currently not supported. Progress updates for this feature can be found in PR [#33567](https://github.com/electron/electron/issues/33567).
|
||||
|
||||
## Create transparent windows
|
||||
|
||||
By setting the `transparent` option to `true`, you can make a fully transparent window.
|
||||
@@ -188,7 +184,7 @@ allowing events such as `mouseleave` to be emitted:
|
||||
|
||||
```javascript title='main.js'
|
||||
const { BrowserWindow, ipcMain } = require('electron')
|
||||
const path = require('path')
|
||||
const path = require('node:path')
|
||||
|
||||
const win = new BrowserWindow({
|
||||
webPreferences: {
|
||||
|
||||
@@ -126,7 +126,7 @@ following lines:
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow, nativeImage } = require('electron')
|
||||
const path = require('path')
|
||||
const path = require('node:path')
|
||||
|
||||
const win = new BrowserWindow()
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ template("electron_extra_paks") {
|
||||
])
|
||||
output = "${invoker.output_dir}/resources.pak"
|
||||
sources = [
|
||||
"$root_gen_dir/chrome/accessibility_resources.pak",
|
||||
"$root_gen_dir/chrome/browser_resources.pak",
|
||||
"$root_gen_dir/chrome/common_resources.pak",
|
||||
"$root_gen_dir/chrome/dev_ui_browser_resources.pak",
|
||||
@@ -60,6 +61,7 @@ template("electron_extra_paks") {
|
||||
"$root_gen_dir/content/browser/tracing/tracing_resources.pak",
|
||||
"$root_gen_dir/content/browser/webrtc/resources/webrtc_internals_resources.pak",
|
||||
"$root_gen_dir/content/content_resources.pak",
|
||||
"$root_gen_dir/content/gpu_resources.pak",
|
||||
"$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
|
||||
"$root_gen_dir/net/net_resources.pak",
|
||||
"$root_gen_dir/third_party/blink/public/resources/blink_resources.pak",
|
||||
@@ -69,9 +71,11 @@ template("electron_extra_paks") {
|
||||
deps = [
|
||||
"//chrome/browser:dev_ui_browser_resources",
|
||||
"//chrome/browser:resources",
|
||||
"//chrome/browser/resources/accessibility:resources",
|
||||
"//chrome/common:resources",
|
||||
"//components/resources",
|
||||
"//content:content_resources",
|
||||
"//content/browser/resources/gpu:resources",
|
||||
"//content/browser/resources/media:resources",
|
||||
"//content/browser/tracing:resources",
|
||||
"//content/browser/webrtc/resources",
|
||||
@@ -172,6 +176,7 @@ template("electron_paks") {
|
||||
}
|
||||
|
||||
source_patterns = [
|
||||
"${root_gen_dir}/chrome/chromium_strings_",
|
||||
"${root_gen_dir}/chrome/locale_settings_",
|
||||
"${root_gen_dir}/chrome/platform_locale_settings_",
|
||||
"${root_gen_dir}/chrome/generated_resources_",
|
||||
@@ -187,6 +192,7 @@ template("electron_paks") {
|
||||
"${root_gen_dir}/ui/strings/ui_strings_",
|
||||
]
|
||||
deps = [
|
||||
"//chrome/app:chromium_strings",
|
||||
"//chrome/app:generated_resources",
|
||||
"//chrome/app/resources:locale_settings",
|
||||
"//chrome/app/resources:platform_locale_settings",
|
||||
|
||||
@@ -115,6 +115,7 @@ auto_filenames = {
|
||||
"docs/api/structures/protocol-response.md",
|
||||
"docs/api/structures/rectangle.md",
|
||||
"docs/api/structures/referrer.md",
|
||||
"docs/api/structures/render-process-gone-details.md",
|
||||
"docs/api/structures/resolved-endpoint.md",
|
||||
"docs/api/structures/resolved-host.md",
|
||||
"docs/api/structures/scrubber-item.md",
|
||||
|
||||
@@ -129,10 +129,6 @@ filenames = {
|
||||
"shell/browser/auto_updater_mac.mm",
|
||||
"shell/browser/browser_mac.mm",
|
||||
"shell/browser/electron_browser_main_parts_mac.mm",
|
||||
"shell/browser/mac/dict_util.h",
|
||||
"shell/browser/mac/dict_util.mm",
|
||||
"shell/browser/mac/electron_application_delegate.h",
|
||||
"shell/browser/mac/electron_application_delegate.mm",
|
||||
"shell/browser/mac/electron_application.h",
|
||||
"shell/browser/mac/electron_application.mm",
|
||||
"shell/browser/mac/in_app_purchase_observer.h",
|
||||
@@ -512,6 +508,7 @@ filenames = {
|
||||
"shell/browser/web_contents_preferences.h",
|
||||
"shell/browser/web_contents_zoom_controller.cc",
|
||||
"shell/browser/web_contents_zoom_controller.h",
|
||||
"shell/browser/web_contents_zoom_observer.h",
|
||||
"shell/browser/web_view_guest_delegate.cc",
|
||||
"shell/browser/web_view_guest_delegate.h",
|
||||
"shell/browser/web_view_manager.cc",
|
||||
@@ -699,6 +696,8 @@ filenames = {
|
||||
"shell/browser/extensions/api/resources_private/resources_private_api.h",
|
||||
"shell/browser/extensions/api/runtime/electron_runtime_api_delegate.cc",
|
||||
"shell/browser/extensions/api/runtime/electron_runtime_api_delegate.h",
|
||||
"shell/browser/extensions/api/scripting/scripting_api.cc",
|
||||
"shell/browser/extensions/api/scripting/scripting_api.h",
|
||||
"shell/browser/extensions/api/streams_private/streams_private_api.cc",
|
||||
"shell/browser/extensions/api/streams_private/streams_private_api.h",
|
||||
"shell/browser/extensions/api/tabs/tabs_api.cc",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Buffer } from 'buffer';
|
||||
import { constants } from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as util from 'util';
|
||||
import type * as Crypto from 'crypto';
|
||||
@@ -27,7 +28,7 @@ const cachedArchives = new Map<string, NodeJS.AsarArchive>();
|
||||
const getOrCreateArchive = (archivePath: string) => {
|
||||
const isCached = cachedArchives.has(archivePath);
|
||||
if (isCached) {
|
||||
return cachedArchives.get(archivePath);
|
||||
return cachedArchives.get(archivePath)!;
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -39,6 +40,8 @@ const getOrCreateArchive = (archivePath: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
process._getOrCreateArchive = getOrCreateArchive;
|
||||
|
||||
const asarRe = /\.asar/i;
|
||||
|
||||
// Separate asar package's path from full path.
|
||||
@@ -65,18 +68,22 @@ const gid = process.getgid?.() ?? 0;
|
||||
|
||||
const fakeTime = new Date();
|
||||
|
||||
enum AsarFileType {
|
||||
kFile = (constants as any).UV_DIRENT_FILE,
|
||||
kDirectory = (constants as any).UV_DIRENT_DIR,
|
||||
kLink = (constants as any).UV_DIRENT_LINK,
|
||||
}
|
||||
|
||||
const fileTypeToMode = new Map<AsarFileType, number>([
|
||||
[AsarFileType.kFile, constants.S_IFREG],
|
||||
[AsarFileType.kDirectory, constants.S_IFDIR],
|
||||
[AsarFileType.kLink, constants.S_IFLNK]
|
||||
]);
|
||||
|
||||
const asarStatsToFsStats = function (stats: NodeJS.AsarFileStat) {
|
||||
const { Stats, constants } = require('fs');
|
||||
const { Stats } = require('fs');
|
||||
|
||||
let mode = constants.S_IROTH ^ constants.S_IRGRP ^ constants.S_IRUSR ^ constants.S_IWUSR;
|
||||
|
||||
if (stats.isFile) {
|
||||
mode ^= constants.S_IFREG;
|
||||
} else if (stats.isDirectory) {
|
||||
mode ^= constants.S_IFDIR;
|
||||
} else if (stats.isLink) {
|
||||
mode ^= constants.S_IFLNK;
|
||||
}
|
||||
const mode = constants.S_IROTH | constants.S_IRGRP | constants.S_IRUSR | constants.S_IWUSR | fileTypeToMode.get(stats.type)!;
|
||||
|
||||
return new Stats(
|
||||
1, // dev
|
||||
@@ -239,7 +246,6 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||
const logASARAccess = (asarPath: string, filePath: string, offset: number) => {
|
||||
if (!process.env.ELECTRON_LOG_ASAR_READS) return;
|
||||
if (!logFDs.has(asarPath)) {
|
||||
const path = require('path');
|
||||
const logFilename = `${path.basename(asarPath, '.asar')}-access-log.txt`;
|
||||
const logPath = path.join(require('os').tmpdir(), logFilename);
|
||||
logFDs.set(asarPath, fs.openSync(logPath, 'a'));
|
||||
@@ -655,13 +661,7 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||
nextTick(callback!, [error]);
|
||||
return;
|
||||
}
|
||||
if (stats.isFile) {
|
||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
|
||||
} else if (stats.isDirectory) {
|
||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_DIR));
|
||||
} else if (stats.isLink) {
|
||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_LINK));
|
||||
}
|
||||
dirents.push(new fs.Dirent(file, stats.type));
|
||||
}
|
||||
nextTick(callback!, [null, dirents]);
|
||||
return;
|
||||
@@ -698,13 +698,7 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||
if (!stats) {
|
||||
throw createError(AsarError.NOT_FOUND, { asarPath, filePath: childPath });
|
||||
}
|
||||
if (stats.isFile) {
|
||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
|
||||
} else if (stats.isDirectory) {
|
||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_DIR));
|
||||
} else if (stats.isLink) {
|
||||
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_LINK));
|
||||
}
|
||||
dirents.push(new fs.Dirent(file, stats.type));
|
||||
}
|
||||
return dirents;
|
||||
}
|
||||
@@ -755,7 +749,7 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||
const stats = archive.stat(filePath);
|
||||
if (!stats) return -34;
|
||||
|
||||
return (stats.isDirectory) ? 1 : 0;
|
||||
return (stats.type === AsarFileType.kDirectory) ? 1 : 0;
|
||||
};
|
||||
|
||||
// Calling mkdir for directory inside asar archive should throw ENOTDIR
|
||||
@@ -838,7 +832,7 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||
const originalModuleLoad = Module._load;
|
||||
Module._load = (request: string, ...args: any[]) => {
|
||||
const loadResult = originalModuleLoad(request, ...args);
|
||||
if (request === 'child_process') {
|
||||
if (request === 'child_process' || request === 'node:child_process') {
|
||||
if (!asarReady.has(loadResult)) {
|
||||
asarReady.add(loadResult);
|
||||
// Just to make it obvious what we are dealing with here
|
||||
|
||||
@@ -114,5 +114,11 @@ for (const name of events) {
|
||||
}
|
||||
|
||||
// Deprecation.
|
||||
deprecate.event(app, 'gpu-process-crashed', 'child-process-gone');
|
||||
deprecate.event(app, 'renderer-process-crashed', 'render-process-gone');
|
||||
deprecate.event(app, 'gpu-process-crashed', 'child-process-gone', () => {
|
||||
// the old event is still emitted by App::OnGpuProcessCrashed()
|
||||
return undefined;
|
||||
});
|
||||
|
||||
deprecate.event(app, 'renderer-process-crashed', 'render-process-gone', (event: Electron.Event, webContents: Electron.WebContents, details: Electron.RenderProcessGoneDetails) => {
|
||||
return [event, webContents, details.reason === 'killed'];
|
||||
});
|
||||
|
||||
@@ -69,7 +69,7 @@ Menu.prototype.popup = function (options = {}) {
|
||||
if (options == null || typeof options !== 'object') {
|
||||
throw new TypeError('Options must be an object');
|
||||
}
|
||||
let { window, x, y, positioningItem, callback } = options;
|
||||
let { window, x, y, positioningItem, sourceType, callback } = options;
|
||||
|
||||
// no callback passed
|
||||
if (!callback || typeof callback !== 'function') callback = () => {};
|
||||
@@ -78,6 +78,7 @@ Menu.prototype.popup = function (options = {}) {
|
||||
if (typeof x !== 'number') x = -1;
|
||||
if (typeof y !== 'number') y = -1;
|
||||
if (typeof positioningItem !== 'number') positioningItem = -1;
|
||||
if (typeof sourceType !== 'string' || !sourceType) sourceType = 'mouse';
|
||||
|
||||
// find which window to use
|
||||
const wins = BaseWindow.getAllWindows();
|
||||
@@ -91,7 +92,7 @@ Menu.prototype.popup = function (options = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
this.popupAt(window as unknown as BaseWindow, x, y, positioningItem, callback);
|
||||
this.popupAt(window as unknown as BaseWindow, x, y, positioningItem, sourceType, callback);
|
||||
return { browserWindow: window, x, y, position: positioningItem };
|
||||
};
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ const { registerSchemesAsPrivileged, getStandardSchemes, Protocol } = process._l
|
||||
const ERR_FAILED = -2;
|
||||
const ERR_UNEXPECTED = -9;
|
||||
|
||||
const isBuiltInScheme = (scheme: string) => scheme === 'http' || scheme === 'https';
|
||||
const isBuiltInScheme = (scheme: string) => ['http', 'https', 'file'].includes(scheme);
|
||||
|
||||
function makeStreamFromPipe (pipe: any): ReadableStream {
|
||||
const buf = new Uint8Array(1024 * 1024 /* 1 MB */);
|
||||
@@ -60,6 +60,26 @@ function convertToRequestBody (uploadData: ProtocolRequest['uploadData']): Reque
|
||||
}) as RequestInit['body'];
|
||||
}
|
||||
|
||||
// TODO(codebytere): Use Object.hasOwn() once we update to ECMAScript 2022.
|
||||
function validateResponse (res: Response) {
|
||||
if (!res || typeof res !== 'object') return false;
|
||||
|
||||
if (res.type === 'error') return true;
|
||||
|
||||
const exists = (key: string) => Object.prototype.hasOwnProperty.call(res, key);
|
||||
|
||||
if (exists('status') && typeof res.status !== 'number') return false;
|
||||
if (exists('statusText') && typeof res.statusText !== 'string') return false;
|
||||
if (exists('headers') && typeof res.headers !== 'object') return false;
|
||||
|
||||
if (exists('body')) {
|
||||
if (typeof res.body !== 'object') return false;
|
||||
if (res.body !== null && !(res.body instanceof ReadableStream)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Protocol.prototype.handle = function (this: Electron.Protocol, scheme: string, handler: (req: Request) => Response | Promise<Response>) {
|
||||
const register = isBuiltInScheme(scheme) ? this.interceptProtocol : this.registerProtocol;
|
||||
const success = register.call(this, scheme, async (preq: ProtocolRequest, cb: any) => {
|
||||
@@ -73,13 +93,14 @@ Protocol.prototype.handle = function (this: Electron.Protocol, scheme: string, h
|
||||
duplex: body instanceof ReadableStream ? 'half' : undefined
|
||||
} as any);
|
||||
const res = await handler(req);
|
||||
if (!res || typeof res !== 'object') {
|
||||
if (!validateResponse(res)) {
|
||||
return cb({ error: ERR_UNEXPECTED });
|
||||
}
|
||||
if (res.type === 'error') { cb({ error: ERR_FAILED }); } else {
|
||||
} else if (res.type === 'error') {
|
||||
cb({ error: ERR_FAILED });
|
||||
} else {
|
||||
cb({
|
||||
data: res.body ? Readable.fromWeb(res.body as ReadableStream<ArrayBufferView>) : null,
|
||||
headers: Object.fromEntries(res.headers),
|
||||
headers: res.headers ? Object.fromEntries(res.headers) : {},
|
||||
statusCode: res.status,
|
||||
statusText: res.statusText,
|
||||
mimeType: (res as any).__original_resp?._responseHead?.mimeType
|
||||
|
||||
@@ -1,12 +1,31 @@
|
||||
import * as deprecate from '@electron/internal/common/deprecate';
|
||||
|
||||
const { systemPreferences } = process._linkedBinding('electron_browser_system_preferences');
|
||||
|
||||
if ('getAppLevelAppearance' in systemPreferences) {
|
||||
const nativeALAGetter = systemPreferences.getAppLevelAppearance;
|
||||
const nativeALASetter = systemPreferences.setAppLevelAppearance;
|
||||
const warnALA = deprecate.warnOnce('appLevelAppearance');
|
||||
const warnALAGetter = deprecate.warnOnce('getAppLevelAppearance function');
|
||||
const warnALASetter = deprecate.warnOnce('setAppLevelAppearance function');
|
||||
Object.defineProperty(systemPreferences, 'appLevelAppearance', {
|
||||
get: () => nativeALAGetter.call(systemPreferences),
|
||||
set: (appearance) => nativeALASetter.call(systemPreferences, appearance)
|
||||
get: () => {
|
||||
warnALA();
|
||||
return nativeALAGetter.call(systemPreferences);
|
||||
},
|
||||
set: (appearance) => {
|
||||
warnALA();
|
||||
nativeALASetter.call(systemPreferences, appearance);
|
||||
}
|
||||
});
|
||||
systemPreferences.getAppLevelAppearance = () => {
|
||||
warnALAGetter();
|
||||
return nativeALAGetter.call(systemPreferences);
|
||||
};
|
||||
systemPreferences.setAppLevelAppearance = (appearance) => {
|
||||
warnALASetter();
|
||||
nativeALASetter.call(systemPreferences, appearance);
|
||||
};
|
||||
}
|
||||
|
||||
if ('getEffectiveAppearance' in systemPreferences) {
|
||||
|
||||
@@ -317,7 +317,7 @@ WebContents.prototype.printToPDF = async function (options) {
|
||||
|
||||
if (options.preferCSSPageSize !== undefined) {
|
||||
if (typeof options.preferCSSPageSize !== 'boolean') {
|
||||
return Promise.reject(new Error('footerTemplate must be a String'));
|
||||
return Promise.reject(new Error('preferCSSPageSize must be a Boolean'));
|
||||
}
|
||||
printSettings.preferCSSPageSize = options.preferCSSPageSize;
|
||||
}
|
||||
@@ -335,44 +335,56 @@ WebContents.prototype.printToPDF = async function (options) {
|
||||
}
|
||||
};
|
||||
|
||||
WebContents.prototype.print = function (options: ElectronInternal.WebContentsPrintOptions = {}, callback) {
|
||||
// TODO(codebytere): deduplicate argument sanitization by moving rest of
|
||||
// print param logic into new file shared between printToPDF and print
|
||||
if (typeof options === 'object') {
|
||||
// Optionally set size for PDF.
|
||||
if (options.pageSize !== undefined) {
|
||||
const pageSize = options.pageSize;
|
||||
if (typeof pageSize === 'object') {
|
||||
if (!pageSize.height || !pageSize.width) {
|
||||
throw new Error('height and width properties are required for pageSize');
|
||||
}
|
||||
// TODO(codebytere): deduplicate argument sanitization by moving rest of
|
||||
// print param logic into new file shared between printToPDF and print
|
||||
WebContents.prototype.print = function (options: ElectronInternal.WebContentsPrintOptions, callback) {
|
||||
if (typeof options !== 'object') {
|
||||
throw new Error('webContents.print(): Invalid print settings specified.');
|
||||
}
|
||||
|
||||
// Dimensions in Microns - 1 meter = 10^6 microns
|
||||
const height = Math.ceil(pageSize.height);
|
||||
const width = Math.ceil(pageSize.width);
|
||||
if (!isValidCustomPageSize(width, height)) {
|
||||
throw new Error('height and width properties must be minimum 352 microns.');
|
||||
}
|
||||
const printSettings: Record<string, any> = { ...options };
|
||||
|
||||
options.mediaSize = {
|
||||
name: 'CUSTOM',
|
||||
custom_display_name: 'Custom',
|
||||
height_microns: height,
|
||||
width_microns: width
|
||||
};
|
||||
} else if (PDFPageSizes[pageSize]) {
|
||||
options.mediaSize = PDFPageSizes[pageSize];
|
||||
} else {
|
||||
throw new Error(`Unsupported pageSize: ${pageSize}`);
|
||||
}
|
||||
const pageSize = options.pageSize ?? 'A4';
|
||||
if (typeof pageSize === 'object') {
|
||||
if (!pageSize.height || !pageSize.width) {
|
||||
throw new Error('height and width properties are required for pageSize');
|
||||
}
|
||||
|
||||
// Dimensions in Microns - 1 meter = 10^6 microns
|
||||
const height = Math.ceil(pageSize.height);
|
||||
const width = Math.ceil(pageSize.width);
|
||||
if (!isValidCustomPageSize(width, height)) {
|
||||
throw new Error('height and width properties must be minimum 352 microns.');
|
||||
}
|
||||
|
||||
printSettings.mediaSize = {
|
||||
name: 'CUSTOM',
|
||||
custom_display_name: 'Custom',
|
||||
height_microns: height,
|
||||
width_microns: width,
|
||||
imageable_area_left_microns: 0,
|
||||
imageable_area_bottom_microns: 0,
|
||||
imageable_area_right_microns: width,
|
||||
imageable_area_top_microns: height
|
||||
};
|
||||
} else if (typeof pageSize === 'string' && PDFPageSizes[pageSize]) {
|
||||
const mediaSize = PDFPageSizes[pageSize];
|
||||
printSettings.mediaSize = {
|
||||
...mediaSize,
|
||||
imageable_area_left_microns: 0,
|
||||
imageable_area_bottom_microns: 0,
|
||||
imageable_area_right_microns: mediaSize.width_microns,
|
||||
imageable_area_top_microns: mediaSize.height_microns
|
||||
};
|
||||
} else {
|
||||
throw new Error(`Unsupported pageSize: ${pageSize}`);
|
||||
}
|
||||
|
||||
if (this._print) {
|
||||
if (callback) {
|
||||
this._print(options, callback);
|
||||
this._print(printSettings, callback);
|
||||
} else {
|
||||
this._print(options);
|
||||
this._print(printSettings);
|
||||
}
|
||||
} else {
|
||||
console.error('Error: Printing feature is disabled.');
|
||||
@@ -439,6 +451,7 @@ WebContents.prototype.loadURL = function (url, options) {
|
||||
};
|
||||
|
||||
let navigationStarted = false;
|
||||
let browserInitiatedInPageNavigation = false;
|
||||
const navigationListener = (event: Electron.Event, url: string, isSameDocument: boolean, isMainFrame: boolean) => {
|
||||
if (isMainFrame) {
|
||||
if (navigationStarted && !isSameDocument) {
|
||||
@@ -453,6 +466,7 @@ WebContents.prototype.loadURL = function (url, options) {
|
||||
// as the routing does not leave the document
|
||||
return rejectAndCleanup(-3, 'ERR_ABORTED', url);
|
||||
}
|
||||
browserInitiatedInPageNavigation = navigationStarted && isSameDocument;
|
||||
navigationStarted = true;
|
||||
}
|
||||
};
|
||||
@@ -467,17 +481,22 @@ WebContents.prototype.loadURL = function (url, options) {
|
||||
// would be more appropriate.
|
||||
rejectAndCleanup(-2, 'ERR_FAILED', url);
|
||||
};
|
||||
const finishListenerWhenUserInitiatedNavigation = () => {
|
||||
if (!browserInitiatedInPageNavigation) {
|
||||
finishListener();
|
||||
}
|
||||
};
|
||||
const removeListeners = () => {
|
||||
this.removeListener('did-finish-load', finishListener);
|
||||
this.removeListener('did-fail-load', failListener);
|
||||
this.removeListener('did-navigate-in-page', finishListener);
|
||||
this.removeListener('did-navigate-in-page', finishListenerWhenUserInitiatedNavigation);
|
||||
this.removeListener('did-start-navigation', navigationListener);
|
||||
this.removeListener('did-stop-loading', stopLoadingListener);
|
||||
this.removeListener('destroyed', stopLoadingListener);
|
||||
};
|
||||
this.on('did-finish-load', finishListener);
|
||||
this.on('did-fail-load', failListener);
|
||||
this.on('did-navigate-in-page', finishListener);
|
||||
this.on('did-navigate-in-page', finishListenerWhenUserInitiatedNavigation);
|
||||
this.on('did-start-navigation', navigationListener);
|
||||
this.on('did-stop-loading', stopLoadingListener);
|
||||
this.on('destroyed', stopLoadingListener);
|
||||
@@ -650,8 +669,8 @@ WebContents.prototype._init = function () {
|
||||
ipcMain.emit(channel, event, message);
|
||||
});
|
||||
|
||||
this.on('crashed', (event, ...args) => {
|
||||
app.emit('renderer-process-crashed', event, this, ...args);
|
||||
deprecate.event(this, 'crashed', 'render-process-gone', (event: Electron.Event, details: Electron.RenderProcessGoneDetails) => {
|
||||
return [event, details.reason === 'killed'];
|
||||
});
|
||||
|
||||
this.on('render-process-gone', (event, details) => {
|
||||
|
||||
@@ -84,11 +84,20 @@ const v8Util = process._linkedBinding('electron_common_v8_util');
|
||||
let packagePath = null;
|
||||
let packageJson = null;
|
||||
const searchPaths: string[] = v8Util.getHiddenValue(global, 'appSearchPaths');
|
||||
const searchPathsOnlyLoadASAR: boolean = v8Util.getHiddenValue(global, 'appSearchPathsOnlyLoadASAR');
|
||||
// Borrow the _getOrCreateArchive asar helper
|
||||
const getOrCreateArchive = process._getOrCreateArchive;
|
||||
delete process._getOrCreateArchive;
|
||||
|
||||
if (process.resourcesPath) {
|
||||
for (packagePath of searchPaths) {
|
||||
try {
|
||||
packagePath = path.join(process.resourcesPath, packagePath);
|
||||
if (searchPathsOnlyLoadASAR) {
|
||||
if (!getOrCreateArchive?.(packagePath)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
packageJson = Module._load(path.join(packagePath, 'package.json'));
|
||||
break;
|
||||
} catch {
|
||||
|
||||
@@ -66,14 +66,17 @@ export function renameFunction<T extends Function> (fn: T, newName: string): T {
|
||||
}
|
||||
|
||||
// change the name of an event
|
||||
export function event (emitter: NodeJS.EventEmitter, oldName: string, newName: string) {
|
||||
export function event (emitter: NodeJS.EventEmitter, oldName: string, newName: string, transformer: (...args: any[]) => any[] | undefined = (...args) => args) {
|
||||
const warn = newName.startsWith('-') /* internal event */
|
||||
? warnOnce(`${oldName} event`)
|
||||
: warnOnce(`${oldName} event`, `${newName} event`);
|
||||
return emitter.on(newName, function (this: NodeJS.EventEmitter, ...args) {
|
||||
if (this.listenerCount(oldName) !== 0) {
|
||||
warn();
|
||||
this.emit(oldName, ...args);
|
||||
const transformedArgs = transformer(...args);
|
||||
if (transformedArgs) {
|
||||
this.emit(oldName, ...transformedArgs);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -17,13 +17,13 @@ const isWebView = mainFrame.getWebPreference('isWebView');
|
||||
// ElectronApiServiceImpl will look for the "ipcNative" hidden object when
|
||||
// invoking the 'onMessage' callback.
|
||||
v8Util.setHiddenValue(global, 'ipcNative', {
|
||||
onMessage (internal: boolean, channel: string, ports: MessagePort[], args: any[], senderId: number) {
|
||||
onMessage (internal: boolean, channel: string, ports: MessagePort[], args: any[], senderId: number, senderIsMainFrame: boolean) {
|
||||
if (internal && senderId !== 0) {
|
||||
console.error(`Message ${channel} sent by unexpected WebContents (${senderId})`);
|
||||
return;
|
||||
}
|
||||
const sender = internal ? ipcRendererInternal : ipcRenderer;
|
||||
sender.emit(channel, { sender, senderId, ports }, ...args);
|
||||
sender.emit(channel, { sender, senderId, ...(senderId ? { senderIsMainFrame } : {}), ports }, ...args);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -38,12 +38,15 @@ const loadedModules = new Map<string, any>([
|
||||
['electron', electron],
|
||||
['electron/common', electron],
|
||||
['electron/renderer', electron],
|
||||
['events', events]
|
||||
['events', events],
|
||||
['node:events', events]
|
||||
]);
|
||||
|
||||
const loadableModules = new Map<string, Function>([
|
||||
['timers', () => require('timers')],
|
||||
['url', () => require('url')]
|
||||
['node:timers', () => require('timers')],
|
||||
['url', () => require('url')],
|
||||
['node:url', () => require('url')]
|
||||
]);
|
||||
|
||||
// Pass different process object to the preload script.
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
"devDependencies": {
|
||||
"@azure/storage-blob": "^12.9.0",
|
||||
"@electron/asar": "^3.2.1",
|
||||
"@electron/docs-parser": "^1.1.0",
|
||||
"@electron/docs-parser": "^1.1.1",
|
||||
"@electron/fiddle-core": "^1.0.4",
|
||||
"@electron/github-app-auth": "^2.0.0",
|
||||
"@electron/lint-roller": "^1.5.0",
|
||||
"@electron/typescript-definitions": "^8.14.0",
|
||||
"@electron/typescript-definitions": "^8.14.5",
|
||||
"@octokit/rest": "^19.0.7",
|
||||
"@primer/octicons": "^10.0.0",
|
||||
"@types/basic-auth": "^1.1.3",
|
||||
|
||||
3
patches/angle/.patches
Normal file
3
patches/angle/.patches
Normal file
@@ -0,0 +1,3 @@
|
||||
cherry-pick-285c7712c506.patch
|
||||
cherry-pick-2bf945775fe6.patch
|
||||
cherry-pick-cafe56b591ed.patch
|
||||
153
patches/angle/cherry-pick-285c7712c506.patch
Normal file
153
patches/angle/cherry-pick-285c7712c506.patch
Normal file
@@ -0,0 +1,153 @@
|
||||
From 285c7712c50654e3d7238b059c4631bc91285514 Mon Sep 17 00:00:00 2001
|
||||
From: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
Date: Thu, 13 Jul 2023 15:23:49 -0400
|
||||
Subject: [PATCH] M116: Translator: Unconditionally limit variable sizes
|
||||
|
||||
... instead of just for WebGL. This is to avoid hitting driver bugs
|
||||
that were prevented with this check for WebGL on a compromised renderer
|
||||
that can create non-WebGL contexts.
|
||||
|
||||
Bug: chromium:1464682
|
||||
Change-Id: I2b1c5a8c51f06225f5f850109d30778d97e574c7
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4717371
|
||||
Reviewed-by: Roman Lavrov <romanl@google.com>
|
||||
---
|
||||
|
||||
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
|
||||
index 7b1ac4e..383feeb 100644
|
||||
--- a/src/compiler/translator/Compiler.cpp
|
||||
+++ b/src/compiler/translator/Compiler.cpp
|
||||
@@ -397,9 +397,10 @@
|
||||
|
||||
bool TCompiler::shouldLimitTypeSizes() const
|
||||
{
|
||||
- // WebGL shaders limit the size of variables' types in shaders,
|
||||
- // including arrays, structs and interface blocks.
|
||||
- return IsWebGLBasedSpec(mShaderSpec);
|
||||
+ // Prevent unrealistically large variable sizes in shaders. This works around driver bugs
|
||||
+ // around int-size limits (such as 2GB). The limits are generously large enough that no real
|
||||
+ // shader should ever hit it.
|
||||
+ return true;
|
||||
}
|
||||
|
||||
bool TCompiler::Init(const ShBuiltInResources &resources)
|
||||
diff --git a/src/compiler/translator/ValidateTypeSizeLimitations.cpp b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
|
||||
index 2a033ad..19a4821 100644
|
||||
--- a/src/compiler/translator/ValidateTypeSizeLimitations.cpp
|
||||
+++ b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
|
||||
@@ -23,10 +23,10 @@
|
||||
// Arbitrarily enforce that all types declared with a size in bytes of over 2 GB will cause
|
||||
// compilation failure.
|
||||
//
|
||||
-// For local and global variables, the limit is much lower (1MB) as that much memory won't fit in
|
||||
+// For local and global variables, the limit is much lower (16MB) as that much memory won't fit in
|
||||
// the GPU registers anyway.
|
||||
constexpr size_t kMaxVariableSizeInBytes = static_cast<size_t>(2) * 1024 * 1024 * 1024;
|
||||
-constexpr size_t kMaxPrivateVariableSizeInBytes = static_cast<size_t>(1) * 1024 * 1024;
|
||||
+constexpr size_t kMaxPrivateVariableSizeInBytes = static_cast<size_t>(16) * 1024 * 1024;
|
||||
|
||||
// Traverses intermediate tree to ensure that the shader does not
|
||||
// exceed certain implementation-defined limits on the sizes of types.
|
||||
diff --git a/src/compiler/translator/util.cpp b/src/compiler/translator/util.cpp
|
||||
index a91f8b0..a866b25 100644
|
||||
--- a/src/compiler/translator/util.cpp
|
||||
+++ b/src/compiler/translator/util.cpp
|
||||
@@ -282,6 +282,9 @@
|
||||
|
||||
return kBoolGLType[type.getNominalSize() - 1];
|
||||
|
||||
+ case EbtYuvCscStandardEXT:
|
||||
+ return GL_UNSIGNED_INT;
|
||||
+
|
||||
case EbtSampler2D:
|
||||
return GL_SAMPLER_2D;
|
||||
case EbtSampler3D:
|
||||
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
|
||||
index 9ae56f5..a8d2ce4 100644
|
||||
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
|
||||
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
|
||||
@@ -5284,8 +5284,8 @@
|
||||
|
||||
constexpr char kVSArrayTooLarge[] =
|
||||
R"(varying vec4 color;
|
||||
-// 1 MB / 32 aligned bytes per mat2 = 32768
|
||||
-const int array_size = 32769;
|
||||
+// 16 MB / 32 aligned bytes per mat2 = 524288
|
||||
+const int array_size = 524289;
|
||||
void main()
|
||||
{
|
||||
mat2 array[array_size];
|
||||
@@ -5297,7 +5297,7 @@
|
||||
|
||||
constexpr char kVSArrayMuchTooLarge[] =
|
||||
R"(varying vec4 color;
|
||||
-const int array_size = 55600;
|
||||
+const int array_size = 757000;
|
||||
void main()
|
||||
{
|
||||
mat2 array[array_size];
|
||||
@@ -5361,9 +5361,9 @@
|
||||
constexpr char kTooLargeGlobalMemory1[] =
|
||||
R"(precision mediump float;
|
||||
|
||||
-// 1 MB / 16 bytes per vec4 = 65536
|
||||
-vec4 array[32768];
|
||||
-vec4 array2[32769];
|
||||
+// 16 MB / 16 bytes per vec4 = 1048576
|
||||
+vec4 array[524288];
|
||||
+vec4 array2[524289];
|
||||
|
||||
void main()
|
||||
{
|
||||
@@ -5376,9 +5376,9 @@
|
||||
constexpr char kTooLargeGlobalMemory2[] =
|
||||
R"(precision mediump float;
|
||||
|
||||
-// 1 MB / 16 bytes per vec4 = 65536
|
||||
-vec4 array[32767];
|
||||
-vec4 array2[32767];
|
||||
+// 16 MB / 16 bytes per vec4 = 1048576
|
||||
+vec4 array[524287];
|
||||
+vec4 array2[524287];
|
||||
vec4 x, y, z;
|
||||
|
||||
void main()
|
||||
@@ -5392,12 +5392,12 @@
|
||||
constexpr char kTooLargeGlobalAndLocalMemory1[] =
|
||||
R"(precision mediump float;
|
||||
|
||||
-// 1 MB / 16 bytes per vec4 = 65536
|
||||
-vec4 array[32768];
|
||||
+// 16 MB / 16 bytes per vec4 = 1048576
|
||||
+vec4 array[524288];
|
||||
|
||||
void main()
|
||||
{
|
||||
- vec4 array2[32769];
|
||||
+ vec4 array2[524289];
|
||||
if (array[0].x + array[1].x == 2.0)
|
||||
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
else
|
||||
@@ -5408,18 +5408,18 @@
|
||||
constexpr char kTooLargeGlobalAndLocalMemory2[] =
|
||||
R"(precision mediump float;
|
||||
|
||||
-// 1 MB / 16 bytes per vec4 = 65536
|
||||
-vec4 array[32768];
|
||||
+// 16 MB / 16 bytes per vec4 = 1048576
|
||||
+vec4 array[524288];
|
||||
|
||||
float f()
|
||||
{
|
||||
- vec4 array2[16384];
|
||||
+ vec4 array2[524288];
|
||||
return array2[0].x;
|
||||
}
|
||||
|
||||
float g()
|
||||
{
|
||||
- vec4 array3[16383];
|
||||
+ vec4 array3[524287];
|
||||
return array3[0].x;
|
||||
}
|
||||
|
||||
197
patches/angle/cherry-pick-2bf945775fe6.patch
Normal file
197
patches/angle/cherry-pick-2bf945775fe6.patch
Normal file
@@ -0,0 +1,197 @@
|
||||
From 2bf945775fe634eb9e420c2263dae6043bbb5ece Mon Sep 17 00:00:00 2001
|
||||
From: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
Date: Fri, 14 Jul 2023 12:30:15 -0400
|
||||
Subject: [PATCH] M116: Translator: Limit variable sizes vs uint overflow
|
||||
|
||||
Bug: chromium:1464680
|
||||
Change-Id: Iee41a2da7a7a330e6cc4d6da59a6e9836ee9dd36
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4717372
|
||||
Reviewed-by: Roman Lavrov <romanl@google.com>
|
||||
---
|
||||
|
||||
diff --git a/src/compiler/translator/ValidateTypeSizeLimitations.cpp b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
|
||||
index 19a4821..f0ff9cb 100644
|
||||
--- a/src/compiler/translator/ValidateTypeSizeLimitations.cpp
|
||||
+++ b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "compiler/translator/ValidateTypeSizeLimitations.h"
|
||||
|
||||
#include "angle_gl.h"
|
||||
+#include "common/mathutil.h"
|
||||
#include "compiler/translator/Diagnostics.h"
|
||||
#include "compiler/translator/Symbol.h"
|
||||
#include "compiler/translator/SymbolTable.h"
|
||||
@@ -113,7 +114,8 @@
|
||||
|
||||
void validateTotalPrivateVariableSize()
|
||||
{
|
||||
- if (mTotalPrivateVariablesSize > kMaxPrivateVariableSizeInBytes)
|
||||
+ if (mTotalPrivateVariablesSize.ValueOrDefault(std::numeric_limits<size_t>::max()) >
|
||||
+ kMaxPrivateVariableSizeInBytes)
|
||||
{
|
||||
mDiagnostics->error(
|
||||
TSourceLoc{},
|
||||
@@ -231,7 +233,7 @@
|
||||
TDiagnostics *mDiagnostics;
|
||||
std::vector<int> mLoopSymbolIds;
|
||||
|
||||
- size_t mTotalPrivateVariablesSize;
|
||||
+ angle::base::CheckedNumeric<size_t> mTotalPrivateVariablesSize;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
|
||||
index a8d2ce4..542d49f 100644
|
||||
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
|
||||
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
|
||||
@@ -5426,7 +5426,7 @@
|
||||
float h()
|
||||
{
|
||||
vec4 value;
|
||||
- float value2
|
||||
+ float value2;
|
||||
return value.x + value2;
|
||||
}
|
||||
|
||||
@@ -5438,6 +5438,131 @@
|
||||
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
})";
|
||||
|
||||
+ constexpr char kTooLargeGlobalMemoryOverflow[] =
|
||||
+ R"(precision mediump float;
|
||||
+
|
||||
+// 16 MB / 16 bytes per vec4 = 1048576
|
||||
+// Create 256 arrays so each is small, but the total overflows a 32-bit number
|
||||
+vec4 array[1048576], array2[1048576], array3[1048576], array4[1048576], array5[1048576];
|
||||
+vec4 array6[1048576], array7[1048576], array8[1048576], array9[1048576], array10[1048576];
|
||||
+vec4 array11[1048576], array12[1048576], array13[1048576], array14[1048576], array15[1048576];
|
||||
+vec4 array16[1048576], array17[1048576], array18[1048576], array19[1048576], array20[1048576];
|
||||
+vec4 array21[1048576], array22[1048576], array23[1048576], array24[1048576], array25[1048576];
|
||||
+vec4 array26[1048576], array27[1048576], array28[1048576], array29[1048576], array30[1048576];
|
||||
+vec4 array31[1048576], array32[1048576], array33[1048576], array34[1048576], array35[1048576];
|
||||
+vec4 array36[1048576], array37[1048576], array38[1048576], array39[1048576], array40[1048576];
|
||||
+vec4 array41[1048576], array42[1048576], array43[1048576], array44[1048576], array45[1048576];
|
||||
+vec4 array46[1048576], array47[1048576], array48[1048576], array49[1048576], array50[1048576];
|
||||
+vec4 array51[1048576], array52[1048576], array53[1048576], array54[1048576], array55[1048576];
|
||||
+vec4 array56[1048576], array57[1048576], array58[1048576], array59[1048576], array60[1048576];
|
||||
+vec4 array61[1048576], array62[1048576], array63[1048576], array64[1048576], array65[1048576];
|
||||
+vec4 array66[1048576], array67[1048576], array68[1048576], array69[1048576], array70[1048576];
|
||||
+vec4 array71[1048576], array72[1048576], array73[1048576], array74[1048576], array75[1048576];
|
||||
+vec4 array76[1048576], array77[1048576], array78[1048576], array79[1048576], array80[1048576];
|
||||
+vec4 array81[1048576], array82[1048576], array83[1048576], array84[1048576], array85[1048576];
|
||||
+vec4 array86[1048576], array87[1048576], array88[1048576], array89[1048576], array90[1048576];
|
||||
+vec4 array91[1048576], array92[1048576], array93[1048576], array94[1048576], array95[1048576];
|
||||
+vec4 array96[1048576], array97[1048576], array98[1048576], array99[1048576], array100[1048576];
|
||||
+vec4 array101[1048576], array102[1048576], array103[1048576], array104[1048576], array105[1048576];
|
||||
+vec4 array106[1048576], array107[1048576], array108[1048576], array109[1048576], array110[1048576];
|
||||
+vec4 array111[1048576], array112[1048576], array113[1048576], array114[1048576], array115[1048576];
|
||||
+vec4 array116[1048576], array117[1048576], array118[1048576], array119[1048576], array120[1048576];
|
||||
+vec4 array121[1048576], array122[1048576], array123[1048576], array124[1048576], array125[1048576];
|
||||
+vec4 array126[1048576], array127[1048576], array128[1048576], array129[1048576], array130[1048576];
|
||||
+vec4 array131[1048576], array132[1048576], array133[1048576], array134[1048576], array135[1048576];
|
||||
+vec4 array136[1048576], array137[1048576], array138[1048576], array139[1048576], array140[1048576];
|
||||
+vec4 array141[1048576], array142[1048576], array143[1048576], array144[1048576], array145[1048576];
|
||||
+vec4 array146[1048576], array147[1048576], array148[1048576], array149[1048576], array150[1048576];
|
||||
+vec4 array151[1048576], array152[1048576], array153[1048576], array154[1048576], array155[1048576];
|
||||
+vec4 array156[1048576], array157[1048576], array158[1048576], array159[1048576], array160[1048576];
|
||||
+vec4 array161[1048576], array162[1048576], array163[1048576], array164[1048576], array165[1048576];
|
||||
+vec4 array166[1048576], array167[1048576], array168[1048576], array169[1048576], array170[1048576];
|
||||
+vec4 array171[1048576], array172[1048576], array173[1048576], array174[1048576], array175[1048576];
|
||||
+vec4 array176[1048576], array177[1048576], array178[1048576], array179[1048576], array180[1048576];
|
||||
+vec4 array181[1048576], array182[1048576], array183[1048576], array184[1048576], array185[1048576];
|
||||
+vec4 array186[1048576], array187[1048576], array188[1048576], array189[1048576], array190[1048576];
|
||||
+vec4 array191[1048576], array192[1048576], array193[1048576], array194[1048576], array195[1048576];
|
||||
+vec4 array196[1048576], array197[1048576], array198[1048576], array199[1048576], array200[1048576];
|
||||
+vec4 array201[1048576], array202[1048576], array203[1048576], array204[1048576], array205[1048576];
|
||||
+vec4 array206[1048576], array207[1048576], array208[1048576], array209[1048576], array210[1048576];
|
||||
+vec4 array211[1048576], array212[1048576], array213[1048576], array214[1048576], array215[1048576];
|
||||
+vec4 array216[1048576], array217[1048576], array218[1048576], array219[1048576], array220[1048576];
|
||||
+vec4 array221[1048576], array222[1048576], array223[1048576], array224[1048576], array225[1048576];
|
||||
+vec4 array226[1048576], array227[1048576], array228[1048576], array229[1048576], array230[1048576];
|
||||
+vec4 array231[1048576], array232[1048576], array233[1048576], array234[1048576], array235[1048576];
|
||||
+vec4 array236[1048576], array237[1048576], array238[1048576], array239[1048576], array240[1048576];
|
||||
+vec4 array241[1048576], array242[1048576], array243[1048576], array244[1048576], array245[1048576];
|
||||
+vec4 array246[1048576], array247[1048576], array248[1048576], array249[1048576], array250[1048576];
|
||||
+vec4 array251[1048576], array252[1048576], array253[1048576], array254[1048576], array255[1048576];
|
||||
+vec4 array256[1048576];
|
||||
+
|
||||
+void main()
|
||||
+{
|
||||
+ float f = array[0].x; f += array2[0].x; f += array3[0].x; f += array4[0].x; f += array5[0].x;
|
||||
+ f += array6[0].x; f += array7[0].x; f += array8[0].x; f += array9[0].x; f += array10[0].x;
|
||||
+ f += array11[0].x; f += array12[0].x; f += array13[0].x; f += array14[0].x; f += array15[0].x;
|
||||
+ f += array16[0].x; f += array17[0].x; f += array18[0].x; f += array19[0].x; f += array20[0].x;
|
||||
+ f += array21[0].x; f += array22[0].x; f += array23[0].x; f += array24[0].x; f += array25[0].x;
|
||||
+ f += array26[0].x; f += array27[0].x; f += array28[0].x; f += array29[0].x; f += array30[0].x;
|
||||
+ f += array31[0].x; f += array32[0].x; f += array33[0].x; f += array34[0].x; f += array35[0].x;
|
||||
+ f += array36[0].x; f += array37[0].x; f += array38[0].x; f += array39[0].x; f += array40[0].x;
|
||||
+ f += array41[0].x; f += array42[0].x; f += array43[0].x; f += array44[0].x; f += array45[0].x;
|
||||
+ f += array46[0].x; f += array47[0].x; f += array48[0].x; f += array49[0].x; f += array50[0].x;
|
||||
+ f += array51[0].x; f += array52[0].x; f += array53[0].x; f += array54[0].x; f += array55[0].x;
|
||||
+ f += array56[0].x; f += array57[0].x; f += array58[0].x; f += array59[0].x; f += array60[0].x;
|
||||
+ f += array61[0].x; f += array62[0].x; f += array63[0].x; f += array64[0].x; f += array65[0].x;
|
||||
+ f += array66[0].x; f += array67[0].x; f += array68[0].x; f += array69[0].x; f += array70[0].x;
|
||||
+ f += array71[0].x; f += array72[0].x; f += array73[0].x; f += array74[0].x; f += array75[0].x;
|
||||
+ f += array76[0].x; f += array77[0].x; f += array78[0].x; f += array79[0].x; f += array80[0].x;
|
||||
+ f += array81[0].x; f += array82[0].x; f += array83[0].x; f += array84[0].x; f += array85[0].x;
|
||||
+ f += array86[0].x; f += array87[0].x; f += array88[0].x; f += array89[0].x; f += array90[0].x;
|
||||
+ f += array91[0].x; f += array92[0].x; f += array93[0].x; f += array94[0].x; f += array95[0].x;
|
||||
+ f += array96[0].x; f += array97[0].x; f += array98[0].x; f += array99[0].x; f += array100[0].x;
|
||||
+ f += array101[0].x; f += array102[0].x; f += array103[0].x; f += array104[0].x;
|
||||
+ f += array105[0].x; f += array106[0].x; f += array107[0].x; f += array108[0].x;
|
||||
+ f += array109[0].x; f += array110[0].x; f += array111[0].x; f += array112[0].x;
|
||||
+ f += array113[0].x; f += array114[0].x; f += array115[0].x; f += array116[0].x;
|
||||
+ f += array117[0].x; f += array118[0].x; f += array119[0].x; f += array120[0].x;
|
||||
+ f += array121[0].x; f += array122[0].x; f += array123[0].x; f += array124[0].x;
|
||||
+ f += array125[0].x; f += array126[0].x; f += array127[0].x; f += array128[0].x;
|
||||
+ f += array129[0].x; f += array130[0].x; f += array131[0].x; f += array132[0].x;
|
||||
+ f += array133[0].x; f += array134[0].x; f += array135[0].x; f += array136[0].x;
|
||||
+ f += array137[0].x; f += array138[0].x; f += array139[0].x; f += array140[0].x;
|
||||
+ f += array141[0].x; f += array142[0].x; f += array143[0].x; f += array144[0].x;
|
||||
+ f += array145[0].x; f += array146[0].x; f += array147[0].x; f += array148[0].x;
|
||||
+ f += array149[0].x; f += array150[0].x; f += array151[0].x; f += array152[0].x;
|
||||
+ f += array153[0].x; f += array154[0].x; f += array155[0].x; f += array156[0].x;
|
||||
+ f += array157[0].x; f += array158[0].x; f += array159[0].x; f += array160[0].x;
|
||||
+ f += array161[0].x; f += array162[0].x; f += array163[0].x; f += array164[0].x;
|
||||
+ f += array165[0].x; f += array166[0].x; f += array167[0].x; f += array168[0].x;
|
||||
+ f += array169[0].x; f += array170[0].x; f += array171[0].x; f += array172[0].x;
|
||||
+ f += array173[0].x; f += array174[0].x; f += array175[0].x; f += array176[0].x;
|
||||
+ f += array177[0].x; f += array178[0].x; f += array179[0].x; f += array180[0].x;
|
||||
+ f += array181[0].x; f += array182[0].x; f += array183[0].x; f += array184[0].x;
|
||||
+ f += array185[0].x; f += array186[0].x; f += array187[0].x; f += array188[0].x;
|
||||
+ f += array189[0].x; f += array190[0].x; f += array191[0].x; f += array192[0].x;
|
||||
+ f += array193[0].x; f += array194[0].x; f += array195[0].x; f += array196[0].x;
|
||||
+ f += array197[0].x; f += array198[0].x; f += array199[0].x; f += array200[0].x;
|
||||
+ f += array201[0].x; f += array202[0].x; f += array203[0].x; f += array204[0].x;
|
||||
+ f += array205[0].x; f += array206[0].x; f += array207[0].x; f += array208[0].x;
|
||||
+ f += array209[0].x; f += array210[0].x; f += array211[0].x; f += array212[0].x;
|
||||
+ f += array213[0].x; f += array214[0].x; f += array215[0].x; f += array216[0].x;
|
||||
+ f += array217[0].x; f += array218[0].x; f += array219[0].x; f += array220[0].x;
|
||||
+ f += array221[0].x; f += array222[0].x; f += array223[0].x; f += array224[0].x;
|
||||
+ f += array225[0].x; f += array226[0].x; f += array227[0].x; f += array228[0].x;
|
||||
+ f += array229[0].x; f += array230[0].x; f += array231[0].x; f += array232[0].x;
|
||||
+ f += array233[0].x; f += array234[0].x; f += array235[0].x; f += array236[0].x;
|
||||
+ f += array237[0].x; f += array238[0].x; f += array239[0].x; f += array240[0].x;
|
||||
+ f += array241[0].x; f += array242[0].x; f += array243[0].x; f += array244[0].x;
|
||||
+ f += array245[0].x; f += array246[0].x; f += array247[0].x; f += array248[0].x;
|
||||
+ f += array249[0].x; f += array250[0].x; f += array251[0].x; f += array252[0].x;
|
||||
+ f += array253[0].x; f += array254[0].x; f += array255[0].x; f += array256[0].x;
|
||||
+ if (f == 2.0)
|
||||
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
+ else
|
||||
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
+})";
|
||||
+
|
||||
GLuint program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalMemory1);
|
||||
EXPECT_EQ(0u, program);
|
||||
|
||||
@@ -5449,6 +5574,9 @@
|
||||
|
||||
program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalAndLocalMemory2);
|
||||
EXPECT_EQ(0u, program);
|
||||
+
|
||||
+ program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalMemoryOverflow);
|
||||
+ EXPECT_EQ(0u, program);
|
||||
}
|
||||
|
||||
// Linking should fail when corresponding vertex/fragment uniform blocks have different precision
|
||||
286
patches/angle/cherry-pick-cafe56b591ed.patch
Normal file
286
patches/angle/cherry-pick-cafe56b591ed.patch
Normal file
@@ -0,0 +1,286 @@
|
||||
From cafe56b591edb77f041be70b58cac3a61565644a Mon Sep 17 00:00:00 2001
|
||||
From: Geoff Lang <geofflang@chromium.org>
|
||||
Date: Fri, 23 Jun 2023 14:46:28 -0400
|
||||
Subject: [PATCH] M116: GL: Ensure all instanced attributes have a buffer with data
|
||||
|
||||
Apple OpenGL drivers sometimes crash when given an instanced draw with
|
||||
a buffer that has never been given data.
|
||||
|
||||
It's not efficient to check if the attribute is both zero-sized and
|
||||
instanced so just ensure that every time a zero-sized buffer is bound
|
||||
to an attribute, it gets initialized with some data.
|
||||
|
||||
Bug: chromium:1456243
|
||||
Change-Id: I66b7c7017843153db2df3bc50010cba765d03c5f
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4642048
|
||||
Commit-Queue: Geoff Lang <geofflang@chromium.org>
|
||||
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
(cherry picked from commit 4e6124dae892690204f8e5996aeaad14f45e0a97)
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4727452
|
||||
---
|
||||
|
||||
diff --git a/include/platform/FeaturesGL_autogen.h b/include/platform/FeaturesGL_autogen.h
|
||||
index aa0565c..2f6e094 100644
|
||||
--- a/include/platform/FeaturesGL_autogen.h
|
||||
+++ b/include/platform/FeaturesGL_autogen.h
|
||||
@@ -501,6 +501,12 @@
|
||||
"supportsShaderPixelLocalStorageEXT", FeatureCategory::OpenGLFeatures,
|
||||
"Backend GL context supports EXT_shader_pixel_local_storage extension", &members,
|
||||
"http://anglebug.com/7279"};
|
||||
+
|
||||
+ FeatureInfo ensureNonEmptyBufferIsBoundForDraw = {
|
||||
+ "ensureNonEmptyBufferIsBoundForDraw", FeatureCategory::OpenGLFeatures,
|
||||
+ "Apple OpenGL drivers crash when drawing with a zero-sized buffer bound using a non-zero "
|
||||
+ "divisor.",
|
||||
+ &members, "http://crbug.com/1456243"};
|
||||
};
|
||||
|
||||
inline FeaturesGL::FeaturesGL() = default;
|
||||
diff --git a/include/platform/gl_features.json b/include/platform/gl_features.json
|
||||
index 032f29a..b358cea 100644
|
||||
--- a/include/platform/gl_features.json
|
||||
+++ b/include/platform/gl_features.json
|
||||
@@ -699,6 +699,14 @@
|
||||
"Backend GL context supports EXT_shader_pixel_local_storage extension"
|
||||
],
|
||||
"issue": "http://anglebug.com/7279"
|
||||
+ },
|
||||
+ {
|
||||
+ "name": "ensure_non_empty_buffer_is_bound_for_draw",
|
||||
+ "category": "Features",
|
||||
+ "description": [
|
||||
+ "Apple OpenGL drivers crash when drawing with a zero-sized buffer bound using a non-zero divisor."
|
||||
+ ],
|
||||
+ "issue": "http://crbug.com/1456243"
|
||||
}
|
||||
]
|
||||
}
|
||||
diff --git a/scripts/code_generation_hashes/ANGLE_features.json b/scripts/code_generation_hashes/ANGLE_features.json
|
||||
index d4576c2..503001c 100644
|
||||
--- a/scripts/code_generation_hashes/ANGLE_features.json
|
||||
+++ b/scripts/code_generation_hashes/ANGLE_features.json
|
||||
@@ -2,7 +2,7 @@
|
||||
"include/platform/FeaturesD3D_autogen.h":
|
||||
"9923fb44d0a6f31948d0c8f46ee1d9e2",
|
||||
"include/platform/FeaturesGL_autogen.h":
|
||||
- "a795a806d71b0e6d1f9e6d95c6e11971",
|
||||
+ "fef16ab3946346a2a7d5b76bb39471a4",
|
||||
"include/platform/FeaturesMtl_autogen.h":
|
||||
"407426c8874de9295482ace9c94bd812",
|
||||
"include/platform/FeaturesVk_autogen.h":
|
||||
@@ -16,13 +16,13 @@
|
||||
"include/platform/gen_features.py":
|
||||
"062989f7a8f3ff3b383f98fc8908dc33",
|
||||
"include/platform/gl_features.json":
|
||||
- "3335055a70e35ebb7bf74c6d7c58897b",
|
||||
+ "c9aead89696e7fd0c8bfe5c5ca85ca63",
|
||||
"include/platform/mtl_features.json":
|
||||
"c66d170e7a8eb3448030f4c423ed0133",
|
||||
"include/platform/vk_features.json":
|
||||
"416bbb28b9fa1a3c4ef141f243c0a9e6",
|
||||
"util/angle_features_autogen.cpp":
|
||||
- "73169f63c755192c3b4bd27d6f4096ca",
|
||||
+ "288daaec490eb816883d744f108d74c9",
|
||||
"util/angle_features_autogen.h":
|
||||
- "7aa8120eb8f8fd335946b8c27074745d"
|
||||
+ "daf25d3e4ffea143d1c082416513f7e7"
|
||||
}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/libANGLE/renderer/gl/BufferGL.cpp b/src/libANGLE/renderer/gl/BufferGL.cpp
|
||||
index c99fd5d..9651838 100644
|
||||
--- a/src/libANGLE/renderer/gl/BufferGL.cpp
|
||||
+++ b/src/libANGLE/renderer/gl/BufferGL.cpp
|
||||
@@ -296,6 +296,11 @@
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
+size_t BufferGL::getBufferSize() const
|
||||
+{
|
||||
+ return mBufferSize;
|
||||
+}
|
||||
+
|
||||
GLuint BufferGL::getBufferID() const
|
||||
{
|
||||
return mBufferID;
|
||||
diff --git a/src/libANGLE/renderer/gl/BufferGL.h b/src/libANGLE/renderer/gl/BufferGL.h
|
||||
index 7b57594..fe9138e 100644
|
||||
--- a/src/libANGLE/renderer/gl/BufferGL.h
|
||||
+++ b/src/libANGLE/renderer/gl/BufferGL.h
|
||||
@@ -56,6 +56,7 @@
|
||||
bool primitiveRestartEnabled,
|
||||
gl::IndexRange *outRange) override;
|
||||
|
||||
+ size_t getBufferSize() const;
|
||||
GLuint getBufferID() const;
|
||||
|
||||
private:
|
||||
diff --git a/src/libANGLE/renderer/gl/VertexArrayGL.cpp b/src/libANGLE/renderer/gl/VertexArrayGL.cpp
|
||||
index dc981de..fda9099 100644
|
||||
--- a/src/libANGLE/renderer/gl/VertexArrayGL.cpp
|
||||
+++ b/src/libANGLE/renderer/gl/VertexArrayGL.cpp
|
||||
@@ -646,6 +646,7 @@
|
||||
|
||||
angle::Result VertexArrayGL::updateAttribPointer(const gl::Context *context, size_t attribIndex)
|
||||
{
|
||||
+ const angle::FeaturesGL &features = GetFeaturesGL(context);
|
||||
|
||||
const VertexAttribute &attrib = mState.getVertexAttribute(attribIndex);
|
||||
|
||||
@@ -687,8 +688,16 @@
|
||||
// is not NULL.
|
||||
|
||||
StateManagerGL *stateManager = GetStateManagerGL(context);
|
||||
- GLuint bufferId = GetNativeBufferID(arrayBuffer);
|
||||
+ BufferGL *bufferGL = GetImplAs<BufferGL>(arrayBuffer);
|
||||
+ GLuint bufferId = bufferGL->getBufferID();
|
||||
stateManager->bindBuffer(gl::BufferBinding::Array, bufferId);
|
||||
+ if (features.ensureNonEmptyBufferIsBoundForDraw.enabled && bufferGL->getBufferSize() == 0)
|
||||
+ {
|
||||
+ constexpr uint32_t data = 0;
|
||||
+ ANGLE_TRY(bufferGL->setData(context, gl::BufferBinding::Array, &data, sizeof(data),
|
||||
+ gl::BufferUsage::StaticDraw));
|
||||
+ ASSERT(bufferGL->getBufferSize() > 0);
|
||||
+ }
|
||||
ANGLE_TRY(callVertexAttribPointer(context, static_cast<GLuint>(attribIndex), attrib,
|
||||
binding.getStride(), binding.getOffset()));
|
||||
|
||||
diff --git a/src/libANGLE/renderer/gl/renderergl_utils.cpp b/src/libANGLE/renderer/gl/renderergl_utils.cpp
|
||||
index 6911247..ab2a608 100644
|
||||
--- a/src/libANGLE/renderer/gl/renderergl_utils.cpp
|
||||
+++ b/src/libANGLE/renderer/gl/renderergl_utils.cpp
|
||||
@@ -2465,6 +2465,9 @@
|
||||
// EXT_shader_pixel_local_storage
|
||||
ANGLE_FEATURE_CONDITION(features, supportsShaderPixelLocalStorageEXT,
|
||||
functions->hasGLESExtension("GL_EXT_shader_pixel_local_storage"));
|
||||
+
|
||||
+ // http://crbug.com/1456243
|
||||
+ ANGLE_FEATURE_CONDITION(features, ensureNonEmptyBufferIsBoundForDraw, IsApple() || IsAndroid());
|
||||
}
|
||||
|
||||
void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
|
||||
diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt
|
||||
index 59ec7c2..44ff3e4 100644
|
||||
--- a/src/tests/angle_end2end_tests_expectations.txt
|
||||
+++ b/src/tests/angle_end2end_tests_expectations.txt
|
||||
@@ -380,6 +380,7 @@
|
||||
7294 WIN D3D11 : StateChangeTestES3.StencilWriteMask/* = SKIP
|
||||
7316 WIN D3D11 : StateChangeTestES3.StencilTestAndFunc/* = SKIP
|
||||
7329 WIN D3D11 : StateChangeTestES3.PrimitiveRestart/* = SKIP
|
||||
+1456243 WIN D3D11 : WebGL2CompatibilityTest.DrawWithZeroSizedBuffer/* = SKIP
|
||||
|
||||
// Android
|
||||
6095 ANDROID GLES : GLSLTest_ES3.InitGlobalComplexConstant/* = SKIP
|
||||
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
|
||||
index 7dc56cd..bd7ecd1 100644
|
||||
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
|
||||
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
|
||||
@@ -1632,10 +1632,10 @@
|
||||
|
||||
constexpr GLuint kMaxIntAsGLuint = static_cast<GLuint>(std::numeric_limits<GLint>::max());
|
||||
constexpr GLuint kIndexData[] = {
|
||||
- kMaxIntAsGLuint,
|
||||
- kMaxIntAsGLuint + 1,
|
||||
- kMaxIntAsGLuint + 2,
|
||||
- kMaxIntAsGLuint + 3,
|
||||
+ kMaxIntAsGLuint,
|
||||
+ kMaxIntAsGLuint + 1,
|
||||
+ kMaxIntAsGLuint + 2,
|
||||
+ kMaxIntAsGLuint + 3,
|
||||
};
|
||||
|
||||
GLBuffer indexBuffer;
|
||||
@@ -3687,8 +3687,8 @@
|
||||
|
||||
constexpr float readPixelsData[] = {-5000.0f, 0.0f, 0.0f, 1.0f};
|
||||
const GLushort textureData[] = {
|
||||
- gl::float32ToFloat16(readPixelsData[0]), gl::float32ToFloat16(readPixelsData[1]),
|
||||
- gl::float32ToFloat16(readPixelsData[2]), gl::float32ToFloat16(readPixelsData[3])};
|
||||
+ gl::float32ToFloat16(readPixelsData[0]), gl::float32ToFloat16(readPixelsData[1]),
|
||||
+ gl::float32ToFloat16(readPixelsData[2]), gl::float32ToFloat16(readPixelsData[3])};
|
||||
|
||||
for (auto extension : FloatingPointTextureExtensions)
|
||||
{
|
||||
@@ -3748,8 +3748,8 @@
|
||||
|
||||
constexpr float readPixelsData[] = {7108.0f, -10.0f, 0.0f, 1.0f};
|
||||
const GLushort textureData[] = {
|
||||
- gl::float32ToFloat16(readPixelsData[0]), gl::float32ToFloat16(readPixelsData[1]),
|
||||
- gl::float32ToFloat16(readPixelsData[2]), gl::float32ToFloat16(readPixelsData[3])};
|
||||
+ gl::float32ToFloat16(readPixelsData[0]), gl::float32ToFloat16(readPixelsData[1]),
|
||||
+ gl::float32ToFloat16(readPixelsData[2]), gl::float32ToFloat16(readPixelsData[3])};
|
||||
|
||||
for (auto extension : FloatingPointTextureExtensions)
|
||||
{
|
||||
@@ -3811,8 +3811,8 @@
|
||||
|
||||
constexpr float readPixelsData[] = {7000.0f, 100.0f, 33.0f, 1.0f};
|
||||
const GLushort textureData[] = {
|
||||
- gl::float32ToFloat16(readPixelsData[0]), gl::float32ToFloat16(readPixelsData[1]),
|
||||
- gl::float32ToFloat16(readPixelsData[2]), gl::float32ToFloat16(readPixelsData[3])};
|
||||
+ gl::float32ToFloat16(readPixelsData[0]), gl::float32ToFloat16(readPixelsData[1]),
|
||||
+ gl::float32ToFloat16(readPixelsData[2]), gl::float32ToFloat16(readPixelsData[3])};
|
||||
|
||||
for (auto extension : FloatingPointTextureExtensions)
|
||||
{
|
||||
@@ -3874,8 +3874,8 @@
|
||||
|
||||
constexpr float readPixelsData[] = {7000.0f, 100.0f, 33.0f, -1.0f};
|
||||
const GLushort textureData[] = {
|
||||
- gl::float32ToFloat16(readPixelsData[0]), gl::float32ToFloat16(readPixelsData[1]),
|
||||
- gl::float32ToFloat16(readPixelsData[2]), gl::float32ToFloat16(readPixelsData[3])};
|
||||
+ gl::float32ToFloat16(readPixelsData[0]), gl::float32ToFloat16(readPixelsData[1]),
|
||||
+ gl::float32ToFloat16(readPixelsData[2]), gl::float32ToFloat16(readPixelsData[3])};
|
||||
|
||||
for (auto extension : FloatingPointTextureExtensions)
|
||||
{
|
||||
@@ -5803,6 +5803,26 @@
|
||||
}
|
||||
}
|
||||
|
||||
+// Test for a mishandling of instanced vertex attributes with zero-sized buffers bound on Apple
|
||||
+// OpenGL drivers.
|
||||
+TEST_P(WebGL2CompatibilityTest, DrawWithZeroSizedBuffer)
|
||||
+{
|
||||
+ ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
|
||||
+ glUseProgram(program);
|
||||
+
|
||||
+ GLBuffer buffer;
|
||||
+ glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
+
|
||||
+ GLint posLocation = glGetAttribLocation(program, essl3_shaders::PositionAttrib());
|
||||
+ glEnableVertexAttribArray(posLocation);
|
||||
+
|
||||
+ glVertexAttribDivisor(posLocation, 1);
|
||||
+ glVertexAttribPointer(posLocation, 1, GL_UNSIGNED_BYTE, GL_FALSE, 9,
|
||||
+ reinterpret_cast<void *>(0x41424344));
|
||||
+
|
||||
+ glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
+}
|
||||
+
|
||||
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(WebGLCompatibilityTest);
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WebGL2CompatibilityTest);
|
||||
diff --git a/util/angle_features_autogen.cpp b/util/angle_features_autogen.cpp
|
||||
index adb9610..a060dd2 100644
|
||||
--- a/util/angle_features_autogen.cpp
|
||||
+++ b/util/angle_features_autogen.cpp
|
||||
@@ -118,6 +118,7 @@
|
||||
{Feature::EnablePrecisionQualifiers, "enablePrecisionQualifiers"},
|
||||
{Feature::EnablePreRotateSurfaces, "enablePreRotateSurfaces"},
|
||||
{Feature::EnableProgramBinaryForCapture, "enableProgramBinaryForCapture"},
|
||||
+ {Feature::EnsureNonEmptyBufferIsBoundForDraw, "ensureNonEmptyBufferIsBoundForDraw"},
|
||||
{Feature::ExpandIntegerPowExpressions, "expandIntegerPowExpressions"},
|
||||
{Feature::ExplicitlyEnablePerSampleShading, "explicitlyEnablePerSampleShading"},
|
||||
{Feature::ExposeNonConformantExtensionsAndVersions, "exposeNonConformantExtensionsAndVersions"},
|
||||
diff --git a/util/angle_features_autogen.h b/util/angle_features_autogen.h
|
||||
index 3d8c47f..4064425 100644
|
||||
--- a/util/angle_features_autogen.h
|
||||
+++ b/util/angle_features_autogen.h
|
||||
@@ -112,6 +112,7 @@
|
||||
EnablePrecisionQualifiers,
|
||||
EnablePreRotateSurfaces,
|
||||
EnableProgramBinaryForCapture,
|
||||
+ EnsureNonEmptyBufferIsBoundForDraw,
|
||||
ExpandIntegerPowExpressions,
|
||||
ExplicitlyEnablePerSampleShading,
|
||||
ExposeNonConformantExtensionsAndVersions,
|
||||
@@ -20,7 +20,7 @@ index 2ca14efae5ea478f43794a81883b00dfdb1a37b0..d73055fbf39334925ef4b4804bbaca57
|
||||
|
||||
case ssl_open_record_error:
|
||||
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc
|
||||
index 838761af5cb8498d8bcb66b1a7a6f9c1a233cac7..b9bda24dd4d372485622ff99873ee34ee4bd9684 100644
|
||||
index d7b5be3ddeec762a3353baefc67d659c9aba68f5..82bf00311b36bdbc948ae14f808c78fd2f71ca54 100644
|
||||
--- a/ssl/ssl_lib.cc
|
||||
+++ b/ssl/ssl_lib.cc
|
||||
@@ -1333,7 +1333,7 @@ int SSL_get_error(const SSL *ssl, int ret_code) {
|
||||
@@ -32,7 +32,7 @@ index 838761af5cb8498d8bcb66b1a7a6f9c1a233cac7..b9bda24dd4d372485622ff99873ee34e
|
||||
return SSL_ERROR_ZERO_RETURN;
|
||||
}
|
||||
// An EOF was observed which violates the protocol, and the underlying
|
||||
@@ -2622,13 +2622,7 @@ void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) {
|
||||
@@ -2695,13 +2695,7 @@ void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) {
|
||||
return CRYPTO_get_ex_data(&ctx->ex_data, idx);
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,6 @@ make_gtk_getlibgtk_public.patch
|
||||
build_disable_print_content_analysis.patch
|
||||
custom_protocols_plzserviceworker.patch
|
||||
feat_filter_out_non-shareable_windows_in_the_current_application_in.patch
|
||||
fix_allow_guest_webcontents_to_enter_fullscreen.patch
|
||||
disable_freezing_flags_after_init_in_node.patch
|
||||
short-circuit_permissions_checks_in_mediastreamdevicescontroller.patch
|
||||
chore_add_electron_deps_to_gitignores.patch
|
||||
@@ -127,3 +126,14 @@ chore_defer_usb_service_getdevices_request_until_usb_service_is.patch
|
||||
fix_remove_profiles_from_spellcheck_service.patch
|
||||
chore_patch_out_profile_methods_in_chrome_browser_pdf.patch
|
||||
chore_patch_out_profile_methods_in_titlebar_config.patch
|
||||
fix_crash_on_nativetheme_change_during_context_menu_close.patch
|
||||
potential_fix_for_flaky_desktopcaptureapitest_delegation_unittest.patch
|
||||
fix_select_the_first_menu_item_when_opened_via_keyboard.patch
|
||||
chore_add_buildflag_guard_around_new_include.patch
|
||||
fix_use_delegated_generic_capturer_when_available.patch
|
||||
revert_remove_the_allowaggressivethrottlingwithwebsocket_feature.patch
|
||||
cherry-pick-b11e7d07a6f4.patch
|
||||
cherry-pick-f218b4f37018.patch
|
||||
cherry-pick-d756d71a652c.patch
|
||||
parameterize_axtreeserializer_by_vector_type.patch
|
||||
avoid_allocating_recordid_objects_in_elementtiming_and_lcp.patch
|
||||
|
||||
@@ -10,10 +10,10 @@ Allows Electron to restore WER when ELECTRON_DEFAULT_ERROR_MODE is set.
|
||||
This should be upstreamed.
|
||||
|
||||
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc
|
||||
index c641da1b1f096a41c708737435140691a501c431..4e9940c00bad3f0ba72c0b32833a0d0df095c61e 100644
|
||||
index 280c8b9d08a35c7fbe9e352f2f71ed104cbde955..12bbcb8518110a5f4873e4f4a89e43c8920ec7b6 100644
|
||||
--- a/content/gpu/gpu_main.cc
|
||||
+++ b/content/gpu/gpu_main.cc
|
||||
@@ -258,6 +258,10 @@ int GpuMain(MainFunctionParams parameters) {
|
||||
@@ -260,6 +260,10 @@ int GpuMain(MainFunctionParams parameters) {
|
||||
// to the GpuProcessHost once the GpuServiceImpl has started.
|
||||
viz::GpuServiceImpl::InstallPreInitializeLogHandler();
|
||||
|
||||
@@ -24,7 +24,7 @@ index c641da1b1f096a41c708737435140691a501c431..4e9940c00bad3f0ba72c0b32833a0d0d
|
||||
// We are experiencing what appear to be memory-stomp issues in the GPU
|
||||
// process. These issues seem to be impacting the task executor and listeners
|
||||
// registered to it. Create the task executor on the heap to guard against
|
||||
@@ -342,7 +346,6 @@ int GpuMain(MainFunctionParams parameters) {
|
||||
@@ -344,7 +348,6 @@ int GpuMain(MainFunctionParams parameters) {
|
||||
const_cast<base::CommandLine*>(&command_line), gpu_preferences);
|
||||
const bool dead_on_arrival = !init_success;
|
||||
|
||||
|
||||
@@ -23,10 +23,10 @@ index 103a9d9fb17e954ecaf0acecaa3eeafc23e39c94..de299316216dba204decba3b0eb57f5c
|
||||
int32_t world_id) {}
|
||||
virtual void DidClearWindowObject() {}
|
||||
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
|
||||
index 1a0e197b5fe5b698671ddcb0660b69669939ebc2..b1978947e3dc568ea3badcd21dfdb4d089c791e5 100644
|
||||
index 68cc76c0f63f3f828ab582dab88f893453144b2a..5547fb35630d2f2c24b21640a90b8c0858f604ce 100644
|
||||
--- a/content/renderer/render_frame_impl.cc
|
||||
+++ b/content/renderer/render_frame_impl.cc
|
||||
@@ -4416,6 +4416,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
|
||||
@@ -4438,6 +4438,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
|
||||
observer.DidCreateScriptContext(context, world_id);
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ index 93acf68fbb7ff9b3bfc414a33fa1cdda4fe73bb1..90ec3437c2c94e87cfd0b25b200729c1
|
||||
virtual void WillReleaseScriptContext(v8::Local<v8::Context>,
|
||||
int32_t world_id) {}
|
||||
diff --git a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
|
||||
index 62b35b9fa47f0b99f2b7b6bc712b3a4b2c1c8e4e..4a0fdbb120edc76647560fb86d95613c95ae7094 100644
|
||||
index 1cada05806cb35a82822507f708d43979d97de61..f8e063397b161b7501308945a7df9fb89ea7d165 100644
|
||||
--- a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
|
||||
+++ b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
|
||||
@@ -198,6 +198,7 @@ void LocalWindowProxy::Initialize() {
|
||||
@@ -79,10 +79,10 @@ index 62b35b9fa47f0b99f2b7b6bc712b3a4b2c1c8e4e..4a0fdbb120edc76647560fb86d95613c
|
||||
if (World().IsMainWorld()) {
|
||||
probe::DidCreateMainWorldContext(GetFrame());
|
||||
diff --git a/third_party/blink/renderer/core/frame/local_frame_client.h b/third_party/blink/renderer/core/frame/local_frame_client.h
|
||||
index 6068419926ed24e8269905c7cfe89c429071fb9c..d48eb2cec03dd3186377d23b0e93097719ab0298 100644
|
||||
index 62e611ec3ac95eac88d4665d2640429e9d833594..7bf646d6cd8eaf29267b6136de0952e2545ec503 100644
|
||||
--- a/third_party/blink/renderer/core/frame/local_frame_client.h
|
||||
+++ b/third_party/blink/renderer/core/frame/local_frame_client.h
|
||||
@@ -321,6 +321,8 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
|
||||
@@ -319,6 +319,8 @@ class CORE_EXPORT LocalFrameClient : public FrameClient {
|
||||
|
||||
virtual void DidCreateScriptContext(v8::Local<v8::Context>,
|
||||
int32_t world_id) = 0;
|
||||
@@ -92,7 +92,7 @@ index 6068419926ed24e8269905c7cfe89c429071fb9c..d48eb2cec03dd3186377d23b0e930977
|
||||
int32_t world_id) = 0;
|
||||
virtual bool AllowScriptExtensions() = 0;
|
||||
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
|
||||
index feed61542c8cd66744c1fbc0ba412879f3696035..1bf7b85147499b185189eab49bd6e2786751c0b1 100644
|
||||
index dbf7fd73a855f7d45eeeeff17582696aac66ff0d..9b489f661f524f380523e38518345e9b22eb8dec 100644
|
||||
--- a/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
|
||||
+++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.cc
|
||||
@@ -283,6 +283,13 @@ void LocalFrameClientImpl::DidCreateScriptContext(
|
||||
@@ -110,7 +110,7 @@ index feed61542c8cd66744c1fbc0ba412879f3696035..1bf7b85147499b185189eab49bd6e278
|
||||
v8::Local<v8::Context> context,
|
||||
int32_t world_id) {
|
||||
diff --git a/third_party/blink/renderer/core/frame/local_frame_client_impl.h b/third_party/blink/renderer/core/frame/local_frame_client_impl.h
|
||||
index 8ea11a5c27365a234cae9ec00eaa83ad2d2aa69a..3d2eed6318fe899e1b7e9625c7b3e2781aa2e65d 100644
|
||||
index 28e1c00e05e74d5a79f32897e57a854ff14ce7a9..1cd704b1bb53eaf226d1c72c97e3f765a4b1f10e 100644
|
||||
--- a/third_party/blink/renderer/core/frame/local_frame_client_impl.h
|
||||
+++ b/third_party/blink/renderer/core/frame/local_frame_client_impl.h
|
||||
@@ -84,6 +84,8 @@ class CORE_EXPORT LocalFrameClientImpl final : public LocalFrameClient {
|
||||
@@ -123,7 +123,7 @@ index 8ea11a5c27365a234cae9ec00eaa83ad2d2aa69a..3d2eed6318fe899e1b7e9625c7b3e278
|
||||
int32_t world_id) override;
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h
|
||||
index bd4592a4f10d1370c72caf5c153cf831d5a55d7b..cc4d49cb14f5b259777a9b8023388175825ce8cf 100644
|
||||
index 1934ca82e3e26e0f5c4f2f7b417df6bcd6e66abf..1277b858f2d5b4b0a0dd1c97282eff0d763cdc2b 100644
|
||||
--- a/third_party/blink/renderer/core/loader/empty_clients.h
|
||||
+++ b/third_party/blink/renderer/core/loader/empty_clients.h
|
||||
@@ -403,6 +403,8 @@ class CORE_EXPORT EmptyLocalFrameClient : public LocalFrameClient {
|
||||
|
||||
@@ -7,10 +7,10 @@ Ensure that licenses for the dependencies introduced by Electron
|
||||
are included in `LICENSES.chromium.html`
|
||||
|
||||
diff --git a/tools/licenses/licenses.py b/tools/licenses/licenses.py
|
||||
index d775931a09f38db3eb472d095d461b50c5ef76f0..9d844edc8f7c2f526fa99804e8a072da1f47c656 100755
|
||||
index 2a6a4733128dfc5916163c1c91c26f27da1d2f0a..f248f68e22d94b5762f0a64e0fe6804eef1d61d1 100755
|
||||
--- a/tools/licenses/licenses.py
|
||||
+++ b/tools/licenses/licenses.py
|
||||
@@ -383,6 +383,31 @@ SPECIAL_CASES = {
|
||||
@@ -413,6 +413,31 @@ SPECIAL_CASES = {
|
||||
"License": "Apache 2.0",
|
||||
"License File": "/third_party/selenium-atoms/LICENSE.closure",
|
||||
},
|
||||
@@ -41,4 +41,4 @@ index d775931a09f38db3eb472d095d461b50c5ef76f0..9d844edc8f7c2f526fa99804e8a072da
|
||||
+ },
|
||||
}
|
||||
|
||||
# Special value for 'License File' field used to indicate that the license file
|
||||
# Soon-to-be-deprecated special value for 'License File' field used to indicate
|
||||
|
||||
@@ -6,10 +6,10 @@ Subject: allow disabling blink scheduler throttling per RenderView
|
||||
This allows us to disable throttling for hidden windows.
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
|
||||
index 3b059b6121562dba8ec7c4483388408100d8ef26..0eb07c514883975f39b1a98ccfe65028e4c2ad75 100644
|
||||
index 421a0b8ba291a944db62507d1004210555a1200c..09dd63d9f9a59d32dc9dd569aaa176a94dbfdfaa 100644
|
||||
--- a/content/browser/renderer_host/render_view_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_view_host_impl.cc
|
||||
@@ -700,6 +700,11 @@ void RenderViewHostImpl::SetBackgroundOpaque(bool opaque) {
|
||||
@@ -710,6 +710,11 @@ void RenderViewHostImpl::SetBackgroundOpaque(bool opaque) {
|
||||
GetWidget()->GetAssociatedFrameWidget()->SetBackgroundOpaque(opaque);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,21 @@ index 180abdc9f983887c83fd9d4a596472222e9ab472..00842717a7570561ee9e3eca11190ab5
|
||||
void SendWebPreferencesToRenderer();
|
||||
void SendRendererPreferencesToRenderer(
|
||||
const blink::RendererPreferences& preferences);
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
index 9716c8f8a5fe15ffabe4eeedb7b5b35a57b61bac..75796596daeda51d303856ae767e2bae9b9d2d18 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
@@ -554,8 +554,8 @@ void RenderWidgetHostViewAura::ShowImpl(PageVisibilityState page_visibility) {
|
||||
// OnShowWithPageVisibility will not call NotifyHostAndDelegateOnWasShown,
|
||||
// which updates `visibility_`, unless the host is hidden. Make sure no update
|
||||
// is needed.
|
||||
- DCHECK(host_->is_hidden() || visibility_ == Visibility::VISIBLE);
|
||||
- OnShowWithPageVisibility(page_visibility);
|
||||
+ if (host_->is_hidden() || visibility_ == Visibility::VISIBLE)
|
||||
+ OnShowWithPageVisibility(page_visibility);
|
||||
}
|
||||
|
||||
void RenderWidgetHostViewAura::NotifyHostAndDelegateOnWasShown(
|
||||
diff --git a/content/public/browser/render_view_host.h b/content/public/browser/render_view_host.h
|
||||
index 9979c25ecd57e68331b628a518368635db5c2027..32733bf951af3eff7da5fd5758bbcbaa49ff0e3c 100644
|
||||
--- a/content/public/browser/render_view_host.h
|
||||
@@ -47,14 +62,26 @@ index 9979c25ecd57e68331b628a518368635db5c2027..32733bf951af3eff7da5fd5758bbcbaa
|
||||
private:
|
||||
// This interface should only be implemented inside content.
|
||||
friend class RenderViewHostImpl;
|
||||
diff --git a/content/test/test_page_broadcast.h b/content/test/test_page_broadcast.h
|
||||
index 73c0f64aa84061381a98ba60906835258f881468..41bdf7e231eca4617dbe53737a3925039bf77c4f 100644
|
||||
--- a/content/test/test_page_broadcast.h
|
||||
+++ b/content/test/test_page_broadcast.h
|
||||
@@ -45,6 +45,7 @@ class TestPageBroadcast : public blink::mojom::PageBroadcast {
|
||||
override;
|
||||
void UpdatePageBrowsingContextGroup(const blink::BrowsingContextGroupInfo&
|
||||
browsing_context_group_info) override;
|
||||
+ void SetSchedulerThrottling(bool allowed) override {}
|
||||
|
||||
mojo::AssociatedReceiver<blink::mojom::PageBroadcast> receiver_;
|
||||
};
|
||||
diff --git a/third_party/blink/public/mojom/page/page.mojom b/third_party/blink/public/mojom/page/page.mojom
|
||||
index d18c66114870de83c7eef21578e9e2b8d5606a8b..e1defb3992289427df85963f44a705e3d9257342 100644
|
||||
index d3877e946b1d65eba5bb45efe786fbcc7925ca6e..73bd5056baf7e4278b7260e550e2b8516be72f20 100644
|
||||
--- a/third_party/blink/public/mojom/page/page.mojom
|
||||
+++ b/third_party/blink/public/mojom/page/page.mojom
|
||||
@@ -149,4 +149,7 @@ interface PageBroadcast {
|
||||
mojo_base.mojom.UnguessableToken devtools_frame_token,
|
||||
RemoteFrameInterfacesFromBrowser remote_frame_interfaces,
|
||||
RemoteMainFrameInterfaces remote_main_frame_interfaces);
|
||||
@@ -155,4 +155,7 @@ interface PageBroadcast {
|
||||
// in `browsing_context_group_info`.
|
||||
UpdatePageBrowsingContextGroup(
|
||||
blink.mojom.BrowsingContextGroupInfo browsing_context_group_info);
|
||||
+
|
||||
+ // Whether to enable the Renderer scheduler background throttling.
|
||||
+ SetSchedulerThrottling(bool allowed);
|
||||
@@ -72,10 +99,20 @@ index 8a18ecf567cd3a6a2fb1627083a5544a93198bf4..8b6436f3ba6c8bfc2cba054e77ab8886
|
||||
// Visibility -----------------------------------------------------------
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
|
||||
index a1bcdb3b7ceb5bed96b4c442268e3b7ddb490fa4..acda9f8ea1789d3febc0386ae855c009ea462816 100644
|
||||
index 3fd94156edd9868f0d46746227ae40da604bbc2c..6ce650e2fc879ae135e5bb731750f8929b592f17 100644
|
||||
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
|
||||
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
|
||||
@@ -3833,13 +3833,21 @@ PageScheduler* WebViewImpl::Scheduler() const {
|
||||
@@ -2386,6 +2386,9 @@ void WebViewImpl::SetPageLifecycleStateInternal(
|
||||
TRACE_EVENT2("navigation", "WebViewImpl::SetPageLifecycleStateInternal",
|
||||
"old_state", old_state, "new_state", new_state);
|
||||
|
||||
+ if (!scheduler_throttling_allowed_)
|
||||
+ new_state->visibility = mojom::blink::PageVisibilityState::kVisible;
|
||||
+
|
||||
bool storing_in_bfcache = new_state->is_in_back_forward_cache &&
|
||||
!old_state->is_in_back_forward_cache;
|
||||
bool restoring_from_bfcache = !new_state->is_in_back_forward_cache &&
|
||||
@@ -3847,17 +3850,30 @@ PageScheduler* WebViewImpl::Scheduler() const {
|
||||
return GetPage()->GetPageScheduler();
|
||||
}
|
||||
|
||||
@@ -90,19 +127,34 @@ index a1bcdb3b7ceb5bed96b4c442268e3b7ddb490fa4..acda9f8ea1789d3febc0386ae855c009
|
||||
mojom::blink::PageVisibilityState visibility_state,
|
||||
bool is_initial_state) {
|
||||
DCHECK(GetPage());
|
||||
GetPage()->SetVisibilityState(visibility_state, is_initial_state);
|
||||
GetPage()->GetPageScheduler()->SetPageVisible(
|
||||
- GetPage()->SetVisibilityState(visibility_state, is_initial_state);
|
||||
- GetPage()->GetPageScheduler()->SetPageVisible(
|
||||
- visibility_state == mojom::blink::PageVisibilityState::kVisible);
|
||||
+ scheduler_throttling_allowed_ ?
|
||||
+ (visibility_state == mojom::blink::PageVisibilityState::kVisible) : true);
|
||||
// Notify observers of the change.
|
||||
if (!is_initial_state) {
|
||||
for (auto& observer : observers_)
|
||||
- // Notify observers of the change.
|
||||
- if (!is_initial_state) {
|
||||
- for (auto& observer : observers_)
|
||||
- observer.OnPageVisibilityChanged(visibility_state);
|
||||
+ // If backgroundThrottling is disabled, the page is always visible.
|
||||
+ if (!scheduler_throttling_allowed_) {
|
||||
+ GetPage()->SetVisibilityState(mojom::blink::PageVisibilityState::kVisible, is_initial_state);
|
||||
+ GetPage()->GetPageScheduler()->SetPageVisible(true);
|
||||
+ } else {
|
||||
+ bool is_visible = visibility_state == mojom::blink::PageVisibilityState::kVisible;
|
||||
+ GetPage()->SetVisibilityState(visibility_state, is_initial_state);
|
||||
+ GetPage()->GetPageScheduler()->SetPageVisible(is_visible);
|
||||
+ // Notify observers of the change.
|
||||
+ if (!is_initial_state) {
|
||||
+ for (auto& observer : observers_)
|
||||
+ observer.OnPageVisibilityChanged(visibility_state);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h
|
||||
index cce09d720fda1929cd5202841305ea564ebdecaf..63bb7c62a8a6abf32fd8e29861018b0c9c80d471 100644
|
||||
index 6a180620e00c77d0f4be346d1296f62feb714abb..c0ccf14faa52ab190c5848e8e9b597bcf637d4c0 100644
|
||||
--- a/third_party/blink/renderer/core/exported/web_view_impl.h
|
||||
+++ b/third_party/blink/renderer/core/exported/web_view_impl.h
|
||||
@@ -443,6 +443,7 @@ class CORE_EXPORT WebViewImpl final : public WebView,
|
||||
@@ -445,6 +445,7 @@ class CORE_EXPORT WebViewImpl final : public WebView,
|
||||
LocalDOMWindow* PagePopupWindow() const;
|
||||
|
||||
PageScheduler* Scheduler() const override;
|
||||
@@ -110,7 +162,7 @@ index cce09d720fda1929cd5202841305ea564ebdecaf..63bb7c62a8a6abf32fd8e29861018b0c
|
||||
void SetVisibilityState(mojom::blink::PageVisibilityState visibility_state,
|
||||
bool is_initial_state) override;
|
||||
mojom::blink::PageVisibilityState GetVisibilityState() override;
|
||||
@@ -907,6 +908,8 @@ class CORE_EXPORT WebViewImpl final : public WebView,
|
||||
@@ -909,6 +910,8 @@ class CORE_EXPORT WebViewImpl final : public WebView,
|
||||
// If true, we send IPC messages when |preferred_size_| changes.
|
||||
bool send_preferred_size_changes_ = false;
|
||||
|
||||
|
||||
@@ -6,10 +6,10 @@ Subject: Allow setting secondary label via SimpleMenuModel
|
||||
Builds on https://chromium-review.googlesource.com/c/chromium/src/+/2208976
|
||||
|
||||
diff --git a/ui/base/models/simple_menu_model.cc b/ui/base/models/simple_menu_model.cc
|
||||
index c058edaf6ea40746228da569a8739c50f958500d..2d4306d16ce8e354dcdf3da8c5afce8546349fcd 100644
|
||||
index 73bdc6d0788463ef7a8656e8902fde62cbbb5464..7d49d9928fcbb23361a63eb458d6841e4adcbf41 100644
|
||||
--- a/ui/base/models/simple_menu_model.cc
|
||||
+++ b/ui/base/models/simple_menu_model.cc
|
||||
@@ -52,6 +52,11 @@ std::u16string SimpleMenuModel::Delegate::GetLabelForCommandId(
|
||||
@@ -48,6 +48,11 @@ std::u16string SimpleMenuModel::Delegate::GetLabelForCommandId(
|
||||
return std::u16string();
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ index c058edaf6ea40746228da569a8739c50f958500d..2d4306d16ce8e354dcdf3da8c5afce85
|
||||
ImageModel SimpleMenuModel::Delegate::GetIconForCommandId(
|
||||
int command_id) const {
|
||||
return ImageModel();
|
||||
@@ -310,6 +315,11 @@ void SimpleMenuModel::SetLabel(size_t index, const std::u16string& label) {
|
||||
@@ -313,6 +318,11 @@ void SimpleMenuModel::SetLabel(size_t index, const std::u16string& label) {
|
||||
MenuItemsChanged();
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ index c058edaf6ea40746228da569a8739c50f958500d..2d4306d16ce8e354dcdf3da8c5afce85
|
||||
void SimpleMenuModel::SetMinorText(size_t index,
|
||||
const std::u16string& minor_text) {
|
||||
items_[ValidateItemIndex(index)].minor_text = minor_text;
|
||||
@@ -403,6 +413,12 @@ std::u16string SimpleMenuModel::GetLabelAt(size_t index) const {
|
||||
@@ -406,6 +416,12 @@ std::u16string SimpleMenuModel::GetLabelAt(size_t index) const {
|
||||
return items_[ValidateItemIndex(index)].label;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ index c058edaf6ea40746228da569a8739c50f958500d..2d4306d16ce8e354dcdf3da8c5afce85
|
||||
return items_[ValidateItemIndex(index)].minor_text;
|
||||
}
|
||||
diff --git a/ui/base/models/simple_menu_model.h b/ui/base/models/simple_menu_model.h
|
||||
index 3f2ae4cb1347a8bac7df6d993d5b70b4212fdc66..72d70e3f94f990f8f9f5e4268f6186762e409d15 100644
|
||||
index 5ffe7891e71c24a0f31f758c1f467eff645bb658..7c4d37c8b05c64866bc41b38596ffb06e16d69f4 100644
|
||||
--- a/ui/base/models/simple_menu_model.h
|
||||
+++ b/ui/base/models/simple_menu_model.h
|
||||
@@ -50,6 +50,7 @@ class COMPONENT_EXPORT(UI_BASE) SimpleMenuModel : public MenuModel {
|
||||
@@ -58,7 +58,7 @@ index 3f2ae4cb1347a8bac7df6d993d5b70b4212fdc66..72d70e3f94f990f8f9f5e4268f618676
|
||||
// Gets the icon for the item with the specified id.
|
||||
virtual ImageModel GetIconForCommandId(int command_id) const;
|
||||
|
||||
@@ -167,6 +168,9 @@ class COMPONENT_EXPORT(UI_BASE) SimpleMenuModel : public MenuModel {
|
||||
@@ -168,6 +169,9 @@ class COMPONENT_EXPORT(UI_BASE) SimpleMenuModel : public MenuModel {
|
||||
// Sets the label for the item at |index|.
|
||||
void SetLabel(size_t index, const std::u16string& label);
|
||||
|
||||
@@ -68,7 +68,7 @@ index 3f2ae4cb1347a8bac7df6d993d5b70b4212fdc66..72d70e3f94f990f8f9f5e4268f618676
|
||||
// Sets the minor text for the item at |index|.
|
||||
void SetMinorText(size_t index, const std::u16string& minor_text);
|
||||
|
||||
@@ -206,6 +210,7 @@ class COMPONENT_EXPORT(UI_BASE) SimpleMenuModel : public MenuModel {
|
||||
@@ -207,6 +211,7 @@ class COMPONENT_EXPORT(UI_BASE) SimpleMenuModel : public MenuModel {
|
||||
ui::MenuSeparatorType GetSeparatorTypeAt(size_t index) const override;
|
||||
int GetCommandIdAt(size_t index) const override;
|
||||
std::u16string GetLabelAt(size_t index) const override;
|
||||
|
||||
@@ -0,0 +1,655 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Yoav Weiss <yoavweiss@chromium.org>
|
||||
Date: Thu, 31 Aug 2023 10:11:57 +0000
|
||||
Subject: Avoid allocating RecordId objects in ElementTiming and LCP
|
||||
|
||||
RecordId objects in current code keep around references to LayoutObject
|
||||
and ImageResourceContent, both GCed objects.
|
||||
Turn out that most of these references are not needed and are only used
|
||||
as hashmap keys that would be better served with an actual hash. The
|
||||
ones that are needed don't need extensive lifetimes and can be stack
|
||||
allocated.
|
||||
|
||||
Bug=1472365,1472366
|
||||
|
||||
Change-Id: I3fd77bed9899932d5bfadc2a8e6403a8e434235f
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4821128
|
||||
Commit-Queue: Yoav Weiss <yoavweiss@chromium.org>
|
||||
Reviewed-by: Omer Katz <omerkatz@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#1190644}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/paint/DEPS b/third_party/blink/renderer/core/paint/DEPS
|
||||
index c6d60f8f418f03a3dcf1db94ca0e7feb87d85efa..16a5c09a09bf5343e7b05375bd55345f1023a9a3 100644
|
||||
--- a/third_party/blink/renderer/core/paint/DEPS
|
||||
+++ b/third_party/blink/renderer/core/paint/DEPS
|
||||
@@ -4,6 +4,8 @@ include_rules = [
|
||||
"+cc/layers/picture_layer.h",
|
||||
# For DCHECK.
|
||||
"+base/logging.h",
|
||||
+ # Hash function access
|
||||
+ "+base/hash/hash.h",
|
||||
]
|
||||
|
||||
specific_include_rules = {
|
||||
diff --git a/third_party/blink/renderer/core/paint/build.gni b/third_party/blink/renderer/core/paint/build.gni
|
||||
index fd75feaf315977a60b80e66b4a8ecd09d8edb7e4..663cdaf120c579b75b94af835e62d937e9f2a115 100644
|
||||
--- a/third_party/blink/renderer/core/paint/build.gni
|
||||
+++ b/third_party/blink/renderer/core/paint/build.gni
|
||||
@@ -200,6 +200,8 @@ blink_core_sources_paint = [
|
||||
"timing/image_paint_timing_detector.h",
|
||||
"timing/largest_contentful_paint_calculator.cc",
|
||||
"timing/largest_contentful_paint_calculator.h",
|
||||
+ "timing/media_record_id.cc",
|
||||
+ "timing/media_record_id.h",
|
||||
"timing/paint_timing.cc",
|
||||
"timing/paint_timing_detector.cc",
|
||||
"timing/paint_timing_detector.h",
|
||||
diff --git a/third_party/blink/renderer/core/paint/timing/image_element_timing.cc b/third_party/blink/renderer/core/paint/timing/image_element_timing.cc
|
||||
index a8501cfcc91e57b3348e3db8ff11256c4d7176b2..21f7a0ac38732e5381da6b82544044b8e6da3a11 100644
|
||||
--- a/third_party/blink/renderer/core/paint/timing/image_element_timing.cc
|
||||
+++ b/third_party/blink/renderer/core/paint/timing/image_element_timing.cc
|
||||
@@ -68,7 +68,7 @@ void ImageElementTiming::NotifyImageFinished(
|
||||
return;
|
||||
|
||||
const auto& insertion_result = images_notified_.insert(
|
||||
- std::make_pair(&layout_object, cached_image), ImageInfo());
|
||||
+ MediaRecordId::GenerateHash(&layout_object, cached_image), ImageInfo());
|
||||
if (insertion_result.is_new_entry)
|
||||
insertion_result.stored_value->value.load_time_ = base::TimeTicks::Now();
|
||||
}
|
||||
@@ -97,8 +97,8 @@ void ImageElementTiming::NotifyImagePainted(
|
||||
if (!internal::IsExplicitlyRegisteredForTiming(layout_object))
|
||||
return;
|
||||
|
||||
- auto it =
|
||||
- images_notified_.find(std::make_pair(&layout_object, &cached_image));
|
||||
+ auto it = images_notified_.find(
|
||||
+ MediaRecordId::GenerateHash(&layout_object, &cached_image));
|
||||
// It is possible that the pair is not in |images_notified_|. See
|
||||
// https://crbug.com/1027948
|
||||
if (it != images_notified_.end() && !it->value.is_painted_) {
|
||||
@@ -218,7 +218,8 @@ void ImageElementTiming::NotifyBackgroundImagePainted(
|
||||
|
||||
ImageInfo& info =
|
||||
images_notified_
|
||||
- .insert(std::make_pair(layout_object, cached_image), ImageInfo())
|
||||
+ .insert(MediaRecordId::GenerateHash(layout_object, cached_image),
|
||||
+ ImageInfo())
|
||||
.stored_value->value;
|
||||
if (!info.is_painted_) {
|
||||
info.is_painted_ = true;
|
||||
@@ -246,7 +247,7 @@ void ImageElementTiming::ReportImagePaintPresentationTime(
|
||||
|
||||
void ImageElementTiming::NotifyImageRemoved(const LayoutObject* layout_object,
|
||||
const ImageResourceContent* image) {
|
||||
- images_notified_.erase(std::make_pair(layout_object, image));
|
||||
+ images_notified_.erase(MediaRecordId::GenerateHash(layout_object, image));
|
||||
}
|
||||
|
||||
void ImageElementTiming::Trace(Visitor* visitor) const {
|
||||
diff --git a/third_party/blink/renderer/core/paint/timing/image_element_timing.h b/third_party/blink/renderer/core/paint/timing/image_element_timing.h
|
||||
index 0a152210de91ab69c255be8caa951616afb3df06..7d3f5dd7c9137b277543e52d4d1e327d75b01e84 100644
|
||||
--- a/third_party/blink/renderer/core/paint/timing/image_element_timing.h
|
||||
+++ b/third_party/blink/renderer/core/paint/timing/image_element_timing.h
|
||||
@@ -5,12 +5,11 @@
|
||||
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_TIMING_IMAGE_ELEMENT_TIMING_H_
|
||||
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_TIMING_IMAGE_ELEMENT_TIMING_H_
|
||||
|
||||
-#include <utility>
|
||||
-
|
||||
#include "base/time/time.h"
|
||||
#include "third_party/blink/renderer/core/core_export.h"
|
||||
#include "third_party/blink/renderer/core/dom/element.h"
|
||||
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
|
||||
+#include "third_party/blink/renderer/core/paint/timing/media_record_id.h"
|
||||
#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h"
|
||||
#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h"
|
||||
#include "third_party/blink/renderer/platform/supplementable.h"
|
||||
@@ -123,13 +122,12 @@ class CORE_EXPORT ImageElementTiming final
|
||||
|
||||
DISALLOW_NEW();
|
||||
};
|
||||
- typedef std::pair<const LayoutObject*, const ImageResourceContent*> RecordId;
|
||||
// Hashmap of pairs of elements, LayoutObjects (for the elements) and
|
||||
// ImageResourceContent (for the src) which correspond to either images or
|
||||
// background images whose paint has been observed. For background images,
|
||||
// only the |is_painted_| bit is used, as the timestamp needs to be tracked by
|
||||
// |background_image_timestamps_|.
|
||||
- WTF::HashMap<RecordId, ImageInfo> images_notified_;
|
||||
+ WTF::HashMap<MediaRecordIdHash, ImageInfo> images_notified_;
|
||||
|
||||
// Hashmap of background images which contain information about the load time
|
||||
// of the background image.
|
||||
diff --git a/third_party/blink/renderer/core/paint/timing/image_element_timing_test.cc b/third_party/blink/renderer/core/paint/timing/image_element_timing_test.cc
|
||||
index 963493d548df51a704cb332c0df7a70ffa091011..6ed8840f58b0bafd50a67acfd389a41c2b4cc78d 100644
|
||||
--- a/third_party/blink/renderer/core/paint/timing/image_element_timing_test.cc
|
||||
+++ b/third_party/blink/renderer/core/paint/timing/image_element_timing_test.cc
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "third_party/blink/renderer/core/layout/layout_image.h"
|
||||
#include "third_party/blink/renderer/core/layout/svg/layout_svg_image.h"
|
||||
#include "third_party/blink/renderer/core/loader/resource/image_resource_content.h"
|
||||
+#include "third_party/blink/renderer/core/paint/timing/media_record_id.h"
|
||||
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
|
||||
#include "third_party/blink/renderer/platform/testing/paint_test_configurations.h"
|
||||
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
|
||||
@@ -60,11 +61,9 @@ class ImageElementTimingTest : public testing::Test,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- bool ImagesNotifiedContains(
|
||||
- const std::pair<const LayoutObject*, const ImageResourceContent*>&
|
||||
- record_id) {
|
||||
+ bool ImagesNotifiedContains(MediaRecordIdHash record_id_hash) {
|
||||
return ImageElementTiming::From(*GetDoc()->domWindow())
|
||||
- .images_notified_.Contains(record_id);
|
||||
+ .images_notified_.Contains(record_id_hash);
|
||||
}
|
||||
|
||||
unsigned ImagesNotifiedSize() {
|
||||
@@ -159,7 +158,7 @@ TEST_P(ImageElementTimingTest, IgnoresUnmarkedElement) {
|
||||
ASSERT_TRUE(layout_image);
|
||||
UpdateAllLifecyclePhases();
|
||||
EXPECT_FALSE(ImagesNotifiedContains(
|
||||
- std::make_pair(layout_image, layout_image->CachedImage())));
|
||||
+ MediaRecordId::GenerateHash(layout_image, layout_image->CachedImage())));
|
||||
}
|
||||
|
||||
TEST_P(ImageElementTimingTest, ImageInsideSVG) {
|
||||
@@ -179,7 +178,7 @@ TEST_P(ImageElementTimingTest, ImageInsideSVG) {
|
||||
|
||||
// |layout_image| should have had its paint notified to ImageElementTiming.
|
||||
EXPECT_TRUE(ImagesNotifiedContains(
|
||||
- std::make_pair(layout_image, layout_image->CachedImage())));
|
||||
+ MediaRecordId::GenerateHash(layout_image, layout_image->CachedImage())));
|
||||
}
|
||||
|
||||
TEST_P(ImageElementTimingTest, ImageInsideNonRenderedSVG) {
|
||||
@@ -214,7 +213,7 @@ TEST_P(ImageElementTimingTest, ImageRemoved) {
|
||||
ASSERT_TRUE(layout_image);
|
||||
UpdateAllLifecyclePhases();
|
||||
EXPECT_TRUE(ImagesNotifiedContains(
|
||||
- std::make_pair(layout_image, layout_image->CachedImage())));
|
||||
+ MediaRecordId::GenerateHash(layout_image, layout_image->CachedImage())));
|
||||
|
||||
GetDoc()->getElementById("target")->remove();
|
||||
// |layout_image| should no longer be part of |images_notified| since it will
|
||||
@@ -234,7 +233,7 @@ TEST_P(ImageElementTimingTest, SVGImageRemoved) {
|
||||
LayoutSVGImage* layout_image = SetSVGImageResource("target", 5, 5);
|
||||
ASSERT_TRUE(layout_image);
|
||||
UpdateAllLifecyclePhases();
|
||||
- EXPECT_TRUE(ImagesNotifiedContains(std::make_pair(
|
||||
+ EXPECT_TRUE(ImagesNotifiedContains(MediaRecordId::GenerateHash(
|
||||
layout_image, layout_image->ImageResource()->CachedImage())));
|
||||
|
||||
GetDoc()->getElementById("target")->remove();
|
||||
@@ -261,7 +260,8 @@ TEST_P(ImageElementTimingTest, BackgroundImageRemoved) {
|
||||
object->Style()->BackgroundLayers().GetImage()->CachedImage();
|
||||
UpdateAllLifecyclePhases();
|
||||
EXPECT_EQ(ImagesNotifiedSize(), 1u);
|
||||
- EXPECT_TRUE(ImagesNotifiedContains(std::make_pair(object, content)));
|
||||
+ EXPECT_TRUE(
|
||||
+ ImagesNotifiedContains(MediaRecordId::GenerateHash(object, content)));
|
||||
|
||||
GetDoc()->getElementById("target")->remove();
|
||||
EXPECT_EQ(ImagesNotifiedSize(), 0u);
|
||||
diff --git a/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector.cc b/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector.cc
|
||||
index b4ed09ccd893b39d4497fc9a237c1ab00bda91fa..e516c2a15a362fa71fcb1d644e8eb61ea2934b1e 100644
|
||||
--- a/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector.cc
|
||||
+++ b/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector.cc
|
||||
@@ -231,8 +231,8 @@ void ImagePaintTimingDetector::OnPaintFinished() {
|
||||
void ImagePaintTimingDetector::NotifyImageRemoved(
|
||||
const LayoutObject& object,
|
||||
const MediaTiming* media_timing) {
|
||||
- RecordId record_id = std::make_pair(&object, media_timing);
|
||||
- records_manager_.RemoveRecord(record_id);
|
||||
+ records_manager_.RemoveRecord(
|
||||
+ MediaRecordId::GenerateHash(&object, media_timing));
|
||||
}
|
||||
|
||||
void ImagePaintTimingDetector::StopRecordEntries() {
|
||||
@@ -270,7 +270,7 @@ void ImageRecordsManager::AssignPaintTimeToRegisteredQueuedRecords(
|
||||
unsigned last_queued_frame_index) {
|
||||
while (!images_queued_for_paint_time_.empty()) {
|
||||
const base::WeakPtr<ImageRecord>& record =
|
||||
- images_queued_for_paint_time_.front().first;
|
||||
+ images_queued_for_paint_time_.front().image_record;
|
||||
if (!record) {
|
||||
images_queued_for_paint_time_.pop_front();
|
||||
continue;
|
||||
@@ -282,8 +282,8 @@ void ImageRecordsManager::AssignPaintTimeToRegisteredQueuedRecords(
|
||||
record->first_animated_frame_time = timestamp;
|
||||
record->queue_animated_paint = false;
|
||||
}
|
||||
- auto it =
|
||||
- pending_images_.find(images_queued_for_paint_time_.front().second);
|
||||
+ auto it = pending_images_.find(
|
||||
+ images_queued_for_paint_time_.front().record_id_hash);
|
||||
images_queued_for_paint_time_.pop_front();
|
||||
// A record may be in |images_queued_for_paint_time_| twice, for instance if
|
||||
// is already loaded by the time of its first paint.
|
||||
@@ -319,7 +319,8 @@ bool ImagePaintTimingDetector::RecordImage(
|
||||
if (image_border.IsEmpty())
|
||||
return false;
|
||||
|
||||
- RecordId record_id = std::make_pair(&object, &media_timing);
|
||||
+ MediaRecordId record_id(&object, &media_timing);
|
||||
+ MediaRecordIdHash record_id_hash = record_id.GetHash();
|
||||
|
||||
if (int depth = IgnorePaintTimingScope::IgnoreDepth()) {
|
||||
// Record the largest loaded image that is hidden due to documentElement
|
||||
@@ -340,17 +341,18 @@ bool ImagePaintTimingDetector::RecordImage(
|
||||
return false;
|
||||
}
|
||||
|
||||
- if (records_manager_.IsRecordedImage(record_id)) {
|
||||
+ if (records_manager_.IsRecordedImage(record_id_hash)) {
|
||||
base::WeakPtr<ImageRecord> record =
|
||||
- records_manager_.GetPendingImage(record_id);
|
||||
+ records_manager_.GetPendingImage(record_id_hash);
|
||||
if (!record)
|
||||
return false;
|
||||
if (ShouldReportAnimatedImages() && media_timing.IsPaintedFirstFrame()) {
|
||||
added_entry_in_latest_frame_ |=
|
||||
- records_manager_.OnFirstAnimatedFramePainted(record_id, frame_index_);
|
||||
+ records_manager_.OnFirstAnimatedFramePainted(record_id_hash,
|
||||
+ frame_index_);
|
||||
}
|
||||
if (!record->loaded && media_timing.IsSufficientContentLoadedForPaint()) {
|
||||
- records_manager_.OnImageLoaded(record_id, frame_index_, style_image);
|
||||
+ records_manager_.OnImageLoaded(record_id_hash, frame_index_, style_image);
|
||||
added_entry_in_latest_frame_ = true;
|
||||
if (absl::optional<PaintTimingVisualizer>& visualizer =
|
||||
frame_view_->GetPaintTimingDetector().Visualizer()) {
|
||||
@@ -386,10 +388,11 @@ bool ImagePaintTimingDetector::RecordImage(
|
||||
|
||||
if (ShouldReportAnimatedImages() && media_timing.IsPaintedFirstFrame()) {
|
||||
added_entry_in_latest_frame_ |=
|
||||
- records_manager_.OnFirstAnimatedFramePainted(record_id, frame_index_);
|
||||
+ records_manager_.OnFirstAnimatedFramePainted(record_id_hash,
|
||||
+ frame_index_);
|
||||
}
|
||||
if (media_timing.IsSufficientContentLoadedForPaint()) {
|
||||
- records_manager_.OnImageLoaded(record_id, frame_index_, style_image);
|
||||
+ records_manager_.OnImageLoaded(record_id_hash, frame_index_, style_image);
|
||||
added_entry_in_latest_frame_ = true;
|
||||
return true;
|
||||
}
|
||||
@@ -445,8 +448,8 @@ uint64_t ImagePaintTimingDetector::ComputeImageRectSize(
|
||||
void ImagePaintTimingDetector::NotifyImageFinished(
|
||||
const LayoutObject& object,
|
||||
const MediaTiming* media_timing) {
|
||||
- RecordId record_id = std::make_pair(&object, media_timing);
|
||||
- records_manager_.NotifyImageFinished(record_id);
|
||||
+ records_manager_.NotifyImageFinished(
|
||||
+ MediaRecordId::GenerateHash(&object, media_timing));
|
||||
}
|
||||
|
||||
void ImagePaintTimingDetector::ReportLargestIgnoredImage() {
|
||||
@@ -458,9 +461,9 @@ ImageRecordsManager::ImageRecordsManager(LocalFrameView* frame_view)
|
||||
: size_ordered_set_(&LargeImageFirst), frame_view_(frame_view) {}
|
||||
|
||||
bool ImageRecordsManager::OnFirstAnimatedFramePainted(
|
||||
- const RecordId& record_id,
|
||||
+ MediaRecordIdHash record_id_hash,
|
||||
unsigned current_frame_index) {
|
||||
- base::WeakPtr<ImageRecord> record = GetPendingImage(record_id);
|
||||
+ base::WeakPtr<ImageRecord> record = GetPendingImage(record_id_hash);
|
||||
DCHECK(record);
|
||||
if (record->media_timing &&
|
||||
!record->media_timing->GetFirstVideoFrameTime().is_null()) {
|
||||
@@ -473,19 +476,19 @@ bool ImageRecordsManager::OnFirstAnimatedFramePainted(
|
||||
// Otherwise, this is an animated images, and so we should wait for the
|
||||
// presentation callback to fire to set the first frame presentation time.
|
||||
record->queue_animated_paint = true;
|
||||
- QueueToMeasurePaintTime(record_id, record, current_frame_index);
|
||||
+ QueueToMeasurePaintTime(record_id_hash, record, current_frame_index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
-void ImageRecordsManager::OnImageLoaded(const RecordId& record_id,
|
||||
+void ImageRecordsManager::OnImageLoaded(MediaRecordIdHash record_id_hash,
|
||||
unsigned current_frame_index,
|
||||
const StyleFetchedImage* style_image) {
|
||||
- base::WeakPtr<ImageRecord> record = GetPendingImage(record_id);
|
||||
+ base::WeakPtr<ImageRecord> record = GetPendingImage(record_id_hash);
|
||||
DCHECK(record);
|
||||
if (!style_image) {
|
||||
- auto it = image_finished_times_.find(record_id);
|
||||
+ auto it = image_finished_times_.find(record_id_hash);
|
||||
if (it != image_finished_times_.end()) {
|
||||
record->load_time = it->value;
|
||||
DCHECK(!record->load_time.is_null());
|
||||
@@ -498,7 +501,7 @@ void ImageRecordsManager::OnImageLoaded(const RecordId& record_id,
|
||||
record->origin_clean = style_image->IsOriginClean();
|
||||
}
|
||||
}
|
||||
- OnImageLoadedInternal(record_id, record, current_frame_index);
|
||||
+ OnImageLoadedInternal(record_id_hash, record, current_frame_index);
|
||||
}
|
||||
|
||||
void ImageRecordsManager::ReportLargestIgnoredImage(
|
||||
@@ -518,25 +521,25 @@ void ImageRecordsManager::ReportLargestIgnoredImage(
|
||||
DCHECK(document);
|
||||
PaintTiming::From(*document).MarkFirstContentfulPaint();
|
||||
|
||||
- RecordId record_id = std::make_pair(node->GetLayoutObject(),
|
||||
- largest_ignored_image_->media_timing);
|
||||
- recorded_images_.insert(record_id);
|
||||
+ MediaRecordIdHash record_id_hash = MediaRecordId::GenerateHash(
|
||||
+ node->GetLayoutObject(), largest_ignored_image_->media_timing);
|
||||
+ recorded_images_.insert(record_id_hash);
|
||||
base::WeakPtr<ImageRecord> record = largest_ignored_image_->AsWeakPtr();
|
||||
size_ordered_set_.insert(record);
|
||||
- pending_images_.insert(record_id, std::move(largest_ignored_image_));
|
||||
- OnImageLoadedInternal(record_id, record, current_frame_index);
|
||||
+ pending_images_.insert(record_id_hash, std::move(largest_ignored_image_));
|
||||
+ OnImageLoadedInternal(record_id_hash, record, current_frame_index);
|
||||
}
|
||||
|
||||
void ImageRecordsManager::OnImageLoadedInternal(
|
||||
- const RecordId& record_id,
|
||||
+ MediaRecordIdHash record_id_hash,
|
||||
base::WeakPtr<ImageRecord>& record,
|
||||
unsigned current_frame_index) {
|
||||
SetLoaded(record);
|
||||
- QueueToMeasurePaintTime(record_id, record, current_frame_index);
|
||||
+ QueueToMeasurePaintTime(record_id_hash, record, current_frame_index);
|
||||
}
|
||||
|
||||
void ImageRecordsManager::MaybeUpdateLargestIgnoredImage(
|
||||
- const RecordId& record_id,
|
||||
+ const MediaRecordId& record_id,
|
||||
const uint64_t& visual_size,
|
||||
const gfx::Rect& frame_visual_rect,
|
||||
const gfx::RectF& root_visual_rect,
|
||||
@@ -544,14 +547,14 @@ void ImageRecordsManager::MaybeUpdateLargestIgnoredImage(
|
||||
if (visual_size && (!largest_ignored_image_ ||
|
||||
visual_size > largest_ignored_image_->recorded_size)) {
|
||||
largest_ignored_image_ = CreateImageRecord(
|
||||
- *record_id.first, record_id.second, visual_size, frame_visual_rect,
|
||||
- root_visual_rect, is_loaded_after_mouseover);
|
||||
+ *record_id.GetLayoutObject(), record_id.GetMediaTiming(), visual_size,
|
||||
+ frame_visual_rect, root_visual_rect, is_loaded_after_mouseover);
|
||||
largest_ignored_image_->load_time = base::TimeTicks::Now();
|
||||
}
|
||||
}
|
||||
|
||||
bool ImageRecordsManager::RecordFirstPaintAndReturnIsPending(
|
||||
- const RecordId& record_id,
|
||||
+ const MediaRecordId& record_id,
|
||||
const uint64_t& visual_size,
|
||||
const gfx::Rect& frame_visual_rect,
|
||||
const gfx::RectF& root_visual_rect,
|
||||
@@ -562,7 +565,7 @@ bool ImageRecordsManager::RecordFirstPaintAndReturnIsPending(
|
||||
if (visual_size == 0u) {
|
||||
return false;
|
||||
}
|
||||
- recorded_images_.insert(record_id);
|
||||
+ recorded_images_.insert(record_id.GetHash());
|
||||
// If this cannot become an LCP candidate, no need to do anything else.
|
||||
if (visual_size == 0u ||
|
||||
(largest_painted_image_ &&
|
||||
@@ -588,10 +591,10 @@ bool ImageRecordsManager::RecordFirstPaintAndReturnIsPending(
|
||||
}
|
||||
|
||||
std::unique_ptr<ImageRecord> record = CreateImageRecord(
|
||||
- *record_id.first, record_id.second, visual_size, frame_visual_rect,
|
||||
- root_visual_rect, is_loaded_after_mouseover);
|
||||
+ *record_id.GetLayoutObject(), record_id.GetMediaTiming(), visual_size,
|
||||
+ frame_visual_rect, root_visual_rect, is_loaded_after_mouseover);
|
||||
size_ordered_set_.insert(record->AsWeakPtr());
|
||||
- pending_images_.insert(record_id, std::move(record));
|
||||
+ pending_images_.insert(record_id.GetHash(), std::move(record));
|
||||
return true;
|
||||
}
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector.h b/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector.h
|
||||
index 6625edaafdce8697dbe14c86f6a8fba0042a1e5f..188df4392e6409170842147ec4768307869297da 100644
|
||||
--- a/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector.h
|
||||
+++ b/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector.h
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "third_party/blink/renderer/core/core_export.h"
|
||||
#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
|
||||
#include "third_party/blink/renderer/core/loader/resource/image_resource_content.h"
|
||||
+#include "third_party/blink/renderer/core/paint/timing/media_record_id.h"
|
||||
#include "third_party/blink/renderer/core/paint/timing/paint_timing_detector.h"
|
||||
#include "third_party/blink/renderer/platform/allow_discouraged_type.h"
|
||||
#include "third_party/blink/renderer/platform/loader/fetch/media_timing.h"
|
||||
@@ -91,8 +92,6 @@ class ImageRecord : public base::SupportsWeakPtr<ImageRecord> {
|
||||
bool is_loaded_after_mouseover = false;
|
||||
};
|
||||
|
||||
-typedef std::pair<const LayoutObject*, const MediaTiming*> RecordId;
|
||||
-
|
||||
// |ImageRecordsManager| is the manager of all of the images that Largest
|
||||
// Image Paint cares about. Note that an image does not necessarily correspond
|
||||
// to a node; it can also be one of the background images attached to a node.
|
||||
@@ -116,10 +115,10 @@ class CORE_EXPORT ImageRecordsManager {
|
||||
ImageRecordsManager& operator=(const ImageRecordsManager&) = delete;
|
||||
ImageRecord* LargestImage() const;
|
||||
|
||||
- inline void RemoveRecord(const RecordId& record_id) {
|
||||
- recorded_images_.erase(record_id);
|
||||
- image_finished_times_.erase(record_id);
|
||||
- auto it = pending_images_.find(record_id);
|
||||
+ inline void RemoveRecord(MediaRecordIdHash record_id_hash) {
|
||||
+ recorded_images_.erase(record_id_hash);
|
||||
+ image_finished_times_.erase(record_id_hash);
|
||||
+ auto it = pending_images_.find(record_id_hash);
|
||||
if (it != pending_images_.end()) {
|
||||
size_ordered_set_.erase(it->value->AsWeakPtr());
|
||||
pending_images_.erase(it);
|
||||
@@ -129,41 +128,42 @@ class CORE_EXPORT ImageRecordsManager {
|
||||
}
|
||||
}
|
||||
// Returns whether an image was added to |pending_images_|.
|
||||
- bool RecordFirstPaintAndReturnIsPending(const RecordId& record_id,
|
||||
+ bool RecordFirstPaintAndReturnIsPending(const MediaRecordId& record_id,
|
||||
const uint64_t& visual_size,
|
||||
const gfx::Rect& frame_visual_rect,
|
||||
const gfx::RectF& root_visual_rect,
|
||||
double bpp,
|
||||
bool is_loaded_after_mouseover);
|
||||
- bool IsRecordedImage(const RecordId& record_id) const {
|
||||
- return recorded_images_.Contains(record_id);
|
||||
+ bool IsRecordedImage(MediaRecordIdHash record_id_hash) const {
|
||||
+ return recorded_images_.Contains(record_id_hash);
|
||||
}
|
||||
|
||||
- void NotifyImageFinished(const RecordId& record_id) {
|
||||
+ void NotifyImageFinished(MediaRecordIdHash record_id_hash) {
|
||||
// TODO(npm): Ideally NotifyImageFinished() would only be called when the
|
||||
// record has not yet been inserted in |image_finished_times_| but that's
|
||||
// not currently the case. If we plumb some information from
|
||||
// MediaTiming we may be able to ensure that this call does not
|
||||
// require the Contains() check, which would save time.
|
||||
- if (!image_finished_times_.Contains(record_id)) {
|
||||
- image_finished_times_.insert(record_id, base::TimeTicks::Now());
|
||||
+ if (!image_finished_times_.Contains(record_id_hash)) {
|
||||
+ image_finished_times_.insert(record_id_hash, base::TimeTicks::Now());
|
||||
}
|
||||
}
|
||||
|
||||
- inline base::WeakPtr<ImageRecord> GetPendingImage(const RecordId& record_id) {
|
||||
- auto it = pending_images_.find(record_id);
|
||||
+ inline base::WeakPtr<ImageRecord> GetPendingImage(
|
||||
+ MediaRecordIdHash record_id_hash) {
|
||||
+ auto it = pending_images_.find(record_id_hash);
|
||||
return it == pending_images_.end() ? nullptr : it->value->AsWeakPtr();
|
||||
}
|
||||
- bool OnFirstAnimatedFramePainted(const RecordId&,
|
||||
+ bool OnFirstAnimatedFramePainted(MediaRecordIdHash,
|
||||
unsigned current_frame_index);
|
||||
- void OnImageLoaded(const RecordId&,
|
||||
+ void OnImageLoaded(MediaRecordIdHash,
|
||||
unsigned current_frame_index,
|
||||
const StyleFetchedImage*);
|
||||
|
||||
// Receives a candidate image painted under opacity 0 but without nested
|
||||
// opacity. May update |largest_ignored_image_| if the new candidate has a
|
||||
// larger size.
|
||||
- void MaybeUpdateLargestIgnoredImage(const RecordId&,
|
||||
+ void MaybeUpdateLargestIgnoredImage(const MediaRecordId&,
|
||||
const uint64_t& visual_size,
|
||||
const gfx::Rect& frame_visual_rect,
|
||||
const gfx::RectF& root_visual_rect,
|
||||
@@ -187,19 +187,31 @@ class CORE_EXPORT ImageRecordsManager {
|
||||
const gfx::Rect& frame_visual_rect,
|
||||
const gfx::RectF& root_visual_rect,
|
||||
bool is_loaded_after_mouseover);
|
||||
- inline void QueueToMeasurePaintTime(const RecordId& record_id,
|
||||
+ inline void QueueToMeasurePaintTime(MediaRecordIdHash record_id_hash,
|
||||
base::WeakPtr<ImageRecord>& record,
|
||||
unsigned current_frame_index) {
|
||||
record->frame_index = current_frame_index;
|
||||
- images_queued_for_paint_time_.push_back(std::make_pair(record, record_id));
|
||||
+ images_queued_for_paint_time_.push_back(
|
||||
+ ImageRecordAndHashPair(record, record_id_hash));
|
||||
}
|
||||
inline void SetLoaded(base::WeakPtr<ImageRecord>& record) {
|
||||
record->loaded = true;
|
||||
}
|
||||
- void OnImageLoadedInternal(const RecordId&,
|
||||
+ void OnImageLoadedInternal(MediaRecordIdHash,
|
||||
base::WeakPtr<ImageRecord>&,
|
||||
unsigned current_frame_index);
|
||||
|
||||
+ struct ImageRecordAndHashPair {
|
||||
+ ImageRecordAndHashPair(base::WeakPtr<ImageRecord>& record,
|
||||
+ MediaRecordIdHash id_hash) {
|
||||
+ image_record = record;
|
||||
+ record_id_hash = id_hash;
|
||||
+ }
|
||||
+
|
||||
+ base::WeakPtr<ImageRecord> image_record;
|
||||
+ MediaRecordIdHash record_id_hash;
|
||||
+ };
|
||||
+
|
||||
// The ImageRecord corresponding to the largest image that has been loaded and
|
||||
// painted.
|
||||
std::unique_ptr<ImageRecord> largest_painted_image_;
|
||||
@@ -208,24 +220,23 @@ class CORE_EXPORT ImageRecordsManager {
|
||||
// timestamp, ordered by size.
|
||||
ImageRecordSet size_ordered_set_;
|
||||
|
||||
- // RecordId for images for which we have seen a first paint. A RecordId is
|
||||
- // added to this set regardless of whether the image could be an LCP
|
||||
- // candidate.
|
||||
- HashSet<RecordId> recorded_images_;
|
||||
+ // MediaRecordId for images for which we have seen a first paint. A
|
||||
+ // MediaRecordId is added to this set regardless of whether the image could be
|
||||
+ // an LCP candidate.
|
||||
+ HashSet<MediaRecordIdHash> recorded_images_;
|
||||
|
||||
- // Map of RecordId to ImageRecord for images for which the first paint has
|
||||
- // been seen but which do not have the paint time set yet. This may contain
|
||||
- // only images which are potential LCP candidates.
|
||||
- HashMap<RecordId, std::unique_ptr<ImageRecord>> pending_images_;
|
||||
+ // Map of MediaRecordId to ImageRecord for images for which the first paint
|
||||
+ // has been seen but which do not have the paint time set yet. This may
|
||||
+ // contain only images which are potential LCP candidates.
|
||||
+ HashMap<MediaRecordIdHash, std::unique_ptr<ImageRecord>> pending_images_;
|
||||
|
||||
// |ImageRecord|s waiting for paint time are stored in this map
|
||||
// until they get a presentation time.
|
||||
- Deque<std::pair<base::WeakPtr<ImageRecord>, RecordId>>
|
||||
- images_queued_for_paint_time_;
|
||||
+ Deque<ImageRecordAndHashPair> images_queued_for_paint_time_;
|
||||
|
||||
// Map containing timestamps of when LayoutObject::ImageNotifyFinished is
|
||||
// first called.
|
||||
- HashMap<RecordId, base::TimeTicks> image_finished_times_;
|
||||
+ HashMap<MediaRecordIdHash, base::TimeTicks> image_finished_times_;
|
||||
|
||||
Member<LocalFrameView> frame_view_;
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/paint/timing/media_record_id.cc b/third_party/blink/renderer/core/paint/timing/media_record_id.cc
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e49c898d1111015d80a71ddc11bd791bb2a0dca1
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/renderer/core/paint/timing/media_record_id.cc
|
||||
@@ -0,0 +1,27 @@
|
||||
+// Copyright 2023 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/core/paint/timing/media_record_id.h"
|
||||
+
|
||||
+#include "base/hash/hash.h"
|
||||
+
|
||||
+namespace blink {
|
||||
+
|
||||
+MediaRecordId::MediaRecordId(const LayoutObject* layout,
|
||||
+ const MediaTiming* media)
|
||||
+ : layout_object_(layout),
|
||||
+ media_timing_(media),
|
||||
+ hash_(GenerateHash(layout, media)) {}
|
||||
+
|
||||
+// This hash is used as a key where previously MediaRecordId was used directly.
|
||||
+// That helps us avoid storing references to the GCed LayoutObject and
|
||||
+// MediaTiming, as that can be unsafe when using regular WTF containers. It also
|
||||
+// helps us avoid needlessly allocating MediaRecordId on the heap.
|
||||
+MediaRecordIdHash MediaRecordId::GenerateHash(const LayoutObject* layout,
|
||||
+ const MediaTiming* media) {
|
||||
+ return base::HashInts(reinterpret_cast<MediaRecordIdHash>(layout),
|
||||
+ reinterpret_cast<MediaRecordIdHash>(media));
|
||||
+}
|
||||
+
|
||||
+} // namespace blink
|
||||
diff --git a/third_party/blink/renderer/core/paint/timing/media_record_id.h b/third_party/blink/renderer/core/paint/timing/media_record_id.h
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..32952101e8463e31617d1b5f67c36abf04303c4a
|
||||
--- /dev/null
|
||||
+++ b/third_party/blink/renderer/core/paint/timing/media_record_id.h
|
||||
@@ -0,0 +1,37 @@
|
||||
+// Copyright 2023 The Chromium Authors
|
||||
+// Use of this source code is governed by a BSD-style license that can be
|
||||
+// found in the LICENSE file.
|
||||
+
|
||||
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_TIMING_MEDIA_RECORD_ID_H_
|
||||
+#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_TIMING_MEDIA_RECORD_ID_H_
|
||||
+
|
||||
+#include "third_party/blink/renderer/core/core_export.h"
|
||||
+#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
|
||||
+
|
||||
+namespace blink {
|
||||
+class LayoutObject;
|
||||
+class MediaTiming;
|
||||
+
|
||||
+using MediaRecordIdHash = size_t;
|
||||
+
|
||||
+class MediaRecordId {
|
||||
+ STACK_ALLOCATED();
|
||||
+
|
||||
+ public:
|
||||
+ static MediaRecordIdHash CORE_EXPORT GenerateHash(const LayoutObject* layout,
|
||||
+ const MediaTiming* media);
|
||||
+
|
||||
+ MediaRecordId(const LayoutObject* layout, const MediaTiming* media);
|
||||
+
|
||||
+ MediaRecordIdHash GetHash() const { return hash_; }
|
||||
+ const LayoutObject* GetLayoutObject() const { return layout_object_; }
|
||||
+ const MediaTiming* GetMediaTiming() const { return media_timing_; }
|
||||
+
|
||||
+ private:
|
||||
+ const LayoutObject* const layout_object_;
|
||||
+ const MediaTiming* const media_timing_;
|
||||
+ const MediaRecordIdHash hash_;
|
||||
+};
|
||||
+
|
||||
+} // namespace blink
|
||||
+#endif
|
||||
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
|
||||
index 408a2916a00bb2a871f3a680215de54e7be2077c..caa3d8277acbecbeb25b3449719866e061a82761 100755
|
||||
--- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
|
||||
+++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
|
||||
@@ -67,6 +67,7 @@ _CONFIG = [
|
||||
'base::DefaultTickClock',
|
||||
'base::ElapsedTimer',
|
||||
'base::EnumSet',
|
||||
+ 'base::HashInts',
|
||||
'base::JobDelegate',
|
||||
'base::JobHandle',
|
||||
'base::PostJob',
|
||||
@@ -49,10 +49,10 @@ index 22c4d4e9718a503d9c7ca26a40c97149b0f8986a..6bdc2757c96a28022fda9e6f5e3b74a0
|
||||
// its owning reference back to our owning LocalFrame.
|
||||
client_->Detached(type);
|
||||
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
|
||||
index c01a916555d1fe5dbf972cba3b7ce248c80df371..d7ba7113f69e23b0fe47d135a4f51b9d50fa45b2 100644
|
||||
index 51ac02abf2f2e61538b26fcbbaa437567310c164..f91a1af51c01e29ee6ec734eee368e04bf714311 100644
|
||||
--- a/third_party/blink/renderer/core/frame/local_frame.cc
|
||||
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
|
||||
@@ -636,10 +636,6 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
|
||||
@@ -665,10 +665,6 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
|
||||
}
|
||||
DCHECK(!view_ || !view_->IsAttached());
|
||||
|
||||
@@ -63,7 +63,7 @@ index c01a916555d1fe5dbf972cba3b7ce248c80df371..d7ba7113f69e23b0fe47d135a4f51b9d
|
||||
if (!Client())
|
||||
return false;
|
||||
|
||||
@@ -687,6 +683,11 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
|
||||
@@ -716,6 +712,11 @@ bool LocalFrame::DetachImpl(FrameDetachType type) {
|
||||
DCHECK(!view_->IsAttached());
|
||||
Client()->WillBeDetached();
|
||||
|
||||
|
||||
@@ -8,13 +8,14 @@ categories in use are known / declared. This patch is required for us
|
||||
to introduce a new Electron category for Electron-specific tracing.
|
||||
|
||||
diff --git a/base/trace_event/builtin_categories.h b/base/trace_event/builtin_categories.h
|
||||
index caf0822f9c14c4be6b9454a1ba006f7bc59086be..8e361bf1796bafbb4682d1bdd4feda98fcc7cbb0 100644
|
||||
index da966a58b11be318770fccdd14986efd2a92ccf8..2a7ea1edd970a205ec5f16c66b5722282f2bcf59 100644
|
||||
--- a/base/trace_event/builtin_categories.h
|
||||
+++ b/base/trace_event/builtin_categories.h
|
||||
@@ -80,6 +80,7 @@
|
||||
@@ -80,6 +80,8 @@
|
||||
X("drm") \
|
||||
X("drmcursor") \
|
||||
X("dwrite") \
|
||||
X("DXVA_Decoding") \
|
||||
+ X("DXVA_Decoding") \
|
||||
+ X("electron") \
|
||||
X("evdev") \
|
||||
X("event") \
|
||||
|
||||
@@ -33,10 +33,10 @@ index 884bccba58c66861b43b3b50a7535cba543302e2..82e7bf534aa6b998cee8df53be3ca7db
|
||||
"//base",
|
||||
"//build:branding_buildflags",
|
||||
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
|
||||
index 2c6b04487112395646469cc077993c6b293fbefa..8a18b4acf613089afbd208fba3a6c8db0268f684 100644
|
||||
index 01194da83fe3f14c5f84671a186ed01fdbd2dc1e..191766f5e9cf2a0f3c43a6abb2d7e0139d1b666c 100644
|
||||
--- a/chrome/browser/BUILD.gn
|
||||
+++ b/chrome/browser/BUILD.gn
|
||||
@@ -4638,7 +4638,7 @@ static_library("browser") {
|
||||
@@ -4618,7 +4618,7 @@ static_library("browser") {
|
||||
|
||||
# On Windows, the hashes are embedded in //chrome:chrome_initial rather
|
||||
# than here in :chrome_dll.
|
||||
@@ -46,10 +46,10 @@ index 2c6b04487112395646469cc077993c6b293fbefa..8a18b4acf613089afbd208fba3a6c8db
|
||||
sources += [ "certificate_viewer_stub.cc" ]
|
||||
}
|
||||
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
|
||||
index 6c55b5fc4cfba94942305f81ad15a83d1c5412c4..f037e4150aef12d2db1d0bd8773e55bcaf723114 100644
|
||||
index 1029220fce0773fffc4fd8259f09e3659daa1979..bbe49d76df9287fe2561a674c1d8acb622508057 100644
|
||||
--- a/chrome/test/BUILD.gn
|
||||
+++ b/chrome/test/BUILD.gn
|
||||
@@ -6584,7 +6584,6 @@ test("unit_tests") {
|
||||
@@ -6589,7 +6589,6 @@ test("unit_tests") {
|
||||
|
||||
deps += [
|
||||
"//chrome:other_version",
|
||||
@@ -57,7 +57,7 @@ index 6c55b5fc4cfba94942305f81ad15a83d1c5412c4..f037e4150aef12d2db1d0bd8773e55bc
|
||||
"//chrome//services/util_win:unit_tests",
|
||||
"//chrome/app:chrome_dll_resources",
|
||||
"//chrome/app:win_unit_tests",
|
||||
@@ -6610,6 +6609,10 @@ test("unit_tests") {
|
||||
@@ -6615,6 +6614,10 @@ test("unit_tests") {
|
||||
"//ui/resources",
|
||||
]
|
||||
|
||||
@@ -68,7 +68,7 @@ index 6c55b5fc4cfba94942305f81ad15a83d1c5412c4..f037e4150aef12d2db1d0bd8773e55bc
|
||||
ldflags = [
|
||||
"/DELAYLOAD:api-ms-win-core-winrt-error-l1-1-0.dll",
|
||||
"/DELAYLOAD:api-ms-win-core-winrt-l1-1-0.dll",
|
||||
@@ -7559,7 +7562,6 @@ test("unit_tests") {
|
||||
@@ -7542,7 +7545,6 @@ test("unit_tests") {
|
||||
}
|
||||
|
||||
deps += [
|
||||
@@ -76,7 +76,7 @@ index 6c55b5fc4cfba94942305f81ad15a83d1c5412c4..f037e4150aef12d2db1d0bd8773e55bc
|
||||
"//chrome/browser/apps:icon_standardizer",
|
||||
"//chrome/browser/apps/app_service",
|
||||
"//chrome/browser/apps/app_service:test_support",
|
||||
@@ -7645,6 +7647,10 @@ test("unit_tests") {
|
||||
@@ -7629,6 +7631,10 @@ test("unit_tests") {
|
||||
"//ui/webui/resources/js/browser_command:mojo_bindings",
|
||||
]
|
||||
|
||||
|
||||
@@ -6,10 +6,18 @@ Subject: build: only use the mas build config in the required components
|
||||
Before landing this patch should be split into the relevant MAS patches, or at least the patch this one partially reverts
|
||||
|
||||
diff --git a/base/BUILD.gn b/base/BUILD.gn
|
||||
index 4925a756be531749e3fe1fd6f1c081b060c28a4f..b7596e0d06f07bcb950fadb0775cec5479af4c0e 100644
|
||||
index 304223b58a7062e3a6ae466d54b9e877708e5cb3..e9efa7f9d44977982fdf72153623e423753f0386 100644
|
||||
--- a/base/BUILD.gn
|
||||
+++ b/base/BUILD.gn
|
||||
@@ -1031,6 +1031,7 @@ component("base") {
|
||||
@@ -228,6 +228,7 @@ if (is_apple) {
|
||||
]
|
||||
defines = [ "BASE_IMPLEMENTATION" ]
|
||||
configs += [ "//build/config/compiler:enable_arc" ]
|
||||
+ configs += [ "//electron/build/config:mas_build" ]
|
||||
deps = [
|
||||
"//base:base_static",
|
||||
"//base/numerics:base_numerics",
|
||||
@@ -1082,6 +1083,7 @@ component("base") {
|
||||
"//build/config/compiler:prevent_unsafe_narrowing",
|
||||
"//build/config/compiler:wexit_time_destructors",
|
||||
"//build/config/compiler:wglobal_constructors",
|
||||
@@ -30,10 +38,10 @@ index 63b32e52a11af599dbc5154ed353e2bf7250e9d3..fc6ed0cdbe211cb29dd5a1dded36b3b0
|
||||
|
||||
if (is_win) {
|
||||
diff --git a/components/os_crypt/sync/BUILD.gn b/components/os_crypt/sync/BUILD.gn
|
||||
index a20e1b68ebd112d66ad82e5753b756218e457c9e..65c7170d1c2dbe4ecfc75c4fed92d6e7ff8efb27 100644
|
||||
index 7ed10085264af6f50b05e51dd93c49e3828d5b3b..d8c77f52376a13af7636e64ff0b5cf58f4fbcf97 100644
|
||||
--- a/components/os_crypt/sync/BUILD.gn
|
||||
+++ b/components/os_crypt/sync/BUILD.gn
|
||||
@@ -71,6 +71,8 @@ component("os_crypt") {
|
||||
@@ -48,6 +48,8 @@ component("os_crypt") {
|
||||
"os_crypt_mac.mm",
|
||||
]
|
||||
configs += [ "//build/config/compiler:enable_arc" ]
|
||||
@@ -43,10 +51,18 @@ index a20e1b68ebd112d66ad82e5753b756218e457c9e..65c7170d1c2dbe4ecfc75c4fed92d6e7
|
||||
|
||||
if (is_win) {
|
||||
diff --git a/components/remote_cocoa/app_shim/BUILD.gn b/components/remote_cocoa/app_shim/BUILD.gn
|
||||
index 0625f07f317de46af619fdb279be78d9ecdc0029..5897820839d6d57ada22a83fe753e3a6b3d752de 100644
|
||||
index 3bc799978ea24e2f6e566dcc7f8638789e18d61d..cd8910dbc57813d41cd0fa28bb2ad61aaa014bc9 100644
|
||||
--- a/components/remote_cocoa/app_shim/BUILD.gn
|
||||
+++ b/components/remote_cocoa/app_shim/BUILD.gn
|
||||
@@ -16,6 +16,7 @@ component("app_shim") {
|
||||
@@ -17,6 +17,7 @@ source_set("app_shim_arc") {
|
||||
configs += [
|
||||
":app_shim_warnings",
|
||||
"//build/config/compiler:enable_arc",
|
||||
+ "//electron/build/config:mas_build"
|
||||
]
|
||||
sources = [
|
||||
"immersive_mode_controller.h",
|
||||
@@ -56,6 +57,7 @@ component("app_shim") {
|
||||
assert(is_mac)
|
||||
|
||||
configs += [ ":app_shim_warnings" ]
|
||||
@@ -55,10 +71,10 @@ index 0625f07f317de46af619fdb279be78d9ecdc0029..5897820839d6d57ada22a83fe753e3a6
|
||||
"alert.h",
|
||||
"alert.mm",
|
||||
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
|
||||
index 9551e3ea2e5f3de9bff158fc0f443df69a27f93a..e8c192bfbe5a2688e8c767443edbe7fb573ed509 100644
|
||||
index 488abc9ed0d61a4b73f4bec34cbca416abfbf715..7b1b36d6ab787e2c43d7556b1e4bb1d39c279879 100644
|
||||
--- a/components/viz/service/BUILD.gn
|
||||
+++ b/components/viz/service/BUILD.gn
|
||||
@@ -332,6 +332,7 @@ viz_component("service") {
|
||||
@@ -331,6 +331,7 @@ viz_component("service") {
|
||||
"frame_sinks/external_begin_frame_source_mac.h",
|
||||
]
|
||||
}
|
||||
@@ -66,7 +82,7 @@ index 9551e3ea2e5f3de9bff158fc0f443df69a27f93a..e8c192bfbe5a2688e8c767443edbe7fb
|
||||
}
|
||||
|
||||
if (is_android || use_ozone) {
|
||||
@@ -588,6 +589,8 @@ viz_source_set("unit_tests") {
|
||||
@@ -587,6 +588,8 @@ viz_source_set("unit_tests") {
|
||||
"display_embedder/software_output_device_mac_unittest.mm",
|
||||
]
|
||||
frameworks = [ "IOSurface.framework" ]
|
||||
@@ -76,7 +92,7 @@ index 9551e3ea2e5f3de9bff158fc0f443df69a27f93a..e8c192bfbe5a2688e8c767443edbe7fb
|
||||
|
||||
if (is_win) {
|
||||
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
|
||||
index caf1b4ee59a75c3ea1363b592e12b6b58d637c01..b554ce1be61de41088c21fced4b9b2dd01e9dc7a 100644
|
||||
index abc33d4abffaff80f6c23f63e206505ffacade86..6e6fe7a75ae6ec87e1f4f13d28ffdffc1bb0e7ea 100644
|
||||
--- a/content/browser/BUILD.gn
|
||||
+++ b/content/browser/BUILD.gn
|
||||
@@ -56,6 +56,7 @@ source_set("browser") {
|
||||
@@ -88,10 +104,10 @@ index caf1b4ee59a75c3ea1363b592e12b6b58d637c01..b554ce1be61de41088c21fced4b9b2dd
|
||||
libs = []
|
||||
frameworks = []
|
||||
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
|
||||
index d38bd551f8bafbc3be22ca0bedb508e4a74ffbb5..9e17dd2484a633301e684dc091b4800d635e5a20 100644
|
||||
index aa1ae523aee045fb1db412a42af8aadb97e9ee2a..e5fe6c0212721a67d67b17ee8871eb92e339f845 100644
|
||||
--- a/content/common/BUILD.gn
|
||||
+++ b/content/common/BUILD.gn
|
||||
@@ -170,6 +170,7 @@ source_set("common") {
|
||||
@@ -174,6 +174,7 @@ source_set("common") {
|
||||
"//content:content_implementation",
|
||||
"//build/config:precompiled_headers",
|
||||
]
|
||||
@@ -100,7 +116,7 @@ index d38bd551f8bafbc3be22ca0bedb508e4a74ffbb5..9e17dd2484a633301e684dc091b4800d
|
||||
public_deps = [
|
||||
":mojo_bindings",
|
||||
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
|
||||
index 34636a58846e2b250e423dde76e4e6ea1f686676..899b75f2be91e86c526f550718e22221eea604f3 100644
|
||||
index 65714a5dca013794527640645d8eb2ce36049ac6..b2df50b4cd64816ddf9c5b7e222c47b60304f01e 100644
|
||||
--- a/content/renderer/BUILD.gn
|
||||
+++ b/content/renderer/BUILD.gn
|
||||
@@ -228,6 +228,7 @@ target(link_target_type, "renderer") {
|
||||
@@ -111,14 +127,39 @@ index 34636a58846e2b250e423dde76e4e6ea1f686676..899b75f2be91e86c526f550718e22221
|
||||
defines = []
|
||||
|
||||
public_deps = [
|
||||
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
|
||||
index 027fa679e34298ec627282796355b6284876520f..14fc5a7c899145872d0df98d7eab019a320da984 100644
|
||||
--- a/content/test/BUILD.gn
|
||||
+++ b/content/test/BUILD.gn
|
||||
@@ -475,6 +475,7 @@ static_library("test_support") {
|
||||
configs += [
|
||||
"//build/config:precompiled_headers",
|
||||
"//v8:external_startup_data",
|
||||
+ "//electron/build/config:mas_build",
|
||||
]
|
||||
|
||||
public_deps = [
|
||||
diff --git a/content/web_test/BUILD.gn b/content/web_test/BUILD.gn
|
||||
index 9d47887dd255187ffe49f5d9dbd01aff5b1de15e..7cde88462e0fc57f9f19badbf1042153708ed423 100644
|
||||
--- a/content/web_test/BUILD.gn
|
||||
+++ b/content/web_test/BUILD.gn
|
||||
@@ -143,6 +143,8 @@ static_library("web_test_browser") {
|
||||
"browser/web_test_tts_platform.h",
|
||||
]
|
||||
|
||||
+ configs += ["//electron/build/config:mas_build"]
|
||||
+
|
||||
if (is_apple) {
|
||||
configs += [ "//build/config/compiler:enable_arc" ]
|
||||
}
|
||||
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn
|
||||
index 642afd72cc0f98fe2590cef0c470f378eabb939e..894769a5de698767117339cab0fc2942d1a20b90 100644
|
||||
index 52940b9bc43aa96dc0a7f90e63ec123ca41c5fab..7c71b07ca2d4b1418b305e876b6be51921b3ea66 100644
|
||||
--- a/device/bluetooth/BUILD.gn
|
||||
+++ b/device/bluetooth/BUILD.gn
|
||||
@@ -240,6 +240,7 @@ component("bluetooth") {
|
||||
"IOKit.framework",
|
||||
@@ -241,6 +241,7 @@ component("bluetooth") {
|
||||
"Foundation.framework",
|
||||
]
|
||||
configs += [ "//build/config/compiler:enable_arc" ]
|
||||
+ configs += ["//electron/build/config:mas_build"]
|
||||
}
|
||||
|
||||
@@ -136,10 +177,10 @@ index ed977f540a2920858a05292f823bf49c669aa6d2..9acd66a086654d77f2a2f84b91779519
|
||||
if (is_ios) {
|
||||
sources += [
|
||||
diff --git a/media/audio/BUILD.gn b/media/audio/BUILD.gn
|
||||
index 93cf87a37792691f41d7c611104a378d9af45195..2d3a0f923f4991be41534e7f951fe5dfcceda5c9 100644
|
||||
index fbed855d14713ec3507b62d86d37b7be9969581e..b08bdea30ad4e5caf26f59c66c34fd63cd6207e4 100644
|
||||
--- a/media/audio/BUILD.gn
|
||||
+++ b/media/audio/BUILD.gn
|
||||
@@ -199,6 +199,7 @@ source_set("audio") {
|
||||
@@ -203,6 +203,7 @@ source_set("audio") {
|
||||
"mac/coreaudio_dispatch_override.h",
|
||||
]
|
||||
frameworks += [ "AudioUnit.framework" ]
|
||||
@@ -148,10 +189,10 @@ index 93cf87a37792691f41d7c611104a378d9af45195..2d3a0f923f4991be41534e7f951fe5df
|
||||
|
||||
if (is_ios) {
|
||||
diff --git a/net/dns/BUILD.gn b/net/dns/BUILD.gn
|
||||
index a8193d411da14f4ff0087fba81e63809832d1806..94c410b59ab7b40654fb214a6a9d828170fe2095 100644
|
||||
index 6eb142954e6a9b2a3937dbf3ae733f330865c9da..f4061586471b23762ba898766ae16b6c46b5a90e 100644
|
||||
--- a/net/dns/BUILD.gn
|
||||
+++ b/net/dns/BUILD.gn
|
||||
@@ -173,6 +173,8 @@ source_set("dns") {
|
||||
@@ -177,6 +177,8 @@ source_set("dns") {
|
||||
":host_resolver_manager",
|
||||
":mdns_client",
|
||||
]
|
||||
@@ -189,10 +230,10 @@ index 5e9fc18352d1bf0939f8366d2282b49aeb307994..69dcc2cafa27b3d8bdf3fe8d0a22a980
|
||||
|
||||
source_set("sandbox_unittests") {
|
||||
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
|
||||
index 2c9080001cf8e8b4da54a4744f6754e3d5aac5a0..e08a38e5f9ea9c15fc5ceba1a38af682055389b7 100644
|
||||
index d1ab6d45d519dd131a854b01b90295b5e7316d71..7086774c980636b160f5152ac2c3c6b737217dd1 100644
|
||||
--- a/third_party/blink/renderer/core/BUILD.gn
|
||||
+++ b/third_party/blink/renderer/core/BUILD.gn
|
||||
@@ -304,6 +304,7 @@ component("core") {
|
||||
@@ -308,6 +308,7 @@ component("core") {
|
||||
configs -= core_config_remove
|
||||
configs += core_config_add
|
||||
configs += [ "//v8:external_startup_data" ]
|
||||
@@ -214,10 +255,10 @@ index 7637db0ce03b9e8d242e47f5aff85c21967a541f..e66fdb98adb035a917942432806e0dfa
|
||||
sources += [ "ca_layer_frame_sink_provider.h" ]
|
||||
}
|
||||
diff --git a/ui/accessibility/platform/BUILD.gn b/ui/accessibility/platform/BUILD.gn
|
||||
index c9777e07fdd311213db325da44573ed09080856e..76a7ca0545b69baf19c6c89088fb277468cb424d 100644
|
||||
index cb282e3a526fb724b25c0d4c6a2af3da30ee0a20..d4275f68211f5a0cddfd2bcbc0f620e8f8b6c7aa 100644
|
||||
--- a/ui/accessibility/platform/BUILD.gn
|
||||
+++ b/ui/accessibility/platform/BUILD.gn
|
||||
@@ -250,6 +250,7 @@ component("platform") {
|
||||
@@ -247,6 +247,7 @@ component("platform") {
|
||||
weak_frameworks = [
|
||||
"Accessibility.framework", # macOS 11
|
||||
]
|
||||
@@ -226,11 +267,11 @@ index c9777e07fdd311213db325da44573ed09080856e..76a7ca0545b69baf19c6c89088fb2774
|
||||
|
||||
if (use_atk) {
|
||||
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn
|
||||
index 9ffa8129d29ecda50f91355ffd01ce9926a70b11..5ebf5ea4db7c692b3288110945d470831e7797e2 100644
|
||||
index e6a0ca42d0fa2446b300714372986da7e2013f16..fd651028ead9103dabcbb3686e412c12ba8e7952 100644
|
||||
--- a/ui/base/BUILD.gn
|
||||
+++ b/ui/base/BUILD.gn
|
||||
@@ -359,6 +359,7 @@ component("base") {
|
||||
"l10n/l10n_util_mac.mm",
|
||||
@@ -355,6 +355,7 @@ component("base") {
|
||||
"interaction/element_tracker_mac.mm",
|
||||
"resource/resource_bundle_mac.mm",
|
||||
]
|
||||
+ configs += ["//electron/build/config:mas_build"]
|
||||
@@ -238,7 +279,7 @@ index 9ffa8129d29ecda50f91355ffd01ce9926a70b11..5ebf5ea4db7c692b3288110945d47083
|
||||
|
||||
if (is_apple) {
|
||||
diff --git a/ui/display/BUILD.gn b/ui/display/BUILD.gn
|
||||
index 4fb4a862d285fababc67d4f2fe38036ea83bd8a9..fa71bc82342412d85fb05312b441cecbfd9da778 100644
|
||||
index e7e52516cec15d41abb9f9c9458c5f3420de7dc0..2e13ca6442c616944577b3374fae082554e585c0 100644
|
||||
--- a/ui/display/BUILD.gn
|
||||
+++ b/ui/display/BUILD.gn
|
||||
@@ -67,6 +67,10 @@ component("display") {
|
||||
@@ -253,10 +294,10 @@ index 4fb4a862d285fababc67d4f2fe38036ea83bd8a9..fa71bc82342412d85fb05312b441cecb
|
||||
|
||||
if (is_win) {
|
||||
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn
|
||||
index c7a777df6803678108952185a40b590bbf419859..76303e25a06ed2123bf9ac6b93b8a1e0a91273e9 100644
|
||||
index f5038c6478eeccc17e061681dbee0f384dac4911..bf23c3576bb7b2d10a840e6eb2a420b739b4f4d7 100644
|
||||
--- a/ui/gfx/BUILD.gn
|
||||
+++ b/ui/gfx/BUILD.gn
|
||||
@@ -192,6 +192,7 @@ component("gfx") {
|
||||
@@ -193,6 +193,7 @@ component("gfx") {
|
||||
"scoped_ns_graphics_context_save_gstate_mac.h",
|
||||
"scoped_ns_graphics_context_save_gstate_mac.mm",
|
||||
]
|
||||
@@ -265,10 +306,10 @@ index c7a777df6803678108952185a40b590bbf419859..76303e25a06ed2123bf9ac6b93b8a1e0
|
||||
if (is_win) {
|
||||
sources += [
|
||||
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn
|
||||
index 01bbf457bc079c266e6110f7ad7c1ba701343312..0718cc10706de5e4b12a891eff696c80352fb9cd 100644
|
||||
index a4072a85236ad029ecb292be0085e537a7c482bb..d9250541ab197f625c42feb96d94aca4cd791195 100644
|
||||
--- a/ui/views/BUILD.gn
|
||||
+++ b/ui/views/BUILD.gn
|
||||
@@ -675,6 +675,7 @@ component("views") {
|
||||
@@ -682,6 +682,7 @@ component("views") {
|
||||
"IOSurface.framework",
|
||||
"QuartzCore.framework",
|
||||
]
|
||||
@@ -276,8 +317,17 @@ index 01bbf457bc079c266e6110f7ad7c1ba701343312..0718cc10706de5e4b12a891eff696c80
|
||||
}
|
||||
|
||||
if (is_win) {
|
||||
@@ -1098,6 +1099,8 @@ source_set("test_support") {
|
||||
"//testing/gtest",
|
||||
]
|
||||
|
||||
+ configs += ["//electron/build/config:mas_build"]
|
||||
+
|
||||
if (is_win) {
|
||||
sources += [
|
||||
"test/desktop_window_tree_host_win_test_api.cc",
|
||||
diff --git a/ui/views/controls/webview/BUILD.gn b/ui/views/controls/webview/BUILD.gn
|
||||
index f37a5a881ac6ac432a4672c5738b7f49b75b5523..1764117f539c2423ebe8bb4c3fe70afcdd0883e8 100644
|
||||
index e3dd4fab3a1cac0138f8dac60247e0ea3343e87e..61ce57a66ec9d686816446c7f05ce82ee7ee442e 100644
|
||||
--- a/ui/views/controls/webview/BUILD.gn
|
||||
+++ b/ui/views/controls/webview/BUILD.gn
|
||||
@@ -19,6 +19,7 @@ component("webview") {
|
||||
|
||||
@@ -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 12b9553587d04990afe25c8e1cc96ce295838498..fba8faa8c1a060a9a8874acd87d259e626c58191 100644
|
||||
index 23f8f5f1042cbc85e630d57e26624963d9cbc71c..544f2bcf906ad40769e5961d97211fbba549d03a 100644
|
||||
--- a/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
@@ -7800,6 +7800,7 @@ void RenderFrameHostImpl::CreateNewWindow(
|
||||
@@ -7836,6 +7836,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 12b9553587d04990afe25c8e1cc96ce295838498..fba8faa8c1a060a9a8874acd87d259e6
|
||||
&no_javascript_access);
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index c7b82e032049fb94f6686f5b1b22c73659919c2e..d9e99e818f0115c341c2b297488b26c75b301ffe 100644
|
||||
index c9b13be94c531a528cdbc8046d80d43fe704ef36..4b53b6060e6d7aae818a3d81faa0a1ae673ea59e 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -4175,6 +4175,12 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
@@ -4212,6 +4212,12 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
|
||||
auto* new_contents_impl = new_contents.get();
|
||||
|
||||
@@ -37,7 +37,7 @@ index c7b82e032049fb94f6686f5b1b22c73659919c2e..d9e99e818f0115c341c2b297488b26c7
|
||||
// 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
|
||||
@@ -4216,12 +4222,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
@@ -4253,12 +4259,6 @@ FrameTree* WebContentsImpl::CreateNewWindow(
|
||||
AddWebContentsDestructionObserver(new_contents_impl);
|
||||
}
|
||||
|
||||
@@ -66,10 +66,10 @@ index 033780b477965e6915fc808cb468598f55050f2b..51da4e464c5768d979188bb46c11565c
|
||||
|
||||
// Operation result when the renderer asks the browser to create a new window.
|
||||
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
|
||||
index 1c459729c7c90f71b40d99ff5a72fc2617361808..d42b55fb8b6a01787e3a167ee9e8ec1c76742c16 100644
|
||||
index d7a8a6d628b790ad9747335b45d1bb148f536ed7..7ba6f9bf054cf9b4d89cfa129caf91a865e1cf97 100644
|
||||
--- a/content/public/browser/content_browser_client.cc
|
||||
+++ b/content/public/browser/content_browser_client.cc
|
||||
@@ -658,6 +658,8 @@ bool ContentBrowserClient::CanCreateWindow(
|
||||
@@ -665,6 +665,8 @@ bool ContentBrowserClient::CanCreateWindow(
|
||||
const std::string& frame_name,
|
||||
WindowOpenDisposition disposition,
|
||||
const blink::mojom::WindowFeatures& features,
|
||||
@@ -79,10 +79,10 @@ index 1c459729c7c90f71b40d99ff5a72fc2617361808..d42b55fb8b6a01787e3a167ee9e8ec1c
|
||||
bool opener_suppressed,
|
||||
bool* no_javascript_access) {
|
||||
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
|
||||
index 44fbcd7d2dde27793cfc2c465717fee32d89eecc..0b04edcca248d337335bde2d28f25c95b07012b8 100644
|
||||
index fe0b1b96209c48d298a0de2041e2841083f891a9..044a426f4dab1b60b035e4f383b6c468446afc74 100644
|
||||
--- a/content/public/browser/content_browser_client.h
|
||||
+++ b/content/public/browser/content_browser_client.h
|
||||
@@ -167,6 +167,7 @@ class NetworkService;
|
||||
@@ -169,6 +169,7 @@ class NetworkService;
|
||||
class TrustedURLLoaderHeaderClient;
|
||||
} // namespace mojom
|
||||
struct ResourceRequest;
|
||||
@@ -90,7 +90,7 @@ index 44fbcd7d2dde27793cfc2c465717fee32d89eecc..0b04edcca248d337335bde2d28f25c95
|
||||
} // namespace network
|
||||
|
||||
namespace sandbox {
|
||||
@@ -1070,6 +1071,8 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
@@ -1078,6 +1079,8 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
const std::string& frame_name,
|
||||
WindowOpenDisposition disposition,
|
||||
const blink::mojom::WindowFeatures& features,
|
||||
@@ -100,7 +100,7 @@ index 44fbcd7d2dde27793cfc2c465717fee32d89eecc..0b04edcca248d337335bde2d28f25c95
|
||||
bool opener_suppressed,
|
||||
bool* no_javascript_access);
|
||||
diff --git a/content/public/browser/web_contents_delegate.cc b/content/public/browser/web_contents_delegate.cc
|
||||
index 885899b151520e0173a5ca68c2613b1333cadddf..5b53ee691c0a07ed1655139ca2d90341b5fa55a3 100644
|
||||
index 0e348f7ca57e3004c1f85435ecd0c66896c5a8fb..8019a5c687a87a4257f9f7c0581781095fc20043 100644
|
||||
--- a/content/public/browser/web_contents_delegate.cc
|
||||
+++ b/content/public/browser/web_contents_delegate.cc
|
||||
@@ -28,6 +28,17 @@ namespace content {
|
||||
@@ -122,7 +122,7 @@ index 885899b151520e0173a5ca68c2613b1333cadddf..5b53ee691c0a07ed1655139ca2d90341
|
||||
const OpenURLParams& params) {
|
||||
return nullptr;
|
||||
diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h
|
||||
index 5da6f93293bc5ddae88c17ac2dd8d7037ba8e8f3..76d699790fb7d92587293b14332f696dc5460322 100644
|
||||
index c5bda327264c330345baf7b44b4ba5c478e58952..989778079d5dc91127989e43f3ce6b25a9df56d4 100644
|
||||
--- a/content/public/browser/web_contents_delegate.h
|
||||
+++ b/content/public/browser/web_contents_delegate.h
|
||||
@@ -16,6 +16,7 @@
|
||||
@@ -148,10 +148,10 @@ index 5da6f93293bc5ddae88c17ac2dd8d7037ba8e8f3..76d699790fb7d92587293b14332f696d
|
||||
// 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 59f5d3e730a108c7541925809b7c49345f556257..1a0e197b5fe5b698671ddcb0660b69669939ebc2 100644
|
||||
index 556f5310719f9a9e56bb3a34d75a529b8b26f839..68cc76c0f63f3f828ab582dab88f893453144b2a 100644
|
||||
--- a/content/renderer/render_frame_impl.cc
|
||||
+++ b/content/renderer/render_frame_impl.cc
|
||||
@@ -6288,6 +6288,10 @@ WebView* RenderFrameImpl::CreateNewWindow(
|
||||
@@ -6316,6 +6316,10 @@ WebView* RenderFrameImpl::CreateNewWindow(
|
||||
blink::GetNavigationInitiatorActivationAndAdStatus(
|
||||
request.HasUserGesture(), GetWebFrame()->IsAdScriptInStack());
|
||||
|
||||
@@ -163,7 +163,7 @@ index 59f5d3e730a108c7541925809b7c49345f556257..1a0e197b5fe5b698671ddcb0660b6966
|
||||
// moved on send.
|
||||
bool is_background_tab =
|
||||
diff --git a/content/web_test/browser/web_test_content_browser_client.cc b/content/web_test/browser/web_test_content_browser_client.cc
|
||||
index bdf18ff21a92c7cde33cb299b5c3c0a609ce2ea8..97822402213729a4204cf36c3cd42ee5f568fc21 100644
|
||||
index e4ee6ba03a5683ce7b1a72ac643b5b2520a2f998..44ac0ad92d22b2db8992c67910e420029f005433 100644
|
||||
--- a/content/web_test/browser/web_test_content_browser_client.cc
|
||||
+++ b/content/web_test/browser/web_test_content_browser_client.cc
|
||||
@@ -504,6 +504,8 @@ bool WebTestContentBrowserClient::CanCreateWindow(
|
||||
@@ -176,7 +176,7 @@ index bdf18ff21a92c7cde33cb299b5c3c0a609ce2ea8..97822402213729a4204cf36c3cd42ee5
|
||||
bool opener_suppressed,
|
||||
bool* no_javascript_access) {
|
||||
diff --git a/content/web_test/browser/web_test_content_browser_client.h b/content/web_test/browser/web_test_content_browser_client.h
|
||||
index 6e9041279578d8365a4eae6bd9f221baf79324d7..39ff665cc8b87ed4997a60a18c05cd42bc6ffd24 100644
|
||||
index d17a2d7f09d1899f2e8888c4747ecffbc5b5ff9a..894795fe392013e66513f1f578970908ec652d5d 100644
|
||||
--- a/content/web_test/browser/web_test_content_browser_client.h
|
||||
+++ b/content/web_test/browser/web_test_content_browser_client.h
|
||||
@@ -83,6 +83,8 @@ class WebTestContentBrowserClient : public ShellContentBrowserClient {
|
||||
@@ -210,10 +210,10 @@ index bef5a989bac50c177f15f52fe87ac3790d553e85..65dcd2e3b51929400c8bfb6a98a4fb59
|
||||
|
||||
} // 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 0fe13a68578656da5bd511ce7ea2339150080044..cd6f197dcfdd797c0cffe1194a949c8c095c20ae 100644
|
||||
index 6283f14f8b613bc435f8c04fec13d1222795797a..2313fe0a9092dd41db0fecf17080ed12b91b0485 100644
|
||||
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
|
||||
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
|
||||
@@ -2202,6 +2202,8 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
|
||||
@@ -2195,6 +2195,8 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
|
||||
WebWindowFeatures window_features =
|
||||
GetWindowFeaturesFromString(features, entered_window);
|
||||
|
||||
|
||||
40
patches/chromium/cherry-pick-b11e7d07a6f4.patch
Normal file
40
patches/chromium/cherry-pick-b11e7d07a6f4.patch
Normal file
@@ -0,0 +1,40 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lei Zhang <thestig@chromium.org>
|
||||
Date: Wed, 13 Sep 2023 23:32:40 +0000
|
||||
Subject: M117: Check for object destruction in PdfViewWebPlugin::UpdateFocus()
|
||||
|
||||
PdfViewWebPlugin::UpdateFocus() can potentially triggers its own
|
||||
destruction. Add a check for this and bail out.
|
||||
|
||||
(cherry picked from commit cacf485a202b342526374d444375b80a044add76)
|
||||
|
||||
Bug: 1480184
|
||||
Change-Id: I5e7760ed541a2bffb9dd1ebeb522f10650049033
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4852346
|
||||
Reviewed-by: Tom Sepez <tsepez@chromium.org>
|
||||
Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com>
|
||||
Commit-Queue: Lei Zhang <thestig@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1194210}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4863395
|
||||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||||
Cr-Commit-Position: refs/branch-heads/5938@{#1286}
|
||||
Cr-Branched-From: 2b50cb4bcc2318034581a816714d9535dc38966d-refs/heads/main@{#1181205}
|
||||
|
||||
diff --git a/pdf/pdf_view_web_plugin.cc b/pdf/pdf_view_web_plugin.cc
|
||||
index ff6c55728c83cadbce6c7cc9387ccdf8a57d1306..e4bd28814c2b2d8c9fa12a1e48dab979c8f671c8 100644
|
||||
--- a/pdf/pdf_view_web_plugin.cc
|
||||
+++ b/pdf/pdf_view_web_plugin.cc
|
||||
@@ -517,7 +517,13 @@ void PdfViewWebPlugin::UpdateFocus(bool focused,
|
||||
if (has_focus_ != focused) {
|
||||
engine_->UpdateFocus(focused);
|
||||
client_->UpdateTextInputState();
|
||||
+
|
||||
+ // Make sure `this` is still alive after the UpdateSelectionBounds() call.
|
||||
+ auto weak_this = weak_factory_.GetWeakPtr();
|
||||
client_->UpdateSelectionBounds();
|
||||
+ if (!weak_this) {
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
has_focus_ = focused;
|
||||
|
||||
201
patches/chromium/cherry-pick-d756d71a652c.patch
Normal file
201
patches/chromium/cherry-pick-d756d71a652c.patch
Normal file
@@ -0,0 +1,201 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Moshchuk <alexmos@chromium.org>
|
||||
Date: Mon, 9 Oct 2023 17:14:13 +0000
|
||||
Subject: Fix RFHI::pending_navigate_ cleanup after crashes and early RFH
|
||||
swaps.
|
||||
|
||||
When resuming a navigation that had been saved into
|
||||
RenderFrameHostImpl::pending_navigate_, we need to account for the
|
||||
fact that OnBeginNavigation() calls GetFrameHostForNavigation() which
|
||||
may perform an early RenderFrameHost swap and synchronously destroy
|
||||
the old RFH.
|
||||
|
||||
There's also no need to keep a pending_navigate_ around after the
|
||||
corresponding renderer process crashes, so this CL also adds logic to
|
||||
clear it. Resuming such a navigation would require additional work,
|
||||
since the NavigationClient stashed in pending_navigate_ is no longer
|
||||
usable and would just immediately call the disconnect handler and
|
||||
cancel the navigation. But there isn't really any benefit to adding
|
||||
that complexity, and we already cancel the RFH's other ongoing
|
||||
navigations when its renderer process dies.
|
||||
|
||||
This CL also tweaks the logic in RenderWidgetHostImpl to allow the
|
||||
resuming logic (ResumeLoadingCreatedWebContents) to work without
|
||||
hitting DCHECKs, if it's called after a renderer process crash. This
|
||||
case never worked cleanly before, but is supported now (and allows the
|
||||
new test to work without crashing).
|
||||
|
||||
(cherry picked from commit 093daae65d50511c2027d01f9188681749b5a1be)
|
||||
|
||||
Bug: 1487110
|
||||
Change-Id: Icd6a55002e52729e6ee966210efba1a5ce23eb55
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4908270
|
||||
Commit-Queue: Alex Moshchuk <alexmos@chromium.org>
|
||||
Reviewed-by: Rakina Zata Amni <rakina@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1205927}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4923011
|
||||
Owners-Override: Krishna Govind <govind@chromium.org>
|
||||
Reviewed-by: Krishna Govind <govind@chromium.org>
|
||||
Commit-Queue: Krishna Govind <govind@chromium.org>
|
||||
Cr-Commit-Position: refs/branch-heads/5993@{#1208}
|
||||
Cr-Branched-From: 511350718e646be62331ae9d7213d10ec320d514-refs/heads/main@{#1192594}
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
index 2c5a63a85ba37573182ab9b8731f70948c2cc0e6..505ae0be1155585a19deb29e0c6734e9878f46c2 100644
|
||||
--- a/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
@@ -3119,6 +3119,13 @@ void RenderFrameHostImpl::RenderProcessGone(
|
||||
ResetOwnedNavigationRequests(NavigationDiscardReason::kRenderProcessGone);
|
||||
ResetLoadingState();
|
||||
|
||||
+ // Also, clear any pending navigations that have been blocked while the
|
||||
+ // embedder is processing window.open() requests. This is consistent
|
||||
+ // with clearing NavigationRequests and loading state above, and it also
|
||||
+ // makes sense because certain parts of `pending_navigate_`, like the
|
||||
+ // NavigationClient remote interface, can no longer be used.
|
||||
+ pending_navigate_.reset();
|
||||
+
|
||||
// Any future UpdateState or UpdateTitle messages from this or a recreated
|
||||
// process should be ignored until the next commit.
|
||||
set_nav_entry_id(0);
|
||||
@@ -3528,14 +3535,25 @@ void RenderFrameHostImpl::Init() {
|
||||
// BeginNavigation() should only be triggered when the navigation is
|
||||
// initiated by a document in the same process.
|
||||
const int initiator_process_id = GetProcess()->GetID();
|
||||
+
|
||||
+ // Transfer `pending_navigate_` to a local variable, to avoid resetting it
|
||||
+ // after OnBeginNavigation since `this` might already be destroyed (see
|
||||
+ // below).
|
||||
+ //
|
||||
+ // This shouldn't matter for early RFH swaps out of crashed frames, since
|
||||
+ // `pending_navigate_` is cleared when the renderer process dies, but it
|
||||
+ // may matter for other current/future use cases of the early RFH swap.
|
||||
+ std::unique_ptr<PendingNavigation> pending_navigation =
|
||||
+ std::move(pending_navigate_);
|
||||
frame_tree_node()->navigator().OnBeginNavigation(
|
||||
- frame_tree_node(), std::move(pending_navigate_->common_params),
|
||||
- std::move(pending_navigate_->begin_navigation_params),
|
||||
- std::move(pending_navigate_->blob_url_loader_factory),
|
||||
- std::move(pending_navigate_->navigation_client),
|
||||
+ frame_tree_node(), std::move(pending_navigation->common_params),
|
||||
+ std::move(pending_navigation->begin_navigation_params),
|
||||
+ std::move(pending_navigation->blob_url_loader_factory),
|
||||
+ std::move(pending_navigation->navigation_client),
|
||||
EnsurePrefetchedSignedExchangeCache(), initiator_process_id,
|
||||
- std::move(pending_navigate_->renderer_cancellation_listener));
|
||||
- pending_navigate_.reset();
|
||||
+ std::move(pending_navigation->renderer_cancellation_listener));
|
||||
+ // DO NOT ADD CODE after this, as `this` might be deleted if an early
|
||||
+ // RenderFrameHost swap was performed when starting the navigation above.
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
|
||||
index 7107c17a8f36688d245b4cad5ee92dfcedd2485e..94a726acd9a65fdddd0eed81f064d5f17d536aa3 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
|
||||
@@ -757,9 +757,15 @@ void RenderWidgetHostImpl::RendererWidgetCreated(bool for_frame_widget) {
|
||||
}
|
||||
|
||||
void RenderWidgetHostImpl::Init() {
|
||||
- DCHECK(renderer_widget_created_);
|
||||
- DCHECK(waiting_for_init_);
|
||||
+ // Note that this may be called after a renderer crash. In this case, we can
|
||||
+ // just exit early, as there is nothing else to do. Note that
|
||||
+ // `waiting_for_init_` should've already been reset to false in that case.
|
||||
+ if (!renderer_widget_created_) {
|
||||
+ DCHECK(!waiting_for_init_);
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
+ DCHECK(waiting_for_init_);
|
||||
waiting_for_init_ = false;
|
||||
|
||||
// These two methods avoid running while we are `waiting_for_init_`, so we
|
||||
@@ -2277,6 +2283,10 @@ void RenderWidgetHostImpl::RendererExited() {
|
||||
|
||||
blink_widget_.reset();
|
||||
|
||||
+ // No need to perform a deferred show after the renderer crashes, and this
|
||||
+ // wouldn't work anyway as it requires a valid `blink_widget_`.
|
||||
+ pending_show_params_.reset();
|
||||
+
|
||||
// After the renderer crashes, the view is destroyed and so the
|
||||
// RenderWidgetHost cannot track its visibility anymore. We assume such
|
||||
// RenderWidgetHost to be invisible for the sake of internal accounting - be
|
||||
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc
|
||||
index c3aebce8b6aeefd85b6e87d50272cf3a798923bb..9a06710dd0998f852f0440c2652d88fc612b4560 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl_browsertest.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
|
||||
@@ -81,6 +81,7 @@
|
||||
#include "content/public/test/fenced_frame_test_util.h"
|
||||
#include "content/public/test/mock_client_hints_controller_delegate.h"
|
||||
#include "content/public/test/mock_web_contents_observer.h"
|
||||
+#include "content/public/test/navigation_handle_observer.h"
|
||||
#include "content/public/test/no_renderer_crashes_assertion.h"
|
||||
#include "content/public/test/prerender_test_util.h"
|
||||
#include "content/public/test/resource_load_observer.h"
|
||||
@@ -5573,6 +5574,63 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
|
||||
EXPECT_FALSE(shell()->web_contents()->IsCrashed());
|
||||
}
|
||||
|
||||
+// Check that there's no crash if a new window is set to defer navigations (for
|
||||
+// example, this is done on Android Webview and for <webview> guests), then the
|
||||
+// renderer process crashes while there's a deferred new window navigation in
|
||||
+// place, and then navigations are resumed. Prior to fixing
|
||||
+// https://crbug.com/1487110, the deferred navigation was allowed to proceed,
|
||||
+// performing an early RenderFrameHost swap and hitting a bug while clearing
|
||||
+// the deferred navigation state. Now, the deferred navigation should be
|
||||
+// canceled when the renderer process dies.
|
||||
+IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
|
||||
+ DeferredWindowOpenNavigationIsResumedWithEarlySwap) {
|
||||
+ // Force WebContents in a new Shell to defer new navigations until the
|
||||
+ // delegate is set.
|
||||
+ shell()->set_delay_popup_contents_delegate_for_testing(true);
|
||||
+
|
||||
+ // Load an initial page.
|
||||
+ ASSERT_TRUE(embedded_test_server()->Start());
|
||||
+ GURL url(embedded_test_server()->GetURL("/title1.html"));
|
||||
+ EXPECT_TRUE(NavigateToURL(shell(), url));
|
||||
+
|
||||
+ // Open a popup to a same-site URL via window.open.
|
||||
+ ShellAddedObserver new_shell_observer;
|
||||
+ EXPECT_TRUE(ExecJs(shell(), JsReplace("window.open($1);", url)));
|
||||
+ Shell* new_shell = new_shell_observer.GetShell();
|
||||
+ WebContents* new_contents = new_shell->web_contents();
|
||||
+
|
||||
+ // The navigation in the new popup should be deferred.
|
||||
+ EXPECT_TRUE(WaitForLoadStop(new_contents));
|
||||
+ EXPECT_TRUE(new_contents->GetController().IsInitialBlankNavigation());
|
||||
+ EXPECT_TRUE(new_contents->GetLastCommittedURL().is_empty());
|
||||
+
|
||||
+ // Set the new shell's delegate now. This doesn't resume the navigation just
|
||||
+ // yet.
|
||||
+ EXPECT_FALSE(new_contents->GetDelegate());
|
||||
+ new_contents->SetDelegate(new_shell);
|
||||
+
|
||||
+ // Crash the renderer process. This should clear the deferred navigation
|
||||
+ // state. If this wasn't done due to a bug, it would also force the resumed
|
||||
+ // navigation to use the early RenderFrameHost swap.
|
||||
+ {
|
||||
+ RenderProcessHost* popup_process =
|
||||
+ new_contents->GetPrimaryMainFrame()->GetProcess();
|
||||
+ RenderProcessHostWatcher crash_observer(
|
||||
+ popup_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
|
||||
+ EXPECT_TRUE(popup_process->Shutdown(0));
|
||||
+ crash_observer.Wait();
|
||||
+ }
|
||||
+
|
||||
+ // Resume the navigation and verify that it gets canceled. Ensure this
|
||||
+ // doesn't crash.
|
||||
+ NavigationHandleObserver handle_observer(new_contents, url);
|
||||
+ new_contents->ResumeLoadingCreatedWebContents();
|
||||
+ EXPECT_TRUE(WaitForLoadStop(new_contents));
|
||||
+ EXPECT_FALSE(handle_observer.has_committed());
|
||||
+ EXPECT_TRUE(new_contents->GetController().IsInitialBlankNavigation());
|
||||
+ EXPECT_TRUE(new_contents->GetLastCommittedURL().is_empty());
|
||||
+}
|
||||
+
|
||||
namespace {
|
||||
|
||||
class MediaWaiter : public WebContentsObserver {
|
||||
56
patches/chromium/cherry-pick-f218b4f37018.patch
Normal file
56
patches/chromium/cherry-pick-f218b4f37018.patch
Normal file
@@ -0,0 +1,56 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Joshua Pawlicki <waffles@chromium.org>
|
||||
Date: Fri, 29 Sep 2023 22:25:20 +0000
|
||||
Subject: update_client: Check string length before calling front().
|
||||
|
||||
(cherry picked from commit 6581c6b7c4b7b627b32b09cdbe9e84d2dd9ec018)
|
||||
|
||||
Fixed: 1486316
|
||||
Change-Id: I7be04ea0c8e040b5a67364925fc06d4ee9167242
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4892838
|
||||
Commit-Queue: Joshua Pawlicki <waffles@chromium.org>
|
||||
Auto-Submit: Joshua Pawlicki <waffles@chromium.org>
|
||||
Reviewed-by: Sorin Jianu <sorin@chromium.org>
|
||||
Cr-Original-Commit-Position: refs/heads/main@{#1201617}
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4902697
|
||||
Cr-Commit-Position: refs/branch-heads/5993@{#978}
|
||||
Cr-Branched-From: 511350718e646be62331ae9d7213d10ec320d514-refs/heads/main@{#1192594}
|
||||
|
||||
diff --git a/components/update_client/protocol_parser_json.cc b/components/update_client/protocol_parser_json.cc
|
||||
index 9858ba06290675ae39d2606fbe4aea34f2efe655..ba1aeba747d990bc97977bebb60f1141e3981517 100644
|
||||
--- a/components/update_client/protocol_parser_json.cc
|
||||
+++ b/components/update_client/protocol_parser_json.cc
|
||||
@@ -196,7 +196,7 @@ bool ParseUpdateCheck(const base::Value& updatecheck_node_val,
|
||||
const base::Value::Dict& updatecheck_node = updatecheck_node_val.GetDict();
|
||||
|
||||
for (auto kv : updatecheck_node) {
|
||||
- if (kv.first.front() == '_' && kv.second.is_string()) {
|
||||
+ if (!kv.first.empty() && kv.first.front() == '_' && kv.second.is_string()) {
|
||||
result->custom_attributes[kv.first] = kv.second.GetString();
|
||||
}
|
||||
}
|
||||
diff --git a/components/update_client/protocol_parser_json_unittest.cc b/components/update_client/protocol_parser_json_unittest.cc
|
||||
index 606c6ddc8f906e4bcd0722828ab34f5c77e73e5d..c59bf8ab7b1f7751c2e78396712f0de283c3b00d 100644
|
||||
--- a/components/update_client/protocol_parser_json_unittest.cc
|
||||
+++ b/components/update_client/protocol_parser_json_unittest.cc
|
||||
@@ -393,6 +393,10 @@ const char* kJSONCustomAttributes = R"()]}'
|
||||
]
|
||||
}})";
|
||||
|
||||
+const char* kBadJSONBadAppIdNoNewlinesBadUCKey =
|
||||
+ R"()]}'{"response":{"app":[{"appid":";","updatecheck":{"":1}}],)"
|
||||
+ R"("protocol":"3.1"}})";
|
||||
+
|
||||
TEST(UpdateClientProtocolParserJSONTest, Parse) {
|
||||
const auto parser = std::make_unique<ProtocolParserJSON>();
|
||||
|
||||
@@ -610,4 +614,9 @@ TEST(UpdateClientProtocolParserJSONTest, ParseAttrs) {
|
||||
}
|
||||
}
|
||||
|
||||
+TEST(UpdateClientProtocolParserJSONTest, ParseBadJSONNoCrash) {
|
||||
+ const auto parser = std::make_unique<ProtocolParserJSON>();
|
||||
+ EXPECT_TRUE(parser->Parse(kBadJSONBadAppIdNoNewlinesBadUCKey));
|
||||
+}
|
||||
+
|
||||
} // namespace update_client
|
||||
@@ -0,0 +1,33 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Charles Kerr <charles@charleskerr.com>
|
||||
Date: Wed, 5 Jul 2023 16:28:30 -0500
|
||||
Subject: chore: add BUILDFLAG guard around new include
|
||||
|
||||
Xref: https://chromium-review.googlesource.com/c/chromium/src/+/4628373
|
||||
|
||||
This is an experimental commit; but if it's successful,
|
||||
This patch should be upstreamed and then removed from electron's code.
|
||||
|
||||
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
|
||||
index 7145cc6ad5d1724cde8e2c6b6168a36f4e6b2dbe..f796d075fd07d68e6992c351f639288e9baa4224 100644
|
||||
--- a/chrome/browser/ui/views/frame/browser_view.h
|
||||
+++ b/chrome/browser/ui/views/frame/browser_view.h
|
||||
@@ -43,7 +43,6 @@
|
||||
#include "chrome/browser/ui/views/user_education/browser_feature_promo_controller.h"
|
||||
#include "chrome/common/buildflags.h"
|
||||
#include "components/infobars/core/infobar_container.h"
|
||||
-#include "components/segmentation_platform/public/result.h"
|
||||
#include "components/user_education/common/feature_promo_controller.h"
|
||||
#include "components/user_education/common/feature_promo_handle.h"
|
||||
#include "components/webapps/browser/banners/app_banner_manager.h"
|
||||
@@ -62,6 +61,10 @@
|
||||
#include "ui/views/widget/widget_observer.h"
|
||||
#include "ui/views/window/client_view.h"
|
||||
|
||||
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
|
||||
+#include "components/segmentation_platform/public/result.h"
|
||||
+#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
|
||||
+
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
#include "ui/compositor/throughput_tracker.h"
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user