mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
Compare commits
90 Commits
v11.2.0
...
v12.0.0-ni
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6f05c34e6 | ||
|
|
d2a82dbd1d | ||
|
|
dae60e01d4 | ||
|
|
c50ded2b71 | ||
|
|
2dd7ad268b | ||
|
|
15c30c5649 | ||
|
|
ea76788b67 | ||
|
|
a80c35d161 | ||
|
|
69f1731bbb | ||
|
|
e50d6e47c4 | ||
|
|
efd003d277 | ||
|
|
137fc65e2f | ||
|
|
ecb7f877a3 | ||
|
|
735d8b84f0 | ||
|
|
a65f7f7d42 | ||
|
|
2cfa41e6e0 | ||
|
|
77038b7bda | ||
|
|
4d1dab849f | ||
|
|
0b055b2fb8 | ||
|
|
53aaeb7a16 | ||
|
|
e0a25cb1e3 | ||
|
|
993eab691f | ||
|
|
a200b15600 | ||
|
|
ba55aaa53b | ||
|
|
1ba46a91b6 | ||
|
|
fa7a29e84b | ||
|
|
e5933c6910 | ||
|
|
2091fd7dd9 | ||
|
|
45170fdbd7 | ||
|
|
fbf32f697f | ||
|
|
459a95aaec | ||
|
|
b1d8057ec9 | ||
|
|
87d67a9365 | ||
|
|
9f4a097e03 | ||
|
|
5de7eb3618 | ||
|
|
7f885bd266 | ||
|
|
bc9816b206 | ||
|
|
633e5d8503 | ||
|
|
9b08fbefe5 | ||
|
|
70e3aa0182 | ||
|
|
a3389d017f | ||
|
|
ce86591459 | ||
|
|
7d56ca7360 | ||
|
|
cd455c8b40 | ||
|
|
acf5d487d2 | ||
|
|
dd781c4f63 | ||
|
|
98683190b4 | ||
|
|
1815b95e74 | ||
|
|
a829ae56b2 | ||
|
|
e6fbbf4325 | ||
|
|
f6df79b927 | ||
|
|
5a8046c994 | ||
|
|
ae5776041e | ||
|
|
f7d9d68e14 | ||
|
|
2c5c51afb9 | ||
|
|
860e14c0da | ||
|
|
31322400e7 | ||
|
|
4ad9bcb8b5 | ||
|
|
29c1248e96 | ||
|
|
a6b9f9d8e5 | ||
|
|
d305fe7d30 | ||
|
|
4dc09ea9dc | ||
|
|
4484e95fc8 | ||
|
|
03e60cce8b | ||
|
|
733d56e908 | ||
|
|
43485b8705 | ||
|
|
bda6378685 | ||
|
|
1b6534b326 | ||
|
|
e9e7eee25e | ||
|
|
7e698df8f3 | ||
|
|
e0611d0946 | ||
|
|
184e72fafd | ||
|
|
3745b76da8 | ||
|
|
bf7dbff858 | ||
|
|
7c10f86c6e | ||
|
|
9803e4d526 | ||
|
|
068b464e13 | ||
|
|
a09694ae85 | ||
|
|
e06a1c2746 | ||
|
|
c5320b3951 | ||
|
|
6cc960f214 | ||
|
|
a4b6fce907 | ||
|
|
8f727b3569 | ||
|
|
95073decd3 | ||
|
|
e8ef1ef252 | ||
|
|
075502477e | ||
|
|
97755bbd85 | ||
|
|
bab69ae4d2 | ||
|
|
443540fd13 | ||
|
|
5e1950ceff |
@@ -69,7 +69,7 @@ parameters:
|
||||
# Build machines configs.
|
||||
docker-image: &docker-image
|
||||
docker:
|
||||
- image: electron.azurecr.io/build:4cec2c5ab66765caa724e37bae2bffb9b29722a5
|
||||
- image: electronjs/build:d09fd95029bd8c1c73069888231b29688ef385ed
|
||||
|
||||
machine-linux-medium: &machine-linux-medium
|
||||
<<: *docker-image
|
||||
@@ -107,7 +107,6 @@ env-release-build: &env-release-build
|
||||
STRIP_BINARIES: true
|
||||
GENERATE_SYMBOLS: true
|
||||
CHECK_DIST_MANIFEST: '1'
|
||||
IS_RELEASE: true
|
||||
|
||||
env-headless-testing: &env-headless-testing
|
||||
DISPLAY: ':99.0'
|
||||
@@ -257,34 +256,23 @@ step-gclient-sync: &step-gclient-sync
|
||||
"$CIRCLE_REPOSITORY_URL"
|
||||
|
||||
ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES=1 gclient sync --with_branch_heads --with_tags
|
||||
if [ "$IS_RELEASE" != "true" ]; then
|
||||
# Re-export all the patches to check if there were changes.
|
||||
python src/electron/script/export_all_patches.py src/electron/patches/config.json
|
||||
cd src/electron
|
||||
git update-index --refresh || true
|
||||
if ! git diff-index --quiet HEAD --; then
|
||||
# There are changes to the patches. Make a git commit with the updated patches
|
||||
git add patches
|
||||
GIT_COMMITTER_NAME="Electron Bot" GIT_COMMITTER_EMAIL="electron@github.com" git commit -m "update patches" --author="Electron Bot <electron@github.com>"
|
||||
# Export it
|
||||
mkdir -p ../../patches
|
||||
git format-patch -1 --stdout --keep-subject --no-stat --full-index > ../../patches/update-patches.patch
|
||||
if (node ./script/push-patch.js 2> /dev/null > /dev/null); then
|
||||
echo
|
||||
echo "======================================================================"
|
||||
echo "Changes to the patches when applying, we have auto-pushed the diff to the current branch"
|
||||
echo "A new CI job will kick off shortly"
|
||||
echo "======================================================================"
|
||||
exit 1
|
||||
else
|
||||
echo
|
||||
echo "======================================================================"
|
||||
echo "There were changes to the patches when applying."
|
||||
echo "Check the CI artifacts for a patch you can apply to fix it."
|
||||
echo "======================================================================"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
# Re-export all the patches to check if there were changes.
|
||||
python src/electron/script/export_all_patches.py src/electron/patches/config.json
|
||||
cd src/electron
|
||||
git update-index --refresh || true
|
||||
if ! git diff-index --quiet HEAD --; then
|
||||
# There are changes to the patches. Make a git commit with the updated patches
|
||||
git add patches
|
||||
GIT_COMMITTER_NAME="Electron Bot" GIT_COMMITTER_EMAIL="anonymous@electronjs.org" git commit -m "update patches" --author="Electron Bot <anonymous@electronjs.org>"
|
||||
# Export it
|
||||
mkdir -p ../../patches
|
||||
git format-patch -1 --stdout --keep-subject --no-stat --full-index > ../../patches/update-patches.patch
|
||||
echo
|
||||
echo "======================================================================"
|
||||
echo "There were changes to the patches when applying."
|
||||
echo "Check the CI artifacts for a patch you can apply to fix it."
|
||||
echo "======================================================================"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -311,10 +299,10 @@ step-setup-goma-for-build: &step-setup-goma-for-build
|
||||
name: Setup Goma
|
||||
command: |
|
||||
echo 'export USE_GOMA=true' >> $BASH_ENV
|
||||
echo 'export NUMBER_OF_NINJA_PROCESSES=300' >> $BASH_ENV
|
||||
if [ "`uname`" == "Darwin" ]; then
|
||||
echo 'ulimit -n 10000' >> $BASH_ENV
|
||||
echo 'sudo launchctl limit maxfiles 65536 200000' >> $BASH_ENV
|
||||
if [ "`uname`" == "Linux" ]; then
|
||||
echo 'export NUMBER_OF_NINJA_PROCESSES=300' >> $BASH_ENV
|
||||
else
|
||||
echo 'export NUMBER_OF_NINJA_PROCESSES=25' >> $BASH_ENV
|
||||
fi
|
||||
if [ ! -z "$RAW_GOMA_AUTH" ]; then
|
||||
echo $RAW_GOMA_AUTH > ~/.goma_oauth2_config
|
||||
@@ -323,7 +311,7 @@ step-setup-goma-for-build: &step-setup-goma-for-build
|
||||
cd build-tools
|
||||
npm install
|
||||
mkdir third_party
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare()"
|
||||
node -e "require('./src/utils/goma.js').ensure()"
|
||||
echo 'export GN_GOMA_FILE='`node -e "console.log(require('./src/utils/goma.js').gnFilePath)"` >> $BASH_ENV
|
||||
echo 'export LOCAL_GOMA_DIR='`node -e "console.log(require('./src/utils/goma.js').dir)"` >> $BASH_ENV
|
||||
@@ -584,9 +572,6 @@ step-electron-dist-build: &step-electron-dist-build
|
||||
if [ x"$MAS_BUILD" == x"true" ]; then
|
||||
target_os=mac_mas
|
||||
fi
|
||||
if [ "$TARGET_ARCH" == "arm64" ]; then
|
||||
target_cpu=arm64
|
||||
fi
|
||||
elif [ "`uname`" == "Linux" ]; then
|
||||
target_os=linux
|
||||
if [ x"$TARGET_ARCH" == x ]; then
|
||||
@@ -674,10 +659,10 @@ step-electron-publish: &step-electron-publish
|
||||
cd src/electron
|
||||
if [ "$UPLOAD_TO_S3" == "1" ]; then
|
||||
echo 'Uploading Electron release distribution to S3'
|
||||
script/release/uploaders/upload.py --verbose --upload_to_s3
|
||||
script/release/uploaders/upload.py --upload_to_s3
|
||||
else
|
||||
echo 'Uploading Electron release distribution to Github releases'
|
||||
script/release/uploaders/upload.py --verbose
|
||||
script/release/uploaders/upload.py
|
||||
fi
|
||||
|
||||
step-persist-data-for-tests: &step-persist-data-for-tests
|
||||
@@ -779,20 +764,14 @@ step-setup-linux-for-headless-testing: &step-setup-linux-for-headless-testing
|
||||
|
||||
step-show-sccache-stats: &step-show-sccache-stats
|
||||
run:
|
||||
shell: /bin/bash
|
||||
name: Check sccache/goma stats after build
|
||||
command: |
|
||||
if [ "$SCCACHE_PATH" != "" ]; then
|
||||
$SCCACHE_PATH -s
|
||||
fi
|
||||
if [ "$USE_GOMA" == "true" ]; then
|
||||
set +e
|
||||
set +o pipefail
|
||||
$LOCAL_GOMA_DIR/goma_ctl.py stat
|
||||
$LOCAL_GOMA_DIR/diagnose_goma_log.py
|
||||
true
|
||||
fi
|
||||
when: always
|
||||
|
||||
step-mksnapshot-build: &step-mksnapshot-build
|
||||
run:
|
||||
@@ -930,8 +909,6 @@ step-ninja-summary: &step-ninja-summary
|
||||
run:
|
||||
name: Print ninja summary
|
||||
command: |
|
||||
set +e
|
||||
set +o pipefail
|
||||
python depot_tools/post_build_ninja_summary.py -C src/out/Default
|
||||
|
||||
step-ninja-report: &step-ninja-report
|
||||
@@ -1822,7 +1799,7 @@ jobs:
|
||||
|
||||
# Layer 2: Builds.
|
||||
linux-x64-testing:
|
||||
<<: *machine-linux-2xlarge
|
||||
<<: *machine-linux-xlarge
|
||||
environment:
|
||||
<<: *env-global
|
||||
<<: *env-testing-build
|
||||
@@ -1902,7 +1879,7 @@ jobs:
|
||||
checkout: false
|
||||
|
||||
linux-ia32-testing:
|
||||
<<: *machine-linux-2xlarge
|
||||
<<: *machine-linux-xlarge
|
||||
environment:
|
||||
<<: *env-global
|
||||
<<: *env-ia32
|
||||
|
||||
9
.github/CODEOWNERS
vendored
9
.github/CODEOWNERS
vendored
@@ -10,3 +10,12 @@ DEPS @electron/wg-upgrades
|
||||
# Releases WG
|
||||
/npm/ @electron/wg-releases
|
||||
/script/release @electron/wg-releases
|
||||
|
||||
# Security WG
|
||||
/lib/browser/rpc-server.ts @electron/wg-security
|
||||
|
||||
# Remote Change Disliker
|
||||
/lib/browser/remote/ @nornagon
|
||||
/lib/renderer/remote/ @nornagon
|
||||
/lib/renderer/api/remote.ts @nornagon
|
||||
/docs/api/remote.md @nornagon
|
||||
|
||||
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -15,7 +15,6 @@ Contributors guide: https://github.com/electron/electron/blob/master/CONTRIBUTIN
|
||||
- [ ] relevant documentation is changed or added
|
||||
- [ ] PR title follows semantic [commit guidelines](https://github.com/electron/electron/blob/master/docs/development/pull-requests.md#commit-message-guidelines)
|
||||
- [ ] [PR release notes](https://github.com/electron/clerk/blob/master/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/master/README.md#examples).
|
||||
- [ ] This is **NOT A BREAKING CHANGE**. Breaking changes may not be merged to master until 11-x-y is branched.
|
||||
|
||||
#### Release Notes
|
||||
|
||||
|
||||
82
BUILD.gn
82
BUILD.gn
@@ -325,6 +325,7 @@ source_set("electron_lib") {
|
||||
"//base/allocator:buildflags",
|
||||
"//chrome/app:command_ids",
|
||||
"//chrome/app/resources:platform_locale_settings",
|
||||
"//chrome/services/printing/public/mojom",
|
||||
"//components/certificate_transparency",
|
||||
"//components/language/core/browser",
|
||||
"//components/net_log",
|
||||
@@ -371,7 +372,6 @@ source_set("electron_lib") {
|
||||
"//third_party/libyuv",
|
||||
"//third_party/webrtc_overrides:webrtc_component",
|
||||
"//third_party/widevine/cdm:headers",
|
||||
"//third_party/zlib/google:zip",
|
||||
"//ui/base/idle",
|
||||
"//ui/events:dom_keycode_converter",
|
||||
"//ui/gl",
|
||||
@@ -405,26 +405,44 @@ source_set("electron_lib") {
|
||||
defines += [ "GDK_DISABLE_DEPRECATION_WARNINGS" ]
|
||||
}
|
||||
|
||||
extra_source_filters = []
|
||||
if (!is_linux) {
|
||||
extra_source_filters += [
|
||||
"*\bx/*",
|
||||
"*_x11.h",
|
||||
"*_x11.cc",
|
||||
"*_gtk.h",
|
||||
"*_gtk.cc",
|
||||
"*\blibrary_loaders/*",
|
||||
]
|
||||
}
|
||||
if (!is_win) {
|
||||
extra_source_filters += [
|
||||
"*\bwin_*.h",
|
||||
"*\bwin_*.cc",
|
||||
]
|
||||
}
|
||||
if (!is_posix) {
|
||||
extra_source_filters += [
|
||||
"*_posix.cc",
|
||||
"*_posix.h",
|
||||
]
|
||||
}
|
||||
if (is_mac) {
|
||||
extra_source_filters += [
|
||||
"*_views.cc",
|
||||
"*_views.h",
|
||||
"*\bviews/*",
|
||||
]
|
||||
}
|
||||
if (!is_mas_build) {
|
||||
deps += [ "//components/crash/core/app" ]
|
||||
}
|
||||
|
||||
set_sources_assignment_filter(
|
||||
sources_assignment_filter + extra_source_filters)
|
||||
sources = filenames.lib_sources
|
||||
if (is_win) {
|
||||
sources += filenames.lib_sources_win
|
||||
}
|
||||
if (is_mac) {
|
||||
sources += filenames.lib_sources_mac
|
||||
}
|
||||
if (is_posix) {
|
||||
sources += filenames.lib_sources_posix
|
||||
}
|
||||
if (is_linux) {
|
||||
sources += filenames.lib_sources_linux
|
||||
}
|
||||
if (!is_mac) {
|
||||
sources += filenames.lib_sources_views
|
||||
}
|
||||
set_sources_assignment_filter(sources_assignment_filter)
|
||||
|
||||
if (is_component_build) {
|
||||
defines += [ "NODE_SHARED_MODE" ]
|
||||
@@ -571,6 +589,7 @@ source_set("electron_lib") {
|
||||
sources += [
|
||||
"shell/browser/osr/osr_host_display_client.cc",
|
||||
"shell/browser/osr/osr_host_display_client.h",
|
||||
"shell/browser/osr/osr_host_display_client_mac.mm",
|
||||
"shell/browser/osr/osr_render_widget_host_view.cc",
|
||||
"shell/browser/osr/osr_render_widget_host_view.h",
|
||||
"shell/browser/osr/osr_video_consumer.cc",
|
||||
@@ -579,13 +598,8 @@ source_set("electron_lib") {
|
||||
"shell/browser/osr/osr_view_proxy.h",
|
||||
"shell/browser/osr/osr_web_contents_view.cc",
|
||||
"shell/browser/osr/osr_web_contents_view.h",
|
||||
"shell/browser/osr/osr_web_contents_view_mac.mm",
|
||||
]
|
||||
if (is_mac) {
|
||||
sources += [
|
||||
"shell/browser/osr/osr_host_display_client_mac.mm",
|
||||
"shell/browser/osr/osr_web_contents_view_mac.mm",
|
||||
]
|
||||
}
|
||||
deps += [
|
||||
"//components/viz/service",
|
||||
"//services/viz/public/mojom",
|
||||
@@ -620,10 +634,7 @@ source_set("electron_lib") {
|
||||
"shell/renderer/printing/print_render_frame_helper_delegate.cc",
|
||||
"shell/renderer/printing/print_render_frame_helper_delegate.h",
|
||||
]
|
||||
deps += [
|
||||
"//chrome/services/printing/public/mojom",
|
||||
"//components/printing/common:mojo_interfaces",
|
||||
]
|
||||
deps += [ "//components/printing/common:mojo_interfaces" ]
|
||||
}
|
||||
|
||||
if (enable_electron_extensions) {
|
||||
@@ -633,6 +644,7 @@ source_set("electron_lib") {
|
||||
"shell/common/extensions/api",
|
||||
"shell/common/extensions/api:extensions_features",
|
||||
"//chrome/browser/resources:component_extension_resources",
|
||||
"//components/update_client:update_client",
|
||||
"//components/zoom",
|
||||
"//extensions/browser",
|
||||
"//extensions/browser:core_api_provider",
|
||||
@@ -661,14 +673,6 @@ source_set("electron_lib") {
|
||||
"shell/browser/electron_pdf_web_contents_helper_client.h",
|
||||
]
|
||||
}
|
||||
|
||||
if (is_win && enable_win_dark_mode_window_ui) {
|
||||
sources += [
|
||||
"shell/browser/win/dark_mode.cc",
|
||||
"shell/browser/win/dark_mode.h",
|
||||
]
|
||||
libs += [ "uxtheme.lib" ]
|
||||
}
|
||||
}
|
||||
|
||||
electron_paks("packed_resources") {
|
||||
@@ -694,10 +698,10 @@ if (is_mac) {
|
||||
action("fake_v8_context_snapshot_generator") {
|
||||
script = "build/fake_v8_context_snapshot_generator.py"
|
||||
args = [
|
||||
rebase_path("$root_out_dir/$v8_context_snapshot_filename"),
|
||||
rebase_path("$root_out_dir/fake/$v8_context_snapshot_filename"),
|
||||
rebase_path("$root_out_dir/v8_context_snapshot.bin"),
|
||||
rebase_path("$root_out_dir/fake/v8_context_snapshot.bin"),
|
||||
]
|
||||
outputs = [ "$root_out_dir/fake/$v8_context_snapshot_filename" ]
|
||||
outputs = [ "$root_out_dir/fake/v8_context_snapshot.bin" ]
|
||||
}
|
||||
|
||||
bundle_data("electron_framework_resources") {
|
||||
@@ -711,10 +715,10 @@ if (is_mac) {
|
||||
public_deps += [ "//v8" ]
|
||||
if (use_v8_context_snapshot) {
|
||||
if (use_prebuilt_v8_context_snapshot) {
|
||||
sources += [ "$root_out_dir/fake/$v8_context_snapshot_filename" ]
|
||||
sources += [ "$root_out_dir/fake/v8_context_snapshot.bin" ]
|
||||
public_deps += [ ":fake_v8_context_snapshot_generator" ]
|
||||
} else {
|
||||
sources += [ "$root_out_dir/$v8_context_snapshot_filename" ]
|
||||
sources += [ "$root_out_dir/v8_context_snapshot.bin" ]
|
||||
public_deps += [ "//tools/v8_context_snapshot" ]
|
||||
}
|
||||
} else {
|
||||
|
||||
6
DEPS
6
DEPS
@@ -14,13 +14,13 @@ gclient_gn_args = [
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'87.0.4280.141',
|
||||
'b943d006a33ec5bc1743792d64724693eb357083',
|
||||
'node_version':
|
||||
'v12.18.3',
|
||||
'v14.11.0',
|
||||
'nan_version':
|
||||
'2c4ee8a32a299eada3cd6e468bbd0a473bfea96d',
|
||||
'squirrel.mac_version':
|
||||
'a3a5b3f03b824441c014893b18f99a103b2603e9',
|
||||
'44468f858ce0d25c27bd5e674abfa104e0119738',
|
||||
|
||||
'boto_version': 'f7574aa6cc2c819430c1f05e9a1a1a666ef8169b',
|
||||
'pyyaml_version': '3.12',
|
||||
|
||||
@@ -1 +1 @@
|
||||
11.2.0
|
||||
12.0.0-nightly.20200922
|
||||
30
appveyor.yml
30
appveyor.yml
@@ -53,9 +53,7 @@ build_script:
|
||||
} else {
|
||||
node script/yarn.js install --frozen-lockfile
|
||||
|
||||
$result = node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH
|
||||
Write-Output $result
|
||||
if ($result.ExitCode -eq 0) {
|
||||
if ($(node script/doc-only-change.js --prNumber=$env:APPVEYOR_PULL_REQUEST_NUMBER --prBranch=$env:APPVEYOR_REPO_BRANCH;$LASTEXITCODE -eq 0)) {
|
||||
Write-warning "Skipping build for doc only change"; Exit-AppveyorBuild
|
||||
}
|
||||
}
|
||||
@@ -101,11 +99,6 @@ build_script:
|
||||
} else {
|
||||
# update external binaries
|
||||
python src/electron/script/update-external-binaries.py
|
||||
# update angle
|
||||
cd src\third_party\angle
|
||||
git remote set-url origin https://chromium.googlesource.com/angle/angle.git
|
||||
git fetch
|
||||
cd ..\..\..
|
||||
}
|
||||
} else {
|
||||
# file does not exist, gclient sync, then zip
|
||||
@@ -121,16 +114,14 @@ build_script:
|
||||
if ($env:SAVE_GCLIENT_SRC -eq 'true') {
|
||||
# archive current source for future use
|
||||
# only run on x64/woa to avoid contention saving
|
||||
$(7z a $zipfile src -xr!android_webview -xr!electron -xr'!*\.git' -xr!third_party\WebKit\LayoutTests! -xr!third_party\blink\web_tests -xr!third_party\blink\perf_tests -slp -t7z -mmt=30)
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
if ($(7z a $zipfile src -xr!android_webview -xr!electron -xr'!*\.git' -xr!third_party\WebKit\LayoutTests! -xr!third_party\blink\web_tests -xr!third_party\blink\perf_tests -slp -t7z -mmt=30;$LASTEXITCODE -ne 0)) {
|
||||
Write-warning "Could not save source to shared drive; continuing anyway"
|
||||
}
|
||||
# build time generation of file gen/angle/angle_commit.h depends on
|
||||
# third_party/angle/.git
|
||||
# build time generation of file gen/angle/commit.h depends on
|
||||
# third_party/angle/.git/HEAD.
|
||||
# https://chromium-review.googlesource.com/c/angle/angle/+/2074924
|
||||
$(7z a $zipfile src\third_party\angle\.git)
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-warning "Failed to add third_party\angle\.git; continuing anyway"
|
||||
if ($(7z a $zipfile src\third_party\angle\.git\HEAD;$LASTEXITCODE -ne 0)) {
|
||||
Write-warning "Failed to add third_party\angle\.git\HEAD; continuing anyway"
|
||||
}
|
||||
}
|
||||
- ps: >-
|
||||
@@ -143,7 +134,7 @@ build_script:
|
||||
cd build-tools
|
||||
npm install
|
||||
mkdir third_party
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
|
||||
node -e "require('./src/utils/goma.js').downloadAndPrepare()"
|
||||
$env:GN_GOMA_FILE = node -e "console.log(require('./src/utils/goma.js').gnFilePath)"
|
||||
$env:LOCAL_GOMA_DIR = node -e "console.log(require('./src/utils/goma.js').dir)"
|
||||
cd ..
|
||||
@@ -214,8 +205,7 @@ test_script:
|
||||
echo "Skipping tests for $env:GN_CONFIG build"
|
||||
}
|
||||
- cd electron
|
||||
# CalculateNativeWinOcclusion is disabled due to https://bugs.chromium.org/p/chromium/issues/detail?id=1139022
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running test suite & node script/yarn test -- --trace-uncaught --enable-logging --disable-features=CalculateNativeWinOcclusion )
|
||||
- if "%RUN_TESTS%"=="true" ( echo Running test suite & node script/yarn test -- --trace-uncaught --enable-logging)
|
||||
- cd ..
|
||||
- if "%RUN_TESTS%"=="true" ( echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg )
|
||||
- echo "About to verify mksnapshot"
|
||||
@@ -229,10 +219,10 @@ deploy_script:
|
||||
if (Test-Path Env:\ELECTRON_RELEASE) {
|
||||
if (Test-Path Env:\UPLOAD_TO_S3) {
|
||||
Write-Output "Uploading Electron release distribution to s3"
|
||||
& python script\release\uploaders\upload.py --verbose --upload_to_s3
|
||||
& python script\release\uploaders\upload.py --upload_to_s3
|
||||
} else {
|
||||
Write-Output "Uploading Electron release distribution to github releases"
|
||||
& python script\release\uploaders\upload.py --verbose
|
||||
& python script\release\uploaders\upload.py
|
||||
}
|
||||
} elseif (Test-Path Env:\TEST_WOA) {
|
||||
node script/release/ci-release-build.js --job=electron-woa-testing --ci=VSTS --armTest --appveyorJobId=$env:APPVEYOR_JOB_ID $env:APPVEYOR_REPO_BRANCH
|
||||
|
||||
@@ -63,8 +63,7 @@ steps:
|
||||
set npm_config_nodedir=%cd%\out\Default\gen\node_headers
|
||||
set npm_config_arch=arm64
|
||||
cd electron
|
||||
# CalculateNativeWinOcclusion is disabled due to https://bugs.chromium.org/p/chromium/issues/detail?id=1139022
|
||||
node script/yarn test -- --enable-logging --verbose --disable-features=CalculateNativeWinOcclusion
|
||||
node script/yarn test -- --enable-logging --verbose
|
||||
displayName: 'Run Electron tests'
|
||||
env:
|
||||
ELECTRON_OUT_DIR: Default
|
||||
|
||||
@@ -2,7 +2,7 @@ is_electron_build = true
|
||||
root_extra_deps = [ "//electron" ]
|
||||
|
||||
# Registry of NMVs --> https://github.com/nodejs/node/blob/master/doc/abi_version_registry.json
|
||||
node_module_version = 85
|
||||
node_module_version = 82
|
||||
|
||||
v8_promise_internal_field_count = 1
|
||||
v8_typed_array_max_size_in_heap = 0
|
||||
|
||||
@@ -11,7 +11,6 @@ import find_depot_tools
|
||||
from vs_toolchain import \
|
||||
SetEnvironmentAndGetRuntimeDllDirs, \
|
||||
SetEnvironmentAndGetSDKDir, \
|
||||
GetVisualStudioVersion, \
|
||||
NormalizePath
|
||||
|
||||
sys.path.append("%s/win_toolchain" % find_depot_tools.add_depot_tools_to_path())
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
def main(argv):
|
||||
cwd = argv[1]
|
||||
|
||||
21
build/zip.py
21
build/zip.py
@@ -13,30 +13,27 @@ EXTENSIONS_TO_SKIP = [
|
||||
]
|
||||
|
||||
PATHS_TO_SKIP = [
|
||||
# Skip because it is an output of //ui/gl that we don't need.
|
||||
'angledata',
|
||||
# Skip because these are outputs that we don't need.
|
||||
'./libVkICD_mock_',
|
||||
# Skip because these are outputs that we don't need.
|
||||
'./VkICD_mock_',
|
||||
# Skip because its an output of create_bundle from //build/config/mac/rules.gni
|
||||
'angledata', #Skipping because it is an output of //ui/gl that we don't need
|
||||
'./libVkICD_mock_', #Skipping because these are outputs that we don't need
|
||||
'./VkICD_mock_', #Skipping because these are outputs that we don't need
|
||||
|
||||
# Skipping because its an output of create_bundle from //build/config/mac/rules.gni
|
||||
# that we don't need
|
||||
'Electron.dSYM',
|
||||
# Refs https://chromium-review.googlesource.com/c/angle/angle/+/2425197.
|
||||
# Remove this when Angle themselves remove the file: https://issuetracker.google.com/issues/168736059
|
||||
'gen/angle/angle_commit.h',
|
||||
|
||||
# //chrome/browser:resources depends on this via
|
||||
# //chrome/browser/resources/ssl/ssl_error_assistant, but we don't need to
|
||||
# ship it.
|
||||
'pyproto',
|
||||
|
||||
# On Windows, this binary doesn't exist (the crashpad handler is built-in).
|
||||
# On MacOS, the binary is called 'chrome_crashpad_handler' and is inside the
|
||||
# app bundle.
|
||||
# On Linux, we don't use crashpad, but this binary is still built for some
|
||||
# reason. Exclude it from the zip.
|
||||
'./crashpad_handler',
|
||||
# Skip because these are outputs that we don't need.
|
||||
'resources/inspector',
|
||||
|
||||
'resources/inspector', #Skipping because these are outputs that we don't need
|
||||
]
|
||||
|
||||
def skip_path(dep, dist_zip, target_cpu):
|
||||
|
||||
@@ -21,7 +21,6 @@ buildflag_header("buildflags") {
|
||||
"ENABLE_ELECTRON_EXTENSIONS=$enable_electron_extensions",
|
||||
"ENABLE_BUILTIN_SPELLCHECKER=$enable_builtin_spellchecker",
|
||||
"ENABLE_PICTURE_IN_PICTURE=$enable_picture_in_picture",
|
||||
"ENABLE_WIN_DARK_MODE_WINDOW_UI=$enable_win_dark_mode_window_ui",
|
||||
"OVERRIDE_LOCATION_PROVIDER=$enable_fake_location_provider",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -36,7 +36,4 @@ declare_args() {
|
||||
|
||||
# Enable Spellchecker support
|
||||
enable_builtin_spellchecker = true
|
||||
|
||||
# Undocumented Windows dark mode API
|
||||
enable_win_dark_mode_window_ui = false
|
||||
}
|
||||
|
||||
@@ -26,10 +26,18 @@ static_library("chrome") {
|
||||
"//chrome/browser/devtools/devtools_file_system_indexer.h",
|
||||
"//chrome/browser/extensions/global_shortcut_listener.cc",
|
||||
"//chrome/browser/extensions/global_shortcut_listener.h",
|
||||
"//chrome/browser/extensions/global_shortcut_listener_mac.h",
|
||||
"//chrome/browser/extensions/global_shortcut_listener_mac.mm",
|
||||
"//chrome/browser/extensions/global_shortcut_listener_win.cc",
|
||||
"//chrome/browser/extensions/global_shortcut_listener_win.h",
|
||||
"//chrome/browser/icon_loader.cc",
|
||||
"//chrome/browser/icon_loader.h",
|
||||
"//chrome/browser/icon_loader_mac.mm",
|
||||
"//chrome/browser/icon_loader_win.cc",
|
||||
"//chrome/browser/icon_manager.cc",
|
||||
"//chrome/browser/icon_manager.h",
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_mac.h",
|
||||
"//chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm",
|
||||
"//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",
|
||||
@@ -49,32 +57,14 @@ static_library("chrome") {
|
||||
"//chrome/browser/ssl/tls_deprecation_config.cc",
|
||||
"//chrome/browser/ui/views/autofill/autofill_popup_view_utils.cc",
|
||||
"//chrome/browser/ui/views/autofill/autofill_popup_view_utils.h",
|
||||
"//chrome/browser/win/chrome_process_finder.cc",
|
||||
"//chrome/browser/win/chrome_process_finder.h",
|
||||
"//chrome/child/v8_crashpad_support_win.cc",
|
||||
"//chrome/child/v8_crashpad_support_win.h",
|
||||
"//extensions/browser/app_window/size_constraints.cc",
|
||||
"//extensions/browser/app_window/size_constraints.h",
|
||||
]
|
||||
|
||||
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",
|
||||
]
|
||||
}
|
||||
|
||||
if (is_win) {
|
||||
sources += [
|
||||
"//chrome/browser/extensions/global_shortcut_listener_win.cc",
|
||||
"//chrome/browser/extensions/global_shortcut_listener_win.h",
|
||||
"//chrome/browser/icon_loader_win.cc",
|
||||
"//chrome/browser/win/chrome_process_finder.cc",
|
||||
"//chrome/browser/win/chrome_process_finder.h",
|
||||
"//chrome/child/v8_crashpad_support_win.cc",
|
||||
"//chrome/child/v8_crashpad_support_win.h",
|
||||
]
|
||||
}
|
||||
|
||||
public_deps = [
|
||||
"//chrome/common",
|
||||
"//chrome/common:version_header",
|
||||
@@ -276,17 +266,6 @@ static_library("chrome") {
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_mas_build) {
|
||||
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump.h" ]
|
||||
if (is_mac) {
|
||||
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump_mac.cc" ]
|
||||
} else if (is_win) {
|
||||
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump_win.cc" ]
|
||||
} else {
|
||||
sources += [ "//chrome/browser/hang_monitor/hang_crash_dump.cc" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
source_set("plugins") {
|
||||
|
||||
@@ -826,9 +826,10 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
|
||||
to_send.append(current_dir.value());
|
||||
|
||||
const std::vector<std::string>& argv = electron::ElectronCommandLine::argv();
|
||||
for (const auto& arg : argv) {
|
||||
for (std::vector<std::string>::const_iterator it = argv.begin();
|
||||
it != argv.end(); ++it) {
|
||||
to_send.push_back(kTokenDelimiter);
|
||||
to_send.append(arg);
|
||||
to_send.append(*it);
|
||||
}
|
||||
|
||||
// Send the message
|
||||
|
||||
@@ -122,7 +122,8 @@ void GlobalMenuBarRegistrarX11::OnNameOwnerChanged(GObject* /* ignored */,
|
||||
GParamSpec* /* ignored */) {
|
||||
// If the name owner changed, we need to reregister all the live x11::Window
|
||||
// with the system.
|
||||
for (const auto& window : live_windows_) {
|
||||
RegisterXWindow(window);
|
||||
for (std::set<x11::Window>::const_iterator it = live_windows_.begin();
|
||||
it != live_windows_.end(); ++it) {
|
||||
RegisterXWindow(*it);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ an issue:
|
||||
* [Accessibility](tutorial/accessibility.md)
|
||||
* [Spectron](tutorial/accessibility.md#spectron)
|
||||
* [Devtron](tutorial/accessibility.md#devtron)
|
||||
* [Enabling Accessibility](tutorial/accessibility.md#enabling-accessibility)
|
||||
* [Manually Enabling Accessibility Features](tutorial/accessibility.md#manually-enabling-accessibility-features)
|
||||
* [Testing and Debugging](tutorial/application-debugging.md)
|
||||
* [Debugging the Main Process](tutorial/debugging-main-process.md)
|
||||
* [Debugging the Main Process with Visual Studio Code](tutorial/debugging-main-process-vscode.md)
|
||||
|
||||
@@ -32,8 +32,7 @@ In most cases, you should do everything in the `ready` event handler.
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `launchInfo` Record<string, any> _macOS_
|
||||
* `launchInfo` unknown _macOS_
|
||||
|
||||
Emitted once, when Electron has finished initializing. On macOS, `launchInfo`
|
||||
holds the `userInfo` of the `NSUserNotification` that was used to open the
|
||||
@@ -403,7 +402,7 @@ Returns:
|
||||
* `killed` - Process was sent a SIGTERM or otherwise killed externally
|
||||
* `crashed` - Process crashed
|
||||
* `oom` - Process ran out of memory
|
||||
* `launch-failed` - Process never successfully launched
|
||||
* `launch-failure` - Process never successfully launched
|
||||
* `integrity-failure` - Windows code integrity checks failed
|
||||
|
||||
Emitted when the renderer process unexpectedly disappears. This is normally
|
||||
@@ -429,7 +428,7 @@ Returns:
|
||||
* `killed` - Process was sent a SIGTERM or otherwise killed externally
|
||||
* `crashed` - Process crashed
|
||||
* `oom` - Process ran out of memory
|
||||
* `launch-failed` - Process never successfully launched
|
||||
* `launch-failure` - Process never successfully launched
|
||||
* `integrity-failure` - Windows code integrity checks failed
|
||||
* `exitCode` Number - The exit code for the process
|
||||
(e.g. status from waitpid if on posix, from GetExitCodeProcess on Windows).
|
||||
@@ -502,7 +501,7 @@ Returns:
|
||||
Emitted when `desktopCapturer.getSources()` is called in the renderer process of `webContents`.
|
||||
Calling `event.preventDefault()` will make it return empty sources.
|
||||
|
||||
### Event: 'remote-require'
|
||||
### Event: 'remote-require' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -514,7 +513,7 @@ Emitted when `remote.require()` is called in the renderer process of `webContent
|
||||
Calling `event.preventDefault()` will prevent the module from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Event: 'remote-get-global'
|
||||
### Event: 'remote-get-global' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -526,7 +525,7 @@ Emitted when `remote.getGlobal()` is called in the renderer process of `webConte
|
||||
Calling `event.preventDefault()` will prevent the global from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Event: 'remote-get-builtin'
|
||||
### Event: 'remote-get-builtin' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -538,7 +537,7 @@ Emitted when `remote.getBuiltin()` is called in the renderer process of `webCont
|
||||
Calling `event.preventDefault()` will prevent the module from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Event: 'remote-get-current-window'
|
||||
### Event: 'remote-get-current-window' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -549,7 +548,7 @@ Emitted when `remote.getCurrentWindow()` is called in the renderer process of `w
|
||||
Calling `event.preventDefault()` will prevent the object from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
### Event: 'remote-get-current-web-contents'
|
||||
### Event: 'remote-get-current-web-contents' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -1341,7 +1340,7 @@ systems Application folder. Use in combination with `app.moveToApplicationsFolde
|
||||
### `app.moveToApplicationsFolder([options])` _macOS_
|
||||
|
||||
* `options` Object (optional)
|
||||
* `conflictHandler` Function\<Boolean> (optional) - A handler for potential conflict in move failure.
|
||||
* `conflictHandler` Function<Boolean> (optional) - A handler for potential conflict in move failure.
|
||||
* `conflictType` String - The type of move conflict encountered by the handler; can be `exists` or `existsAndRunning`, where `exists` means that an app of the same name is present in the Applications directory and `existsAndRunning` means both that it exists and that it's presently running.
|
||||
|
||||
Returns `Boolean` - Whether the move was successful. Please note that if
|
||||
@@ -1485,12 +1484,3 @@ which native modules you can use in the renderer process. For more information
|
||||
on the direction Electron is going with renderer process restarts and usage of
|
||||
native modules in the renderer process please check out this
|
||||
[Tracking Issue](https://github.com/electron/electron/issues/18397).
|
||||
|
||||
### `app.runningUnderRosettaTranslation` _macOS_ _Readonly_
|
||||
|
||||
A `Boolean` which when `true` indicates that the app is currently running
|
||||
under the [Rosetta Translator Environment](https://en.wikipedia.org/wiki/Rosetta_(software)).
|
||||
|
||||
You can use this property to prompt users to download the arm64 version of
|
||||
your application when they are running the x64 version under Rosetta
|
||||
incorrectly.
|
||||
|
||||
@@ -8,9 +8,6 @@ Process: [Main](../glossary.md#main-process)
|
||||
// In the main process.
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
// Or use `remote` from the renderer process.
|
||||
// const { BrowserWindow } = require('electron').remote
|
||||
|
||||
const win = new BrowserWindow({ width: 800, height: 600 })
|
||||
|
||||
// Load a remote URL
|
||||
@@ -541,12 +538,6 @@ Note that this is only emitted when the window is being resized manually. Resizi
|
||||
|
||||
Emitted after the window has been resized.
|
||||
|
||||
#### Event: 'resized' _macOS_ _Windows_
|
||||
|
||||
Emitted once when the window has finished being resized.
|
||||
|
||||
This is usually emitted when the window has been resized manually. On macOS, resizing the window with `setBounds`/`setSize` and setting the `animate` parameter to `true` will also emit this event once resizing has finished.
|
||||
|
||||
#### Event: 'will-move' _macOS_ _Windows_
|
||||
|
||||
Returns:
|
||||
@@ -562,12 +553,12 @@ Note that this is only emitted when the window is being resized manually. Resizi
|
||||
|
||||
Emitted when the window is being moved to a new position.
|
||||
|
||||
#### Event: 'moved' _macOS_ _Windows_
|
||||
__Note__: On macOS this event is an alias of `moved`.
|
||||
|
||||
#### Event: 'moved' _macOS_
|
||||
|
||||
Emitted once when the window is moved to a new position.
|
||||
|
||||
__Note__: On macOS this event is an alias of `move`.
|
||||
|
||||
#### Event: 'enter-full-screen'
|
||||
|
||||
Emitted when the window enters a full-screen state.
|
||||
@@ -676,20 +667,6 @@ Emitted when the window has closed a sheet.
|
||||
|
||||
Emitted when the native new tab button is clicked.
|
||||
|
||||
#### Event: 'system-context-menu' _Windows_
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `point` [Point](structures/point.md) - The screen coordinates the context menu was triggered at
|
||||
|
||||
Emitted when the system context menu is triggered on the window, this is
|
||||
normally only triggered when the user right clicks on the non-client area
|
||||
of your window. This is the window titlebar or any area you have declared
|
||||
as `-webkit-app-region: drag` in a frameless window.
|
||||
|
||||
Calling `event.preventDefault()` will prevent the menu from being displayed.
|
||||
|
||||
### Static Methods
|
||||
|
||||
The `BrowserWindow` class has the following static methods:
|
||||
@@ -1049,7 +1026,7 @@ Returns `Boolean` - Whether the window is in simple (pre-Lion) fullscreen mode.
|
||||
|
||||
Returns `Boolean` - Whether the window is in normal state (not maximized, not minimized, not in fullscreen mode).
|
||||
|
||||
#### `win.setAspectRatio(aspectRatio[, extraSize])`
|
||||
#### `win.setAspectRatio(aspectRatio[, extraSize])` _macOS_ _Linux_
|
||||
|
||||
* `aspectRatio` Float - The aspect ratio to maintain for some portion of the
|
||||
content view.
|
||||
@@ -1070,9 +1047,6 @@ the player itself we would call this function with arguments of 16/9 and
|
||||
are within the content view--only that they exist. Sum any extra width and
|
||||
height areas you have within the overall content view.
|
||||
|
||||
The aspect ratio is not respected when window is resized programmingly with
|
||||
APIs like `win.setSize`.
|
||||
|
||||
#### `win.setBackgroundColor(backgroundColor)`
|
||||
|
||||
* `backgroundColor` String - Window's background color as a hexadecimal value,
|
||||
@@ -1372,6 +1346,17 @@ Enters or leaves kiosk mode.
|
||||
|
||||
Returns `Boolean` - Whether the window is in kiosk mode.
|
||||
|
||||
#### `win.isTabletMode()` _Windows_
|
||||
|
||||
Returns `Boolean` - Whether the window is in Windows 10 tablet mode.
|
||||
|
||||
Since Windows 10 users can [use their PC as tablet](https://support.microsoft.com/en-us/help/17210/windows-10-use-your-pc-like-a-tablet),
|
||||
under this mode apps can choose to optimize their UI for tablets, such as
|
||||
enlarging the titlebar and hiding titlebar buttons.
|
||||
|
||||
This API returns whether the window is in tablet mode, and the `resize` event
|
||||
can be be used to listen to changes to tablet mode.
|
||||
|
||||
#### `win.getMediaSourceId()`
|
||||
|
||||
Returns `String` - Window id in the format of DesktopCapturerSource's id. For example "window:1234:0".
|
||||
|
||||
@@ -198,14 +198,6 @@ logging level for all code in the source files under a `foo/bar` directory.
|
||||
|
||||
This switch only works when `--enable-logging` is also passed.
|
||||
|
||||
### --force_high_performance_gpu
|
||||
|
||||
Force using discrete GPU when there are multiple GPUs available.
|
||||
|
||||
### --force_low_power_gpu
|
||||
|
||||
Force using integrated GPU when there are multiple GPUs available.
|
||||
|
||||
## Node.js Flags
|
||||
|
||||
Electron supports some of the [CLI flags][node-cli] supported by Node.js.
|
||||
|
||||
@@ -16,7 +16,7 @@ const { app, contentTracing } = require('electron')
|
||||
app.whenReady().then(() => {
|
||||
(async () => {
|
||||
await contentTracing.startRecording({
|
||||
included_categories: ['*']
|
||||
include_categories: ['*']
|
||||
})
|
||||
console.log('Tracing started')
|
||||
await new Promise(resolve => setTimeout(resolve, 5000))
|
||||
|
||||
@@ -59,7 +59,7 @@ The `crashReporter` module has the following methods:
|
||||
* `rateLimit` Boolean (optional) _macOS_ _Windows_ - If true, limit the
|
||||
number of crashes uploaded to 1/hour. Default is `false`.
|
||||
* `compress` Boolean (optional) - If true, crash reports will be compressed
|
||||
and uploaded with `Content-Encoding: gzip`. Default is `false`.
|
||||
and uploaded with `Content-Encoding: gzip`. Default is `true`.
|
||||
* `extra` Record<String, String> (optional) - Extra string key/value
|
||||
annotations that will be sent along with crash reports that are generated
|
||||
in the main process. Only string values are supported. Crashes generated in
|
||||
|
||||
@@ -11,14 +11,6 @@ const { dialog } = require('electron')
|
||||
console.log(dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'] }))
|
||||
```
|
||||
|
||||
The Dialog is opened from Electron's main thread. If you want to use the dialog
|
||||
object from a renderer process, remember to access it using the remote:
|
||||
|
||||
```javascript
|
||||
const { dialog } = require('electron').remote
|
||||
console.log(dialog)
|
||||
```
|
||||
|
||||
## Methods
|
||||
|
||||
The `dialog` module has the following methods:
|
||||
|
||||
@@ -74,6 +74,7 @@ The following methods of `chrome.runtime` are supported:
|
||||
|
||||
- `chrome.runtime.getBackgroundPage`
|
||||
- `chrome.runtime.getManifest`
|
||||
- `chrome.runtime.getPlatformInfo`
|
||||
- `chrome.runtime.getURL`
|
||||
- `chrome.runtime.connect`
|
||||
- `chrome.runtime.sendMessage`
|
||||
@@ -114,9 +115,3 @@ The following methods of `chrome.management` are supported:
|
||||
- `chrome.management.getPermissionWarningsByManifest`
|
||||
- `chrome.management.onEnabled`
|
||||
- `chrome.management.onDisabled`
|
||||
|
||||
### `chrome.webRequest`
|
||||
|
||||
All features of this API are supported.
|
||||
|
||||
> **NOTE:** Electron's [`webRequest`](web-request.md) module takes precedence over `chrome.webRequest` if there are conflicting handlers.
|
||||
|
||||
@@ -112,13 +112,19 @@ optional parameter can be used to forward mouse move messages to the web page,
|
||||
allowing events such as `mouseleave` to be emitted:
|
||||
|
||||
```javascript
|
||||
const win = require('electron').remote.getCurrentWindow()
|
||||
const { ipcRenderer } = require('electron')
|
||||
const el = document.getElementById('clickThroughElement')
|
||||
el.addEventListener('mouseenter', () => {
|
||||
win.setIgnoreMouseEvents(true, { forward: true })
|
||||
ipcRenderer.send('set-ignore-mouse-events', true, { forward: true })
|
||||
})
|
||||
el.addEventListener('mouseleave', () => {
|
||||
win.setIgnoreMouseEvents(false)
|
||||
ipcRenderer.send('set-ignore-mouse-events', false)
|
||||
})
|
||||
|
||||
// Main process
|
||||
const { ipcMain } = require('electron')
|
||||
ipcMain.on('set-ignore-mouse-events', (event, ...args) => {
|
||||
BrowserWindow.fromWebContents(event.sender).setIgnoreMouseEvents(...args)
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ with the operating system so that you can customize the operations for various
|
||||
shortcuts.
|
||||
|
||||
**Note:** The shortcut is global; it will work even if the app does
|
||||
not have the keyboard focus. This module cannot be used before the `ready`
|
||||
not have the keyboard focus. You should not use this module until the `ready`
|
||||
event of the app module is emitted.
|
||||
|
||||
```javascript
|
||||
|
||||
@@ -91,7 +91,7 @@ Removes listeners of the specified `channel`.
|
||||
### `ipcMain.handle(channel, listener)`
|
||||
|
||||
* `channel` String
|
||||
* `listener` Function<Promise\<void> | any>
|
||||
* `listener` Function<Promise<void> | any>
|
||||
* `event` IpcMainInvokeEvent
|
||||
* `...args` any[]
|
||||
|
||||
@@ -123,7 +123,7 @@ WebContents is the source of the invoke request.
|
||||
### `ipcMain.handleOnce(channel, listener)`
|
||||
|
||||
* `channel` String
|
||||
* `listener` Function<Promise\<void> | any>
|
||||
* `listener` Function<Promise<void> | any>
|
||||
* `event` IpcMainInvokeEvent
|
||||
* `...args` any[]
|
||||
|
||||
|
||||
@@ -141,13 +141,7 @@ can have a submenu.
|
||||
|
||||
## Examples
|
||||
|
||||
The `Menu` class is only available in the main process, but you can also use it
|
||||
in the render process via the [`remote`](remote.md) module.
|
||||
|
||||
### Main process
|
||||
|
||||
An example of creating the application menu in the main process with the
|
||||
simple template API:
|
||||
An example of creating the application menu with the simple template API:
|
||||
|
||||
```javascript
|
||||
const { app, Menu } = require('electron')
|
||||
@@ -257,26 +251,36 @@ Menu.setApplicationMenu(menu)
|
||||
|
||||
### Render process
|
||||
|
||||
Below is an example of creating a menu dynamically in a web page
|
||||
(render process) by using the [`remote`](remote.md) module, and showing it when
|
||||
the user right clicks the page:
|
||||
To create menus initiated by the renderer process, send the required
|
||||
information to the main process using IPC and have the main process display the
|
||||
menu on behalf of the renderer.
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
<script>
|
||||
const { remote } = require('electron')
|
||||
const { Menu, MenuItem } = remote
|
||||
|
||||
const menu = new Menu()
|
||||
menu.append(new MenuItem({ label: 'MenuItem1', click() { console.log('item 1 clicked') } }))
|
||||
menu.append(new MenuItem({ type: 'separator' }))
|
||||
menu.append(new MenuItem({ label: 'MenuItem2', type: 'checkbox', checked: true }))
|
||||
Below is an example of showing a menu when the user right clicks the page:
|
||||
|
||||
```js
|
||||
// renderer
|
||||
window.addEventListener('contextmenu', (e) => {
|
||||
e.preventDefault()
|
||||
menu.popup({ window: remote.getCurrentWindow() })
|
||||
}, false)
|
||||
</script>
|
||||
ipcRenderer.send('show-context-menu')
|
||||
})
|
||||
|
||||
ipcRenderer.on('context-menu-command', (e, command) => {
|
||||
// ...
|
||||
})
|
||||
|
||||
// main
|
||||
ipcMain.on('show-context-menu', (event) => {
|
||||
const template = [
|
||||
{
|
||||
label: 'Menu Item 1',
|
||||
click: () => { event.sender.send('context-menu-command', 'menu-item-1') }
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{ label: 'Menu Item 2', type: 'checkbox', checked: true }
|
||||
]
|
||||
const menu = Menu.buildFromTemplate(template)
|
||||
menu.popup(BrowserWindow.fromWebContents(event.sender))
|
||||
})
|
||||
```
|
||||
|
||||
## Notes on macOS Application Menu
|
||||
|
||||
@@ -4,6 +4,16 @@
|
||||
|
||||
Process: [Renderer](../glossary.md#renderer-process)
|
||||
|
||||
> ⚠️ WARNING ⚠️
|
||||
> The `remote` module is [deprecated](https://github.com/electron/electron/issues/21408).
|
||||
> Instead of `remote`, use [`ipcRenderer`](ipc-renderer.md) and
|
||||
> [`ipcMain`](ipc-main.md).
|
||||
>
|
||||
> Read more about why the `remote` module is deprecated [here](https://medium.com/@nornagon/electrons-remote-module-considered-harmful-70d69500f31).
|
||||
>
|
||||
> If you still want to use `remote` despite the performance and security
|
||||
> concerns, see [@electron/remote](https://github.com/electron/remote).
|
||||
|
||||
The `remote` module provides a simple way to do inter-process communication
|
||||
(IPC) between the renderer process (web page) and the main process.
|
||||
|
||||
@@ -140,11 +150,32 @@ console.log(app)
|
||||
|
||||
The `remote` module has the following methods:
|
||||
|
||||
### `remote.require(module)`
|
||||
### `remote.getCurrentWindow()`
|
||||
|
||||
* `module` String
|
||||
Returns [`BrowserWindow`](browser-window.md) - The window to which this web page
|
||||
belongs.
|
||||
|
||||
Returns `any` - The object returned by `require(module)` in the main process.
|
||||
**Note:** Do not use `removeAllListeners` on [`BrowserWindow`](browser-window.md).
|
||||
Use of this can remove all [`blur`](https://developer.mozilla.org/en-US/docs/Web/Events/blur)
|
||||
listeners, disable click events on touch bar buttons, and other unintended
|
||||
consequences.
|
||||
|
||||
### `remote.getCurrentWebContents()`
|
||||
|
||||
Returns [`WebContents`](web-contents.md) - The web contents of this web page.
|
||||
|
||||
### `remote.getGlobal(name)`
|
||||
|
||||
* `name` String
|
||||
|
||||
Returns `any` - The global variable of `name` (e.g. `global[name]`) in the main
|
||||
process.
|
||||
|
||||
## Properties
|
||||
|
||||
### `remote.require`
|
||||
|
||||
A `NodeJS.Require` function equivalent to `require(module)` in the main process.
|
||||
Modules specified by their relative path will resolve relative to the entrypoint
|
||||
of the main process.
|
||||
|
||||
@@ -176,28 +207,6 @@ module.exports = 'bar'
|
||||
const foo = require('electron').remote.require('./foo') // bar
|
||||
```
|
||||
|
||||
### `remote.getCurrentWindow()`
|
||||
|
||||
Returns [`BrowserWindow`](browser-window.md) - The window to which this web page
|
||||
belongs.
|
||||
|
||||
**Note:** Do not use `removeAllListeners` on [`BrowserWindow`](browser-window.md).
|
||||
Use of this can remove all [`blur`](https://developer.mozilla.org/en-US/docs/Web/Events/blur)
|
||||
listeners, disable click events on touch bar buttons, and other unintended
|
||||
consequences.
|
||||
|
||||
### `remote.getCurrentWebContents()`
|
||||
|
||||
Returns [`WebContents`](web-contents.md) - The web contents of this web page.
|
||||
|
||||
### `remote.getGlobal(name)`
|
||||
|
||||
* `name` String
|
||||
|
||||
Returns `any` - The global variable of `name` (e.g. `global[name]`) in the main
|
||||
process.
|
||||
|
||||
## Properties
|
||||
|
||||
### `remote.process` _Readonly_
|
||||
|
||||
|
||||
@@ -88,26 +88,17 @@ and preload.js:
|
||||
|
||||
```js
|
||||
// This file is loaded whenever a javascript context is created. It runs in a
|
||||
// private scope that can access a subset of Electron renderer APIs. We must be
|
||||
// careful to not leak any objects into the global scope!
|
||||
const { ipcRenderer, remote } = require('electron')
|
||||
const fs = remote.require('fs')
|
||||
|
||||
// read a configuration file using the `fs` module
|
||||
const buf = fs.readFileSync('allowed-popup-urls.json')
|
||||
const allowedUrls = JSON.parse(buf.toString('utf8'))
|
||||
// private scope that can access a subset of Electron renderer APIs. Without
|
||||
// contextIsolation enabled, it's possible to accidentally leak privileged
|
||||
// globals like ipcRenderer to web content.
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
const defaultWindowOpen = window.open
|
||||
|
||||
function customWindowOpen (url, ...args) {
|
||||
if (allowedUrls.indexOf(url) === -1) {
|
||||
ipcRenderer.sendSync('blocked-popup-notification', location.origin, url)
|
||||
return null
|
||||
}
|
||||
return defaultWindowOpen(url, ...args)
|
||||
window.open = function customWindowOpen (url, ...args) {
|
||||
ipcRenderer.send('report-window-open', location.origin, url, args)
|
||||
return defaultWindowOpen(url + '?from_electron=1', ...args)
|
||||
}
|
||||
|
||||
window.open = customWindowOpen
|
||||
```
|
||||
|
||||
Important things to notice in the preload script:
|
||||
@@ -115,8 +106,6 @@ Important things to notice in the preload script:
|
||||
- Even though the sandboxed renderer doesn't have Node.js running, it still has
|
||||
access to a limited node-like environment: `Buffer`, `process`, `setImmediate`,
|
||||
`clearImmediate` and `require` are available.
|
||||
- The preload script can indirectly access all APIs from the main process through the
|
||||
`remote` and `ipcRenderer` modules.
|
||||
- The preload script must be contained in a single script, but it is possible to have
|
||||
complex preload code composed with multiple modules by using a tool like
|
||||
webpack or browserify. An example of using browserify is below.
|
||||
@@ -144,15 +133,12 @@ following modules:
|
||||
- `desktopCapturer`
|
||||
- `ipcRenderer`
|
||||
- `nativeImage`
|
||||
- `remote`
|
||||
- `webFrame`
|
||||
- `events`
|
||||
- `timers`
|
||||
- `url`
|
||||
|
||||
More may be added as needed to expose more Electron APIs in the sandbox, but any
|
||||
module in the main process can already be used through
|
||||
`electron.remote.require`.
|
||||
More may be added as needed to expose more Electron APIs in the sandbox.
|
||||
|
||||
## Rendering untrusted content
|
||||
|
||||
|
||||
@@ -349,7 +349,6 @@ win.webContents.session.setCertificateVerifyProc((request, callback) => {
|
||||
* `handler` Function | null
|
||||
* `webContents` [WebContents](web-contents.md) - WebContents requesting the permission. Please note that if the request comes from a subframe you should use `requestingUrl` to check the request origin.
|
||||
* `permission` String - The type of requested permission.
|
||||
* `clipboard-read` - Request access to read from the clipboard.
|
||||
* `media` - Request access to media devices such as camera, microphone and speakers.
|
||||
* `mediaKeySystem` - Request access to DRM protected content.
|
||||
* `geolocation` - Request access to user's current location.
|
||||
@@ -385,7 +384,7 @@ session.fromPartition('some-partition').setPermissionRequestHandler((webContents
|
||||
|
||||
#### `ses.setPermissionCheckHandler(handler)`
|
||||
|
||||
* `handler` Function\<Boolean> | null
|
||||
* `handler` Function<Boolean> | null
|
||||
* `webContents` [WebContents](web-contents.md) - WebContents checking the permission. Please note that if the request comes from a subframe you should use `requestingUrl` to check the request origin.
|
||||
* `permission` String - Enum of 'media'.
|
||||
* `requestingOrigin` String - The origin URL of the permission check
|
||||
|
||||
@@ -45,15 +45,27 @@ Returns `Promise<void>`
|
||||
|
||||
Open the given external protocol URL in the desktop's default manner. (For example, mailto: URLs in the user's default mail agent).
|
||||
|
||||
### `shell.moveItemToTrash(fullPath[, deleteOnFail])`
|
||||
### `shell.moveItemToTrash(fullPath[, deleteOnFail])` _Deprecated_
|
||||
|
||||
* `fullPath` String
|
||||
* `deleteOnFail` Boolean (optional) - Whether or not to unilaterally remove the item if the Trash is disabled or unsupported on the volume. _macOS_
|
||||
|
||||
Returns `Boolean` - Whether the item was successfully moved to the trash or otherwise deleted.
|
||||
|
||||
> NOTE: This method is deprecated. Use `shell.trashItem` instead.
|
||||
|
||||
Move the given file to trash and returns a boolean status for the operation.
|
||||
|
||||
### `shell.trashItem(path)`
|
||||
|
||||
* `path` String - path to the item to be moved to the trash.
|
||||
|
||||
Returns `Promise<void>` - Resolves when the operation has been completed.
|
||||
Rejects if there was an error while deleting the requested item.
|
||||
|
||||
This moves a path to the OS-specific trash location (Trash on macOS, Recycle
|
||||
Bin on Windows, and a desktop-environment-specific location on Linux).
|
||||
|
||||
### `shell.beep()`
|
||||
|
||||
Play the beep sound.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# IpcMainEvent Object extends `Event`
|
||||
|
||||
* `processId` Integer - The internal ID of the renderer process that sent this message
|
||||
* `frameId` Integer - The ID of the renderer frame that sent this message
|
||||
* `returnValue` any - Set this to the value to be returned in a synchronous message
|
||||
* `sender` WebContents - Returns the `webContents` that sent the message
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# IpcMainInvokeEvent Object extends `Event`
|
||||
|
||||
* `processId` Integer - The internal ID of the renderer process that sent this message
|
||||
* `frameId` Integer - The ID of the renderer frame that sent this message
|
||||
* `sender` WebContents - Returns the `webContents` that sent the message
|
||||
|
||||
@@ -13,3 +13,5 @@ target's icon.
|
||||
DLL or EXE. Default is 0.
|
||||
* `appUserModelId` String (optional) - The Application User Model ID. Default
|
||||
is empty.
|
||||
* `toastActivatorClsid` String (optional) - The Application Toast Activator CLSID. Needed
|
||||
for participating in Action Center.
|
||||
|
||||
5
docs/api/structures/stream-protocol-response.md
Normal file
5
docs/api/structures/stream-protocol-response.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# StreamProtocolResponse Object
|
||||
|
||||
* `statusCode` Number (optional) - The HTTP response code.
|
||||
* `headers` Record<String, String | String[]> (optional) - An object containing the response headers.
|
||||
* `data` ReadableStream | null - A Node.js readable stream representing the response body.
|
||||
5
docs/api/structures/string-protocol-response.md
Normal file
5
docs/api/structures/string-protocol-response.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# StringProtocolResponse Object
|
||||
|
||||
* `mimeType` String (optional) - MIME type of the response.
|
||||
* `charset` String (optional) - Charset of the response.
|
||||
* `data` String | null - A string representing the response body.
|
||||
@@ -9,7 +9,7 @@ the [native modules](../tutorial/using-native-node-modules.md)).
|
||||
Electron also provides some extra built-in modules for developing native
|
||||
desktop applications. Some modules are only available in the main process, some
|
||||
are only available in the renderer process (web page), and some can be used in
|
||||
both processes.
|
||||
either process type.
|
||||
|
||||
The basic rule is: if a module is [GUI][gui] or low-level system related, then
|
||||
it should be only available in the main process. You need to be familiar with
|
||||
@@ -29,15 +29,15 @@ app.whenReady().then(() => {
|
||||
```
|
||||
|
||||
The renderer process is no different than a normal web page, except for the
|
||||
extra ability to use node modules:
|
||||
extra ability to use node modules if `nodeIntegration` is enabled:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
const { app } = require('electron').remote
|
||||
console.log(app.getVersion())
|
||||
const fs = require('fs')
|
||||
console.log(fs.readFileSync(__filename, 'utf8'))
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -42,8 +42,7 @@ returns `null`.
|
||||
|
||||
* `id` Integer
|
||||
|
||||
Returns `WebContents` | undefined - A WebContents instance with the given ID, or
|
||||
`undefined` if there is no WebContents associated with the given ID.
|
||||
Returns `WebContents` - A WebContents instance with the given ID.
|
||||
|
||||
## Class: WebContents
|
||||
|
||||
@@ -365,7 +364,7 @@ Returns:
|
||||
* `killed` - Process was sent a SIGTERM or otherwise killed externally
|
||||
* `crashed` - Process crashed
|
||||
* `oom` - Process ran out of memory
|
||||
* `launch-failed` - Process never successfully launched
|
||||
* `launch-failure` - Process never successfully launched
|
||||
* `integrity-failure` - Windows code integrity checks failed
|
||||
|
||||
Emitted when the renderer process unexpectedly disappears. This is normally
|
||||
@@ -785,7 +784,7 @@ Returns:
|
||||
Emitted when `desktopCapturer.getSources()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will make it return empty sources.
|
||||
|
||||
#### Event: 'remote-require'
|
||||
#### Event: 'remote-require' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -796,7 +795,7 @@ Emitted when `remote.require()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the module from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
#### Event: 'remote-get-global'
|
||||
#### Event: 'remote-get-global' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -807,7 +806,7 @@ Emitted when `remote.getGlobal()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the global from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
#### Event: 'remote-get-builtin'
|
||||
#### Event: 'remote-get-builtin' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -818,7 +817,7 @@ Emitted when `remote.getBuiltin()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the module from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
#### Event: 'remote-get-current-window'
|
||||
#### Event: 'remote-get-current-window' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -828,7 +827,7 @@ Emitted when `remote.getCurrentWindow()` is called in the renderer process.
|
||||
Calling `event.preventDefault()` will prevent the object from being returned.
|
||||
Custom value can be returned by setting `event.returnValue`.
|
||||
|
||||
#### Event: 'remote-get-current-web-contents'
|
||||
#### Event: 'remote-get-current-web-contents' _Deprecated_
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -999,34 +998,6 @@ Navigates to the specified offset from the "current entry".
|
||||
|
||||
Returns `Boolean` - Whether the renderer process has crashed.
|
||||
|
||||
#### `contents.forcefullyCrashRenderer()`
|
||||
|
||||
Forcefully terminates the renderer process that is currently hosting this
|
||||
`webContents`. This will cause the `render-process-gone` event to be emitted
|
||||
with the `reason=killed || reason=crashed`. Please note that some webContents share renderer
|
||||
processes and therefore calling this method may also crash the host process
|
||||
for other webContents as well.
|
||||
|
||||
Calling `reload()` immediately after calling this
|
||||
method will force the reload to occur in a new process. This should be used
|
||||
when this process is unstable or unusable, for instance in order to recover
|
||||
from the `unresponsive` event.
|
||||
|
||||
```js
|
||||
contents.on('unresponsive', async () => {
|
||||
const { response } = await dialog.showMessageBox({
|
||||
message: 'App X has become unresponsive',
|
||||
title: 'Do you want to try forcefully reloading the app?',
|
||||
buttons: ['OK', 'Cancel'],
|
||||
cancelId: 1
|
||||
})
|
||||
if (response === 0) {
|
||||
contents.forcefullyCrashRenderer()
|
||||
contents.reload()
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
#### `contents.setUserAgent(userAgent)`
|
||||
|
||||
* `userAgent` String
|
||||
@@ -1146,6 +1117,10 @@ increment above or below represents zooming 20% larger or smaller to default
|
||||
limits of 300% and 50% of original size, respectively. The formula for this is
|
||||
`scale := 1.2 ^ level`.
|
||||
|
||||
> **NOTE**: The zoom policy at the Chromium level is same-origin, meaning that the
|
||||
> zoom level for a specific domain propagates across all instances of windows with
|
||||
> the same domain. Differentiating the window URLs will make zoom work per-window.
|
||||
|
||||
#### `contents.getZoomLevel()`
|
||||
|
||||
Returns `Number` - the current zoom level.
|
||||
@@ -1325,7 +1300,7 @@ Returns [`PrinterInfo[]`](structures/printer-info.md)
|
||||
* `pagesPerSheet` Number (optional) - The number of pages to print per page sheet.
|
||||
* `collate` Boolean (optional) - Whether the web page should be collated.
|
||||
* `copies` Number (optional) - The number of copies of the web page to print.
|
||||
* `pageRanges` Object[] (optional) - The page range to print. On macOS, only one range is honored.
|
||||
* `pageRanges` Object[] (optional) - The page range to print. On macOS, only one range is honored.
|
||||
* `from` Number - Index of the first page to print (0-based).
|
||||
* `to` Number - Index of the last page to print (inclusive) (0-based).
|
||||
* `duplexMode` String (optional) - Set the duplex mode of the printed web page. Can be `simplex`, `shortEdge`, or `longEdge`.
|
||||
@@ -1482,7 +1457,7 @@ An example of showing devtools in a `<webview>` tag:
|
||||
<webview id="browser" src="https://github.com"></webview>
|
||||
<webview id="devtools" src="about:blank"></webview>
|
||||
<script>
|
||||
const { webContents } = require('electron').remote
|
||||
const { ipcRenderer } = require('electron')
|
||||
const emittedOnce = (element, eventName) => new Promise(resolve => {
|
||||
element.addEventListener(eventName, event => resolve(event), { once: true })
|
||||
})
|
||||
@@ -1491,16 +1466,26 @@ An example of showing devtools in a `<webview>` tag:
|
||||
const browserReady = emittedOnce(browserView, 'dom-ready')
|
||||
const devtoolsReady = emittedOnce(devtoolsView, 'dom-ready')
|
||||
Promise.all([browserReady, devtoolsReady]).then(() => {
|
||||
const browser = webContents.fromId(browserView.getWebContentsId())
|
||||
const devtools = webContents.fromId(devtoolsView.getWebContentsId())
|
||||
browser.setDevToolsWebContents(devtools)
|
||||
browser.openDevTools()
|
||||
const targetId = browserView.getWebContentsId()
|
||||
const devtoolsId = devtoolsView.getWebContentsId()
|
||||
ipcRenderer.send('open-devtools', targetId, devtoolsId)
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```js
|
||||
// Main process
|
||||
const { ipcMain, webContents } = require('electron')
|
||||
ipcMain.on('open-devtools', (event, targetContentsId, devtoolsContentsId) => {
|
||||
const target = webContents.fromId(targetContentsId)
|
||||
const devtools = webContents.fromId(devtoolsContentsId)
|
||||
target.setDevToolsWebContents(devtools)
|
||||
target.openDevTools()
|
||||
})
|
||||
```
|
||||
|
||||
An example of showing devtools in a `BrowserWindow`:
|
||||
|
||||
```js
|
||||
@@ -1622,9 +1607,7 @@ app.whenReady().then(() => {
|
||||
|
||||
#### `contents.sendToFrame(frameId, channel, ...args)`
|
||||
|
||||
* `frameId` Integer | [number, number] - the ID of the frame to send to, or a
|
||||
pair of `[processId, frameId]` if the frame is in a different process to the
|
||||
main frame.
|
||||
* `frameId` Integer
|
||||
* `channel` String
|
||||
* `...args` any[]
|
||||
|
||||
@@ -1798,7 +1781,7 @@ Returns `Boolean` - If *offscreen rendering* is enabled returns whether it is cu
|
||||
* `fps` Integer
|
||||
|
||||
If *offscreen rendering* is enabled sets the frame rate to the specified number.
|
||||
Only values between 1 and 240 are accepted.
|
||||
Only values between 1 and 60 are accepted.
|
||||
|
||||
#### `contents.getFrameRate()`
|
||||
|
||||
@@ -1896,7 +1879,7 @@ The zoom factor is the zoom percent divided by 100, so 300% = 3.0.
|
||||
#### `contents.frameRate`
|
||||
|
||||
An `Integer` property that sets the frame rate of the web contents to the specified number.
|
||||
Only values between 1 and 240 are accepted.
|
||||
Only values between 1 and 60 are accepted.
|
||||
|
||||
Only applicable if *offscreen rendering* is enabled.
|
||||
|
||||
|
||||
@@ -41,6 +41,10 @@ Changes the zoom level to the specified level. The original size is 0 and each
|
||||
increment above or below represents zooming 20% larger or smaller to default
|
||||
limits of 300% and 50% of original size, respectively.
|
||||
|
||||
> **NOTE**: The zoom policy at the Chromium level is same-origin, meaning that the
|
||||
> zoom level for a specific domain propagates across all instances of windows with
|
||||
> the same domain. Differentiating the window URLs will make zoom work per-window.
|
||||
|
||||
### `webFrame.getZoomLevel()`
|
||||
|
||||
Returns `Number` - The current zoom level.
|
||||
|
||||
@@ -137,7 +137,7 @@ This option is disabled by default in the guest page.
|
||||
```
|
||||
|
||||
A `Boolean`. When this attribute is `false` the guest page in `webview` will not have access
|
||||
to the [`remote`](remote.md) module. The remote module is available by default.
|
||||
to the [`remote`](remote.md) module. The remote module is unavailable by default.
|
||||
|
||||
### `plugins`
|
||||
|
||||
@@ -587,7 +587,7 @@ Prints `webview`'s web page. Same as `webContents.print([options])`.
|
||||
default margin, 1 for no margin, and 2 for minimum margin.
|
||||
and `width` in microns.
|
||||
* `scaleFactor` Number (optional) - The scale factor of the web page. Can range from 0 to 100.
|
||||
* `pageRanges` Record<string, number> (optional) - The page range to print.
|
||||
* `pageRanges` Record<string, number> (optional) - The page range to print. On macOS, only the first range is honored.
|
||||
* `from` Number - Index of the first page to print (0-based).
|
||||
* `to` Number - Index of the last page to print (inclusive) (0-based).
|
||||
* `pageSize` String | Size (optional) - Specify page size of the generated PDF. Can be `A3`,
|
||||
@@ -648,6 +648,10 @@ increment above or below represents zooming 20% larger or smaller to default
|
||||
limits of 300% and 50% of original size, respectively. The formula for this is
|
||||
`scale := 1.2 ^ level`.
|
||||
|
||||
> **NOTE**: The zoom policy at the Chromium level is same-origin, meaning that the
|
||||
> zoom level for a specific domain propagates across all instances of windows with
|
||||
> the same domain. Differentiating the window URLs will make zoom work per-window.
|
||||
|
||||
### `<webview>.getZoomFactor()`
|
||||
|
||||
Returns `Number` - the current zoom factor.
|
||||
@@ -968,4 +972,4 @@ Emitted when DevTools is closed.
|
||||
Emitted when DevTools is focused / opened.
|
||||
|
||||
[runtime-enabled-features]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/runtime_enabled_features.json5?l=70
|
||||
[chrome-webview]: https://developer.chrome.com/docs/extensions/reference/webviewTag/
|
||||
[chrome-webview]: https://developer.chrome.com/apps/tags/webview
|
||||
|
||||
61
docs/breaking-changes-ns.md
Normal file
61
docs/breaking-changes-ns.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Breaking changes (NetworkService) (Draft)
|
||||
|
||||
This document describes changes to Electron APIs after migrating network code
|
||||
to NetworkService API.
|
||||
|
||||
We don't currently have an estimate of when we will enable `NetworkService` by
|
||||
default in Electron, but as Chromium is already removing non-`NetworkService`
|
||||
code, we might switch before Electron 10.
|
||||
|
||||
The content of this document should be moved to `breaking-changes.md` once we have
|
||||
determined when to enable `NetworkService` in Electron.
|
||||
|
||||
## Planned Breaking API Changes
|
||||
|
||||
### `protocol.unregisterProtocol`
|
||||
### `protocol.uninterceptProtocol`
|
||||
|
||||
The APIs are now synchronous and the optional callback is no longer needed.
|
||||
|
||||
```javascript
|
||||
// Deprecated
|
||||
protocol.unregisterProtocol(scheme, () => { /* ... */ })
|
||||
// Replace with
|
||||
protocol.unregisterProtocol(scheme)
|
||||
```
|
||||
|
||||
### `protocol.registerFileProtocol`
|
||||
### `protocol.registerBufferProtocol`
|
||||
### `protocol.registerStringProtocol`
|
||||
### `protocol.registerHttpProtocol`
|
||||
### `protocol.registerStreamProtocol`
|
||||
### `protocol.interceptFileProtocol`
|
||||
### `protocol.interceptStringProtocol`
|
||||
### `protocol.interceptBufferProtocol`
|
||||
### `protocol.interceptHttpProtocol`
|
||||
### `protocol.interceptStreamProtocol`
|
||||
|
||||
The APIs are now synchronous and the optional callback is no longer needed.
|
||||
|
||||
```javascript
|
||||
// Deprecated
|
||||
protocol.registerFileProtocol(scheme, handler, () => { /* ... */ })
|
||||
// Replace with
|
||||
protocol.registerFileProtocol(scheme, handler)
|
||||
```
|
||||
|
||||
The registered or intercepted protocol does not have effect on current page
|
||||
until navigation happens.
|
||||
|
||||
### `protocol.isProtocolHandled`
|
||||
|
||||
This API is deprecated and users should use `protocol.isProtocolRegistered`
|
||||
and `protocol.isProtocolIntercepted` instead.
|
||||
|
||||
```javascript
|
||||
// Deprecated
|
||||
protocol.isProtocolHandled(scheme).then(() => { /* ... */ })
|
||||
// Replace with
|
||||
const isRegistered = protocol.isProtocolRegistered(scheme)
|
||||
const isIntercepted = protocol.isProtocolIntercepted(scheme)
|
||||
```
|
||||
@@ -12,6 +12,20 @@ This document uses the following convention to categorize breaking changes:
|
||||
- **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release.
|
||||
- **Removed:** An API or feature was removed, and is no longer supported by Electron.
|
||||
|
||||
## Planned Breaking API Changes (13.0)
|
||||
|
||||
### Removed: `shell.moveItemToTrash()`
|
||||
|
||||
The deprecated synchronous `shell.moveItemToTrash()` API has been removed. Use
|
||||
the asynchronous `shell.trashItem()` instead.
|
||||
|
||||
```js
|
||||
// Removed in Electron 13
|
||||
shell.moveItemToTrash(path)
|
||||
// Replace with
|
||||
shell.trashItem(path).then(/* ... */)
|
||||
```
|
||||
|
||||
## Planned Breaking API Changes (12.0)
|
||||
|
||||
### Default Changed: `contextIsolation` defaults to `true`
|
||||
@@ -50,6 +64,37 @@ If your crash ingestion server does not support compressed payloads, you can
|
||||
turn off compression by specifying `{ compress: false }` in the crash reporter
|
||||
options.
|
||||
|
||||
### Deprecated: `remote` module
|
||||
|
||||
The `remote` module is deprecated in Electron 12, and will be removed in
|
||||
Electron 14. It is replaced by the
|
||||
[`@electron/remote`](https://github.com/electron/remote) module.
|
||||
|
||||
```js
|
||||
// Deprecated in Electron 12:
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
```
|
||||
|
||||
```js
|
||||
// Replace with:
|
||||
const { BrowserWindow } = require('@electron/remote')
|
||||
|
||||
// In the main process:
|
||||
require('@electron/remote/main').initialize()
|
||||
```
|
||||
|
||||
### Deprecated: `shell.moveItemToTrash()`
|
||||
|
||||
The synchronous `shell.moveItemToTrash()` has been replaced by the new,
|
||||
asynchronous `shell.trashItem()`.
|
||||
|
||||
```js
|
||||
// Deprecated in Electron 12
|
||||
shell.moveItemToTrash(path)
|
||||
// Replace with
|
||||
shell.trashItem(path).then(/* ... */)
|
||||
```
|
||||
|
||||
## Planned Breaking API Changes (11.0)
|
||||
|
||||
There are no breaking changes planned for 11.0.
|
||||
@@ -133,54 +178,6 @@ const w = new BrowserWindow({
|
||||
We [recommend moving away from the remote
|
||||
module](https://medium.com/@nornagon/electrons-remote-module-considered-harmful-70d69500f31).
|
||||
|
||||
### `protocol.unregisterProtocol`
|
||||
### `protocol.uninterceptProtocol`
|
||||
|
||||
The APIs are now synchronous and the optional callback is no longer needed.
|
||||
|
||||
```javascript
|
||||
// Deprecated
|
||||
protocol.unregisterProtocol(scheme, () => { /* ... */ })
|
||||
// Replace with
|
||||
protocol.unregisterProtocol(scheme)
|
||||
```
|
||||
|
||||
### `protocol.registerFileProtocol`
|
||||
### `protocol.registerBufferProtocol`
|
||||
### `protocol.registerStringProtocol`
|
||||
### `protocol.registerHttpProtocol`
|
||||
### `protocol.registerStreamProtocol`
|
||||
### `protocol.interceptFileProtocol`
|
||||
### `protocol.interceptStringProtocol`
|
||||
### `protocol.interceptBufferProtocol`
|
||||
### `protocol.interceptHttpProtocol`
|
||||
### `protocol.interceptStreamProtocol`
|
||||
|
||||
The APIs are now synchronous and the optional callback is no longer needed.
|
||||
|
||||
```javascript
|
||||
// Deprecated
|
||||
protocol.registerFileProtocol(scheme, handler, () => { /* ... */ })
|
||||
// Replace with
|
||||
protocol.registerFileProtocol(scheme, handler)
|
||||
```
|
||||
|
||||
The registered or intercepted protocol does not have effect on current page
|
||||
until navigation happens.
|
||||
|
||||
### `protocol.isProtocolHandled`
|
||||
|
||||
This API is deprecated and users should use `protocol.isProtocolRegistered`
|
||||
and `protocol.isProtocolIntercepted` instead.
|
||||
|
||||
```javascript
|
||||
// Deprecated
|
||||
protocol.isProtocolHandled(scheme).then(() => { /* ... */ })
|
||||
// Replace with
|
||||
const isRegistered = protocol.isProtocolRegistered(scheme)
|
||||
const isIntercepted = protocol.isProtocolIntercepted(scheme)
|
||||
```
|
||||
|
||||
## Planned Breaking API Changes (9.0)
|
||||
|
||||
### Default Changed: Loading non-context-aware native modules in the renderer process is disabled by default
|
||||
@@ -195,45 +192,6 @@ you should plan to update your native modules to be context aware.
|
||||
|
||||
For more detailed information see [#18397](https://github.com/electron/electron/issues/18397).
|
||||
|
||||
### Deprecated: `BrowserWindow` extension APIs
|
||||
|
||||
The following extension APIs have been deprecated:
|
||||
* `BrowserWindow.addExtension(path)`
|
||||
* `BrowserWindow.addDevToolsExtension(path)`
|
||||
* `BrowserWindow.removeExtension(name)`
|
||||
* `BrowserWindow.removeDevToolsExtension(name)`
|
||||
* `BrowserWindow.getExtensions()`
|
||||
* `BrowserWindow.getDevToolsExtensions()`
|
||||
|
||||
Use the session APIs instead:
|
||||
* `ses.loadExtension(path)`
|
||||
* `ses.removeExtension(extension_id)`
|
||||
* `ses.getAllExtensions()`
|
||||
|
||||
```js
|
||||
// Deprecated in Electron 9
|
||||
BrowserWindow.addExtension(path)
|
||||
BrowserWindow.addDevToolsExtension(path)
|
||||
// Replace with
|
||||
session.defaultSession.loadExtension(path)
|
||||
```
|
||||
|
||||
```js
|
||||
// Deprecated in Electron 9
|
||||
BrowserWindow.removeExtension(name)
|
||||
BrowserWindow.removeDevToolsExtension(name)
|
||||
// Replace with
|
||||
session.defaultSession.removeExtension(extension_id)
|
||||
```
|
||||
|
||||
```js
|
||||
// Deprecated in Electron 9
|
||||
BrowserWindow.getExtensions()
|
||||
BrowserWindow.getDevToolsExtensions()
|
||||
// Replace with
|
||||
session.defaultSession.getAllExtensions()
|
||||
```
|
||||
|
||||
### Removed: `<webview>.getWebContents()`
|
||||
|
||||
This API, which was deprecated in Electron 8.0, is now removed.
|
||||
@@ -377,52 +335,6 @@ in Electron 8.x, and cease to exist in Electron 9.x. The layout zoom level
|
||||
limits are now fixed at a minimum of 0.25 and a maximum of 5.0, as defined
|
||||
[here](https://chromium.googlesource.com/chromium/src/+/938b37a6d2886bf8335fc7db792f1eb46c65b2ae/third_party/blink/common/page/page_zoom.cc#11).
|
||||
|
||||
### Deprecated events in `systemPreferences`
|
||||
|
||||
The following `systemPreferences` events have been deprecated:
|
||||
* `inverted-color-scheme-changed`
|
||||
* `high-contrast-color-scheme-changed`
|
||||
|
||||
Use the new `updated` event on the `nativeTheme` module instead.
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
systemPreferences.on('inverted-color-scheme-changed', () => { /* ... */ })
|
||||
systemPreferences.on('high-contrast-color-scheme-changed', () => { /* ... */ })
|
||||
|
||||
// Replace with
|
||||
nativeTheme.on('updated', () => { /* ... */ })
|
||||
```
|
||||
|
||||
### Deprecated: methods in `systemPreferences`
|
||||
|
||||
The following `systemPreferences` methods have been deprecated:
|
||||
* `systemPreferences.isDarkMode()`
|
||||
* `systemPreferences.isInvertedColorScheme()`
|
||||
* `systemPreferences.isHighContrastColorScheme()`
|
||||
|
||||
Use the following `nativeTheme` properties instead:
|
||||
* `nativeTheme.shouldUseDarkColors`
|
||||
* `nativeTheme.shouldUseInvertedColorScheme`
|
||||
* `nativeTheme.shouldUseHighContrastColors`
|
||||
|
||||
```js
|
||||
// Deprecated
|
||||
systemPreferences.isDarkMode()
|
||||
// Replace with
|
||||
nativeTheme.shouldUseDarkColors
|
||||
|
||||
// Deprecated
|
||||
systemPreferences.isInvertedColorScheme()
|
||||
// Replace with
|
||||
nativeTheme.shouldUseInvertedColorScheme
|
||||
|
||||
// Deprecated
|
||||
systemPreferences.isHighContrastColorScheme()
|
||||
// Replace with
|
||||
nativeTheme.shouldUseHighContrastColors
|
||||
```
|
||||
|
||||
## Planned Breaking API Changes (7.0)
|
||||
|
||||
### Deprecated: Atom.io Node Headers URL
|
||||
|
||||
@@ -4,8 +4,8 @@ These guides are intended for people working on the Electron project itself.
|
||||
For guides on Electron app development, see
|
||||
[/docs/README.md](../README.md#guides-and-tutorials).
|
||||
|
||||
* [Code of Conduct](../../CODE_OF_CONDUCT.md)
|
||||
* [Contributing to Electron](../../CONTRIBUTING.md)
|
||||
* [Code of Conduct](https://github.com/electron/electron/blob/master/CODE_OF_CONDUCT.md)
|
||||
* [Contributing to Electron](https://github.com/electron/electron/blob/master/CONTRIBUTING.md)
|
||||
* [Issues](issues.md)
|
||||
* [Pull Requests](pull-requests.md)
|
||||
* [Documentation Styleguide](coding-style.md#documentation)
|
||||
|
||||
@@ -177,12 +177,12 @@ $ gn gen out/Testing-x86 --args='... target_cpu = "x86"'
|
||||
|
||||
Not all combinations of source and target CPU/OS are supported by Chromium.
|
||||
|
||||
| Host | Target | Status |
|
||||
|-------------|---------------|----------------------|
|
||||
| Windows x64 | Windows arm64 | Experimental |
|
||||
| Windows x64 | Windows x86 | Automatically tested |
|
||||
| Linux x64 | Linux x86 | Automatically tested |
|
||||
|
||||
<table>
|
||||
<tr><th>Host</th><th>Target</th><th>Status</th></tr>
|
||||
<tr><td>Windows x64</td><td>Windows arm64</td><td>Experimental</td>
|
||||
<tr><td>Windows x64</td><td>Windows x86</td><td>Automatically tested</td></tr>
|
||||
<tr><td>Linux x64</td><td>Linux x86</td><td>Automatically tested</td></tr>
|
||||
</table>
|
||||
|
||||
If you test other combinations and find them to work, please update this document :)
|
||||
|
||||
|
||||
@@ -69,8 +69,7 @@ way of figuring out which is which.
|
||||
### Which Process Should I Attach to?
|
||||
|
||||
Code executed within the main process (that is, code found in or eventually run
|
||||
by your main JavaScript file) as well as code called using the remote
|
||||
(`require('electron').remote`) will run inside the main process, while other
|
||||
by your main JavaScript file) will run inside the main process, while other
|
||||
code will execute inside its respective renderer process.
|
||||
|
||||
You can be attached to multiple programs when you are debugging, but only one
|
||||
|
||||
@@ -43,8 +43,8 @@ SRV*c:\code\symbols\*https://msdl.microsoft.com/download/symbols;SRV*c:\code\sym
|
||||
|
||||
## Using the symbol server in Visual Studio
|
||||
|
||||

|
||||

|
||||
<img src='https://mdn.mozillademos.org/files/733/symbol-server-vc8express-menu.jpg'>
|
||||
<img src='https://mdn.mozillademos.org/files/2497/2005_options.gif'>
|
||||
|
||||
## Troubleshooting: Symbols will not load
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
<a href="#" id="drag">Drag me</a>
|
||||
<script src="renderer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,41 +0,0 @@
|
||||
const { app, BrowserWindow, ipcMain, nativeImage, NativeImage } = require('electron')
|
||||
const fs = require('fs');
|
||||
const http = require('http');
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
const iconName = 'iconForDragAndDrop.png';
|
||||
const icon = fs.createWriteStream(`${process.cwd()}/${iconName}`);
|
||||
http.get('http://img.icons8.com/ios/452/drag-and-drop.png', (response) => {
|
||||
response.pipe(icon);
|
||||
});
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
ipcMain.on('ondragstart', (event, filePath) => {
|
||||
event.sender.startDrag({
|
||||
file: filePath,
|
||||
icon: `${process.cwd()}/${iconName}`
|
||||
})
|
||||
})
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
@@ -1,9 +0,0 @@
|
||||
const { ipcRenderer } = require('electron')
|
||||
const fs = require('fs')
|
||||
|
||||
document.getElementById('drag').ondragstart = (event) => {
|
||||
const fileName = 'drag-and-drop.md'
|
||||
fs.writeFileSync(fileName, '# Test drag and drop');
|
||||
event.preventDefault()
|
||||
ipcRenderer.send('ondragstart', process.cwd() + `/${fileName}`)
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,31 +0,0 @@
|
||||
const { app, BrowserWindow, globalShortcut } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
globalShortcut.register('Alt+CommandOrControl+I', () => {
|
||||
console.log('Electron loves global shortcuts!')
|
||||
})
|
||||
}).then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
@@ -1,14 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,13 +0,0 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
app.whenReady().then(() => {
|
||||
const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true } })
|
||||
|
||||
win.loadFile('index.html')
|
||||
win.webContents.on('before-input-event', (event, input) => {
|
||||
if (input.control && input.key.toLowerCase() === 'i') {
|
||||
console.log('Pressed Control+I')
|
||||
event.preventDefault()
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -1,16 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,39 +0,0 @@
|
||||
const { app, BrowserWindow, Menu, MenuItem } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
const menu = new Menu()
|
||||
menu.append(new MenuItem({
|
||||
label: 'Electron',
|
||||
submenu: [{
|
||||
role: 'help',
|
||||
accelerator: process.platform === 'darwin' ? 'Alt+Cmd+I' : 'Alt+Shift+I',
|
||||
click: () => { console.log('Electron rocks!') }
|
||||
}]
|
||||
}))
|
||||
|
||||
Menu.setApplicationMenu(menu)
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
@@ -1,19 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
<link rel="stylesheet" type="text/css" href="./styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>Current theme source: <strong id="theme-source">System</strong></p>
|
||||
|
||||
<button id="toggle-dark-mode">Toggle Dark Mode</button>
|
||||
<button id="reset-to-system">Reset to System Theme</button>
|
||||
|
||||
<script src="renderer.js"></script>
|
||||
</body>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,40 +0,0 @@
|
||||
const { app, BrowserWindow, ipcMain, nativeTheme } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
|
||||
ipcMain.handle('dark-mode:toggle', () => {
|
||||
if (nativeTheme.shouldUseDarkColors) {
|
||||
nativeTheme.themeSource = 'light'
|
||||
} else {
|
||||
nativeTheme.themeSource = 'dark'
|
||||
}
|
||||
return nativeTheme.shouldUseDarkColors
|
||||
})
|
||||
|
||||
ipcMain.handle('dark-mode:system', () => {
|
||||
nativeTheme.themeSouce = 'system'
|
||||
})
|
||||
}
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
@@ -1,11 +0,0 @@
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
document.getElementById('toggle-dark-mode').addEventListener('click', async () => {
|
||||
const isDarkMode = await ipcRenderer.invoke('dark-mode:toggle')
|
||||
document.getElementById('theme-source').innerHTML = isDarkMode ? 'Dark' : 'Light'
|
||||
})
|
||||
|
||||
document.getElementById('reset-to-system').addEventListener('click', async () => {
|
||||
await ipcRenderer.invoke('dark-mode:system')
|
||||
document.getElementById('theme-source').innerHTML = 'System'
|
||||
})
|
||||
@@ -1,7 +0,0 @@
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body { background: #333; color: white; }
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
body { background: #ddd; color: black; }
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,43 +0,0 @@
|
||||
const { app, BrowserWindow, Menu } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
const dockMenu = Menu.buildFromTemplate([
|
||||
{
|
||||
label: 'New Window',
|
||||
click () { console.log('New Window') }
|
||||
}, {
|
||||
label: 'New Window with Settings',
|
||||
submenu: [
|
||||
{ label: 'Basic' },
|
||||
{ label: 'Pro' }
|
||||
]
|
||||
},
|
||||
{ label: 'New Command...' }
|
||||
])
|
||||
|
||||
app.whenReady().then(() => {
|
||||
app.dock.setMenu(dockMenu)
|
||||
}).then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
@@ -1,16 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,35 +0,0 @@
|
||||
const { app, BrowserWindow, Notification } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
function showNotification () {
|
||||
const notification = {
|
||||
title: 'Basic Notification',
|
||||
body: 'Notification from the Main process'
|
||||
}
|
||||
new Notification(notification).show()
|
||||
}
|
||||
|
||||
app.whenReady().then(createWindow).then(showNotification)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
@@ -1,17 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
<script src="renderer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,27 +0,0 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
@@ -1,7 +0,0 @@
|
||||
const myNotification = new Notification('Title', {
|
||||
body: 'Notification from the Renderer process'
|
||||
})
|
||||
|
||||
myNotification.onclick = () => {
|
||||
console.log('Notification clicked')
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,28 +0,0 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const fs = require('fs')
|
||||
|
||||
app.disableHardwareAcceleration()
|
||||
|
||||
let win
|
||||
|
||||
app.whenReady().then(() => {
|
||||
win = new BrowserWindow({ webPreferences: { offscreen: true } })
|
||||
win.loadURL('https://github.com')
|
||||
win.webContents.on('paint', (event, dirty, image) => {
|
||||
fs.writeFileSync('ex.png', image.toPNG())
|
||||
})
|
||||
win.webContents.setFrameRate(60)
|
||||
console.log(`The screenshot has been successfully saved to ${process.cwd()}/ex.png`)
|
||||
})
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
@@ -1,17 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
<script src="renderer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,24 +0,0 @@
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
|
||||
let onlineStatusWindow
|
||||
|
||||
app.whenReady().then(() => {
|
||||
onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false, webPreferences: { nodeIntegration: true } })
|
||||
onlineStatusWindow.loadURL(`file://${__dirname}/index.html`)
|
||||
})
|
||||
|
||||
ipcMain.on('online-status-changed', (event, status) => {
|
||||
console.log(status)
|
||||
})
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
@@ -1,7 +0,0 @@
|
||||
const { ipcRenderer } = require('electron')
|
||||
const updateOnlineStatus = () => { ipcRenderer.send('online-status-changed', navigator.onLine ? 'online' : 'offline') }
|
||||
|
||||
window.addEventListener('online', updateOnlineStatus)
|
||||
window.addEventListener('offline', updateOnlineStatus)
|
||||
|
||||
updateOnlineStatus()
|
||||
@@ -1,17 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
<script src="renderer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,20 +0,0 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
let onlineStatusWindow
|
||||
|
||||
app.whenReady().then(() => {
|
||||
onlineStatusWindow = new BrowserWindow({ width: 0, height: 0, show: false })
|
||||
onlineStatusWindow.loadURL(`file://${__dirname}/index.html`)
|
||||
})
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
@@ -1,6 +0,0 @@
|
||||
const alertOnlineStatus = () => { window.alert(navigator.onLine ? 'online' : 'offline') }
|
||||
|
||||
window.addEventListener('online', alertOnlineStatus)
|
||||
window.addEventListener('offline', alertOnlineStatus)
|
||||
|
||||
alertOnlineStatus()
|
||||
@@ -1,16 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,30 +0,0 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
win.setProgressBar(0.5)
|
||||
}
|
||||
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
@@ -1,16 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,34 +0,0 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
const fileName = 'recently-used.md'
|
||||
fs.writeFile(fileName, 'Lorem Ipsum', () => {
|
||||
app.addRecentDocument(path.join(process.cwd(), `${fileName}`))
|
||||
})
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
app.clearRecentDocuments()
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
@@ -1,16 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,33 +0,0 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const os = require('os');
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
const win = new BrowserWindow()
|
||||
|
||||
win.setRepresentedFilename(os.homedir())
|
||||
win.setDocumentEdited(true)
|
||||
})
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
@@ -1,7 +1,11 @@
|
||||
const { BrowserWindow, app } = require('electron')
|
||||
const { BrowserWindow, app, screen, ipcMain } = require('electron')
|
||||
|
||||
let mainWindow = null
|
||||
|
||||
ipcMain.handle('get-screen-size', () => {
|
||||
return screen.getPrimaryDisplay().workAreaSize
|
||||
})
|
||||
|
||||
function createWindow () {
|
||||
const windowOptions = {
|
||||
width: 600,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
const { desktopCapturer } = require('electron')
|
||||
const { screen, shell } = require('electron').remote
|
||||
const { desktopCapturer, shell, ipcRenderer } = require('electron')
|
||||
|
||||
const fs = require('fs')
|
||||
const os = require('os')
|
||||
@@ -8,9 +7,9 @@ const path = require('path')
|
||||
const screenshot = document.getElementById('screen-shot')
|
||||
const screenshotMsg = document.getElementById('screenshot-path')
|
||||
|
||||
screenshot.addEventListener('click', (event) => {
|
||||
screenshot.addEventListener('click', async (event) => {
|
||||
screenshotMsg.textContent = 'Gathering screens...'
|
||||
const thumbSize = determineScreenShotSize()
|
||||
const thumbSize = await determineScreenShotSize()
|
||||
const options = { types: ['screen'], thumbnailSize: thumbSize }
|
||||
|
||||
desktopCapturer.getSources(options, (error, sources) => {
|
||||
@@ -33,8 +32,8 @@ screenshot.addEventListener('click', (event) => {
|
||||
})
|
||||
})
|
||||
|
||||
function determineScreenShotSize () {
|
||||
const screenSize = screen.getPrimaryDisplay().workAreaSize
|
||||
async function determineScreenShotSize () {
|
||||
const screenSize = await ipcRenderer.invoke('get-screen-size')
|
||||
const maxDimension = Math.max(screenSize.width, screenSize.height)
|
||||
return {
|
||||
width: maxDimension * window.devicePixelRatio,
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World!</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
<p>
|
||||
We are using node <script>document.write(process.versions.node)</script>,
|
||||
Chrome <script>document.write(process.versions.chrome)</script>,
|
||||
and Electron <script>document.write(process.versions.electron)</script>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,27 +0,0 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
@@ -1,23 +1,20 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
|
||||
let mainWindow = null
|
||||
ipcMain.on('create-frameless-window', (event, {url}) => {
|
||||
const win = new BrowserWindow({ frame: false })
|
||||
win.loadURL(url)
|
||||
})
|
||||
|
||||
function createWindow () {
|
||||
const windowOptions = {
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 600,
|
||||
height: 400,
|
||||
title: 'Create a frameless window',
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
}
|
||||
|
||||
mainWindow = new BrowserWindow(windowOptions)
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = null
|
||||
})
|
||||
mainWindow.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
const newWindowBtn = document.getElementById('frameless-window')
|
||||
|
||||
newWindowBtn.addEventListener('click', (event) => {
|
||||
let win = new BrowserWindow({ frame: false })
|
||||
|
||||
win.on('close', () => { win = null })
|
||||
|
||||
win.loadURL('data:text/html,<h2>Hello World!</h2><a id="close" href="javascript:window.close()">Close this Window</a>')
|
||||
win.show()
|
||||
newWindowBtn.addEventListener('click', () => {
|
||||
const url = 'data:text/html,<h2>Hello World!</h2><a id="close" href="javascript:window.close()">Close this Window</a>'
|
||||
ipcRenderer.send('create-frameless-window', { url })
|
||||
})
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
ipcMain.on('create-frameless-window', (event, {url}) => {
|
||||
const win = new BrowserWindow({ frame: false })
|
||||
win.loadURL(url)
|
||||
})
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
@@ -17,17 +18,6 @@ function createWindow () {
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
|
||||
@@ -1,25 +1,8 @@
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const shell = require('electron').shell
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
const framelessWindowBtn = document.getElementById('frameless-window')
|
||||
const newWindowBtn = document.getElementById('frameless-window')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
framelessWindowBtn.addEventListener('click', (event) => {
|
||||
const modalPath = 'https://electronjs.org'
|
||||
let win = new BrowserWindow({ frame: false })
|
||||
|
||||
win.on('close', () => { win = null })
|
||||
win.loadURL(modalPath)
|
||||
win.show()
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
link.addEventListener('click', (e) => {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
})
|
||||
}
|
||||
newWindowBtn.addEventListener('click', () => {
|
||||
const url = 'data:text/html,<h2>Hello World!</h2><a id="close" href="javascript:window.close()">Close this Window</a>'
|
||||
ipcRenderer.send('create-frameless-window', { url })
|
||||
})
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
ipcMain.on('create-demo-window', (event) => {
|
||||
const win = new BrowserWindow({ width: 400, height: 275 })
|
||||
|
||||
function updateReply() {
|
||||
event.sender.send('bounds-changed', {
|
||||
size: win.getSize(),
|
||||
position: win.getPosition()
|
||||
})
|
||||
}
|
||||
|
||||
win.on('resize', updateReply)
|
||||
win.on('move', updateReply)
|
||||
win.loadURL('https://electronjs.org')
|
||||
})
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
@@ -17,17 +28,6 @@ function createWindow () {
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
|
||||
@@ -1,27 +1,17 @@
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const shell = require('electron').shell
|
||||
const { shell, ipcRenderer } = require('electron')
|
||||
|
||||
const manageWindowBtn = document.getElementById('manage-window')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
let win
|
||||
ipcRenderer.on('bounds-changed', (event, bounds) => {
|
||||
const manageWindowReply = document.getElementById('manage-window-reply')
|
||||
const message = `Size: ${bounds.size} Position: ${bounds.position}`
|
||||
manageWindowReply.textContent = message
|
||||
})
|
||||
|
||||
manageWindowBtn.addEventListener('click', (event) => {
|
||||
const modalPath = 'https://electronjs.org'
|
||||
win = new BrowserWindow({ width: 400, height: 275 })
|
||||
|
||||
win.on('resize', updateReply)
|
||||
win.on('move', updateReply)
|
||||
win.on('close', () => { win = null })
|
||||
win.loadURL(modalPath)
|
||||
win.show()
|
||||
|
||||
function updateReply () {
|
||||
const manageWindowReply = document.getElementById('manage-window-reply')
|
||||
const message = `Size: ${win.getSize()} Position: ${win.getPosition()}`
|
||||
manageWindowReply.innerText = message
|
||||
}
|
||||
ipcRenderer.send('create-demo-window')
|
||||
})
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<h2>Create a new window</h2>
|
||||
<h3>Supports: Win, macOS, Linux <span>|</span> Process: Main</h3>
|
||||
<button id="new-window">View Demo</button>
|
||||
<p>The <code>BrowserWindow</code> module gives you the ability to create new windows in your app. This main process module can be used from the renderer process with the <code>remote</code> module, as is shown in this demo.</p>
|
||||
<p>The <code>BrowserWindow</code> module gives you the ability to create new windows in your app.</p>
|
||||
<p>There are a lot of options when creating a new window. A few are in this demo, but visit the <a id="browser-window-link" href="">documentation<span>(opens in new window)</span></a>
|
||||
<div>
|
||||
<h2>ProTip</h2>
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
ipcMain.on('new-window', (event, { url, width, height }) => {
|
||||
const win = new BrowserWindow({ width, height })
|
||||
win.loadURL(url)
|
||||
})
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
@@ -17,17 +18,6 @@ function createWindow () {
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const { shell } = require('electron').remote
|
||||
const { shell, ipcRenderer } = require('electron')
|
||||
|
||||
const newWindowBtn = document.getElementById('new-window')
|
||||
const link = document.getElementById('browser-window-link')
|
||||
|
||||
newWindowBtn.addEventListener('click', (event) => {
|
||||
|
||||
let win = new BrowserWindow({ width: 400, height: 320 })
|
||||
|
||||
win.on('close', () => { win = null })
|
||||
win.loadURL('https://electronjs.org')
|
||||
win.show()
|
||||
const url = 'https://electronjs.org'
|
||||
ipcRenderer.send('new-window', { url, width: 400, height: 320 });
|
||||
})
|
||||
|
||||
link.addEventListener('click', (e) => {
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
// Modules to control application life and create native browser window
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let mainWindow
|
||||
const { app, BrowserWindow, ipcMain } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
@@ -18,15 +14,27 @@ function createWindow () {
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.webContents.openDevTools()
|
||||
let demoWindow
|
||||
ipcMain.on('show-demo-window', () => {
|
||||
if (demoWindow) {
|
||||
demoWindow.focus()
|
||||
return
|
||||
}
|
||||
demoWindow = new BrowserWindow({ width: 600, height: 400 })
|
||||
demoWindow.loadURL('https://electronjs.org')
|
||||
demoWindow.on('close', () => {
|
||||
mainWindow.webContents.send('window-close')
|
||||
})
|
||||
demoWindow.on('focus', () => {
|
||||
mainWindow.webContents.send('window-focus')
|
||||
})
|
||||
demoWindow.on('blur', () => {
|
||||
mainWindow.webContents.send('window-blur')
|
||||
})
|
||||
})
|
||||
|
||||
// Emitted when the window is closed.
|
||||
mainWindow.on('closed', function () {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
mainWindow = null
|
||||
ipcMain.on('focus-demo-window', () => {
|
||||
if (demoWindow) demoWindow.focus()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,42 +1,33 @@
|
||||
const { BrowserWindow } = require('electron').remote
|
||||
const shell = require('electron').shell
|
||||
const { shell, ipcRenderer } = require('electron')
|
||||
|
||||
const listenToWindowBtn = document.getElementById('listen-to-window')
|
||||
const focusModalBtn = document.getElementById('focus-on-modal-window')
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
const hideFocusBtn = () => {
|
||||
focusModalBtn.classList.add('disappear')
|
||||
focusModalBtn.classList.remove('smooth-appear')
|
||||
focusModalBtn.removeEventListener('click', focusWindow)
|
||||
}
|
||||
|
||||
let win
|
||||
const showFocusBtn = (btn) => {
|
||||
focusModalBtn.classList.add('smooth-appear')
|
||||
focusModalBtn.classList.remove('disappear')
|
||||
focusModalBtn.addEventListener('click', focusWindow)
|
||||
}
|
||||
const focusWindow = () => {
|
||||
ipcRenderer.send('focus-demo-window')
|
||||
}
|
||||
|
||||
ipcRenderer.on('window-focus', hideFocusBtn)
|
||||
ipcRenderer.on('window-close', hideFocusBtn)
|
||||
ipcRenderer.on('window-blur', showFocusBtn)
|
||||
|
||||
listenToWindowBtn.addEventListener('click', () => {
|
||||
const modalPath = 'https://electronjs.org'
|
||||
win = new BrowserWindow({ width: 600, height: 400 })
|
||||
|
||||
const hideFocusBtn = () => {
|
||||
focusModalBtn.classList.add('disappear')
|
||||
focusModalBtn.classList.remove('smooth-appear')
|
||||
focusModalBtn.removeEventListener('click', clickHandler)
|
||||
}
|
||||
|
||||
const showFocusBtn = (btn) => {
|
||||
if (!win) return
|
||||
focusModalBtn.classList.add('smooth-appear')
|
||||
focusModalBtn.classList.remove('disappear')
|
||||
focusModalBtn.addEventListener('click', clickHandler)
|
||||
}
|
||||
|
||||
win.on('focus', hideFocusBtn)
|
||||
win.on('blur', showFocusBtn)
|
||||
win.on('close', () => {
|
||||
hideFocusBtn()
|
||||
win = null
|
||||
})
|
||||
win.loadURL(modalPath)
|
||||
win.show()
|
||||
|
||||
const clickHandler = () => { win.focus() }
|
||||
ipcRenderer.send('show-demo-window')
|
||||
})
|
||||
|
||||
const links = document.querySelectorAll('a[href]')
|
||||
|
||||
Array.prototype.forEach.call(links, (link) => {
|
||||
const url = link.getAttribute('href')
|
||||
if (url.indexOf('http') === 0) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Accessibility
|
||||
|
||||
Making accessible applications is important and we're happy to introduce new
|
||||
Making accessible applications is important and we're happy to provide
|
||||
functionality to [Devtron][devtron] and [Spectron][spectron] that gives
|
||||
developers the opportunity to make their apps better for everyone.
|
||||
|
||||
@@ -11,7 +11,7 @@ websites because they're both ultimately HTML. With Electron apps, however,
|
||||
you can't use the online resources for accessibility audits because your app
|
||||
doesn't have a URL to point the auditor to.
|
||||
|
||||
These new features bring those auditing tools to your Electron app. You can
|
||||
These features bring those auditing tools to your Electron app. You can
|
||||
choose to add audits to your tests with Spectron or use them within DevTools
|
||||
with Devtron. Read on for a summary of the tools.
|
||||
|
||||
@@ -32,7 +32,7 @@ You can read more about this feature in [Spectron's documentation][spectron-a11y
|
||||
|
||||
## Devtron
|
||||
|
||||
In Devtron, there is a new accessibility tab which will allow you to audit a
|
||||
In Devtron, there is an accessibility tab which will allow you to audit a
|
||||
page in your app, sort and filter the results.
|
||||
|
||||
![devtron screenshot][devtron-screenshot]
|
||||
@@ -44,26 +44,29 @@ audit rules this library uses on that [repository's wiki][a11y-devtools-wiki].
|
||||
If you know of other great accessibility tools for Electron, add them to the
|
||||
accessibility documentation with a pull request.
|
||||
|
||||
## Enabling Accessibility
|
||||
## Manually enabling accessibility features
|
||||
|
||||
Electron applications keep accessibility disabled by default for performance
|
||||
reasons but there are multiple ways to enable it.
|
||||
Electron applications will automatically enable accessibility features in the
|
||||
presence of assistive technology (e.g. [JAWS](https://www.freedomscientific.com/products/software/jaws/)
|
||||
on Windows or [VoiceOver](https://help.apple.com/voiceover/mac/10.15/) on macOS).
|
||||
See Chrome's [accessibility documentation][a11y-docs] for more details.
|
||||
|
||||
### Inside Application
|
||||
You can also manually toggle these features either within your Electron application
|
||||
or by setting flags in third-party native software.
|
||||
|
||||
By using [`app.setAccessibilitySupportEnabled(enabled)`][setAccessibilitySupportEnabled],
|
||||
you can expose accessibility switch to users in the application preferences.
|
||||
User's system assistive utilities have priority over this setting and will
|
||||
override it.
|
||||
### Using Electron's API
|
||||
|
||||
### Assistive Technology
|
||||
By using the [`app.setAccessibilitySupportEnabled(enabled)`][setAccessibilitySupportEnabled]
|
||||
API, you can manually expose Chrome's accessibility tree to users in the application preferences.
|
||||
Note that the user's system assistive utilities have priority over this setting and
|
||||
will override it.
|
||||
|
||||
Electron application will enable accessibility automatically when it detects
|
||||
assistive technology (Windows) or VoiceOver (macOS). See Chrome's
|
||||
[accessibility documentation][a11y-docs] for more details.
|
||||
### Within third-party software
|
||||
|
||||
On macOS, third-party assistive technology can switch accessibility inside
|
||||
Electron applications by setting the attribute `AXManualAccessibility`
|
||||
#### macOS
|
||||
|
||||
On macOS, third-party assistive technology can toggle accessibility features inside
|
||||
Electron applications by setting the `AXManualAccessibility` attribute
|
||||
programmatically:
|
||||
|
||||
```objc
|
||||
|
||||
@@ -26,7 +26,8 @@ To test In-App Purchase in development with Electron you'll have to change the `
|
||||
Here is an example that shows how to use In-App Purchases in Electron. You'll have to replace the product ids by the identifiers of the products created with iTunes Connect (the identifier of `com.example.app.product1` is `product1`). Note that you have to listen to the `transactions-updated` event as soon as possible in your app.
|
||||
|
||||
```javascript
|
||||
const { inAppPurchase } = require('electron').remote
|
||||
// Main process
|
||||
const { inAppPurchase } = require('electron')
|
||||
const PRODUCT_IDS = ['id1', 'id2']
|
||||
|
||||
// Listen for transactions as soon as possible.
|
||||
|
||||
@@ -9,7 +9,7 @@ Two modes of rendering can be used and only the dirty area is passed in the
|
||||
`'paint'` event to be more efficient. The rendering can be stopped, continued
|
||||
and the frame rate can be set. The specified frame rate is a top limit value,
|
||||
when there is nothing happening on a webpage, no frames are generated. The
|
||||
maximum frame rate is 240, because above that there is no benefit, only
|
||||
maximum frame rate is 60, because above that there is no benefit, only
|
||||
performance loss.
|
||||
|
||||
**Note:** An offscreen window is always created as a [Frameless Window](../api/frameless-window.md).
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user