mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
Compare commits
1 Commits
v33.2.1
...
mp-33-x-y-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8c15bf756 |
@@ -2,7 +2,7 @@ version: '3'
|
||||
|
||||
services:
|
||||
buildtools:
|
||||
image: ghcr.io/electron/devcontainer:77262e58c37631ab082482f42c33cdf68c6c394b
|
||||
image: ghcr.io/electron/devcontainer:9a43c14f5c19be0359843299f79e736521373adc
|
||||
|
||||
volumes:
|
||||
- ..:/workspaces/gclient/src/electron:cached
|
||||
|
||||
14
.github/actions/build-electron/action.yml
vendored
14
.github/actions/build-electron/action.yml
vendored
@@ -63,7 +63,7 @@ runs:
|
||||
run: |
|
||||
cd src
|
||||
electron/script/copy-debug-symbols.py --target-cpu="${{ inputs.target-arch }}" --out-dir=out/Default/debug --compress
|
||||
electron/script/strip-binaries.py --target-cpu="${{ inputs.target-arch }}" --verbose
|
||||
electron/script/strip-binaries.py --target-cpu="${{ inputs.target-arch }}"
|
||||
electron/script/add-debug-link.py --target-cpu="${{ inputs.target-arch }}" --debug-dir=out/Default/debug
|
||||
- name: Build Electron dist.zip ${{ inputs.step-suffix }}
|
||||
shell: bash
|
||||
@@ -159,19 +159,21 @@ runs:
|
||||
run: |
|
||||
cd src
|
||||
gn gen out/ffmpeg --args="import(\"//electron/build/args/ffmpeg.gn\") use_remoteexec=true $GN_EXTRA_ARGS"
|
||||
e build --target electron:electron_ffmpeg_zip -C ../../out/ffmpeg -j $NUMBER_OF_NINJA_PROCESSES
|
||||
autoninja -C out/ffmpeg electron:electron_ffmpeg_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
- name: Generate Hunspell Dictionaries ${{ inputs.step-suffix }}
|
||||
shell: bash
|
||||
if: ${{ inputs.is-release == 'true' && inputs.target-platform == 'linux' }}
|
||||
run: |
|
||||
e build --target electron:hunspell_dictionaries_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
cd src
|
||||
autoninja -C out/Default electron:hunspell_dictionaries_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
- name: Generate Libcxx ${{ inputs.step-suffix }}
|
||||
shell: bash
|
||||
if: ${{ inputs.is-release == 'true' && inputs.target-platform == 'linux' }}
|
||||
run: |
|
||||
e build --target electron:libcxx_headers_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
e build --target electron:libcxxabi_headers_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
e build --target electron:libcxx_objects_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
cd src
|
||||
autoninja -C out/Default electron:libcxx_headers_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
autoninja -C out/Default electron:libcxxabi_headers_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
autoninja -C out/Default electron:libcxx_objects_zip -j $NUMBER_OF_NINJA_PROCESSES
|
||||
- name: Generate TypeScript Definitions ${{ inputs.step-suffix }}
|
||||
if: ${{ inputs.is-release == 'true' }}
|
||||
shell: bash
|
||||
|
||||
15
.github/actions/checkout/action.yml
vendored
15
.github/actions/checkout/action.yml
vendored
@@ -57,26 +57,13 @@ runs:
|
||||
cache_path=/mnt/cross-instance-cache/$DEPSHASH.tar
|
||||
echo "Using cache key: $DEPSHASH"
|
||||
echo "Checking for cache in: $cache_path"
|
||||
if [ ! -f "$cache_path" ] || [ `du $cache_path | cut -f1` = "0" ]; then
|
||||
if [ ! -f "$cache_path" ]; then
|
||||
echo "cache_exists=false" >> $GITHUB_OUTPUT
|
||||
echo "Cache Does Not Exist for $DEPSHASH"
|
||||
else
|
||||
echo "cache_exists=true" >> $GITHUB_OUTPUT
|
||||
echo "Cache Already Exists for $DEPSHASH, Skipping.."
|
||||
fi
|
||||
- name: Check cross instance cache disk space
|
||||
if: steps.check-cache.outputs.cache_exists == 'false'
|
||||
shell: bash
|
||||
run: |
|
||||
# if there is less than 20 GB free space then creating the cache might fail so exit early
|
||||
freespace=`df -m /mnt/cross-instance-cache | grep -w /mnt/cross-instance-cache | awk '{print $4}'`
|
||||
freespace_human=`df -h /mnt/cross-instance-cache | grep -w /mnt/cross-instance-cache | awk '{print $4}'`
|
||||
if [ $freespace -le 20000 ]; then
|
||||
echo "The cross mount cache has $freespace_human free space which is not enough - exiting"
|
||||
exit 1
|
||||
else
|
||||
echo "The cross mount cache has $freespace_human free space - continuing"
|
||||
fi
|
||||
- name: Gclient Sync
|
||||
if: steps.check-cache.outputs.cache_exists == 'false'
|
||||
shell: bash
|
||||
|
||||
@@ -6,6 +6,6 @@ runs:
|
||||
- name: Install Build Tools
|
||||
shell: bash
|
||||
run: |
|
||||
export BUILD_TOOLS_SHA=eeb1a11392e4cec08fd926c93b31ab556dc0c23b
|
||||
export BUILD_TOOLS_SHA=d5b87591842be19058e8d75d2c5b7f1fabe9f450
|
||||
npm i -g @electron/build-tools
|
||||
e auto-update disable
|
||||
|
||||
5
.github/actions/restore-cache-aks/action.yml
vendored
5
.github/actions/restore-cache-aks/action.yml
vendored
@@ -17,11 +17,6 @@ runs:
|
||||
fi
|
||||
|
||||
echo "Persisted cache is $(du -sh $cache_path | cut -f1)"
|
||||
if [ `du $cache_path | cut -f1` = "0" ]; then
|
||||
echo "Cache is empty - exiting"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir temp-cache
|
||||
tar -xf $cache_path -C temp-cache
|
||||
echo "Unzipped cache is $(du -sh temp-cache/src | cut -f1)"
|
||||
|
||||
@@ -44,11 +44,6 @@ runs:
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Downloaded cache is $(du -sh $DEPSHASH.tar | cut -f1)"
|
||||
if [ `du $DEPSHASH.tar | cut -f1` = "0" ]; then
|
||||
echo "Cache is empty - exiting"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir temp-cache
|
||||
tar -xf $DEPSHASH.tar -C temp-cache
|
||||
echo "Unzipped cache is $(du -sh temp-cache/src | cut -f1)"
|
||||
|
||||
14
.github/workflows/build.yml
vendored
14
.github/workflows/build.yml
vendored
@@ -6,7 +6,7 @@ on:
|
||||
build-image-sha:
|
||||
type: string
|
||||
description: 'SHA for electron/build image'
|
||||
default: 'bc2f48b2415a670de18d13605b1cf0eb5fdbaae1'
|
||||
default: 'cf814a4d2501e8e843caea071a6b70a48e78b855'
|
||||
required: true
|
||||
skip-macos:
|
||||
type: boolean
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
id: set-output
|
||||
run: |
|
||||
if [ -z "${{ inputs.build-image-sha }}" ]; then
|
||||
echo "build-image-sha=bc2f48b2415a670de18d13605b1cf0eb5fdbaae1" >> "$GITHUB_OUTPUT"
|
||||
echo "build-image-sha=77262e58c37631ab082482f42c33cdf68c6c394b" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "build-image-sha=${{ inputs.build-image-sha }}" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
@@ -250,13 +250,3 @@ jobs:
|
||||
generate-symbols: false
|
||||
upload-to-storage: '0'
|
||||
secrets: inherit
|
||||
|
||||
gha-done:
|
||||
name: GitHub Actions Completed
|
||||
runs-on: ubuntu-latest
|
||||
needs: [docs-only, macos-x64, macos-arm64, linux-x64, linux-x64-asan, linux-arm, linux-arm64]
|
||||
if: always() && !contains(needs.*.result, 'failure')
|
||||
steps:
|
||||
- name: GitHub Actions Jobs Done
|
||||
run: |
|
||||
echo "All GitHub Actions Jobs are done"
|
||||
|
||||
21
.github/workflows/clean-src-cache.yml
vendored
21
.github/workflows/clean-src-cache.yml
vendored
@@ -1,21 +0,0 @@
|
||||
name: Clean Source Cache
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * SUN" # Run at midnight every Sunday
|
||||
|
||||
jobs:
|
||||
clean-src-cache:
|
||||
runs-on: electron-arc-linux-amd64-32core
|
||||
container:
|
||||
image: ghcr.io/electron/build:bc2f48b2415a670de18d13605b1cf0eb5fdbaae1
|
||||
options: --user root
|
||||
volumes:
|
||||
- /mnt/cross-instance-cache:/mnt/cross-instance-cache
|
||||
steps:
|
||||
- name: Cleanup Source Cache
|
||||
shell: bash
|
||||
run: |
|
||||
df -h /mnt/cross-instance-cache
|
||||
find /mnt/cross-instance-cache -type f -mtime +30 -delete
|
||||
df -h /mnt/cross-instance-cache
|
||||
2
.github/workflows/linux-publish.yml
vendored
2
.github/workflows/linux-publish.yml
vendored
@@ -6,7 +6,7 @@ on:
|
||||
build-image-sha:
|
||||
type: string
|
||||
description: 'SHA for electron/build image'
|
||||
default: 'bc2f48b2415a670de18d13605b1cf0eb5fdbaae1'
|
||||
default: 'cf814a4d2501e8e843caea071a6b70a48e78b855'
|
||||
upload-to-storage:
|
||||
description: 'Uploads to Azure storage'
|
||||
required: false
|
||||
|
||||
2
.github/workflows/macos-publish.yml
vendored
2
.github/workflows/macos-publish.yml
vendored
@@ -6,7 +6,7 @@ on:
|
||||
build-image-sha:
|
||||
type: string
|
||||
description: 'SHA for electron/build image'
|
||||
default: 'bc2f48b2415a670de18d13605b1cf0eb5fdbaae1'
|
||||
default: 'cf814a4d2501e8e843caea071a6b70a48e78b855'
|
||||
required: true
|
||||
upload-to-storage:
|
||||
description: 'Uploads to Azure storage'
|
||||
|
||||
@@ -164,7 +164,7 @@ jobs:
|
||||
uses: ./src/electron/.github/actions/install-build-tools
|
||||
- name: Init Build Tools
|
||||
run: |
|
||||
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} --import ${{ inputs.gn-build-type }} --target-cpu ${{ inputs.target-arch }}
|
||||
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} --import ${{ inputs.gn-build-type }} --target-cpu ${{ inputs.target-arch }} --only-sdk
|
||||
- name: Run Electron Only Hooks
|
||||
run: |
|
||||
gclient runhooks --spec="solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]"
|
||||
@@ -177,9 +177,18 @@ jobs:
|
||||
- name: Fix Sync (macOS)
|
||||
if: ${{ inputs.target-platform == 'macos' }}
|
||||
uses: ./src/electron/.github/actions/fix-sync-macos
|
||||
- name: Setup Number of Ninja Processes
|
||||
- name: Install build-tools & Setup RBE
|
||||
run: |
|
||||
echo "NUMBER_OF_NINJA_PROCESSES=${{ inputs.target-platform == 'linux' && '300' || '200' }}" >> $GITHUB_ENV
|
||||
cd ~/.electron_build_tools
|
||||
npx yarn --ignore-engines
|
||||
# Pull down credential helper and print status
|
||||
node -e "require('./src/utils/reclient.js').downloadAndPrepare({})"
|
||||
HELPER=$(node -p "require('./src/utils/reclient.js').helperPath({})")
|
||||
$HELPER login
|
||||
echo 'RBE_service='`node -e "console.log(require('./src/utils/reclient.js').serviceAddress)"` >> $GITHUB_ENV
|
||||
echo 'RBE_experimental_credentials_helper='`node -e "console.log(require('./src/utils/reclient.js').helperPath({}))"` >> $GITHUB_ENV
|
||||
echo 'RBE_experimental_credentials_helper_args=print' >> $GITHUB_ENV
|
||||
- name: Free up space (macOS)
|
||||
if: ${{ inputs.target-platform == 'macos' }}
|
||||
uses: ./src/electron/.github/actions/free-space-macos
|
||||
|
||||
@@ -75,7 +75,7 @@ jobs:
|
||||
uses: ./src/electron/.github/actions/install-build-tools
|
||||
- name: Init Build Tools
|
||||
run: |
|
||||
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} --import ${{ inputs.gn-build-type }} --target-cpu ${{ inputs.target-arch }}
|
||||
e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} --import ${{ inputs.gn-build-type }} --target-cpu ${{ inputs.target-arch }} --only-sdk
|
||||
- name: Get Depot Tools
|
||||
timeout-minutes: 5
|
||||
run: |
|
||||
@@ -132,10 +132,6 @@ jobs:
|
||||
with:
|
||||
path: src/electron
|
||||
fetch-depth: 0
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
cd src/electron
|
||||
node script/yarn install --frozen-lockfile
|
||||
- name: Default GN gen
|
||||
run: |
|
||||
cd src/electron
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
"autolink": false,
|
||||
"shortcut": false
|
||||
},
|
||||
"MD049": {
|
||||
"style": "underscore"
|
||||
},
|
||||
"no-angle-brackets": true,
|
||||
"no-curly-braces": true,
|
||||
"no-inline-html": {
|
||||
|
||||
@@ -12,7 +12,7 @@ propose changes to this document in a pull request.
|
||||
|
||||
## [Issues](https://electronjs.org/docs/development/issues)
|
||||
|
||||
Issues are created [here](https://github.com/electron/electron/issues/new/choose).
|
||||
Issues are created [here](https://github.com/electron/electron/issues/new).
|
||||
|
||||
* [How to Contribute in Issues](https://electronjs.org/docs/development/issues#how-to-contribute-in-issues)
|
||||
* [Asking for General Help](https://electronjs.org/docs/development/issues#asking-for-general-help)
|
||||
|
||||
4
DEPS
4
DEPS
@@ -2,9 +2,9 @@ gclient_gn_args_from = 'src'
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'130.0.6723.137',
|
||||
'130.0.6723.44',
|
||||
'node_version':
|
||||
'v20.18.1',
|
||||
'v20.18.0',
|
||||
'nan_version':
|
||||
'e14bdcd1f72d62bca1d541b66da43130384ec213',
|
||||
'squirrel.mac_version':
|
||||
|
||||
@@ -68,7 +68,7 @@ build_script:
|
||||
- ps: $env:PATH="$pwd\depot_tools;$env:PATH"
|
||||
- update_depot_tools.bat
|
||||
# Uncomment the following line if windows deps change
|
||||
# - src\electron\script\setup-win-for-dev.bat
|
||||
- src\electron\script\setup-win-for-dev.bat
|
||||
- >-
|
||||
gclient config
|
||||
--name "src\electron"
|
||||
|
||||
@@ -128,6 +128,8 @@ for:
|
||||
if ($env:ELECTRON_RBE_JWT -eq '') {
|
||||
$env:RBE_fail_early_min_action_count = "0"
|
||||
$env:RBE_fail_early_min_fallback_ratio = "0"
|
||||
$env:RBE_exec_strategy = "local"
|
||||
$env:RBE_remote_update_cache= "false"
|
||||
}
|
||||
- cd ..\..
|
||||
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
|
||||
@@ -156,7 +158,7 @@ for:
|
||||
- gn check out/Default //electron:electron_app
|
||||
- gn check out/Default //electron/shell/common:mojo
|
||||
- gn check out/Default //electron/shell/common:plugin
|
||||
- autoninja -j 300 -C out/Default electron:electron_app
|
||||
- if DEFINED ELECTRON_RBE_JWT (autoninja -j 300 -C out/Default electron:electron_app) else (autoninja -C out/Default electron:electron_app)
|
||||
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
|
||||
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") use_remoteexec=true %GN_EXTRA_ARGS%"
|
||||
- autoninja -C out/ffmpeg electron:electron_ffmpeg_zip
|
||||
|
||||
@@ -123,6 +123,8 @@ for:
|
||||
if ($env:ELECTRON_RBE_JWT -eq '') {
|
||||
$env:RBE_fail_early_min_action_count = "0"
|
||||
$env:RBE_fail_early_min_fallback_ratio = "0"
|
||||
$env:RBE_exec_strategy = "local"
|
||||
$env:RBE_remote_update_cache= "false"
|
||||
}
|
||||
- cd ..\..
|
||||
- ps: $env:CHROMIUM_BUILDTOOLS_PATH="$pwd\src\buildtools"
|
||||
@@ -151,7 +153,7 @@ for:
|
||||
- gn check out/Default //electron:electron_app
|
||||
- gn check out/Default //electron/shell/common:mojo
|
||||
- gn check out/Default //electron/shell/common:plugin
|
||||
- autoninja -j 300 -C out/Default electron:electron_app
|
||||
- if DEFINED ELECTRON_RBE_JWT (autoninja -j 300 -C out/Default electron:electron_app) else (autoninja -C out/Default electron:electron_app)
|
||||
- if "%GN_CONFIG%"=="testing" ( python C:\depot_tools\post_build_ninja_summary.py -C out\Default )
|
||||
- gn gen out/ffmpeg "--args=import(\"//electron/build/args/ffmpeg.gn\") use_remoteexec=true %GN_EXTRA_ARGS%"
|
||||
- autoninja -C out/ffmpeg electron:electron_ffmpeg_zip
|
||||
|
||||
@@ -2,7 +2,7 @@ import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
DEFINE_EXTRACT_REGEX = re.compile(r'^ *# *define (\w*)', re.MULTILINE)
|
||||
DEFINE_EXTRACT_REGEX = re.compile('^ *# *define (\w*)', re.MULTILINE)
|
||||
|
||||
def main(out_dir, headers):
|
||||
defines = []
|
||||
|
||||
@@ -158,12 +158,14 @@ static_library("chrome") {
|
||||
"//chrome/browser/icon_loader_win.cc",
|
||||
"//chrome/browser/media/webrtc/window_icon_util_win.cc",
|
||||
"//chrome/browser/process_singleton_win.cc",
|
||||
"//chrome/browser/ui/frame/window_frame_util.h",
|
||||
"//chrome/browser/win/chrome_process_finder.cc",
|
||||
"//chrome/browser/win/chrome_process_finder.h",
|
||||
"//chrome/browser/win/chrome_select_file_dialog_factory.cc",
|
||||
"//chrome/browser/win/chrome_select_file_dialog_factory.h",
|
||||
"//chrome/browser/win/titlebar_config.cc",
|
||||
"//chrome/browser/win/titlebar_config.h",
|
||||
"//chrome/browser/win/titlebar_config.h",
|
||||
"//chrome/browser/win/util_win_service.cc",
|
||||
"//chrome/browser/win/util_win_service.h",
|
||||
"//chrome/child/v8_crashpad_support_win.cc",
|
||||
@@ -178,7 +180,6 @@ static_library("chrome") {
|
||||
public_deps = [
|
||||
"//chrome/browser:dev_ui_browser_resources",
|
||||
"//chrome/browser/resources/accessibility:resources",
|
||||
"//chrome/browser/ui/color:color_headers",
|
||||
"//chrome/browser/ui/color:mixers",
|
||||
"//chrome/common",
|
||||
"//chrome/common:version_header",
|
||||
|
||||
2
docs/api/app.md
Normal file → Executable file
2
docs/api/app.md
Normal file → Executable file
@@ -416,7 +416,7 @@ Returns:
|
||||
* `launch-failed` - 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).
|
||||
(e.g. status from waitpid if on posix, from GetExitCodeProcess on Windows).
|
||||
* `serviceName` string (optional) - The non-localized name of the process.
|
||||
* `name` string (optional) - The name of the process.
|
||||
Examples for utility: `Audio Service`, `Content Decryption Module Service`, `Network Service`, `Video Capture`, etc.
|
||||
|
||||
@@ -487,7 +487,7 @@ Sets the content view of the window.
|
||||
|
||||
#### `win.getContentView()`
|
||||
|
||||
Returns [`View`](view.md) - The content view of the window.
|
||||
Returns [View](view.md) - The content view of the window.
|
||||
|
||||
#### `win.destroy()`
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ Without `*` prefix the URL has to match exactly.
|
||||
|
||||
### --disable-ntlm-v2
|
||||
|
||||
Disables NTLM v2 for POSIX platforms, no effect elsewhere.
|
||||
Disables NTLM v2 for posix platforms, no effect elsewhere.
|
||||
|
||||
### --disable-http-cache
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ process, see [webContents.send][web-contents-send] for more information.
|
||||
|
||||
## Methods
|
||||
|
||||
The `ipcMain` module has the following methods to listen for events:
|
||||
The `ipcMain` module has the following method to listen for events:
|
||||
|
||||
### `ipcMain.on(channel, listener)`
|
||||
|
||||
@@ -44,16 +44,6 @@ The `ipcMain` module has the following methods to listen for events:
|
||||
Listens to `channel`, when a new message arrives `listener` would be called with
|
||||
`listener(event, args...)`.
|
||||
|
||||
### `ipcMain.off(channel, listener)`
|
||||
|
||||
* `channel` string
|
||||
* `listener` Function
|
||||
* `event` [IpcMainEvent][ipc-main-event]
|
||||
* `...args` any[]
|
||||
|
||||
Removes the specified `listener` from the listener array for the specified
|
||||
`channel`.
|
||||
|
||||
### `ipcMain.once(channel, listener)`
|
||||
|
||||
* `channel` string
|
||||
@@ -64,28 +54,20 @@ Removes the specified `listener` from the listener array for the specified
|
||||
Adds a one time `listener` function for the event. This `listener` is invoked
|
||||
only the next time a message is sent to `channel`, after which it is removed.
|
||||
|
||||
### `ipcMain.addListener(channel, listener)`
|
||||
|
||||
* `channel` string
|
||||
* `listener` Function
|
||||
* `event` [IpcMainEvent][ipc-main-event]
|
||||
* `...args` any[]
|
||||
|
||||
Alias for [`ipcMain.on`](#ipcmainonchannel-listener).
|
||||
|
||||
### `ipcMain.removeListener(channel, listener)`
|
||||
|
||||
* `channel` string
|
||||
* `listener` Function
|
||||
* `...args` any[]
|
||||
|
||||
Alias for [`ipcMain.off`](#ipcmainoffchannel-listener).
|
||||
Removes the specified `listener` from the listener array for the specified
|
||||
`channel`.
|
||||
|
||||
### `ipcMain.removeAllListeners([channel])`
|
||||
|
||||
* `channel` string (optional)
|
||||
|
||||
Removes all listeners from the specified `channel`. Removes all listeners from all channels if no channel is specified.
|
||||
Removes listeners of the specified `channel`.
|
||||
|
||||
### `ipcMain.handle(channel, listener)`
|
||||
|
||||
|
||||
@@ -48,8 +48,7 @@ Listens to `channel`, when a new message arrives `listener` would be called with
|
||||
* `event` [IpcRendererEvent][ipc-renderer-event]
|
||||
* `...args` any[]
|
||||
|
||||
Removes the specified `listener` from the listener array for the specified
|
||||
`channel`.
|
||||
Alias for [`ipcRenderer.removeListener`](#ipcrendererremovelistenerchannel-listener).
|
||||
|
||||
### `ipcRenderer.once(channel, listener)`
|
||||
|
||||
@@ -77,13 +76,14 @@ Alias for [`ipcRenderer.on`](#ipcrendereronchannel-listener).
|
||||
* `event` [IpcRendererEvent][ipc-renderer-event]
|
||||
* `...args` any[]
|
||||
|
||||
Alias for [`ipcRenderer.off`](#ipcrendereroffchannel-listener).
|
||||
Removes the specified `listener` from the listener array for the specified
|
||||
`channel`.
|
||||
|
||||
### `ipcRenderer.removeAllListeners([channel])`
|
||||
### `ipcRenderer.removeAllListeners(channel)`
|
||||
|
||||
* `channel` string (optional)
|
||||
* `channel` string
|
||||
|
||||
Removes all listeners from the specified `channel`. Removes all listeners from all channels if no channel is specified.
|
||||
Removes all listeners, or those of the specified `channel`.
|
||||
|
||||
### `ipcRenderer.send(channel, ...args)`
|
||||
|
||||
|
||||
@@ -268,8 +268,7 @@ Returns:
|
||||
* `event` Event
|
||||
* `details` Object
|
||||
* `deviceList` [HIDDevice[]](structures/hid-device.md)
|
||||
* `frame` [WebFrameMain](web-frame-main.md) | null - The frame initiating this event.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `frame` [WebFrameMain](web-frame-main.md)
|
||||
* `callback` Function
|
||||
* `deviceId` string | null (optional)
|
||||
|
||||
@@ -333,8 +332,7 @@ Returns:
|
||||
* `event` Event
|
||||
* `details` Object
|
||||
* `device` [HIDDevice](structures/hid-device.md)
|
||||
* `frame` [WebFrameMain](web-frame-main.md) | null - The frame initiating this event.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `frame` [WebFrameMain](web-frame-main.md)
|
||||
|
||||
Emitted after `navigator.hid.requestDevice` has been called and
|
||||
`select-hid-device` has fired if a new device becomes available before
|
||||
@@ -349,8 +347,7 @@ Returns:
|
||||
* `event` Event
|
||||
* `details` Object
|
||||
* `device` [HIDDevice](structures/hid-device.md)
|
||||
* `frame` [WebFrameMain](web-frame-main.md) | null - The frame initiating this event.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `frame` [WebFrameMain](web-frame-main.md)
|
||||
|
||||
Emitted after `navigator.hid.requestDevice` has been called and
|
||||
`select-hid-device` has fired if a device has been removed before the callback
|
||||
@@ -476,8 +473,7 @@ Returns:
|
||||
* `event` Event
|
||||
* `details` Object
|
||||
* `port` [SerialPort](structures/serial-port.md)
|
||||
* `frame` [WebFrameMain](web-frame-main.md) | null - The frame initiating this event.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `frame` [WebFrameMain](web-frame-main.md)
|
||||
* `origin` string - The origin that the device has been revoked from.
|
||||
|
||||
Emitted after `SerialPort.forget()` has been called. This event can be used
|
||||
@@ -521,8 +517,7 @@ Returns:
|
||||
* `event` Event
|
||||
* `details` Object
|
||||
* `deviceList` [USBDevice[]](structures/usb-device.md)
|
||||
* `frame` [WebFrameMain](web-frame-main.md) | null - The frame initiating this event.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `frame` [WebFrameMain](web-frame-main.md)
|
||||
* `callback` Function
|
||||
* `deviceId` string (optional)
|
||||
|
||||
@@ -962,8 +957,7 @@ session.fromPartition('some-partition').setPermissionCheckHandler((webContents,
|
||||
|
||||
* `handler` Function | null
|
||||
* `request` Object
|
||||
* `frame` [WebFrameMain](web-frame-main.md) | null - Frame that is requesting access to media.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `frame` [WebFrameMain](web-frame-main.md) - Frame that is requesting access to media.
|
||||
* `securityOrigin` String - Origin of the page making the request.
|
||||
* `videoRequested` Boolean - true if the web content requested a video stream.
|
||||
* `audioRequested` Boolean - true if the web content requested an audio stream.
|
||||
@@ -1164,8 +1158,7 @@ app.whenReady().then(() => {
|
||||
pin displayed on the device.
|
||||
* `providePin`
|
||||
This prompt is requesting that a pin be provided for the device.
|
||||
* `frame` [WebFrameMain](web-frame-main.md) | null - The frame initiating this handler.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `frame` [WebFrameMain](web-frame-main.md)
|
||||
* `pin` string (optional) - The pin value to verify if `pairingKind` is `confirmPin`.
|
||||
* `callback` Function
|
||||
* `response` Object
|
||||
|
||||
@@ -36,7 +36,7 @@ Open the given file in the desktop's default manner.
|
||||
|
||||
### `shell.openExternal(url[, options])`
|
||||
|
||||
* `url` string - Max 2081 characters on Windows.
|
||||
* `url` string - Max 2081 characters on windows.
|
||||
* `options` Object (optional)
|
||||
* `activate` boolean (optional) _macOS_ - `true` to bring the opened application to the foreground. The default is `true`.
|
||||
* `workingDirectory` string (optional) _Windows_ - The working directory.
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
* `show` boolean (optional) - Whether window should be shown when created. Default is
|
||||
`true`.
|
||||
* `frame` boolean (optional) - Specify `false` to create a
|
||||
[frameless window](../../tutorial/custom-window-styles.md#frameless-windows). Default is `true`.
|
||||
[frameless window](../../tutorial/window-customization.md#create-frameless-windows). Default is `true`.
|
||||
* `parent` BaseWindow (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`.
|
||||
@@ -70,7 +70,7 @@
|
||||
is only implemented on Windows and macOS.
|
||||
* `darkTheme` boolean (optional) - Forces using dark theme for the window, only works on
|
||||
some GTK+3 desktop environments. Default is `false`.
|
||||
* `transparent` boolean (optional) - Makes the window [transparent](../../tutorial/custom-window-styles.md#transparent-windows).
|
||||
* `transparent` boolean (optional) - Makes the window [transparent](../../tutorial/window-customization.md#create-transparent-windows).
|
||||
Default is `false`. On Windows, does not work unless the window is frameless.
|
||||
* `type` string (optional) - The type of window, default is normal window. See more about
|
||||
this below.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* `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](../web-contents.md) - Returns the `webContents` that sent the message
|
||||
* `senderFrame` [WebFrameMain](../web-frame-main.md) | null _Readonly_ - The frame that sent this message. May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `senderFrame` [WebFrameMain](../web-frame-main.md) _Readonly_ - The frame that sent this message
|
||||
* `ports` [MessagePortMain](../message-port-main.md)[] - A list of MessagePorts that were transferred with this message
|
||||
* `reply` Function - A function that will send an IPC message to the renderer frame that sent the original message that you are currently handling. You should use this method to "reply" to the sent message in order to guarantee the reply will go to the correct process and frame.
|
||||
* `channel` string
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
* `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](../web-contents.md) - Returns the `webContents` that sent the message
|
||||
* `senderFrame` [WebFrameMain](../web-frame-main.md) | null _Readonly_ - The frame that sent this message. May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `senderFrame` [WebFrameMain](../web-frame-main.md) _Readonly_ - The frame that sent this message
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
# OffscreenSharedTexture Object
|
||||
|
||||
* `textureInfo` Object - The shared texture info.
|
||||
* `widgetType` string - The widget type of the texture. Can be `popup` or `frame`.
|
||||
* `pixelFormat` string - The pixel format of the texture. Can be `rgba` or `bgra`.
|
||||
* `codedSize` [Size](size.md) - The full dimensions of the video frame.
|
||||
* `visibleRect` [Rectangle](rectangle.md) - A subsection of [0, 0, codedSize.width(), codedSize.height()]. In OSR case, it is expected to have the full section area.
|
||||
* `contentRect` [Rectangle](rectangle.md) - The region of the video frame that capturer would like to populate. In OSR case, it is the same with `dirtyRect` that needs to be painted.
|
||||
* `timestamp` number - The time in microseconds since the capture start.
|
||||
* `metadata` Object - Extra metadata. See comments in src\media\base\video_frame_metadata.h for accurate details.
|
||||
* `captureUpdateRect` [Rectangle](rectangle.md) (optional) - Updated area of frame, can be considered as the `dirty` area.
|
||||
* `regionCaptureRect` [Rectangle](rectangle.md) (optional) - May reflect the frame's contents origin if region capture is used internally.
|
||||
* `sourceSize` [Rectangle](rectangle.md) (optional) - Full size of the source frame.
|
||||
* `frameCount` number (optional) - The increasing count of captured frame. May contain gaps if frames are dropped between two consecutively received frames.
|
||||
* `sharedTextureHandle` Buffer _Windows_ _macOS_ - The handle to the shared texture.
|
||||
* `planes` Object[] _Linux_ - Each plane's info of the shared texture.
|
||||
* `stride` number - The strides and offsets in bytes to be used when accessing the buffers via a memory mapping. One per plane per entry.
|
||||
* `offset` number - The strides and offsets in bytes to be used when accessing the buffers via a memory mapping. One per plane per entry.
|
||||
* `size` number - Size in bytes of the plane. This is necessary to map the buffers.
|
||||
* `fd` number - File descriptor for the underlying memory object (usually dmabuf).
|
||||
* `modifier` string _Linux_ - The modifier is retrieved from GBM library and passed to EGL driver.
|
||||
* `release` Function - Release the resources. The `texture` cannot be directly passed to another process, users need to maintain texture lifecycles in
|
||||
main process, but it is safe to pass the `textureInfo` to another process. Only a limited number of textures can exist at the same time, so it's important
|
||||
that you call `texture.release()` as soon as you're done with the texture.
|
||||
@@ -79,14 +79,10 @@
|
||||
[browserWindow](../browser-window.md) has disabled `backgroundThrottling` then
|
||||
frames will be drawn and swapped for the whole window and other
|
||||
[webContents](../web-contents.md) displayed by it. Defaults to `true`.
|
||||
* `offscreen` Object | boolean (optional) - Whether to enable offscreen rendering for the browser
|
||||
* `offscreen` boolean (optional) - Whether to enable offscreen rendering for the browser
|
||||
window. Defaults to `false`. See the
|
||||
[offscreen rendering tutorial](../../tutorial/offscreen-rendering.md) for
|
||||
more details.
|
||||
* `useSharedTexture` boolean (optional) _Experimental_ - Whether to use GPU shared texture for accelerated
|
||||
paint event. Defaults to `false`. See the
|
||||
[offscreen rendering tutorial](../../tutorial/offscreen-rendering.md) for
|
||||
more details.
|
||||
* `contextIsolation` boolean (optional) - Whether to run Electron APIs and
|
||||
the specified `preload` script in a separate JavaScript context. Defaults
|
||||
to `true`. The context that the `preload` script runs in will only have
|
||||
|
||||
@@ -86,25 +86,9 @@ true if the kill is successful, and false otherwise.
|
||||
#### `child.pid`
|
||||
|
||||
A `Integer | undefined` representing the process identifier (PID) of the child process.
|
||||
Until the child process has spawned successfully, the value is `undefined`. When
|
||||
If the child process fails to spawn due to errors, then the value is `undefined`. When
|
||||
the child process exits, then the value is `undefined` after the `exit` event is emitted.
|
||||
|
||||
```js
|
||||
const child = utilityProcess.fork(path.join(__dirname, 'test.js'))
|
||||
|
||||
console.log(child.pid) // undefined
|
||||
|
||||
child.on('spawn', () => {
|
||||
console.log(child.pid) // Integer
|
||||
})
|
||||
|
||||
child.on('exit', () => {
|
||||
console.log(child.pid) // undefined
|
||||
})
|
||||
```
|
||||
|
||||
**Note:** You can use the `pid` to determine if the process is currently running.
|
||||
|
||||
#### `child.stdout`
|
||||
|
||||
A `NodeJS.ReadableStream | null` that represents the child process's stdout.
|
||||
@@ -151,7 +135,7 @@ child process terminates.
|
||||
Returns:
|
||||
|
||||
* `code` number - Contains the exit code for
|
||||
the process obtained from waitpid on POSIX, or GetExitCodeProcess on Windows.
|
||||
the process obtained from waitpid on posix, or GetExitCodeProcess on windows.
|
||||
|
||||
Emitted after the child process ends.
|
||||
|
||||
|
||||
@@ -242,9 +242,8 @@ Returns:
|
||||
* `isSameDocument` boolean - This event does not fire for same document navigations using window.history api and reference fragment navigations.
|
||||
This property is always set to `false` for this event.
|
||||
* `isMainFrame` boolean - True if the navigation is taking place in a main frame.
|
||||
* `frame` WebFrameMain | null - The frame to be navigated.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `initiator` WebFrameMain | null (optional) - The frame which initiated the
|
||||
* `frame` WebFrameMain - The frame to be navigated.
|
||||
* `initiator` WebFrameMain (optional) - The frame which initiated the
|
||||
navigation, which can be a parent frame (e.g. via `window.open` with a
|
||||
frame's name), or null if the navigation was not initiated by a frame. This
|
||||
can also be null if the initiating frame was deleted before the event was
|
||||
@@ -276,9 +275,8 @@ Returns:
|
||||
* `isSameDocument` boolean - This event does not fire for same document navigations using window.history api and reference fragment navigations.
|
||||
This property is always set to `false` for this event.
|
||||
* `isMainFrame` boolean - True if the navigation is taking place in a main frame.
|
||||
* `frame` WebFrameMain | null - The frame to be navigated.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `initiator` WebFrameMain | null (optional) - The frame which initiated the
|
||||
* `frame` WebFrameMain - The frame to be navigated.
|
||||
* `initiator` WebFrameMain (optional) - The frame which initiated the
|
||||
navigation, which can be a parent frame (e.g. via `window.open` with a
|
||||
frame's name), or null if the navigation was not initiated by a frame. This
|
||||
can also be null if the initiating frame was deleted before the event was
|
||||
@@ -308,9 +306,8 @@ Returns:
|
||||
document. Examples of same document navigations are reference fragment
|
||||
navigations, pushState/replaceState, and same page history navigation.
|
||||
* `isMainFrame` boolean - True if the navigation is taking place in a main frame.
|
||||
* `frame` WebFrameMain | null - The frame to be navigated.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `initiator` WebFrameMain | null (optional) - The frame which initiated the
|
||||
* `frame` WebFrameMain - The frame to be navigated.
|
||||
* `initiator` WebFrameMain (optional) - The frame which initiated the
|
||||
navigation, which can be a parent frame (e.g. via `window.open` with a
|
||||
frame's name), or null if the navigation was not initiated by a frame. This
|
||||
can also be null if the initiating frame was deleted before the event was
|
||||
@@ -333,9 +330,8 @@ Returns:
|
||||
document. Examples of same document navigations are reference fragment
|
||||
navigations, pushState/replaceState, and same page history navigation.
|
||||
* `isMainFrame` boolean - True if the navigation is taking place in a main frame.
|
||||
* `frame` WebFrameMain | null - The frame to be navigated.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `initiator` WebFrameMain | null (optional) - The frame which initiated the
|
||||
* `frame` WebFrameMain - The frame to be navigated.
|
||||
* `initiator` WebFrameMain (optional) - The frame which initiated the
|
||||
navigation, which can be a parent frame (e.g. via `window.open` with a
|
||||
frame's name), or null if the navigation was not initiated by a frame. This
|
||||
can also be null if the initiating frame was deleted before the event was
|
||||
@@ -365,9 +361,8 @@ Returns:
|
||||
document. Examples of same document navigations are reference fragment
|
||||
navigations, pushState/replaceState, and same page history navigation.
|
||||
* `isMainFrame` boolean - True if the navigation is taking place in a main frame.
|
||||
* `frame` WebFrameMain | null - The frame to be navigated.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `initiator` WebFrameMain | null (optional) - The frame which initiated the
|
||||
* `frame` WebFrameMain - The frame to be navigated.
|
||||
* `initiator` WebFrameMain (optional) - The frame which initiated the
|
||||
navigation, which can be a parent frame (e.g. via `window.open` with a
|
||||
frame's name), or null if the navigation was not initiated by a frame. This
|
||||
can also be null if the initiating frame was deleted before the event was
|
||||
@@ -748,8 +743,7 @@ Returns:
|
||||
* `params` Object
|
||||
* `x` Integer - x coordinate.
|
||||
* `y` Integer - y coordinate.
|
||||
* `frame` WebFrameMain | null - Frame from which the context menu was invoked.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `frame` WebFrameMain - Frame from which the context menu was invoked.
|
||||
* `linkURL` string - URL of the link that encloses the node the context menu
|
||||
was invoked on.
|
||||
* `linkText` string - Text associated with the link. May be an empty
|
||||
@@ -875,12 +869,12 @@ app.whenReady().then(() => {
|
||||
|
||||
Returns:
|
||||
|
||||
* `details` Event\<\>
|
||||
* `texture` [OffscreenSharedTexture](structures/offscreen-shared-texture.md) (optional) _Experimental_ - The GPU shared texture of the frame, when `webPreferences.offscreen.useSharedTexture` is `true`.
|
||||
* `event` Event
|
||||
* `dirtyRect` [Rectangle](structures/rectangle.md)
|
||||
* `image` [NativeImage](native-image.md) - The image data of the whole frame.
|
||||
|
||||
Emitted when a new frame is generated. Only the dirty area is passed in the buffer.
|
||||
Emitted when a new frame is generated. Only the dirty area is passed in the
|
||||
buffer.
|
||||
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
@@ -892,33 +886,6 @@ win.webContents.on('paint', (event, dirty, image) => {
|
||||
win.loadURL('https://github.com')
|
||||
```
|
||||
|
||||
When using shared texture (set `webPreferences.offscreen.useSharedTexture` to `true`) feature, you can pass the texture handle to external rendering pipeline without the overhead of
|
||||
copying data between CPU and GPU memory, with Chromium's hardware acceleration support. This feature is helpful for high-performance rendering scenarios.
|
||||
|
||||
Only a limited number of textures can exist at the same time, so it's important that you call `texture.release()` as soon as you're done with the texture.
|
||||
By managing the texture lifecycle by yourself, you can safely pass the `texture.textureInfo` to other processes through IPC.
|
||||
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
const win = new BrowserWindow({ webPreferences: { offscreen: { useSharedTexture: true } } })
|
||||
win.webContents.on('paint', async (e, dirty, image) => {
|
||||
if (e.texture) {
|
||||
// By managing lifecycle yourself, you can handle the event in async handler or pass the `e.texture.textureInfo`
|
||||
// to other processes (not `e.texture`, the `e.texture.release` function is not passable through IPC).
|
||||
await new Promise(resolve => setTimeout(resolve, 50))
|
||||
|
||||
// You can send the native texture handle to native code for importing into your rendering pipeline.
|
||||
// For example: https://github.com/electron/electron/tree/main/spec/fixtures/native-addon/osr-gpu
|
||||
// importTextureHandle(dirty, e.texture.textureInfo)
|
||||
|
||||
// You must call `e.texture.release()` as soon as possible, before the underlying frame pool is drained.
|
||||
e.texture.release()
|
||||
}
|
||||
})
|
||||
win.loadURL('https://github.com')
|
||||
```
|
||||
|
||||
#### Event: 'devtools-reload-page'
|
||||
|
||||
Emitted when the devtools window instructs the webContents to reload
|
||||
@@ -1016,8 +983,7 @@ Returns:
|
||||
|
||||
* `event` Event
|
||||
* `details` Object
|
||||
* `frame` WebFrameMain | null - The created frame.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `frame` WebFrameMain
|
||||
|
||||
Emitted when the [mainFrame](web-contents.md#contentsmainframe-readonly), an `<iframe>`, or a nested `<iframe>` is loaded within the page.
|
||||
|
||||
|
||||
@@ -97,10 +97,6 @@ this limitation.
|
||||
|
||||
Returns `boolean` - Whether the reload was initiated successfully. Only results in `false` when the frame has no history.
|
||||
|
||||
#### `frame.isDestroyed()`
|
||||
|
||||
Returns `boolean` - Whether the frame is destroyed.
|
||||
|
||||
#### `frame.send(channel, ...args)`
|
||||
|
||||
* `channel` string
|
||||
@@ -235,13 +231,6 @@ A `string` representing the [visibility state](https://developer.mozilla.org/en-
|
||||
|
||||
See also how the [Page Visibility API](browser-window.md#page-visibility) is affected by other Electron APIs.
|
||||
|
||||
#### `frame.detached` _Readonly_
|
||||
|
||||
A `Boolean` representing whether the frame is detached from the frame tree. If a frame is accessed
|
||||
while the corresponding page is running any [unload][] listeners, it may become detached as the
|
||||
newly navigated page replaced it in the frame tree.
|
||||
|
||||
[SCA]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
|
||||
[`postMessage`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
|
||||
[`MessagePortMain`]: message-port-main.md
|
||||
[unload]: https://developer.mozilla.org/en-US/docs/Web/API/Window/unload_event
|
||||
|
||||
@@ -182,7 +182,7 @@ dispatch errors of isolated worlds to foreign worlds.
|
||||
|
||||
### `webFrame.setIsolatedWorldInfo(worldId, info)`
|
||||
|
||||
* `worldId` Integer - The ID of the world to run the javascript in, `0` is the default world, `999` is the world used by Electron's `contextIsolation` feature. Chrome extensions reserve the range of IDs in `[1 << 20, 1 << 29)`. You can provide any integer here.
|
||||
* `worldId` Integer - The ID of the world to run the javascript in, `0` is the default world, `999` is the world used by Electrons `contextIsolation` feature. Chrome extensions reserve the range of IDs in `[1 << 20, 1 << 29)`. You can provide any integer here.
|
||||
* `info` Object
|
||||
* `securityOrigin` string (optional) - Security origin for the isolated world.
|
||||
* `csp` string (optional) - Content Security Policy for the isolated world.
|
||||
|
||||
@@ -51,8 +51,7 @@ The following methods are available on instances of `WebRequest`:
|
||||
* `method` string
|
||||
* `webContentsId` Integer (optional)
|
||||
* `webContents` WebContents (optional)
|
||||
* `frame` WebFrameMain | null (optional) - Requesting frame.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `frame` WebFrameMain (optional)
|
||||
* `resourceType` string - Can be `mainFrame`, `subFrame`, `stylesheet`, `script`, `image`, `font`, `object`, `xhr`, `ping`, `cspReport`, `media`, `webSocket` or `other`.
|
||||
* `referrer` string
|
||||
* `timestamp` Double
|
||||
@@ -95,8 +94,7 @@ Some examples of valid `urls`:
|
||||
* `method` string
|
||||
* `webContentsId` Integer (optional)
|
||||
* `webContents` WebContents (optional)
|
||||
* `frame` WebFrameMain | null (optional) - Requesting frame.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `frame` WebFrameMain (optional)
|
||||
* `resourceType` string - Can be `mainFrame`, `subFrame`, `stylesheet`, `script`, `image`, `font`, `object`, `xhr`, `ping`, `cspReport`, `media`, `webSocket` or `other`.
|
||||
* `referrer` string
|
||||
* `timestamp` Double
|
||||
@@ -124,8 +122,7 @@ The `callback` has to be called with a `response` object.
|
||||
* `method` string
|
||||
* `webContentsId` Integer (optional)
|
||||
* `webContents` WebContents (optional)
|
||||
* `frame` WebFrameMain | null (optional) - Requesting frame.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `frame` WebFrameMain (optional)
|
||||
* `resourceType` string - Can be `mainFrame`, `subFrame`, `stylesheet`, `script`, `image`, `font`, `object`, `xhr`, `ping`, `cspReport`, `media`, `webSocket` or `other`.
|
||||
* `referrer` string
|
||||
* `timestamp` Double
|
||||
@@ -145,8 +142,7 @@ response are visible by the time this listener is fired.
|
||||
* `method` string
|
||||
* `webContentsId` Integer (optional)
|
||||
* `webContents` WebContents (optional)
|
||||
* `frame` WebFrameMain | null (optional) - Requesting frame.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `frame` WebFrameMain (optional)
|
||||
* `resourceType` string - Can be `mainFrame`, `subFrame`, `stylesheet`, `script`, `image`, `font`, `object`, `xhr`, `ping`, `cspReport`, `media`, `webSocket` or `other`.
|
||||
* `referrer` string
|
||||
* `timestamp` Double
|
||||
@@ -177,8 +173,7 @@ The `callback` has to be called with a `response` object.
|
||||
* `method` string
|
||||
* `webContentsId` Integer (optional)
|
||||
* `webContents` WebContents (optional)
|
||||
* `frame` WebFrameMain | null (optional) - Requesting frame.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `frame` WebFrameMain (optional)
|
||||
* `resourceType` string - Can be `mainFrame`, `subFrame`, `stylesheet`, `script`, `image`, `font`, `object`, `xhr`, `ping`, `cspReport`, `media`, `webSocket` or `other`.
|
||||
* `referrer` string
|
||||
* `timestamp` Double
|
||||
@@ -202,8 +197,7 @@ and response headers are available.
|
||||
* `method` string
|
||||
* `webContentsId` Integer (optional)
|
||||
* `webContents` WebContents (optional)
|
||||
* `frame` WebFrameMain | null (optional) - Requesting frame.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `frame` WebFrameMain (optional)
|
||||
* `resourceType` string - Can be `mainFrame`, `subFrame`, `stylesheet`, `script`, `image`, `font`, `object`, `xhr`, `ping`, `cspReport`, `media`, `webSocket` or `other`.
|
||||
* `referrer` string
|
||||
* `timestamp` Double
|
||||
@@ -228,8 +222,7 @@ redirect is about to occur.
|
||||
* `method` string
|
||||
* `webContentsId` Integer (optional)
|
||||
* `webContents` WebContents (optional)
|
||||
* `frame` WebFrameMain | null (optional) - Requesting frame.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `frame` WebFrameMain (optional)
|
||||
* `resourceType` string - Can be `mainFrame`, `subFrame`, `stylesheet`, `script`, `image`, `font`, `object`, `xhr`, `ping`, `cspReport`, `media`, `webSocket` or `other`.
|
||||
* `referrer` string
|
||||
* `timestamp` Double
|
||||
@@ -252,8 +245,7 @@ completed.
|
||||
* `method` string
|
||||
* `webContentsId` Integer (optional)
|
||||
* `webContents` WebContents (optional)
|
||||
* `frame` WebFrameMain | null (optional) - Requesting frame.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `frame` WebFrameMain (optional)
|
||||
* `resourceType` string - Can be `mainFrame`, `subFrame`, `stylesheet`, `script`, `image`, `font`, `object`, `xhr`, `ping`, `cspReport`, `media`, `webSocket` or `other`.
|
||||
* `referrer` string
|
||||
* `timestamp` Double
|
||||
|
||||
@@ -14,34 +14,6 @@ This document uses the following convention to categorize breaking changes:
|
||||
|
||||
## Planned Breaking API Changes (33.0)
|
||||
|
||||
### Behavior Changed: frame properties may retrieve detached WebFrameMain instances or none at all
|
||||
|
||||
APIs which provide access to a `WebFrameMain` instance may return an instance
|
||||
with `frame.detached` set to `true`, or possibly return `null`.
|
||||
|
||||
When a frame performs a cross-origin navigation, it enters into a detached state
|
||||
in which it's no longer attached to the page. In this state, it may be running
|
||||
[unload](https://developer.mozilla.org/en-US/docs/Web/API/Window/unload_event)
|
||||
handlers prior to being deleted. In the event of an IPC sent during this state,
|
||||
`frame.detached` will be set to `true` with the frame being destroyed shortly
|
||||
thereafter.
|
||||
|
||||
When receiving an event, it's important to access WebFrameMain properties
|
||||
immediately upon being received. Otherwise, it's not guaranteed to point to the
|
||||
same webpage as when received. To avoid misaligned expectations, Electron will
|
||||
return `null` in the case of late access where the webpage has changed.
|
||||
|
||||
```ts
|
||||
ipcMain.on('unload-event', (event) => {
|
||||
event.senderFrame; // ✅ accessed immediately
|
||||
});
|
||||
|
||||
ipcMain.on('unload-event', async (event) => {
|
||||
await crossOriginNavigationPromise;
|
||||
event.senderFrame; // ❌ returns `null` due to late access
|
||||
});
|
||||
```
|
||||
|
||||
### Behavior Changed: custom protocol URL handling on Windows
|
||||
|
||||
Due to changes made in Chromium to support [Non-Special Scheme URLs](http://bit.ly/url-non-special), custom protocol URLs that use Windows file paths will no longer work correctly with the deprecated `protocol.registerFileProtocol` and the `baseURLForDataURL` property on `BrowserWindow.loadURL`, `WebContents.loadURL`, and `<webview>.loadURL`. `protocol.handle` will also not work with these types of URLs but this is not a change since it has always worked that way.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Experimental APIs
|
||||
|
||||
Some of Electron's APIs are tagged with `_Experimental_` in the documentation.
|
||||
Some of Electrons APIs are tagged with `_Experimental_` in the documentation.
|
||||
This tag indicates that the API may not be considered stable and the API may
|
||||
be removed or modified more frequently than other APIs with less warning.
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'">
|
||||
<link href="./styles.css" rel="stylesheet">
|
||||
<title>Custom Titlebar App</title>
|
||||
</head>
|
||||
<body>
|
||||
<!-- mount your title bar at the top of you application's body tag -->
|
||||
<div class="titlebar">Cool titlebar</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,16 +0,0 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
// remove the default titlebar
|
||||
titleBarStyle: 'hidden',
|
||||
// expose window controlls in Windows/Linux
|
||||
...(process.platform !== 'darwin' ? { titleBarOverlay: true } : {})
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
})
|
||||
@@ -1,12 +0,0 @@
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
.titlebar {
|
||||
height: 30px;
|
||||
background: blue;
|
||||
color: white;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
app-region: drag;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'">
|
||||
<link href="./styles.css" rel="stylesheet">
|
||||
<title>Custom Titlebar App</title>
|
||||
</head>
|
||||
<body>
|
||||
<!-- mount your title bar at the top of you application's body tag -->
|
||||
<div class="titlebar">Cool titlebar</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,16 +0,0 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
// remove the default titlebar
|
||||
titleBarStyle: 'hidden',
|
||||
// expose window controlls in Windows/Linux
|
||||
...(process.platform !== 'darwin' ? { titleBarOverlay: true } : {})
|
||||
})
|
||||
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
})
|
||||
@@ -1,12 +0,0 @@
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.titlebar {
|
||||
height: 30px;
|
||||
background: blue;
|
||||
color: white;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
// remove the default titlebar
|
||||
titleBarStyle: 'hidden',
|
||||
// expose window controlls in Windows/Linux
|
||||
...(process.platform !== 'darwin' ? { titleBarOverlay: true } : {})
|
||||
})
|
||||
win.loadURL('https://example.com')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
})
|
||||
@@ -1,13 +0,0 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
// remove the default titlebar
|
||||
titleBarStyle: 'hidden'
|
||||
})
|
||||
win.loadURL('https://example.com')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
})
|
||||
@@ -1,10 +0,0 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({})
|
||||
win.loadURL('https://example.com')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
})
|
||||
@@ -1,14 +0,0 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 300,
|
||||
height: 200,
|
||||
frame: false
|
||||
})
|
||||
win.loadURL('https://example.com')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
})
|
||||
@@ -1,15 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'">
|
||||
<link href="./styles.css" rel="stylesheet">
|
||||
<title>Transparent Hello World</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="white-circle">
|
||||
<div>Hello World!</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,16 +0,0 @@
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
function createWindow () {
|
||||
const win = new BrowserWindow({
|
||||
width: 100,
|
||||
height: 100,
|
||||
resizable: false,
|
||||
frame: false,
|
||||
transparent: true
|
||||
})
|
||||
win.loadFile('index.html')
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
})
|
||||
@@ -1,16 +0,0 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: rgba(0, 0, 0, 0); /* Transparent background */
|
||||
}
|
||||
.white-circle {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: white;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
app-region: drag;
|
||||
user-select: none;
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 412 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 215 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 98 KiB |
@@ -1,176 +0,0 @@
|
||||
# Custom Title Bar
|
||||
|
||||
## Basic tutorial
|
||||
|
||||
Application windows have a default [chrome][] applied by the OS. Not to be confused
|
||||
with the Google Chrome browser, window _chrome_ refers to the parts of the window (e.g.
|
||||
title bar, toolbars, controls) that are not a part of the main web content. While the
|
||||
default title bar provided by the OS chrome is sufficent for simple use cases, many
|
||||
applications opt to remove it. Implementing a custom title bar can help your application
|
||||
feel more modern and consistent across platforms.
|
||||
|
||||
You can follow along with this tutorial by opening Fiddle with the following starter code.
|
||||
|
||||
```fiddle docs/fiddles/features/window-customization/custom-title-bar/starter-code
|
||||
|
||||
```
|
||||
|
||||
### Remove the default title bar
|
||||
|
||||
Let’s start by configuring a window with native window controls and a hidden title bar.
|
||||
To remove the default title bar, set the [`BaseWindowContructorOptions`][] `titleBarStyle`
|
||||
param in the `BrowserWindow` constructor to `'hidden'`.
|
||||
|
||||
```fiddle docs/fiddles/features/window-customization/custom-title-bar/remove-title-bar
|
||||
|
||||
```
|
||||
|
||||
### Add native window controls _Windows_ _Linux_
|
||||
|
||||
On macOS, setting `titleBarStyle: 'hidden'` removes the title bar while keeping the window’s
|
||||
traffic light controls available in the upper left hand corner. However on Windows and Linux,
|
||||
you’ll need to add window controls back into your `BrowserWindow` by setting the
|
||||
[`BaseWindowContructorOptions`][] `titleBarOverlay` param in the `BrowserWindow` constructor.
|
||||
|
||||
```fiddle docs/fiddles/features/window-customization/custom-title-bar/native-window-controls
|
||||
|
||||
```
|
||||
|
||||
Setting `titleBarOverlay: true` is the simplest way to expose window controls back into
|
||||
your `BrowserWindow`. If you’re interested in customizing the window controls further,
|
||||
check out the sections [Custom traffic lights][] and [Custom window controls][] that cover
|
||||
this in more detail.
|
||||
|
||||
### Create a custom title bar
|
||||
|
||||
Now, let’s implement a simple custom title bar in the `webContents` of our `BrowserWindow`.
|
||||
There’s nothing fancy here, just HTML and CSS!
|
||||
|
||||
```fiddle docs/fiddles/features/window-customization/custom-title-bar/custom-title-bar
|
||||
|
||||
```
|
||||
|
||||
Currently our application window can’t be moved. Since we’ve removed the default title bar,
|
||||
the application needs to tell Electron which regions are draggable. We’ll do this by adding
|
||||
the CSS style `app-region: drag` to the custom title bar. Now we can drag the custom title
|
||||
bar to reposition our app window!
|
||||
|
||||
```fiddle docs/fiddles/features/window-customization/custom-title-bar/custom-drag-region
|
||||
|
||||
```
|
||||
|
||||
For more information around how to manage drag regions defined by your electron application,
|
||||
see the [Custom draggable regions][] section below.
|
||||
|
||||
Congratulations, you've just implemented a basic custom title bar!
|
||||
|
||||
## Advanced window customization
|
||||
|
||||
### Custom traffic lights _macOS_
|
||||
|
||||
#### Customize the look of your traffic lights _macOS_
|
||||
|
||||
The `customButtonsOnHover` title bar style will hide the traffic lights until you hover
|
||||
over them. This is useful if you want to create custom traffic lights in your HTML but still
|
||||
use the native UI to control the window.
|
||||
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow({ titleBarStyle: 'customButtonsOnHover' })
|
||||
```
|
||||
|
||||
#### Customize the traffic light position _macOS_
|
||||
|
||||
To modify the position of the traffic light window controls, there are two configuration
|
||||
options available.
|
||||
|
||||
Applying `hiddenInset` title bar style will shift the vertical inset of the traffic lights
|
||||
by a fixed amount.
|
||||
|
||||
```js title='main.js'
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow({ titleBarStyle: 'hiddenInset' })
|
||||
```
|
||||
|
||||
If you need more granular control over the positioning of the traffic lights, you can pass
|
||||
a set of coordinates to the `trafficLightPosition` option in the `BrowserWindow`
|
||||
constructor.
|
||||
|
||||
```js title='main.js'
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow({
|
||||
titleBarStyle: 'hidden',
|
||||
trafficLightPosition: { x: 10, y: 10 }
|
||||
})
|
||||
```
|
||||
|
||||
#### Show and hide the traffic lights programmatically _macOS_
|
||||
|
||||
You can also show and hide the traffic lights programmatically from the main process.
|
||||
The `win.setWindowButtonVisibility` forces traffic lights to be show or hidden depending
|
||||
on the value of its boolean parameter.
|
||||
|
||||
```js title='main.js'
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow()
|
||||
// hides the traffic lights
|
||||
win.setWindowButtonVisibility(false)
|
||||
```
|
||||
|
||||
:::note
|
||||
Given the number of APIs available, there are many ways of achieving this. For instance,
|
||||
combining `frame: false` with `win.setWindowButtonVisibility(true)` will yield the same
|
||||
layout outcome as setting `titleBarStyle: 'hidden'`.
|
||||
:::
|
||||
|
||||
#### Custom window controls
|
||||
|
||||
The [Window Controls Overlay API][] is a web standard that gives web apps the ability to
|
||||
customize their title bar region when installed on desktop. Electron exposes this API
|
||||
through the `titleBarOverlay` option in the `BrowserWindow` constructor. When `titleBarOverlay`
|
||||
is enabled, the window controls become exposed in their default position, and DOM elements
|
||||
cannot use the area underneath this region.
|
||||
|
||||
:::note
|
||||
`titleBarOverlay` requires the `titleBarStyle` param in the `BrowserWindow` constructor
|
||||
to have a value other than `default`.
|
||||
:::
|
||||
|
||||
The custom title bar tutorial covers a [basic example][Add native window controls] of exposing
|
||||
window controls by setting `titleBarOverlay: true`. The height, color (_Windows_ _Linux_), and
|
||||
symbol colors (_Windows_) of the window controls can be customized further by setting
|
||||
`titleBarOverlay` to an object.
|
||||
|
||||
The value passed to the `height` property must be an integer. The `color` and `symbolColor`
|
||||
properties accept `rgba()`, `hsla()`, and `#RRGGBBAA` color formats and support transparency.
|
||||
If a color option is not specified, the color will default to its system color for the window
|
||||
control buttons. Similarly, if the height option is not specified, the window controls will
|
||||
default to the standard system height:
|
||||
|
||||
```js title='main.js'
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow({
|
||||
titleBarStyle: 'hidden',
|
||||
titleBarOverlay: {
|
||||
color: '#2f3241',
|
||||
symbolColor: '#74b1be',
|
||||
height: 60
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
:::note
|
||||
Once your title bar overlay is enabled from the main process, you can access the overlay's
|
||||
color and dimension values from a renderer using a set of readonly
|
||||
[JavaScript APIs][overlay-javascript-apis] and [CSS Environment Variables][overlay-css-env-vars].
|
||||
:::
|
||||
|
||||
[Add native window controls]: #add-native-window-controls-windows-linux
|
||||
[`BaseWindowContructorOptions`]: ../api/structures/base-window-options.md
|
||||
[chrome]: https://developer.mozilla.org/en-US/docs/Glossary/Chrome
|
||||
[Custom draggable regions]: ./custom-window-interactions.md#custom-draggable-regions
|
||||
[Custom traffic lights]: #custom-traffic-lights-macos
|
||||
[Custom window controls]: #custom-window-controls
|
||||
[overlay-css-env-vars]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#css-environment-variables
|
||||
[overlay-javascript-apis]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#javascript-apis
|
||||
[Window Controls Overlay API]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md
|
||||
@@ -1,107 +0,0 @@
|
||||
# Custom Window Interactions
|
||||
|
||||
## Custom draggable regions
|
||||
|
||||
By default, windows are dragged using the title bar provided by the OS chrome. Apps
|
||||
that remove the default title bar need to use the `app-region` CSS property to define
|
||||
specific areas that can be used to drag the window. Setting `app-region: drag` marks
|
||||
a rectagular area as draggable.
|
||||
|
||||
It is important to note that draggable areas ignore all pointer events. For example,
|
||||
a button element that overlaps a draggable region will not emit mouse clicks or mouse
|
||||
enter/exit events within that overlapping area. Setting `app-region: no-drag` reenables
|
||||
pointer events by excluding a rectagular area from a draggable region.
|
||||
|
||||
To make the whole window draggable, you can add `app-region: drag` as
|
||||
`body`'s style:
|
||||
|
||||
```css title='styles.css'
|
||||
body {
|
||||
app-region: drag;
|
||||
}
|
||||
```
|
||||
|
||||
And note that if you have made the whole window draggable, you must also mark
|
||||
buttons as non-draggable, otherwise it would be impossible for users to click on
|
||||
them:
|
||||
|
||||
```css title='styles.css'
|
||||
button {
|
||||
app-region: no-drag;
|
||||
}
|
||||
```
|
||||
|
||||
If you're only setting a custom title bar as draggable, you also need to make all
|
||||
buttons in title bar non-draggable.
|
||||
|
||||
### Tip: disable text selection
|
||||
|
||||
When creating a draggable region, the dragging behavior may conflict with text selection.
|
||||
For example, when you drag the title bar, you may accidentally select its text contents.
|
||||
To prevent this, you need to disable text selection within a draggable area like this:
|
||||
|
||||
```css
|
||||
.titlebar {
|
||||
user-select: none;
|
||||
app-region: drag;
|
||||
}
|
||||
```
|
||||
|
||||
### Tip: disable context menus
|
||||
|
||||
On some platforms, the draggable area will be treated as a non-client frame, so
|
||||
when you right click on it, a system menu will pop up. To make the context menu
|
||||
behave correctly on all platforms, you should never use a custom context menu on
|
||||
draggable areas.
|
||||
|
||||
## Click-through windows
|
||||
|
||||
To create a click-through window, i.e. making the window ignore all mouse
|
||||
events, you can call the [win.setIgnoreMouseEvents(ignore)][ignore-mouse-events]
|
||||
API:
|
||||
|
||||
```js title='main.js'
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow()
|
||||
win.setIgnoreMouseEvents(true)
|
||||
```
|
||||
|
||||
### Forward mouse events _macOS_ _Windows_
|
||||
|
||||
Ignoring mouse messages makes the web contents oblivious to mouse movement,
|
||||
meaning that mouse movement events will not be emitted. On Windows and macOS, an
|
||||
optional parameter can be used to forward mouse move messages to the web page,
|
||||
allowing events such as `mouseleave` to be emitted:
|
||||
|
||||
```js title='main.js'
|
||||
const { BrowserWindow, ipcMain } = require('electron')
|
||||
const path = require('node:path')
|
||||
|
||||
const win = new BrowserWindow({
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, 'preload.js')
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('set-ignore-mouse-events', (event, ignore, options) => {
|
||||
const win = BrowserWindow.fromWebContents(event.sender)
|
||||
win.setIgnoreMouseEvents(ignore, options)
|
||||
})
|
||||
```
|
||||
|
||||
```js title='preload.js'
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
const el = document.getElementById('clickThroughElement')
|
||||
el.addEventListener('mouseenter', () => {
|
||||
ipcRenderer.send('set-ignore-mouse-events', true, { forward: true })
|
||||
})
|
||||
el.addEventListener('mouseleave', () => {
|
||||
ipcRenderer.send('set-ignore-mouse-events', false)
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
This makes the web page click-through when over the `#clickThroughElement` element,
|
||||
and returns to normal outside it.
|
||||
|
||||
[ignore-mouse-events]: ../api/browser-window.md#winsetignoremouseeventsignore-options
|
||||
@@ -1,49 +0,0 @@
|
||||
# Custom Window Styles
|
||||
|
||||
## Frameless windows
|
||||
|
||||

|
||||
|
||||
A frameless window removes all [chrome][] applied by the OS, including window controls.
|
||||
|
||||
To create a frameless window, set the [`BaseWindowContructorOptions`][] `frame` param in the `BrowserWindow` constructor to `false`.
|
||||
|
||||
```fiddle docs/fiddles/features/window-customization/custom-window-styles/frameless-windows
|
||||
|
||||
```
|
||||
|
||||
## Transparent windows
|
||||
|
||||

|
||||

|
||||
|
||||
To create a fully transparent window, set the [`BaseWindowContructorOptions`][] `transparent` param in the `BrowserWindow` constructor to `true`.
|
||||
|
||||
The following fiddle takes advantage of a tranparent window and CSS styling to create
|
||||
the illusion of a circular window.
|
||||
|
||||
```fiddle docs/fiddles/features/window-customization/custom-window-styles/transparent-windows
|
||||
|
||||
```
|
||||
|
||||
### Limitations
|
||||
|
||||
* You cannot click through the transparent area. See
|
||||
[#1335](https://github.com/electron/electron/issues/1335) for details.
|
||||
* Transparent windows are not resizable. Setting `resizable` to `true` may make
|
||||
a transparent window stop working on some platforms.
|
||||
* The CSS [`blur()`][] filter only applies to the window's web contents, so there is
|
||||
no way to apply blur effect to the content below the window (i.e. other applications
|
||||
open on the user's system).
|
||||
* The window will not be transparent when DevTools is opened.
|
||||
* On _Windows_:
|
||||
* Transparent windows will not work when DWM is disabled.
|
||||
* Transparent windows can not be maximized using the Windows system menu or by double
|
||||
clicking the title bar. The reasoning behind this can be seen on
|
||||
PR [#28207](https://github.com/electron/electron/pull/28207).
|
||||
* On _macOS_:
|
||||
* The native window shadow will not be shown on a transparent window.
|
||||
|
||||
[`BaseWindowContructorOptions`]: ../api/structures/base-window-options.md
|
||||
[`blur()`]: https://developer.mozilla.org/en-US/docs/Web/CSS/filter-function/blur()
|
||||
[chrome]: https://developer.mozilla.org/en-US/docs/Glossary/Chrome
|
||||
@@ -9,11 +9,10 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
|
||||
|
||||
| Electron | Alpha | Beta | Stable | EOL | Chrome | Node | Supported |
|
||||
| ------- | ----- | ------- | ------ | ------ | ---- | ---- | ---- |
|
||||
| 34.0.0 | 2024-Oct-17 | 2024-Nov-13 | 2025-Jan-14 | 2025-Jun-24 | M132 | TBD | ✅ |
|
||||
| 33.0.0 | 2024-Aug-22 | 2024-Sep-18 | 2024-Oct-15 | 2025-Apr-29 | M130 | v20.18 | ✅ |
|
||||
| 33.0.0 | 2024-Aug-22 | 2024-Sep-18 | 2024-Oct-15 | 2025-Apr-29 | M130 | TBD | ✅ |
|
||||
| 32.0.0 | 2024-Jun-14 | 2024-Jul-24 | 2024-Aug-20 | 2025-Mar-04 | M128 | v20.16 | ✅ |
|
||||
| 31.0.0 | 2024-Apr-18 | 2024-May-15 | 2024-Jun-11 | 2025-Jan-14 | M126 | v20.14 | ✅ |
|
||||
| 30.0.0 | 2024-Feb-22 | 2024-Mar-20 | 2024-Apr-16 | 2024-Oct-15 | M124 | v20.11 | 🚫 |
|
||||
| 31.0.0 | 2024-Apr-18 | 2024-May-15 | 2024-Jun-11 | 2025-Jan-07 | M126 | v20.14 | ✅ |
|
||||
| 30.0.0 | 2024-Feb-22 | 2024-Mar-20 | 2024-Apr-16 | 2024-Oct-15 | M124 | v20.11 | ✅ |
|
||||
| 29.0.0 | 2023-Dec-07 | 2024-Jan-24 | 2024-Feb-20 | 2024-Aug-20 | M122 | v20.9 | 🚫 |
|
||||
| 28.0.0 | 2023-Oct-11 | 2023-Nov-06 | 2023-Dec-05 | 2024-Jun-11 | M120 | v18.18 | 🚫 |
|
||||
| 27.0.0 | 2023-Aug-17 | 2023-Sep-13 | 2023-Oct-10 | 2024-Apr-16 | M118 | v18.17 | 🚫 |
|
||||
|
||||
@@ -68,10 +68,6 @@ The onlyLoadAppFromAsar fuse changes the search system that Electron uses to loc
|
||||
|
||||
The loadBrowserProcessSpecificV8Snapshot fuse changes which V8 snapshot file is used for the browser process. By default Electron's processes will all use the same V8 snapshot file. When this fuse is enabled the browser process uses the file called `browser_v8_context_snapshot.bin` for its V8 snapshot. The other processes will use the V8 snapshot file that they normally do.
|
||||
|
||||
V8 snapshots can be useful to improve app startup performance. V8 lets you take snapshots of initialized heaps and then load them back in to avoid the cost of initializing the heap.
|
||||
|
||||
Using separate snapshots for renderer processes and the main process can improve security, especially to make sure that the renderer doesn't use a snapshot with `nodeIntegration` enabled. See [#35170](https://github.com/electron/electron/issues/35170) for details.
|
||||
|
||||
### `grantFileProtocolExtraPrivileges`
|
||||
|
||||
**Default:** Enabled
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
## Overview
|
||||
|
||||
Offscreen rendering lets you obtain the content of a `BrowserWindow` in a
|
||||
bitmap or a shared GPU texture, so it can be rendered anywhere, for example,
|
||||
on texture in a 3D scene.
|
||||
bitmap, so it can be rendered anywhere, for example, on texture in a 3D scene.
|
||||
The offscreen rendering in Electron uses a similar approach to that of the
|
||||
[Chromium Embedded Framework](https://bitbucket.org/chromiumembedded/cef)
|
||||
project.
|
||||
@@ -18,39 +17,22 @@ the dirty area is passed to the `paint` event to be more efficient.
|
||||
losses with no benefits.
|
||||
* When nothing is happening on a webpage, no frames are generated.
|
||||
* An offscreen window is always created as a
|
||||
[Frameless Window](../tutorial/window-customization.md).
|
||||
[Frameless Window](../tutorial/window-customization.md)..
|
||||
|
||||
### Rendering Modes
|
||||
|
||||
#### GPU accelerated
|
||||
|
||||
GPU accelerated rendering means that the GPU is used for composition. The benefit
|
||||
of this mode is that WebGL and 3D CSS animations are supported. There are two
|
||||
different approaches depending on the `webPreferences.offscreen.useSharedTexture`
|
||||
setting.
|
||||
|
||||
1. Use GPU shared texture
|
||||
|
||||
Used when `webPreferences.offscreen.useSharedTexture` is set to `true`.
|
||||
|
||||
This is an advanced feature requiring a native node module to work with your own code.
|
||||
The frames are directly copied in GPU textures, thus this mode is very fast because
|
||||
there's no CPU-GPU memory copies overhead, and you can directly import the shared
|
||||
texture to your own rendering program.
|
||||
|
||||
2. Use CPU shared memory bitmap
|
||||
|
||||
Used when `webPreferences.offscreen.useSharedTexture` is set to `false` (default behavior).
|
||||
|
||||
The texture is accessible using the `NativeImage` API at the cost of performance.
|
||||
The frame has to be copied from the GPU to the CPU bitmap which requires more system
|
||||
resources, thus this mode is slower than the Software output device mode. But it supports
|
||||
GPU related functionalities.
|
||||
GPU accelerated rendering means that the GPU is used for composition. Because of
|
||||
that, the frame has to be copied from the GPU which requires more resources,
|
||||
thus this mode is slower than the Software output device. The benefit of this
|
||||
mode is that WebGL and 3D CSS animations are supported.
|
||||
|
||||
#### Software output device
|
||||
|
||||
This mode uses a software output device for rendering in the CPU, so the frame
|
||||
generation is faster than shared memory bitmap GPU accelerated mode.
|
||||
generation is much faster. As a result, this mode is preferred over the GPU
|
||||
accelerated one.
|
||||
|
||||
To enable this mode, GPU acceleration has to be disabled by calling the
|
||||
[`app.disableHardwareAcceleration()`][disablehardwareacceleration] API.
|
||||
|
||||
@@ -1,17 +1,269 @@
|
||||
# Window Customization
|
||||
|
||||
The [`BrowserWindow`][] module is the foundation of your Electron application, and
|
||||
it exposes many APIs that let you customize the look and behavior of your app’s windows.
|
||||
This section covers how to implement various use cases for window customization on macOS,
|
||||
Windows, and Linux.
|
||||
The `BrowserWindow` module is the foundation of your Electron application, and it exposes
|
||||
many APIs that can change the look and behavior of your browser windows. In this
|
||||
tutorial, we will be going over the various use-cases for window customization on
|
||||
macOS, Windows, and Linux.
|
||||
|
||||
:::info
|
||||
`BrowserWindow` is a subclass of the [`BaseWindow`][] module. Both modules allow
|
||||
you to create and manage application windows in Electron, with the main difference
|
||||
being that `BrowserWindow` supports a single, full size web view while `BaseWindow`
|
||||
supports composing many web views. `BaseWindow` can be used interchangeably with `BrowserWindow`
|
||||
in the examples of the documents in this section.
|
||||
:::
|
||||
## Create frameless windows
|
||||
|
||||
[`BaseWindow`]: ../api/base-window.md
|
||||
[`BrowserWindow`]: ../api/browser-window.md
|
||||
A frameless window is a window that has no [chrome][]. Not to be confused with the Google
|
||||
Chrome browser, window _chrome_ refers to the parts of the window (e.g. toolbars, controls)
|
||||
that are not a part of the web page.
|
||||
|
||||
To create a frameless window, you need to set `frame` to `false` in the `BrowserWindow`
|
||||
constructor.
|
||||
|
||||
```js title='main.js'
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow({ frame: false })
|
||||
```
|
||||
|
||||
## Apply custom title bar styles _macOS_ _Windows_
|
||||
|
||||
Title bar styles allow you to hide most of a BrowserWindow's chrome while keeping the
|
||||
system's native window controls intact and can be configured with the `titleBarStyle`
|
||||
option in the `BrowserWindow` constructor.
|
||||
|
||||
Applying the `hidden` title bar style results in a hidden title bar and a full-size
|
||||
content window.
|
||||
|
||||
```js title='main.js'
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow({ titleBarStyle: 'hidden' })
|
||||
```
|
||||
|
||||
### Control the traffic lights _macOS_
|
||||
|
||||
On macOS, applying the `hidden` title bar style will still expose the standard window
|
||||
controls (“traffic lights”) in the top left.
|
||||
|
||||
#### Customize the look of your traffic lights _macOS_
|
||||
|
||||
The `customButtonsOnHover` title bar style will hide the traffic lights until you hover
|
||||
over them. This is useful if you want to create custom traffic lights in your HTML but still
|
||||
use the native UI to control the window.
|
||||
|
||||
```js
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow({ titleBarStyle: 'customButtonsOnHover' })
|
||||
```
|
||||
|
||||
#### Customize the traffic light position _macOS_
|
||||
|
||||
To modify the position of the traffic light window controls, there are two configuration
|
||||
options available.
|
||||
|
||||
Applying `hiddenInset` title bar style will shift the vertical inset of the traffic lights
|
||||
by a fixed amount.
|
||||
|
||||
```js title='main.js'
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow({ titleBarStyle: 'hiddenInset' })
|
||||
```
|
||||
|
||||
If you need more granular control over the positioning of the traffic lights, you can pass
|
||||
a set of coordinates to the `trafficLightPosition` option in the `BrowserWindow`
|
||||
constructor.
|
||||
|
||||
```js title='main.js'
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow({
|
||||
titleBarStyle: 'hidden',
|
||||
trafficLightPosition: { x: 10, y: 10 }
|
||||
})
|
||||
```
|
||||
|
||||
#### Show and hide the traffic lights programmatically _macOS_
|
||||
|
||||
You can also show and hide the traffic lights programmatically from the main process.
|
||||
The `win.setWindowButtonVisibility` forces traffic lights to be show or hidden depending
|
||||
on the value of its boolean parameter.
|
||||
|
||||
```js title='main.js'
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow()
|
||||
// hides the traffic lights
|
||||
win.setWindowButtonVisibility(false)
|
||||
```
|
||||
|
||||
> Note: Given the number of APIs available, there are many ways of achieving this. For instance,
|
||||
> combining `frame: false` with `win.setWindowButtonVisibility(true)` will yield the same
|
||||
> layout outcome as setting `titleBarStyle: 'hidden'`.
|
||||
|
||||
## Window Controls Overlay
|
||||
|
||||
The [Window Controls Overlay API][] is a web standard that gives web apps the ability to
|
||||
customize their title bar region when installed on desktop. Electron exposes this API
|
||||
through the `BrowserWindow` constructor option `titleBarOverlay`.
|
||||
|
||||
This option only works whenever a custom `titlebarStyle` is applied.
|
||||
When `titleBarOverlay` is enabled, the window controls become exposed in their default
|
||||
position, and DOM elements cannot use the area underneath this region.
|
||||
|
||||
The `titleBarOverlay` option accepts two different value formats.
|
||||
|
||||
Specifying `true` on either platform will result in an overlay region with default
|
||||
system colors:
|
||||
|
||||
```js title='main.js'
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow({
|
||||
titleBarStyle: 'hidden',
|
||||
titleBarOverlay: true
|
||||
})
|
||||
```
|
||||
|
||||
On either platform `titleBarOverlay` can also be an object. The height of the overlay can be specified with the `height` property. On Windows and Linux, the color of the overlay and can be specified using the `color` property. On Windows and Linux, the color of the overlay and its symbols can be specified using the `color` and `symbolColor` properties respectively. The `rgba()`, `hsla()`, and `#RRGGBBAA` color formats are supported to apply transparency.
|
||||
|
||||
If a color option is not specified, the color will default to its system color for the window control buttons. Similarly, if the height option is not specified it will default to the default height:
|
||||
|
||||
```js title='main.js'
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow({
|
||||
titleBarStyle: 'hidden',
|
||||
titleBarOverlay: {
|
||||
color: '#2f3241',
|
||||
symbolColor: '#74b1be',
|
||||
height: 60
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
> Note: Once your title bar overlay is enabled from the main process, you can access the overlay's
|
||||
> color and dimension values from a renderer using a set of readonly
|
||||
> [JavaScript APIs][overlay-javascript-apis] and [CSS Environment Variables][overlay-css-env-vars].
|
||||
|
||||
## Create transparent windows
|
||||
|
||||
By setting the `transparent` option to `true`, you can make a fully transparent window.
|
||||
|
||||
```js title='main.js'
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow({ transparent: true })
|
||||
```
|
||||
|
||||
### Limitations
|
||||
|
||||
* You cannot click through the transparent area. See
|
||||
[#1335](https://github.com/electron/electron/issues/1335) for details.
|
||||
* Transparent windows are not resizable. Setting `resizable` to `true` may make
|
||||
a transparent window stop working on some platforms.
|
||||
* The CSS [`blur()`][] filter only applies to the window's web contents, so there is no way to apply
|
||||
blur effect to the content below the window (i.e. other applications open on
|
||||
the user's system).
|
||||
* The window will not be transparent when DevTools is opened.
|
||||
* On _Windows_:
|
||||
* Transparent windows will not work when DWM is disabled.
|
||||
* Transparent windows can not be maximized using the Windows system menu or by double
|
||||
clicking the title bar. The reasoning behind this can be seen on
|
||||
PR [#28207](https://github.com/electron/electron/pull/28207).
|
||||
* On _macOS_:
|
||||
* The native window shadow will not be shown on a transparent window.
|
||||
|
||||
## Create click-through windows
|
||||
|
||||
To create a click-through window, i.e. making the window ignore all mouse
|
||||
events, you can call the [win.setIgnoreMouseEvents(ignore)][ignore-mouse-events]
|
||||
API:
|
||||
|
||||
```js title='main.js'
|
||||
const { BrowserWindow } = require('electron')
|
||||
const win = new BrowserWindow()
|
||||
win.setIgnoreMouseEvents(true)
|
||||
```
|
||||
|
||||
### Forward mouse events _macOS_ _Windows_
|
||||
|
||||
Ignoring mouse messages makes the web contents oblivious to mouse movement,
|
||||
meaning that mouse movement events will not be emitted. On Windows and macOS, an
|
||||
optional parameter can be used to forward mouse move messages to the web page,
|
||||
allowing events such as `mouseleave` to be emitted:
|
||||
|
||||
```js title='main.js'
|
||||
const { BrowserWindow, ipcMain } = require('electron')
|
||||
const path = require('node:path')
|
||||
|
||||
const win = new BrowserWindow({
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, 'preload.js')
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('set-ignore-mouse-events', (event, ignore, options) => {
|
||||
const win = BrowserWindow.fromWebContents(event.sender)
|
||||
win.setIgnoreMouseEvents(ignore, options)
|
||||
})
|
||||
```
|
||||
|
||||
```js title='preload.js'
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
const el = document.getElementById('clickThroughElement')
|
||||
el.addEventListener('mouseenter', () => {
|
||||
ipcRenderer.send('set-ignore-mouse-events', true, { forward: true })
|
||||
})
|
||||
el.addEventListener('mouseleave', () => {
|
||||
ipcRenderer.send('set-ignore-mouse-events', false)
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
This makes the web page click-through when over the `#clickThroughElement` element,
|
||||
and returns to normal outside it.
|
||||
|
||||
## Set custom draggable region
|
||||
|
||||
By default, the frameless window is non-draggable. Apps need to specify
|
||||
`-webkit-app-region: drag` in CSS to tell Electron which regions are draggable
|
||||
(like the OS's standard titlebar), and apps can also use
|
||||
`-webkit-app-region: no-drag` to exclude the non-draggable area from the
|
||||
draggable region. Note that only rectangular shapes are currently supported.
|
||||
|
||||
To make the whole window draggable, you can add `-webkit-app-region: drag` as
|
||||
`body`'s style:
|
||||
|
||||
```css title='styles.css'
|
||||
body {
|
||||
-webkit-app-region: drag;
|
||||
}
|
||||
```
|
||||
|
||||
And note that if you have made the whole window draggable, you must also mark
|
||||
buttons as non-draggable, otherwise it would be impossible for users to click on
|
||||
them:
|
||||
|
||||
```css title='styles.css'
|
||||
button {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
```
|
||||
|
||||
If you're only setting a custom titlebar as draggable, you also need to make all
|
||||
buttons in titlebar non-draggable.
|
||||
|
||||
### Tip: disable text selection
|
||||
|
||||
When creating a draggable region, the dragging behavior may conflict with text selection.
|
||||
For example, when you drag the titlebar, you may accidentally select its text contents.
|
||||
To prevent this, you need to disable text selection within a draggable area like this:
|
||||
|
||||
```css
|
||||
.titlebar {
|
||||
-webkit-user-select: none;
|
||||
-webkit-app-region: drag;
|
||||
}
|
||||
```
|
||||
|
||||
### Tip: disable context menus
|
||||
|
||||
On some platforms, the draggable area will be treated as a non-client frame, so
|
||||
when you right click on it, a system menu will pop up. To make the context menu
|
||||
behave correctly on all platforms, you should never use a custom context menu on
|
||||
draggable areas.
|
||||
|
||||
[`blur()`]: https://developer.mozilla.org/en-US/docs/Web/CSS/filter-function/blur()
|
||||
[chrome]: https://developer.mozilla.org/en-US/docs/Glossary/Chrome
|
||||
[ignore-mouse-events]: ../api/browser-window.md#winsetignoremouseeventsignore-options
|
||||
[overlay-css-env-vars]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#css-environment-variables
|
||||
[overlay-javascript-apis]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md#javascript-apis
|
||||
[Window Controls Overlay API]: https://github.com/WICG/window-controls-overlay/blob/main/explainer.md
|
||||
|
||||
@@ -108,7 +108,6 @@ auto_filenames = {
|
||||
"docs/api/structures/navigation-entry.md",
|
||||
"docs/api/structures/notification-action.md",
|
||||
"docs/api/structures/notification-response.md",
|
||||
"docs/api/structures/offscreen-shared-texture.md",
|
||||
"docs/api/structures/open-external-permission-request.md",
|
||||
"docs/api/structures/payment-discount.md",
|
||||
"docs/api/structures/permission-request.md",
|
||||
|
||||
@@ -205,8 +205,6 @@ filenames = {
|
||||
"shell/common/mac/main_application_bundle.mm",
|
||||
"shell/common/mac/codesign_util.cc",
|
||||
"shell/common/mac/codesign_util.h",
|
||||
"shell/common/mac_util.h",
|
||||
"shell/common/mac_util.mm",
|
||||
"shell/common/node_bindings_mac.cc",
|
||||
"shell/common/node_bindings_mac.h",
|
||||
"shell/common/platform_util_mac.mm",
|
||||
@@ -470,8 +468,6 @@ filenames = {
|
||||
"shell/browser/notifications/platform_notification_service.h",
|
||||
"shell/browser/osr/osr_host_display_client.cc",
|
||||
"shell/browser/osr/osr_host_display_client.h",
|
||||
"shell/browser/osr/osr_paint_event.cc",
|
||||
"shell/browser/osr/osr_paint_event.h",
|
||||
"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",
|
||||
@@ -507,10 +503,6 @@ filenames = {
|
||||
"shell/browser/ui/devtools_manager_delegate.h",
|
||||
"shell/browser/ui/devtools_ui.cc",
|
||||
"shell/browser/ui/devtools_ui.h",
|
||||
"shell/browser/ui/devtools_ui_bundle_data_source.cc",
|
||||
"shell/browser/ui/devtools_ui_bundle_data_source.h",
|
||||
"shell/browser/ui/devtools_ui_theme_data_source.cc",
|
||||
"shell/browser/ui/devtools_ui_theme_data_source.h",
|
||||
"shell/browser/ui/drag_util.cc",
|
||||
"shell/browser/ui/drag_util.h",
|
||||
"shell/browser/ui/electron_menu_model.cc",
|
||||
@@ -619,8 +611,6 @@ filenames = {
|
||||
"shell/common/gin_converters/net_converter.cc",
|
||||
"shell/common/gin_converters/net_converter.h",
|
||||
"shell/common/gin_converters/optional_converter.h",
|
||||
"shell/common/gin_converters/osr_converter.cc",
|
||||
"shell/common/gin_converters/osr_converter.h",
|
||||
"shell/common/gin_converters/serial_port_info_converter.h",
|
||||
"shell/common/gin_converters/std_converter.h",
|
||||
"shell/common/gin_converters/time_converter.cc",
|
||||
@@ -690,8 +680,8 @@ filenames = {
|
||||
"shell/common/skia_util.cc",
|
||||
"shell/common/skia_util.h",
|
||||
"shell/common/thread_restrictions.h",
|
||||
"shell/common/v8_util.cc",
|
||||
"shell/common/v8_util.h",
|
||||
"shell/common/v8_value_serializer.cc",
|
||||
"shell/common/v8_value_serializer.h",
|
||||
"shell/common/world_ids.h",
|
||||
"shell/renderer/api/context_bridge/object_cache.cc",
|
||||
"shell/renderer/api/context_bridge/object_cache.h",
|
||||
|
||||
@@ -37,33 +37,6 @@ BrowserWindow.prototype._init = function (this: BWT) {
|
||||
app.emit('browser-window-focus', event, this);
|
||||
});
|
||||
|
||||
let unresponsiveEvent: NodeJS.Timeout | null = null;
|
||||
const emitUnresponsiveEvent = () => {
|
||||
unresponsiveEvent = null;
|
||||
if (!this.isDestroyed() && this.isEnabled()) { this.emit('unresponsive'); }
|
||||
};
|
||||
this.webContents.on('unresponsive', () => {
|
||||
if (!unresponsiveEvent) { unresponsiveEvent = setTimeout(emitUnresponsiveEvent, 50); }
|
||||
});
|
||||
this.webContents.on('responsive', () => {
|
||||
if (unresponsiveEvent) {
|
||||
clearTimeout(unresponsiveEvent);
|
||||
unresponsiveEvent = null;
|
||||
}
|
||||
this.emit('responsive');
|
||||
});
|
||||
this.on('close', (event) => {
|
||||
queueMicrotask(() => {
|
||||
if (!unresponsiveEvent && !event.defaultPrevented) {
|
||||
unresponsiveEvent = setTimeout(emitUnresponsiveEvent, 5000);
|
||||
}
|
||||
});
|
||||
});
|
||||
this.webContents.on('destroyed', () => {
|
||||
if (unresponsiveEvent) clearTimeout(unresponsiveEvent);
|
||||
unresponsiveEvent = null;
|
||||
});
|
||||
|
||||
// Subscribe to visibilityState changes and pass to renderer process.
|
||||
let isVisible = this.isVisible() && !this.isMinimized();
|
||||
const visibilityChanged = () => {
|
||||
|
||||
@@ -485,6 +485,10 @@ const addReplyToEvent = (event: Electron.IpcMainEvent) => {
|
||||
|
||||
const addSenderToEvent = (event: Electron.IpcMainEvent | Electron.IpcMainInvokeEvent, sender: Electron.WebContents) => {
|
||||
event.sender = sender;
|
||||
const { processId, frameId } = event;
|
||||
Object.defineProperty(event, 'senderFrame', {
|
||||
get: () => webFrameMain.fromId(processId, frameId)
|
||||
});
|
||||
};
|
||||
|
||||
const addReturnValueToEvent = (event: Electron.IpcMainEvent) => {
|
||||
@@ -494,6 +498,11 @@ const addReturnValueToEvent = (event: Electron.IpcMainEvent) => {
|
||||
});
|
||||
};
|
||||
|
||||
const getWebFrameForEvent = (event: Electron.IpcMainEvent | Electron.IpcMainInvokeEvent) => {
|
||||
if (!event.processId || !event.frameId) return null;
|
||||
return webFrameMainBinding.fromIdOrNull(event.processId, event.frameId);
|
||||
};
|
||||
|
||||
const commandLine = process._linkedBinding('electron_common_command_line');
|
||||
const environment = process._linkedBinding('electron_common_environment');
|
||||
|
||||
@@ -571,28 +580,6 @@ WebContents.prototype._init = function () {
|
||||
enumerable: true
|
||||
});
|
||||
|
||||
/**
|
||||
* Cached IPC emitters sorted by dispatch priority.
|
||||
* Caching is used to avoid frequent array allocations.
|
||||
*
|
||||
* 0: WebFrameMain ipc
|
||||
* 1: WebContents ipc
|
||||
* 2: ipcMain
|
||||
*/
|
||||
const cachedIpcEmitters: (ElectronInternal.IpcMainInternal | undefined)[] = [undefined, ipc, ipcMain];
|
||||
|
||||
// Get list of relevant IPC emitters for dispatch.
|
||||
const getIpcEmittersForEvent = (event: Electron.IpcMainEvent | Electron.IpcMainInvokeEvent): (ElectronInternal.IpcMainInternal | undefined)[] => {
|
||||
// Lookup by FrameTreeNode ID to ensure IPCs received after a frame swap are
|
||||
// always received. This occurs when a RenderFrame sends an IPC while it's
|
||||
// unloading and its internal state is pending deletion.
|
||||
const { frameTreeNodeId } = event;
|
||||
const webFrameByFtn = frameTreeNodeId ? webFrameMainBinding._fromFtnIdIfExists(frameTreeNodeId) : undefined;
|
||||
cachedIpcEmitters[0] = webFrameByFtn?.ipc;
|
||||
|
||||
return cachedIpcEmitters;
|
||||
};
|
||||
|
||||
// Add navigationHistory property which handles session history,
|
||||
// maintaining a list of navigation entries for backward and forward navigation.
|
||||
Object.defineProperty(this, 'navigationHistory', {
|
||||
@@ -623,9 +610,10 @@ WebContents.prototype._init = function () {
|
||||
} else {
|
||||
addReplyToEvent(event);
|
||||
this.emit('ipc-message', event, channel, ...args);
|
||||
for (const ipcEmitter of getIpcEmittersForEvent(event)) {
|
||||
ipcEmitter?.emit(channel, event, ...args);
|
||||
}
|
||||
const maybeWebFrame = getWebFrameForEvent(event);
|
||||
maybeWebFrame && maybeWebFrame.ipc.emit(channel, event, ...args);
|
||||
ipc.emit(channel, event, ...args);
|
||||
ipcMain.emit(channel, event, ...args);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -636,8 +624,9 @@ WebContents.prototype._init = function () {
|
||||
console.error(`Error occurred in handler for '${channel}':`, error);
|
||||
event._replyChannel.sendReply({ error: error.toString() });
|
||||
};
|
||||
const targets: (ElectronInternal.IpcMainInternal | undefined)[] = internal ? [ipcMainInternal] : getIpcEmittersForEvent(event);
|
||||
const target = targets.find(target => (target as any)?._invokeHandlers.has(channel));
|
||||
const maybeWebFrame = getWebFrameForEvent(event);
|
||||
const targets: (ElectronInternal.IpcMainInternal| undefined)[] = internal ? [ipcMainInternal] : [maybeWebFrame?.ipc, ipc, ipcMain];
|
||||
const target = targets.find(target => target && (target as any)._invokeHandlers.has(channel));
|
||||
if (target) {
|
||||
const handler = (target as any)._invokeHandlers.get(channel);
|
||||
try {
|
||||
@@ -657,27 +646,24 @@ WebContents.prototype._init = function () {
|
||||
ipcMainInternal.emit(channel, event, ...args);
|
||||
} else {
|
||||
addReplyToEvent(event);
|
||||
const ipcEmitters = getIpcEmittersForEvent(event);
|
||||
if (
|
||||
this.listenerCount('ipc-message-sync') === 0 &&
|
||||
ipcEmitters.every(emitter => !emitter || emitter.listenerCount(channel) === 0)
|
||||
) {
|
||||
const maybeWebFrame = getWebFrameForEvent(event);
|
||||
if (this.listenerCount('ipc-message-sync') === 0 && ipc.listenerCount(channel) === 0 && ipcMain.listenerCount(channel) === 0 && (!maybeWebFrame || maybeWebFrame.ipc.listenerCount(channel) === 0)) {
|
||||
console.warn(`WebContents #${this.id} called ipcRenderer.sendSync() with '${channel}' channel without listeners.`);
|
||||
}
|
||||
this.emit('ipc-message-sync', event, channel, ...args);
|
||||
for (const ipcEmitter of ipcEmitters) {
|
||||
ipcEmitter?.emit(channel, event, ...args);
|
||||
}
|
||||
maybeWebFrame && maybeWebFrame.ipc.emit(channel, event, ...args);
|
||||
ipc.emit(channel, event, ...args);
|
||||
ipcMain.emit(channel, event, ...args);
|
||||
}
|
||||
});
|
||||
|
||||
this.on('-ipc-ports', function (this: Electron.WebContents, event: Electron.IpcMainEvent, internal: boolean, channel: string, message: any, ports: any[]) {
|
||||
addSenderToEvent(event, this);
|
||||
event.ports = ports.map(p => new MessagePortMain(p));
|
||||
const ipcEmitters = getIpcEmittersForEvent(event);
|
||||
for (const ipcEmitter of ipcEmitters) {
|
||||
ipcEmitter?.emit(channel, event, message);
|
||||
}
|
||||
const maybeWebFrame = getWebFrameForEvent(event);
|
||||
maybeWebFrame && maybeWebFrame.ipc.emit(channel, event, message);
|
||||
ipc.emit(channel, event, message);
|
||||
ipcMain.emit(channel, event, message);
|
||||
});
|
||||
|
||||
this.on('render-process-gone', (event, details) => {
|
||||
@@ -909,13 +895,6 @@ WebContents.prototype._init = function () {
|
||||
openDialogs.clear();
|
||||
});
|
||||
|
||||
this.on('-unresponsive' as any, (event: Electron.Event<any>) => {
|
||||
const shouldEmit = !event.shouldIgnore && event.visible && event.rendererInitialized;
|
||||
if (shouldEmit) {
|
||||
this.emit('unresponsive', event);
|
||||
}
|
||||
});
|
||||
|
||||
app.emit('web-contents-created', { sender: this, preventDefault () {}, get defaultPrevented () { return false; } }, this);
|
||||
|
||||
// Properties
|
||||
|
||||
@@ -168,8 +168,8 @@ const createGuest = function (embedder: Electron.WebContents, embedderFrameId: n
|
||||
sendToEmbedder(IPC_MESSAGES.GUEST_VIEW_INTERNAL_DISPATCH_EVENT, 'will-frame-navigate', {
|
||||
url: event.url,
|
||||
isMainFrame: event.isMainFrame,
|
||||
frameProcessId: event.processId,
|
||||
frameRoutingId: event.routingId
|
||||
frameProcessId: event.frame.processId,
|
||||
frameRoutingId: event.frame.routingId
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ wrapFsWithAsar(require('fs'));
|
||||
|
||||
// See ElectronRendererClient::DidCreateScriptContext.
|
||||
if ((globalThis as any).blinkfetch) {
|
||||
const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers', 'EventSource'];
|
||||
const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers'];
|
||||
for (const key of keys) {
|
||||
(globalThis as any)[key] = (globalThis as any)[`blink${key}`];
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ global.require = makeRequireFunction(global.module);
|
||||
|
||||
// See WebWorkerObserver::WorkerScriptReadyForEvaluation.
|
||||
if ((globalThis as any).blinkfetch) {
|
||||
const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers', 'EventSource'];
|
||||
const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers'];
|
||||
for (const key of keys) {
|
||||
(globalThis as any)[key] = (globalThis as any)[`blink${key}`];
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
"folder-hash": "^2.1.1",
|
||||
"got": "^11.8.5",
|
||||
"husky": "^8.0.1",
|
||||
"lint": "^1.1.2",
|
||||
"lint-staged": "^10.2.11",
|
||||
"markdownlint-cli2": "^0.13.0",
|
||||
"minimist": "^1.2.8",
|
||||
|
||||
@@ -130,9 +130,4 @@ chore_remove_reference_to_chrome_browser_themes.patch
|
||||
feat_enable_customizing_symbol_color_in_framecaptionbutton.patch
|
||||
build_expose_webplugininfo_interface_to_electron.patch
|
||||
feat_allow_usage_of_sccontentsharingpicker_on_supported_platforms.patch
|
||||
fix_software_compositing_infinite_loop.patch
|
||||
ui_add_missing_shortcut_text_for_vkey_command_on_linux.patch
|
||||
osr_shared_texture_remove_keyed_mutex_on_win_dxgi.patch
|
||||
refactor_unfilter_unresponsive_events.patch
|
||||
wayland_support_outgoing_dnd_sessions_with_no_offered_mime_types.patch
|
||||
support_bstr_pkey_appusermodel_id_in_windows_shortcuts.patch
|
||||
feat_allow_-4_as_a_macos_screen_share_id.patch
|
||||
|
||||
@@ -46,10 +46,10 @@ index 7f1c26990d8d43e92615bd3a5f4046d121d6ac6b..89d03b68cab5cec6095c2df2159a2f1c
|
||||
# than here in :chrome_dll.
|
||||
deps += [ "//chrome:packed_resources_integrity_header" ]
|
||||
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
|
||||
index 26702ebe305dae944d7f425ec610058e51c43656..855bd8f541db112929e5cca4473bde5e577d0d4d 100644
|
||||
index c53d7af88b3570e6c320b408afa449e51e355b6b..61aecb395632212911d57545cb068ca67bbac7d5 100644
|
||||
--- a/chrome/test/BUILD.gn
|
||||
+++ b/chrome/test/BUILD.gn
|
||||
@@ -7174,9 +7174,12 @@ test("unit_tests") {
|
||||
@@ -7173,9 +7173,12 @@ test("unit_tests") {
|
||||
"//chrome/notification_helper",
|
||||
]
|
||||
|
||||
@@ -63,7 +63,7 @@ index 26702ebe305dae944d7f425ec610058e51c43656..855bd8f541db112929e5cca4473bde5e
|
||||
"//chrome//services/util_win:unit_tests",
|
||||
"//chrome/app:chrome_dll_resources",
|
||||
"//chrome/app:win_unit_tests",
|
||||
@@ -8182,6 +8185,10 @@ test("unit_tests") {
|
||||
@@ -8181,6 +8184,10 @@ test("unit_tests") {
|
||||
"../browser/performance_manager/policies/background_tab_loading_policy_unittest.cc",
|
||||
]
|
||||
|
||||
@@ -74,7 +74,7 @@ index 26702ebe305dae944d7f425ec610058e51c43656..855bd8f541db112929e5cca4473bde5e
|
||||
sources += [
|
||||
# The importer code is not used on Android.
|
||||
"../common/importer/firefox_importer_utils_unittest.cc",
|
||||
@@ -8238,7 +8245,6 @@ test("unit_tests") {
|
||||
@@ -8237,7 +8244,6 @@ test("unit_tests") {
|
||||
# Non-android deps for "unit_tests" target.
|
||||
deps += [
|
||||
"../browser/screen_ai:screen_ai_install_state",
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Fedor Indutny <indutny@signal.org>
|
||||
Date: Tue, 17 Sep 2024 17:51:46 -0700
|
||||
Subject: feat: allow -4 as a macos screen share id
|
||||
|
||||
We use fake video source ids for native macOS screen share window picker
|
||||
of the following form:
|
||||
|
||||
window:-4:-1
|
||||
|
||||
Where the last digit represents the window id and decrements with each
|
||||
requested screen share.
|
||||
|
||||
diff --git a/content/browser/media/capture/screen_capture_kit_device_mac.mm b/content/browser/media/capture/screen_capture_kit_device_mac.mm
|
||||
index 1c2d0c6dd4101fe0bac69e3018bbbedadce224cc..e407382a3463374fd57a83d70c5f96dca5825faf 100644
|
||||
--- a/content/browser/media/capture/screen_capture_kit_device_mac.mm
|
||||
+++ b/content/browser/media/capture/screen_capture_kit_device_mac.mm
|
||||
@@ -510,7 +510,9 @@ void OnStart(std::optional<bool> use_native_picker) override {
|
||||
|
||||
if (@available(macOS 15.0, *)) {
|
||||
constexpr bool DefaultUseNativePicker = true;
|
||||
- if (use_native_picker.value_or(DefaultUseNativePicker) && source_.id < 0 && source_.window_id == 0) {
|
||||
+ if (use_native_picker.value_or(DefaultUseNativePicker) &&
|
||||
+ source_.id == DesktopMediaID::kMacOsNativePickerId &&
|
||||
+ source_.window_id < 0) {
|
||||
auto* picker = [SCContentSharingPicker sharedPicker];
|
||||
ScreenCaptureKitDeviceMac::active_streams_++;
|
||||
picker.maximumStreamCount = @(ScreenCaptureKitDeviceMac::active_streams_);
|
||||
diff --git a/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc b/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
|
||||
index d162612dc70a2b57190aaf558aca8f46cbdedcad..bab2f0282b191a4263fc964125e199e52c62554b 100644
|
||||
--- a/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
|
||||
+++ b/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
|
||||
@@ -332,8 +332,16 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
break;
|
||||
}
|
||||
|
||||
+#if defined(USE_AURA)
|
||||
+ bool allow_window_id = false;
|
||||
+#elif BUILDFLAG(IS_MAC)
|
||||
+ bool allow_window_id =
|
||||
+ desktop_id.id == DesktopMediaID::kMacOsNativePickerId;
|
||||
+#endif
|
||||
+
|
||||
#if defined(USE_AURA) || BUILDFLAG(IS_MAC)
|
||||
- if (desktop_id.window_id != DesktopMediaID::kNullId) {
|
||||
+ if (!allow_window_id &&
|
||||
+ desktop_id.window_id != DesktopMediaID::kNullId) {
|
||||
// For the other capturers, when a bug reports the type of capture it's
|
||||
// easy enough to determine which capturer was used, but it's a little
|
||||
// fuzzier with window capture.
|
||||
diff --git a/content/public/browser/desktop_media_id.h b/content/public/browser/desktop_media_id.h
|
||||
index 415156d403a59bf426cf4561a9d58ecdb27524b4..78aa7b2359c684d5305bf6352751dfbb7ca00d29 100644
|
||||
--- a/content/public/browser/desktop_media_id.h
|
||||
+++ b/content/public/browser/desktop_media_id.h
|
||||
@@ -27,6 +27,8 @@ struct CONTENT_EXPORT DesktopMediaID {
|
||||
static constexpr Id kNullId = 0;
|
||||
// Represents a fake id to create a dummy capturer for autotests.
|
||||
static constexpr Id kFakeId = -3;
|
||||
+ // Represents an id to use native macOS picker for screenshare
|
||||
+ static constexpr Id kMacOsNativePickerId = -4;
|
||||
|
||||
#if defined(USE_AURA) || BUILDFLAG(IS_MAC)
|
||||
// Assigns integer identifier to the |window| and returns its DesktopMediaID.
|
||||
@@ -46,7 +46,7 @@ index 8ac12480f663a74dfbdcf7128a582a81b4474d25..db6802a2603e1d3c3039e49737438124
|
||||
// OnStop is called by StopAndDeAllocate.
|
||||
virtual void OnStop() = 0;
|
||||
diff --git a/content/browser/media/capture/screen_capture_kit_device_mac.mm b/content/browser/media/capture/screen_capture_kit_device_mac.mm
|
||||
index b6129282c6807702cf88e0a3e2ba233e41a20960..87a00302de8db47299b185471e303b9e172e9c76 100644
|
||||
index b6129282c6807702cf88e0a3e2ba233e41a20960..1c2d0c6dd4101fe0bac69e3018bbbedadce224cc 100644
|
||||
--- a/content/browser/media/capture/screen_capture_kit_device_mac.mm
|
||||
+++ b/content/browser/media/capture/screen_capture_kit_device_mac.mm
|
||||
@@ -24,24 +24,83 @@
|
||||
@@ -143,7 +143,7 @@ index b6129282c6807702cf88e0a3e2ba233e41a20960..87a00302de8db47299b185471e303b9e
|
||||
public:
|
||||
explicit ScreenCaptureKitDeviceMac(const DesktopMediaID& source,
|
||||
SCContentFilter* filter)
|
||||
@@ -152,18 +212,42 @@ explicit ScreenCaptureKitDeviceMac(const DesktopMediaID& source,
|
||||
@@ -152,18 +212,41 @@ explicit ScreenCaptureKitDeviceMac(const DesktopMediaID& source,
|
||||
device_task_runner_,
|
||||
base::BindRepeating(&ScreenCaptureKitDeviceMac::OnStreamSample,
|
||||
weak_factory_.GetWeakPtr()));
|
||||
@@ -165,8 +165,8 @@ index b6129282c6807702cf88e0a3e2ba233e41a20960..87a00302de8db47299b185471e303b9e
|
||||
+ device_task_runner_,
|
||||
+ base::BindRepeating(&ScreenCaptureKitDeviceMac::OnContentFilterReady, weak_factory_.GetWeakPtr())
|
||||
+ );
|
||||
+ picker_helper_ = [[ScreenCaptureKitPickerHelper alloc] initWithStreamPickCallback:picker_callback cancelCallback:cancel_callback errorCallback:error_callback];
|
||||
+ [[SCContentSharingPicker sharedPicker] addObserver:picker_helper_];
|
||||
+ auto* picker_observer = [[ScreenCaptureKitPickerHelper alloc] initWithStreamPickCallback:picker_callback cancelCallback:cancel_callback errorCallback:error_callback];
|
||||
+ [[SCContentSharingPicker sharedPicker] addObserver:picker_observer];
|
||||
+ }
|
||||
}
|
||||
ScreenCaptureKitDeviceMac(const ScreenCaptureKitDeviceMac&) = delete;
|
||||
@@ -180,14 +180,13 @@ index b6129282c6807702cf88e0a3e2ba233e41a20960..87a00302de8db47299b185471e303b9e
|
||||
+ picker.maximumStreamCount = @(ScreenCaptureKitDeviceMac::active_streams_);
|
||||
+ if (ScreenCaptureKitDeviceMac::active_streams_ == 0 && picker.active) {
|
||||
+ picker.active = false;
|
||||
+ [[SCContentSharingPicker sharedPicker] removeObserver:picker_helper_];
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
|
||||
void OnShareableContentCreated(SCShareableContent* content) {
|
||||
DCHECK(device_task_runner_->RunsTasksInCurrentSequence());
|
||||
@@ -232,7 +316,7 @@ void CreateStream(SCContentFilter* filter) {
|
||||
@@ -232,7 +315,7 @@ void CreateStream(SCContentFilter* filter) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -196,7 +195,7 @@ index b6129282c6807702cf88e0a3e2ba233e41a20960..87a00302de8db47299b185471e303b9e
|
||||
// Update the content size. This step is neccessary when used together
|
||||
// with SCContentSharingPicker. If the Chrome picker is used, it will
|
||||
// change to retina resolution if applicable.
|
||||
@@ -241,6 +325,9 @@ void CreateStream(SCContentFilter* filter) {
|
||||
@@ -241,6 +324,9 @@ void CreateStream(SCContentFilter* filter) {
|
||||
filter.contentRect.size.height * filter.pointPixelScale);
|
||||
}
|
||||
|
||||
@@ -206,7 +205,7 @@ index b6129282c6807702cf88e0a3e2ba233e41a20960..87a00302de8db47299b185471e303b9e
|
||||
gfx::RectF dest_rect_in_frame;
|
||||
actual_capture_format_ = capture_params().requested_format;
|
||||
actual_capture_format_.pixel_format = media::PIXEL_FORMAT_NV12;
|
||||
@@ -254,6 +341,7 @@ void CreateStream(SCContentFilter* filter) {
|
||||
@@ -254,6 +340,7 @@ void CreateStream(SCContentFilter* filter) {
|
||||
stream_ = [[SCStream alloc] initWithFilter:filter
|
||||
configuration:config
|
||||
delegate:helper_];
|
||||
@@ -214,7 +213,7 @@ index b6129282c6807702cf88e0a3e2ba233e41a20960..87a00302de8db47299b185471e303b9e
|
||||
{
|
||||
NSError* error = nil;
|
||||
bool add_stream_output_result =
|
||||
@@ -395,7 +483,7 @@ void OnStreamError() {
|
||||
@@ -395,7 +482,7 @@ void OnStreamError() {
|
||||
if (fullscreen_module_) {
|
||||
fullscreen_module_->Reset();
|
||||
}
|
||||
@@ -223,7 +222,7 @@ index b6129282c6807702cf88e0a3e2ba233e41a20960..87a00302de8db47299b185471e303b9e
|
||||
} else {
|
||||
client()->OnError(media::VideoCaptureError::kScreenCaptureKitStreamError,
|
||||
FROM_HERE, "Stream delegate called didStopWithError");
|
||||
@@ -418,23 +506,41 @@ void OnUpdateConfigurationError() {
|
||||
@@ -418,23 +505,39 @@ void OnUpdateConfigurationError() {
|
||||
}
|
||||
|
||||
// IOSurfaceCaptureDeviceBase:
|
||||
@@ -247,9 +246,7 @@ index b6129282c6807702cf88e0a3e2ba233e41a20960..87a00302de8db47299b185471e303b9e
|
||||
+
|
||||
+ if (@available(macOS 15.0, *)) {
|
||||
+ constexpr bool DefaultUseNativePicker = true;
|
||||
+ if (use_native_picker.value_or(DefaultUseNativePicker) &&
|
||||
+ source_.id == DesktopMediaID::kMacOsNativePickerId &&
|
||||
+ source_.window_id < 0) {
|
||||
+ if (use_native_picker.value_or(DefaultUseNativePicker) && source_.id < 0 && source_.window_id == 0) {
|
||||
+ auto* picker = [SCContentSharingPicker sharedPicker];
|
||||
+ ScreenCaptureKitDeviceMac::active_streams_++;
|
||||
+ picker.maximumStreamCount = @(ScreenCaptureKitDeviceMac::active_streams_);
|
||||
@@ -280,7 +277,7 @@ index b6129282c6807702cf88e0a3e2ba233e41a20960..87a00302de8db47299b185471e303b9e
|
||||
}
|
||||
void OnStop() override {
|
||||
DCHECK(device_task_runner_->RunsTasksInCurrentSequence());
|
||||
@@ -492,6 +598,8 @@ void ResetStreamTo(SCWindow* window) override {
|
||||
@@ -492,6 +595,8 @@ void ResetStreamTo(SCWindow* window) override {
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -289,18 +286,7 @@ index b6129282c6807702cf88e0a3e2ba233e41a20960..87a00302de8db47299b185471e303b9e
|
||||
const DesktopMediaID source_;
|
||||
SCContentFilter* const filter_;
|
||||
const scoped_refptr<base::SingleThreadTaskRunner> device_task_runner_;
|
||||
@@ -509,6 +617,10 @@ void ResetStreamTo(SCWindow* window) override {
|
||||
// Helper class that acts as output and delegate for `stream_`.
|
||||
ScreenCaptureKitDeviceHelper* __strong helper_;
|
||||
|
||||
+ // Helper class that acts as an observer for SCContentSharingPicker
|
||||
+ API_AVAILABLE(macos(15.0))
|
||||
+ ScreenCaptureKitPickerHelper* __strong picker_helper_;
|
||||
+
|
||||
// This is used to detect when a captured presentation enters fullscreen mode.
|
||||
// If this happens, the module will call the ResetStreamTo function.
|
||||
std::unique_ptr<ScreenCaptureKitFullscreenModule> fullscreen_module_;
|
||||
@@ -521,6 +633,8 @@ void ResetStreamTo(SCWindow* window) override {
|
||||
@@ -521,6 +626,8 @@ void ResetStreamTo(SCWindow* window) override {
|
||||
base::WeakPtrFactory<ScreenCaptureKitDeviceMac> weak_factory_{this};
|
||||
};
|
||||
|
||||
@@ -310,28 +296,10 @@ index b6129282c6807702cf88e0a3e2ba233e41a20960..87a00302de8db47299b185471e303b9e
|
||||
|
||||
// Although ScreenCaptureKit is available in 12.3 there were some bugs that
|
||||
diff --git a/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc b/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
|
||||
index 7adf8264cfa9980c4a8414bf0f8bfa9ad70ec0b3..bab2f0282b191a4263fc964125e199e52c62554b 100644
|
||||
index 7adf8264cfa9980c4a8414bf0f8bfa9ad70ec0b3..d162612dc70a2b57190aaf558aca8f46cbdedcad 100644
|
||||
--- a/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
|
||||
+++ b/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
|
||||
@@ -332,8 +332,16 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
break;
|
||||
}
|
||||
|
||||
+#if defined(USE_AURA)
|
||||
+ bool allow_window_id = false;
|
||||
+#elif BUILDFLAG(IS_MAC)
|
||||
+ bool allow_window_id =
|
||||
+ desktop_id.id == DesktopMediaID::kMacOsNativePickerId;
|
||||
+#endif
|
||||
+
|
||||
#if defined(USE_AURA) || BUILDFLAG(IS_MAC)
|
||||
- if (desktop_id.window_id != DesktopMediaID::kNullId) {
|
||||
+ if (!allow_window_id &&
|
||||
+ desktop_id.window_id != DesktopMediaID::kNullId) {
|
||||
// For the other capturers, when a bug reports the type of capture it's
|
||||
// easy enough to determine which capturer was used, but it's a little
|
||||
// fuzzier with window capture.
|
||||
@@ -360,13 +368,15 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
@@ -360,13 +360,15 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
|
||||
std::move(after_start_capture_callback));
|
||||
break;
|
||||
#else
|
||||
@@ -348,19 +316,6 @@ index 7adf8264cfa9980c4a8414bf0f8bfa9ad70ec0b3..bab2f0282b191a4263fc964125e199e5
|
||||
CreateDeviceClient(media::VideoCaptureBufferType::kSharedMemory,
|
||||
kMaxNumberOfBuffers, std::move(receiver),
|
||||
std::move(receiver_on_io_thread)),
|
||||
diff --git a/content/public/browser/desktop_media_id.h b/content/public/browser/desktop_media_id.h
|
||||
index 415156d403a59bf426cf4561a9d58ecdb27524b4..78aa7b2359c684d5305bf6352751dfbb7ca00d29 100644
|
||||
--- a/content/public/browser/desktop_media_id.h
|
||||
+++ b/content/public/browser/desktop_media_id.h
|
||||
@@ -27,6 +27,8 @@ struct CONTENT_EXPORT DesktopMediaID {
|
||||
static constexpr Id kNullId = 0;
|
||||
// Represents a fake id to create a dummy capturer for autotests.
|
||||
static constexpr Id kFakeId = -3;
|
||||
+ // Represents an id to use native macOS picker for screenshare
|
||||
+ static constexpr Id kMacOsNativePickerId = -4;
|
||||
|
||||
#if defined(USE_AURA) || BUILDFLAG(IS_MAC)
|
||||
// Assigns integer identifier to the |window| and returns its DesktopMediaID.
|
||||
diff --git a/media/capture/video_capture_types.h b/media/capture/video_capture_types.h
|
||||
index f2b75f5b2f547ad135c1288bf3639b26dedc8053..ef18724d9f2ea68a47b66fc3981f58a73ac1b51d 100644
|
||||
--- a/media/capture/video_capture_types.h
|
||||
|
||||
@@ -11,7 +11,7 @@ ServiceProcessHost::Observer functions, but we need to pass the exit code to
|
||||
the observer.
|
||||
|
||||
diff --git a/content/browser/service_process_host_impl.cc b/content/browser/service_process_host_impl.cc
|
||||
index f6082bada22c5f4e70af60ea6f555b0f363919c5..f691676a629bf82f81117599ae0bd0a4870c9f61 100644
|
||||
index f6082bada22c5f4e70af60ea6f555b0f363919c5..228f947edbe04bce242df62080052d9c383f1709 100644
|
||||
--- a/content/browser/service_process_host_impl.cc
|
||||
+++ b/content/browser/service_process_host_impl.cc
|
||||
@@ -73,12 +73,15 @@ class ServiceProcessTracker {
|
||||
@@ -33,7 +33,19 @@ index f6082bada22c5f4e70af60ea6f555b0f363919c5..f691676a629bf82f81117599ae0bd0a4
|
||||
processes_.erase(iter);
|
||||
}
|
||||
|
||||
@@ -154,7 +157,7 @@ class UtilityProcessClient : public UtilityProcessHost::Client {
|
||||
@@ -87,6 +90,11 @@ class ServiceProcessTracker {
|
||||
observers_.AddObserver(observer);
|
||||
}
|
||||
|
||||
+ bool HasObserver(ServiceProcessHost::Observer* observer) {
|
||||
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
+ return observers_.HasObserver(observer);
|
||||
+ }
|
||||
+
|
||||
void RemoveObserver(ServiceProcessHost::Observer* observer) {
|
||||
// NOTE: Some tests may remove observers after BrowserThreads are shut down.
|
||||
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
|
||||
@@ -154,7 +162,7 @@ class UtilityProcessClient : public UtilityProcessHost::Client {
|
||||
process_info_->service_process_id());
|
||||
}
|
||||
|
||||
@@ -42,7 +54,7 @@ index f6082bada22c5f4e70af60ea6f555b0f363919c5..f691676a629bf82f81117599ae0bd0a4
|
||||
// TODO(crbug.com/40654042): It is unclear how we can observe
|
||||
// |OnProcessCrashed()| without observing |OnProcessLaunched()| first, but
|
||||
// it can happen on Android. Ignore the notification in this case.
|
||||
@@ -162,7 +165,7 @@ class UtilityProcessClient : public UtilityProcessHost::Client {
|
||||
@@ -162,7 +170,7 @@ class UtilityProcessClient : public UtilityProcessHost::Client {
|
||||
return;
|
||||
|
||||
GetServiceProcessTracker().NotifyCrashed(
|
||||
@@ -51,6 +63,18 @@ index f6082bada22c5f4e70af60ea6f555b0f363919c5..f691676a629bf82f81117599ae0bd0a4
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -232,6 +240,11 @@ void ServiceProcessHost::AddObserver(Observer* observer) {
|
||||
GetServiceProcessTracker().AddObserver(observer);
|
||||
}
|
||||
|
||||
+// static
|
||||
+bool ServiceProcessHost::HasObserver(Observer* observer) {
|
||||
+ return GetServiceProcessTracker().HasObserver(observer);
|
||||
+}
|
||||
+
|
||||
// static
|
||||
void ServiceProcessHost::RemoveObserver(Observer* observer) {
|
||||
GetServiceProcessTracker().RemoveObserver(observer);
|
||||
diff --git a/content/browser/utility_process_host.cc b/content/browser/utility_process_host.cc
|
||||
index 918d1f92476277cd8f463a7aa1ceda008815c1d7..cdebe04babbd9682f97923149261bbe23c9d9701 100644
|
||||
--- a/content/browser/utility_process_host.cc
|
||||
@@ -77,8 +101,23 @@ index c1809298c830b814f886859c2626d6bce7b9ac8c..8d202e7e47c08c33394eb49e87b48225
|
||||
};
|
||||
|
||||
// This class is self-owned. It must be instantiated using new, and shouldn't
|
||||
diff --git a/content/public/browser/service_process_host.h b/content/public/browser/service_process_host.h
|
||||
index 611a52e908f4cb70fbe5628e220a082e45320b70..d7fefab99f86515007aff5f523a423a421850c47 100644
|
||||
--- a/content/public/browser/service_process_host.h
|
||||
+++ b/content/public/browser/service_process_host.h
|
||||
@@ -235,6 +235,10 @@ class CONTENT_EXPORT ServiceProcessHost {
|
||||
// removed before destruction. Must be called from the UI thread only.
|
||||
static void AddObserver(Observer* observer);
|
||||
|
||||
+ // Returns true if the given observer is currently registered.
|
||||
+ // Must be called from the UI thread only.
|
||||
+ static bool HasObserver(Observer* observer);
|
||||
+
|
||||
// Removes a registered observer. This must be called some time before
|
||||
// |*observer| is destroyed and must be called from the UI thread only.
|
||||
static void RemoveObserver(Observer* observer);
|
||||
diff --git a/content/public/browser/service_process_info.h b/content/public/browser/service_process_info.h
|
||||
index 1a8656aef341cd3b23af588fb00569b79d6cd100..6af523eb27a8c1e5529721c029e5b3ba0708b9fc 100644
|
||||
index 1a8656aef341cd3b23af588fb00569b79d6cd100..f904af7ee6bbacf4474e0939855ecf9f2c9a5eaa 100644
|
||||
--- a/content/public/browser/service_process_info.h
|
||||
+++ b/content/public/browser/service_process_info.h
|
||||
@@ -64,7 +64,13 @@ class CONTENT_EXPORT ServiceProcessInfo {
|
||||
@@ -90,7 +129,7 @@ index 1a8656aef341cd3b23af588fb00569b79d6cd100..6af523eb27a8c1e5529721c029e5b3ba
|
||||
+
|
||||
private:
|
||||
+ // The exit code of the process, if it has exited.
|
||||
+ int exit_code_ = 0;
|
||||
+ int exit_code_;
|
||||
+
|
||||
// The name of the service interface for which the process was launched.
|
||||
std::string service_interface_name_;
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Maddock <smaddock@slack-corp.com>
|
||||
Date: Fri, 18 Oct 2024 11:11:11 -0400
|
||||
Subject: fix: software compositing infinite loop
|
||||
|
||||
When GPU compositing is unavailable, LayerTreeView::RequestNewLayerTreeFrameSink
|
||||
may run in an infinite loop due to a race condition. Need to allow time to
|
||||
process CompositingModeFallbackToSoftware IPC to disable GPU compositing.
|
||||
|
||||
https://issues.chromium.org/345275130
|
||||
|
||||
diff --git a/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.cc b/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.cc
|
||||
index 9497ab591864295231db47fdc526e59935e6aa31..635fa41649db41800f99da2683cc955b2e1e935f 100644
|
||||
--- a/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.cc
|
||||
+++ b/third_party/blink/renderer/platform/widget/compositing/layer_tree_view.cc
|
||||
@@ -374,9 +374,13 @@ void LayerTreeView::DidFailToInitializeLayerTreeFrameSink() {
|
||||
// unable to be killed after Chrome is closed.
|
||||
// https://issues.chromium.org/336164423
|
||||
if (!Platform::Current()->IsGpuRemoteDisconnected()) {
|
||||
- layer_tree_host_->GetTaskRunnerProvider()->MainThreadTaskRunner()->PostTask(
|
||||
+ // CompositingModeFallbackToSoftware IPC will disable GPU compositing in
|
||||
+ // RenderThread. Post task with delay to give time to receive this IPC and
|
||||
+ // prevent infinite loop of retries for software renderers.
|
||||
+ // https://issues.chromium.org/345275130
|
||||
+ layer_tree_host_->GetTaskRunnerProvider()->MainThreadTaskRunner()->PostDelayedTask(
|
||||
FROM_HERE, base::BindOnce(&LayerTreeView::RequestNewLayerTreeFrameSink,
|
||||
- weak_factory_.GetWeakPtr()));
|
||||
+ weak_factory_.GetWeakPtr()), base::Milliseconds(10));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: reito <cnschwarzer@qq.com>
|
||||
Date: Thu, 15 Aug 2024 14:05:52 +0800
|
||||
Subject: Remove DXGI GMB keyed-mutex
|
||||
|
||||
This patch removes the keyed mutex of the d3d11 texture only when the texture is requested by offscreen rendering and on Windows.
|
||||
|
||||
The keyed mutex introduce extra performance cost and spikes. However, at offscreen rendering scenario, the shared resources will not be simultaneously read from & written to, typically just one reader, so it doesn't need such exclusive guarantee, and it's safe to remove this mutex for extra performance gain.
|
||||
|
||||
For resolving complex conflict please pin @reitowo
|
||||
For more reason please see: https://crrev.com/c/5465148
|
||||
|
||||
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory_dxgi.cc b/gpu/ipc/service/gpu_memory_buffer_factory_dxgi.cc
|
||||
index 2096591596a26464ab8f71a399ccb16a04edfd59..9eb966b3ddc3551d6beeff123071b2c99a576620 100644
|
||||
--- a/gpu/ipc/service/gpu_memory_buffer_factory_dxgi.cc
|
||||
+++ b/gpu/ipc/service/gpu_memory_buffer_factory_dxgi.cc
|
||||
@@ -179,7 +179,8 @@ gfx::GpuMemoryBufferHandle GpuMemoryBufferFactoryDXGI::CreateGpuMemoryBuffer(
|
||||
// so make sure that the usage is one that we support.
|
||||
DCHECK(usage == gfx::BufferUsage::GPU_READ ||
|
||||
usage == gfx::BufferUsage::SCANOUT ||
|
||||
- usage == gfx::BufferUsage::SCANOUT_CPU_READ_WRITE)
|
||||
+ usage == gfx::BufferUsage::SCANOUT_CPU_READ_WRITE ||
|
||||
+ usage == gfx::BufferUsage::SCANOUT_VEA_CPU_READ)
|
||||
<< "Incorrect usage, usage=" << gfx::BufferUsageToString(usage);
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc = {
|
||||
@@ -193,7 +194,9 @@ gfx::GpuMemoryBufferHandle GpuMemoryBufferFactoryDXGI::CreateGpuMemoryBuffer(
|
||||
D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET,
|
||||
0,
|
||||
D3D11_RESOURCE_MISC_SHARED_NTHANDLE |
|
||||
- D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX};
|
||||
+ static_cast<UINT>(usage == gfx::BufferUsage::SCANOUT_VEA_CPU_READ
|
||||
+ ? D3D11_RESOURCE_MISC_SHARED
|
||||
+ : D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX)};
|
||||
|
||||
Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture;
|
||||
|
||||
diff --git a/media/video/renderable_gpu_memory_buffer_video_frame_pool.cc b/media/video/renderable_gpu_memory_buffer_video_frame_pool.cc
|
||||
index cf5bde2e431fd137ce3501e2a913aa5a3dad5d5b..2f1d64464d76fdbd9af69c8b122e508219d1cced 100644
|
||||
--- a/media/video/renderable_gpu_memory_buffer_video_frame_pool.cc
|
||||
+++ b/media/video/renderable_gpu_memory_buffer_video_frame_pool.cc
|
||||
@@ -205,7 +205,7 @@ gfx::Size GetBufferSizeInPixelsForVideoPixelFormat(
|
||||
bool FrameResources::Initialize() {
|
||||
auto* context = pool_->GetContext();
|
||||
|
||||
- constexpr gfx::BufferUsage kBufferUsage =
|
||||
+ gfx::BufferUsage buffer_usage =
|
||||
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS)
|
||||
gfx::BufferUsage::SCANOUT_VEA_CPU_READ
|
||||
#else
|
||||
@@ -219,6 +219,23 @@ bool FrameResources::Initialize() {
|
||||
const gfx::Size buffer_size_in_pixels =
|
||||
GetBufferSizeInPixelsForVideoPixelFormat(format_, coded_size_);
|
||||
|
||||
+#if BUILDFLAG(IS_WIN)
|
||||
+ // For CEF OSR feature, currently there's no other place in chromium use RGBA.
|
||||
+ // If the format is RGBA, currently CEF do not write to the texture anymore
|
||||
+ // once the GMB is returned from CopyRequest. So there will be no race
|
||||
+ // condition on that texture. We can request a GMB without a keyed mutex to
|
||||
+ // accelerate and probably prevent some driver deadlock.
|
||||
+ if (format_ == PIXEL_FORMAT_ARGB || format_ == PIXEL_FORMAT_ABGR) {
|
||||
+ // This value is 'borrowed', SCANOUT_VEA_CPU_READ is probably invalid
|
||||
+ // cause there's no real SCANOUT on Windows. We simply use this enum as a
|
||||
+ // flag to disable mutex in the GMBFactoryDXGI because this enum is also
|
||||
+ // used above in macOS and CrOS for similar usage (claim no other one will
|
||||
+ // concurrently use the resource).
|
||||
+ // https://chromium-review.googlesource.com/c/chromium/src/+/5302103
|
||||
+ buffer_usage = gfx::BufferUsage::SCANOUT_VEA_CPU_READ;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
// Create the GpuMemoryBuffer if MappableSharedImages is not enabled. When its
|
||||
// enabled, clients only create a mappable shared image directly without
|
||||
// needing to create a GMB.
|
||||
@@ -226,11 +243,11 @@ bool FrameResources::Initialize() {
|
||||
kUseMappableSIForRenderableGpuMemoryBufferVideoFramePool);
|
||||
if (!is_mappable_si_enabled) {
|
||||
gpu_memory_buffer_ = context->CreateGpuMemoryBuffer(
|
||||
- buffer_size_in_pixels, buffer_format, kBufferUsage);
|
||||
+ buffer_size_in_pixels, buffer_format, buffer_usage);
|
||||
if (!gpu_memory_buffer_) {
|
||||
LOG(ERROR) << "Failed to allocate GpuMemoryBuffer for frame: coded_size="
|
||||
<< coded_size_.ToString()
|
||||
- << ", usage=" << static_cast<int>(kBufferUsage);
|
||||
+ << ", usage=" << static_cast<int>(buffer_usage);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -264,7 +281,7 @@ bool FrameResources::Initialize() {
|
||||
|
||||
if (is_mappable_si_enabled) {
|
||||
shared_image_ = context->CreateSharedImage(
|
||||
- buffer_size_in_pixels, kBufferUsage, si_format, color_space_,
|
||||
+ buffer_size_in_pixels, buffer_usage, si_format, color_space_,
|
||||
kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, kSharedImageUsage,
|
||||
sync_token_);
|
||||
} else {
|
||||
@@ -926,23 +926,3 @@ index 7a65f7f2d68edb74fbaf74fe41949ed9cc198b25..4d7c59e93d71b624d4e93e643932c816
|
||||
namespace sandbox::policy {
|
||||
|
||||
base::FilePath GetCanonicalPath(const base::FilePath& path) {
|
||||
diff --git a/ui/gtk/gtk_util.cc b/ui/gtk/gtk_util.cc
|
||||
index d86fbcf969f2fa0d176ead903703ab612e5464c2..6b963ea8401d20e655d068a69105586814bab320 100644
|
||||
--- a/ui/gtk/gtk_util.cc
|
||||
+++ b/ui/gtk/gtk_util.cc
|
||||
@@ -227,9 +227,13 @@ aura::Window* GetAuraTransientParent(GtkWidget* dialog) {
|
||||
}
|
||||
|
||||
void ClearAuraTransientParent(GtkWidget* dialog, aura::Window* parent) {
|
||||
+ if (!parent || !parent->GetHost()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
g_object_set_data(G_OBJECT(dialog), kAuraTransientParent, nullptr);
|
||||
- GtkUi::GetPlatform()->ClearTransientFor(
|
||||
- parent->GetHost()->GetAcceleratedWidget());
|
||||
+ gfx::AcceleratedWidget parent_id = parent->GetHost()->GetAcceleratedWidget();
|
||||
+ GtkUi::GetPlatform()->ClearTransientFor(parent_id);
|
||||
}
|
||||
|
||||
base::OnceClosure DisableHostInputHandling(GtkWidget* dialog,
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Samuel Maddock <smaddock@slack-corp.com>
|
||||
Date: Tue, 12 Nov 2024 17:30:42 -0500
|
||||
Subject: refactor: unfilter unresponsive events
|
||||
|
||||
RendererUnresponsive events are filtered out when
|
||||
* DisableHangMonitor switch is set
|
||||
* WebContents is awaiting a clipboard scan
|
||||
* Any remote debugger is attached
|
||||
* Any local debugger is attached
|
||||
* Visibility state is not visible
|
||||
* Renderer process is not initialized
|
||||
|
||||
This CL removes these filters so the unresponsive event can still be
|
||||
accessed from our JS event. The filtering is moved into Electron's code.
|
||||
|
||||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
|
||||
index ad1f4c8f5dbe0da06955205e5c8a34908c04a0cd..fc720ea3ef4a45da258075f87da239fa9c3b0e82 100644
|
||||
--- a/content/browser/web_contents/web_contents_impl.cc
|
||||
+++ b/content/browser/web_contents/web_contents_impl.cc
|
||||
@@ -9410,29 +9410,17 @@ void WebContentsImpl::RendererUnresponsive(
|
||||
base::RepeatingClosure hang_monitor_restarter) {
|
||||
OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RendererUnresponsive",
|
||||
"render_widget_host", render_widget_host);
|
||||
- if (ShouldIgnoreUnresponsiveRenderer()) {
|
||||
+ if (IsBeingDestroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool visible = GetVisibility() == Visibility::VISIBLE;
|
||||
base::UmaHistogramBoolean("Renderer.Unresponsive.Visibility", visible);
|
||||
|
||||
- // Do not report hangs (to task manager, to hang renderer dialog, etc.) for
|
||||
- // invisible tabs (like extension background page, background tabs). See
|
||||
- // https://crbug.com/881812 for rationale and for choosing the visibility
|
||||
- // (rather than process priority) as the signal here.
|
||||
- if (!visible) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
base::UmaHistogramBoolean(
|
||||
"Renderer.Unresponsive.PageVisible.WidgetVisibility",
|
||||
!render_widget_host->is_hidden());
|
||||
|
||||
- if (!render_widget_host->renderer_initialized()) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
CrashRepHandlingOutcome outcome =
|
||||
base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
switches::kNoErrorDialogs)
|
||||
@@ -1,47 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Thu, 21 Nov 2024 14:23:17 +0100
|
||||
Subject: Support BSTR PKEY_AppUserModel_ID in Windows Shortcuts
|
||||
|
||||
It's possible for a shortcut link on Windows to be BSTR format;
|
||||
this resulted in a DCHECK previously but as of the NOTREACHED
|
||||
fatal migration now will crash a given app. This has created an
|
||||
issue for Electron, which allows providing the shortcut information
|
||||
to end users. This CL thus allows for supporting VT_BSTR variants
|
||||
for PKEY_AppUserModel_ID and mitigates a crash. One such example
|
||||
is https://github.com/wez/wezterm, which after this change
|
||||
correctly gets an appUserModelId of 'org.wezfurlong.wezterm'.
|
||||
|
||||
Bug: N/A
|
||||
Change-Id: I5ad114bc345059637465b68a53a2f3f8c42de898
|
||||
|
||||
diff --git a/base/win/shortcut.cc b/base/win/shortcut.cc
|
||||
index d4a54d1afdc121192f9c0321c6ced584ee066486..02f3e63d16c3324f546f6155d722900f0a81131a 100644
|
||||
--- a/base/win/shortcut.cc
|
||||
+++ b/base/win/shortcut.cc
|
||||
@@ -289,14 +289,22 @@ bool ResolveShortcutProperties(const FilePath& shortcut_path,
|
||||
return false;
|
||||
}
|
||||
switch (pv_app_id.get().vt) {
|
||||
- case VT_EMPTY:
|
||||
+ case VT_EMPTY: {
|
||||
properties->set_app_id(std::wstring());
|
||||
break;
|
||||
- case VT_LPWSTR:
|
||||
+ }
|
||||
+ case VT_LPWSTR: {
|
||||
properties->set_app_id(pv_app_id.get().pwszVal);
|
||||
break;
|
||||
- default:
|
||||
+ }
|
||||
+ case VT_BSTR: {
|
||||
+ BSTR bs = pv_app_id.get().bstrVal;
|
||||
+ properties->set_app_id(std::wstring(bs, ::SysStringLen(bs)));
|
||||
+ break;
|
||||
+ }
|
||||
+ default: {
|
||||
NOTREACHED() << "Unexpected variant type: " << pv_app_id.get().vt;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: deepak1556 <hop2deep@gmail.com>
|
||||
Date: Tue, 22 Oct 2024 00:27:27 +0900
|
||||
Subject: Add missing shortcut text for VKEY_COMMAND on linux
|
||||
|
||||
Backports https://chromium-review.googlesource.com/c/chromium/src/+/5947724
|
||||
|
||||
diff --git a/ui/base/accelerators/accelerator.cc b/ui/base/accelerators/accelerator.cc
|
||||
index 32a3fc0843656eaa87b85dd63ac1ade6d83b6e5b..ed1ff076b1db6b77d0684bae1931714bf575ebe8 100644
|
||||
--- a/ui/base/accelerators/accelerator.cc
|
||||
+++ b/ui/base/accelerators/accelerator.cc
|
||||
@@ -419,6 +419,8 @@ std::u16string Accelerator::ApplyLongFormModifiers(
|
||||
result = ApplyModifierToAcceleratorString(result, IDS_APP_SEARCH_KEY);
|
||||
#elif BUILDFLAG(IS_WIN)
|
||||
result = ApplyModifierToAcceleratorString(result, IDS_APP_WINDOWS_KEY);
|
||||
+#elif BUILDFLAG(IS_LINUX)
|
||||
+ result = ApplyModifierToAcceleratorString(result, IDS_APP_SUPER_KEY);
|
||||
#else
|
||||
NOTREACHED();
|
||||
#endif
|
||||
diff --git a/ui/base/accelerators/accelerator_unittest.cc b/ui/base/accelerators/accelerator_unittest.cc
|
||||
index 246cfe906786c1586e15acbae063a77cb5cc84e7..7627da94c48473870b127b57edad2a2845d76d4c 100644
|
||||
--- a/ui/base/accelerators/accelerator_unittest.cc
|
||||
+++ b/ui/base/accelerators/accelerator_unittest.cc
|
||||
@@ -58,6 +58,9 @@ TEST(AcceleratorTest, MAYBE_GetShortcutText) {
|
||||
{VKEY_OEM_COMMA, EF_CONTROL_DOWN, u"Ctrl+Comma", u"⌃,"},
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
{VKEY_T, EF_COMMAND_DOWN | EF_CONTROL_DOWN, nullptr, u"⌃⌘T"},
|
||||
+#endif
|
||||
+#if BUILDFLAG(IS_LINUX)
|
||||
+ {VKEY_T, EF_COMMAND_DOWN | EF_CONTROL_DOWN, u"Super+Ctrl+T", nullptr},
|
||||
#endif
|
||||
};
|
||||
|
||||
diff --git a/ui/strings/ui_strings.grd b/ui/strings/ui_strings.grd
|
||||
index c7e58d4820443f3af9b494259e160ad27b9dbfdd..8937506c5594404c916d3a73907c883bc86198e7 100644
|
||||
--- a/ui/strings/ui_strings.grd
|
||||
+++ b/ui/strings/ui_strings.grd
|
||||
@@ -764,6 +764,11 @@ need to be translated for each locale.-->
|
||||
Win
|
||||
</message>
|
||||
</if>
|
||||
+ <if expr="is_linux">
|
||||
+ <message name="IDS_APP_SUPER_KEY" desc="Windows key on Windows keyboards, and Command key on Mac keyboards.">
|
||||
+ Super
|
||||
+ </message>
|
||||
+ </if>
|
||||
<if expr="chromeos_ash">
|
||||
<message name="IDS_APP_META_KEY" desc="External Meta key (Search key on ChromeOS keyboards, Windows key on Windows keyboards, and Command key on Mac keyboards)">
|
||||
Meta
|
||||
@@ -1,97 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Diego Yamane <nickdiego@igalia.com>
|
||||
Date: Thu, 7 Nov 2024 23:11:14 +0000
|
||||
Subject: wayland: support outgoing dnd sessions with no offered mime types
|
||||
|
||||
Even though the Wayland spec says that dnd sessions with no accepted
|
||||
mime type should always end as cancelled [1], W3C's counterpart does not
|
||||
enforce such behavior [2]. In order to ensure compatibility for web
|
||||
apps already relying on such behavior, this CL uses a placeholder mime
|
||||
type to make it possible for outgoing drag-and-drop sessions with empty
|
||||
mime types list (not set by the application) to end successfully.
|
||||
|
||||
The minimal sample at [3] was used to validate it, in addition to
|
||||
vscode.dev web app, by rearranging its left-side bar action items. Refer
|
||||
to linked crbug and comments at [4] for further repro steps and
|
||||
expectations.
|
||||
|
||||
[1] https://wayland.app/protocols/wayland#wl_data_offer:request:accept.
|
||||
[2] https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#drag_data
|
||||
[3] https://people.igalia.com/nickdiego/samples/dnd-empty-drag-data/
|
||||
[4] https://github.com/microsoft/vscode/issues/156723#issuecomment-2460617294
|
||||
|
||||
R=orko@igalia.com, thomasanderson
|
||||
|
||||
Bug: 377760837
|
||||
Test: Manually, by rearranging left side bar items of https://vscode.dev and the minimal sample at [3].
|
||||
Change-Id: I3fd5dd2ab9a9f3482334371af35bde554fd3d1a3
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6000277
|
||||
Commit-Queue: Nick Yamane <nickdiego@igalia.com>
|
||||
Reviewed-by: Orko Garai <orko@igalia.com>
|
||||
Cr-Commit-Position: refs/heads/main@{#1380008}
|
||||
|
||||
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
|
||||
index 3d63985300269fb33707ead548665d5e99ebdbf3..22cb6406bc4f667b949c23690bedf1f59d988faa 100644
|
||||
--- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
|
||||
+++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
|
||||
@@ -54,6 +54,16 @@ namespace {
|
||||
using mojom::DragEventSource;
|
||||
using mojom::DragOperation;
|
||||
|
||||
+// Used for compatibility between W3C and Wayland drag-and-drop specifications.
|
||||
+// Since wl_data_offer version >= 3, Wayland dnd sessions with no accepted mime
|
||||
+// type always end as cancelled. W3C drag-and-drop spec on the other hand does
|
||||
+// not require drag data to be set in order to proceed with drop and drag-end
|
||||
+// events. Thus, the special mime type below is used to ensure such behavior is
|
||||
+// supported by the Wayland backend. Further context can be found at
|
||||
+// https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API and
|
||||
+// https://wayland.app/protocols/wayland#wl_data_offer:request:accept.
|
||||
+constexpr char kMimeTypeEmptyDragData[] = "chromium/x-empty-drag-data";
|
||||
+
|
||||
DragOperation DndActionToDragOperation(uint32_t action) {
|
||||
// Prevent the usage of this function for an operation mask.
|
||||
DCHECK_LE(std::bitset<32>(action).count(), 1u);
|
||||
@@ -158,9 +168,17 @@ bool WaylandDataDragController::StartSession(const OSExchangeData& data,
|
||||
<< ", serial tracker=" << connection_->serial_tracker().ToString();
|
||||
|
||||
// Create new data source and offers |data|.
|
||||
- SetOfferedExchangeDataProvider(data);
|
||||
+ offered_exchange_data_provider_ = data.provider().Clone();
|
||||
+ auto mime_types = GetOfferedExchangeDataProvider()->BuildMimeTypesList();
|
||||
+ if (mime_types.empty()) {
|
||||
+ // Add placeholder mime type to ensure the drag-and-drop session can end
|
||||
+ // successfully, even if no drag data was set by the application. See
|
||||
+ // `kMimeTypeEmptyDragData` declaration for more details.
|
||||
+ mime_types.push_back(kMimeTypeEmptyDragData);
|
||||
+ }
|
||||
+
|
||||
data_source_ = data_device_manager_->CreateSource(this);
|
||||
- data_source_->Offer(GetOfferedExchangeDataProvider()->BuildMimeTypesList());
|
||||
+ data_source_->Offer(mime_types);
|
||||
data_source_->SetDndActions(DragOperationsToDndActions(operations));
|
||||
|
||||
// Create drag icon surface (if any) and store the data to be exchanged.
|
||||
@@ -788,11 +806,6 @@ WaylandDataDragController::GetAndValidateSerialForDrag(DragEventSource source) {
|
||||
: std::nullopt;
|
||||
}
|
||||
|
||||
-void WaylandDataDragController::SetOfferedExchangeDataProvider(
|
||||
- const OSExchangeData& data) {
|
||||
- offered_exchange_data_provider_ = data.provider().Clone();
|
||||
-}
|
||||
-
|
||||
const WaylandExchangeDataProvider*
|
||||
WaylandDataDragController::GetOfferedExchangeDataProvider() const {
|
||||
DCHECK(offered_exchange_data_provider_);
|
||||
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h
|
||||
index fd64adeeec3a715c278957e1ef934a8e53d07953..a7453424c0e3de7c62b912c4bce86156914d93f3 100644
|
||||
--- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h
|
||||
+++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h
|
||||
@@ -216,7 +216,6 @@ class WaylandDataDragController : public WaylandDataDevice::DragDelegate,
|
||||
std::optional<wl::Serial> GetAndValidateSerialForDrag(
|
||||
mojom::DragEventSource source);
|
||||
|
||||
- void SetOfferedExchangeDataProvider(const OSExchangeData& data);
|
||||
const WaylandExchangeDataProvider* GetOfferedExchangeDataProvider() const;
|
||||
|
||||
// Checks whether |data| holds information about a window dragging session.
|
||||
@@ -1268,10 +1268,10 @@ index 0000000000000000000000000000000000000000..af9cbada10203b387fb9732b346583b1
|
||||
+}
|
||||
diff --git a/filenames.json b/filenames.json
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..c429d4cbfff605ff78c7c8ee3c5ad046594163f3
|
||||
index 0000000000000000000000000000000000000000..889a487e24721a8ecfef91f5a655892a607bb12f
|
||||
--- /dev/null
|
||||
+++ b/filenames.json
|
||||
@@ -0,0 +1,740 @@
|
||||
@@ -0,0 +1,741 @@
|
||||
+// This file is automatically generated by generate_gn_filenames_json.py
|
||||
+// DO NOT EDIT
|
||||
+{
|
||||
@@ -1550,6 +1550,7 @@ index 0000000000000000000000000000000000000000..c429d4cbfff605ff78c7c8ee3c5ad046
|
||||
+ "lib/internal/http2/compat.js",
|
||||
+ "lib/internal/http2/core.js",
|
||||
+ "lib/internal/http2/util.js",
|
||||
+ "lib/internal/idna.js",
|
||||
+ "lib/internal/inspector_async_hook.js",
|
||||
+ "lib/internal/inspector_network_tracking.js",
|
||||
+ "lib/internal/js_stream_socket.js",
|
||||
|
||||
@@ -40,7 +40,7 @@ index 697b8bba6a55358924d6986f2eb347a99ff73889..bdf1a1f33f3ea09d933757c7fee87c56
|
||||
# list in v8/BUILD.gn.
|
||||
['v8_enable_v8_checks == 1', {
|
||||
diff --git a/configure.py b/configure.py
|
||||
index 0d089c35d1720e05c4c61d0226a2ebc276b65d6e..cf19b9d092698e1697508e8891926947bc2f7b12 100755
|
||||
index a6f66c41f75bffcfaf75d4415c694300b7624136..7ca0762fe3590fef7b88ba684de44d99aaecace4 100755
|
||||
--- a/configure.py
|
||||
+++ b/configure.py
|
||||
@@ -1585,6 +1585,7 @@ def configure_library(lib, output, pkgname=None):
|
||||
|
||||
@@ -26,7 +26,7 @@ index 364469160af5e348f8890417de16a63c0d1dca67..75d5f58fe02fa8cfa7716ffaf761d567
|
||||
try {
|
||||
resolvedArgv = Module._resolveFilename(process.argv[1], null, false);
|
||||
diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js
|
||||
index a05d2846050c2f505eac16320f645e79182a27f6..348bb80ef7fae1e0e5f529b1313093eeadad9276 100644
|
||||
index ea7afd52fab1cf3fde1674be1429a00562b714c0..02cfc8b3328fedb6306abf6c738bea772c674458 100644
|
||||
--- a/lib/internal/process/pre_execution.js
|
||||
+++ b/lib/internal/process/pre_execution.js
|
||||
@@ -247,12 +247,14 @@ function patchProcessObject(expandArgv1) {
|
||||
|
||||
@@ -9,7 +9,7 @@ This patch can be removed when Node.js upgrades to a version of V8 containing
|
||||
the above CL.
|
||||
|
||||
diff --git a/lib/.eslintrc.yaml b/lib/.eslintrc.yaml
|
||||
index c028204481d44cb5f35ad98413022e7b07ce04b2..230c2378996c5d1ec18a9183ef138bbf70bba22d 100644
|
||||
index 74e867ace6207751a96b4da03802b50b620dbd7b..53ceabeb58f56ebd27e60fd49c362d26e361e6d8 100644
|
||||
--- a/lib/.eslintrc.yaml
|
||||
+++ b/lib/.eslintrc.yaml
|
||||
@@ -30,10 +30,6 @@ rules:
|
||||
@@ -24,10 +24,10 @@ index c028204481d44cb5f35ad98413022e7b07ce04b2..230c2378996c5d1ec18a9183ef138bbf
|
||||
message: Use `const { Blob } = require('buffer');` instead of the global.
|
||||
- name: BroadcastChannel
|
||||
diff --git a/lib/internal/main/worker_thread.js b/lib/internal/main/worker_thread.js
|
||||
index cfd1d1b6f18e2943e155cf021b566a4673f71ab0..8d1a184ad1936c0d8493d6c54c32bebcf0021d8b 100644
|
||||
index 30f7a5f79e50fdeb4e1775a0e56dafa4c6908898..f7250985277c4127425ef36dff566c1fe06603e2 100644
|
||||
--- a/lib/internal/main/worker_thread.js
|
||||
+++ b/lib/internal/main/worker_thread.js
|
||||
@@ -113,7 +113,7 @@ port.on('message', (message) => {
|
||||
@@ -112,7 +112,7 @@ port.on('message', (message) => {
|
||||
|
||||
require('internal/worker').assignEnvironmentData(environmentData);
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@ index 606a6f5caa3b11b6d2a9068ed2fd65800530a5eb..080dcce21da05ccea398d8a856deb397
|
||||
typedef void (*FreeCallback)(char* data, void* hint);
|
||||
|
||||
diff --git a/src/node_errors.h b/src/node_errors.h
|
||||
index ac07b96b5cad0f3502468c86745e2b341d338e1f..f51c4309ceec3f0dc5e07982fb789ff6663076ba 100644
|
||||
index 1662491bac44311421eeb7ee35bb47c025162abf..a62b18e832986ee38d93b412b36020a2c22255a9 100644
|
||||
--- a/src/node_errors.h
|
||||
+++ b/src/node_errors.h
|
||||
@@ -235,7 +235,7 @@ inline v8::Local<v8::Object> ERR_BUFFER_TOO_LARGE(v8::Isolate* isolate) {
|
||||
@@ -230,7 +230,7 @@ inline v8::Local<v8::Object> ERR_BUFFER_TOO_LARGE(v8::Isolate* isolate) {
|
||||
char message[128];
|
||||
snprintf(message, sizeof(message),
|
||||
"Cannot create a Buffer larger than 0x%zx bytes",
|
||||
|
||||
@@ -8,7 +8,7 @@ to child processes spawned with `ELECTRON_RUN_AS_NODE` which is used
|
||||
by the crashpad client to connect with the handler process.
|
||||
|
||||
diff --git a/lib/child_process.js b/lib/child_process.js
|
||||
index cc81cb373d59dbc1ab18182aa2a0c8ebe63f6245..d3871405e2ecb3917b8ec816490c575891c91d18 100644
|
||||
index 48870b35ad0f3411f2d509b12d92a9e0d20046f9..e7ef454d2d71207ae7b2788a437b82bf7732716e 100644
|
||||
--- a/lib/child_process.js
|
||||
+++ b/lib/child_process.js
|
||||
@@ -61,6 +61,7 @@ let debug = require('internal/util/debuglog').debuglog(
|
||||
|
||||
@@ -58,7 +58,7 @@ index b9098d102b40adad7fafcc331ac62870617019b9..cb9269a31e073caf86164aa39c064037
|
||||
}
|
||||
|
||||
diff --git a/src/node_options.cc b/src/node_options.cc
|
||||
index efbe48e10b8408642a6b5010b1a7a3749068188a..9b5f49ebb478a21acf8f0d6ed012ed6829a8a320 100644
|
||||
index 818baf611fcab7838a339f3ea137467653e270d0..4e3c82e9528b04fd1a0cc99d30fb885e4b224bc9 100644
|
||||
--- a/src/node_options.cc
|
||||
+++ b/src/node_options.cc
|
||||
@@ -1405,14 +1405,16 @@ void GetEmbedderOptions(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
@@ -33,7 +33,7 @@ index f3dfc69cd2cdec50bc3b3f7cb2d63349812d87dd..b6f2d7194cb75ecc8c47869761c63184
|
||||
if (!loaded) {
|
||||
module = new CJSModule(filename);
|
||||
diff --git a/lib/internal/modules/run_main.js b/lib/internal/modules/run_main.js
|
||||
index 4ad694debfc72f56dd98a4e56dd0bbc63711242e..73f0e00ad34132e7d2fd37ec321110881e89617f 100644
|
||||
index ca401044c0178c46db9b439b27c440a5d7924c84..dc1a682f0a3cf1ba1095c60bf6a6ca992d6043b3 100644
|
||||
--- a/lib/internal/modules/run_main.js
|
||||
+++ b/lib/internal/modules/run_main.js
|
||||
@@ -2,6 +2,7 @@
|
||||
@@ -58,7 +58,7 @@ index 4ad694debfc72f56dd98a4e56dd0bbc63711242e..73f0e00ad34132e7d2fd37ec32111088
|
||||
const defaultType = getOptionValue('--experimental-default-type');
|
||||
/** @type {string} */
|
||||
let mainPath;
|
||||
@@ -58,6 +66,13 @@ function resolveMainPath(main) {
|
||||
@@ -59,6 +67,13 @@ function resolveMainPath(main) {
|
||||
* @param {string} mainPath - Absolute path to the main entry point
|
||||
*/
|
||||
function shouldUseESMLoader(mainPath) {
|
||||
|
||||
@@ -353,7 +353,7 @@ index 990638ec3993bde40ad3dd40d373d816ebc66a6a..63d971e1fe6b861e29c12f04563701b0
|
||||
} // namespace
|
||||
|
||||
diff --git a/src/env.h b/src/env.h
|
||||
index 2ec0a56e05ff879df8c55bf140677e571a56fafa..a30c25a3a61dfe73944731760404c555f2782d72 100644
|
||||
index 30561ab7a24c734be71ed29d963c11e2ea2c2b22..7cb77fb4f35a60fbda5b868798321ac8b6340bfa 100644
|
||||
--- a/src/env.h
|
||||
+++ b/src/env.h
|
||||
@@ -49,7 +49,7 @@
|
||||
@@ -365,7 +365,7 @@ index 2ec0a56e05ff879df8c55bf140677e571a56fafa..a30c25a3a61dfe73944731760404c555
|
||||
#include <openssl/evp.h>
|
||||
#endif
|
||||
|
||||
@@ -1051,7 +1051,7 @@ class Environment : public MemoryRetainer {
|
||||
@@ -1065,7 +1065,7 @@ class Environment : public MemoryRetainer {
|
||||
kExitInfoFieldCount
|
||||
};
|
||||
|
||||
@@ -388,7 +388,7 @@ index cf051585e779e2b03bd7b95fe5008b89cc7f8162..9de49c6828468fdf846dcd4ad445390f
|
||||
#if NODE_OPENSSL_HAS_QUIC
|
||||
#include <openssl/quic.h>
|
||||
diff --git a/src/node_options.cc b/src/node_options.cc
|
||||
index e325b082dec6ae891a737a4fa7775937e4d7b7f9..efbe48e10b8408642a6b5010b1a7a3749068188a 100644
|
||||
index dba59c5560c22899bd108789360f21fd85dd41bf..818baf611fcab7838a339f3ea137467653e270d0 100644
|
||||
--- a/src/node_options.cc
|
||||
+++ b/src/node_options.cc
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
@@ -16,7 +16,7 @@ patch:
|
||||
(cherry picked from commit 30329d06235a9f9733b1d4da479b403462d1b326)
|
||||
|
||||
diff --git a/src/env-inl.h b/src/env-inl.h
|
||||
index 852c82fd7f50c01d08eeddc151b1bec6afa68028..8f4b004d6655acd1c0dac449612316a48cf885c6 100644
|
||||
index d98a32d6ec311459877bc3b0de33cca4766aeda7..9fc934975b015b97ddd84bf3eea5d53144130035 100644
|
||||
--- a/src/env-inl.h
|
||||
+++ b/src/env-inl.h
|
||||
@@ -62,31 +62,6 @@ inline uv_loop_t* IsolateData::event_loop() const {
|
||||
@@ -52,7 +52,7 @@ index 852c82fd7f50c01d08eeddc151b1bec6afa68028..8f4b004d6655acd1c0dac449612316a4
|
||||
return &(wrapper_data_->cppgc_id);
|
||||
}
|
||||
diff --git a/src/env.cc b/src/env.cc
|
||||
index ca75e0360bbf6a20ea18e67dda167d5ec523b075..158b96a9b1ea5553fa74d2429152a5c974d50c03 100644
|
||||
index 38802b1e9acf9b3e99fdc4f39770e896393befe3..e0433e29ca98c42a38d1da6d66085fdea1edde29 100644
|
||||
--- a/src/env.cc
|
||||
+++ b/src/env.cc
|
||||
@@ -22,6 +22,7 @@
|
||||
@@ -146,7 +146,7 @@ index ca75e0360bbf6a20ea18e67dda167d5ec523b075..158b96a9b1ea5553fa74d2429152a5c9
|
||||
|
||||
void IsolateData::MemoryInfo(MemoryTracker* tracker) const {
|
||||
diff --git a/src/env.h b/src/env.h
|
||||
index a30c25a3a61dfe73944731760404c555f2782d72..6137551bb8168d8fa9a3e6bc79c3d1e79b306931 100644
|
||||
index 7cb77fb4f35a60fbda5b868798321ac8b6340bfa..06746554e1d60a9377ff6d7d970220f3fa88e4ac 100644
|
||||
--- a/src/env.h
|
||||
+++ b/src/env.h
|
||||
@@ -174,10 +174,6 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer {
|
||||
|
||||
@@ -298,17 +298,3 @@ index 9787b14352753c5e0f8dc2b90093680e7cd10f1a..31af9e62396368af1b81f8841a705fd3
|
||||
auto ab = ArrayBuffer::New(isolate, std::move(bs));
|
||||
v8::Local<Uint8Array> u8 = v8::Uint8Array::New(ab, 0, 1);
|
||||
|
||||
diff --git a/test/parallel/test-buffer-tostring-range.js b/test/parallel/test-buffer-tostring-range.js
|
||||
index 1167654dcf0773be953d09dfcf534e902e75595b..a769ec1fb61916d4285fa9d3559ded5df4f02e9e 100644
|
||||
--- a/test/parallel/test-buffer-tostring-range.js
|
||||
+++ b/test/parallel/test-buffer-tostring-range.js
|
||||
@@ -103,6 +103,8 @@ assert.throws(() => {
|
||||
// Cannot test on 32bit machine as we are testing the case
|
||||
// when start and end are above the threshold
|
||||
common.skipIf32Bits();
|
||||
+/* Disabled due to incompatiblity with v8 memory cage
|
||||
const threshold = 0xFFFFFFFF;
|
||||
const largeBuffer = Buffer.alloc(threshold);
|
||||
largeBuffer.toString('utf8', threshold + 0xF, threshold + 0xFF);
|
||||
+*/
|
||||
\ No newline at end of file
|
||||
|
||||
@@ -28,7 +28,7 @@ index 79a953df7da64b7d7580e099a5cc5160e7842999..94616df356cab50c8ef4099e7863f598
|
||||
test-net-write-fully-async-hex-string: PASS, FLAKY
|
||||
# https://github.com/nodejs/node/issues/52273
|
||||
diff --git a/test/sequential/sequential.status b/test/sequential/sequential.status
|
||||
index 073b29cce8dbca4c8d92ad666f9244ad511296db..338d20263f29a630febb96567f3cb708623bd09a 100644
|
||||
index a539649d5537376a6a2ac9a7a46051b8648f0cb1..a03c86b752772be7ae36fab31faeccf3b0ccff64 100644
|
||||
--- a/test/sequential/sequential.status
|
||||
+++ b/test/sequential/sequential.status
|
||||
@@ -7,6 +7,18 @@ prefix sequential
|
||||
|
||||
@@ -7,10 +7,10 @@ Subject: test: match wpt/streams/transferable/transform-stream-members.any.js
|
||||
All four of this calls should fail - see third_party/blink/web_tests/external/wpt/streams/transferable/transform-stream-members.any-expected.txt
|
||||
|
||||
diff --git a/test/wpt/status/streams.json b/test/wpt/status/streams.json
|
||||
index af3646c65ea6609e17638da925f86de8c9d6221c..f1d9e76718c264aafb9c27c516589d9874d8b73f 100644
|
||||
index 5425c86bba85079a44745779d998337aaa063df1..775661cd59b14132c9a811e448792ea02198f949 100644
|
||||
--- a/test/wpt/status/streams.json
|
||||
+++ b/test/wpt/status/streams.json
|
||||
@@ -53,7 +53,9 @@
|
||||
@@ -60,7 +60,9 @@
|
||||
"fail": {
|
||||
"expected": [
|
||||
"Transferring [object TransformStream],[object ReadableStream] should fail",
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
const chalk = require('chalk');
|
||||
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
@@ -19,29 +17,6 @@ function findAllHeaders (basePath) {
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
const diff = (array1, array2) => {
|
||||
const set1 = new Set(array1);
|
||||
const set2 = new Set(array2);
|
||||
|
||||
const added = array1.filter(item => !set2.has(item));
|
||||
const removed = array2.filter(item => !set1.has(item));
|
||||
|
||||
console.log(chalk.white.bgGreen.bold('Files Added:'));
|
||||
added.forEach(item => console.log(chalk.green.bold(`+ ${item}`)));
|
||||
|
||||
console.log(chalk.white.bgRed.bold('Files Removed:'));
|
||||
removed.forEach(item => console.log(chalk.red.bold(`- ${item}`)));
|
||||
};
|
||||
|
||||
const parseHeaders = (name, content) => {
|
||||
const pattern = new RegExp(`${name}_headers\\s*=\\s*\\[(.*?)\\]`, 's');
|
||||
const headers = content.match(pattern);
|
||||
if (!headers) return [];
|
||||
return headers[1].split(',')
|
||||
.map(item => item.trim().replace(/"/g, ''))
|
||||
.filter(item => item.length > 0);
|
||||
};
|
||||
|
||||
for (const folder of ['libc++', 'libc++abi']) {
|
||||
const prettyName = folder.replace(/\+/g, 'x');
|
||||
|
||||
@@ -50,26 +25,21 @@ for (const folder of ['libc++', 'libc++abi']) {
|
||||
|
||||
const headers = findAllHeaders(libcxxIncludeDir).map(absPath => path.relative(path.resolve(__dirname, '../..', gclientPath), absPath));
|
||||
|
||||
const newHeaders = headers.map(f => `//${path.posix.join(gclientPath, f)}`);
|
||||
const content = `${prettyName}_headers = [
|
||||
${newHeaders.map(h => `"${h}"`).join(',\n ')},
|
||||
${headers.map(f => `"//${path.posix.join(gclientPath, f)}"`).join(',\n ')},
|
||||
]
|
||||
|
||||
${prettyName}_licenses = [ "//third_party/${folder}/src/LICENSE.TXT" ]
|
||||
`;
|
||||
|
||||
const file = `filenames.${prettyName}.gni`;
|
||||
const filenamesPath = path.resolve(__dirname, '..', file);
|
||||
const filenamesPath = path.resolve(__dirname, '..', `filenames.${prettyName}.gni`);
|
||||
|
||||
if (check) {
|
||||
const currentContent = fs.readFileSync(filenamesPath, 'utf8');
|
||||
if (currentContent !== content) {
|
||||
const currentHeaders = parseHeaders(prettyName, currentContent);
|
||||
|
||||
console.error(chalk.bold(`${file} contents are not up to date:\n`));
|
||||
diff(currentHeaders, newHeaders);
|
||||
console.error(chalk.bold(`\nRun node gen-libc++-filenames.js to regenerate ${file}`));
|
||||
process.exit(1);
|
||||
console.log('currentContent: ', currentContent);
|
||||
console.log('content: ', content);
|
||||
throw new Error(`${prettyName} filenames need to be regenerated, latest generation does not match current file. Please run node gen-libc++-filenames.js`);
|
||||
}
|
||||
} else {
|
||||
console.log(filenamesPath);
|
||||
|
||||
@@ -6,6 +6,7 @@ import pprint
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from lib.config import get_target_arch
|
||||
|
||||
ELECTRON_DIR = os.path.abspath(os.path.join(__file__, '..', '..'))
|
||||
NODE_DIR = os.path.join(ELECTRON_DIR, '..', 'third_party', 'electron_node')
|
||||
@@ -39,8 +40,8 @@ def read_electron_args():
|
||||
for line in file_in:
|
||||
if line.startswith('#'):
|
||||
continue
|
||||
m = re.match(r'(\w+) = (.+)', line)
|
||||
if m is None:
|
||||
m = re.match('(\w+) = (.+)', line)
|
||||
if m == None:
|
||||
continue
|
||||
args[m.group(1)] = m.group(2)
|
||||
return args
|
||||
|
||||
@@ -28,17 +28,16 @@ def get_target_arch():
|
||||
return 'x64'
|
||||
return arch
|
||||
|
||||
def set_verbose_mode(mode):
|
||||
|
||||
def enable_verbose_mode():
|
||||
print('Running in verbose mode')
|
||||
global verbose_mode
|
||||
verbose_mode = mode
|
||||
verbose_mode = True
|
||||
|
||||
|
||||
def is_verbose_mode():
|
||||
return verbose_mode
|
||||
|
||||
def verbose_mode_print(output):
|
||||
if verbose_mode:
|
||||
print(output)
|
||||
|
||||
def get_zip_name(name, version, suffix=''):
|
||||
arch = get_target_arch()
|
||||
|
||||
@@ -11,7 +11,9 @@ import sys
|
||||
from urllib.request import urlopen
|
||||
import zipfile
|
||||
|
||||
from lib.config import verbose_mode_print
|
||||
# from lib.config import is_verbose_mode
|
||||
def is_verbose_mode():
|
||||
return False
|
||||
|
||||
ELECTRON_DIR = os.path.abspath(
|
||||
os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
|
||||
@@ -110,11 +112,13 @@ def safe_mkdir(path):
|
||||
def execute(argv, env=None, cwd=None):
|
||||
if env is None:
|
||||
env = os.environ
|
||||
verbose_mode_print(' '.join(argv))
|
||||
if is_verbose_mode():
|
||||
print(' '.join(argv))
|
||||
try:
|
||||
output = subprocess.check_output(argv, stderr=subprocess.STDOUT,
|
||||
env=env, cwd=cwd)
|
||||
verbose_mode_print(output.decode('utf-8').strip())
|
||||
if is_verbose_mode():
|
||||
print(output)
|
||||
return output
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(e.output)
|
||||
|
||||
@@ -205,6 +205,17 @@ async function tagRelease (version: string) {
|
||||
}
|
||||
}
|
||||
|
||||
// function to determine if there have been commits to main since the last release
|
||||
async function changesToRelease () {
|
||||
const lastCommitWasRelease =
|
||||
/^Bump v[0-9]+.[0-9]+.[0-9]+(-beta.[0-9]+)?(-alpha.[0-9]+)?(-nightly.[0-9]+)?$/g;
|
||||
const lastCommit = await GitProcess.exec(
|
||||
['log', '-n', '1', "--pretty=format:'%s'"],
|
||||
ELECTRON_DIR
|
||||
);
|
||||
return !lastCommitWasRelease.test(lastCommit.stdout);
|
||||
}
|
||||
|
||||
export async function printNextVersion (options: PrepareReleaseOptions) {
|
||||
const newVersion = await getNewVersion(options, DryRunMode.DRY_RUN);
|
||||
console.log(newVersion);
|
||||
@@ -214,9 +225,17 @@ export async function prepareRelease (options: PrepareReleaseOptions) {
|
||||
const currentBranch =
|
||||
options.targetBranch || (await getCurrentBranch(ELECTRON_DIR));
|
||||
|
||||
const newVersion = await getNewVersion(options, DryRunMode.DRY_RUN);
|
||||
console.log(`${pass} Starting release of ${newVersion}`);
|
||||
await createRelease(options, currentBranch);
|
||||
await pushRelease(currentBranch);
|
||||
await runReleaseBuilds(currentBranch, newVersion);
|
||||
const changes = await changesToRelease();
|
||||
if (changes) {
|
||||
const newVersion = await getNewVersion(options, DryRunMode.DRY_RUN);
|
||||
console.log(`${pass} Starting release of ${newVersion}`);
|
||||
await createRelease(options, currentBranch);
|
||||
await pushRelease(currentBranch);
|
||||
await runReleaseBuilds(currentBranch, newVersion);
|
||||
} else {
|
||||
console.log(
|
||||
'There are no new changes to this branch since the last release, aborting release.'
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user