diff --git a/.circleci/config.yml b/.circleci/config.yml index 68cf567953f70..5cf46e6350069 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -45,7 +45,7 @@ executors: type: enum enum: ["medium", "xlarge", "2xlarge+"] docker: - - image: electron.azurecr.io/build:4fc81b50f9c0980699d329bc32062fac20a26701 + - image: ghcr.io/electron/build:27db4a3e3512bfd2e47f58cea69922da0835f1d9 resource_class: << parameters.size >> macos: @@ -219,6 +219,8 @@ step-maybe-cleanup-arm64-mac: &step-maybe-cleanup-arm64-mac killall Safari || echo "No Safari processes left running" rm -rf ~/Library/Application\ Support/Electron* rm -rf ~/Library/Application\ Support/electron* + security delete-generic-password -l "Chromium Safe Storage" || echo "✓ Keychain does not contain password from tests" + security delete-generic-password -l "Electron Test Main Safe Storage" || echo "✓ Keychain does not contain password from tests" elif [ "$TARGET_ARCH" == "arm" ] || [ "$TARGET_ARCH" == "arm64" ]; then XVFB=/usr/bin/Xvfb /sbin/start-stop-daemon --stop --exec $XVFB || echo "Xvfb not running" @@ -312,6 +314,7 @@ step-setup-goma-for-build: &step-setup-goma-for-build npm install mkdir third_party node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })" + export GOMA_FALLBACK_ON_AUTH_FAILURE=true third_party/goma/goma_ctl.py ensure_start 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 @@ -1206,6 +1209,9 @@ steps-tests: &steps-tests (cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging) (cd electron && node script/yarn test --runners=remote --trace-uncaught --enable-logging) else + if [ "$TARGET_ARCH" == "ia32" ]; then + npm_config_arch=x64 node electron/node_modules/dugite/script/download-git.js + fi (cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging --files $(circleci tests glob spec-main/*-spec.ts | circleci tests split --split-by=timings)) (cd electron && node script/yarn test --runners=remote --trace-uncaught --enable-logging --files $(circleci tests glob spec/*-spec.js | circleci tests split --split-by=timings)) fi diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 0000000000000..c12625a1481e8 --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,59 @@ +# Electron Dev on Codespaces + +Welcome to the Codespaces Electron Developer Environment. + +## Quick Start + +Upon creation of your codespace you should have [build tools](https://github.com/electron/build-tools) installed and an initialized gclient checkout of Electron. In order to build electron you'll need to run the following commands. + +```bash +e sync -vv +e build +``` + +The initial sync will take approximately ~30 minutes and the build will take ~8 minutes. Incremental syncs and incremental builds are substantially quicker. + +## Directory Structure + +Codespaces doesn't lean very well into gclient based checkouts, the directory structure is slightly strange. There are two locations for the `electron` checkout that both map to the same files under the hood. + +```graphql +# Primary gclient checkout container +/workspaces/gclient/* + └─ src/* - # Chromium checkout + └─ electron - # Electron checkout +# Symlinked Electron checkout (identical to the above) +/workspaces/electron +``` + +## Goma + +If you are a maintainer [with Goma access](../docs/development/goma.md) it should be automatically configured and authenticated when you spin up a new codespaces instance. You can validate this by checking `e d goma_auth info` or by checking that your build-tools configuration has a goma mode of `cluster`. + +## Running Electron + +You can run Electron in a few ways. If you just want to see if it launches: + +```bash +# Enter an interactive JS prompt headlessly +xvfb-run e start -i +``` + +But if you want to actually see Electron you will need to use the built-in VNC capability. If you click "Ports" in codespaces and then open the `VNC web client` forwarded port you should see a web based VNC portal in your browser. When you are asked for a password use `builduser`. + +Once in the VNC UI you can open `Applications -> System -> XTerm` which will open a VNC based terminal app and then you can run `e start` like normal and Electron will open in your VNC session. + +## Running Tests + +You run tests via build-tools and `xvfb`. + +```bash +# Run all tests +xvfb-run e test + +# Run the main process tests +xvfb-run e test --runners=main + +# Run the old remote tests +xvfb-run e test --runners=remote +``` diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000000000..5c800028282d8 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,43 @@ +{ + "dockerComposeFile": "docker-compose.yml", + "service": "buildtools", + "onCreateCommand": ".devcontainer/on-create-command.sh", + "workspaceFolder": "/workspaces/gclient/src/electron", + "extensions": [ + "joeleinbinder.mojom-language", + "rafaelmaiolla.diff", + "surajbarkale.ninja", + "ms-vscode.cpptools", + "mutantdino.resourcemonitor", + "dbaeumer.vscode-eslint", + "shakram02.bash-beautify", + "marshallofsound.gnls-electron" + ], + "settings": { + "[gn]": { + "editor.formatOnSave": true + }, + "editor.tabSize": 2, + "bashBeautify.tabSize": 2 + }, + "forwardPorts": [8088, 6080, 5901], + "portsAttributes": { + "8088": { + "label": "Goma Control Panel", + "onAutoForward": "silent" + }, + "6080": { + "label": "VNC web client (noVNC)", + "onAutoForward": "silent" + }, + "5901": { + "label": "VNC TCP port", + "onAutoForward": "silent" + } + }, + "hostRequirements": { + "storage": "32gb", + "cpus": 8 + }, + "remoteUser": "builduser" +} \ No newline at end of file diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml new file mode 100644 index 0000000000000..794577745512d --- /dev/null +++ b/.devcontainer/docker-compose.yml @@ -0,0 +1,19 @@ +version: '3' + +services: + buildtools: + image: ghcr.io/electron/devcontainer:27db4a3e3512bfd2e47f58cea69922da0835f1d9 + + volumes: + - ..:/workspaces/gclient/src/electron:cached + + - /var/run/docker.sock:/var/run/docker.sock + + command: /bin/sh -c "while sleep 1000; do :; done" + + user: builduser + + cap_add: + - SYS_PTRACE + security_opt: + - seccomp:unconfined diff --git a/.devcontainer/on-create-command.sh b/.devcontainer/on-create-command.sh new file mode 100755 index 0000000000000..8899906dff20e --- /dev/null +++ b/.devcontainer/on-create-command.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +set -eo pipefail + +buildtools=$HOME/.electron_build_tools +gclient_root=/workspaces/gclient +buildtools_configs=/workspaces/buildtools-configs + +export PATH="$PATH:$buildtools/src" + +# Create the persisted buildtools config folder +mkdir -p $buildtools_configs +rm -f $buildtools/configs +ln -s $buildtools_configs $buildtools/configs + +# Write the gclient config if it does not already exist +if [ ! -f $gclient_root/.gclient ]; then + echo "solutions = [ + { \"name\" : \"src/electron\", + \"url\" : \"https://github.com/electron/electron\", + \"deps_file\" : \"DEPS\", + \"managed\" : False, + \"custom_deps\" : { + }, + \"custom_vars\": {}, + }, + ] + " >$gclient_root/.gclient +fi + +# Write the default buildtools config file if it does +# not already exist +if [ ! -f $buildtools/configs/evm.testing.json ]; then + write_config() { + echo " + { + \"root\": \"/workspaces/gclient\", + \"goma\": \"$1\", + \"gen\": { + \"args\": [ + \"import(\\\"//electron/build/args/testing.gn\\\")\", + \"import(\\\"/home/builduser/.electron_build_tools/third_party/goma.gn\\\")\" + ], + \"out\": \"Testing\" + }, + \"env\": { + \"CHROMIUM_BUILDTOOLS_PATH\": \"/workspaces/gclient/src/buildtools\", + \"GIT_CACHE_PATH\": \"/workspaces/gclient/.git-cache\" + }, + \"remotes\": { + \"electron\": { + \"origin\": \"https://github.com/electron/electron.git\" + } + } + } + " >$buildtools/configs/evm.testing.json + } + + # Start out as cache only + write_config cache-only + + e use testing + + # Attempt to auth to the goma service via codespaces tokens + # if it works we can use the goma cluster + export NOTGOMA_CODESPACES_TOKEN=$GITHUB_TOKEN + if e d goma_auth login; then + write_config cluster + fi +else + # Even if the config file existed we still need to re-auth with the goma + # cluster + NOTGOMA_CODESPACES_TOKEN=$GITHUB_TOKEN e d goma_auth login || true +fi diff --git a/.gitignore b/.gitignore index b47ed4f8ae3b9..e2168896e2ce0 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ compile_commands.json # npm package /npm/dist /npm/path.txt +/npm/checksums.json .npmrc diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000000000..8351c19397f4f --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +14 diff --git a/BUILD.gn b/BUILD.gn index 6cc1a63394d30..de90247359e9e 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -307,6 +307,23 @@ action("electron_fuses") { args = rebase_path(outputs) } +action("electron_generate_node_defines") { + script = "build/generate_node_defines.py" + + inputs = [ + "//third_party/electron_node/src/tracing/trace_event_common.h", + "//third_party/electron_node/src/tracing/trace_event.h", + "//third_party/electron_node/src/util.h", + ] + + outputs = [ + "$target_gen_dir/push_and_undef_node_defines.h", + "$target_gen_dir/pop_node_defines.h", + ] + + args = [ rebase_path(target_gen_dir) ] + rebase_path(inputs) +} + source_set("electron_lib") { configs += [ "//v8:external_startup_data" ] configs += [ "//third_party/electron_node:node_internals" ] @@ -318,6 +335,7 @@ source_set("electron_lib") { deps = [ ":electron_fuses", + ":electron_generate_node_defines", ":electron_js2c", ":electron_version_header", ":resources", @@ -1404,7 +1422,8 @@ dist_zip("hunspell_dictionaries_zip") { } copy("libcxx_headers") { - sources = libcxx_headers + libcxx_licenses + sources = libcxx_headers + libcxx_licenses + + [ "//buildtools/third_party/libc++/__config_site" ] outputs = [ "$target_gen_dir/electron_libcxx_include/{{source_root_relative_dir}}/{{source_file_part}}" ] } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1802b9c7fa80d..d1454b0fe8faa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,7 +22,7 @@ Issues are created [here](https://github.com/electron/electron/issues/new). ### Issue Closure -Bug reports will be closed if the issue has been inactive and the latest affected version no longer receives support. At the moment, Electron maintains its three latest major versions, with a new major version being released every 12 weeks. (For more information on Electron's release cadence, see [this blog post](https://electronjs.org/blog/12-week-cadence).) +Bug reports will be closed if the issue has been inactive and the latest affected version no longer receives support. At the moment, Electron maintains its three latest major versions, with a new major version being released every 8 weeks. (For more information on Electron's release cadence, see [this blog post](https://electronjs.org/blog/8-week-cadence).) _If an issue has been closed and you still feel it's relevant, feel free to ping a maintainer or add a comment!_ diff --git a/DEPS b/DEPS index d7fcb79edde75..5e3720a63f481 100644 --- a/DEPS +++ b/DEPS @@ -15,9 +15,9 @@ gclient_gn_args = [ vars = { 'chromium_version': - '93.0.4566.0', + '94.0.4590.2', 'node_version': - 'v16.4.1', + 'v16.7.0', 'nan_version': # The following commit hash of NAN is v2.14.2 with *only* changes to the # test suite. This should be updated to a specific tag when one becomes diff --git a/ELECTRON_VERSION b/ELECTRON_VERSION index 711929aa39023..5f170fda0dbcc 100644 --- a/ELECTRON_VERSION +++ b/ELECTRON_VERSION @@ -1 +1 @@ -15.0.0-nightly.20210713 \ No newline at end of file +16.0.0-nightly.20210820 \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 26449fd65c29c..64b906aa0c010 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -112,7 +112,7 @@ build_script: } } } - - if "%RUN_GCLIENT_SYNC%"=="true" ( gclient sync --with_branch_heads --with_tags --ignore_locks) + - if "%RUN_GCLIENT_SYNC%"=="true" ( gclient sync ) - ps: >- if ($env:SAVE_GCLIENT_SRC -eq 'true') { # archive current source for future use diff --git a/azure-pipelines-woa.yml b/azure-pipelines-woa.yml index a2e68aa95ac43..f58cf5d2152cd 100644 --- a/azure-pipelines-woa.yml +++ b/azure-pipelines-woa.yml @@ -53,6 +53,16 @@ steps: env: APPVEYOR_TOKEN: $(APPVEYOR_TOKEN) +- powershell: | + $localArtifactPath = "$pwd\src\pdb.zip" + $serverArtifactPath = "$env:APPVEYOR_URL/buildjobs/$env:APPVEYOR_JOB_ID/artifacts/pdb.zip" + Invoke-RestMethod -Method Get -Uri $serverArtifactPath -OutFile $localArtifactPath -Headers @{ "Authorization" = "Bearer $env:APPVEYOR_TOKEN" } + cd src + & "${env:ProgramFiles(x86)}\7-Zip\7z.exe" x -y pdb.zip + displayName: 'Download pdb files for detailed stacktraces' + env: + APPVEYOR_TOKEN: $(APPVEYOR_TOKEN) + - powershell: | New-Item src\out\Default\gen\node_headers\Release -Type directory Copy-Item -path src\out\Default\electron.lib -destination src\out\Default\gen\node_headers\Release\node.lib @@ -63,15 +73,30 @@ 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 - displayName: 'Run Electron tests' + node script/yarn test --runners=main --runTestFilesSeperately --enable-logging --disable-features=CalculateNativeWinOcclusion + displayName: 'Run Electron Main process tests' + env: + ELECTRON_ENABLE_STACK_DUMPING: true + ELECTRON_OUT_DIR: Default + IGNORE_YARN_INSTALL_ERROR: 1 + ELECTRON_TEST_RESULTS_DIR: junit + MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap' + MOCHA_REPORTER: mocha-multi-reporters + +- script: | + cd src + set npm_config_nodedir=%cd%\out\Default\gen\node_headers + set npm_config_arch=arm64 + cd electron + node script/yarn test --runners=remote --enable-logging --disable-features=CalculateNativeWinOcclusion + displayName: 'Run Electron Remote based tests' env: ELECTRON_OUT_DIR: Default IGNORE_YARN_INSTALL_ERROR: 1 ELECTRON_TEST_RESULTS_DIR: junit MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap' MOCHA_REPORTER: mocha-multi-reporters + condition: always() - task: PublishTestResults@2 displayName: 'Publish Test Results' diff --git a/build/fuses/fuses.json5 b/build/fuses/fuses.json5 index dfc518ffa36e7..bb5ec6c1f21e4 100644 --- a/build/fuses/fuses.json5 +++ b/build/fuses/fuses.json5 @@ -3,5 +3,7 @@ "_schema": "0 == off, 1 == on, r == removed fuse", "_version": 1, "run_as_node": "1", - "cookie_encryption": "0" + "cookie_encryption": "0", + "node_options": "1", + "node_cli_inspect": "1" } diff --git a/build/generate_node_defines.py b/build/generate_node_defines.py new file mode 100755 index 0000000000000..f2004abb9fe8e --- /dev/null +++ b/build/generate_node_defines.py @@ -0,0 +1,34 @@ +import os +import re +import sys + +DEFINE_EXTRACT_REGEX = re.compile('^ *# *define (\w*)', re.MULTILINE) + +def main(outDir, headers): + defines = [] + for filename in headers: + with open(filename, 'r') as f: + content = f.read() + defines += read_defines(content) + + push_and_undef = '' + for define in defines: + push_and_undef += '#pragma push_macro("%s")\n' % define + push_and_undef += '#undef %s\n' % define + with open(os.path.join(outDir, 'push_and_undef_node_defines.h'), 'w') as o: + o.write(push_and_undef) + + pop = '' + for define in defines: + pop += '#pragma pop_macro("%s")\n' % define + with open(os.path.join(outDir, 'pop_node_defines.h'), 'w') as o: + o.write(pop) + +def read_defines(content): + defines = [] + for match in DEFINE_EXTRACT_REGEX.finditer(content): + defines.append(match.group(1)) + return defines + +if __name__ == '__main__': + main(sys.argv[1], sys.argv[2:]) diff --git a/build/npm.gni b/build/npm.gni index 1d1c944256b8b..c2a0d1725af75 100644 --- a/build/npm.gni +++ b/build/npm.gni @@ -5,8 +5,8 @@ template("npm_action") { action("npm_pre_flight_" + target_name) { inputs = [ - "package.json", - "yarn.lock", + "//electron/package.json", + "//electron/yarn.lock", ] script = "//electron/build/npm-run.py" diff --git a/build/webpack/webpack.gni b/build/webpack/webpack.gni index 2157cceabe320..bc9cd5f439f24 100644 --- a/build/webpack/webpack.gni +++ b/build/webpack/webpack.gni @@ -36,7 +36,7 @@ template("webpack_build") { rebase_path("$target_gen_dir/buildflags/buildflags.h"), "--env.mode=" + mode, ] - deps += [ "buildflags" ] + deps += [ "//electron/buildflags" ] outputs = [ invoker.out_file ] } diff --git a/build/zip.py b/build/zip.py index 285544aed0b1f..19fe514cd9d30 100644 --- a/build/zip.py +++ b/build/zip.py @@ -31,12 +31,6 @@ # //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', 'gen/third_party/devtools-frontend/src', diff --git a/chromium_src/BUILD.gn b/chromium_src/BUILD.gn index f5ce3bbf779f6..1b6be88ba8026 100644 --- a/chromium_src/BUILD.gn +++ b/chromium_src/BUILD.gn @@ -21,6 +21,8 @@ static_library("chrome") { "//chrome/browser/devtools/devtools_contents_resizing_strategy.h", "//chrome/browser/devtools/devtools_embedder_message_dispatcher.cc", "//chrome/browser/devtools/devtools_embedder_message_dispatcher.h", + "//chrome/browser/devtools/devtools_eye_dropper.cc", + "//chrome/browser/devtools/devtools_eye_dropper.h", "//chrome/browser/devtools/devtools_file_system_indexer.cc", "//chrome/browser/devtools/devtools_file_system_indexer.h", "//chrome/browser/extensions/global_shortcut_listener.cc", @@ -35,6 +37,8 @@ static_library("chrome") { "//chrome/browser/net/proxy_config_monitor.h", "//chrome/browser/net/proxy_service_factory.cc", "//chrome/browser/net/proxy_service_factory.h", + "//chrome/browser/platform_util.cc", + "//chrome/browser/platform_util.h", "//chrome/browser/predictors/preconnect_manager.cc", "//chrome/browser/predictors/preconnect_manager.h", "//chrome/browser/predictors/predictors_features.cc", @@ -45,6 +49,10 @@ static_library("chrome") { "//chrome/browser/predictors/resolve_host_client_impl.h", "//chrome/browser/ui/views/autofill/autofill_popup_view_utils.cc", "//chrome/browser/ui/views/autofill/autofill_popup_view_utils.h", + "//chrome/browser/ui/views/eye_dropper/eye_dropper.cc", + "//chrome/browser/ui/views/eye_dropper/eye_dropper.h", + "//chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc", + "//chrome/browser/ui/views/eye_dropper/eye_dropper_view.h", "//extensions/browser/app_window/size_constraints.cc", "//extensions/browser/app_window/size_constraints.h", ] @@ -56,6 +64,9 @@ static_library("chrome") { "//chrome/browser/icon_loader_mac.mm", "//chrome/browser/media/webrtc/system_media_capture_permissions_mac.h", "//chrome/browser/media/webrtc/system_media_capture_permissions_mac.mm", + "//chrome/browser/media/webrtc/window_icon_util_mac.mm", + "//chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.h", + "//chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm", ] } @@ -64,13 +75,28 @@ static_library("chrome") { "//chrome/browser/extensions/global_shortcut_listener_win.cc", "//chrome/browser/extensions/global_shortcut_listener_win.h", "//chrome/browser/icon_loader_win.cc", + "//chrome/browser/media/webrtc/window_icon_util_win.cc", + "//chrome/browser/ui/frame/window_frame_util.h", + "//chrome/browser/ui/view_ids.h", "//chrome/browser/win/chrome_process_finder.cc", "//chrome/browser/win/chrome_process_finder.h", + "//chrome/browser/win/titlebar_config.h", "//chrome/child/v8_crashpad_support_win.cc", "//chrome/child/v8_crashpad_support_win.h", ] } + if (is_linux) { + sources += [ "//chrome/browser/media/webrtc/window_icon_util_linux.cc" ] + } + + if (use_aura) { + sources += [ + "//chrome/browser/platform_util_aura.cc", + "//chrome/browser/ui/views/eye_dropper/eye_dropper_view_aura.cc", + ] + } + public_deps = [ "//chrome/browser:dev_ui_browser_resources", "//chrome/common", @@ -144,64 +170,6 @@ static_library("chrome") { deps += [ "//ui/snapshot" ] } - if (enable_color_chooser) { - sources += [ - "//chrome/browser/devtools/devtools_eye_dropper.cc", - "//chrome/browser/devtools/devtools_eye_dropper.h", - "//chrome/browser/platform_util.cc", - "//chrome/browser/platform_util.h", - "//chrome/browser/ui/browser_dialogs.h", - "//chrome/browser/ui/color_chooser.h", - "//chrome/browser/ui/views/eye_dropper/eye_dropper.cc", - "//chrome/browser/ui/views/eye_dropper/eye_dropper.h", - "//chrome/browser/ui/views/eye_dropper/eye_dropper_view.cc", - "//chrome/browser/ui/views/eye_dropper/eye_dropper_view.h", - ] - - if (use_aura) { - sources += [ - "//chrome/browser/platform_util_aura.cc", - "//chrome/browser/ui/views/eye_dropper/eye_dropper_view_aura.cc", - ] - - if (!is_win) { - sources += [ - "//chrome/browser/ui/views/color_chooser_aura.cc", - "//chrome/browser/ui/views/color_chooser_aura.h", - ] - } - - deps += [ "//components/feature_engagement" ] - } - - if (is_mac) { - sources += [ - "//chrome/browser/media/webrtc/window_icon_util_mac.mm", - "//chrome/browser/ui/cocoa/color_chooser_mac.h", - "//chrome/browser/ui/cocoa/color_chooser_mac.mm", - "//chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.h", - "//chrome/browser/ui/views/eye_dropper/eye_dropper_view_mac.mm", - ] - deps += [ - "//components/remote_cocoa/app_shim", - "//components/remote_cocoa/browser", - ] - } - - if (is_win) { - sources += [ - "//chrome/browser/media/webrtc/window_icon_util_win.cc", - "//chrome/browser/ui/views/color_chooser_dialog.cc", - "//chrome/browser/ui/views/color_chooser_dialog.h", - "//chrome/browser/ui/views/color_chooser_win.cc", - ] - } - - if (is_linux) { - sources += [ "//chrome/browser/media/webrtc/window_icon_util_linux.cc" ] - } - } - if (enable_widevine) { sources += [ "//chrome/renderer/media/chrome_key_systems.cc", diff --git a/chromium_src/chrome/browser/process_singleton_win.cc b/chromium_src/chrome/browser/process_singleton_win.cc index d1e115945c407..e8a81c284f416 100644 --- a/chromium_src/chrome/browser/process_singleton_win.cc +++ b/chromium_src/chrome/browser/process_singleton_win.cc @@ -4,6 +4,7 @@ #include "chrome/browser/process_singleton.h" +#include #include #include "base/base_paths.h" diff --git a/docs/api/app.md b/docs/api/app.md index 370ee386626de..f1f6890cd61f3 100755 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -1137,8 +1137,8 @@ badge. On macOS, it shows on the dock icon. On Linux, it only works for Unity launcher. -**Note:** Unity launcher requires the existence of a `.desktop` file to work, -for more information please read [Desktop Environment Integration][unity-requirement]. +**Note:** Unity launcher requires a `.desktop` file to work. For more information, +please read the [Unity integration documentation][unity-requirement]. ### `app.getBadgeCount()` _Linux_ _macOS_ @@ -1376,8 +1376,8 @@ An `Integer` property that returns the badge count for current app. Setting the On macOS, setting this with any nonzero integer shows on the dock icon. On Linux, this property only works for Unity launcher. -**Note:** Unity launcher requires the existence of a `.desktop` file to work, -for more information please read [Desktop Environment Integration][unity-requirement]. +**Note:** Unity launcher requires a `.desktop` file to work. For more information, +please read the [Unity integration documentation][unity-requirement]. **Note:** On macOS, you need to ensure that your application has the permission to display notifications for this property to take effect. @@ -1405,7 +1405,7 @@ A `Boolean` property that returns `true` if the app is packaged, `false` otherw [LSCopyDefaultHandlerForURLScheme]: https://developer.apple.com/library/mac/documentation/Carbon/Reference/LaunchServicesReference/#//apple_ref/c/func/LSCopyDefaultHandlerForURLScheme [handoff]: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/Handoff/HandoffFundamentals/HandoffFundamentals.html [activity-type]: https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSUserActivity_Class/index.html#//apple_ref/occ/instp/NSUserActivity/activityType -[unity-requirement]: ../tutorial/desktop-environment-integration.md#unity-launcher +[unity-requirement]: https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles#Adding_shortcuts_to_a_launcher [mas-builds]: ../tutorial/mac-app-store-submission-guide.md [Squirrel-Windows]: https://github.com/Squirrel/Squirrel.Windows [JumpListBeginListMSDN]: https://msdn.microsoft.com/en-us/library/windows/desktop/dd378398(v=vs.85).aspx diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 61c4b00e03a9e..10f4533fda95e 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -187,9 +187,9 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. * `parent` BrowserWindow (optional) - Specify parent window. Default is `null`. * `modal` Boolean (optional) - Whether this is a modal window. This only works when the window is a child window. Default is `false`. - * `acceptFirstMouse` Boolean (optional) - Whether the web view accepts a single - mouse-down event that simultaneously activates the window. Default is - `false`. + * `acceptFirstMouse` Boolean (optional) - Whether clicking an inactive window will also + click through to the web contents. Default is `false` on macOS. This option is not + configurable on other platforms. * `disableAutoHideCursor` Boolean (optional) - Whether to hide cursor when typing. Default is `false`. * `autoHideMenuBar` Boolean (optional) - Auto hide the menu bar unless the `Alt` @@ -213,16 +213,13 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. * `followWindow` - The backdrop should automatically appear active when the window is active, and inactive when it is not. This is the default. * `active` - The backdrop should always appear active. * `inactive` - The backdrop should always appear inactive. - * `titleBarStyle` String (optional) - The style of window title bar. + * `titleBarStyle` String (optional) _macOS_ _Windows_ - The style of window title bar. Default is `default`. Possible values are: - * `default` - Results in the standard gray opaque Mac title - bar. - * `hidden` - Results in a hidden title bar and a full size content window, yet - the title bar still has the standard window controls ("traffic lights") in - the top left. - * `hiddenInset` - Results in a hidden title bar with an alternative look + * `default` - Results in the standard title bar for macOS or Windows respectively. + * `hidden` - Results in a hidden title bar and a full size content window. On macOS, the window still has the standard window controls (“traffic lights”) in the top left. On Windows, when combined with `titleBarOverlay: true` it will activate the Window Controls Overlay (see `titleBarOverlay` for more information), otherwise no window controls will be shown. + * `hiddenInset` - Only on macOS, results in a hidden title bar with an alternative look where the traffic light buttons are slightly more inset from the window edge. - * `customButtonsOnHover` - Results in a hidden title bar and a full size + * `customButtonsOnHover` - Only on macOS, results in a hidden title bar and a full size content window, the traffic light buttons will display when being hovered over in the top left of the window. **Note:** This option is currently experimental. @@ -392,10 +389,9 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. contain the layout of the document—without requiring scrolling. Enabling this will cause the `preferred-size-changed` event to be emitted on the `WebContents` when the preferred size changes. Default is `false`. - * `titleBarOverlay` Boolean (optional) - On macOS, when using a frameless window in conjunction with - `win.setWindowButtonVisibility(true)` or using a `titleBarStyle` so that the traffic lights are visible, - this property enables the Window Controls Overlay [JavaScript APIs][overlay-javascript-apis] and - [CSS Environment Variables][overlay-css-env-vars]. Default is `false`. + * `titleBarOverlay` Object | Boolean (optional) - When using a frameless window in conjuction with `win.setWindowButtonVisibility(true)` on macOS or using a `titleBarStyle` so that the standard window controls ("traffic lights" on macOS) are visible, this property enables the Window Controls Overlay [JavaScript APIs][overlay-javascript-apis] and [CSS Environment Variables][overlay-css-env-vars]. Specifying `true` will result in an overlay with default system colors. Default is `false`. + * `color` String (optional) _Windows_ - The CSS color of the Window Controls Overlay when enabled. Default is the system color. + * `symbolColor` String (optional) _Windows_ - The CSS color of the symbols on the Window Controls Overlay when enabled. Default is the system color. When setting minimum or maximum window size with `minWidth`/`maxWidth`/ `minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from diff --git a/docs/api/crash-reporter.md b/docs/api/crash-reporter.md index 8331bc8d43f52..bf318eae954f0 100644 --- a/docs/api/crash-reporter.md +++ b/docs/api/crash-reporter.md @@ -19,6 +19,9 @@ following projects: * [socorro](https://github.com/mozilla/socorro) * [mini-breakpad-server](https://github.com/electron/mini-breakpad-server) +> **Note:** Electron uses Crashpad, not Breakpad, to collect and upload +> crashes, but for the time being, the [upload protocol is the same](https://chromium.googlesource.com/crashpad/crashpad/+/HEAD/doc/overview_design.md#Upload-to-collection-server). + Or use a 3rd party hosted solution: * [Backtrace](https://backtrace.io/electron/) @@ -26,49 +29,12 @@ Or use a 3rd party hosted solution: * [BugSplat](https://www.bugsplat.com/docs/platforms/electron) Crash reports are stored temporarily before being uploaded in a directory -underneath the app's user data directory (called 'Crashpad' on Windows and Mac, -or 'Crash Reports' on Linux). You can override this directory by calling -`app.setPath('crashDumps', '/path/to/crashes')` before starting the crash -reporter. - -On Windows and macOS, Electron uses -[crashpad](https://chromium.googlesource.com/crashpad/crashpad/+/master/README.md) -to monitor and report crashes. On Linux, Electron uses -[breakpad](https://chromium.googlesource.com/breakpad/breakpad/+/master/). This -is an implementation detail driven by Chromium, and it may change in future. In -particular, crashpad is newer and will likely eventually replace breakpad on -all platforms. - -### Note about Node child processes on Linux - -If you are using the Node.js `child_process` module and want to report crashes -from those processes on Linux, there is an extra step you will need to take to -properly initialize the crash reporter in the child process. This is not -necessary on Mac or Windows, as those platforms use Crashpad, which -automatically monitors child processes. - -Since `require('electron')` is not available in Node child processes, the -following APIs are available on the `process` object in Node child processes. -Note that, on Linux, each Node child process has its own separate instance of -the breakpad crash reporter. This is dissimilar to renderer child processes, -which have a "stub" breakpad reporter which returns information to the main -process for reporting. - -#### `process.crashReporter.start(options)` - -See [`crashReporter.start()`](#crashreporterstartoptions). +underneath the app's user data directory, called 'Crashpad'. You can override +this directory by calling `app.setPath('crashDumps', '/path/to/crashes')` +before starting the crash reporter. -#### `process.crashReporter.getParameters()` - -See [`crashReporter.getParameters()`](#crashreportergetparameters). - -#### `process.crashReporter.addExtraParameter(key, value)` - -See [`crashReporter.addExtraParameter(key, value)`](#crashreporteraddextraparameterkey-value). - -#### `process.crashReporter.removeExtraParameter(key)` - -See [`crashReporter.removeExtraParameter(key)`](#crashreporterremoveextraparameterkey). +Electron uses [crashpad](https://chromium.googlesource.com/crashpad/crashpad/+/refs/heads/main/README.md) +to monitor and report crashes. ## Methods @@ -186,12 +152,6 @@ names must be no longer than 39 bytes, and values must be no longer than 20320 bytes. Keys with names longer than the maximum will be silently ignored. Key values longer than the maximum length will be truncated. -**Note:** On linux values that are longer than 127 bytes will be chunked into -multiple keys, each 127 bytes in length. E.g. `addExtraParameter('foo', 'a'.repeat(130))` -will result in two chunked keys `foo__1` and `foo__2`, the first will contain -the first 127 bytes and the second will contain the remaining 3 bytes. On -your crash reporting backend you should stitch together keys in this format. - ### `crashReporter.removeExtraParameter(key)` * `key` String - Parameter key, must be no longer than 39 bytes. @@ -203,6 +163,32 @@ will not include this parameter. Returns `Record` - The current 'extra' parameters of the crash reporter. +## In Node child processes + +Since `require('electron')` is not available in Node child processes, the +following APIs are available on the `process` object in Node child processes. + +#### `process.crashReporter.start(options)` + +See [`crashReporter.start()`](#crashreporterstartoptions). + +Note that if the crash reporter is started in the main process, it will +automatically monitor child processes, so it should not be started in the child +process. Only use this method if the main process does not initialize the crash +reporter. + +#### `process.crashReporter.getParameters()` + +See [`crashReporter.getParameters()`](#crashreportergetparameters). + +#### `process.crashReporter.addExtraParameter(key, value)` + +See [`crashReporter.addExtraParameter(key, value)`](#crashreporteraddextraparameterkey-value). + +#### `process.crashReporter.removeExtraParameter(key)` + +See [`crashReporter.removeExtraParameter(key)`](#crashreporterremoveextraparameterkey). + ## Crash Report Payload The crash reporter will send the following data to the `submitURL` as diff --git a/docs/api/dialog.md b/docs/api/dialog.md index c1fc0a2b2947c..ab2833d14251a 100644 --- a/docs/api/dialog.md +++ b/docs/api/dialog.md @@ -273,6 +273,11 @@ If `browserWindow` is not shown dialog will not be attached to it. In such case will result in one button labeled "OK". * `defaultId` Integer (optional) - Index of the button in the buttons array which will be selected by default when the message box opens. + * `signal` AbortSignal (optional) - Pass an instance of [AbortSignal][] to + optionally close the message box, the message box will behave as if it was + cancelled by the user. On macOS, `signal` does not work with message boxes + that do not have a parent window, since those message boxes run + synchronously due to platform limitations. * `title` String (optional) - Title of the message box, some platforms will not show it. * `detail` String (optional) - Extra information of the message. * `checkboxLabel` String (optional) - If provided, the message box will @@ -360,3 +365,5 @@ window is provided. You can call `BrowserWindow.getCurrentWindow().setSheetOffset(offset)` to change the offset from the window frame where sheets are attached. + +[AbortSignal]: https://nodejs.org/api/globals.html#globals_class_abortsignal diff --git a/docs/api/extensions.md b/docs/api/extensions.md index 3bd27f4fd1c79..afaff0ef63487 100644 --- a/docs/api/extensions.md +++ b/docs/api/extensions.md @@ -78,6 +78,7 @@ The following methods of `chrome.runtime` are supported: - `chrome.runtime.getURL` - `chrome.runtime.connect` - `chrome.runtime.sendMessage` +- `chrome.runtime.reload` The following events of `chrome.runtime` are supported: @@ -99,6 +100,8 @@ The following methods of `chrome.tabs` are supported: - `chrome.tabs.sendMessage` - `chrome.tabs.executeScript` +- `chrome.tabs.update` (partial support) + - supported properties: `url`, `muted`. > **Note:** In Chrome, passing `-1` as a tab ID signifies the "currently active > tab". Since Electron has no such concept, passing `-1` as a tab ID is not diff --git a/docs/api/frameless-window.md b/docs/api/frameless-window.md index 7a73c8925e200..7f327904b36e7 100644 --- a/docs/api/frameless-window.md +++ b/docs/api/frameless-window.md @@ -18,17 +18,17 @@ const win = new BrowserWindow({ width: 800, height: 600, frame: false }) win.show() ``` -### Alternatives on macOS +### Alternatives -There's an alternative way to specify a chromeless window. +There's an alternative way to specify a chromeless window on macOS and Windows. Instead of setting `frame` to `false` which disables both the titlebar and window controls, you may want to have the title bar hidden and your content extend to the full window size, -yet still preserve the window controls ("traffic lights") for standard window actions. +yet still preserve the window controls ("traffic lights" on macOS) for standard window actions. You can do so by specifying the `titleBarStyle` option: #### `hidden` -Results in a hidden title bar and a full size content window, yet the title bar still has the standard window controls (“traffic lights”) in the top left. +Results in a hidden title bar and a full size content window. On macOS, the title bar still has the standard window controls (“traffic lights”) in the top left. ```javascript const { BrowserWindow } = require('electron') @@ -36,6 +36,8 @@ const win = new BrowserWindow({ titleBarStyle: 'hidden' }) win.show() ``` +### Alternatives on macOS + #### `hiddenInset` Results in a hidden title bar with an alternative look where the traffic light buttons are slightly more inset from the window edge. @@ -63,19 +65,33 @@ win.show() ## Windows Control Overlay -On macOS, when using a frameless window in conjuction with `win.setWindowButtonVisibility(true)` or using one of the `titleBarStyle`s described above so -that the traffic lights are visible, you can access the Window Controls Overlay [JavaScript APIs][overlay-javascript-apis] and -[CSS Environment Variables][overlay-css-env-vars] by setting the `titleBarOverlay` option to true: +When using a frameless window in conjuction with `win.setWindowButtonVisibility(true)` on macOS, using one of the `titleBarStyle`s as described above so +that the traffic lights are visible, or using `titleBarStyle: hidden` on Windows, you can access the Window Controls Overlay [JavaScript APIs][overlay-javascript-apis] and +[CSS Environment Variables][overlay-css-env-vars] by setting the `titleBarOverlay` option to true. Specifying `true` will result in an overlay with default system colors. + +On Windows, you can also specify the color of the overlay and its symbols by setting `titleBarOverlay` to an object with the options `color` and `symbolColor`. If an option is not specified, the color will default to its system color for the window control buttons: ```javascript const { BrowserWindow } = require('electron') const win = new BrowserWindow({ - titleBarStyle: 'hiddenInset', + titleBarStyle: 'hidden', titleBarOverlay: true }) win.show() ``` +```javascript +const { BrowserWindow } = require('electron') +const win = new BrowserWindow({ + titleBarStyle: 'hidden', + titleBarOverlay: { + color: '#2f3241', + symbolColor: '#74b1be' + } +}) +win.show() +``` + ## Transparent window By setting the `transparent` option to `true`, you can also make the frameless diff --git a/docs/api/menu-item.md b/docs/api/menu-item.md index 6a9c755c16fa3..1eec94b93e313 100644 --- a/docs/api/menu-item.md +++ b/docs/api/menu-item.md @@ -14,7 +14,7 @@ See [`Menu`](menu.md) for examples. * `menuItem` MenuItem * `browserWindow` [BrowserWindow](browser-window.md) | undefined - This will not be defined if no window is open. * `event` [KeyboardEvent](structures/keyboard-event.md) - * `role` String (optional) - Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `shareMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` - Define the action of the menu item, when specified the + * `role` String (optional) - Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `toggleSpellChecker`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `shareMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` - Define the action of the menu item, when specified the `click` property will be ignored. See [roles](#roles). * `type` String (optional) - Can be `normal`, `separator`, `submenu`, `checkbox` or `radio`. @@ -155,7 +155,7 @@ A `String` indicating the type of the item. Can be `normal`, `separator`, `subme #### `menuItem.role` -A `String` (optional) indicating the item's role, if set. Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` +A `String` (optional) indicating the item's role, if set. Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `toggleSpellChecker`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `shareMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` #### `menuItem.accelerator` diff --git a/docs/api/menu.md b/docs/api/menu.md index 4def1a18e12f0..fd8f81f352506 100644 --- a/docs/api/menu.md +++ b/docs/api/menu.md @@ -162,7 +162,7 @@ const template = [ { role: 'services' }, { type: 'separator' }, { role: 'hide' }, - { role: 'hideothers' }, + { role: 'hideOthers' }, { role: 'unhide' }, { type: 'separator' }, { role: 'quit' } diff --git a/docs/api/safe-storage.md b/docs/api/safe-storage.md new file mode 100644 index 0000000000000..b604198e233ee --- /dev/null +++ b/docs/api/safe-storage.md @@ -0,0 +1,40 @@ +# safeStorage + +> Allows access to simple encryption and decryption of strings for storage on the local machine. + +Process: [Main](../glossary.md#main-process) + +This module protects data stored on disk from being accessed by other applications or users with full disk access. + +Note that on Mac, access to the system Keychain is required and +these calls can block the current thread to collect user input. +The same is true for Linux, if a password management tool is available. + +## Methods + +The `safeStorage` module has the following methods: + +### `safeStorage.isEncryptionAvailable()` + +Returns `Boolean` - Whether encryption is available. + +On Linux, returns true if the secret key is +available. On MacOS, returns true if Keychain is available. +On Windows, returns true with no other preconditions. + +### `safeStorage.encryptString(plainText)` + +* `plainText` String + +Returns `Buffer` - An array of bytes representing the encrypted string. + +This function will throw an error if encryption fails. + +### `safeStorage.decryptString(encrypted)` + +* `encrypted` Buffer + +Returns `String` - the decrypted string. Decrypts the encrypted buffer +obtained with `safeStorage.encryptString` back into a string. + +This function will throw an error if decryption fails. diff --git a/docs/api/session.md b/docs/api/session.md index 25389f70b713a..e88dbce9fa941 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -86,8 +86,8 @@ available from next tick of the process. const { session } = require('electron') session.defaultSession.on('will-download', (event, item, webContents) => { event.preventDefault() - require('request')(item.getURL(), (data) => { - require('fs').writeFileSync('/somewhere', data) + require('got')(item.getURL()).then((response) => { + require('fs').writeFileSync('/somewhere', response.body) }) }) ``` @@ -180,7 +180,7 @@ Emitted when a hunspell dictionary file download fails. For details on the failure you should collect a netlog and inspect the download request. -#### Event: 'select-serial-port' _Experimental_ +#### Event: 'select-serial-port' Returns: @@ -197,14 +197,10 @@ cancel the request. Additionally, permissioning on `navigator.serial` can be managed by using [ses.setPermissionCheckHandler(handler)](#sessetpermissioncheckhandlerhandler) with the `serial` permission. -Because this is an experimental feature it is disabled by default. To enable this feature, you -will need to use the `--enable-features=ElectronSerialChooser` command line switch. - ```javascript const { app, BrowserWindow } = require('electron') let win = null -app.commandLine.appendSwitch('enable-features', 'ElectronSerialChooser') app.whenReady().then(() => { win = new BrowserWindow({ @@ -225,7 +221,7 @@ app.whenReady().then(() => { }) ``` -#### Event: 'serial-port-added' _Experimental_ +#### Event: 'serial-port-added' Returns: @@ -235,7 +231,7 @@ Returns: Emitted after `navigator.serial.requestPort` has been called and `select-serial-port` has fired if a new serial port becomes available. For example, this event will fire when a new USB device is plugged in. -#### Event: 'serial-port-removed' _Experimental_ +#### Event: 'serial-port-removed' Returns: @@ -447,7 +443,8 @@ the original network configuration. * `hostname` String * `certificate` [Certificate](structures/certificate.md) * `validatedCertificate` [Certificate](structures/certificate.md) - * `verificationResult` String - Verification result from chromium. + * `isIssuedByKnownRoot` Boolean - `true` if Chromium recognises the root CA as a standard root. If it isn't then it's probably the case that this certificate was generated by a MITM proxy whose root has been installed locally (for example, by a corporate proxy). This should not be trusted if the `verificationResult` is not `OK`. + * `verificationResult` String - `OK` if the certificate is trusted, otherwise an error like `CERT_REVOKED`. * `errorCode` Integer - Error code. * `callback` Function * `verificationResult` Integer - Value can be one of certificate error codes diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 9e0e6e0066945..b61984607cca7 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -449,6 +449,8 @@ Returns: * `control` Boolean - Equivalent to [KeyboardEvent.controlKey][keyboardevent]. * `alt` Boolean - Equivalent to [KeyboardEvent.altKey][keyboardevent]. * `meta` Boolean - Equivalent to [KeyboardEvent.metaKey][keyboardevent]. + * `location` Number - Equivalent to [KeyboardEvent.location][keyboardevent]. + * `modifiers` String[] - See [InputEvent.modifiers](structures/input-event.md). Emitted before dispatching the `keydown` and `keyup` events in the page. Calling `event.preventDefault` will prevent the page `keydown`/`keyup` events diff --git a/docs/api/webview-tag.md b/docs/api/webview-tag.md index 29753e4bcb7f6..0c5dfd69d2ed9 100644 --- a/docs/api/webview-tag.md +++ b/docs/api/webview-tag.md @@ -710,6 +710,10 @@ Corresponds to the points in time when the spinner of the tab starts spinning. Corresponds to the points in time when the spinner of the tab stops spinning. +### Event: 'did-attach' + +Fired when attached to the embedder web contents. + ### Event: 'dom-ready' Fired when document in the given frame is loaded. @@ -830,6 +834,19 @@ this purpose. Calling `event.preventDefault()` does __NOT__ have any effect. +### Event: 'did-start-navigation' + +Returns: + +* `url` String +* `isInPlace` Boolean +* `isMainFrame` Boolean +* `frameProcessId` Integer +* `frameRoutingId` Integer + +Emitted when any frame (including main) starts navigating. `isInPlace` will be +`true` for in-page navigations. + ### Event: 'did-navigate' Returns: @@ -842,6 +859,23 @@ This event is not emitted for in-page navigations, such as clicking anchor links or updating the `window.location.hash`. Use `did-navigate-in-page` event for this purpose. +### Event: 'did-frame-navigate' + +Returns: + +* `url` String +* `httpResponseCode` Integer - -1 for non HTTP navigations +* `httpStatusText` String - empty for non HTTP navigations, +* `isMainFrame` Boolean +* `frameProcessId` Integer +* `frameRoutingId` Integer + +Emitted when any frame navigation is done. + +This event is not emitted for in-page navigations, such as clicking anchor links +or updating the `window.location.hash`. Use `did-navigate-in-page` event for +this purpose. + ### Event: 'did-navigate-in-page' Returns: diff --git a/docs/breaking-changes.md b/docs/breaking-changes.md index de11e1eb4a451..abc640c29c936 100644 --- a/docs/breaking-changes.md +++ b/docs/breaking-changes.md @@ -12,6 +12,21 @@ 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 (16.0) + +### Behavior Changed: `crashReporter` implementation switched to Crashpad on Linux + +The underlying implementation of the `crashReporter` API on Linux has changed +from Breakpad to Crashpad, bringing it in line with Windows and Mac. As a +result of this, child processes are now automatically monitored, and calling +`process.crashReporter.start` in Node child processes is no longer needed (and +is not advisable, as it will start a second instance of the Crashpad reporter). + +There are also some subtle changes to how annotations will be reported on +Linux, including that long values will no longer be split between annotations +appended with `__1`, `__2` and so on, and instead will be truncated at the +(new, longer) annotation value limit. + ## Planned Breaking API Changes (14.0) ### Removed: `app.allowRendererProcessReuse` diff --git a/docs/tutorial/accessibility.md b/docs/tutorial/accessibility.md index a2c47d47d13cb..ee9a074ff22b6 100644 --- a/docs/tutorial/accessibility.md +++ b/docs/tutorial/accessibility.md @@ -21,7 +21,7 @@ In the testing framework Spectron, you can now audit each window and `` tag in your application. For example: ```javascript -app.client.auditAccessibility().then(function (audit) { +app.client.auditAccessibility().then((audit) => { if (audit.failed) { console.error(audit.message) } diff --git a/docs/tutorial/automated-testing-with-a-custom-driver.md b/docs/tutorial/automated-testing-with-a-custom-driver.md index a5e7920eb3683..15a59218c1a81 100644 --- a/docs/tutorial/automated-testing-with-a-custom-driver.md +++ b/docs/tutorial/automated-testing-with-a-custom-driver.md @@ -84,11 +84,15 @@ class TestDriver { In the app, you'd need to write a simple handler for the RPC calls: ```js -if (process.env.APP_TEST_DRIVER) { - process.on('message', onMessage) +const METHODS = { + isReady () { + // do any setup needed + return true + } + // define your RPC-able methods here } -async function onMessage ({ msgId, cmd, args }) { +const onMessage = async ({ msgId, cmd, args }) => { let method = METHODS[cmd] if (!method) method = () => new Error('Invalid method: ' + cmd) try { @@ -104,12 +108,8 @@ async function onMessage ({ msgId, cmd, args }) { } } -const METHODS = { - isReady () { - // do any setup needed - return true - } - // define your RPC-able methods here +if (process.env.APP_TEST_DRIVER) { + process.on('message', onMessage) } ``` diff --git a/docs/tutorial/code-signing.md b/docs/tutorial/code-signing.md index 5d6b16216ea49..f8e34468dea84 100644 --- a/docs/tutorial/code-signing.md +++ b/docs/tutorial/code-signing.md @@ -133,7 +133,7 @@ are likely using [`electron-packager`], which includes [`electron-osx-sign`] and If you're using Packager's API, you can pass [in configuration that both signs and notarizes your -application](https://electron.github.io/electron-packager/master/interfaces/electronpackager.options.html). +application](https://electron.github.io/electron-packager/main/interfaces/electronpackager.options.html). ```js const packager = require('electron-packager') diff --git a/docs/tutorial/creating-api.md b/docs/tutorial/creating-api.md new file mode 100644 index 0000000000000..4edc198f9c108 --- /dev/null +++ b/docs/tutorial/creating-api.md @@ -0,0 +1,175 @@ +# Creating an Electron Browser Module API + +Welcome to the Electron API guide! If you are unfamiliar with creating electron APIs within the `browser` module, this guide serves as a checklist for some of the necessary steps that you will need to implement. + +This is not a comprehensive end-all guide to creating an Electron Browser API, rather an outline documenting some of the more unintuitive steps. + +## Adding Your Files To Electron's Project Configuration + +Electron uses [GN](https://gn.googlesource.com/gn) as a meta build system to generate files for its compiler, [Ninja](https://ninja-build.org/). This means that in order to tell Electron to compile your code, we have to add your API's code and header file names into [`filenames.gni`](https://github.com/electron/electron/blob/main/filenames.gni). + +You will need to append your api file names alphabetically into the appropriate files like so: + +```cpp +lib_sources = [ + "path/to/api/api_name.cc", + "path/to/api/api_name.h", +] + +lib_sources_mac = [ + "path/to/api/api_name_mac.h", + "path/to/api/api_name_mac.mm", +] + +lib_sources_win = [ + "path/to/api/api_name_win.cc", + "path/to/api/api_name_win.h", +] + +lib_sources_linux = [ + "path/to/api/api_name_linux.cc", + "path/to/api/api_name_linux.h", +] +``` + +Note that the Windows, MacOS and Linux array additions are optional and should only be added if your API has specific platform implementations. + +## Create API Documentation + +Type definitions are generated by Electron using [`docs-parser`](https://github.com/electron/docs-parser) and [`typescript-definitions`](https://github.com/electron/typescript-definitions). This step is necessary to ensure consistency across Electron's API documentation. This means that for your API type definition to appear in the `electron.d.ts` file, we must create a `.md` file. Examples can be found in [this folder](https://github.com/electron/electron/tree/main/docs/api). + +## Setting Up `ObjectTemplateBuilder` and `Wrappable` + +Electron constructs its modules using [`object_template_builder`](https://www.electronjs.org/blog/from-native-to-js#mateobjecttemplatebuilder). + +[`wrappable`](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/gin/wrappable.h) is a base class for C++ objects that have corresponding v8 wrapper objects. + +Here is a basic example of code that you may need to add, in order to incorporate `object_template_builder` and `wrappable` into your API. For further reference, you can find more implementations [here](https://github.com/electron/electron/tree/main/shell/browser/api). + +In your `api_name.h` file: + +```cpp + +#ifndef SHELL_BROWSER_API_ELECTRON_API_{API_NAME}_H_ +#define SHELL_BROWSER_API_ELECTRON_API_{API_NAME}_H_ + +#include "gin/handle.h" +#include "gin/wrappable.h" + +namespace electron { + +namespace api { + +class ApiName : public gin::Wrappable { + public: + static gin::Handle Create(v8::Isolate* isolate); + + // gin::Wrappable + static gin::WrapperInfo kWrapperInfo; + gin::ObjectTemplateBuilder GetObjectTemplateBuilder( + v8::Isolate* isolate) override; + const char* GetTypeName() override; +} // namespace api +} // namespace electron +``` + +In your `api_name.cc` file: + +```cpp +#include "shell/browser/api/electron_api_safe_storage.h" + +#include "shell/browser/browser.h" +#include "shell/common/gin_converters/base_converter.h" +#include "shell/common/gin_converters/callback_converter.h" +#include "shell/common/gin_helper/dictionary.h" +#include "shell/common/gin_helper/object_template_builder.h" +#include "shell/common/node_includes.h" +#include "shell/common/platform_util.h" + +namespace electron { + +namespace api { + +gin::WrapperInfo ApiName::kWrapperInfo = {gin::kEmbedderNativeGin}; + +gin::ObjectTemplateBuilder ApiName::GetObjectTemplateBuilder( + v8::Isolate* isolate) { + return gin::ObjectTemplateBuilder(isolate) + .SetMethod("methodName", &ApiName::methodName); +} + +const char* ApiName::GetTypeName() { + return "ApiName"; +} + +// static +gin::Handle ApiName::Create(v8::Isolate* isolate) { + return gin::CreateHandle(isolate, new ApiName()); +} + +} // namespace api + +} // namespace electron + +namespace { + +void Initialize(v8::Local exports, + v8::Local unused, + v8::Local context, + void* priv) { + v8::Isolate* isolate = context->GetIsolate(); + gin_helper::Dictionary dict(isolate, exports); + dict.Set("apiName", electron::api::ApiName::Create(isolate)); +} + +} // namespace +``` + +## Link Your Electron API With Node + +To learn about how Electron links with Node, [click here.](https://www.electronjs.org/blog/electron-internals-using-node-as-a-library#link-node-with-electron) + +In the [`internal-ambient.d.ts`](https://github.com/electron/electron/blob/main/typings/internal-ambient.d.ts) file: + +We need to append a new property onto the `Process` interface found in this file like so: + +```ts +interface Process { + _linkedBinding(name: 'electron_browser_{api_name}', Electron.ApiName); +} +``` + +At the very bottom of your `api_name.cc` file: + +```cpp +NODE_LINKED_MODULE_CONTEXT_AWARE(electron_browser_{api_name},Initialize) +``` + +In your [`shell/common/node_bindings.cc`](https://github.com/electron/electron/blob/main/shell/common/node_bindings.cc) file: + +Add your node binding name to Electron's built-in modules. + +```cpp +#define ELECTRON_BUILTIN_MODULES(V) \ + V(electron_browser_{api_name}) +``` + +## Expose Your API to TypeScript + +### Export Your API as a module + +We will need to create a new TypeScript file in the path that follows: + +`"lib/browser/api/{electron_browser_{api_name}}.ts"` + +An example of the contents of this file can be found [here](https://github.com/electron/electron/blob/main/lib/browser/api/native-image.ts). + +### Expose Your module to TypeScript + +Add your module to the module list found at `"lib/browser/api/module-list.ts"` like so: + +```typescript +export const browserModuleList: ElectronInternal.ModuleEntry[] = [ + { name: 'apiName', loader: () => require('./api-name') }, +]; +``` diff --git a/docs/tutorial/dark-mode.md b/docs/tutorial/dark-mode.md index 430fc0eea3a88..bf16303e4ecb1 100644 --- a/docs/tutorial/dark-mode.md +++ b/docs/tutorial/dark-mode.md @@ -138,7 +138,7 @@ Finally, the `main.js` file represents the main process and contains the actual const { app, BrowserWindow, ipcMain, nativeTheme } = require('electron') const path = require('path') -function createWindow () { +const createWindow = () => { const win = new BrowserWindow({ width: 800, height: 600, @@ -200,6 +200,6 @@ Run the example using Electron Fiddle and then click the "Toggle Dark Mode" butt [system-wide-dark-mode]: https://developer.apple.com/design/human-interface-guidelines/macos/visual-design/dark-mode/ [electron-forge]: https://www.electronforge.io/ [electron-packager]: https://github.com/electron/electron-packager -[packager-darwindarkmode-api]: https://electron.github.io/electron-packager/master/interfaces/electronpackager.options.html#darwindarkmodesupport +[packager-darwindarkmode-api]: https://electron.github.io/electron-packager/main/interfaces/electronpackager.options.html#darwindarkmodesupport [prefers-color-scheme]: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme [event-listeners]: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener diff --git a/docs/tutorial/desktop-environment-integration.md b/docs/tutorial/desktop-environment-integration.md deleted file mode 100644 index 1eb883b463060..0000000000000 --- a/docs/tutorial/desktop-environment-integration.md +++ /dev/null @@ -1,35 +0,0 @@ -# Desktop Environment Integration - -Different operating systems provide different features for integrating desktop -applications into their desktop environments. For example, on Windows, -applications can put shortcuts in the JumpList of task bar, and on Mac, -applications can put a custom menu in the dock menu. - -This guide explains how to integrate your application into those desktop -environments with Electron APIs. - -## Notifications - -See the [Notifications documentation](notifications.md). - -## Recent Documents - -See [Recent Documents documentation](recent-documents.md). - -## Progress Bar - -See the [Progress Bar documentation](progress-bar.md). - -## Unity Launcher - -See the [Unity Launcher documentation][unity-launcher]. - -## Represented File for macOS Window - -See the [Represented File documentation](represented-file.md). - -## Dragging files out of the window - -See the [Native File Drag & Drop documentation](native-file-drag-drop.md). - -[unity-launcher]: https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles#Adding_shortcuts_to_a_launcher diff --git a/docs/tutorial/electron-timelines.md b/docs/tutorial/electron-timelines.md index dc0b089b44132..b13249ec056fd 100644 --- a/docs/tutorial/electron-timelines.md +++ b/docs/tutorial/electron-timelines.md @@ -1,23 +1,27 @@ # Electron Release Timelines +Special notes: + * The `-beta.1` and `stable` dates are our solid release dates. * We strive for weekly beta releases, however we often release more betas than scheduled. * All dates are our goals but there may be reasons for adjusting the stable deadline, such as security bugs. * Take a look at the [5.0.0 Timeline blog post](https://electronjs.org/blog/electron-5-0-timeline) for info about publicizing our release dates. * Since Electron 6.0, we've been targeting every other Chromium version and releasing our stable on the same day as Chrome stable. You can reference Chromium's release schedule [here](https://chromiumdash.appspot.com/schedule). See [Electron's new release cadence blog post](https://www.electronjs.org/blog/12-week-cadence) for more details on our release schedule. +* Electron 15.0 only will include a special Alpha release. Starting in Electron 16.0, we will release on an 8-week cadence. See [Electron's new 8-week cadence blog post](https://www.electronjs.org/blog/8-week-cadence) for more details. -| Version | -beta.1 | Stable | Chrome | Node | -| ------- | ------- | ------ | ------ | ---- | -| 2.0.0 | 2018-02-21 | 2018-05-01 | M61 | v8.9 | -| 3.0.0 | 2018-06-21 | 2018-09-18 | M66 | v10.2 | -| 4.0.0 | 2018-10-11 | 2018-12-20 | M69 | v10.11 | -| 5.0.0 | 2019-01-22 | 2019-04-24 | M73 | v12.0 | -| 6.0.0 | 2019-05-01 | 2019-07-30 | M76 | v12.4 | -| 7.0.0 | 2019-08-01 | 2019-10-22 | M78 | v12.8 | -| 8.0.0 | 2019-10-24 | 2020-02-04 | M80 | v12.13 | -| 9.0.0 | 2020-02-06 | 2020-05-19 | M83 | v12.14 | -| 10.0.0 | 2020-05-21 | 2020-08-25 | M85 | v12.16 | -| 11.0.0 | 2020-08-27 | 2020-11-17 | M87 | v12.18 | -| 12.0.0 | 2020-11-19 | 2021-03-02 | M89 | v14.16 | -| 13.0.0 | 2021-03-04 | 2021-05-25 | M91 | v14.16 | -| 14.0.0 | 2021-05-27 | 2021-08-31 | M93 | TBD | +| Electron | Alpha | Beta | Stable | Chrome | Node | +| ------- | ----- | ------- | ------ | ------ | ---- | +| 2.0.0 | -- | 2018-Feb-21 | 2018-May-01 | M61 | v8.9 | +| 3.0.0 | -- | 2018-Jun-21 | 2018-Sep-18 | M66 | v10.2 | +| 4.0.0 | -- | 2018-Oct-11 | 2018-Dec-20 | M69 | v10.11 | +| 5.0.0 | -- | 2019-Jan-22 | 2019-Apr-24 | M73 | v12.0 | +| 6.0.0 | -- | 2019-May-01 | 2019-Jul-30 | M76 | v12.4 | +| 7.0.0 | -- | 2019-Aug-01 | 2019-Oct-22 | M78 | v12.8 | +| 8.0.0 | -- | 2019-Oct-24 | 2020-Feb-04 | M80 | v12.13 | +| 9.0.0 | -- | 2020-Feb-06 | 2020-May-19 | M83 | v12.14 | +| 10.0.0 | -- | 2020-May-21 | 2020-Aug-25 | M85 | v12.16 | +| 11.0.0 | -- | 2020-Aug-27 | 2020-Nov-17 | M87 | v12.18 | +| 12.0.0 | -- | 2020-Nov-19 | 2021-Mar-02 | M89 | v14.16 | +| 13.0.0 | -- | 2021-Mar-04 | 2021-May-25 | M91 | v14.16 | +| 14.0.0 | -- | 2021-May-27 | 2021-Aug-31 | M93 | TBD | +| 15.0.0 | 2021-Jul-20 | 2021-Sep-01 | 2021-Sep-21 | M94 | TBD | diff --git a/docs/tutorial/in-app-purchases.md b/docs/tutorial/in-app-purchases.md index f9c2e9381ecb8..d4a27c854f6c5 100644 --- a/docs/tutorial/in-app-purchases.md +++ b/docs/tutorial/in-app-purchases.md @@ -1,4 +1,4 @@ -# In-App Purchase (macOS) +# In-App Purchases (macOS) ## Preparing @@ -39,7 +39,7 @@ inAppPurchase.on('transactions-updated', (event, transactions) => { } // Check each transaction. - transactions.forEach(function (transaction) { + transactions.forEach((transaction) => { const payment = transaction.payment switch (transaction.transactionState) { diff --git a/docs/tutorial/installation.md b/docs/tutorial/installation.md index 87b6623fd7bf4..2ddf281823c2e 100644 --- a/docs/tutorial/installation.md +++ b/docs/tutorial/installation.md @@ -1,4 +1,4 @@ -# Installation +# Advanced Installation Instructions To install prebuilt Electron binaries, use [`npm`][npm]. The preferred method is to install Electron as a development dependency in your @@ -90,6 +90,11 @@ ELECTRON_CUSTOM_DIR="{{ version }}" The above configuration will download from URLs such as `https://npm.taobao.org/mirrors/electron/8.0.0/electron-v8.0.0-linux-x64.zip`. +If your mirror serves artifacts with different checksums to the official +Electron release you may have to set `ELECTRON_USE_REMOTE_CHECKSUMS=1` to +force Electron to use the remote `SHASUMS256.txt` file to verify the checksum +instead of the embedded checksums. + #### Cache Alternatively, you can override the local cache. `@electron/get` will cache diff --git a/docs/tutorial/keyboard-shortcuts.md b/docs/tutorial/keyboard-shortcuts.md index af510a197b626..30b9429e83cdb 100644 --- a/docs/tutorial/keyboard-shortcuts.md +++ b/docs/tutorial/keyboard-shortcuts.md @@ -82,7 +82,7 @@ listen for the `keyup` and `keydown` [DOM events][dom-events] inside the renderer process using the [addEventListener() API][addEventListener-api]. ```javascript fiddle='docs/fiddles/features/keyboard-shortcuts/web-apis|focus=renderer.js' -function handleKeyPress(event) { +const handleKeyPress = (event) => { // You can put code here to handle the keypress. document.getElementById("last-keypress").innerText = event.key; console.log(`You pressed ${event.key}`); diff --git a/docs/tutorial/launch-app-from-url-in-another-app.md b/docs/tutorial/launch-app-from-url-in-another-app.md index f8f44e42b21fe..dafe86d8ce282 100644 --- a/docs/tutorial/launch-app-from-url-in-another-app.md +++ b/docs/tutorial/launch-app-from-url-in-another-app.md @@ -1,5 +1,5 @@ --- -title: launch-app-from-URL-in-another-app +title: Launching Your Electron App From A URL In Another App description: This guide will take you through the process of setting your electron app as the default handler for a specific protocol. slug: launch-app-from-url-in-another-app hide_title: true @@ -44,7 +44,7 @@ if (process.defaultApp) { We will now define the function in charge of creating our browser window and load our application's `index.html` file. ```js -function createWindow () { +const createWindow = () => { // Create the browser window. mainWindow = new BrowserWindow({ width: 800, @@ -112,7 +112,7 @@ Finally, we will add some additional code to handle when someone closes our appl // Quit when all windows are closed, except on macOS. There, it's common // for applications and their menu bar to stay active until the user quits // explicitly with Cmd + Q. -app.on('window-all-closed', function () { +app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit() }) ``` @@ -127,31 +127,25 @@ can add the flag `--extend-info` with a path to the `plist` you've created. The ### Plist ```XML -

-

macOS plist
-

-    
-        
-            
-                
-                    CFBundleURLTypes
-                    
-                        
-                            CFBundleURLSchemes
-                            
-                                electron-api-demos
-                            
-                            CFBundleURLName
-                            Electron API Demos Protocol
-                        
-                    
-                    ElectronTeamID
-                    VEKTX9H2N7
-                
-            
-        
-    
-

+ + + + + CFBundleURLTypes + + + CFBundleURLSchemes + + electron-api-demos + + CFBundleURLName + Electron API Demos Protocol + + + ElectronTeamID + VEKTX9H2N7 + + ``` ## Conclusion @@ -168,7 +162,7 @@ After you start your electron app, you can now enter in a URL in your browser th can leave it empty. --> -```fiddle docs/fiddles/system/protocol-handler/launch-app-from-url-in-another-app +```fiddle docs/fiddles/system/protocol-handler/launch-app-from-URL-in-another-app ``` diff --git a/docs/tutorial/linux-desktop-actions.md b/docs/tutorial/linux-desktop-actions.md index 3b998c95d6c65..5fa3c5abedaba 100644 --- a/docs/tutorial/linux-desktop-actions.md +++ b/docs/tutorial/linux-desktop-actions.md @@ -1,4 +1,4 @@ -# Custom Linux Desktop Launcher Actions +# Desktop Launcher Actions (Linux) ## Overview diff --git a/docs/tutorial/macos-dock.md b/docs/tutorial/macos-dock.md index b5527a4956b57..0a080e763d01f 100644 --- a/docs/tutorial/macos-dock.md +++ b/docs/tutorial/macos-dock.md @@ -1,4 +1,4 @@ -# Configuring the macOS Dock +# Dock (macOS) Electron has APIs to configure the app's icon in the macOS Dock. A macOS-only API exists to create a custom dock menu, but Electron also uses the app dock @@ -25,7 +25,7 @@ Starting with a working application from the ```javascript fiddle='docs/fiddles/features/macos-dock-menu' const { app, BrowserWindow, Menu } = require('electron') -function createWindow () { +const createWindow = () => { const win = new BrowserWindow({ width: 800, height: 600, diff --git a/docs/tutorial/message-ports.md b/docs/tutorial/message-ports.md index f8c4ea594a784..9f1e9bf467aff 100644 --- a/docs/tutorial/message-ports.md +++ b/docs/tutorial/message-ports.md @@ -134,7 +134,7 @@ app.whenReady().then(async () => {