mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
286 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69fe268d4d | ||
|
|
55738ddac3 | ||
|
|
7916733f5f | ||
|
|
6c37483f2c | ||
|
|
bb6a7d443b | ||
|
|
a3c0d0db3f | ||
|
|
0ffac056c3 | ||
|
|
ae70118ffb | ||
|
|
8c384c13b3 | ||
|
|
91fa68bd32 | ||
|
|
6b67839770 | ||
|
|
fc98a28d67 | ||
|
|
f1c1b22fd4 | ||
|
|
4439b13027 | ||
|
|
1bd2e574a7 | ||
|
|
468c4af661 | ||
|
|
83576caa40 | ||
|
|
36edecf606 | ||
|
|
3f3c0c45f2 | ||
|
|
805674fa8a | ||
|
|
e7ba28f8f9 | ||
|
|
8e0d1af44e | ||
|
|
dde1b500cc | ||
|
|
fefe45e897 | ||
|
|
bd43e652f6 | ||
|
|
bb01e52fb8 | ||
|
|
985b56a68d | ||
|
|
47a2df48b9 | ||
|
|
b5646778e9 | ||
|
|
772bbe775c | ||
|
|
be3b6c1e2b | ||
|
|
cf49565a31 | ||
|
|
415301c477 | ||
|
|
b4742f9f91 | ||
|
|
5868f9ac5e | ||
|
|
6e675c831e | ||
|
|
66432ed9fc | ||
|
|
0ed48378c2 | ||
|
|
42b4744740 | ||
|
|
04e85b4eda | ||
|
|
e42169b7e4 | ||
|
|
67b2739f44 | ||
|
|
a5e78c4a2f | ||
|
|
fe62d46a4a | ||
|
|
beebf99946 | ||
|
|
df0f25dfd9 | ||
|
|
e0e5549ce8 | ||
|
|
1d1ce9c63f | ||
|
|
aa799e2239 | ||
|
|
3ac4532efb | ||
|
|
dc3ce65dd5 | ||
|
|
9faee48070 | ||
|
|
69b8ebc7f4 | ||
|
|
2e8177c839 | ||
|
|
7a3d7b5c95 | ||
|
|
84b863d399 | ||
|
|
149f314e38 | ||
|
|
0c450f8c89 | ||
|
|
3a99edbbdb | ||
|
|
4d371b067b | ||
|
|
84d7f7f071 | ||
|
|
4cefd54143 | ||
|
|
c7fde250bb | ||
|
|
1c7de7e5ee | ||
|
|
4ad7e5f648 | ||
|
|
3bb93c472d | ||
|
|
0412b07612 | ||
|
|
f818ec3295 | ||
|
|
437a0a2c6e | ||
|
|
2d4c150a99 | ||
|
|
31aa0dacee | ||
|
|
39bdf64347 | ||
|
|
1f3161b2ce | ||
|
|
e3f64e7b1f | ||
|
|
6fb688889d | ||
|
|
92371e7231 | ||
|
|
417f2fd3f1 | ||
|
|
e033c294fc | ||
|
|
f138d464b2 | ||
|
|
dfd80db886 | ||
|
|
74d019463a | ||
|
|
a56fbc563a | ||
|
|
00fa1e8404 | ||
|
|
34be316c40 | ||
|
|
cde60dff6a | ||
|
|
7970dc2c0e | ||
|
|
ea2d902de8 | ||
|
|
c697368d14 | ||
|
|
174696e604 | ||
|
|
9b01cedffd | ||
|
|
7e60fc4922 | ||
|
|
e90f6e2e38 | ||
|
|
5c23f17d16 | ||
|
|
a3c129d5d0 | ||
|
|
efa09d8da2 | ||
|
|
d219fcc8b6 | ||
|
|
762ce69066 | ||
|
|
57ce0704e3 | ||
|
|
1f20e4c284 | ||
|
|
b8f05c3648 | ||
|
|
990fb72e35 | ||
|
|
c18e5bae5f | ||
|
|
b71a50e2d3 | ||
|
|
38ce1d68d6 | ||
|
|
eb8dcb52aa | ||
|
|
3d07626ddf | ||
|
|
9caade81c4 | ||
|
|
8c89a771b2 | ||
|
|
b5c8af02f5 | ||
|
|
db7acc9fc0 | ||
|
|
eccc08e653 | ||
|
|
c50975f664 | ||
|
|
20a551ba94 | ||
|
|
8926e4e93d | ||
|
|
bca09956f3 | ||
|
|
5fa67613d9 | ||
|
|
974dbc167c | ||
|
|
1fae9d5ac0 | ||
|
|
6978a722d4 | ||
|
|
b68143a9be | ||
|
|
910cafd785 | ||
|
|
b1223100f5 | ||
|
|
4a20042b5e | ||
|
|
0e5725b4a1 | ||
|
|
95aa5405e7 | ||
|
|
3c75dd1684 | ||
|
|
81fb39f154 | ||
|
|
2448993d1c | ||
|
|
deb0f6ecc0 | ||
|
|
476c925660 | ||
|
|
2b355f8ab3 | ||
|
|
dadb872c3d | ||
|
|
5305596f02 | ||
|
|
9281a34f8b | ||
|
|
35cf190ab9 | ||
|
|
6c7e9b861d | ||
|
|
37df7c5170 | ||
|
|
2fdfa0b662 | ||
|
|
0034868d6c | ||
|
|
1b626b805b | ||
|
|
a597775259 | ||
|
|
71d9362819 | ||
|
|
32eb8c9336 | ||
|
|
1c0936897e | ||
|
|
7e401f4828 | ||
|
|
679f4732bd | ||
|
|
fcab6c6705 | ||
|
|
32d4d01b3c | ||
|
|
cc01109491 | ||
|
|
3505270a2a | ||
|
|
fc5a7dd023 | ||
|
|
1cb343e079 | ||
|
|
11c6f1f684 | ||
|
|
c5e5b13003 | ||
|
|
f44be42478 | ||
|
|
70fe0d9a07 | ||
|
|
cea70deb8a | ||
|
|
31b0daaa91 | ||
|
|
4249800e9c | ||
|
|
2ba9860a5a | ||
|
|
7c65388483 | ||
|
|
96ae5c107e | ||
|
|
6dc122fe5a | ||
|
|
160d48f0f2 | ||
|
|
605d6c9f41 | ||
|
|
b606a98b77 | ||
|
|
4779d565d2 | ||
|
|
a7bb6de466 | ||
|
|
8f9f1cc2fe | ||
|
|
90040360c3 | ||
|
|
b452c7fab4 | ||
|
|
b1cddb0dc8 | ||
|
|
f755b2579f | ||
|
|
7bca7f2c0f | ||
|
|
ed328d8987 | ||
|
|
1a7c546c3a | ||
|
|
748c4bfbcb | ||
|
|
9ec8b1d21c | ||
|
|
32138c6405 | ||
|
|
bc458c97dc | ||
|
|
06ac9d989f | ||
|
|
e8ef5f4ae4 | ||
|
|
6c136d5582 | ||
|
|
7ddb80fbb1 | ||
|
|
3a2306d9e4 | ||
|
|
38d83cfefc | ||
|
|
d61f6309a2 | ||
|
|
126897bd6b | ||
|
|
d3f0970964 | ||
|
|
012774a0eb | ||
|
|
a546545a53 | ||
|
|
742bd735e6 | ||
|
|
a54725b6b5 | ||
|
|
be61126d30 | ||
|
|
7fbc867eaf | ||
|
|
0c4134fefe | ||
|
|
b19a3a65a4 | ||
|
|
563a0622d9 | ||
|
|
6a5bd8dc28 | ||
|
|
b78c30a6d8 | ||
|
|
9ecd8910de | ||
|
|
da87a471fe | ||
|
|
6544df1992 | ||
|
|
c9f7ebf821 | ||
|
|
d3a0a255b1 | ||
|
|
2d3819e2a8 | ||
|
|
bd384b5301 | ||
|
|
1e13475e89 | ||
|
|
8ce23c425d | ||
|
|
c891980848 | ||
|
|
15f4e8ef88 | ||
|
|
b6b4971da0 | ||
|
|
14918767d8 | ||
|
|
f7a16f33a8 | ||
|
|
662fa261da | ||
|
|
8ceb20c75c | ||
|
|
e0e824f069 | ||
|
|
ab0a13eed6 | ||
|
|
7910ace135 | ||
|
|
eb8eb6fae2 | ||
|
|
c9bea8b712 | ||
|
|
71ee04a3e2 | ||
|
|
f7f55d096a | ||
|
|
ad6155f08e | ||
|
|
37caca046f | ||
|
|
ea6a8eea22 | ||
|
|
d314b4e18b | ||
|
|
1bc8549ce5 | ||
|
|
8e6c8cc384 | ||
|
|
5c13da7c40 | ||
|
|
45a5827e09 | ||
|
|
e809a5a043 | ||
|
|
4f2e369bdc | ||
|
|
eef9787c48 | ||
|
|
81fe8993ec | ||
|
|
55b5c85f92 | ||
|
|
a0e6ca8dab | ||
|
|
e30b25269d | ||
|
|
319d77a4ee | ||
|
|
e22767b1e7 | ||
|
|
5008e3ecab | ||
|
|
d69776bfb0 | ||
|
|
b56e4287d3 | ||
|
|
1254a684dd | ||
|
|
99a81e4ef0 | ||
|
|
36d5706ea9 | ||
|
|
2ae9588e1c | ||
|
|
320415edf9 | ||
|
|
dd59115ac6 | ||
|
|
80a378a9de | ||
|
|
8d2530437e | ||
|
|
dde3a0f1ba | ||
|
|
ce079c02bc | ||
|
|
f23df11352 | ||
|
|
abb86a7ea1 | ||
|
|
8f96b2192a | ||
|
|
977a7eb1d0 | ||
|
|
504588c861 | ||
|
|
5bc09dda1a | ||
|
|
6b72837203 | ||
|
|
9f2bef9a65 | ||
|
|
d0273d83ef | ||
|
|
248dc89217 | ||
|
|
a75a867997 | ||
|
|
0d82286a23 | ||
|
|
4553ec2a2a | ||
|
|
62f64f9f03 | ||
|
|
f35adf303b | ||
|
|
f236478b2b | ||
|
|
b69de7c412 | ||
|
|
8c3bbded4f | ||
|
|
d9019fc54b | ||
|
|
7c624c17fa | ||
|
|
3e336d2923 | ||
|
|
95b727ccdb | ||
|
|
382b19f816 | ||
|
|
a1b3b506d7 | ||
|
|
9b25d6b91b | ||
|
|
b113c5d583 | ||
|
|
a36e44c973 | ||
|
|
8ae741102d | ||
|
|
666e8f9647 | ||
|
|
fdceacce44 | ||
|
|
0ad8ffa3d2 | ||
|
|
031283003c | ||
|
|
63fdcba0c8 |
@@ -62,7 +62,7 @@ jobs:
|
||||
cd .circleci/config
|
||||
yarn
|
||||
export CIRCLECI_BINARY="$HOME/circleci"
|
||||
curl -fLSs https://raw.githubusercontent.com/CircleCI-Public/circleci-cli/main/install.sh | DESTDIR=$CIRCLECI_BINARY bash
|
||||
curl -fLSs https://raw.githubusercontent.com/CircleCI-Public/circleci-cli/master/install.sh | DESTDIR=$CIRCLECI_BINARY bash
|
||||
node build.js
|
||||
name: Pack config.yml
|
||||
- run:
|
||||
|
||||
@@ -80,14 +80,12 @@ executors:
|
||||
machine: true
|
||||
|
||||
linux-arm:
|
||||
resource_class: electronjs/aks-linux-arm-test
|
||||
docker:
|
||||
- image: ghcr.io/electron/test:arm32v7-b0dee37de023a8d8a15bb8916325b54a4aebfb0c
|
||||
resource_class: electronjs/linux-arm
|
||||
machine: true
|
||||
|
||||
linux-arm64:
|
||||
resource_class: electronjs/aks-linux-arm-test
|
||||
docker:
|
||||
- image: ghcr.io/electron/test:arm64v8-b0dee37de023a8d8a15bb8916325b54a4aebfb0c
|
||||
resource_class: electronjs/linux-arm64
|
||||
machine: true
|
||||
|
||||
# The config expects the following environment variables to be set:
|
||||
# - "SLACK_WEBHOOK" Slack hook URL to send notifications.
|
||||
@@ -257,10 +255,6 @@ step-depot-tools-get: &step-depot-tools-get
|
||||
name: Get depot tools
|
||||
command: |
|
||||
git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
cd depot_tools
|
||||
git fetch --depth 1 origin f76550541c751f956ef9287f2695a6c8a74bf709
|
||||
git checkout f76550541c751f956ef9287f2695a6c8a74bf709
|
||||
cd ..
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
# remove ninjalog_uploader_wrapper.py from autoninja since we don't use it and it causes problems
|
||||
sed -i '' '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
|
||||
@@ -488,7 +482,7 @@ step-get-more-space-on-mac: &step-get-more-space-on-mac
|
||||
fi
|
||||
background: true
|
||||
|
||||
# On macOS delete all .git directories under src/ except for
|
||||
# On macOS delete all .git directories under src/ expect for
|
||||
# third_party/angle/ and third_party/dawn/ because of build time generation of files
|
||||
# gen/angle/commit.h depends on third_party/angle/.git/HEAD
|
||||
# https://chromium-review.googlesource.com/c/angle/angle/+/2074924
|
||||
@@ -1669,15 +1663,26 @@ commands:
|
||||
export LLVM_SYMBOLIZER_PATH=$PWD/third_party/llvm-build/Release+Asserts/bin/llvm-symbolizer
|
||||
export MOCHA_TIMEOUT=180000
|
||||
echo "Piping output to ASAN_SYMBOLIZE ($ASAN_SYMBOLIZE)"
|
||||
(cd electron && (circleci tests glob "spec/*-spec.ts" | xargs -I@ -P4 bash -c "echo $(pwd)/@" | circleci tests run --command="xargs node script/yarn test --runners=main --trace-uncaught --enable-logging --files" --split-by=timings 2>&1)) | $ASAN_SYMBOLIZE
|
||||
(cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging --files $(circleci tests glob spec/*-spec.ts | circleci tests split --split-by=timings)) 2>&1 | $ASAN_SYMBOLIZE
|
||||
else
|
||||
if [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then
|
||||
export ELECTRON_SKIP_NATIVE_MODULE_TESTS=true
|
||||
(cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging)
|
||||
else
|
||||
if [ "$TARGET_ARCH" == "ia32" ]; then
|
||||
npm_config_arch=x64 node electron/node_modules/dugite/script/download-git.js
|
||||
fi
|
||||
(cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging --files $(circleci tests glob spec/*-spec.ts | circleci tests split --split-by=timings))
|
||||
fi
|
||||
if [ "$TARGET_ARCH" == "ia32" ]; then
|
||||
npm_config_arch=x64 node electron/node_modules/dugite/script/download-git.js
|
||||
fi
|
||||
(cd electron && (circleci tests glob "spec/*-spec.ts" | xargs -I@ -P4 bash -c "echo $(pwd)/@" | circleci tests run --command="xargs node script/yarn test --runners=main --trace-uncaught --enable-logging --files" --split-by=timings))
|
||||
fi
|
||||
- run:
|
||||
name: Check test results existence
|
||||
command: |
|
||||
cd src
|
||||
|
||||
# Check if test results exist and are not empty.
|
||||
if [ ! -s "junit/test-results-main.xml" ]; then
|
||||
exit 1
|
||||
fi
|
||||
- store_test_results:
|
||||
path: src/junit
|
||||
@@ -2306,7 +2311,6 @@ jobs:
|
||||
<<: *env-global
|
||||
<<: *env-headless-testing
|
||||
<<: *env-stack-dumping
|
||||
parallelism: 3
|
||||
steps:
|
||||
- electron-tests:
|
||||
artifact-key: linux-arm
|
||||
@@ -2318,7 +2322,6 @@ jobs:
|
||||
<<: *env-global
|
||||
<<: *env-headless-testing
|
||||
<<: *env-stack-dumping
|
||||
parallelism: 3
|
||||
steps:
|
||||
- electron-tests:
|
||||
artifact-key: linux-arm64
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
Checks: '-modernize-use-nullptr'
|
||||
InheritParentConfig: true
|
||||
...
|
||||
@@ -45,7 +45,7 @@ if [ ! -f $buildtools/configs/evm.testing.json ]; then
|
||||
\"electron\": {
|
||||
\"origin\": \"https://github.com/electron/electron.git\"
|
||||
}
|
||||
},
|
||||
}
|
||||
\"gen\": {
|
||||
\"args\": [
|
||||
\"import(\\\"//electron/build/args/testing.gn\\\")\",
|
||||
|
||||
25
.gitattributes
vendored
25
.gitattributes
vendored
@@ -4,27 +4,12 @@
|
||||
patches/**/.patches merge=union
|
||||
|
||||
# Source code and markdown files should always use LF as line ending.
|
||||
*.c text eol=lf
|
||||
*.cc text eol=lf
|
||||
*.cpp text eol=lf
|
||||
*.csv text eol=lf
|
||||
*.grd text eol=lf
|
||||
*.grdp text eol=lf
|
||||
*.gn text eol=lf
|
||||
*.gni text eol=lf
|
||||
*.h text eol=lf
|
||||
*.html text eol=lf
|
||||
*.idl text eol=lf
|
||||
*.in text eol=lf
|
||||
*.js text eol=lf
|
||||
*.json text eol=lf
|
||||
*.json5 text eol=lf
|
||||
*.md text eol=lf
|
||||
*.mm text eol=lf
|
||||
*.mojom text eol=lf
|
||||
*.proto text eol=lf
|
||||
*.h text eol=lf
|
||||
*.js text eol=lf
|
||||
*.ts text eol=lf
|
||||
*.py text eol=lf
|
||||
*.ps1 text eol=lf
|
||||
*.sh text eol=lf
|
||||
*.ts text eol=lf
|
||||
*.txt text eol=lf
|
||||
*.html text eol=lf
|
||||
*.md text eol=lf
|
||||
|
||||
55
.github/workflows/branch-created.yml
vendored
55
.github/workflows/branch-created.yml
vendored
@@ -1,55 +0,0 @@
|
||||
name: Branch Created
|
||||
|
||||
on:
|
||||
create:
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
release-branch-created:
|
||||
name: Release Branch Created
|
||||
if: ${{ github.event.ref_type == 'branch' && endsWith(github.event.ref, '-x-y') }}
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
repository-projects: write # Required for labels
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: New Release Branch Tasks
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GH_REPO: electron/electron
|
||||
NUM_SUPPORTED_VERSIONS: 3
|
||||
run: |
|
||||
if [[ ${{ github.event.ref }} =~ ^([0-9]+)-x-y$ ]]; then
|
||||
MAJOR=${BASH_REMATCH[1]}
|
||||
PREVIOUS_MAJOR=$((MAJOR - 1))
|
||||
UNSUPPORTED_MAJOR=$((MAJOR - NUM_SUPPORTED_VERSIONS - 1))
|
||||
|
||||
# Create new labels
|
||||
gh label create $MAJOR-x-y --color 8d9ee8 || true
|
||||
gh label create target/$MAJOR-x-y --color ad244f || true
|
||||
gh label create merged/$MAJOR-x-y --color 61a3c6 || true
|
||||
gh label create in-flight/$MAJOR-x-y --color db69a6 || true
|
||||
gh label create needs-manual-bp/$MAJOR-x-y --color 8b5dba || true
|
||||
|
||||
# Change color of old labels
|
||||
gh label edit $UNSUPPORTED_MAJOR-x-y --color ededed || true
|
||||
gh label edit target/$UNSUPPORTED_MAJOR-x-y --color ededed || true
|
||||
gh label edit merged/$UNSUPPORTED_MAJOR-x-y --color ededed || true
|
||||
gh label edit in-flight/$UNSUPPORTED_MAJOR-x-y --color ededed || true
|
||||
gh label edit needs-manual-bp/$UNSUPPORTED_MAJOR-x-y --color ededed || true
|
||||
|
||||
# Add the new target label to any PRs which:
|
||||
# * target the previous major
|
||||
# * are in-flight for the previous major
|
||||
# * need manual backport for the previous major
|
||||
for PREVIOUS_MAJOR_LABEL in target/$PREVIOUS_MAJOR-x-y in-flight/$PREVIOUS_MAJOR-x-y needs-manual-bp/$PREVIOUS_MAJOR-x-y; do
|
||||
PULL_REQUESTS=$(gh pr list --label $PREVIOUS_MAJOR_LABEL --jq .[].number --json number --limit 500)
|
||||
if [[ $PULL_REQUESTS ]]; then
|
||||
echo $PULL_REQUESTS | xargs -n 1 gh pr edit --add-label target/$MAJOR-x-y || true
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "Not a release branch: ${{ github.event.ref }}"
|
||||
fi
|
||||
24
.github/workflows/issue-commented.yml
vendored
24
.github/workflows/issue-commented.yml
vendored
@@ -1,24 +0,0 @@
|
||||
name: Issue Commented
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types:
|
||||
- created
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
issue-commented:
|
||||
name: Remove blocked/need-repro on comment
|
||||
if: ${{ contains(github.event.issue.labels.*.name, 'blocked/need-repro') && !contains(fromJSON('["MEMBER", "OWNER"]'), github.event.comment.author_association) }}
|
||||
permissions:
|
||||
issues: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Remove label
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
ISSUE_URL: ${{ github.event.issue.html_url }}
|
||||
run: |
|
||||
gh issue edit $ISSUE_URL --remove-label 'blocked/need-repro'
|
||||
5
.github/workflows/issue-labeled.yml
vendored
5
.github/workflows/issue-labeled.yml
vendored
@@ -9,13 +9,12 @@ permissions: # added using https://github.com/step-security/secure-workflows
|
||||
|
||||
jobs:
|
||||
issue-labeled:
|
||||
name: blocked/need-repro label added
|
||||
if: github.event.label.name == 'blocked/need-repro'
|
||||
permissions:
|
||||
issues: write # for actions-cool/issues-helper to update issues
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Create comment
|
||||
- name: blocked/need-repro label added
|
||||
if: github.event.label.name == 'blocked/need-repro'
|
||||
uses: actions-cool/issues-helper@dad28fdb88da5f082c04659b7373d85790f9b135 # v3.3.0
|
||||
with:
|
||||
actions: 'create-comment'
|
||||
|
||||
1
.github/workflows/stale.yml
vendored
1
.github/workflows/stale.yml
vendored
@@ -33,7 +33,6 @@ jobs:
|
||||
with:
|
||||
days-before-stale: -1
|
||||
days-before-close: 10
|
||||
remove-stale-when-updated: false
|
||||
stale-issue-label: blocked/need-repro
|
||||
stale-pr-label: not-a-real-label
|
||||
operations-per-run: 1750
|
||||
|
||||
2
.github/workflows/update_appveyor_image.yml
vendored
2
.github/workflows/update_appveyor_image.yml
vendored
@@ -66,9 +66,7 @@ jobs:
|
||||
signoff: false
|
||||
branch: bump-appveyor-image
|
||||
delete-branch: true
|
||||
reviewers: electron/wg-releases
|
||||
title: 'build: update appveyor image to latest version'
|
||||
labels: semver-none,no-backport
|
||||
body: |
|
||||
This PR updates appveyor.yml to the latest baked image, ${{ env.APPVEYOR_IMAGE_VERSION }}.
|
||||
Notes: none
|
||||
31
BUILD.gn
31
BUILD.gn
@@ -544,7 +544,6 @@ source_set("electron_lib") {
|
||||
|
||||
if (is_mac) {
|
||||
deps += [
|
||||
":electron_lib_arc",
|
||||
"//components/remote_cocoa/app_shim",
|
||||
"//components/remote_cocoa/browser",
|
||||
"//content/browser:mac_helpers",
|
||||
@@ -556,7 +555,6 @@ source_set("electron_lib") {
|
||||
}
|
||||
|
||||
frameworks = [
|
||||
"AuthenticationServices.framework",
|
||||
"AVFoundation.framework",
|
||||
"Carbon.framework",
|
||||
"LocalAuthentication.framework",
|
||||
@@ -706,6 +704,13 @@ source_set("electron_lib") {
|
||||
]
|
||||
}
|
||||
|
||||
if (enable_desktop_capturer) {
|
||||
sources += [
|
||||
"shell/browser/api/electron_api_desktop_capturer.cc",
|
||||
"shell/browser/api/electron_api_desktop_capturer.h",
|
||||
]
|
||||
}
|
||||
|
||||
if (enable_views_api) {
|
||||
sources += [
|
||||
"shell/browser/api/views/electron_api_image_view.cc",
|
||||
@@ -779,28 +784,6 @@ 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",
|
||||
"//content/public/browser",
|
||||
"//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,10 +60,6 @@ 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.5845.228',
|
||||
'114.0.5735.289',
|
||||
'node_version':
|
||||
'v18.16.1',
|
||||
'v18.15.0',
|
||||
'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('node:child_process')
|
||||
const proc = require('child_process')
|
||||
|
||||
// will print something similar to /Users/maf/.../Electron
|
||||
console.log(electron)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
version: 1.0.{build}
|
||||
build_cloud: electronhq-16-core
|
||||
image: e-116.0.5791.0
|
||||
image: e-114.0.5735.16-bust-cache
|
||||
environment:
|
||||
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
|
||||
ELECTRON_OUT_DIR: Default
|
||||
@@ -92,11 +92,6 @@ for:
|
||||
Remove-Item -Recurse -Force $pwd\build-tools
|
||||
}
|
||||
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
- ps: |
|
||||
cd depot_tools
|
||||
git fetch --depth 1 origin f76550541c751f956ef9287f2695a6c8a74bf709
|
||||
git checkout f76550541c751f956ef9287f2695a6c8a74bf709
|
||||
cd ..
|
||||
- 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"
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
version: 1.0.{build}
|
||||
build_cloud: electronhq-16-core
|
||||
image: e-116.0.5791.0
|
||||
image: e-114.0.5735.16-bust-cache
|
||||
environment:
|
||||
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
|
||||
ELECTRON_OUT_DIR: Default
|
||||
@@ -90,11 +90,6 @@ for:
|
||||
Remove-Item -Recurse -Force $pwd\build-tools
|
||||
}
|
||||
- git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
||||
- ps: |
|
||||
cd depot_tools
|
||||
git fetch --depth 1 origin f76550541c751f956ef9287f2695a6c8a74bf709
|
||||
git checkout f76550541c751f956ef9287f2695a6c8a74bf709
|
||||
cd ..
|
||||
- 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"
|
||||
|
||||
@@ -50,13 +50,8 @@ use_qt = false
|
||||
# TODO(codebytere): fix perfetto incompatibility with Node.js.
|
||||
use_perfetto_client_library = false
|
||||
|
||||
# Ref: https://chromium-review.googlesource.com/c/chromium/src/+/4402277
|
||||
enable_check_raw_ptr_fields = false
|
||||
|
||||
# Disables the builtins PGO for V8
|
||||
v8_builtins_profiling_log_file = ""
|
||||
|
||||
# Disable threadisolated allocator implementation from gin for partition allocator,
|
||||
# we are seeing crashes for Linux x64 users when node integration is enabled in the
|
||||
# renderer process causing SIGSEGV when the periodic memory reclaimer runs,
|
||||
# Refs https://github.com/electron/electron/issues/39775.
|
||||
# The current only user of this pool is the v8 CFI which is
|
||||
# not enabled on this branch, so it is safe to disable the feature.
|
||||
enable_pkeys = false
|
||||
|
||||
@@ -4,7 +4,7 @@ import sys
|
||||
|
||||
DEFINE_EXTRACT_REGEX = re.compile('^ *# *define (\w*)', re.MULTILINE)
|
||||
|
||||
def main(out_dir, headers):
|
||||
def main(outDir, headers):
|
||||
defines = []
|
||||
for filename in headers:
|
||||
with open(filename, 'r') as f:
|
||||
@@ -15,13 +15,13 @@ def main(out_dir, headers):
|
||||
for define in defines:
|
||||
push_and_undef += '#pragma push_macro("%s")\n' % define
|
||||
push_and_undef += '#undef %s\n' % define
|
||||
with open(os.path.join(out_dir, 'push_and_undef_node_defines.h'), 'w') as o:
|
||||
with open(os.path.join(outDir, 'push_and_undef_node_defines.h'), 'w') as o:
|
||||
o.write(push_and_undef)
|
||||
|
||||
pop = ''
|
||||
for define in defines:
|
||||
pop += '#pragma pop_macro("%s")\n' % define
|
||||
with open(os.path.join(out_dir, 'pop_node_defines.h'), 'w') as o:
|
||||
with open(os.path.join(outDir, 'pop_node_defines.h'), 'w') as o:
|
||||
o.write(pop)
|
||||
|
||||
def read_defines(content):
|
||||
|
||||
@@ -53,6 +53,14 @@ module.exports = ({
|
||||
|
||||
const ignoredModules = [];
|
||||
|
||||
if (defines.ENABLE_DESKTOP_CAPTURER === 'false') {
|
||||
ignoredModules.push(
|
||||
'@electron/internal/browser/desktop-capturer',
|
||||
'@electron/internal/browser/api/desktop-capturer',
|
||||
'@electron/internal/renderer/api/desktop-capturer'
|
||||
);
|
||||
}
|
||||
|
||||
if (defines.ENABLE_VIEWS_API === 'false') {
|
||||
ignoredModules.push(
|
||||
'@electron/internal/browser/api/views/image-view.js'
|
||||
|
||||
@@ -9,10 +9,13 @@ buildflag_header("buildflags") {
|
||||
header = "buildflags.h"
|
||||
|
||||
flags = [
|
||||
"ENABLE_DESKTOP_CAPTURER=$enable_desktop_capturer",
|
||||
"ENABLE_RUN_AS_NODE=$enable_run_as_node",
|
||||
"ENABLE_OSR=$enable_osr",
|
||||
"ENABLE_VIEWS_API=$enable_views_api",
|
||||
"ENABLE_PDF_VIEWER=$enable_pdf_viewer",
|
||||
"ENABLE_TTS=$enable_tts",
|
||||
"ENABLE_COLOR_CHOOSER=$enable_color_chooser",
|
||||
"ENABLE_ELECTRON_EXTENSIONS=$enable_electron_extensions",
|
||||
"ENABLE_BUILTIN_SPELLCHECKER=$enable_builtin_spellchecker",
|
||||
"ENABLE_PICTURE_IN_PICTURE=$enable_picture_in_picture",
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
# found in the LICENSE file.
|
||||
|
||||
declare_args() {
|
||||
enable_desktop_capturer = true
|
||||
|
||||
# Allow running Electron as a node binary.
|
||||
enable_run_as_node = true
|
||||
|
||||
@@ -12,6 +14,10 @@ declare_args() {
|
||||
|
||||
enable_pdf_viewer = true
|
||||
|
||||
enable_tts = true
|
||||
|
||||
enable_color_chooser = true
|
||||
|
||||
enable_picture_in_picture = true
|
||||
|
||||
# Provide a fake location provider for mocking
|
||||
|
||||
@@ -37,14 +37,6 @@ static_library("chrome") {
|
||||
"//chrome/browser/icon_loader.h",
|
||||
"//chrome/browser/icon_manager.cc",
|
||||
"//chrome/browser/icon_manager.h",
|
||||
"//chrome/browser/media/webrtc/desktop_media_list.cc",
|
||||
"//chrome/browser/media/webrtc/desktop_media_list.h",
|
||||
"//chrome/browser/media/webrtc/desktop_media_list_base.cc",
|
||||
"//chrome/browser/media/webrtc/desktop_media_list_base.h",
|
||||
"//chrome/browser/media/webrtc/desktop_media_list_observer.h",
|
||||
"//chrome/browser/media/webrtc/native_desktop_media_list.cc",
|
||||
"//chrome/browser/media/webrtc/native_desktop_media_list.h",
|
||||
"//chrome/browser/media/webrtc/window_icon_util.h",
|
||||
"//chrome/browser/net/chrome_mojo_proxy_resolver_factory.cc",
|
||||
"//chrome/browser/net/chrome_mojo_proxy_resolver_factory.h",
|
||||
"//chrome/browser/net/proxy_config_monitor.cc",
|
||||
@@ -105,6 +97,16 @@ 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",
|
||||
]
|
||||
@@ -144,7 +146,6 @@ 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",
|
||||
@@ -156,11 +157,7 @@ static_library("chrome") {
|
||||
"//services/strings",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//chrome/browser:resource_prefetch_predictor_proto",
|
||||
"//chrome/browser/resource_coordinator:mojo_bindings",
|
||||
"//ui/snapshot",
|
||||
]
|
||||
deps = [ "//chrome/browser:resource_prefetch_predictor_proto" ]
|
||||
|
||||
if (is_linux) {
|
||||
sources += [ "//chrome/browser/icon_loader_auralinux.cc" ]
|
||||
@@ -195,8 +192,18 @@ static_library("chrome") {
|
||||
public_deps += [ "//chrome/services/util_win:lib" ]
|
||||
}
|
||||
|
||||
if (is_mac) {
|
||||
public_deps += [ ":chrome_lib_arc" ]
|
||||
if (enable_desktop_capturer) {
|
||||
sources += [
|
||||
"//chrome/browser/media/webrtc/desktop_media_list.cc",
|
||||
"//chrome/browser/media/webrtc/desktop_media_list.h",
|
||||
"//chrome/browser/media/webrtc/desktop_media_list_base.cc",
|
||||
"//chrome/browser/media/webrtc/desktop_media_list_base.h",
|
||||
"//chrome/browser/media/webrtc/desktop_media_list_observer.h",
|
||||
"//chrome/browser/media/webrtc/native_desktop_media_list.cc",
|
||||
"//chrome/browser/media/webrtc/native_desktop_media_list.h",
|
||||
"//chrome/browser/media/webrtc/window_icon_util.h",
|
||||
]
|
||||
deps += [ "//ui/snapshot" ]
|
||||
}
|
||||
|
||||
if (enable_widevine) {
|
||||
@@ -375,35 +382,6 @@ 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",
|
||||
"//content/public/browser",
|
||||
"//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 = []
|
||||
|
||||
@@ -1331,7 +1331,7 @@ application name. For example:
|
||||
|
||||
``` js
|
||||
const { app } = require('electron')
|
||||
const path = require('node:path')
|
||||
const path = require('path')
|
||||
|
||||
const appFolder = path.dirname(process.execPath)
|
||||
const updateExe = path.resolve(appFolder, '..', 'Update.exe')
|
||||
@@ -1402,7 +1402,7 @@ Returns `Function` - This function **must** be called once you have finished acc
|
||||
|
||||
```js
|
||||
const { app, dialog } = require('electron')
|
||||
const fs = require('node:fs')
|
||||
const fs = require('fs')
|
||||
|
||||
let filepath
|
||||
let bookmark
|
||||
@@ -1424,7 +1424,7 @@ Start accessing a security scoped resource. With this method Electron applicatio
|
||||
|
||||
### `app.enableSandbox()`
|
||||
|
||||
Enables full sandbox mode on the app. This means that all renderers will be launched sandboxed, regardless of the value of the `sandbox` flag in [`WebPreferences`](structures/web-preferences.md).
|
||||
Enables full sandbox mode on the app. This means that all renderers will be launched sandboxed, regardless of the value of the `sandbox` flag in WebPreferences.
|
||||
|
||||
This method can only be called before app is ready.
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ app.whenReady().then(() => {
|
||||
### `new BrowserView([options])` _Experimental_
|
||||
|
||||
* `options` Object (optional)
|
||||
* `webPreferences` [WebPreferences](structures/web-preferences.md?inline) (optional) - Settings of web page's features.
|
||||
* `webPreferences` Object (optional) - See [BrowserWindow](browser-window.md).
|
||||
|
||||
### Instance Properties
|
||||
|
||||
|
||||
@@ -152,7 +152,297 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
|
||||
|
||||
### `new BrowserWindow([options])`
|
||||
|
||||
* `options` [BrowserWindowConstructorOptions](structures/browser-window-options.md?inline) (optional)
|
||||
* `options` Object (optional)
|
||||
* `width` Integer (optional) - Window's width in pixels. Default is `800`.
|
||||
* `height` Integer (optional) - Window's height in pixels. Default is `600`.
|
||||
* `x` Integer (optional) - (**required** if y is used) Window's left offset from screen.
|
||||
Default is to center the window.
|
||||
* `y` Integer (optional) - (**required** if x is used) Window's top offset from screen.
|
||||
Default is to center the window.
|
||||
* `useContentSize` boolean (optional) - The `width` and `height` would be used as web
|
||||
page's size, which means the actual window's size will include window
|
||||
frame's size and be slightly larger. Default is `false`.
|
||||
* `center` boolean (optional) - Show window in the center of the screen. Default is `false`.
|
||||
* `minWidth` Integer (optional) - Window's minimum width. Default is `0`.
|
||||
* `minHeight` Integer (optional) - Window's minimum height. Default is `0`.
|
||||
* `maxWidth` Integer (optional) - Window's maximum width. Default is no limit.
|
||||
* `maxHeight` Integer (optional) - Window's maximum height. Default is no limit.
|
||||
* `resizable` boolean (optional) - Whether window is resizable. Default is `true`.
|
||||
* `movable` boolean (optional) _macOS_ _Windows_ - Whether window is
|
||||
movable. This is not implemented on Linux. Default is `true`.
|
||||
* `minimizable` boolean (optional) _macOS_ _Windows_ - Whether window is
|
||||
minimizable. This is not implemented on Linux. Default is `true`.
|
||||
* `maximizable` boolean (optional) _macOS_ _Windows_ - Whether window is
|
||||
maximizable. This is not implemented on Linux. Default is `true`.
|
||||
* `closable` boolean (optional) _macOS_ _Windows_ - Whether window is
|
||||
closable. This is not implemented on Linux. Default is `true`.
|
||||
* `focusable` boolean (optional) - Whether the window can be focused. Default is
|
||||
`true`. On Windows setting `focusable: false` also implies setting
|
||||
`skipTaskbar: true`. On Linux setting `focusable: false` makes the window
|
||||
stop interacting with wm, so the window will always stay on top in all
|
||||
workspaces.
|
||||
* `alwaysOnTop` boolean (optional) - Whether the window should always stay on top of
|
||||
other windows. Default is `false`.
|
||||
* `fullscreen` boolean (optional) - Whether the window should show in fullscreen. When
|
||||
explicitly set to `false` the fullscreen button will be hidden or disabled
|
||||
on macOS. Default is `false`.
|
||||
* `fullscreenable` boolean (optional) - Whether the window can be put into fullscreen
|
||||
mode. On macOS, also whether the maximize/zoom button should toggle full
|
||||
screen mode or maximize window. Default is `true`.
|
||||
* `simpleFullscreen` boolean (optional) _macOS_ - Use pre-Lion fullscreen on
|
||||
macOS. Default is `false`.
|
||||
* `skipTaskbar` boolean (optional) _macOS_ _Windows_ - Whether to show the window in taskbar.
|
||||
Default is `false`.
|
||||
* `hiddenInMissionControl` boolean (optional) _macOS_ - Whether window should be hidden when the user toggles into mission control.
|
||||
* `kiosk` boolean (optional) - Whether the window is in kiosk mode. Default is `false`.
|
||||
* `title` string (optional) - Default window title. Default is `"Electron"`. If the HTML tag `<title>` is defined in the HTML file loaded by `loadURL()`, this property will be ignored.
|
||||
* `icon` ([NativeImage](native-image.md) | string) (optional) - The window icon. On Windows it is
|
||||
recommended to use `ICO` icons to get best visual effects, you can also
|
||||
leave it undefined so the executable's icon will be used.
|
||||
* `show` boolean (optional) - Whether window should be shown when created. Default is
|
||||
`true`.
|
||||
* `paintWhenInitiallyHidden` boolean (optional) - Whether the renderer should be active when `show` is `false` and it has just been created. In order for `document.visibilityState` to work correctly on first load with `show: false` you should set this to `false`. Setting this to `false` will cause the `ready-to-show` event to not fire. Default is `true`.
|
||||
* `frame` boolean (optional) - Specify `false` to create a
|
||||
[frameless window](../tutorial/window-customization.md#create-frameless-windows). Default is `true`.
|
||||
* `parent` BrowserWindow (optional) - Specify parent window. Default is `null`.
|
||||
* `modal` boolean (optional) - Whether this is a modal window. This only works when the
|
||||
window is a child window. Default is `false`.
|
||||
* `acceptFirstMouse` boolean (optional) _macOS_ - Whether clicking an
|
||||
inactive window will also click through to the web contents. Default is
|
||||
`false` on macOS. This option is not configurable on other platforms.
|
||||
* `disableAutoHideCursor` boolean (optional) - Whether to hide cursor when typing.
|
||||
Default is `false`.
|
||||
* `autoHideMenuBar` boolean (optional) - Auto hide the menu bar unless the `Alt`
|
||||
key is pressed. Default is `false`.
|
||||
* `enableLargerThanScreen` boolean (optional) _macOS_ - Enable the window to
|
||||
be resized larger than screen. Only relevant for macOS, as other OSes
|
||||
allow larger-than-screen windows by default. Default is `false`.
|
||||
* `backgroundColor` string (optional) - The window's background color in Hex, RGB, RGBA, HSL, HSLA or named CSS color format. Alpha in #AARRGGBB format is supported if `transparent` is set to `true`. Default is `#FFF` (white). See [win.setBackgroundColor](browser-window.md#winsetbackgroundcolorbackgroundcolor) for more information.
|
||||
* `hasShadow` boolean (optional) - Whether window should have a shadow. Default is `true`.
|
||||
* `opacity` number (optional) _macOS_ _Windows_ - Set the initial opacity of
|
||||
the window, between 0.0 (fully transparent) and 1.0 (fully opaque). This
|
||||
is only implemented on Windows and macOS.
|
||||
* `darkTheme` boolean (optional) - Forces using dark theme for the window, only works on
|
||||
some GTK+3 desktop environments. Default is `false`.
|
||||
* `transparent` boolean (optional) - Makes the window [transparent](../tutorial/window-customization.md#create-transparent-windows).
|
||||
Default is `false`. On Windows, does not work unless the window is frameless.
|
||||
* `type` string (optional) - The type of window, default is normal window. See more about
|
||||
this below.
|
||||
* `visualEffectState` string (optional) _macOS_ - Specify how the material
|
||||
appearance should reflect window activity state on macOS. Must be used
|
||||
with the `vibrancy` property. Possible values are:
|
||||
* `followWindow` - The backdrop should automatically appear active when the window is active, and inactive when it is not. This is the default.
|
||||
* `active` - The backdrop should always appear active.
|
||||
* `inactive` - The backdrop should always appear inactive.
|
||||
* `titleBarStyle` string (optional) _macOS_ _Windows_ - The style of window title bar.
|
||||
Default is `default`. Possible values are:
|
||||
* `default` - Results in the standard title bar for macOS or Windows respectively.
|
||||
* `hidden` - Results in a hidden title bar and a full size content window. On macOS, the window still has the standard window controls (“traffic lights”) in the top left. On Windows, when combined with `titleBarOverlay: true` it will activate the Window Controls Overlay (see `titleBarOverlay` for more information), otherwise no window controls will be shown.
|
||||
* `hiddenInset` _macOS_ - Only on macOS, results in a hidden title bar
|
||||
with an alternative look where the traffic light buttons are slightly
|
||||
more inset from the window edge.
|
||||
* `customButtonsOnHover` _macOS_ - Only on macOS, results in a hidden
|
||||
title bar and a full size content window, the traffic light buttons will
|
||||
display when being hovered over in the top left of the window.
|
||||
**Note:** This option is currently experimental.
|
||||
* `trafficLightPosition` [Point](structures/point.md) (optional) _macOS_ -
|
||||
Set a custom position for the traffic light buttons in frameless windows.
|
||||
* `roundedCorners` boolean (optional) _macOS_ - Whether frameless window
|
||||
should have rounded corners on macOS. Default is `true`. Setting this property
|
||||
to `false` will prevent the window from being fullscreenable.
|
||||
* `fullscreenWindowTitle` boolean (optional) _macOS_ _Deprecated_ - Shows
|
||||
the title in the title bar in full screen mode on macOS for `hiddenInset`
|
||||
titleBarStyle. Default is `false`.
|
||||
* `thickFrame` boolean (optional) - Use `WS_THICKFRAME` style for frameless windows on
|
||||
Windows, which adds standard window frame. Setting it to `false` will remove
|
||||
window shadow and window animations. Default is `true`.
|
||||
* `vibrancy` string (optional) _macOS_ - Add a type of vibrancy effect to
|
||||
the window, only on macOS. Can be `appearance-based`, `light`, `dark`,
|
||||
`titlebar`, `selection`, `menu`, `popover`, `sidebar`, `medium-light`,
|
||||
`ultra-dark`, `header`, `sheet`, `window`, `hud`, `fullscreen-ui`,
|
||||
`tooltip`, `content`, `under-window`, or `under-page`. Please note that
|
||||
`appearance-based`, `light`, `dark`, `medium-light`, and `ultra-dark` are
|
||||
deprecated and have been removed in macOS Catalina (10.15).
|
||||
* `backgroundMaterial` string (optional) _Windows_ - Set the window's
|
||||
system-drawn background material, including behind the non-client area.
|
||||
Can be `auto`, `none`, `mica`, `acrylic` or `tabbed`. See [win.setBackgroundMaterial](#winsetbackgroundmaterialmaterial-windows) for more information.
|
||||
* `zoomToPageWidth` boolean (optional) _macOS_ - Controls the behavior on
|
||||
macOS when option-clicking the green stoplight button on the toolbar or by
|
||||
clicking the Window > Zoom menu item. If `true`, the window will grow to
|
||||
the preferred width of the web page when zoomed, `false` will cause it to
|
||||
zoom to the width of the screen. This will also affect the behavior when
|
||||
calling `maximize()` directly. Default is `false`.
|
||||
* `tabbingIdentifier` string (optional) _macOS_ - Tab group name, allows
|
||||
opening the window as a native tab. Windows with the same
|
||||
tabbing identifier will be grouped together. This also adds a native new
|
||||
tab button to your window's tab bar and allows your `app` and window to
|
||||
receive the `new-window-for-tab` event.
|
||||
* `webPreferences` Object (optional) - Settings of web page's features.
|
||||
* `devTools` boolean (optional) - Whether to enable DevTools. If it is set to `false`, can not use `BrowserWindow.webContents.openDevTools()` to open DevTools. Default is `true`.
|
||||
* `nodeIntegration` boolean (optional) - Whether node integration is enabled.
|
||||
Default is `false`.
|
||||
* `nodeIntegrationInWorker` boolean (optional) - Whether node integration is
|
||||
enabled in web workers. Default is `false`. More about this can be found
|
||||
in [Multithreading](../tutorial/multithreading.md).
|
||||
* `nodeIntegrationInSubFrames` boolean (optional) - Experimental option for
|
||||
enabling Node.js support in sub-frames such as iframes and child windows. All your preloads will load for
|
||||
every iframe, you can use `process.isMainFrame` to determine if you are
|
||||
in the main frame or not.
|
||||
* `preload` string (optional) - Specifies a script that will be loaded before other
|
||||
scripts run in the page. This script will always have access to node APIs
|
||||
no matter whether node integration is turned on or off. The value should
|
||||
be the absolute file path to the script.
|
||||
When node integration is turned off, the preload script can reintroduce
|
||||
Node global symbols back to the global scope. See example
|
||||
[here](context-bridge.md#exposing-node-global-symbols).
|
||||
* `sandbox` boolean (optional) - If set, this will sandbox the renderer
|
||||
associated with the window, making it compatible with the Chromium
|
||||
OS-level sandbox and disabling the Node.js engine. This is not the same as
|
||||
the `nodeIntegration` option and the APIs available to the preload script
|
||||
are more limited. Read more about the option [here](../tutorial/sandbox.md).
|
||||
* `session` [Session](session.md#class-session) (optional) - Sets the session used by the
|
||||
page. Instead of passing the Session object directly, you can also choose to
|
||||
use the `partition` option instead, which accepts a partition string. When
|
||||
both `session` and `partition` are provided, `session` will be preferred.
|
||||
Default is the default session.
|
||||
* `partition` string (optional) - Sets the session used by the page according to the
|
||||
session's partition string. If `partition` starts with `persist:`, the page
|
||||
will use a persistent session available to all pages in the app with the
|
||||
same `partition`. If there is no `persist:` prefix, the page will use an
|
||||
in-memory session. By assigning the same `partition`, multiple pages can share
|
||||
the same session. Default is the default session.
|
||||
* `zoomFactor` number (optional) - The default zoom factor of the page, `3.0` represents
|
||||
`300%`. Default is `1.0`.
|
||||
* `javascript` boolean (optional) - Enables JavaScript support. Default is `true`.
|
||||
* `webSecurity` boolean (optional) - When `false`, it will disable the
|
||||
same-origin policy (usually using testing websites by people), and set
|
||||
`allowRunningInsecureContent` to `true` if this options has not been set
|
||||
by user. Default is `true`.
|
||||
* `allowRunningInsecureContent` boolean (optional) - Allow an https page to run
|
||||
JavaScript, CSS or plugins from http URLs. Default is `false`.
|
||||
* `images` boolean (optional) - Enables image support. Default is `true`.
|
||||
* `imageAnimationPolicy` string (optional) - Specifies how to run image animations (E.g. GIFs). Can be `animate`, `animateOnce` or `noAnimation`. Default is `animate`.
|
||||
* `textAreasAreResizable` boolean (optional) - Make TextArea elements resizable. Default
|
||||
is `true`.
|
||||
* `webgl` boolean (optional) - Enables WebGL support. Default is `true`.
|
||||
* `plugins` boolean (optional) - Whether plugins should be enabled. Default is `false`.
|
||||
* `experimentalFeatures` boolean (optional) - Enables Chromium's experimental features.
|
||||
Default is `false`.
|
||||
* `scrollBounce` boolean (optional) _macOS_ - Enables scroll bounce
|
||||
(rubber banding) effect on macOS. Default is `false`.
|
||||
* `enableBlinkFeatures` string (optional) - A list of feature strings separated by `,`, like
|
||||
`CSSVariables,KeyboardEventKey` to enable. The full list of supported feature
|
||||
strings can be found in the [RuntimeEnabledFeatures.json5][runtime-enabled-features]
|
||||
file.
|
||||
* `disableBlinkFeatures` string (optional) - A list of feature strings separated by `,`,
|
||||
like `CSSVariables,KeyboardEventKey` to disable. The full list of supported
|
||||
feature strings can be found in the
|
||||
[RuntimeEnabledFeatures.json5][runtime-enabled-features] file.
|
||||
* `defaultFontFamily` Object (optional) - Sets the default font for the font-family.
|
||||
* `standard` string (optional) - Defaults to `Times New Roman`.
|
||||
* `serif` string (optional) - Defaults to `Times New Roman`.
|
||||
* `sansSerif` string (optional) - Defaults to `Arial`.
|
||||
* `monospace` string (optional) - Defaults to `Courier New`.
|
||||
* `cursive` string (optional) - Defaults to `Script`.
|
||||
* `fantasy` string (optional) - Defaults to `Impact`.
|
||||
* `defaultFontSize` Integer (optional) - Defaults to `16`.
|
||||
* `defaultMonospaceFontSize` Integer (optional) - Defaults to `13`.
|
||||
* `minimumFontSize` Integer (optional) - Defaults to `0`.
|
||||
* `defaultEncoding` string (optional) - Defaults to `ISO-8859-1`.
|
||||
* `backgroundThrottling` boolean (optional) - Whether to throttle animations and timers
|
||||
when the page becomes background. This also affects the
|
||||
[Page Visibility API](#page-visibility). Defaults to `true`.
|
||||
* `offscreen` boolean (optional) - Whether to enable offscreen rendering for the browser
|
||||
window. Defaults to `false`. See the
|
||||
[offscreen rendering tutorial](../tutorial/offscreen-rendering.md) for
|
||||
more details.
|
||||
* `contextIsolation` boolean (optional) - Whether to run Electron APIs and
|
||||
the specified `preload` script in a separate JavaScript context. Defaults
|
||||
to `true`. The context that the `preload` script runs in will only have
|
||||
access to its own dedicated `document` and `window` globals, as well as
|
||||
its own set of JavaScript builtins (`Array`, `Object`, `JSON`, etc.),
|
||||
which are all invisible to the loaded content. The Electron API will only
|
||||
be available in the `preload` script and not the loaded page. This option
|
||||
should be used when loading potentially untrusted remote content to ensure
|
||||
the loaded content cannot tamper with the `preload` script and any
|
||||
Electron APIs being used. This option uses the same technique used by
|
||||
[Chrome Content Scripts][chrome-content-scripts]. You can access this
|
||||
context in the dev tools by selecting the 'Electron Isolated Context'
|
||||
entry in the combo box at the top of the Console tab.
|
||||
* `webviewTag` boolean (optional) - Whether to enable the [`<webview>` tag](webview-tag.md).
|
||||
Defaults to `false`. **Note:** The
|
||||
`preload` script configured for the `<webview>` will have node integration
|
||||
enabled when it is executed so you should ensure remote/untrusted content
|
||||
is not able to create a `<webview>` tag with a possibly malicious `preload`
|
||||
script. You can use the `will-attach-webview` event on [webContents](web-contents.md)
|
||||
to strip away the `preload` script and to validate or alter the
|
||||
`<webview>`'s initial settings.
|
||||
* `additionalArguments` string[] (optional) - A list of strings that will be appended
|
||||
to `process.argv` in the renderer process of this app. Useful for passing small
|
||||
bits of data down to renderer process preload scripts.
|
||||
* `safeDialogs` boolean (optional) - Whether to enable browser style
|
||||
consecutive dialog protection. Default is `false`.
|
||||
* `safeDialogsMessage` string (optional) - The message to display when
|
||||
consecutive dialog protection is triggered. If not defined the default
|
||||
message would be used, note that currently the default message is in
|
||||
English and not localized.
|
||||
* `disableDialogs` boolean (optional) - Whether to disable dialogs
|
||||
completely. Overrides `safeDialogs`. Default is `false`.
|
||||
* `navigateOnDragDrop` boolean (optional) - Whether dragging and dropping a
|
||||
file or link onto the page causes a navigation. Default is `false`.
|
||||
* `autoplayPolicy` string (optional) - Autoplay policy to apply to
|
||||
content in the window, can be `no-user-gesture-required`,
|
||||
`user-gesture-required`, `document-user-activation-required`. Defaults to
|
||||
`no-user-gesture-required`.
|
||||
* `disableHtmlFullscreenWindowResize` boolean (optional) - Whether to
|
||||
prevent the window from resizing when entering HTML Fullscreen. Default
|
||||
is `false`.
|
||||
* `accessibleTitle` string (optional) - An alternative title string provided only
|
||||
to accessibility tools such as screen readers. This string is not directly
|
||||
visible to users.
|
||||
* `spellcheck` boolean (optional) - Whether to enable the builtin spellchecker.
|
||||
Default is `true`.
|
||||
* `enableWebSQL` boolean (optional) - Whether to enable the [WebSQL api](https://www.w3.org/TR/webdatabase/).
|
||||
Default is `true`.
|
||||
* `v8CacheOptions` string (optional) - Enforces the v8 code caching policy
|
||||
used by blink. Accepted values are
|
||||
* `none` - Disables code caching
|
||||
* `code` - Heuristic based code caching
|
||||
* `bypassHeatCheck` - Bypass code caching heuristics but with lazy compilation
|
||||
* `bypassHeatCheckAndEagerCompile` - Same as above except compilation is eager.
|
||||
Default policy is `code`.
|
||||
* `enablePreferredSizeMode` boolean (optional) - Whether to enable
|
||||
preferred size mode. The preferred size is the minimum size needed to
|
||||
contain the layout of the document—without requiring scrolling. Enabling
|
||||
this will cause the `preferred-size-changed` event to be emitted on the
|
||||
`WebContents` when the preferred size changes. Default is `false`.
|
||||
* `titleBarOverlay` Object | Boolean (optional) - When using a frameless window in conjunction with `win.setWindowButtonVisibility(true)` on macOS or using a `titleBarStyle` so that the standard window controls ("traffic lights" on macOS) are visible, this property enables the Window Controls Overlay [JavaScript APIs][overlay-javascript-apis] and [CSS Environment Variables][overlay-css-env-vars]. Specifying `true` will result in an overlay with default system colors. Default is `false`.
|
||||
* `color` String (optional) _Windows_ - The CSS color of the Window Controls Overlay when enabled. Default is the system color.
|
||||
* `symbolColor` String (optional) _Windows_ - The CSS color of the symbols on the Window Controls Overlay when enabled. Default is the system color.
|
||||
* `height` Integer (optional) _macOS_ _Windows_ - The height of the title bar and Window Controls Overlay in pixels. Default is system height.
|
||||
|
||||
When setting minimum or maximum window size with `minWidth`/`maxWidth`/
|
||||
`minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from
|
||||
passing a size that does not follow size constraints to `setBounds`/`setSize` or
|
||||
to the constructor of `BrowserWindow`.
|
||||
|
||||
The possible values and behaviors of the `type` option are platform dependent.
|
||||
Possible values are:
|
||||
|
||||
* On Linux, possible types are `desktop`, `dock`, `toolbar`, `splash`,
|
||||
`notification`.
|
||||
* On macOS, possible types are `desktop`, `textured`, `panel`.
|
||||
* The `textured` type adds metal gradient appearance
|
||||
(`NSWindowStyleMaskTexturedBackground`).
|
||||
* The `desktop` type places the window at the desktop background window level
|
||||
(`kCGDesktopWindowLevel - 1`). Note that desktop window will not receive
|
||||
focus, keyboard or mouse events, but you can use `globalShortcut` to receive
|
||||
input sparingly.
|
||||
* The `panel` type enables the window to float on top of full-screened apps
|
||||
by adding the `NSWindowStyleMaskNonactivatingPanel` style mask,normally
|
||||
reserved for NSPanel, at runtime. Also, the window will appear on all
|
||||
spaces (desktops).
|
||||
* On Windows, possible type is `toolbar`.
|
||||
|
||||
### Instance Events
|
||||
|
||||
@@ -505,10 +795,6 @@ events.
|
||||
|
||||
A `Integer` property representing the unique ID of the window. Each ID is unique among all `BrowserWindow` instances of the entire Electron application.
|
||||
|
||||
#### `win.tabbingIdentifier` _macOS_ _Readonly_
|
||||
|
||||
A `string` (optional) property that is equal to the `tabbingIdentifier` passed to the `BrowserWindow` constructor or `undefined` if none was set.
|
||||
|
||||
#### `win.autoHideMenuBar`
|
||||
|
||||
A `boolean` property that determines whether the window menu bar should hide itself automatically. Once set, the menu bar will only show when users press the single `Alt` key.
|
||||
@@ -1215,7 +1501,7 @@ const win = new BrowserWindow()
|
||||
const url = require('url').format({
|
||||
protocol: 'file',
|
||||
slashes: true,
|
||||
pathname: require('node:path').join(__dirname, 'index.html')
|
||||
pathname: require('path').join(__dirname, 'index.html')
|
||||
})
|
||||
|
||||
win.loadURL(url)
|
||||
@@ -1675,8 +1961,12 @@ removed in future Electron releases.
|
||||
On a Window with Window Controls Overlay already enabled, this method updates
|
||||
the style of the title bar overlay.
|
||||
|
||||
[runtime-enabled-features]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/runtime_enabled_features.json5
|
||||
[page-visibility-api]: https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
|
||||
[quick-look]: https://en.wikipedia.org/wiki/Quick_Look
|
||||
[vibrancy-docs]: https://developer.apple.com/documentation/appkit/nsvisualeffectview?preferredLanguage=objc
|
||||
[window-levels]: https://developer.apple.com/documentation/appkit/nswindow/level
|
||||
[chrome-content-scripts]: https://developer.chrome.com/extensions/content_scripts#execution-environment
|
||||
[event-emitter]: https://nodejs.org/api/events.html#events_class_eventemitter
|
||||
[overlay-javascript-apis]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#javascript-apis
|
||||
[overlay-css-env-vars]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#css-environment-variables
|
||||
|
||||
@@ -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('node:crypto')
|
||||
const crypto = require('crypto')
|
||||
contextBridge.exposeInMainWorld('nodeCrypto', {
|
||||
sha256sum (data) {
|
||||
const hash = crypto.createHash('sha256')
|
||||
|
||||
@@ -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 can be `screen` and `window`.
|
||||
to be captured, available types are `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,23 +40,6 @@ 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.
|
||||
|
||||
@@ -80,10 +80,6 @@ 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 include `good`, `better`, or `best`. The default is `best`.
|
||||
Possible values are `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,8 +85,6 @@ 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:
|
||||
@@ -129,8 +127,6 @@ 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`
|
||||
|
||||
@@ -33,7 +33,7 @@ to register it to that session explicitly.
|
||||
|
||||
```javascript
|
||||
const { app, BrowserWindow, net, protocol, session } = require('electron')
|
||||
const path = require('node:path')
|
||||
const path = require('path')
|
||||
const url = require('url')
|
||||
|
||||
app.whenReady().then(() => {
|
||||
@@ -122,7 +122,7 @@ Example:
|
||||
|
||||
```js
|
||||
const { app, net, protocol } = require('electron')
|
||||
const { join } = require('node:path')
|
||||
const { join } = require('path')
|
||||
const { pathToFileURL } = require('url')
|
||||
|
||||
protocol.registerSchemesAsPrivileged([
|
||||
|
||||
@@ -56,7 +56,10 @@ 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"`.
|
||||
* `gnome_any` - 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"`. When this value is present the application
|
||||
will first try to use `libsecret` backend and if it fails will attempt to use `libgnome_keyring`.
|
||||
* `gnome_libsecret` - When the following command line flag is provided `--password-store="gnome-libsecret"`.
|
||||
* `gnome_keyring` - When the following command line flag is provided `--password-store="gnome-keyring"`.
|
||||
* `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
|
||||
|
||||
@@ -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('node:fs').writeFileSync('/somewhere', response.body)
|
||||
require('fs').writeFileSync('/somewhere', response.body)
|
||||
})
|
||||
})
|
||||
```
|
||||
@@ -266,7 +266,7 @@ Returns:
|
||||
|
||||
* `event` Event
|
||||
* `details` Object
|
||||
* `device` [HIDDevice](structures/hid-device.md)
|
||||
* `device` [HIDDevice[]](structures/hid-device.md)
|
||||
* `frame` [WebFrameMain](web-frame-main.md)
|
||||
|
||||
Emitted after `navigator.hid.requestDevice` has been called and
|
||||
@@ -281,7 +281,7 @@ Returns:
|
||||
|
||||
* `event` Event
|
||||
* `details` Object
|
||||
* `device` [HIDDevice](structures/hid-device.md)
|
||||
* `device` [HIDDevice[]](structures/hid-device.md)
|
||||
* `frame` [WebFrameMain](web-frame-main.md)
|
||||
|
||||
Emitted after `navigator.hid.requestDevice` has been called and
|
||||
@@ -296,7 +296,7 @@ Returns:
|
||||
|
||||
* `event` Event
|
||||
* `details` Object
|
||||
* `device` [HIDDevice](structures/hid-device.md)
|
||||
* `device` [HIDDevice[]](structures/hid-device.md)
|
||||
* `origin` string (optional) - The origin that the device has been revoked from.
|
||||
|
||||
Emitted after `HIDDevice.forget()` has been called. This event can be used
|
||||
@@ -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 be
|
||||
* `storages` string[] (optional) - The types of storages to clear, can contain:
|
||||
`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 be
|
||||
* `quotas` string[] (optional) - The types of quotas to clear, can contain:
|
||||
`temporary`, `syncable`. If not specified, clear all quotas.
|
||||
|
||||
Returns `Promise<void>` - resolves when the storage data has been cleared.
|
||||
@@ -901,7 +901,6 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
|
||||
* `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.
|
||||
* `keyboardLock` - Request capture of keypresses for any or all of the keys on the physical keyboard via the [Keyboard Lock API](https://developer.mozilla.org/en-US/docs/Web/API/Keyboard/lock). 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.
|
||||
@@ -1114,7 +1113,7 @@ app.whenReady().then(() => {
|
||||
|
||||
* `handler` Function\<string[]> | null
|
||||
* `details` Object
|
||||
* `protectedClasses` string[] - The current list of protected USB classes. Possible class values include:
|
||||
* `protectedClasses` string[] - The current list of protected USB classes. Possible class values are:
|
||||
* `audio`
|
||||
* `audio-video`
|
||||
* `hid`
|
||||
@@ -1194,7 +1193,7 @@ automatically. To clear the handler, call `setBluetoothPairingHandler(null)`.
|
||||
|
||||
```javascript
|
||||
const { app, BrowserWindow, session } = require('electron')
|
||||
const path = require('node:path')
|
||||
const path = require('path')
|
||||
|
||||
function createWindow () {
|
||||
let bluetoothPinCallback = null
|
||||
@@ -1458,9 +1457,9 @@ extension to be loaded.
|
||||
|
||||
```js
|
||||
const { app, session } = require('electron')
|
||||
const path = require('node:path')
|
||||
const path = require('path')
|
||||
|
||||
app.whenReady().then(async () => {
|
||||
app.on('ready', async () => {
|
||||
await session.defaultSession.loadExtension(
|
||||
path.join(__dirname, 'react-devtools'),
|
||||
// allowFileAccess is required to load the devtools extension on file:// URLs.
|
||||
@@ -1492,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.
|
||||
@@ -1545,7 +1544,7 @@ A [`Protocol`](protocol.md) object for this session.
|
||||
|
||||
```javascript
|
||||
const { app, session } = require('electron')
|
||||
const path = require('node:path')
|
||||
const path = require('path')
|
||||
|
||||
app.whenReady().then(() => {
|
||||
const protocol = session.fromPartition('some-partition').protocol
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
# BrowserWindowConstructorOptions Object
|
||||
|
||||
* `width` Integer (optional) - Window's width in pixels. Default is `800`.
|
||||
* `height` Integer (optional) - Window's height in pixels. Default is `600`.
|
||||
* `x` Integer (optional) - (**required** if y is used) Window's left offset from screen.
|
||||
Default is to center the window.
|
||||
* `y` Integer (optional) - (**required** if x is used) Window's top offset from screen.
|
||||
Default is to center the window.
|
||||
* `useContentSize` boolean (optional) - The `width` and `height` would be used as web
|
||||
page's size, which means the actual window's size will include window
|
||||
frame's size and be slightly larger. Default is `false`.
|
||||
* `center` boolean (optional) - Show window in the center of the screen. Default is `false`.
|
||||
* `minWidth` Integer (optional) - Window's minimum width. Default is `0`.
|
||||
* `minHeight` Integer (optional) - Window's minimum height. Default is `0`.
|
||||
* `maxWidth` Integer (optional) - Window's maximum width. Default is no limit.
|
||||
* `maxHeight` Integer (optional) - Window's maximum height. Default is no limit.
|
||||
* `resizable` boolean (optional) - Whether window is resizable. Default is `true`.
|
||||
* `movable` boolean (optional) _macOS_ _Windows_ - Whether window is
|
||||
movable. This is not implemented on Linux. Default is `true`.
|
||||
* `minimizable` boolean (optional) _macOS_ _Windows_ - Whether window is
|
||||
minimizable. This is not implemented on Linux. Default is `true`.
|
||||
* `maximizable` boolean (optional) _macOS_ _Windows_ - Whether window is
|
||||
maximizable. This is not implemented on Linux. Default is `true`.
|
||||
* `closable` boolean (optional) _macOS_ _Windows_ - Whether window is
|
||||
closable. This is not implemented on Linux. Default is `true`.
|
||||
* `focusable` boolean (optional) - Whether the window can be focused. Default is
|
||||
`true`. On Windows setting `focusable: false` also implies setting
|
||||
`skipTaskbar: true`. On Linux setting `focusable: false` makes the window
|
||||
stop interacting with wm, so the window will always stay on top in all
|
||||
workspaces.
|
||||
* `alwaysOnTop` boolean (optional) - Whether the window should always stay on top of
|
||||
other windows. Default is `false`.
|
||||
* `fullscreen` boolean (optional) - Whether the window should show in fullscreen. When
|
||||
explicitly set to `false` the fullscreen button will be hidden or disabled
|
||||
on macOS. Default is `false`.
|
||||
* `fullscreenable` boolean (optional) - Whether the window can be put into fullscreen
|
||||
mode. On macOS, also whether the maximize/zoom button should toggle full
|
||||
screen mode or maximize window. Default is `true`.
|
||||
* `simpleFullscreen` boolean (optional) _macOS_ - Use pre-Lion fullscreen on
|
||||
macOS. Default is `false`.
|
||||
* `skipTaskbar` boolean (optional) _macOS_ _Windows_ - Whether to show the window in taskbar.
|
||||
Default is `false`.
|
||||
* `hiddenInMissionControl` boolean (optional) _macOS_ - Whether window should be hidden when the user toggles into mission control.
|
||||
* `kiosk` boolean (optional) - Whether the window is in kiosk mode. Default is `false`.
|
||||
* `title` string (optional) - Default window title. Default is `"Electron"`. If the HTML tag `<title>` is defined in the HTML file loaded by `loadURL()`, this property will be ignored.
|
||||
* `icon` ([NativeImage](../native-image.md) | string) (optional) - The window icon. On Windows it is
|
||||
recommended to use `ICO` icons to get best visual effects, you can also
|
||||
leave it undefined so the executable's icon will be used.
|
||||
* `show` boolean (optional) - Whether window should be shown when created. Default is
|
||||
`true`.
|
||||
* `paintWhenInitiallyHidden` boolean (optional) - Whether the renderer should be active when `show` is `false` and it has just been created. In order for `document.visibilityState` to work correctly on first load with `show: false` you should set this to `false`. Setting this to `false` will cause the `ready-to-show` event to not fire. Default is `true`.
|
||||
* `frame` boolean (optional) - Specify `false` to create a
|
||||
[frameless window](../../tutorial/window-customization.md#create-frameless-windows). Default is `true`.
|
||||
* `parent` BrowserWindow (optional) - Specify parent window. Default is `null`.
|
||||
* `modal` boolean (optional) - Whether this is a modal window. This only works when the
|
||||
window is a child window. Default is `false`.
|
||||
* `acceptFirstMouse` boolean (optional) _macOS_ - Whether clicking an
|
||||
inactive window will also click through to the web contents. Default is
|
||||
`false` on macOS. This option is not configurable on other platforms.
|
||||
* `disableAutoHideCursor` boolean (optional) - Whether to hide cursor when typing.
|
||||
Default is `false`.
|
||||
* `autoHideMenuBar` boolean (optional) - Auto hide the menu bar unless the `Alt`
|
||||
key is pressed. Default is `false`.
|
||||
* `enableLargerThanScreen` boolean (optional) _macOS_ - Enable the window to
|
||||
be resized larger than screen. Only relevant for macOS, as other OSes
|
||||
allow larger-than-screen windows by default. Default is `false`.
|
||||
* `backgroundColor` string (optional) - The window's background color in Hex, RGB, RGBA, HSL, HSLA or named CSS color format. Alpha in #AARRGGBB format is supported if `transparent` is set to `true`. Default is `#FFF` (white). See [win.setBackgroundColor](../browser-window.md#winsetbackgroundcolorbackgroundcolor) for more information.
|
||||
* `hasShadow` boolean (optional) - Whether window should have a shadow. Default is `true`.
|
||||
* `opacity` number (optional) _macOS_ _Windows_ - Set the initial opacity of
|
||||
the window, between 0.0 (fully transparent) and 1.0 (fully opaque). This
|
||||
is only implemented on Windows and macOS.
|
||||
* `darkTheme` boolean (optional) - Forces using dark theme for the window, only works on
|
||||
some GTK+3 desktop environments. Default is `false`.
|
||||
* `transparent` boolean (optional) - Makes the window [transparent](../../tutorial/window-customization.md#create-transparent-windows).
|
||||
Default is `false`. On Windows, does not work unless the window is frameless.
|
||||
* `type` string (optional) - The type of window, default is normal window. See more about
|
||||
this below.
|
||||
* `visualEffectState` string (optional) _macOS_ - Specify how the material
|
||||
appearance should reflect window activity state on macOS. Must be used
|
||||
with the `vibrancy` property. Possible values are:
|
||||
* `followWindow` - The backdrop should automatically appear active when the window is active, and inactive when it is not. This is the default.
|
||||
* `active` - The backdrop should always appear active.
|
||||
* `inactive` - The backdrop should always appear inactive.
|
||||
* `titleBarStyle` string (optional) _macOS_ _Windows_ - The style of window title bar.
|
||||
Default is `default`. Possible values are:
|
||||
* `default` - Results in the standard title bar for macOS or Windows respectively.
|
||||
* `hidden` - Results in a hidden title bar and a full size content window. On macOS, the window still has the standard window controls (“traffic lights”) in the top left. On Windows, when combined with `titleBarOverlay: true` it will activate the Window Controls Overlay (see `titleBarOverlay` for more information), otherwise no window controls will be shown.
|
||||
* `hiddenInset` _macOS_ - Only on macOS, results in a hidden title bar
|
||||
with an alternative look where the traffic light buttons are slightly
|
||||
more inset from the window edge.
|
||||
* `customButtonsOnHover` _macOS_ - Only on macOS, results in a hidden
|
||||
title bar and a full size content window, the traffic light buttons will
|
||||
display when being hovered over in the top left of the window.
|
||||
**Note:** This option is currently experimental.
|
||||
* `trafficLightPosition` [Point](point.md) (optional) _macOS_ -
|
||||
Set a custom position for the traffic light buttons in frameless windows.
|
||||
* `roundedCorners` boolean (optional) _macOS_ - Whether frameless window
|
||||
should have rounded corners on macOS. Default is `true`. Setting this property
|
||||
to `false` will prevent the window from being fullscreenable.
|
||||
* `fullscreenWindowTitle` boolean (optional) _macOS_ _Deprecated_ - Shows
|
||||
the title in the title bar in full screen mode on macOS for `hiddenInset`
|
||||
titleBarStyle. Default is `false`.
|
||||
* `thickFrame` boolean (optional) - Use `WS_THICKFRAME` style for frameless windows on
|
||||
Windows, which adds standard window frame. Setting it to `false` will remove
|
||||
window shadow and window animations. Default is `true`.
|
||||
* `vibrancy` string (optional) _macOS_ - Add a type of vibrancy effect to
|
||||
the window, only on macOS. Can be `appearance-based`, `light`, `dark`,
|
||||
`titlebar`, `selection`, `menu`, `popover`, `sidebar`, `medium-light`,
|
||||
`ultra-dark`, `header`, `sheet`, `window`, `hud`, `fullscreen-ui`,
|
||||
`tooltip`, `content`, `under-window`, or `under-page`. Please note that
|
||||
`appearance-based`, `light`, `dark`, `medium-light`, and `ultra-dark` are
|
||||
deprecated and have been removed in macOS Catalina (10.15).
|
||||
* `backgroundMaterial` string (optional) _Windows_ - Set the window's
|
||||
system-drawn background material, including behind the non-client area.
|
||||
Can be `auto`, `none`, `mica`, `acrylic` or `tabbed`. See [win.setBackgroundMaterial](../browser-window.md#winsetbackgroundmaterialmaterial-windows) for more information.
|
||||
* `zoomToPageWidth` boolean (optional) _macOS_ - Controls the behavior on
|
||||
macOS when option-clicking the green stoplight button on the toolbar or by
|
||||
clicking the Window > Zoom menu item. If `true`, the window will grow to
|
||||
the preferred width of the web page when zoomed, `false` will cause it to
|
||||
zoom to the width of the screen. This will also affect the behavior when
|
||||
calling `maximize()` directly. Default is `false`.
|
||||
* `tabbingIdentifier` string (optional) _macOS_ - Tab group name, allows
|
||||
opening the window as a native tab. Windows with the same
|
||||
tabbing identifier will be grouped together. This also adds a native new
|
||||
tab button to your window's tab bar and allows your `app` and window to
|
||||
receive the `new-window-for-tab` event.
|
||||
* `webPreferences` [WebPreferences](web-preferences.md?inline) (optional) - Settings of web page's features.
|
||||
* `titleBarOverlay` Object | Boolean (optional) - When using a frameless window in conjunction with `win.setWindowButtonVisibility(true)` on macOS or using a `titleBarStyle` so that the standard window controls ("traffic lights" on macOS) are visible, this property enables the Window Controls Overlay [JavaScript APIs][overlay-javascript-apis] and [CSS Environment Variables][overlay-css-env-vars]. Specifying `true` will result in an overlay with default system colors. Default is `false`.
|
||||
* `color` String (optional) _Windows_ - The CSS color of the Window Controls Overlay when enabled. Default is the system color.
|
||||
* `symbolColor` String (optional) _Windows_ - The CSS color of the symbols on the Window Controls Overlay when enabled. Default is the system color.
|
||||
* `height` Integer (optional) _macOS_ _Windows_ - The height of the title bar and Window Controls Overlay in pixels. Default is system height.
|
||||
|
||||
When setting minimum or maximum window size with `minWidth`/`maxWidth`/
|
||||
`minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from
|
||||
passing a size that does not follow size constraints to `setBounds`/`setSize` or
|
||||
to the constructor of `BrowserWindow`.
|
||||
|
||||
The possible values and behaviors of the `type` option are platform dependent.
|
||||
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`).
|
||||
* The `desktop` type places the window at the desktop background window level
|
||||
(`kCGDesktopWindowLevel - 1`). Note that desktop window will not receive
|
||||
focus, keyboard or mouse events, but you can use `globalShortcut` to receive
|
||||
input sparingly.
|
||||
* The `panel` type enables the window to float on top of full-screened apps
|
||||
by adding the `NSWindowStyleMaskNonactivatingPanel` style mask,normally
|
||||
reserved for NSPanel, at runtime. Also, the window will appear on all
|
||||
spaces (desktops).
|
||||
* On Windows, possible type is `toolbar`.
|
||||
|
||||
[overlay-css-env-vars]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#css-environment-variables
|
||||
[overlay-javascript-apis]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#javascript-apis
|
||||
@@ -1,143 +0,0 @@
|
||||
# WebPreferences Object
|
||||
|
||||
* `devTools` boolean (optional) - Whether to enable DevTools. If it is set to `false`, can not use `BrowserWindow.webContents.openDevTools()` to open DevTools. Default is `true`.
|
||||
* `nodeIntegration` boolean (optional) - Whether node integration is enabled.
|
||||
Default is `false`.
|
||||
* `nodeIntegrationInWorker` boolean (optional) - Whether node integration is
|
||||
enabled in web workers. Default is `false`. More about this can be found
|
||||
in [Multithreading](../../tutorial/multithreading.md).
|
||||
* `nodeIntegrationInSubFrames` boolean (optional) - Experimental option for
|
||||
enabling Node.js support in sub-frames such as iframes and child windows. All your preloads will load for
|
||||
every iframe, you can use `process.isMainFrame` to determine if you are
|
||||
in the main frame or not.
|
||||
* `preload` string (optional) - Specifies a script that will be loaded before other
|
||||
scripts run in the page. This script will always have access to node APIs
|
||||
no matter whether node integration is turned on or off. The value should
|
||||
be the absolute file path to the script.
|
||||
When node integration is turned off, the preload script can reintroduce
|
||||
Node global symbols back to the global scope. See example
|
||||
[here](../context-bridge.md#exposing-node-global-symbols).
|
||||
* `sandbox` boolean (optional) - If set, this will sandbox the renderer
|
||||
associated with the window, making it compatible with the Chromium
|
||||
OS-level sandbox and disabling the Node.js engine. This is not the same as
|
||||
the `nodeIntegration` option and the APIs available to the preload script
|
||||
are more limited. Read more about the option [here](../../tutorial/sandbox.md).
|
||||
* `session` [Session](../session.md#class-session) (optional) - Sets the session used by the
|
||||
page. Instead of passing the Session object directly, you can also choose to
|
||||
use the `partition` option instead, which accepts a partition string. When
|
||||
both `session` and `partition` are provided, `session` will be preferred.
|
||||
Default is the default session.
|
||||
* `partition` string (optional) - Sets the session used by the page according to the
|
||||
session's partition string. If `partition` starts with `persist:`, the page
|
||||
will use a persistent session available to all pages in the app with the
|
||||
same `partition`. If there is no `persist:` prefix, the page will use an
|
||||
in-memory session. By assigning the same `partition`, multiple pages can share
|
||||
the same session. Default is the default session.
|
||||
* `zoomFactor` number (optional) - The default zoom factor of the page, `3.0` represents
|
||||
`300%`. Default is `1.0`.
|
||||
* `javascript` boolean (optional) - Enables JavaScript support. Default is `true`.
|
||||
* `webSecurity` boolean (optional) - When `false`, it will disable the
|
||||
same-origin policy (usually using testing websites by people), and set
|
||||
`allowRunningInsecureContent` to `true` if this options has not been set
|
||||
by user. Default is `true`.
|
||||
* `allowRunningInsecureContent` boolean (optional) - Allow an https page to run
|
||||
JavaScript, CSS or plugins from http URLs. Default is `false`.
|
||||
* `images` boolean (optional) - Enables image support. Default is `true`.
|
||||
* `imageAnimationPolicy` string (optional) - Specifies how to run image animations (E.g. GIFs). Can be `animate`, `animateOnce` or `noAnimation`. Default is `animate`.
|
||||
* `textAreasAreResizable` boolean (optional) - Make TextArea elements resizable. Default
|
||||
is `true`.
|
||||
* `webgl` boolean (optional) - Enables WebGL support. Default is `true`.
|
||||
* `plugins` boolean (optional) - Whether plugins should be enabled. Default is `false`.
|
||||
* `experimentalFeatures` boolean (optional) - Enables Chromium's experimental features.
|
||||
Default is `false`.
|
||||
* `scrollBounce` boolean (optional) _macOS_ - Enables scroll bounce
|
||||
(rubber banding) effect on macOS. Default is `false`.
|
||||
* `enableBlinkFeatures` string (optional) - A list of feature strings separated by `,`, like
|
||||
`CSSVariables,KeyboardEventKey` to enable. The full list of supported feature
|
||||
strings can be found in the [RuntimeEnabledFeatures.json5][runtime-enabled-features]
|
||||
file.
|
||||
* `disableBlinkFeatures` string (optional) - A list of feature strings separated by `,`,
|
||||
like `CSSVariables,KeyboardEventKey` to disable. The full list of supported
|
||||
feature strings can be found in the
|
||||
[RuntimeEnabledFeatures.json5][runtime-enabled-features] file.
|
||||
* `defaultFontFamily` Object (optional) - Sets the default font for the font-family.
|
||||
* `standard` string (optional) - Defaults to `Times New Roman`.
|
||||
* `serif` string (optional) - Defaults to `Times New Roman`.
|
||||
* `sansSerif` string (optional) - Defaults to `Arial`.
|
||||
* `monospace` string (optional) - Defaults to `Courier New`.
|
||||
* `cursive` string (optional) - Defaults to `Script`.
|
||||
* `fantasy` string (optional) - Defaults to `Impact`.
|
||||
* `defaultFontSize` Integer (optional) - Defaults to `16`.
|
||||
* `defaultMonospaceFontSize` Integer (optional) - Defaults to `13`.
|
||||
* `minimumFontSize` Integer (optional) - Defaults to `0`.
|
||||
* `defaultEncoding` string (optional) - Defaults to `ISO-8859-1`.
|
||||
* `backgroundThrottling` boolean (optional) - Whether to throttle animations and timers
|
||||
when the page becomes background. This also affects the
|
||||
[Page Visibility API](../browser-window.md#page-visibility). Defaults to `true`.
|
||||
* `offscreen` boolean (optional) - Whether to enable offscreen rendering for the browser
|
||||
window. Defaults to `false`. See the
|
||||
[offscreen rendering tutorial](../../tutorial/offscreen-rendering.md) for
|
||||
more details.
|
||||
* `contextIsolation` boolean (optional) - Whether to run Electron APIs and
|
||||
the specified `preload` script in a separate JavaScript context. Defaults
|
||||
to `true`. The context that the `preload` script runs in will only have
|
||||
access to its own dedicated `document` and `window` globals, as well as
|
||||
its own set of JavaScript builtins (`Array`, `Object`, `JSON`, etc.),
|
||||
which are all invisible to the loaded content. The Electron API will only
|
||||
be available in the `preload` script and not the loaded page. This option
|
||||
should be used when loading potentially untrusted remote content to ensure
|
||||
the loaded content cannot tamper with the `preload` script and any
|
||||
Electron APIs being used. This option uses the same technique used by
|
||||
[Chrome Content Scripts][chrome-content-scripts]. You can access this
|
||||
context in the dev tools by selecting the 'Electron Isolated Context'
|
||||
entry in the combo box at the top of the Console tab.
|
||||
* `webviewTag` boolean (optional) - Whether to enable the [`<webview>` tag](../webview-tag.md).
|
||||
Defaults to `false`. **Note:** The
|
||||
`preload` script configured for the `<webview>` will have node integration
|
||||
enabled when it is executed so you should ensure remote/untrusted content
|
||||
is not able to create a `<webview>` tag with a possibly malicious `preload`
|
||||
script. You can use the `will-attach-webview` event on [webContents](../web-contents.md)
|
||||
to strip away the `preload` script and to validate or alter the
|
||||
`<webview>`'s initial settings.
|
||||
* `additionalArguments` string[] (optional) - A list of strings that will be appended
|
||||
to `process.argv` in the renderer process of this app. Useful for passing small
|
||||
bits of data down to renderer process preload scripts.
|
||||
* `safeDialogs` boolean (optional) - Whether to enable browser style
|
||||
consecutive dialog protection. Default is `false`.
|
||||
* `safeDialogsMessage` string (optional) - The message to display when
|
||||
consecutive dialog protection is triggered. If not defined the default
|
||||
message would be used, note that currently the default message is in
|
||||
English and not localized.
|
||||
* `disableDialogs` boolean (optional) - Whether to disable dialogs
|
||||
completely. Overrides `safeDialogs`. Default is `false`.
|
||||
* `navigateOnDragDrop` boolean (optional) - Whether dragging and dropping a
|
||||
file or link onto the page causes a navigation. Default is `false`.
|
||||
* `autoplayPolicy` string (optional) - Autoplay policy to apply to
|
||||
content in the window, can be `no-user-gesture-required`,
|
||||
`user-gesture-required`, `document-user-activation-required`. Defaults to
|
||||
`no-user-gesture-required`.
|
||||
* `disableHtmlFullscreenWindowResize` boolean (optional) - Whether to
|
||||
prevent the window from resizing when entering HTML Fullscreen. Default
|
||||
is `false`.
|
||||
* `accessibleTitle` string (optional) - An alternative title string provided only
|
||||
to accessibility tools such as screen readers. This string is not directly
|
||||
visible to users.
|
||||
* `spellcheck` boolean (optional) - Whether to enable the builtin spellchecker.
|
||||
Default is `true`.
|
||||
* `enableWebSQL` boolean (optional) - Whether to enable the [WebSQL api](https://www.w3.org/TR/webdatabase/).
|
||||
Default is `true`.
|
||||
* `v8CacheOptions` string (optional) - Enforces the v8 code caching policy
|
||||
used by blink. Accepted values are
|
||||
* `none` - Disables code caching
|
||||
* `code` - Heuristic based code caching
|
||||
* `bypassHeatCheck` - Bypass code caching heuristics but with lazy compilation
|
||||
* `bypassHeatCheckAndEagerCompile` - Same as above except compilation is eager.
|
||||
Default policy is `code`.
|
||||
* `enablePreferredSizeMode` boolean (optional) - Whether to enable
|
||||
preferred size mode. The preferred size is the minimum size needed to
|
||||
contain the layout of the document—without requiring scrolling. Enabling
|
||||
this will cause the `preferred-size-changed` event to be emitted on the
|
||||
`WebContents` when the preferred size changes. Default is `false`.
|
||||
|
||||
[chrome-content-scripts]: https://developer.chrome.com/extensions/content_scripts#execution-environment
|
||||
[runtime-enabled-features]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/runtime_enabled_features.json5
|
||||
@@ -435,11 +435,7 @@ Returns an object with system animation settings.
|
||||
|
||||
## Properties
|
||||
|
||||
### `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_
|
||||
### `systemPreferences.appLevelAppearance` _macOS_
|
||||
|
||||
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
|
||||
|
||||
@@ -210,7 +210,7 @@ Returns:
|
||||
* `url` string - URL for the created window.
|
||||
* `frameName` string - Name given to the created window in the
|
||||
`window.open()` call.
|
||||
* `options` [BrowserWindowConstructorOptions](structures/browser-window-options.md) - The options used to create the
|
||||
* `options` BrowserWindowConstructorOptions - The options used to create the
|
||||
BrowserWindow. They are merged in increasing precedence: parsed options
|
||||
from the `features` string from `window.open()`, security-related
|
||||
webPreferences inherited from the parent, and options given by
|
||||
@@ -239,8 +239,9 @@ 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.
|
||||
* `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.
|
||||
* `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
|
||||
@@ -272,8 +273,6 @@ 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
|
||||
@@ -784,7 +783,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 include `none`, `plainText`,
|
||||
field, the type of that field. Possible values are `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.
|
||||
@@ -896,7 +895,7 @@ Emitted when the devtools window instructs the webContents to reload
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `webPreferences` [WebPreferences](structures/web-preferences.md) - The web preferences that will be used by the guest
|
||||
* `webPreferences` WebPreferences - The web preferences that will be used by the guest
|
||||
page. This object can be modified to adjust the preferences for the guest
|
||||
page.
|
||||
* `params` Record<string, string> - The other `<webview>` parameters such as the `src` URL.
|
||||
@@ -1637,9 +1636,9 @@ An example of `webContents.printToPDF`:
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow } = require('electron')
|
||||
const fs = require('node:fs')
|
||||
const path = require('node:path')
|
||||
const os = require('node:os')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const os = require('os')
|
||||
|
||||
const win = new BrowserWindow()
|
||||
win.loadURL('http://github.com')
|
||||
|
||||
@@ -1106,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 include `none`, `plainText`,
|
||||
field, the type of that field. Possible values are `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.
|
||||
|
||||
@@ -33,12 +33,12 @@ because it is invoked in the main process.
|
||||
Returns [`Window`](https://developer.mozilla.org/en-US/docs/Web/API/Window) | null
|
||||
|
||||
`features` is a comma-separated key-value list, following the standard format of
|
||||
the browser. Electron will parse [`BrowserWindowConstructorOptions`](structures/browser-window-options.md) out of this
|
||||
the browser. Electron will parse `BrowserWindowConstructorOptions` out of this
|
||||
list where possible, for convenience. For full control and better ergonomics,
|
||||
consider using `webContents.setWindowOpenHandler` to customize the
|
||||
BrowserWindow creation.
|
||||
|
||||
A subset of [`WebPreferences`](structures/web-preferences.md) can be set directly,
|
||||
A subset of `WebPreferences` can be set directly,
|
||||
unnested, from the features string: `zoomFactor`, `nodeIntegration`, `preload`,
|
||||
`javascript`, `contextIsolation`, and `webviewTag`.
|
||||
|
||||
@@ -60,7 +60,7 @@ window.open('https://github.com', '_blank', 'top=500,left=200,frame=false,nodeIn
|
||||
`features` will be passed to any registered `webContents`'s
|
||||
`did-create-window` event handler in the `options` argument.
|
||||
* `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
|
||||
* When opening `about:blank`, the child window's `WebPreferences` will be copied
|
||||
from the parent window, and there is no way to override it because Chromium
|
||||
skips browser side navigation in this case.
|
||||
|
||||
@@ -68,7 +68,7 @@ To customize or cancel the creation of the window, you can optionally set an
|
||||
override handler with `webContents.setWindowOpenHandler()` from the main
|
||||
process. Returning `{ action: 'deny' }` cancels the window. Returning `{
|
||||
action: 'allow', overrideBrowserWindowOptions: { ... } }` will allow opening
|
||||
the window and setting the [`BrowserWindowConstructorOptions`](structures/browser-window-options.md) to be used when
|
||||
the window and setting the `BrowserWindowConstructorOptions` to be used when
|
||||
creating the window. Note that this is more powerful than passing options
|
||||
through the feature string, as the renderer has more limited privileges in
|
||||
deciding security preferences than the main process.
|
||||
|
||||
@@ -21,59 +21,6 @@ macOS 10.13 (High Sierra) and macOS 10.14 (Mojave) are no longer supported by [C
|
||||
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`
|
||||
|
||||
@@ -42,14 +42,14 @@ $ asar list /path/to/example.asar
|
||||
Read a file in the ASAR archive:
|
||||
|
||||
```javascript
|
||||
const fs = require('node:fs')
|
||||
const fs = require('fs')
|
||||
fs.readFileSync('/path/to/example.asar/file.txt')
|
||||
```
|
||||
|
||||
List all files under the root of the archive:
|
||||
|
||||
```javascript
|
||||
const fs = require('node:fs')
|
||||
const fs = require('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('node:fs')
|
||||
const fs = require('fs')
|
||||
process.noAsar = true
|
||||
fs.readFileSync('/path/to/example.asar')
|
||||
```
|
||||
|
||||
@@ -123,19 +123,32 @@ support via Electron's support for the [Chrome DevTools Protocol][] (CDP).
|
||||
|
||||
### Install dependencies
|
||||
|
||||
You can install Playwright through your preferred Node.js package manager. It comes with its
|
||||
own [test runner][playwright-intro], which is built for end-to-end testing:
|
||||
You can install Playwright through your preferred Node.js package manager. The Playwright team
|
||||
recommends using the `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD` environment variable to avoid
|
||||
unnecessary browser downloads when testing an Electron app.
|
||||
|
||||
```sh npm2yarn
|
||||
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm install --save-dev playwright
|
||||
```
|
||||
|
||||
Playwright also comes with its own test runner, Playwright Test, which is built for end-to-end
|
||||
testing. You can also install it as a dev dependency in your project:
|
||||
|
||||
```sh npm2yarn
|
||||
npm install --save-dev @playwright/test
|
||||
```
|
||||
|
||||
:::caution Dependencies
|
||||
This tutorial was written with `@playwright/test@1.41.1`. Check out
|
||||
This tutorial was written `playwright@1.16.3` and `@playwright/test@1.16.3`. Check out
|
||||
[Playwright's releases][playwright-releases] page to learn about
|
||||
changes that might affect the code below.
|
||||
:::
|
||||
|
||||
:::info Using third-party test runners
|
||||
If you're interested in using an alternative test runner (e.g. Jest or Mocha), check out
|
||||
Playwright's [Third-Party Test Runner][playwright-test-runners] guide.
|
||||
:::
|
||||
|
||||
### Write your tests
|
||||
|
||||
Playwright launches your app in development mode through the `_electron.launch` API.
|
||||
@@ -143,7 +156,8 @@ To point this API to your Electron app, you can pass the path to your main proce
|
||||
entry point (here, it is `main.js`).
|
||||
|
||||
```js {5} @ts-nocheck
|
||||
const { test, _electron: electron } = require('@playwright/test')
|
||||
const { _electron: electron } = require('playwright')
|
||||
const { test } = require('@playwright/test')
|
||||
|
||||
test('launch app', async () => {
|
||||
const electronApp = await electron.launch({ args: ['main.js'] })
|
||||
@@ -155,8 +169,9 @@ test('launch app', async () => {
|
||||
After that, you will access to an instance of Playwright's `ElectronApp` class. This
|
||||
is a powerful class that has access to main process modules for example:
|
||||
|
||||
```js {5-10} @ts-nocheck
|
||||
const { test, _electron: electron } = require('@playwright/test')
|
||||
```js {6-11} @ts-nocheck
|
||||
const { _electron: electron } = require('playwright')
|
||||
const { test } = require('@playwright/test')
|
||||
|
||||
test('get isPackaged', async () => {
|
||||
const electronApp = await electron.launch({ args: ['main.js'] })
|
||||
@@ -175,7 +190,8 @@ It can also create individual [Page][playwright-page] objects from Electron Brow
|
||||
For example, to grab the first BrowserWindow and save a screenshot:
|
||||
|
||||
```js {6-7} @ts-nocheck
|
||||
const { test, _electron: electron } = require('@playwright/test')
|
||||
const { _electron: electron } = require('playwright')
|
||||
const { test } = require('@playwright/test')
|
||||
|
||||
test('save screenshot', async () => {
|
||||
const electronApp = await electron.launch({ args: ['main.js'] })
|
||||
@@ -186,11 +202,12 @@ test('save screenshot', async () => {
|
||||
})
|
||||
```
|
||||
|
||||
Putting all this together using the Playwright test-runner, let's create a `example.spec.js`
|
||||
Putting all this together using the PlayWright Test runner, let's create a `example.spec.js`
|
||||
test file with a single test and assertion:
|
||||
|
||||
```js title='example.spec.js' @ts-nocheck
|
||||
const { test, expect, _electron: electron } = require('@playwright/test')
|
||||
const { _electron: electron } = require('playwright')
|
||||
const { test, expect } = require('@playwright/test')
|
||||
|
||||
test('example test', async () => {
|
||||
const electronApp = await electron.launch({ args: ['.'] })
|
||||
@@ -226,7 +243,6 @@ Running 1 test using 1 worker
|
||||
:::info
|
||||
Playwright Test will automatically run any files matching the `.*(test|spec)\.(js|ts|mjs)` regex.
|
||||
You can customize this match in the [Playwright Test configuration options][playwright-test-config].
|
||||
It also works with TypeScript out of the box.
|
||||
:::
|
||||
|
||||
:::tip Further reading
|
||||
@@ -244,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('node:child_process')
|
||||
const childProcess = require('child_process')
|
||||
const electronPath = require('electron')
|
||||
|
||||
// spawn the process
|
||||
@@ -384,10 +400,10 @@ test.after.always('cleanup', async t => {
|
||||
|
||||
[chrome-driver]: https://sites.google.com/chromium.org/driver/
|
||||
[Puppeteer]: https://github.com/puppeteer/puppeteer
|
||||
[playwright-intro]: https://playwright.dev/docs/intro
|
||||
[playwright-electron]: https://playwright.dev/docs/api/class-electron/
|
||||
[playwright-electronapplication]: https://playwright.dev/docs/api/class-electronapplication
|
||||
[playwright-page]: https://playwright.dev/docs/api/class-page
|
||||
[playwright-releases]: https://playwright.dev/docs/release-notes
|
||||
[playwright-releases]: https://github.com/microsoft/playwright/releases
|
||||
[playwright-test-config]: https://playwright.dev/docs/api/class-testconfig#test-config-test-match
|
||||
[playwright-test-runners]: https://playwright.dev/docs/test-runners/
|
||||
[Chrome DevTools Protocol]: https://chromedevtools.github.io/devtools-protocol/
|
||||
|
||||
@@ -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('node:path')
|
||||
const path = require('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('node:path')
|
||||
const os = require('node:os')
|
||||
const path = require('path')
|
||||
const os = require('os')
|
||||
|
||||
// on macOS
|
||||
const reactDevToolsPath = path.join(
|
||||
|
||||
@@ -9,11 +9,10 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
|
||||
|
||||
| Electron | Alpha | Beta | Stable | EOL | Chrome | Node | Supported |
|
||||
| ------- | ----- | ------- | ------ | ------ | ---- | ---- | ---- |
|
||||
| 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 | ✅ |
|
||||
| 26.0.0 | 2023-Jun-01 | 2023-Jun-27 | 2023-Aug-15 | TBD | M116 | TBD | ✅ |
|
||||
| 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 | 🚫 |
|
||||
| 24.0.0 | 2022-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 | 🚫 |
|
||||
@@ -48,6 +47,12 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
|
||||
* Since Electron 6, Electron major versions have been targeting every other Chromium major version. Each Electron stable should happen on the same day as Chrome stable ([see blog post](https://www.electronjs.org/blog/12-week-cadence)).
|
||||
* Since Electron 16, Electron has been releasing major versions on an 8-week cadence in accordance to Chrome's change to a 4-week release cadence ([see blog post](https://www.electronjs.org/blog/8-week-cadence)).
|
||||
|
||||
:::info Chrome release dates
|
||||
|
||||
Chromium has the own public release schedule [here](https://chromiumdash.appspot.com/schedule).
|
||||
|
||||
:::
|
||||
|
||||
## Version support policy
|
||||
|
||||
:::info
|
||||
@@ -72,38 +77,6 @@ and the version prior to that receives the vast majority of those fixes
|
||||
as time and bandwidth warrants. The oldest supported release line will receive
|
||||
only security fixes directly.
|
||||
|
||||
### Chromium version support
|
||||
|
||||
:::info Chromium release schedule
|
||||
|
||||
Chromium's public release schedule is [here](https://chromiumdash.appspot.com/schedule).
|
||||
|
||||
:::
|
||||
|
||||
Electron targets Chromium even-number versions, releasing every 8 weeks in concert
|
||||
with Chromium's 4-week release schedule. For example, Electron 26 uses Chromium 116, while Electron 27 uses Chromium 118.
|
||||
|
||||
### Node.js version support
|
||||
|
||||
Electron upgrades its `main` branch to even-number versions of Node.js when they enter Active LTS. The schedule
|
||||
is as follows:
|
||||
|
||||
<img src="https://raw.githubusercontent.com/nodejs/Release/main/schedule.svg?sanitize=true" alt="Releases">
|
||||
|
||||
As a rule, stable branches of Electron do not receive Node.js upgrades after they have been cut.
|
||||
If Electron has recently updated its `main` branch to a new major version of Node.js, the next stable
|
||||
branch to be cut will be released with the new version.
|
||||
|
||||
Patch upgrades of Node that contain significant security or bug fixes, and are submitted
|
||||
more than 2 weeks prior to a stable release date, will be accepted into an Electron alpha
|
||||
or beta release branch.
|
||||
|
||||
Minor upgrades of Node that contain significant security or bug fixes, and are submitted
|
||||
more than 2 weeks prior to a stable release date may be accepted into an Electron alpha or
|
||||
beta release branch on a case-by-case basis. These requests will be reviewed and voted on
|
||||
by the [Releases Working Group](https://github.com/electron/governance/tree/main/wg-releases),
|
||||
to ensure minimal disruption for developers who may be consuming alpha or beta releases.
|
||||
|
||||
### Breaking API changes
|
||||
|
||||
When an API is changed or removed in a way that breaks existing functionality, the
|
||||
|
||||
@@ -4,48 +4,15 @@ 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
|
||||
@@ -53,11 +20,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
|
||||
|
||||
@@ -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('node:path')
|
||||
const path = require('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('node:path')
|
||||
const path = require('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('node:path')
|
||||
const path = require('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('node:path')
|
||||
const path = require('path')
|
||||
```
|
||||
|
||||
Next, we will proceed to register our application to handle all "`electron-fiddle://`" protocols.
|
||||
|
||||
@@ -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('node:path')
|
||||
const path = require('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('node:path')
|
||||
const path = require('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('node:fs')
|
||||
const fs = require('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('node:fs')
|
||||
const fs = require('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('node:fs')
|
||||
const fs = require('fs')
|
||||
|
||||
class Parser {
|
||||
async getFiles () {
|
||||
|
||||
@@ -228,23 +228,6 @@ 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('node:path')
|
||||
const path = require('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('node:path')
|
||||
const path = require('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('node:fs')
|
||||
const path = require('node:path')
|
||||
const fs = require('fs')
|
||||
const path = require('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('node:os')
|
||||
const os = require('os')
|
||||
|
||||
const createWindow = () => {
|
||||
const win = new BrowserWindow({
|
||||
|
||||
@@ -222,26 +222,14 @@ with CommonJS module syntax:
|
||||
- [app][app], which controls your application's event lifecycle.
|
||||
- [BrowserWindow][browser-window], which creates and manages app windows.
|
||||
|
||||
<details><summary>Module capitalization conventions</summary>
|
||||
:::info Capitalization conventions
|
||||
|
||||
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('node:path')
|
||||
const path = require('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('node:path')
|
||||
const path = require('path')
|
||||
|
||||
const createWindow = () => {
|
||||
const win = new BrowserWindow({
|
||||
|
||||
@@ -184,7 +184,7 @@ allowing events such as `mouseleave` to be emitted:
|
||||
|
||||
```javascript title='main.js'
|
||||
const { BrowserWindow, ipcMain } = require('electron')
|
||||
const path = require('node:path')
|
||||
const path = require('path')
|
||||
|
||||
const win = new BrowserWindow({
|
||||
webPreferences: {
|
||||
|
||||
@@ -126,7 +126,7 @@ following lines:
|
||||
|
||||
```javascript
|
||||
const { BrowserWindow, nativeImage } = require('electron')
|
||||
const path = require('node:path')
|
||||
const path = require('path')
|
||||
|
||||
const win = new BrowserWindow()
|
||||
|
||||
|
||||
@@ -52,7 +52,6 @@ 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",
|
||||
@@ -61,6 +60,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/dev_ui_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",
|
||||
@@ -71,10 +71,10 @@ 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:dev_ui_content_resources",
|
||||
"//content/browser/resources/gpu:resources",
|
||||
"//content/browser/resources/media:resources",
|
||||
"//content/browser/tracing:resources",
|
||||
@@ -176,7 +176,6 @@ 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_",
|
||||
@@ -192,7 +191,6 @@ 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",
|
||||
|
||||
@@ -70,7 +70,6 @@ auto_filenames = {
|
||||
"docs/api/webview-tag.md",
|
||||
"docs/api/window-open.md",
|
||||
"docs/api/structures/bluetooth-device.md",
|
||||
"docs/api/structures/browser-window-options.md",
|
||||
"docs/api/structures/certificate-principal.md",
|
||||
"docs/api/structures/certificate.md",
|
||||
"docs/api/structures/cookie.md",
|
||||
@@ -136,7 +135,6 @@ auto_filenames = {
|
||||
"docs/api/structures/upload-raw-data.md",
|
||||
"docs/api/structures/usb-device.md",
|
||||
"docs/api/structures/user-default-types.md",
|
||||
"docs/api/structures/web-preferences.md",
|
||||
"docs/api/structures/web-request-filter.md",
|
||||
"docs/api/structures/web-source.md",
|
||||
]
|
||||
@@ -197,7 +195,6 @@ auto_filenames = {
|
||||
"lib/browser/api/base-window.ts",
|
||||
"lib/browser/api/browser-view.ts",
|
||||
"lib/browser/api/browser-window.ts",
|
||||
"lib/browser/api/clipboard.ts",
|
||||
"lib/browser/api/content-tracing.ts",
|
||||
"lib/browser/api/crash-reporter.ts",
|
||||
"lib/browser/api/desktop-capturer.ts",
|
||||
@@ -247,6 +244,7 @@ auto_filenames = {
|
||||
"lib/browser/parse-features-string.ts",
|
||||
"lib/browser/rpc-server.ts",
|
||||
"lib/browser/web-view-events.ts",
|
||||
"lib/common/api/clipboard.ts",
|
||||
"lib/common/api/module-list.ts",
|
||||
"lib/common/api/native-image.ts",
|
||||
"lib/common/api/shell.ts",
|
||||
@@ -257,6 +255,8 @@ auto_filenames = {
|
||||
"lib/common/reset-search-paths.ts",
|
||||
"lib/common/web-view-methods.ts",
|
||||
"lib/common/webpack-globals-provider.ts",
|
||||
"lib/renderer/ipc-renderer-internal-utils.ts",
|
||||
"lib/renderer/ipc-renderer-internal.ts",
|
||||
"package.json",
|
||||
"tsconfig.electron.json",
|
||||
"tsconfig.json",
|
||||
@@ -265,6 +265,7 @@ auto_filenames = {
|
||||
]
|
||||
|
||||
renderer_bundle_deps = [
|
||||
"lib/common/api/clipboard.ts",
|
||||
"lib/common/api/module-list.ts",
|
||||
"lib/common/api/native-image.ts",
|
||||
"lib/common/api/shell.ts",
|
||||
@@ -274,7 +275,6 @@ auto_filenames = {
|
||||
"lib/common/reset-search-paths.ts",
|
||||
"lib/common/web-view-methods.ts",
|
||||
"lib/common/webpack-provider.ts",
|
||||
"lib/renderer/api/clipboard.ts",
|
||||
"lib/renderer/api/context-bridge.ts",
|
||||
"lib/renderer/api/crash-reporter.ts",
|
||||
"lib/renderer/api/exports/electron.ts",
|
||||
@@ -303,6 +303,7 @@ auto_filenames = {
|
||||
]
|
||||
|
||||
worker_bundle_deps = [
|
||||
"lib/common/api/clipboard.ts",
|
||||
"lib/common/api/module-list.ts",
|
||||
"lib/common/api/native-image.ts",
|
||||
"lib/common/api/shell.ts",
|
||||
@@ -311,7 +312,6 @@ auto_filenames = {
|
||||
"lib/common/ipc-messages.ts",
|
||||
"lib/common/reset-search-paths.ts",
|
||||
"lib/common/webpack-provider.ts",
|
||||
"lib/renderer/api/clipboard.ts",
|
||||
"lib/renderer/api/context-bridge.ts",
|
||||
"lib/renderer/api/crash-reporter.ts",
|
||||
"lib/renderer/api/exports/electron.ts",
|
||||
|
||||
@@ -129,6 +129,10 @@ 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",
|
||||
@@ -193,8 +197,6 @@ filenames = {
|
||||
"shell/common/language_util_mac.mm",
|
||||
"shell/common/mac/main_application_bundle.h",
|
||||
"shell/common/mac/main_application_bundle.mm",
|
||||
"shell/common/mac/codesign_util.cc",
|
||||
"shell/common/mac/codesign_util.h",
|
||||
"shell/common/node_bindings_mac.cc",
|
||||
"shell/common/node_bindings_mac.h",
|
||||
"shell/common/platform_util_mac.mm",
|
||||
@@ -260,8 +262,6 @@ filenames = {
|
||||
"shell/browser/api/electron_api_data_pipe_holder.h",
|
||||
"shell/browser/api/electron_api_debugger.cc",
|
||||
"shell/browser/api/electron_api_debugger.h",
|
||||
"shell/browser/api/electron_api_desktop_capturer.cc",
|
||||
"shell/browser/api/electron_api_desktop_capturer.h",
|
||||
"shell/browser/api/electron_api_dialog.cc",
|
||||
"shell/browser/api/electron_api_download_item.cc",
|
||||
"shell/browser/api/electron_api_download_item.h",
|
||||
@@ -510,7 +510,6 @@ 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",
|
||||
@@ -692,8 +691,6 @@ filenames = {
|
||||
]
|
||||
|
||||
lib_sources_extensions = [
|
||||
"shell/browser/extensions/api/extension_action/extension_action_api.cc",
|
||||
"shell/browser/extensions/api/extension_action/extension_action_api.h",
|
||||
"shell/browser/extensions/api/management/electron_management_api_delegate.cc",
|
||||
"shell/browser/extensions/api/management/electron_management_api_delegate.h",
|
||||
"shell/browser/extensions/api/resources_private/resources_private_api.cc",
|
||||
|
||||
@@ -70,10 +70,6 @@ libcxx_headers = [
|
||||
"//buildtools/third_party/libc++/trunk/include/__algorithm/partition_point.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__algorithm/pop_heap.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__algorithm/prev_permutation.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__algorithm/pstl_any_all_none_of.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__algorithm/pstl_fill.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__algorithm/pstl_find.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__algorithm/pstl_for_each.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__algorithm/push_heap.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_adjacent_find.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__algorithm/ranges_all_of.h",
|
||||
@@ -227,6 +223,8 @@ libcxx_headers = [
|
||||
"//buildtools/third_party/libc++/trunk/include/__bit/popcount.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__bit/rotate.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__bit_reference",
|
||||
"//buildtools/third_party/libc++/trunk/include/__bsd_locale_defaults.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__bsd_locale_fallbacks.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__charconv/chars_format.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__charconv/from_chars_integral.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__charconv/from_chars_result.h",
|
||||
@@ -361,7 +359,6 @@ libcxx_headers = [
|
||||
"//buildtools/third_party/libc++/trunk/include/__format/range_default_formatter.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__format/range_formatter.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__format/unicode.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__format/width_estimation_table.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__functional/binary_function.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__functional/binary_negate.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__functional/bind.h",
|
||||
@@ -391,17 +388,11 @@ libcxx_headers = [
|
||||
"//buildtools/third_party/libc++/trunk/include/__functional/unwrap_ref.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__functional/weak_result_type.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__fwd/array.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__fwd/fstream.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__fwd/get.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__fwd/hash.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__fwd/ios.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__fwd/istream.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__fwd/memory_resource.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__fwd/ostream.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__fwd/pair.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__fwd/span.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__fwd/sstream.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__fwd/streambuf.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__fwd/string.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__fwd/string_view.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__fwd/subrange.h",
|
||||
@@ -449,9 +440,6 @@ libcxx_headers = [
|
||||
"//buildtools/third_party/libc++/trunk/include/__iterator/unreachable_sentinel.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__iterator/wrap_iter.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__locale",
|
||||
"//buildtools/third_party/libc++/trunk/include/__locale_dir/locale_base_api/bsd_locale_defaults.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__locale_dir/locale_base_api/locale_guard.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__mbstate_t.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__memory/addressof.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__memory/align.h",
|
||||
@@ -506,43 +494,6 @@ libcxx_headers = [
|
||||
"//buildtools/third_party/libc++/trunk/include/__numeric/transform_exclusive_scan.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__numeric/transform_inclusive_scan.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__numeric/transform_reduce.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/algorithm_fwd.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/algorithm_impl.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/execution_defs.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/execution_impl.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/glue_algorithm_defs.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/glue_algorithm_impl.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/glue_memory_defs.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/glue_memory_impl.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/glue_numeric_defs.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/glue_numeric_impl.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/memory_impl.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/numeric_fwd.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/numeric_impl.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/omp/parallel_for.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/omp/parallel_for_each.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/omp/parallel_invoke.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/omp/parallel_merge.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/omp/parallel_reduce.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/omp/parallel_scan.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/omp/parallel_stable_partial_sort.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/omp/parallel_stable_sort.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/omp/parallel_transform_reduce.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/omp/parallel_transform_scan.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/omp/util.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/parallel_backend.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/parallel_backend_omp.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/parallel_backend_serial.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/parallel_backend_tbb.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/parallel_backend_utils.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/parallel_impl.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/pstl_config.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/unseq_backend_simd.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl/internal/utils.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl_algorithm",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl_config_site.in",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl_memory",
|
||||
"//buildtools/third_party/libc++/trunk/include/__pstl_numeric",
|
||||
"//buildtools/third_party/libc++/trunk/include/__random/bernoulli_distribution.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__random/binomial_distribution.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__random/cauchy_distribution.h",
|
||||
@@ -619,7 +570,6 @@ libcxx_headers = [
|
||||
"//buildtools/third_party/libc++/trunk/include/__ranges/views.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__ranges/zip_view.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__split_buffer",
|
||||
"//buildtools/third_party/libc++/trunk/include/__std_mbstate_t.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__string/char_traits.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__string/constexpr_c_functions.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__string/extern_template_lists.h",
|
||||
@@ -648,6 +598,7 @@ libcxx_headers = [
|
||||
"//buildtools/third_party/libc++/trunk/include/__thread/timed_backoff_policy.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__threading_support",
|
||||
"//buildtools/third_party/libc++/trunk/include/__tree",
|
||||
"//buildtools/third_party/libc++/trunk/include/__tuple/apply_cv.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__tuple/make_tuple_types.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__tuple/pair_like.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__tuple/sfinae_helpers.h",
|
||||
@@ -707,7 +658,6 @@ libcxx_headers = [
|
||||
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_empty.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_enum.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_equality_comparable.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_execution_policy.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_final.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_floating_point.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__type_traits/is_function.h",
|
||||
@@ -808,7 +758,6 @@ libcxx_headers = [
|
||||
"//buildtools/third_party/libc++/trunk/include/__utility/priority_tag.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__utility/rel_ops.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__utility/swap.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__utility/terminate_on_exception.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__utility/to_underlying.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__utility/unreachable.h",
|
||||
"//buildtools/third_party/libc++/trunk/include/__variant/monostate.h",
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Buffer } from 'buffer';
|
||||
import { constants } from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as util from 'util';
|
||||
import type * as Crypto from 'crypto';
|
||||
@@ -68,22 +67,18 @@ 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 } = require('fs');
|
||||
const { Stats, constants } = require('fs');
|
||||
|
||||
const mode = constants.S_IROTH | constants.S_IRGRP | constants.S_IRUSR | constants.S_IWUSR | fileTypeToMode.get(stats.type)!;
|
||||
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;
|
||||
}
|
||||
|
||||
return new Stats(
|
||||
1, // dev
|
||||
@@ -246,6 +241,7 @@ 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'));
|
||||
@@ -580,6 +576,7 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||
};
|
||||
|
||||
const { readFile: readFilePromise } = fs.promises;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
fs.promises.readFile = function (pathArgument: string, options: any) {
|
||||
const pathInfo = splitPath(pathArgument);
|
||||
if (!pathInfo.isAsar) {
|
||||
@@ -661,7 +658,13 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||
nextTick(callback!, [error]);
|
||||
return;
|
||||
}
|
||||
dirents.push(new fs.Dirent(file, stats.type));
|
||||
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));
|
||||
}
|
||||
}
|
||||
nextTick(callback!, [null, dirents]);
|
||||
return;
|
||||
@@ -698,7 +701,13 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||
if (!stats) {
|
||||
throw createError(AsarError.NOT_FOUND, { asarPath, filePath: childPath });
|
||||
}
|
||||
dirents.push(new fs.Dirent(file, stats.type));
|
||||
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));
|
||||
}
|
||||
}
|
||||
return dirents;
|
||||
}
|
||||
@@ -749,7 +758,7 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
|
||||
const stats = archive.stat(filePath);
|
||||
if (!stats) return -34;
|
||||
|
||||
return (stats.type === AsarFileType.kDirectory) ? 1 : 0;
|
||||
return (stats.isDirectory) ? 1 : 0;
|
||||
};
|
||||
|
||||
// Calling mkdir for directory inside asar archive should throw ENOTDIR
|
||||
|
||||
@@ -24,6 +24,8 @@ const spawnUpdate = function (args: string[], detached: boolean, callback: Funct
|
||||
// Process spawned, different args: Return with error
|
||||
// No process spawned: Spawn new process
|
||||
if (spawnedProcess && !isSameArgs(args)) {
|
||||
// Disabled for backwards compatibility:
|
||||
// eslint-disable-next-line standard/no-callback-literal
|
||||
return callback(`AutoUpdater process with arguments ${args} is already running`);
|
||||
} else if (!spawnedProcess) {
|
||||
spawnedProcess = spawn(updateExe, args, {
|
||||
@@ -64,6 +66,8 @@ const spawnUpdate = function (args: string[], detached: boolean, callback: Funct
|
||||
|
||||
// Process terminated with error.
|
||||
if (code !== 0) {
|
||||
// Disabled for backwards compatibility:
|
||||
// eslint-disable-next-line standard/no-callback-literal
|
||||
return callback(`Command failed: ${signal ?? code}\n${stderr}`);
|
||||
}
|
||||
|
||||
@@ -89,6 +93,8 @@ export function checkForUpdate (updateURL: string, callback: (error: Error | nul
|
||||
const json = stdout.trim().split('\n').pop();
|
||||
update = (ref = JSON.parse(json!)) != null ? (ref1 = ref.releasesToApply) != null ? typeof ref1.pop === 'function' ? ref1.pop() : undefined : undefined : undefined;
|
||||
} catch {
|
||||
// Disabled for backwards compatibility:
|
||||
// eslint-disable-next-line standard/no-callback-literal
|
||||
return callback(new Error(`Invalid result:\n${stdout}`));
|
||||
}
|
||||
return callback(null, update);
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
const clipboard = process._linkedBinding('electron_common_clipboard');
|
||||
|
||||
export default clipboard;
|
||||
@@ -237,6 +237,8 @@ const messageBox = (sync: boolean, window: BrowserWindow | null, options?: Messa
|
||||
}
|
||||
};
|
||||
|
||||
// eat dirt, eslint
|
||||
/* eslint-disable import/export */
|
||||
export function showOpenDialog(window: BrowserWindow, options: OpenDialogOptions): OpenDialogReturnValue;
|
||||
export function showOpenDialog(options: OpenDialogOptions): OpenDialogReturnValue;
|
||||
export function showOpenDialog (windowOrOptions: BrowserWindow | OpenDialogOptions, maybeOptions?: OpenDialogOptions): OpenDialogReturnValue {
|
||||
|
||||
@@ -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, sourceType, callback } = options;
|
||||
let { window, x, y, positioningItem, callback } = options;
|
||||
|
||||
// no callback passed
|
||||
if (!callback || typeof callback !== 'function') callback = () => {};
|
||||
@@ -78,7 +78,6 @@ 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();
|
||||
@@ -92,7 +91,7 @@ Menu.prototype.popup = function (options = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
this.popupAt(window as unknown as BaseWindow, x, y, positioningItem, sourceType, callback);
|
||||
this.popupAt(window as unknown as BaseWindow, x, y, positioningItem, callback);
|
||||
return { browserWindow: window, x, y, position: positioningItem };
|
||||
};
|
||||
|
||||
|
||||
@@ -7,10 +7,8 @@ export const browserModuleList: ElectronInternal.ModuleEntry[] = [
|
||||
{ name: 'BaseWindow', loader: () => require('./base-window') },
|
||||
{ name: 'BrowserView', loader: () => require('./browser-view') },
|
||||
{ name: 'BrowserWindow', loader: () => require('./browser-window') },
|
||||
{ name: 'clipboard', loader: () => require('./clipboard') },
|
||||
{ name: 'contentTracing', loader: () => require('./content-tracing') },
|
||||
{ name: 'crashReporter', loader: () => require('./crash-reporter') },
|
||||
{ name: 'desktopCapturer', loader: () => require('./desktop-capturer') },
|
||||
{ name: 'dialog', loader: () => require('./dialog') },
|
||||
{ name: 'globalShortcut', loader: () => require('./global-shortcut') },
|
||||
{ name: 'ipcMain', loader: () => require('./ipc-main') },
|
||||
@@ -40,6 +38,12 @@ export const browserModuleList: ElectronInternal.ModuleEntry[] = [
|
||||
{ name: 'webFrameMain', loader: () => require('./web-frame-main') }
|
||||
];
|
||||
|
||||
if (BUILDFLAG(ENABLE_DESKTOP_CAPTURER)) {
|
||||
browserModuleList.push(
|
||||
{ name: 'desktopCapturer', loader: () => require('./desktop-capturer') }
|
||||
);
|
||||
}
|
||||
|
||||
if (BUILDFLAG(ENABLE_VIEWS_API)) {
|
||||
browserModuleList.push(
|
||||
{ name: 'ImageView', loader: () => require('./views/image-view') }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { EventEmitter } from 'events';
|
||||
import { app } from 'electron/main';
|
||||
|
||||
const {
|
||||
createPowerMonitor,
|
||||
@@ -14,26 +15,28 @@ class PowerMonitor extends EventEmitter {
|
||||
// Don't start the event source until both a) the app is ready and b)
|
||||
// there's a listener registered for a powerMonitor event.
|
||||
this.once('newListener', () => {
|
||||
const pm = createPowerMonitor();
|
||||
pm.emit = this.emit.bind(this);
|
||||
app.whenReady().then(() => {
|
||||
const pm = createPowerMonitor();
|
||||
pm.emit = this.emit.bind(this);
|
||||
|
||||
if (process.platform === 'linux') {
|
||||
// On Linux, we inhibit shutdown in order to give the app a chance to
|
||||
// decide whether or not it wants to prevent the shutdown. We don't
|
||||
// inhibit the shutdown event unless there's a listener for it. This
|
||||
// keeps the C++ code informed about whether there are any listeners.
|
||||
pm.setListeningForShutdown(this.listenerCount('shutdown') > 0);
|
||||
this.on('newListener', (event) => {
|
||||
if (event === 'shutdown') {
|
||||
pm.setListeningForShutdown(this.listenerCount('shutdown') + 1 > 0);
|
||||
}
|
||||
});
|
||||
this.on('removeListener', (event) => {
|
||||
if (event === 'shutdown') {
|
||||
pm.setListeningForShutdown(this.listenerCount('shutdown') > 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (process.platform === 'linux') {
|
||||
// On Linux, we inhibit shutdown in order to give the app a chance to
|
||||
// decide whether or not it wants to prevent the shutdown. We don't
|
||||
// inhibit the shutdown event unless there's a listener for it. This
|
||||
// keeps the C++ code informed about whether there are any listeners.
|
||||
pm.setListeningForShutdown(this.listenerCount('shutdown') > 0);
|
||||
this.on('newListener', (event) => {
|
||||
if (event === 'shutdown') {
|
||||
pm.setListeningForShutdown(this.listenerCount('shutdown') + 1 > 0);
|
||||
}
|
||||
});
|
||||
this.on('removeListener', (event) => {
|
||||
if (event === 'shutdown') {
|
||||
pm.setListeningForShutdown(this.listenerCount('shutdown') > 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,31 +1,12 @@
|
||||
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: () => {
|
||||
warnALA();
|
||||
return nativeALAGetter.call(systemPreferences);
|
||||
},
|
||||
set: (appearance) => {
|
||||
warnALA();
|
||||
nativeALASetter.call(systemPreferences, appearance);
|
||||
}
|
||||
get: () => nativeALAGetter.call(systemPreferences),
|
||||
set: (appearance) => nativeALASetter.call(systemPreferences, appearance)
|
||||
});
|
||||
systemPreferences.getAppLevelAppearance = () => {
|
||||
warnALAGetter();
|
||||
return nativeALAGetter.call(systemPreferences);
|
||||
};
|
||||
systemPreferences.setAppLevelAppearance = (appearance) => {
|
||||
warnALASetter();
|
||||
nativeALASetter.call(systemPreferences, appearance);
|
||||
};
|
||||
}
|
||||
|
||||
if ('getEffectiveAppearance' in systemPreferences) {
|
||||
|
||||
@@ -83,50 +83,50 @@ abstract class TouchBarItem<ConfigType> extends EventEmitter {
|
||||
|
||||
class TouchBarButton extends TouchBarItem<Electron.TouchBarButtonConstructorOptions> implements Electron.TouchBarButton {
|
||||
@ImmutableProperty(() => 'button')
|
||||
type!: string;
|
||||
type!: string;
|
||||
|
||||
@LiveProperty<TouchBarButton>(config => config.label)
|
||||
label!: string;
|
||||
label!: string;
|
||||
|
||||
@LiveProperty<TouchBarButton>(config => config.accessibilityLabel)
|
||||
accessibilityLabel!: string;
|
||||
accessibilityLabel!: string;
|
||||
|
||||
@LiveProperty<TouchBarButton>(config => config.backgroundColor)
|
||||
backgroundColor!: string;
|
||||
backgroundColor!: string;
|
||||
|
||||
@LiveProperty<TouchBarButton>(config => config.icon)
|
||||
icon!: Electron.NativeImage;
|
||||
icon!: Electron.NativeImage;
|
||||
|
||||
@LiveProperty<TouchBarButton>(config => config.iconPosition)
|
||||
iconPosition!: Electron.TouchBarButton['iconPosition'];
|
||||
iconPosition!: Electron.TouchBarButton['iconPosition'];
|
||||
|
||||
@LiveProperty<TouchBarButton>(config => typeof config.enabled !== 'boolean' ? true : config.enabled)
|
||||
enabled!: boolean;
|
||||
enabled!: boolean;
|
||||
|
||||
@ImmutableProperty<TouchBarButton>(({ click: onClick }) => typeof onClick === 'function' ? () => onClick() : null)
|
||||
onInteraction!: Function | null;
|
||||
onInteraction!: Function | null;
|
||||
}
|
||||
|
||||
class TouchBarColorPicker extends TouchBarItem<Electron.TouchBarColorPickerConstructorOptions> implements Electron.TouchBarColorPicker {
|
||||
@ImmutableProperty(() => 'colorpicker')
|
||||
type!: string;
|
||||
type!: string;
|
||||
|
||||
@LiveProperty<TouchBarColorPicker>(config => config.availableColors)
|
||||
availableColors!: string[];
|
||||
availableColors!: string[];
|
||||
|
||||
@LiveProperty<TouchBarColorPicker>(config => config.selectedColor)
|
||||
selectedColor!: string;
|
||||
selectedColor!: string;
|
||||
|
||||
@ImmutableProperty<TouchBarColorPicker>(({ change: onChange }, setInternalProp) => typeof onChange === 'function' ? (details: { color: string }) => {
|
||||
setInternalProp('selectedColor', details.color);
|
||||
onChange(details.color);
|
||||
} : null)
|
||||
onInteraction!: Function | null;
|
||||
onInteraction!: Function | null;
|
||||
}
|
||||
|
||||
class TouchBarGroup extends TouchBarItem<Electron.TouchBarGroupConstructorOptions> implements Electron.TouchBarGroup {
|
||||
@ImmutableProperty(() => 'group')
|
||||
type!: string;
|
||||
type!: string;
|
||||
|
||||
@LiveProperty<TouchBarGroup>(config => config.items instanceof TouchBar ? config.items : new TouchBar(config.items), (self, newChild: TouchBar) => {
|
||||
if (self.child) {
|
||||
@@ -138,39 +138,39 @@ class TouchBarGroup extends TouchBarItem<Electron.TouchBarGroupConstructorOption
|
||||
item._addParent(self);
|
||||
}
|
||||
})
|
||||
child!: TouchBar;
|
||||
child!: TouchBar;
|
||||
|
||||
onInteraction = null;
|
||||
}
|
||||
|
||||
class TouchBarLabel extends TouchBarItem<Electron.TouchBarLabelConstructorOptions> implements Electron.TouchBarLabel {
|
||||
@ImmutableProperty(() => 'label')
|
||||
type!: string;
|
||||
type!: string;
|
||||
|
||||
@LiveProperty<TouchBarLabel>(config => config.label)
|
||||
label!: string;
|
||||
label!: string;
|
||||
|
||||
@LiveProperty<TouchBarLabel>(config => config.accessibilityLabel)
|
||||
accessibilityLabel!: string;
|
||||
accessibilityLabel!: string;
|
||||
|
||||
@LiveProperty<TouchBarLabel>(config => config.textColor)
|
||||
textColor!: string;
|
||||
textColor!: string;
|
||||
|
||||
onInteraction = null;
|
||||
}
|
||||
|
||||
class TouchBarPopover extends TouchBarItem<Electron.TouchBarPopoverConstructorOptions> implements Electron.TouchBarPopover {
|
||||
@ImmutableProperty(() => 'popover')
|
||||
type!: string;
|
||||
type!: string;
|
||||
|
||||
@LiveProperty<TouchBarPopover>(config => config.label)
|
||||
label!: string;
|
||||
label!: string;
|
||||
|
||||
@LiveProperty<TouchBarPopover>(config => config.icon)
|
||||
icon!: Electron.NativeImage;
|
||||
icon!: Electron.NativeImage;
|
||||
|
||||
@LiveProperty<TouchBarPopover>(config => config.showCloseButton)
|
||||
showCloseButton!: boolean;
|
||||
showCloseButton!: boolean;
|
||||
|
||||
@LiveProperty<TouchBarPopover>(config => config.items instanceof TouchBar ? config.items : new TouchBar(config.items), (self, newChild: TouchBar) => {
|
||||
if (self.child) {
|
||||
@@ -182,88 +182,88 @@ class TouchBarPopover extends TouchBarItem<Electron.TouchBarPopoverConstructorOp
|
||||
item._addParent(self);
|
||||
}
|
||||
})
|
||||
child!: TouchBar;
|
||||
child!: TouchBar;
|
||||
|
||||
onInteraction = null;
|
||||
}
|
||||
|
||||
class TouchBarSlider extends TouchBarItem<Electron.TouchBarSliderConstructorOptions> implements Electron.TouchBarSlider {
|
||||
@ImmutableProperty(() => 'slider')
|
||||
type!: string;
|
||||
type!: string;
|
||||
|
||||
@LiveProperty<TouchBarSlider>(config => config.label)
|
||||
label!: string;
|
||||
label!: string;
|
||||
|
||||
@LiveProperty<TouchBarSlider>(config => config.minValue)
|
||||
minValue!: number;
|
||||
minValue!: number;
|
||||
|
||||
@LiveProperty<TouchBarSlider>(config => config.maxValue)
|
||||
maxValue!: number;
|
||||
maxValue!: number;
|
||||
|
||||
@LiveProperty<TouchBarSlider>(config => config.value)
|
||||
value!: number;
|
||||
value!: number;
|
||||
|
||||
@ImmutableProperty<TouchBarSlider>(({ change: onChange }, setInternalProp) => typeof onChange === 'function' ? (details: { value: number }) => {
|
||||
setInternalProp('value', details.value);
|
||||
onChange(details.value);
|
||||
} : null)
|
||||
onInteraction!: Function | null;
|
||||
onInteraction!: Function | null;
|
||||
}
|
||||
|
||||
class TouchBarSpacer extends TouchBarItem<Electron.TouchBarSpacerConstructorOptions> implements Electron.TouchBarSpacer {
|
||||
@ImmutableProperty(() => 'spacer')
|
||||
type!: string;
|
||||
type!: string;
|
||||
|
||||
@ImmutableProperty<TouchBarSpacer>(config => config.size)
|
||||
size!: Electron.TouchBarSpacer['size'];
|
||||
size!: Electron.TouchBarSpacer['size'];
|
||||
|
||||
onInteraction = null;
|
||||
}
|
||||
|
||||
class TouchBarSegmentedControl extends TouchBarItem<Electron.TouchBarSegmentedControlConstructorOptions> implements Electron.TouchBarSegmentedControl {
|
||||
@ImmutableProperty(() => 'segmented_control')
|
||||
type!: string;
|
||||
type!: string;
|
||||
|
||||
@LiveProperty<TouchBarSegmentedControl>(config => config.segmentStyle)
|
||||
segmentStyle!: Electron.TouchBarSegmentedControl['segmentStyle'];
|
||||
segmentStyle!: Electron.TouchBarSegmentedControl['segmentStyle'];
|
||||
|
||||
@LiveProperty<TouchBarSegmentedControl>(config => config.segments || [])
|
||||
segments!: Electron.SegmentedControlSegment[];
|
||||
segments!: Electron.SegmentedControlSegment[];
|
||||
|
||||
@LiveProperty<TouchBarSegmentedControl>(config => config.selectedIndex)
|
||||
selectedIndex!: number;
|
||||
selectedIndex!: number;
|
||||
|
||||
@LiveProperty<TouchBarSegmentedControl>(config => config.mode)
|
||||
mode!: Electron.TouchBarSegmentedControl['mode'];
|
||||
mode!: Electron.TouchBarSegmentedControl['mode'];
|
||||
|
||||
@ImmutableProperty<TouchBarSegmentedControl>(({ change: onChange }, setInternalProp) => typeof onChange === 'function' ? (details: { selectedIndex: number, isSelected: boolean }) => {
|
||||
setInternalProp('selectedIndex', details.selectedIndex);
|
||||
onChange(details.selectedIndex, details.isSelected);
|
||||
} : null)
|
||||
onInteraction!: Function | null;
|
||||
onInteraction!: Function | null;
|
||||
}
|
||||
|
||||
class TouchBarScrubber extends TouchBarItem<Electron.TouchBarScrubberConstructorOptions> implements Electron.TouchBarScrubber {
|
||||
@ImmutableProperty(() => 'scrubber')
|
||||
type!: string;
|
||||
type!: string;
|
||||
|
||||
@LiveProperty<TouchBarScrubber>(config => config.items)
|
||||
items!: Electron.ScrubberItem[];
|
||||
items!: Electron.ScrubberItem[];
|
||||
|
||||
@LiveProperty<TouchBarScrubber>(config => config.selectedStyle || null)
|
||||
selectedStyle!: Electron.TouchBarScrubber['selectedStyle'];
|
||||
selectedStyle!: Electron.TouchBarScrubber['selectedStyle'];
|
||||
|
||||
@LiveProperty<TouchBarScrubber>(config => config.overlayStyle || null)
|
||||
overlayStyle!: Electron.TouchBarScrubber['overlayStyle'];
|
||||
overlayStyle!: Electron.TouchBarScrubber['overlayStyle'];
|
||||
|
||||
@LiveProperty<TouchBarScrubber>(config => config.showArrowButtons || false)
|
||||
showArrowButtons!: boolean;
|
||||
showArrowButtons!: boolean;
|
||||
|
||||
@LiveProperty<TouchBarScrubber>(config => config.mode || 'free')
|
||||
mode!: Electron.TouchBarScrubber['mode'];
|
||||
mode!: Electron.TouchBarScrubber['mode'];
|
||||
|
||||
@LiveProperty<TouchBarScrubber>(config => typeof config.continuous === 'undefined' ? true : config.continuous)
|
||||
continuous!: boolean;
|
||||
continuous!: boolean;
|
||||
|
||||
@ImmutableProperty<TouchBarScrubber>(({ select: onSelect, highlight: onHighlight }) => typeof onSelect === 'function' || typeof onHighlight === 'function' ? (details: { type: 'select'; selectedIndex: number } | { type: 'highlight'; highlightedIndex: number }) => {
|
||||
if (details.type === 'select') {
|
||||
@@ -272,7 +272,7 @@ class TouchBarScrubber extends TouchBarItem<Electron.TouchBarScrubberConstructor
|
||||
if (onHighlight) onHighlight(details.highlightedIndex);
|
||||
}
|
||||
} : null)
|
||||
onInteraction!: Function | null;
|
||||
onInteraction!: Function | null;
|
||||
}
|
||||
|
||||
class TouchBarOtherItemsProxy extends TouchBarItem<null> implements Electron.TouchBarOtherItemsProxy {
|
||||
|
||||
@@ -14,8 +14,8 @@ import * as deprecate from '@electron/internal/common/deprecate';
|
||||
|
||||
// session is not used here, the purpose is to make sure session is initialized
|
||||
// before the webContents module.
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
session;
|
||||
// eslint-disable-next-line
|
||||
session
|
||||
|
||||
const webFrameMainBinding = process._linkedBinding('electron_browser_web_frame_main');
|
||||
|
||||
|
||||
@@ -96,6 +96,7 @@ const createGuest = function (embedder: Electron.WebContents, embedderFrameId: n
|
||||
return -1;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
const guest = (webContents as typeof ElectronInternal.WebContents).create({
|
||||
...webPreferences,
|
||||
type: 'webview',
|
||||
|
||||
@@ -19,14 +19,14 @@ export class IpcMainImpl extends EventEmitter {
|
||||
throw new Error(`Expected handler to be a function, but found type '${typeof fn}'`);
|
||||
}
|
||||
this._invokeHandlers.set(method, fn);
|
||||
};
|
||||
}
|
||||
|
||||
handleOnce: Electron.IpcMain['handleOnce'] = (method, fn) => {
|
||||
this.handle(method, (e, ...args) => {
|
||||
this.removeHandler(method);
|
||||
return fn(e, ...args);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
removeHandler (method: string) {
|
||||
this._invokeHandlers.delete(method);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { EventEmitter } from 'events';
|
||||
|
||||
export class MessagePortMain extends EventEmitter {
|
||||
_internalPort: any;
|
||||
_internalPort: any
|
||||
constructor (internalPort: any) {
|
||||
super();
|
||||
this._internalPort = internalPort;
|
||||
|
||||
27
lib/common/api/clipboard.ts
Normal file
27
lib/common/api/clipboard.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';
|
||||
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
import type * as ipcRendererUtilsModule from '@electron/internal/renderer/ipc-renderer-internal-utils';
|
||||
|
||||
const clipboard = process._linkedBinding('electron_common_clipboard');
|
||||
|
||||
if (process.type === 'renderer') {
|
||||
const ipcRendererUtils = require('@electron/internal/renderer/ipc-renderer-internal-utils') as typeof ipcRendererUtilsModule;
|
||||
|
||||
const makeRemoteMethod = function (method: keyof Electron.Clipboard): any {
|
||||
return (...args: any[]) => ipcRendererUtils.invokeSync(IPC_MESSAGES.BROWSER_CLIPBOARD_SYNC, method, ...args);
|
||||
};
|
||||
|
||||
if (process.platform === 'linux') {
|
||||
// On Linux we could not access clipboard in renderer process.
|
||||
for (const method of Object.keys(clipboard) as (keyof Electron.Clipboard)[]) {
|
||||
clipboard[method] = makeRemoteMethod(method);
|
||||
}
|
||||
} else if (process.platform === 'darwin') {
|
||||
// Read/write to find pasteboard over IPC since only main process is notified of changes
|
||||
clipboard.readFindText = makeRemoteMethod('readFindText');
|
||||
clipboard.writeFindText = makeRemoteMethod('writeFindText');
|
||||
}
|
||||
}
|
||||
|
||||
export default clipboard;
|
||||
@@ -1,5 +1,6 @@
|
||||
// Common modules, please sort alphabetically
|
||||
export const commonModuleList: ElectronInternal.ModuleEntry[] = [
|
||||
{ name: 'clipboard', loader: () => require('./clipboard') },
|
||||
{ name: 'nativeImage', loader: () => require('./native-image') },
|
||||
{ name: 'shell', loader: () => require('./shell') }
|
||||
];
|
||||
|
||||
@@ -84,8 +84,7 @@ export function event (emitter: NodeJS.EventEmitter, oldName: string, newName: s
|
||||
// remove a property with no replacement
|
||||
export function removeProperty<T, K extends (keyof T & string)>(object: T, removedName: K, onlyForValues?: any[]): T {
|
||||
// if the property's already been removed, warn about it
|
||||
// eslint-disable-next-line no-proto
|
||||
const info = Object.getOwnPropertyDescriptor((object as any).__proto__, removedName);
|
||||
const info = Object.getOwnPropertyDescriptor((object as any).__proto__, removedName) // eslint-disable-line
|
||||
if (!info) {
|
||||
log(`Unable to remove property '${removedName}' from an object that lacks it.`);
|
||||
return object;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import type * as webViewElementModule from '@electron/internal/renderer/web-view/web-view-element';
|
||||
import type { WebViewImplHooks } from '@electron/internal/renderer/web-view/web-view-impl';
|
||||
/* global isolatedApi */
|
||||
|
||||
declare const isolatedApi: WebViewImplHooks;
|
||||
import type * as webViewElementModule from '@electron/internal/renderer/web-view/web-view-element';
|
||||
|
||||
if (isolatedApi.guestViewInternal) {
|
||||
// Must setup the WebView element in main world.
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';
|
||||
import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils';
|
||||
|
||||
const clipboard = process._linkedBinding('electron_common_clipboard');
|
||||
|
||||
const makeRemoteMethod = function (method: keyof Electron.Clipboard): any {
|
||||
return (...args: any[]) => ipcRendererUtils.invokeSync(IPC_MESSAGES.BROWSER_CLIPBOARD_SYNC, method, ...args);
|
||||
};
|
||||
|
||||
if (process.platform === 'linux') {
|
||||
// On Linux we could not access clipboard in renderer process.
|
||||
for (const method of Object.keys(clipboard) as (keyof Electron.Clipboard)[]) {
|
||||
clipboard[method] = makeRemoteMethod(method);
|
||||
}
|
||||
} else if (process.platform === 'darwin') {
|
||||
// Read/write to find pasteboard over IPC since only main process is notified of changes
|
||||
clipboard.readFindText = makeRemoteMethod('readFindText');
|
||||
clipboard.writeFindText = makeRemoteMethod('writeFindText');
|
||||
}
|
||||
|
||||
export default clipboard;
|
||||
@@ -1,6 +1,5 @@
|
||||
// Renderer side modules, please sort alphabetically.
|
||||
export const rendererModuleList: ElectronInternal.ModuleEntry[] = [
|
||||
{ name: 'clipboard', loader: () => require('./clipboard') },
|
||||
{ name: 'contextBridge', loader: () => require('./context-bridge') },
|
||||
{ name: 'crashReporter', loader: () => require('./crash-reporter') },
|
||||
{ name: 'ipcRenderer', loader: () => require('./ipc-renderer') },
|
||||
|
||||
@@ -57,7 +57,7 @@ require('@electron/internal/renderer/common-init');
|
||||
|
||||
if (nodeIntegration) {
|
||||
// Export node bindings to global.
|
||||
const { makeRequireFunction } = __non_webpack_require__('internal/modules/cjs/helpers');
|
||||
const { makeRequireFunction } = __non_webpack_require__('internal/modules/cjs/helpers') // eslint-disable-line
|
||||
global.module = new Module('electron/js2c/renderer_init');
|
||||
global.require = makeRequireFunction(global.module);
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ export class WebViewAttribute implements MutationHandler {
|
||||
}
|
||||
|
||||
// Called when the attribute's value changes.
|
||||
public handleMutation: MutationHandler['handleMutation'] = () => undefined;
|
||||
public handleMutation: MutationHandler['handleMutation'] = () => undefined
|
||||
}
|
||||
|
||||
// An attribute that is treated as a Boolean.
|
||||
@@ -73,7 +73,7 @@ class BooleanAttribute extends WebViewAttribute {
|
||||
|
||||
// Attribute representing the state of the storage partition.
|
||||
export class PartitionAttribute extends WebViewAttribute {
|
||||
public validPartitionId = true;
|
||||
public validPartitionId = true
|
||||
|
||||
constructor (public webViewImpl: WebViewImpl) {
|
||||
super(WEB_VIEW_ATTRIBUTES.PARTITION, webViewImpl);
|
||||
@@ -92,7 +92,7 @@ export class PartitionAttribute extends WebViewAttribute {
|
||||
this.validPartitionId = false;
|
||||
console.error(WEB_VIEW_ERROR_MESSAGES.INVALID_PARTITION_ATTRIBUTE);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Attribute that handles the location and navigation of the webview.
|
||||
@@ -134,7 +134,7 @@ export class SrcAttribute extends WebViewAttribute {
|
||||
return;
|
||||
}
|
||||
this.parse();
|
||||
};
|
||||
}
|
||||
|
||||
// The purpose of this mutation observer is to catch assignment to the src
|
||||
// attribute without any changes to its value. This is useful in the case
|
||||
|
||||
@@ -86,7 +86,9 @@ const defineWebViewElement = (hooks: WebViewImplHooks) => {
|
||||
|
||||
// Register <webview> custom element.
|
||||
const registerWebViewElement = (hooks: WebViewImplHooks) => {
|
||||
const WebViewElement = defineWebViewElement(hooks) as unknown as typeof ElectronInternal.WebViewElement;
|
||||
// I wish eslint wasn't so stupid, but it is
|
||||
// eslint-disable-next-line
|
||||
const WebViewElement = defineWebViewElement(hooks) as unknown as typeof ElectronInternal.WebViewElement
|
||||
|
||||
setupMethods(WebViewElement, hooks);
|
||||
|
||||
|
||||
@@ -19,16 +19,16 @@ export interface WebViewImplHooks {
|
||||
|
||||
// Represents the internal state of the WebView node.
|
||||
export class WebViewImpl {
|
||||
public beforeFirstNavigation = true;
|
||||
public elementAttached = false;
|
||||
public guestInstanceId?: number;
|
||||
public hasFocus = false;
|
||||
public beforeFirstNavigation = true
|
||||
public elementAttached = false
|
||||
public guestInstanceId?: number
|
||||
public hasFocus = false
|
||||
public internalInstanceId?: number;
|
||||
public viewInstanceId: number;
|
||||
public viewInstanceId: number
|
||||
|
||||
// on* Event handlers.
|
||||
public on: Record<string, any> = {};
|
||||
public internalElement: HTMLIFrameElement;
|
||||
public on: Record<string, any> = {}
|
||||
public internalElement: HTMLIFrameElement
|
||||
|
||||
public attributes: Map<string, WebViewAttribute>;
|
||||
|
||||
@@ -197,6 +197,8 @@ export class WebViewImpl {
|
||||
}
|
||||
}
|
||||
|
||||
// I wish eslint wasn't so stupid, but it is
|
||||
// eslint-disable-next-line
|
||||
export const setupMethods = (WebViewElement: typeof ElectronInternal.WebViewElement, hooks: WebViewImplHooks) => {
|
||||
// Focusing the webview should move page focus to the underlying iframe.
|
||||
WebViewElement.prototype.focus = function () {
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
/* global binding */
|
||||
import * as events from 'events';
|
||||
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';
|
||||
|
||||
import type * as ipcRendererUtilsModule from '@electron/internal/renderer/ipc-renderer-internal-utils';
|
||||
import type * as ipcRendererInternalModule from '@electron/internal/renderer/ipc-renderer-internal';
|
||||
|
||||
declare const binding: {
|
||||
get: (name: string) => any;
|
||||
process: NodeJS.Process;
|
||||
createPreloadScript: (src: string) => Function
|
||||
};
|
||||
|
||||
const { EventEmitter } = events;
|
||||
|
||||
process._linkedBinding = binding.get;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { MessagePortMain } from '@electron/internal/browser/message-port-main';
|
||||
const { createParentPort } = process._linkedBinding('electron_utility_parent_port');
|
||||
|
||||
export class ParentPort extends EventEmitter {
|
||||
#port: ParentPort;
|
||||
#port: ParentPort
|
||||
constructor () {
|
||||
super();
|
||||
this.#port = createParentPort();
|
||||
|
||||
@@ -16,7 +16,7 @@ require('@electron/internal/common/init');
|
||||
const { hasSwitch, getSwitchValue } = process._linkedBinding('electron_common_command_line');
|
||||
|
||||
// Export node bindings to global.
|
||||
const { makeRequireFunction } = __non_webpack_require__('internal/modules/cjs/helpers');
|
||||
const { makeRequireFunction } = __non_webpack_require__('internal/modules/cjs/helpers') // eslint-disable-line
|
||||
global.module = new Module('electron/js2c/worker_init');
|
||||
global.require = makeRequireFunction(global.module);
|
||||
|
||||
|
||||
16
package.json
16
package.json
@@ -6,11 +6,11 @@
|
||||
"devDependencies": {
|
||||
"@azure/storage-blob": "^12.9.0",
|
||||
"@electron/asar": "^3.2.1",
|
||||
"@electron/docs-parser": "^1.1.1",
|
||||
"@electron/docs-parser": "^1.1.0",
|
||||
"@electron/fiddle-core": "^1.0.4",
|
||||
"@electron/github-app-auth": "^2.0.0",
|
||||
"@electron/lint-roller": "^1.5.0",
|
||||
"@electron/typescript-definitions": "^8.14.5",
|
||||
"@electron/typescript-definitions": "^8.14.0",
|
||||
"@octokit/rest": "^19.0.7",
|
||||
"@primer/octicons": "^10.0.0",
|
||||
"@types/basic-auth": "^1.1.3",
|
||||
@@ -33,20 +33,22 @@
|
||||
"@types/w3c-web-serial": "^1.0.3",
|
||||
"@types/webpack": "^5.28.0",
|
||||
"@types/webpack-env": "^1.17.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.7",
|
||||
"@typescript-eslint/parser": "^5.59.7",
|
||||
"@typescript-eslint/eslint-plugin": "^4.4.1",
|
||||
"@typescript-eslint/parser": "^4.4.1",
|
||||
"aws-sdk": "^2.814.0",
|
||||
"buffer": "^6.0.3",
|
||||
"check-for-leaks": "^1.2.1",
|
||||
"colors": "1.4.0",
|
||||
"dotenv-safe": "^4.0.4",
|
||||
"dugite": "^2.3.0",
|
||||
"eslint": "^8.41.0",
|
||||
"eslint": "^7.4.0",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-import": "^2.22.0",
|
||||
"eslint-plugin-mocha": "^7.0.1",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"eslint-plugin-typescript": "^0.14.0",
|
||||
"events": "^3.2.0",
|
||||
"express": "^4.16.4",
|
||||
"folder-hash": "^2.1.1",
|
||||
@@ -71,7 +73,6 @@
|
||||
"ts-loader": "^8.0.2",
|
||||
"ts-node": "6.2.0",
|
||||
"typescript": "^4.5.5",
|
||||
"url": "^0.11.0",
|
||||
"webpack": "^5.76.0",
|
||||
"webpack-cli": "^4.10.0",
|
||||
"wrapper-webpack-plugin": "^2.2.0"
|
||||
@@ -102,7 +103,6 @@
|
||||
"gn-format": "python3 script/run-gn-format.py",
|
||||
"precommit": "lint-staged",
|
||||
"preinstall": "node -e 'process.exit(0)'",
|
||||
"pretest": "npm run create-typescript-definitions",
|
||||
"prepack": "check-for-leaks",
|
||||
"prepare": "husky install",
|
||||
"repl": "node ./script/start.js --interactive",
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
m120_translator_optimize_field-name-collision_check.patch
|
||||
m120_translator_fail_compilation_if_too_many_struct_fields.patch
|
||||
m120_translator_limit_private_variable_size_to_64kb.patch
|
||||
m120_vulkan_don_t_crash_when_glcopyteximage2d_redefines_itself.patch
|
||||
cherry-pick-d0ee0197ddff.patch
|
||||
cherry-pick-285c7712c506.patch
|
||||
cherry-pick-2bf945775fe6.patch
|
||||
cherry-pick-cafe56b591ed.patch
|
||||
cherry-pick-5486190be556.patch
|
||||
cherry-pick-e4669a74888d.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
|
||||
42
patches/angle/cherry-pick-5486190be556.patch
Normal file
42
patches/angle/cherry-pick-5486190be556.patch
Normal file
@@ -0,0 +1,42 @@
|
||||
From 5486190be5565f9b5567fbd252a10425af3d59ee Mon Sep 17 00:00:00 2001
|
||||
From: Geoff Lang <geofflang@chromium.org>
|
||||
Date: Fri, 21 Jul 2023 13:45:52 -0400
|
||||
Subject: [PATCH] [M114-LTS] Fix read size validation for RGBX formats.
|
||||
|
||||
GL_RGBX8_ANGLE is the only format where the upload format is 3-channel
|
||||
RGB, whilethe download format is 4-channel RGBX. As such, the internal
|
||||
format corresponding to format+type expects 3-byte input/output. The
|
||||
format is fixed here for readPixels to output 4 bytes per pixel.
|
||||
|
||||
Bug: chromium:1458046
|
||||
Change-Id: Iec737ed64bade003cfab50dc5f595eb4875e81e4
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4706957
|
||||
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
(cherry picked from commit 430a4f559cbc2bcd5d026e8b36ee46ddd80e9651)
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4765136
|
||||
Commit-Queue: Daniel Yip <danielyip@google.com>
|
||||
Auto-Submit: Daniel Yip <danielyip@google.com>
|
||||
(cherry picked from commit 4a372ad49ceddea6c13f79adb212a777ec770a66)
|
||||
---
|
||||
|
||||
diff --git a/src/libANGLE/formatutils.cpp b/src/libANGLE/formatutils.cpp
|
||||
index f2845dc..bb1389aaa 100644
|
||||
--- a/src/libANGLE/formatutils.cpp
|
||||
+++ b/src/libANGLE/formatutils.cpp
|
||||
@@ -1702,7 +1702,15 @@
|
||||
GLuint InternalFormat::computePixelBytes(GLenum formatType) const
|
||||
{
|
||||
const auto &typeInfo = GetTypeInfo(formatType);
|
||||
- GLuint components = typeInfo.specialInterpretation ? 1u : componentCount;
|
||||
+ GLuint components = componentCount;
|
||||
+ if (sizedInternalFormat == GL_RGBX8_ANGLE)
|
||||
+ {
|
||||
+ components = 4;
|
||||
+ }
|
||||
+ else if (typeInfo.specialInterpretation)
|
||||
+ {
|
||||
+ components = 1;
|
||||
+ }
|
||||
return components * typeInfo.bytes;
|
||||
}
|
||||
|
||||
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,
|
||||
208
patches/angle/cherry-pick-d0ee0197ddff.patch
Normal file
208
patches/angle/cherry-pick-d0ee0197ddff.patch
Normal file
@@ -0,0 +1,208 @@
|
||||
From d0ee0197ddff25fe1a9876511c07542ac483702d Mon Sep 17 00:00:00 2001
|
||||
From: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
Date: Wed, 03 May 2023 13:41:36 -0400
|
||||
Subject: [PATCH] WebGL: Limit total size of private data
|
||||
|
||||
... not just individual arrays.
|
||||
|
||||
Bug: chromium:1431761
|
||||
Change-Id: I721e29aeceeaf12c3f6a67b668abffb8dfbc89b0
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4503753
|
||||
Reviewed-by: Kenneth Russell <kbr@chromium.org>
|
||||
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
---
|
||||
|
||||
diff --git a/src/compiler/translator/ValidateTypeSizeLimitations.cpp b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
|
||||
index 6097b6d..2a033ad 100644
|
||||
--- a/src/compiler/translator/ValidateTypeSizeLimitations.cpp
|
||||
+++ b/src/compiler/translator/ValidateTypeSizeLimitations.cpp
|
||||
@@ -35,7 +35,9 @@
|
||||
{
|
||||
public:
|
||||
ValidateTypeSizeLimitationsTraverser(TSymbolTable *symbolTable, TDiagnostics *diagnostics)
|
||||
- : TIntermTraverser(true, false, false, symbolTable), mDiagnostics(diagnostics)
|
||||
+ : TIntermTraverser(true, false, false, symbolTable),
|
||||
+ mDiagnostics(diagnostics),
|
||||
+ mTotalPrivateVariablesSize(0)
|
||||
{
|
||||
ASSERT(diagnostics);
|
||||
}
|
||||
@@ -93,18 +95,33 @@
|
||||
const bool isPrivate = variableType.getQualifier() == EvqTemporary ||
|
||||
variableType.getQualifier() == EvqGlobal ||
|
||||
variableType.getQualifier() == EvqConst;
|
||||
- if (layoutEncoder.getCurrentOffset() > kMaxPrivateVariableSizeInBytes && isPrivate)
|
||||
+ if (isPrivate)
|
||||
{
|
||||
- error(asSymbol->getLine(),
|
||||
- "Size of declared private variable exceeds implementation-defined limit",
|
||||
- asSymbol->getName());
|
||||
- return false;
|
||||
+ if (layoutEncoder.getCurrentOffset() > kMaxPrivateVariableSizeInBytes)
|
||||
+ {
|
||||
+ error(asSymbol->getLine(),
|
||||
+ "Size of declared private variable exceeds implementation-defined limit",
|
||||
+ asSymbol->getName());
|
||||
+ return false;
|
||||
+ }
|
||||
+ mTotalPrivateVariablesSize += layoutEncoder.getCurrentOffset();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+ void validateTotalPrivateVariableSize()
|
||||
+ {
|
||||
+ if (mTotalPrivateVariablesSize > kMaxPrivateVariableSizeInBytes)
|
||||
+ {
|
||||
+ mDiagnostics->error(
|
||||
+ TSourceLoc{},
|
||||
+ "Total size of declared private variables exceeds implementation-defined limit",
|
||||
+ "");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
private:
|
||||
void error(TSourceLoc loc, const char *reason, const ImmutableString &token)
|
||||
{
|
||||
@@ -213,6 +230,8 @@
|
||||
|
||||
TDiagnostics *mDiagnostics;
|
||||
std::vector<int> mLoopSymbolIds;
|
||||
+
|
||||
+ size_t mTotalPrivateVariablesSize;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -223,6 +242,7 @@
|
||||
{
|
||||
ValidateTypeSizeLimitationsTraverser validate(symbolTable, diagnostics);
|
||||
root->traverse(&validate);
|
||||
+ validate.validateTotalPrivateVariableSize();
|
||||
return diagnostics->numErrors() == 0;
|
||||
}
|
||||
|
||||
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
|
||||
index e62c8fb..996bad1 100644
|
||||
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
|
||||
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
|
||||
@@ -5271,11 +5271,12 @@
|
||||
// fairly small array.
|
||||
constexpr char kVSArrayOK[] =
|
||||
R"(varying vec4 color;
|
||||
-const int array_size = 1000;
|
||||
+const int array_size = 500;
|
||||
void main()
|
||||
{
|
||||
mat2 array[array_size];
|
||||
- if (array[0][0][0] == 2.0)
|
||||
+ mat2 array2[array_size];
|
||||
+ if (array[0][0][0] + array2[0][0][0] == 2.0)
|
||||
color = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
else
|
||||
color = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
@@ -5353,6 +5354,103 @@
|
||||
EXPECT_EQ(0u, program);
|
||||
}
|
||||
|
||||
+// Reject attempts to allocate too much private memory.
|
||||
+// This is an implementation-defined limit - crbug.com/1431761.
|
||||
+TEST_P(WebGLCompatibilityTest, ValidateTotalPrivateSize)
|
||||
+{
|
||||
+ constexpr char kTooLargeGlobalMemory1[] =
|
||||
+ R"(precision mediump float;
|
||||
+
|
||||
+// 1 MB / 16 bytes per vec4 = 65536
|
||||
+vec4 array[32768];
|
||||
+vec4 array2[32769];
|
||||
+
|
||||
+void main()
|
||||
+{
|
||||
+ if (array[0].x + array[1].x == 0.)
|
||||
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
+ else
|
||||
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
+})";
|
||||
+
|
||||
+ constexpr char kTooLargeGlobalMemory2[] =
|
||||
+ R"(precision mediump float;
|
||||
+
|
||||
+// 1 MB / 16 bytes per vec4 = 65536
|
||||
+vec4 array[32767];
|
||||
+vec4 array2[32767];
|
||||
+vec4 x, y, z;
|
||||
+
|
||||
+void main()
|
||||
+{
|
||||
+ if (array[0].x + array[1].x == x.w + y.w + z.w)
|
||||
+ gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
+ else
|
||||
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
+})";
|
||||
+
|
||||
+ constexpr char kTooLargeGlobalAndLocalMemory1[] =
|
||||
+ R"(precision mediump float;
|
||||
+
|
||||
+// 1 MB / 16 bytes per vec4 = 65536
|
||||
+vec4 array[32768];
|
||||
+
|
||||
+void main()
|
||||
+{
|
||||
+ vec4 array2[32769];
|
||||
+ if (array[0].x + array[1].x == 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);
|
||||
+})";
|
||||
+
|
||||
+ // Note: The call stack is not taken into account for the purposes of total memory calculation.
|
||||
+ constexpr char kTooLargeGlobalAndLocalMemory2[] =
|
||||
+ R"(precision mediump float;
|
||||
+
|
||||
+// 1 MB / 16 bytes per vec4 = 65536
|
||||
+vec4 array[32768];
|
||||
+
|
||||
+float f()
|
||||
+{
|
||||
+ vec4 array2[16384];
|
||||
+ return array2[0].x;
|
||||
+}
|
||||
+
|
||||
+float g()
|
||||
+{
|
||||
+ vec4 array3[16383];
|
||||
+ return array3[0].x;
|
||||
+}
|
||||
+
|
||||
+float h()
|
||||
+{
|
||||
+ vec4 value;
|
||||
+ float value2
|
||||
+ return value.x + value2;
|
||||
+}
|
||||
+
|
||||
+void main()
|
||||
+{
|
||||
+ if (array[0].x + f() + g() + h() == 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);
|
||||
+
|
||||
+ program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalMemory2);
|
||||
+ EXPECT_EQ(0u, program);
|
||||
+
|
||||
+ program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalAndLocalMemory1);
|
||||
+ EXPECT_EQ(0u, program);
|
||||
+
|
||||
+ program = CompileProgram(essl1_shaders::vs::Simple(), kTooLargeGlobalAndLocalMemory2);
|
||||
+ EXPECT_EQ(0u, program);
|
||||
+}
|
||||
+
|
||||
// Linking should fail when corresponding vertex/fragment uniform blocks have different precision
|
||||
// qualifiers.
|
||||
TEST_P(WebGL2CompatibilityTest, UniformBlockPrecisionMismatch)
|
||||
396
patches/angle/cherry-pick-e4669a74888d.patch
Normal file
396
patches/angle/cherry-pick-e4669a74888d.patch
Normal file
@@ -0,0 +1,396 @@
|
||||
From e4669a74888d7f9bd93d79f72829d576776dfb8a Mon Sep 17 00:00:00 2001
|
||||
From: Charlie Lao <cclao@google.com>
|
||||
Date: Tue, 08 Aug 2023 10:14:47 -0700
|
||||
Subject: [PATCH] [M114-LTS] Vulkan: Fix data race with DynamicDescriptorPool
|
||||
|
||||
Right now DynamicDescriptorPool::destroyCachedDescriptorSet can be
|
||||
called from garbage clean up thread, while simultaneously accessed from
|
||||
context main thread, and data race will happen and cause bugs. This can
|
||||
only happen when the buffer is not being suballocated. In this case,
|
||||
suballocation owns the bufferBlock and bufferBlock gets destroyed when
|
||||
suballocation is destroyed from garbage collection thread. If buffer is
|
||||
suballocated, the shared group owns pool which owns bufferBlocks and
|
||||
they gets destroyed from shared group with the share group lock. This CL
|
||||
avoids this race problem by release the shared cacheKey when the buffer
|
||||
is released, while we still had the shared group lock.
|
||||
|
||||
Bug: chromium:1469542
|
||||
Change-Id: Ie6235fcfb77dee2a12b2ebde44042c3845fc0aca
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4790523
|
||||
(cherry picked from commit b48983ab8c74d2fcd9ef17c80727affb9e690c53)
|
||||
---
|
||||
|
||||
diff --git a/src/libANGLE/renderer/vulkan/BufferVk.cpp b/src/libANGLE/renderer/vulkan/BufferVk.cpp
|
||||
index 2e07deb..93a1092 100644
|
||||
--- a/src/libANGLE/renderer/vulkan/BufferVk.cpp
|
||||
+++ b/src/libANGLE/renderer/vulkan/BufferVk.cpp
|
||||
@@ -305,7 +305,7 @@
|
||||
RendererVk *renderer = contextVk->getRenderer();
|
||||
if (mBuffer.valid())
|
||||
{
|
||||
- mBuffer.releaseBufferAndDescriptorSetCache(contextVk);
|
||||
+ mBuffer.releaseBufferAndDescriptorSetCache(renderer);
|
||||
}
|
||||
if (mStagingBuffer.valid())
|
||||
{
|
||||
@@ -623,7 +623,7 @@
|
||||
memcpy(dstMapPtr, srcMapPtr, static_cast<size_t>(mState.getSize()));
|
||||
}
|
||||
|
||||
- src.releaseBufferAndDescriptorSetCache(contextVk);
|
||||
+ src.releaseBufferAndDescriptorSetCache(contextVk->getRenderer());
|
||||
|
||||
// Return the already mapped pointer with the offset adjustment to avoid the call to unmap().
|
||||
*mapPtr = dstMapPtr + offset;
|
||||
@@ -1029,7 +1029,7 @@
|
||||
|
||||
if (prevBuffer.valid())
|
||||
{
|
||||
- prevBuffer.releaseBufferAndDescriptorSetCache(contextVk);
|
||||
+ prevBuffer.releaseBufferAndDescriptorSetCache(contextVk->getRenderer());
|
||||
}
|
||||
|
||||
return angle::Result::Continue;
|
||||
@@ -1151,7 +1151,7 @@
|
||||
|
||||
if (mBuffer.valid())
|
||||
{
|
||||
- mBuffer.releaseBufferAndDescriptorSetCache(contextVk);
|
||||
+ mBuffer.releaseBufferAndDescriptorSetCache(renderer);
|
||||
}
|
||||
|
||||
// Allocate the buffer directly
|
||||
diff --git a/src/libANGLE/renderer/vulkan/Suballocation.h b/src/libANGLE/renderer/vulkan/Suballocation.h
|
||||
index d25481b..276f6b4 100644
|
||||
--- a/src/libANGLE/renderer/vulkan/Suballocation.h
|
||||
+++ b/src/libANGLE/renderer/vulkan/Suballocation.h
|
||||
@@ -86,6 +86,13 @@
|
||||
{
|
||||
mDescriptorSetCacheManager.addKey(sharedCacheKey);
|
||||
}
|
||||
+ void releaseAllCachedDescriptorSetCacheKeys(RendererVk *renderer)
|
||||
+ {
|
||||
+ if (!mDescriptorSetCacheManager.empty())
|
||||
+ {
|
||||
+ mDescriptorSetCacheManager.releaseKeys(renderer);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
private:
|
||||
mutable std::mutex mVirtualBlockMutex;
|
||||
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp
|
||||
index d43c172..5e6419f 100644
|
||||
--- a/src/libANGLE/renderer/vulkan/TextureVk.cpp
|
||||
+++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp
|
||||
@@ -1623,7 +1623,7 @@
|
||||
onStateChange(angle::SubjectMessage::SubjectChanged);
|
||||
}
|
||||
mRedefinedLevels.reset();
|
||||
- mDescriptorSetCacheManager.releaseKeys(contextVk);
|
||||
+ mDescriptorSetCacheManager.releaseKeys(contextVk->getRenderer());
|
||||
}
|
||||
|
||||
void TextureVk::initImageUsageFlags(ContextVk *contextVk, angle::FormatID actualFormatID)
|
||||
@@ -2857,7 +2857,7 @@
|
||||
|
||||
mBufferViews.release(contextVk);
|
||||
mBufferViews.init(renderer, offset, size);
|
||||
- mDescriptorSetCacheManager.releaseKeys(contextVk);
|
||||
+ mDescriptorSetCacheManager.releaseKeys(renderer);
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
@@ -3300,7 +3300,7 @@
|
||||
{
|
||||
RendererVk *renderer = contextVk->getRenderer();
|
||||
|
||||
- mDescriptorSetCacheManager.releaseKeys(contextVk);
|
||||
+ mDescriptorSetCacheManager.releaseKeys(renderer);
|
||||
|
||||
if (mImage == nullptr)
|
||||
{
|
||||
diff --git a/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp b/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp
|
||||
index f750428..ae86b29 100644
|
||||
--- a/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp
|
||||
+++ b/src/libANGLE/renderer/vulkan/vk_cache_utils.cpp
|
||||
@@ -2589,11 +2589,19 @@
|
||||
{
|
||||
contextVk->getShareGroup()->getFramebufferCache().erase(contextVk, desc);
|
||||
}
|
||||
+void ReleaseCachedObject(RendererVk *renderer, const FramebufferDesc &desc)
|
||||
+{
|
||||
+ UNREACHABLE();
|
||||
+}
|
||||
|
||||
void ReleaseCachedObject(ContextVk *contextVk, const DescriptorSetDescAndPool &descAndPool)
|
||||
{
|
||||
+ UNREACHABLE();
|
||||
+}
|
||||
+void ReleaseCachedObject(RendererVk *renderer, const DescriptorSetDescAndPool &descAndPool)
|
||||
+{
|
||||
ASSERT(descAndPool.mPool != nullptr);
|
||||
- descAndPool.mPool->releaseCachedDescriptorSet(contextVk, descAndPool.mDesc);
|
||||
+ descAndPool.mPool->releaseCachedDescriptorSet(renderer, descAndPool.mDesc);
|
||||
}
|
||||
|
||||
void DestroyCachedObject(RendererVk *renderer, const FramebufferDesc &desc)
|
||||
@@ -6261,6 +6269,22 @@
|
||||
}
|
||||
|
||||
template <class SharedCacheKeyT>
|
||||
+void SharedCacheKeyManager<SharedCacheKeyT>::releaseKeys(RendererVk *renderer)
|
||||
+{
|
||||
+ for (SharedCacheKeyT &sharedCacheKey : mSharedCacheKeys)
|
||||
+ {
|
||||
+ if (*sharedCacheKey.get() != nullptr)
|
||||
+ {
|
||||
+ // Immediate destroy the cached object and the key itself when first releaseKeys call is
|
||||
+ // made
|
||||
+ ReleaseCachedObject(renderer, *(*sharedCacheKey.get()));
|
||||
+ *sharedCacheKey.get() = nullptr;
|
||||
+ }
|
||||
+ }
|
||||
+ mSharedCacheKeys.clear();
|
||||
+}
|
||||
+
|
||||
+template <class SharedCacheKeyT>
|
||||
void SharedCacheKeyManager<SharedCacheKeyT>::destroyKeys(RendererVk *renderer)
|
||||
{
|
||||
for (SharedCacheKeyT &sharedCacheKey : mSharedCacheKeys)
|
||||
diff --git a/src/libANGLE/renderer/vulkan/vk_cache_utils.h b/src/libANGLE/renderer/vulkan/vk_cache_utils.h
|
||||
index 8c9d452..f85459a 100644
|
||||
--- a/src/libANGLE/renderer/vulkan/vk_cache_utils.h
|
||||
+++ b/src/libANGLE/renderer/vulkan/vk_cache_utils.h
|
||||
@@ -1932,6 +1932,7 @@
|
||||
void addKey(const SharedCacheKeyT &key);
|
||||
// Iterate over the descriptor array and release the descriptor and cache.
|
||||
void releaseKeys(ContextVk *contextVk);
|
||||
+ void releaseKeys(RendererVk *rendererVk);
|
||||
// Iterate over the descriptor array and destroy the descriptor and cache.
|
||||
void destroyKeys(RendererVk *renderer);
|
||||
void clear();
|
||||
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.cpp b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
|
||||
index 9088e09bf..8bc027d 100644
|
||||
--- a/src/libANGLE/renderer/vulkan/vk_helpers.cpp
|
||||
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
|
||||
@@ -3798,7 +3798,7 @@
|
||||
return mDescriptorPools[mCurrentPoolIndex]->get().init(context, mPoolSizes, mMaxSetsPerPool);
|
||||
}
|
||||
|
||||
-void DynamicDescriptorPool::releaseCachedDescriptorSet(ContextVk *contextVk,
|
||||
+void DynamicDescriptorPool::releaseCachedDescriptorSet(RendererVk *renderer,
|
||||
const DescriptorSetDesc &desc)
|
||||
{
|
||||
VkDescriptorSet descriptorSet;
|
||||
@@ -3812,7 +3812,7 @@
|
||||
// Wrap it with helper object so that it can be GPU tracked and add it to resource list.
|
||||
DescriptorSetHelper descriptorSetHelper(poolOut->get().getResourceUse(), descriptorSet);
|
||||
poolOut->get().addGarbage(std::move(descriptorSetHelper));
|
||||
- checkAndReleaseUnusedPool(contextVk->getRenderer(), poolOut);
|
||||
+ checkAndReleaseUnusedPool(renderer, poolOut);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5016,6 +5016,12 @@
|
||||
|
||||
if (mSuballocation.valid())
|
||||
{
|
||||
+ if (!mSuballocation.isSuballocated())
|
||||
+ {
|
||||
+ // Destroy cacheKeys now to avoid getting into situation that having to destroy
|
||||
+ // descriptorSet from garbage collection thread.
|
||||
+ mSuballocation.getBufferBlock()->releaseAllCachedDescriptorSetCacheKeys(renderer);
|
||||
+ }
|
||||
renderer->collectSuballocationGarbage(mUse, std::move(mSuballocation),
|
||||
std::move(mBufferForVertexArray));
|
||||
}
|
||||
@@ -5024,17 +5030,15 @@
|
||||
ASSERT(!mBufferForVertexArray.valid());
|
||||
}
|
||||
|
||||
-void BufferHelper::releaseBufferAndDescriptorSetCache(ContextVk *contextVk)
|
||||
+void BufferHelper::releaseBufferAndDescriptorSetCache(RendererVk *renderer)
|
||||
{
|
||||
- RendererVk *renderer = contextVk->getRenderer();
|
||||
-
|
||||
if (renderer->hasResourceUseFinished(getResourceUse()))
|
||||
{
|
||||
mDescriptorSetCacheManager.destroyKeys(renderer);
|
||||
}
|
||||
else
|
||||
{
|
||||
- mDescriptorSetCacheManager.releaseKeys(contextVk);
|
||||
+ mDescriptorSetCacheManager.releaseKeys(renderer);
|
||||
}
|
||||
|
||||
release(renderer);
|
||||
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.h b/src/libANGLE/renderer/vulkan/vk_helpers.h
|
||||
index d2405b6..962dfe8 100644
|
||||
--- a/src/libANGLE/renderer/vulkan/vk_helpers.h
|
||||
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.h
|
||||
@@ -252,7 +252,7 @@
|
||||
VkDescriptorSet *descriptorSetOut,
|
||||
SharedDescriptorSetCacheKey *sharedCacheKeyOut);
|
||||
|
||||
- void releaseCachedDescriptorSet(ContextVk *contextVk, const DescriptorSetDesc &desc);
|
||||
+ void releaseCachedDescriptorSet(RendererVk *renderer, const DescriptorSetDesc &desc);
|
||||
void destroyCachedDescriptorSet(RendererVk *renderer, const DescriptorSetDesc &desc);
|
||||
|
||||
template <typename Accumulator>
|
||||
@@ -777,7 +777,7 @@
|
||||
|
||||
void destroy(RendererVk *renderer);
|
||||
void release(RendererVk *renderer);
|
||||
- void releaseBufferAndDescriptorSetCache(ContextVk *contextVk);
|
||||
+ void releaseBufferAndDescriptorSetCache(RendererVk *renderer);
|
||||
|
||||
BufferSerial getBufferSerial() const { return mSerial; }
|
||||
BufferSerial getBlockSerial() const
|
||||
diff --git a/src/tests/gl_tests/TransformFeedbackTest.cpp b/src/tests/gl_tests/TransformFeedbackTest.cpp
|
||||
index ea3eeea..226eb1f 100644
|
||||
--- a/src/tests/gl_tests/TransformFeedbackTest.cpp
|
||||
+++ b/src/tests/gl_tests/TransformFeedbackTest.cpp
|
||||
@@ -507,8 +507,8 @@
|
||||
|
||||
const std::array<uint32_t, 12> kInitialData = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
|
||||
const std::array<uint32_t, 12> kUpdateData = {
|
||||
- 0x12345678u, 0x9ABCDEF0u, 0x13579BDFu, 0x2468ACE0u, 0x23456781u, 0xABCDEF09u,
|
||||
- 0x3579BDF1u, 0x468ACE02u, 0x34567812u, 0xBCDEF09Au, 0x579BDF13u, 0x68ACE024u,
|
||||
+ 0x12345678u, 0x9ABCDEF0u, 0x13579BDFu, 0x2468ACE0u, 0x23456781u, 0xABCDEF09u,
|
||||
+ 0x3579BDF1u, 0x468ACE02u, 0x34567812u, 0xBCDEF09Au, 0x579BDF13u, 0x68ACE024u,
|
||||
};
|
||||
|
||||
GLBuffer buffer;
|
||||
@@ -3749,9 +3749,9 @@
|
||||
constexpr size_t kCapturedVaryingsCount = 3;
|
||||
constexpr std::array<size_t, kCapturedVaryingsCount> kCaptureSizes = {8, 9, 4};
|
||||
const std::vector<float> kExpected[kCapturedVaryingsCount] = {
|
||||
- {0.27, 0.30, 0.33, 0.36, 0.39, 0.42, 0.45, 0.48},
|
||||
- {0.63, 0.66, 0.69, 0.72, 0.75, 0.78, 0.81, 0.84, 0.87},
|
||||
- {0.25, 0.5, 0.75, 1.0},
|
||||
+ {0.27, 0.30, 0.33, 0.36, 0.39, 0.42, 0.45, 0.48},
|
||||
+ {0.63, 0.66, 0.69, 0.72, 0.75, 0.78, 0.81, 0.84, 0.87},
|
||||
+ {0.25, 0.5, 0.75, 1.0},
|
||||
};
|
||||
|
||||
ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(program, kVS, kFS, tfVaryings, GL_INTERLEAVED_ATTRIBS);
|
||||
@@ -3848,9 +3848,9 @@
|
||||
constexpr size_t kCapturedVaryingsCount = 3;
|
||||
constexpr std::array<size_t, kCapturedVaryingsCount> kCaptureSizes = {1, 2, 1};
|
||||
const std::vector<float> kExpected[kCapturedVaryingsCount] = {
|
||||
- {0.25},
|
||||
- {0.5, 0.75},
|
||||
- {1.0},
|
||||
+ {0.25},
|
||||
+ {0.5, 0.75},
|
||||
+ {1.0},
|
||||
};
|
||||
|
||||
ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(program, kVS, kFS, tfVaryings, GL_SEPARATE_ATTRIBS);
|
||||
@@ -4392,6 +4392,51 @@
|
||||
glEndTransformFeedback();
|
||||
}
|
||||
|
||||
+// Test bufferData call and transform feedback.
|
||||
+TEST_P(TransformFeedbackTest, BufferDataAndTransformFeedback)
|
||||
+{
|
||||
+ const char kVS[] = R"(#version 300 es
|
||||
+flat out highp int var;
|
||||
+void main() {
|
||||
+var = 1;
|
||||
+})";
|
||||
+
|
||||
+ const char kFS[] = R"(#version 300 es
|
||||
+flat in highp int var;
|
||||
+out highp int color;
|
||||
+void main() {
|
||||
+color = var;
|
||||
+})";
|
||||
+
|
||||
+ ANGLE_GL_PROGRAM(program, kVS, kFS);
|
||||
+
|
||||
+ GLTexture texture;
|
||||
+ glBindTexture(GL_TEXTURE_2D, texture);
|
||||
+ glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32I, 1, 1);
|
||||
+
|
||||
+ GLFramebuffer fbo;
|
||||
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
|
||||
+ EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
|
||||
+
|
||||
+ constexpr int kClearColor[] = {123, 0, 0, 0};
|
||||
+ glClearBufferiv(GL_COLOR, 0, kClearColor);
|
||||
+ glDrawArrays(GL_POINTS, 0, 1);
|
||||
+
|
||||
+ const char *kVarying = "var";
|
||||
+ glTransformFeedbackVaryings(program, 1, &kVarying, GL_INTERLEAVED_ATTRIBS);
|
||||
+ glLinkProgram(program);
|
||||
+ ASSERT_GL_NO_ERROR();
|
||||
+
|
||||
+ GLBuffer buffer;
|
||||
+ glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffer);
|
||||
+ glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 0x7ffc * 10000, nullptr, GL_DYNAMIC_READ);
|
||||
+ glBeginTransformFeedback(GL_POINTS);
|
||||
+ glDrawArrays(GL_POINTS, 0, 1);
|
||||
+ glEndTransformFeedback();
|
||||
+ glFlush();
|
||||
+}
|
||||
+
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TransformFeedbackTest);
|
||||
ANGLE_INSTANTIATE_TEST_ES3_AND(TransformFeedbackTest,
|
||||
ES3_VULKAN()
|
||||
diff --git a/src/tests/gl_tests/UniformBufferTest.cpp b/src/tests/gl_tests/UniformBufferTest.cpp
|
||||
index 4d005c0..71b8504 100644
|
||||
--- a/src/tests/gl_tests/UniformBufferTest.cpp
|
||||
+++ b/src/tests/gl_tests/UniformBufferTest.cpp
|
||||
@@ -3422,6 +3422,50 @@
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
|
||||
}
|
||||
|
||||
+// Calling BufferData and use it in a loop to force descriptorSet creation and destroy.
|
||||
+TEST_P(UniformBufferTest, BufferDataInLoop)
|
||||
+{
|
||||
+ glClear(GL_COLOR_BUFFER_BIT);
|
||||
+
|
||||
+ // Use large buffer size to get around suballocation, so that we will gets a new buffer with
|
||||
+ // bufferData call.
|
||||
+ static constexpr size_t kBufferSize = 4 * 1024 * 1024;
|
||||
+ std::vector<float> floatData;
|
||||
+ floatData.resize(kBufferSize / (sizeof(float)), 0.0f);
|
||||
+ floatData[0] = 0.5f;
|
||||
+ floatData[1] = 0.75f;
|
||||
+ floatData[2] = 0.25f;
|
||||
+ floatData[3] = 1.0f;
|
||||
+
|
||||
+ GLTexture textures[2];
|
||||
+ GLFramebuffer fbos[2];
|
||||
+ for (int i = 0; i < 2; i++)
|
||||
+ {
|
||||
+ glBindTexture(GL_TEXTURE_2D, textures[i]);
|
||||
+ glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
|
||||
+
|
||||
+ glBindFramebuffer(GL_FRAMEBUFFER, fbos[i]);
|
||||
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[i], 0);
|
||||
+ EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
|
||||
+ }
|
||||
+
|
||||
+ for (int loop = 0; loop < 10; loop++)
|
||||
+ {
|
||||
+ int i = loop & 0x1;
|
||||
+ // Switch FBO to get around deferred flush
|
||||
+ glBindFramebuffer(GL_FRAMEBUFFER, fbos[i]);
|
||||
+ glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer);
|
||||
+ glBufferData(GL_UNIFORM_BUFFER, kBufferSize, floatData.data(), GL_STATIC_DRAW);
|
||||
+
|
||||
+ glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer);
|
||||
+ glUniformBlockBinding(mProgram, mUniformBufferIndex, 0);
|
||||
+ drawQuad(mProgram, essl3_shaders::PositionAttrib(), 0.5f);
|
||||
+ glFlush();
|
||||
+ }
|
||||
+ ASSERT_GL_NO_ERROR();
|
||||
+ EXPECT_PIXEL_NEAR(0, 0, 128, 191, 64, 255, 1);
|
||||
+}
|
||||
+
|
||||
class WebGL2UniformBufferTest : public UniformBufferTest
|
||||
{
|
||||
protected:
|
||||
@@ -1,215 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shahbaz Youssefi <syoussefi@chromium.org>
|
||||
Date: Thu, 30 Nov 2023 14:12:42 -0500
|
||||
Subject: M120: Translator: Fail compilation if too many struct fields
|
||||
|
||||
If there are too many struct fields, SPIR-V cannot be produced (as it
|
||||
has a hard limit of 16383 fields). The Nvidia GL driver has also been
|
||||
observed to fail when there are too many fields.
|
||||
|
||||
Bug: chromium:1505009
|
||||
Change-Id: I29fd61d180175e89e7db9ca8ba49ab07585b5f9a
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5143827
|
||||
Reviewed-by: Cody Northrop <cnorthrop@google.com>
|
||||
|
||||
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
|
||||
index 7c90ea4f1d23a8af0cab1d44124eea021a27a16d..e174725beb764407185e471a9916ffd164493cd8 100644
|
||||
--- a/src/compiler/translator/ParseContext.cpp
|
||||
+++ b/src/compiler/translator/ParseContext.cpp
|
||||
@@ -4726,6 +4726,8 @@ TIntermDeclaration *TParseContext::addInterfaceBlock(
|
||||
const TVector<unsigned int> *arraySizes,
|
||||
const TSourceLoc &arraySizesLine)
|
||||
{
|
||||
+ checkDoesNotHaveTooManyFields(blockName, fieldList, nameLine);
|
||||
+
|
||||
// Ensure there are no duplicate field names
|
||||
checkDoesNotHaveDuplicateFieldNames(fieldList, nameLine);
|
||||
|
||||
@@ -6289,6 +6291,21 @@ void TParseContext::checkDoesNotHaveDuplicateFieldNames(const TFieldList *fields
|
||||
}
|
||||
}
|
||||
|
||||
+void TParseContext::checkDoesNotHaveTooManyFields(const ImmutableString &name,
|
||||
+ const TFieldList *fields,
|
||||
+ const TSourceLoc &location)
|
||||
+{
|
||||
+ // Check that there are not too many fields. SPIR-V has a limit of 16383 fields, and it would
|
||||
+ // be reasonable to apply that limit to all outputs. For example, it was observed that 32768
|
||||
+ // fields cause the Nvidia GL driver to fail compilation, so such a limit is not too specific to
|
||||
+ // SPIR-V.
|
||||
+ constexpr size_t kMaxFieldCount = 16383;
|
||||
+ if (fields->size() > kMaxFieldCount)
|
||||
+ {
|
||||
+ error(location, "Too many fields in the struct (limit is 16383)", name);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
TFieldList *TParseContext::addStructFieldList(TFieldList *fields, const TSourceLoc &location)
|
||||
{
|
||||
return fields;
|
||||
@@ -6392,6 +6409,8 @@ TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine,
|
||||
}
|
||||
}
|
||||
|
||||
+ checkDoesNotHaveTooManyFields(structName, fieldList, structLine);
|
||||
+
|
||||
// Ensure there are no duplicate field names
|
||||
checkDoesNotHaveDuplicateFieldNames(fieldList, structLine);
|
||||
|
||||
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
|
||||
index b63dbbadd146d1a004513823de72c89240a31929..c83b73271b557ed122668d7e655deae5aa23bc48 100644
|
||||
--- a/src/compiler/translator/ParseContext.h
|
||||
+++ b/src/compiler/translator/ParseContext.h
|
||||
@@ -355,6 +355,9 @@ class TParseContext : angle::NonCopyable
|
||||
const TVector<unsigned int> *arraySizes);
|
||||
|
||||
void checkDoesNotHaveDuplicateFieldNames(const TFieldList *fields, const TSourceLoc &location);
|
||||
+ void checkDoesNotHaveTooManyFields(const ImmutableString &name,
|
||||
+ const TFieldList *fields,
|
||||
+ const TSourceLoc &location);
|
||||
TFieldList *addStructFieldList(TFieldList *fields, const TSourceLoc &location);
|
||||
TFieldList *combineStructFieldLists(TFieldList *processedFields,
|
||||
const TFieldList *newlyAddedFields,
|
||||
diff --git a/src/tests/compiler_tests/ExpressionLimit_test.cpp b/src/tests/compiler_tests/ExpressionLimit_test.cpp
|
||||
index d399e1792d97edb76d5e0247e4166e094cecb7e5..e17eace1b4b9a4185d6833fb7895f5fd49ae7679 100644
|
||||
--- a/src/tests/compiler_tests/ExpressionLimit_test.cpp
|
||||
+++ b/src/tests/compiler_tests/ExpressionLimit_test.cpp
|
||||
@@ -16,12 +16,6 @@ class ExpressionLimitTest : public testing::Test
|
||||
static const int kMaxExpressionComplexity = 16;
|
||||
static const int kMaxCallStackDepth = 16;
|
||||
static const int kMaxFunctionParameters = 16;
|
||||
- static const char *kExpressionTooComplex;
|
||||
- static const char *kCallStackTooDeep;
|
||||
- static const char *kHasRecursion;
|
||||
- static const char *kTooManyParameters;
|
||||
- static const char *kTooComplexSwitch;
|
||||
- static const char *kGlobalVariableInit;
|
||||
|
||||
virtual void SetUp()
|
||||
{
|
||||
@@ -125,9 +119,7 @@ class ExpressionLimitTest : public testing::Test
|
||||
|
||||
GenerateDeepFunctionStack(length, &ss);
|
||||
|
||||
- ss << "void main() {\n"
|
||||
- << " gl_FragColor = function" << length << "();\n"
|
||||
- << "}";
|
||||
+ ss << "void main() {\n" << " gl_FragColor = function" << length << "();\n" << "}";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
@@ -138,9 +130,7 @@ class ExpressionLimitTest : public testing::Test
|
||||
|
||||
GenerateDeepFunctionStack(length, &ss);
|
||||
|
||||
- ss << "void main() {\n"
|
||||
- << " gl_FragColor = vec4(0,0,0,0);\n"
|
||||
- << "}";
|
||||
+ ss << "void main() {\n" << " gl_FragColor = vec4(0,0,0,0);\n" << "}";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
@@ -149,9 +139,7 @@ class ExpressionLimitTest : public testing::Test
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
- ss << "precision mediump float;\n"
|
||||
- << "\n"
|
||||
- << "float foo(";
|
||||
+ ss << "precision mediump float;\n" << "\n" << "float foo(";
|
||||
for (int i = 0; i < parameters; ++i)
|
||||
{
|
||||
ss << "float f" << i;
|
||||
@@ -244,15 +232,13 @@ class ExpressionLimitTest : public testing::Test
|
||||
ShBuiltInResources resources;
|
||||
};
|
||||
|
||||
-const char *ExpressionLimitTest::kExpressionTooComplex = "Expression too complex";
|
||||
-const char *ExpressionLimitTest::kCallStackTooDeep = "Call stack too deep";
|
||||
-const char *ExpressionLimitTest::kHasRecursion =
|
||||
- "Recursive function call in the following call chain";
|
||||
-const char *ExpressionLimitTest::kTooManyParameters = "Function has too many parameters";
|
||||
-const char *ExpressionLimitTest::kTooComplexSwitch =
|
||||
- "too complex expressions inside a switch statement";
|
||||
-const char *ExpressionLimitTest::kGlobalVariableInit =
|
||||
- "global variable initializers must be constant expressions";
|
||||
+constexpr char kExpressionTooComplex[] = "Expression too complex";
|
||||
+constexpr char kCallStackTooDeep[] = "Call stack too deep";
|
||||
+constexpr char kHasRecursion[] = "Recursive function call in the following call chain";
|
||||
+constexpr char kTooManyParameters[] = "Function has too many parameters";
|
||||
+constexpr char kTooComplexSwitch[] = "too complex expressions inside a switch statement";
|
||||
+constexpr char kGlobalVariableInit[] = "global variable initializers must be constant expressions";
|
||||
+constexpr char kTooManyFields[] = "Too many fields in the struct";
|
||||
|
||||
TEST_F(ExpressionLimitTest, ExpressionComplexity)
|
||||
{
|
||||
@@ -632,3 +618,31 @@ TEST_F(ExpressionLimitTest, NestingInsideGlobalInitializer)
|
||||
compileOptions, nullptr));
|
||||
sh::Destruct(compiler);
|
||||
}
|
||||
+
|
||||
+TEST_F(ExpressionLimitTest, TooManyStructFields)
|
||||
+{
|
||||
+ ShShaderSpec spec = SH_WEBGL2_SPEC;
|
||||
+ ShShaderOutput output = SH_ESSL_OUTPUT;
|
||||
+ ShHandle compiler = sh::ConstructCompiler(GL_FRAGMENT_SHADER, spec, output, &resources);
|
||||
+ ShCompileOptions compileOptions = {};
|
||||
+
|
||||
+ std::ostringstream fs;
|
||||
+ fs << R"(#version 300 es
|
||||
+precision highp float;
|
||||
+struct TooManyFields
|
||||
+{
|
||||
+)";
|
||||
+ for (uint32_t i = 0; i < (1 << 16); ++i)
|
||||
+ {
|
||||
+ fs << " float field" << i << ";\n";
|
||||
+ }
|
||||
+ fs << R"(};
|
||||
+uniform B { TooManyFields s; };
|
||||
+out vec4 color;
|
||||
+void main() {
|
||||
+ color = vec4(s.field0, 0.0, 0.0, 1.0);
|
||||
+})";
|
||||
+
|
||||
+ EXPECT_TRUE(CheckShaderCompilation(compiler, fs.str().c_str(), compileOptions, kTooManyFields));
|
||||
+ sh::Destruct(compiler);
|
||||
+}
|
||||
diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp
|
||||
index 9b42b6d9221366e9bc7b6263bf8e14b77ca7694d..46f8645e5a56e527223ea4657d14dbc8619cb631 100644
|
||||
--- a/src/tests/gl_tests/GLSLTest.cpp
|
||||
+++ b/src/tests/gl_tests/GLSLTest.cpp
|
||||
@@ -18064,6 +18064,33 @@ void main() {
|
||||
ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), fs.str().c_str());
|
||||
}
|
||||
|
||||
+// Test that structs with too many fields are rejected. In SPIR-V, the instruction that defines the
|
||||
+// struct lists the fields which means the length of the instruction is a function of the field
|
||||
+// count. Since SPIR-V instruction sizes are limited to 16 bits, structs with more fields cannot be
|
||||
+// represented.
|
||||
+TEST_P(GLSLTest_ES3, TooManyFieldsInStruct)
|
||||
+{
|
||||
+ std::ostringstream fs;
|
||||
+ fs << R"(#version 300 es
|
||||
+precision highp float;
|
||||
+struct TooManyFields
|
||||
+{
|
||||
+)";
|
||||
+ for (uint32_t i = 0; i < (1 << 16); ++i)
|
||||
+ {
|
||||
+ fs << " float field" << i << ";\n";
|
||||
+ }
|
||||
+ fs << R"(};
|
||||
+uniform B { TooManyFields s; };
|
||||
+out vec4 color;
|
||||
+void main() {
|
||||
+ color = vec4(s.field0, 0.0, 0.0, 1.0);
|
||||
+})";
|
||||
+
|
||||
+ GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fs.str().c_str());
|
||||
+ EXPECT_EQ(0u, shader);
|
||||
+}
|
||||
+
|
||||
} // anonymous namespace
|
||||
|
||||
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(GLSLTest);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user