mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
Compare commits
1 Commits
cherry-pic
...
revert-dom
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9dd24d7f57 |
@@ -146,21 +146,17 @@ jobs:
|
||||
sudo security authorizationdb write com.apple.trust-settings.admin allow
|
||||
cd src/electron
|
||||
./script/codesign/generate-identity.sh
|
||||
- name: Install Datadog CLI
|
||||
run: |
|
||||
cd src/electron
|
||||
node script/yarn global add @datadog/datadog-ci
|
||||
- name: Run Electron Tests
|
||||
shell: bash
|
||||
env:
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
MOCHA_MULTI_REPORTERS: mocha-junit-reporter, tap
|
||||
ELECTRON_DISABLE_SECURITY_WARNINGS: 1
|
||||
ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
|
||||
DISPLAY: ':99.0'
|
||||
run: |
|
||||
cd src/electron
|
||||
export ELECTRON_TEST_RESULTS_DIR=`pwd`/junit
|
||||
# Get which tests are on this shard
|
||||
tests_files=$(node script/split-tests ${{ matrix.shard }} ${{ inputs.target-platform == 'macos' && 2 || 3 }})
|
||||
|
||||
@@ -189,18 +185,6 @@ jobs:
|
||||
runuser -u builduser -- xvfb-run script/actions/run-tests.sh script/yarn test --runners=main --trace-uncaught --enable-logging --files $tests_files
|
||||
fi
|
||||
fi
|
||||
- name: Upload Test results to Datadog
|
||||
env:
|
||||
DD_ENV: ci
|
||||
DD_SERVICE: electron
|
||||
DD_API_KEY: ${{ secrets.DD_API_KEY }}
|
||||
DD_CIVISIBILITY_LOGS_ENABLED: true
|
||||
DD_TAGS: "os.architecture:${{ inputs.target-arch }},os.family:${{ inputs.target-platform }},os.platform:${{ inputs.target-platform }},asan:${{ inputs.is-asan }}"
|
||||
run: |
|
||||
if ! [ -z $DD_API_KEY ]; then
|
||||
datadog-ci junit upload src/electron/junit/test-results-main.xml
|
||||
fi
|
||||
if: always() && !cancelled()
|
||||
- name: Upload Test Artifacts
|
||||
if: always() && !cancelled()
|
||||
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
|
||||
|
||||
2
DEPS
2
DEPS
@@ -2,7 +2,7 @@ gclient_gn_args_from = 'src'
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'130.0.6723.44',
|
||||
'130.0.6723.31',
|
||||
'node_version':
|
||||
'v20.18.0',
|
||||
'nan_version':
|
||||
|
||||
@@ -36,7 +36,7 @@ environment:
|
||||
ELECTRON_ENABLE_STACK_DUMPING: 1
|
||||
ELECTRON_ALSO_LOG_TO_STDERR: 1
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
MOCHA_MULTI_REPORTERS: "@marshallofsound/mocha-appveyor-reporter, mocha-junit-reporter, tap"
|
||||
MOCHA_MULTI_REPORTERS: "@marshallofsound/mocha-appveyor-reporter, tap"
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN: 1
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN_BASE_URL: "https://dev-cdn.electronjs.org/windows-toolchains/_"
|
||||
GYP_MSVS_HASH_7393122652: 3ba76c5c20
|
||||
@@ -45,16 +45,10 @@ environment:
|
||||
matrix:
|
||||
|
||||
- job_name: Build Arm on X64 Windows
|
||||
- job_name: Test On Windows On Arm Hardware 1
|
||||
- job_name: Test On Windows On Arm Hardware
|
||||
job_depends_on: Build Arm on X64 Windows
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: base-woa
|
||||
APPVEYOR_BUILD_WORKER_CLOUD: electronhq-woa
|
||||
shard: 1
|
||||
- job_name: Test On Windows On Arm Hardware 2
|
||||
job_depends_on: Build Arm on X64 Windows
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: base-woa
|
||||
APPVEYOR_BUILD_WORKER_CLOUD: electronhq-woa
|
||||
shard: 2
|
||||
|
||||
clone_script:
|
||||
- ps: git clone -q $("--branch=" + $Env:APPVEYOR_REPO_BRANCH) $("https://github.com/" + $Env:APPVEYOR_REPO_NAME + ".git") $Env:APPVEYOR_BUILD_FOLDER
|
||||
@@ -260,19 +254,14 @@ for:
|
||||
}
|
||||
- matrix:
|
||||
only:
|
||||
- job_name: Test On Windows On Arm Hardware 1
|
||||
- job_name: Test On Windows On Arm Hardware 2
|
||||
- job_name: Test On Windows On Arm Hardware
|
||||
|
||||
environment:
|
||||
IGNORE_YARN_INSTALL_ERROR: 1
|
||||
ELECTRON_TEST_RESULTS_DIR: C:\projects\src\electron\junit
|
||||
MOCHA_MULTI_REPORTERS: "@marshallofsound/mocha-appveyor-reporter, mocha-junit-reporter, tap"
|
||||
ELECTRON_TEST_RESULTS_DIR: junit
|
||||
MOCHA_MULTI_REPORTERS: 'mocha-junit-reporter, tap'
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
|
||||
DD_ENV: ci
|
||||
DD_SERVICE: electron
|
||||
DD_CIVISIBILITY_LOGS_ENABLED: true
|
||||
DD_GIT_REPOSITORY_URL: "https://github.com/electron/electron.git"
|
||||
|
||||
build_script:
|
||||
- ps: |
|
||||
@@ -284,7 +273,6 @@ for:
|
||||
} else {
|
||||
$global:LASTEXITCODE = 0
|
||||
}
|
||||
- ps: Invoke-WebRequest -Uri "https://github.com/DataDog/datadog-ci/releases/latest/download/datadog-ci_win-x64" -OutFile "C:\projects\src\electron\datadog-ci.exe"
|
||||
- cd ..
|
||||
- mkdir out\Default
|
||||
- cd ..
|
||||
@@ -333,22 +321,10 @@ for:
|
||||
if ($env:TARGET_ARCH -eq 'ia32') {
|
||||
$env:npm_config_arch = "ia32"
|
||||
}
|
||||
- ps: $env:tests_files=node script\split-tests $env:shard 2
|
||||
- echo "Running shard %shard% specs %tests_files%"
|
||||
- echo Running main test suite & node script/yarn test --runners=main --enable-logging --disable-features=CalculateNativeWinOcclusion --files %tests_files%
|
||||
- echo Running main test suite & node script/yarn test --runners=main --enable-logging --disable-features=CalculateNativeWinOcclusion
|
||||
- cd ..
|
||||
- echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
|
||||
|
||||
on_finish:
|
||||
# Uncomment these lines to enable RDP
|
||||
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
- if exist electron\junit\test-results-main.xml ( appveyor-retry appveyor PushArtifact electron\junit\test-results-main.xml )
|
||||
- ps: |
|
||||
if ($env:DD_API_KEY) {
|
||||
$env:DD_GIT_COMMIT_SHA = $env:APPVEYOR_REPO_COMMIT
|
||||
$env:DD_GIT_BRANCH = $env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH
|
||||
$env:DD_TAGS = "os.architecture:$env:TARGET_ARCH,os.family:windows,os.platform:win32"
|
||||
if (Test-Path -Path "C:\projects\src\electron\junit\test-results-main.xml") {
|
||||
C:\projects\src\electron\datadog-ci.exe junit upload --verbose C:\projects\src\electron\junit\test-results-main.xml
|
||||
}
|
||||
}
|
||||
|
||||
33
appveyor.yml
33
appveyor.yml
@@ -36,7 +36,7 @@ environment:
|
||||
ELECTRON_ENABLE_STACK_DUMPING: 1
|
||||
ELECTRON_ALSO_LOG_TO_STDERR: 1
|
||||
MOCHA_REPORTER: mocha-multi-reporters
|
||||
MOCHA_MULTI_REPORTERS: "@marshallofsound/mocha-appveyor-reporter, mocha-junit-reporter, tap"
|
||||
MOCHA_MULTI_REPORTERS: "@marshallofsound/mocha-appveyor-reporter, tap"
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN: 1
|
||||
DEPOT_TOOLS_WIN_TOOLCHAIN_BASE_URL: "https://dev-cdn.electronjs.org/windows-toolchains/_"
|
||||
GYP_MSVS_HASH_7393122652: 3ba76c5c20
|
||||
@@ -45,12 +45,8 @@ environment:
|
||||
matrix:
|
||||
|
||||
- job_name: Build
|
||||
- job_name: Test 1
|
||||
- job_name: Test
|
||||
job_depends_on: Build
|
||||
shard: 1
|
||||
- job_name: Test 2
|
||||
job_depends_on: Build
|
||||
shard: 2
|
||||
|
||||
clone_script:
|
||||
- ps: git clone -q $("--branch=" + $Env:APPVEYOR_REPO_BRANCH) $("https://github.com/" + $Env:APPVEYOR_REPO_NAME + ".git") $Env:APPVEYOR_BUILD_FOLDER
|
||||
@@ -250,15 +246,7 @@ for:
|
||||
}
|
||||
- matrix:
|
||||
only:
|
||||
- job_name: Test 1
|
||||
- job_name: Test 2
|
||||
|
||||
environment:
|
||||
DD_ENV: ci
|
||||
DD_SERVICE: electron
|
||||
DD_CIVISIBILITY_LOGS_ENABLED: true
|
||||
DD_GIT_REPOSITORY_URL: "https://github.com/electron/electron.git"
|
||||
ELECTRON_TEST_RESULTS_DIR: C:\projects\src\electron\junit
|
||||
- job_name: Test
|
||||
|
||||
init:
|
||||
- ps: |
|
||||
@@ -275,7 +263,6 @@ for:
|
||||
} else {
|
||||
$global:LASTEXITCODE = 0
|
||||
}
|
||||
- npm install -g @datadog/datadog-ci
|
||||
- cd ..
|
||||
- mkdir out\Default
|
||||
- cd ..
|
||||
@@ -321,9 +308,7 @@ for:
|
||||
if ($env:TARGET_ARCH -eq 'ia32') {
|
||||
$env:npm_config_arch = "ia32"
|
||||
}
|
||||
- ps: $env:tests_files=node script\split-tests $env:shard 2
|
||||
- echo "Running shard %shard% specs %tests_files%"
|
||||
- echo Running main test suite & node script/yarn test -- --trace-uncaught --runners=main --enable-logging --files %tests_files%
|
||||
- echo Running main test suite & node script/yarn test -- --trace-uncaught --runners=main --enable-logging
|
||||
- cd ..
|
||||
- echo Verifying non proprietary ffmpeg & python electron\script\verify-ffmpeg.py --build-dir out\Default --source-root %cd% --ffmpeg-path out\ffmpeg
|
||||
- echo "About to verify mksnapshot"
|
||||
@@ -335,13 +320,3 @@ for:
|
||||
on_finish:
|
||||
# Uncomment these lines to enable RDP
|
||||
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
- if exist electron\junit\test-results-main.xml ( appveyor-retry appveyor PushArtifact electron\junit\test-results-main.xml )
|
||||
- ps: |
|
||||
if ($env:RUN_TESTS -eq 'true' -And $env:DD_API_KEY) {
|
||||
$env:DD_GIT_COMMIT_SHA = $env:APPVEYOR_REPO_COMMIT
|
||||
$env:DD_GIT_BRANCH = $env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH
|
||||
$env:DD_TAGS = "os.architecture:$env:TARGET_ARCH,os.family:windows,os.platform:win32"
|
||||
if (Test-Path -Path "C:\projects\src\electron\junit\test-results-main.xml") {
|
||||
C:\Users\appveyor\AppData\Roaming\npm\datadog-ci.ps1 junit upload --verbose C:\projects\src\electron\junit\test-results-main.xml
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,9 +127,6 @@ Returns:
|
||||
|
||||
Emitted when the child process needs to terminate due to non continuable error from V8.
|
||||
|
||||
No matter if you listen to the `error` event, the `exit` event will be emitted after the
|
||||
child process terminates.
|
||||
|
||||
#### Event: 'exit'
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -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 | 2024-Jan-07 | 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-07 | M126 | v20.14 | ✅ |
|
||||
| 30.0.0 | 2024-Feb-22 | 2024-Mar-20 | 2024-Apr-16 | 2024-Oct-15 | M124 | v20.11 | 🚫 |
|
||||
| 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 | 🚫 |
|
||||
|
||||
@@ -680,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",
|
||||
|
||||
@@ -130,3 +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
|
||||
feat_allow_-4_as_a_macos_screen_share_id.patch
|
||||
|
||||
@@ -23,10 +23,10 @@ index ad0092ef2e13853e4bb8b923481559a043b00ab7..1c2dfd23f18733e21312992877ae1499
|
||||
int32_t world_id) {}
|
||||
virtual void DidClearWindowObject() {}
|
||||
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
|
||||
index 24904d0b6436353601aa43c603f9d12fb8eff960..a673c3c00bc59e3bd8b0ed2ecb086856f57134ac 100644
|
||||
index 724818204a4fa1578102c2fe1a8877735323595a..954fdbbdd4d07c32d6fe78632ca95efc29fadc3c 100644
|
||||
--- a/content/renderer/render_frame_impl.cc
|
||||
+++ b/content/renderer/render_frame_impl.cc
|
||||
@@ -4794,6 +4794,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
|
||||
@@ -4791,6 +4791,12 @@ void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
|
||||
observer.DidCreateScriptContext(context, world_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@ Refs changes in:
|
||||
This patch reverts the changes to fix associated crashes in Electron.
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/frame/frame.cc b/third_party/blink/renderer/core/frame/frame.cc
|
||||
index 2f33ec660a975522c473ecd50e633b5edaca707f..65221a51927d9f44bd6adbad88fa1144f2db3add 100644
|
||||
index 6210eae2b7c25dae24ad7087d3e0ac494dada375..934ee55c89c526ca8fa390a13c4dd79b1c85882f 100644
|
||||
--- a/third_party/blink/renderer/core/frame/frame.cc
|
||||
+++ b/third_party/blink/renderer/core/frame/frame.cc
|
||||
@@ -135,14 +135,6 @@ bool Frame::Detach(FrameDetachType type) {
|
||||
@@ -131,14 +131,6 @@ bool Frame::Detach(FrameDetachType type) {
|
||||
|
||||
DCHECK(!IsDetached());
|
||||
|
||||
@@ -33,7 +33,7 @@ index 2f33ec660a975522c473ecd50e633b5edaca707f..65221a51927d9f44bd6adbad88fa1144
|
||||
if (type == FrameDetachType::kRemove) {
|
||||
if (provisional_frame_) {
|
||||
provisional_frame_->Detach(FrameDetachType::kRemove);
|
||||
@@ -166,6 +158,14 @@ bool Frame::Detach(FrameDetachType type) {
|
||||
@@ -162,6 +154,14 @@ bool Frame::Detach(FrameDetachType type) {
|
||||
GetWindowProxyManager()->ClearForSwap();
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ index ad7aef003b233245201937c58be12fa3acb6b1a4..275eb74983e684310753dabcd453e5a2
|
||||
"//base",
|
||||
"//build:branding_buildflags",
|
||||
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
|
||||
index 7f1c26990d8d43e92615bd3a5f4046d121d6ac6b..89d03b68cab5cec6095c2df2159a2f1cd15df0be 100644
|
||||
index 2b66b11333f732ea1ec65474d709b55638696cf3..d2d5eb596db1fc166c0498c2f7a6c15080e5d775 100644
|
||||
--- a/chrome/browser/BUILD.gn
|
||||
+++ b/chrome/browser/BUILD.gn
|
||||
@@ -4486,7 +4486,7 @@ static_library("browser") {
|
||||
@@ -46,7 +46,7 @@ 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 c53d7af88b3570e6c320b408afa449e51e355b6b..61aecb395632212911d57545cb068ca67bbac7d5 100644
|
||||
index 2a55a6189c6a5c399a08edf4659f33f541726093..f8e8fb75e71a265a0cc2b7c57c4f0fd9035c6def 100644
|
||||
--- a/chrome/test/BUILD.gn
|
||||
+++ b/chrome/test/BUILD.gn
|
||||
@@ -7173,9 +7173,12 @@ test("unit_tests") {
|
||||
@@ -63,7 +63,7 @@ index c53d7af88b3570e6c320b408afa449e51e355b6b..61aecb395632212911d57545cb068ca6
|
||||
"//chrome//services/util_win:unit_tests",
|
||||
"//chrome/app:chrome_dll_resources",
|
||||
"//chrome/app:win_unit_tests",
|
||||
@@ -8181,6 +8184,10 @@ test("unit_tests") {
|
||||
@@ -8180,6 +8183,10 @@ test("unit_tests") {
|
||||
"../browser/performance_manager/policies/background_tab_loading_policy_unittest.cc",
|
||||
]
|
||||
|
||||
@@ -74,7 +74,7 @@ index c53d7af88b3570e6c320b408afa449e51e355b6b..61aecb395632212911d57545cb068ca6
|
||||
sources += [
|
||||
# The importer code is not used on Android.
|
||||
"../common/importer/firefox_importer_utils_unittest.cc",
|
||||
@@ -8237,7 +8244,6 @@ test("unit_tests") {
|
||||
@@ -8236,7 +8243,6 @@ test("unit_tests") {
|
||||
# Non-android deps for "unit_tests" target.
|
||||
deps += [
|
||||
"../browser/screen_ai:screen_ai_install_state",
|
||||
|
||||
@@ -9,10 +9,10 @@ potentially prevent a window from being created.
|
||||
TODO(loc): this patch is currently broken.
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
index a0d5a983bb46a50dcf31afadc10f597a0e3ed15d..b6bda9691f0ae96ee4ba5d0d96d4e57e4fa592c2 100644
|
||||
index c2e377d5b1603a2d3c67a61911545ce361d418c2..20fe5301a0120e926d118f8b27ef57621833a5bf 100644
|
||||
--- a/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
@@ -9060,6 +9060,7 @@ void RenderFrameHostImpl::CreateNewWindow(
|
||||
@@ -9040,6 +9040,7 @@ void RenderFrameHostImpl::CreateNewWindow(
|
||||
last_committed_origin_, params->window_container_type,
|
||||
params->target_url, params->referrer.To<Referrer>(),
|
||||
params->frame_name, params->disposition, *params->features,
|
||||
@@ -148,10 +148,10 @@ index a080fb57f00c712eb8a3a9be669413e1082ce3b3..4826eea9747c4860d7f5b4b8d478e62c
|
||||
// typically happens when popups are created.
|
||||
virtual void WebContentsCreated(WebContents* source_contents,
|
||||
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
|
||||
index 7b7e727c44a1477640f8702ad818f4a8607e3fb7..24904d0b6436353601aa43c603f9d12fb8eff960 100644
|
||||
index d5e16b9e780efac46e088b3ef226e4418a90aeaf..724818204a4fa1578102c2fe1a8877735323595a 100644
|
||||
--- a/content/renderer/render_frame_impl.cc
|
||||
+++ b/content/renderer/render_frame_impl.cc
|
||||
@@ -6837,6 +6837,10 @@ WebView* RenderFrameImpl::CreateNewWindow(
|
||||
@@ -6834,6 +6834,10 @@ WebView* RenderFrameImpl::CreateNewWindow(
|
||||
request.HasUserGesture(), GetWebFrame()->IsAdFrame(),
|
||||
GetWebFrame()->IsAdScriptInStack());
|
||||
|
||||
@@ -210,10 +210,10 @@ index c576ace24e81cc877aa2595d40e0a13a7af9f6a2..210fb97d44c19c29af424cc7b9cb3169
|
||||
|
||||
} // namespace blink
|
||||
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
|
||||
index fe3c23e1dd1c818b5cb07a609dbbf17763c6d583..77bcaaf388fe1fb4577e25880b10154db0b46ce4 100644
|
||||
index 7b8158aff39c247e1729edb032833cdebf949acf..7d77f26106950deb1bae43ca7dcd7e0cde0ac6b5 100644
|
||||
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
|
||||
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
|
||||
@@ -2251,6 +2251,8 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
|
||||
@@ -2248,6 +2248,8 @@ DOMWindow* LocalDOMWindow::open(v8::Isolate* isolate,
|
||||
WebWindowFeatures window_features =
|
||||
GetWindowFeaturesFromString(features, entered_window);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -40,10 +40,10 @@ index 22bb23e6a84d3b6686461f87e846125ad7484742..198403ec544e71f50c8555d131015b80
|
||||
// origin of |common_params.url| and/or |common_params.initiator_origin|.
|
||||
url::Origin resolved_origin = url::Origin::Resolve(
|
||||
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc
|
||||
index f8098c86def00cac76932551bf413266facdc935..98a4c1ad9f561e1bec1e6113db46d4bcf3d3f694 100644
|
||||
index 0fb02ada85ed3d4cc113ac7ce18d6efdb7065627..9e78c486fdc9b931dfcbcf40145076a22f221e35 100644
|
||||
--- a/third_party/blink/renderer/core/loader/document_loader.cc
|
||||
+++ b/third_party/blink/renderer/core/loader/document_loader.cc
|
||||
@@ -2264,6 +2264,10 @@ Frame* DocumentLoader::CalculateOwnerFrame() {
|
||||
@@ -2261,6 +2261,10 @@ Frame* DocumentLoader::CalculateOwnerFrame() {
|
||||
scoped_refptr<SecurityOrigin> DocumentLoader::CalculateOrigin(
|
||||
Document* owner_document) {
|
||||
scoped_refptr<SecurityOrigin> origin;
|
||||
@@ -54,7 +54,7 @@ index f8098c86def00cac76932551bf413266facdc935..98a4c1ad9f561e1bec1e6113db46d4bc
|
||||
StringBuilder debug_info_builder;
|
||||
// Whether the origin is newly created within this call, instead of copied
|
||||
// from an existing document's origin or from `origin_to_commit_`. If this is
|
||||
@@ -2316,6 +2320,10 @@ scoped_refptr<SecurityOrigin> DocumentLoader::CalculateOrigin(
|
||||
@@ -2313,6 +2317,10 @@ scoped_refptr<SecurityOrigin> DocumentLoader::CalculateOrigin(
|
||||
debug_info_builder.Append(", url=");
|
||||
debug_info_builder.Append(owner_document->Url().BaseAsString());
|
||||
debug_info_builder.Append(")");
|
||||
|
||||
@@ -10,7 +10,7 @@ an about:blank check to this area.
|
||||
Ref: https://chromium-review.googlesource.com/c/chromium/src/+/5403876
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
index 67e53ad616687ea17719e3f4f1d00192c5b69d61..1642d61585c7aee3ec7a0907f5cdcd016e29ca6e 100644
|
||||
index 2605701ace806adef40b748f93aebae45144e1be..888e1386d7ed0003bbaabddeefa98d2c25e9adbb 100644
|
||||
--- a/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
@@ -782,8 +782,8 @@ void VerifyThatBrowserAndRendererCalculatedOriginsToCommitMatch(
|
||||
|
||||
@@ -15,10 +15,10 @@ Note that we also need to manually update embedder's
|
||||
`api::WebContents::IsFullscreenForTabOrPending` value.
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
index b6bda9691f0ae96ee4ba5d0d96d4e57e4fa592c2..67e53ad616687ea17719e3f4f1d00192c5b69d61 100644
|
||||
index 20fe5301a0120e926d118f8b27ef57621833a5bf..2605701ace806adef40b748f93aebae45144e1be 100644
|
||||
--- a/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
@@ -8175,6 +8175,17 @@ void RenderFrameHostImpl::EnterFullscreen(
|
||||
@@ -8155,6 +8155,17 @@ void RenderFrameHostImpl::EnterFullscreen(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,4 +52,3 @@ build_don_t_redefine_win32_lean_and_mean.patch
|
||||
src_use_supported_api_to_get_stalled_tla_messages.patch
|
||||
build_compile_with_c_20_support.patch
|
||||
add_v8_taskpirority_to_foreground_task_runner_signature.patch
|
||||
build_restore_clang_as_default_compiler_on_macos.patch
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: deepak1556 <hop2deep@gmail.com>
|
||||
Date: Fri, 11 Oct 2024 15:01:25 +0900
|
||||
Subject: build: restore clang as default compiler on macOS
|
||||
|
||||
Refs https://github.com/nodejs/node/commit/6e0a2bb54c5bbeff0e9e33e1a0c683ed980a8a0f
|
||||
configures the value at build time which doesn't work in Electron
|
||||
as it depends on the environment in which the headers got generated from which
|
||||
cannot reflect the value per platform. It works for Node.js since
|
||||
node-gyp will use the result of `process.config` that reflects the environment
|
||||
in which the binary got built.
|
||||
|
||||
diff --git a/common.gypi b/common.gypi
|
||||
index 2eb62610db2f0ebf68fa9a55ffba98291ecfe451..3ec08ee144b586d05c4e49c2251416734cbc02c5 100644
|
||||
--- a/common.gypi
|
||||
+++ b/common.gypi
|
||||
@@ -125,6 +125,7 @@
|
||||
'v8_base': '<(PRODUCT_DIR)/obj.target/tools/v8_gypfiles/libv8_snapshot.a',
|
||||
}],
|
||||
['OS=="mac"', {
|
||||
+ 'clang%': 1,
|
||||
'obj_dir%': '<(PRODUCT_DIR)/obj.target',
|
||||
'v8_base': '<(PRODUCT_DIR)/libv8_snapshot.a',
|
||||
}],
|
||||
@@ -61,10 +61,6 @@ def main(target_file, target_cpu):
|
||||
v['node_module_version'] = int(args['node_module_version'])
|
||||
# Used by certain versions of node-gyp.
|
||||
v['build_v8_with_gn'] = 'false'
|
||||
# Enable clang conditionally based on target platform
|
||||
# in common.gypi
|
||||
if 'clang' in v:
|
||||
del v['clang']
|
||||
|
||||
with open(target_file, 'w+', encoding='utf-8') as file_out:
|
||||
file_out.write(pprint.pformat(config, indent=2))
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
const glob = require('glob');
|
||||
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const currentShard = parseInt(process.argv[2], 10);
|
||||
const shardCount = parseInt(process.argv[3], 10);
|
||||
@@ -26,7 +25,7 @@ specFiles.sort((a, b) => {
|
||||
|
||||
let shard = 0;
|
||||
for (const specFile of specFiles) {
|
||||
buckets[shard].push(path.normalize(specFile));
|
||||
buckets[shard].push(specFile);
|
||||
shard++;
|
||||
if (shard === shardCount) shard = 0;
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "shell/common/options_switches.h"
|
||||
#include "shell/common/thread_restrictions.h"
|
||||
#include "shell/common/v8_util.h"
|
||||
#include "shell/common/v8_value_serializer.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "shell/common/v8_util.h"
|
||||
#include "shell/common/v8_value_serializer.h"
|
||||
#include "third_party/blink/public/common/messaging/message_port_descriptor.h"
|
||||
#include "third_party/blink/public/common/messaging/transferable_message_mojom_traits.h"
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
#include "shell/common/node_util.h"
|
||||
#include "shell/common/options_switches.h"
|
||||
#include "shell/common/thread_restrictions.h"
|
||||
#include "shell/common/v8_util.h"
|
||||
#include "shell/common/v8_value_serializer.h"
|
||||
#include "storage/browser/file_system/isolated_context.h"
|
||||
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
|
||||
#include "third_party/blink/public/common/input/web_input_event.h"
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/gin_helper/promise.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "shell/common/v8_util.h"
|
||||
#include "shell/common/v8_value_serializer.h"
|
||||
|
||||
namespace gin {
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "shell/common/gin_helper/error_thrower.h"
|
||||
#include "shell/common/gin_helper/event_emitter_caller.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "shell/common/v8_util.h"
|
||||
#include "shell/common/v8_value_serializer.h"
|
||||
#include "third_party/blink/public/common/messaging/transferable_message.h"
|
||||
#include "third_party/blink/public/common/messaging/transferable_message_mojom_traits.h"
|
||||
#include "third_party/blink/public/mojom/messaging/transferable_message.mojom.h"
|
||||
|
||||
@@ -25,18 +25,6 @@ namespace electron {
|
||||
|
||||
namespace {
|
||||
|
||||
// write |ref|'s raw bytes to |fd|.
|
||||
template <typename T>
|
||||
void WriteValToFd(int fd, const T& ref) {
|
||||
base::span<const uint8_t> bytes = base::byte_span_from_ref(ref);
|
||||
while (!bytes.empty()) {
|
||||
const ssize_t rv = HANDLE_EINTR(write(fd, bytes.data(), bytes.size()));
|
||||
RAW_CHECK(rv >= 0);
|
||||
const size_t n_bytes_written = rv >= 0 ? static_cast<size_t>(rv) : 0U;
|
||||
bytes = bytes.subspan(n_bytes_written);
|
||||
}
|
||||
}
|
||||
|
||||
// See comment in |PreEarlyInitialization()|, where sigaction is called.
|
||||
void SIGCHLDHandler(int signal) {}
|
||||
|
||||
@@ -61,7 +49,15 @@ void GracefulShutdownHandler(int signal) {
|
||||
RAW_CHECK(g_pipe_pid == getpid());
|
||||
RAW_CHECK(g_shutdown_pipe_write_fd != -1);
|
||||
RAW_CHECK(g_shutdown_pipe_read_fd != -1);
|
||||
WriteValToFd(g_shutdown_pipe_write_fd, signal);
|
||||
size_t bytes_written = 0;
|
||||
do {
|
||||
int rv = HANDLE_EINTR(
|
||||
write(g_shutdown_pipe_write_fd,
|
||||
reinterpret_cast<const char*>(&signal) + bytes_written,
|
||||
sizeof(signal) - bytes_written));
|
||||
RAW_CHECK(rv >= 0);
|
||||
bytes_written += rv;
|
||||
} while (bytes_written < sizeof(signal));
|
||||
}
|
||||
|
||||
// See comment in |PostCreateMainMessageLoop()|, where sigaction is called.
|
||||
@@ -134,33 +130,26 @@ NOINLINE void ExitPosted() {
|
||||
sleep(UINT_MAX);
|
||||
}
|
||||
|
||||
// read |sizeof(T)| raw bytes from |fd| and return the result
|
||||
template <typename T>
|
||||
[[nodiscard]] std::optional<T> ReadValFromFd(int fd) {
|
||||
auto val = T{};
|
||||
base::span<uint8_t> bytes = base::byte_span_from_ref(val);
|
||||
while (!bytes.empty()) {
|
||||
const ssize_t rv = HANDLE_EINTR(read(fd, bytes.data(), bytes.size()));
|
||||
if (rv < 0) {
|
||||
NOTREACHED_IN_MIGRATION() << "Unexpected error: " << strerror(errno);
|
||||
ShutdownFDReadError();
|
||||
return {};
|
||||
}
|
||||
if (rv == 0) {
|
||||
NOTREACHED_IN_MIGRATION() << "Unexpected closure of shutdown pipe.";
|
||||
ShutdownFDClosedError();
|
||||
return {};
|
||||
}
|
||||
const size_t n_bytes_read = static_cast<size_t>(rv);
|
||||
bytes = bytes.subspan(n_bytes_read);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
void ShutdownDetector::ThreadMain() {
|
||||
base::PlatformThread::SetName("CrShutdownDetector");
|
||||
|
||||
const int signal = ReadValFromFd<int>(shutdown_fd_).value_or(0);
|
||||
int signal;
|
||||
size_t bytes_read = 0;
|
||||
do {
|
||||
const ssize_t ret = HANDLE_EINTR(
|
||||
read(shutdown_fd_, reinterpret_cast<char*>(&signal) + bytes_read,
|
||||
sizeof(signal) - bytes_read));
|
||||
if (ret < 0) {
|
||||
NOTREACHED_IN_MIGRATION() << "Unexpected error: " << strerror(errno);
|
||||
ShutdownFDReadError();
|
||||
break;
|
||||
} else if (ret == 0) {
|
||||
NOTREACHED_IN_MIGRATION() << "Unexpected closure of shutdown pipe.";
|
||||
ShutdownFDClosedError();
|
||||
break;
|
||||
}
|
||||
bytes_read += ret;
|
||||
} while (bytes_read < sizeof(signal));
|
||||
VLOG(1) << "Handling shutdown for signal " << signal << ".";
|
||||
|
||||
if (!task_runner_->PostTask(FROM_HERE,
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
#include "shell/common/gin_helper/callback.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/v8_util.h"
|
||||
#include "shell/common/v8_value_serializer.h"
|
||||
|
||||
ElectronNSSCryptoModuleDelegate::ElectronNSSCryptoModuleDelegate(
|
||||
const net::HostPortPair& server)
|
||||
|
||||
@@ -120,20 +120,20 @@ void SetZoomLevelForWebContents(content::WebContents* web_contents,
|
||||
content::HostZoomMap::SetZoomLevel(web_contents, level);
|
||||
}
|
||||
|
||||
double GetNextZoomLevel(double level, bool out) {
|
||||
double GetNextZoomLevel(const double level, const bool out) {
|
||||
static constexpr std::array<double, 16U> kPresetFactors{
|
||||
0.25, 0.333, 0.5, 0.666, 0.75, 0.9, 1.0, 1.1,
|
||||
1.25, 1.5, 1.75, 2.0, 2.5, 3.0, 4.0, 5.0};
|
||||
static constexpr size_t size = std::size(kPresetFactors);
|
||||
static constexpr auto kBegin = kPresetFactors.begin();
|
||||
static constexpr auto kEnd = kPresetFactors.end();
|
||||
|
||||
const double factor = blink::ZoomLevelToZoomFactor(level);
|
||||
for (size_t i = 0U; i < size; ++i) {
|
||||
if (!blink::ZoomValuesEqual(kPresetFactors[i], factor))
|
||||
continue;
|
||||
if (out && i > 0U)
|
||||
return blink::ZoomFactorToZoomLevel(kPresetFactors[i - 1U]);
|
||||
if (!out && i + 1U < size)
|
||||
return blink::ZoomFactorToZoomLevel(kPresetFactors[i + 1U]);
|
||||
auto matches = [=](auto val) { return blink::ZoomValuesEqual(factor, val); };
|
||||
if (auto iter = std::find_if(kBegin, kEnd, matches); iter != kEnd) {
|
||||
if (out && iter != kBegin)
|
||||
return blink::ZoomFactorToZoomLevel(*--iter);
|
||||
if (!out && ++iter != kEnd)
|
||||
return blink::ZoomFactorToZoomLevel(*iter);
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "shell/common/gin_helper/function_template_extensions.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "shell/common/node_util.h"
|
||||
#include "shell/common/process_util.h"
|
||||
#include "shell/common/skia_util.h"
|
||||
#include "shell/common/thread_restrictions.h"
|
||||
@@ -398,18 +397,20 @@ void NativeImage::AddRepresentation(const gin_helper::Dictionary& options) {
|
||||
v8::Local<v8::Value> buffer;
|
||||
GURL url;
|
||||
if (options.Get("buffer", &buffer) && node::Buffer::HasInstance(buffer)) {
|
||||
auto* data = reinterpret_cast<unsigned char*>(node::Buffer::Data(buffer));
|
||||
auto size = node::Buffer::Length(buffer);
|
||||
skia_rep_added = electron::util::AddImageSkiaRepFromBuffer(
|
||||
&image_skia, electron::util::as_byte_span(buffer), width, height,
|
||||
scale_factor);
|
||||
&image_skia, data, size, width, height, scale_factor);
|
||||
} else if (options.Get("dataURL", &url)) {
|
||||
std::string mime_type, charset, data;
|
||||
if (net::DataURL::Parse(url, &mime_type, &charset, &data)) {
|
||||
auto* data_ptr = reinterpret_cast<const unsigned char*>(data.c_str());
|
||||
if (mime_type == "image/png") {
|
||||
skia_rep_added = electron::util::AddImageSkiaRepFromPNG(
|
||||
&image_skia, base::as_byte_span(data), scale_factor);
|
||||
&image_skia, data_ptr, data.size(), scale_factor);
|
||||
} else if (mime_type == "image/jpeg") {
|
||||
skia_rep_added = electron::util::AddImageSkiaRepFromJPEG(
|
||||
&image_skia, base::as_byte_span(data), scale_factor);
|
||||
&image_skia, data_ptr, data.size(), scale_factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -441,20 +442,22 @@ gin::Handle<NativeImage> NativeImage::Create(v8::Isolate* isolate,
|
||||
}
|
||||
|
||||
// static
|
||||
gin::Handle<NativeImage> NativeImage::CreateFromPNG(
|
||||
v8::Isolate* isolate,
|
||||
const base::span<const uint8_t> data) {
|
||||
gin::Handle<NativeImage> NativeImage::CreateFromPNG(v8::Isolate* isolate,
|
||||
const char* buffer,
|
||||
size_t length) {
|
||||
gfx::ImageSkia image_skia;
|
||||
electron::util::AddImageSkiaRepFromPNG(&image_skia, data, 1.0);
|
||||
electron::util::AddImageSkiaRepFromPNG(
|
||||
&image_skia, reinterpret_cast<const unsigned char*>(buffer), length, 1.0);
|
||||
return Create(isolate, gfx::Image(image_skia));
|
||||
}
|
||||
|
||||
// static
|
||||
gin::Handle<NativeImage> NativeImage::CreateFromJPEG(
|
||||
v8::Isolate* isolate,
|
||||
const base::span<const uint8_t> buffer) {
|
||||
gin::Handle<NativeImage> NativeImage::CreateFromJPEG(v8::Isolate* isolate,
|
||||
const char* buffer,
|
||||
size_t length) {
|
||||
gfx::ImageSkia image_skia;
|
||||
electron::util::AddImageSkiaRepFromJPEG(&image_skia, buffer, 1.0);
|
||||
electron::util::AddImageSkiaRepFromJPEG(
|
||||
&image_skia, reinterpret_cast<const unsigned char*>(buffer), length, 1.0);
|
||||
return Create(isolate, gfx::Image(image_skia));
|
||||
}
|
||||
|
||||
@@ -506,8 +509,7 @@ gin::Handle<NativeImage> NativeImage::CreateFromBitmap(
|
||||
auto info = SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType);
|
||||
auto size_bytes = info.computeMinByteSize();
|
||||
|
||||
const auto buffer_data = electron::util::as_byte_span(buffer);
|
||||
if (size_bytes != buffer_data.size()) {
|
||||
if (size_bytes != node::Buffer::Length(buffer)) {
|
||||
thrower.ThrowError("invalid buffer size");
|
||||
return gin::Handle<NativeImage>();
|
||||
}
|
||||
@@ -520,7 +522,7 @@ gin::Handle<NativeImage> NativeImage::CreateFromBitmap(
|
||||
|
||||
SkBitmap bitmap;
|
||||
bitmap.allocN32Pixels(width, height, false);
|
||||
bitmap.writePixels({info, buffer_data.data(), bitmap.rowBytes()});
|
||||
bitmap.writePixels({info, node::Buffer::Data(buffer), bitmap.rowBytes()});
|
||||
|
||||
gfx::ImageSkia image_skia =
|
||||
gfx::ImageSkia::CreateFromBitmap(bitmap, scale_factor);
|
||||
@@ -551,8 +553,8 @@ gin::Handle<NativeImage> NativeImage::CreateFromBuffer(
|
||||
|
||||
gfx::ImageSkia image_skia;
|
||||
electron::util::AddImageSkiaRepFromBuffer(
|
||||
&image_skia, electron::util::as_byte_span(buffer), width, height,
|
||||
scale_factor);
|
||||
&image_skia, reinterpret_cast<unsigned char*>(node::Buffer::Data(buffer)),
|
||||
node::Buffer::Length(buffer), width, height, scale_factor);
|
||||
return Create(args->isolate(), gfx::Image(image_skia));
|
||||
}
|
||||
|
||||
@@ -562,9 +564,9 @@ gin::Handle<NativeImage> NativeImage::CreateFromDataURL(v8::Isolate* isolate,
|
||||
std::string mime_type, charset, data;
|
||||
if (net::DataURL::Parse(url, &mime_type, &charset, &data)) {
|
||||
if (mime_type == "image/png")
|
||||
return CreateFromPNG(isolate, base::as_byte_span(data));
|
||||
if (mime_type == "image/jpeg")
|
||||
return CreateFromJPEG(isolate, base::as_byte_span(data));
|
||||
return CreateFromPNG(isolate, data.c_str(), data.size());
|
||||
else if (mime_type == "image/jpeg")
|
||||
return CreateFromJPEG(isolate, data.c_str(), data.size());
|
||||
}
|
||||
|
||||
return CreateEmpty(isolate);
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <vector>
|
||||
|
||||
#include "base/containers/flat_map.h"
|
||||
#include "base/containers/span.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/values.h"
|
||||
#include "gin/wrappable.h"
|
||||
@@ -62,10 +61,11 @@ class NativeImage final : public gin::Wrappable<NativeImage> {
|
||||
static gin::Handle<NativeImage> Create(v8::Isolate* isolate,
|
||||
const gfx::Image& image);
|
||||
static gin::Handle<NativeImage> CreateFromPNG(v8::Isolate* isolate,
|
||||
base::span<const uint8_t> data);
|
||||
static gin::Handle<NativeImage> CreateFromJPEG(
|
||||
v8::Isolate* isolate,
|
||||
base::span<const uint8_t> data);
|
||||
const char* buffer,
|
||||
size_t length);
|
||||
static gin::Handle<NativeImage> CreateFromJPEG(v8::Isolate* isolate,
|
||||
const char* buffer,
|
||||
size_t length);
|
||||
static gin::Handle<NativeImage> CreateFromPath(v8::Isolate* isolate,
|
||||
const base::FilePath& path);
|
||||
static gin::Handle<NativeImage> CreateFromBitmap(
|
||||
|
||||
@@ -26,19 +26,6 @@
|
||||
|
||||
namespace electron::api {
|
||||
|
||||
namespace {
|
||||
|
||||
base::span<const uint8_t> as_byte_span(NSData* data) {
|
||||
// SAFETY: There is no NSData API that passes the UNSAFE_BUFFER_USAGE
|
||||
// test, so let's isolate the unsafe API use into this function. Instead of
|
||||
// calling '[data bytes]' and '[data length]' directly, the rest of our
|
||||
// code should prefer to use spans returned by this function.
|
||||
return UNSAFE_BUFFERS(base::span{
|
||||
reinterpret_cast<const uint8_t*>([data bytes]), [data length]});
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NSData* bufferFromNSImage(NSImage* image) {
|
||||
CGImageRef ref = [image CGImageForProposedRect:nil context:nil hints:nil];
|
||||
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] initWithCGImage:ref];
|
||||
@@ -140,7 +127,9 @@ gin::Handle<NativeImage> NativeImage::CreateFromNamedImage(gin::Arguments* args,
|
||||
NSData* png_data = bufferFromNSImage(image);
|
||||
|
||||
if (args->GetNext(&hsl_shift) && hsl_shift.size() == 3) {
|
||||
auto gfx_image = gfx::Image::CreateFrom1xPNGBytes(as_byte_span(png_data));
|
||||
gfx::Image gfx_image = gfx::Image::CreateFrom1xPNGBytes(
|
||||
{reinterpret_cast<const uint8_t*>((char*)[png_data bytes]),
|
||||
[png_data length]});
|
||||
color_utils::HSL shift = {safeShift(hsl_shift[0], -1),
|
||||
safeShift(hsl_shift[1], 0.5),
|
||||
safeShift(hsl_shift[2], 0.5)};
|
||||
@@ -150,7 +139,8 @@ gin::Handle<NativeImage> NativeImage::CreateFromNamedImage(gin::Arguments* args,
|
||||
.AsNSImage());
|
||||
}
|
||||
|
||||
return CreateFromPNG(args->isolate(), as_byte_span(png_data));
|
||||
return CreateFromPNG(args->isolate(), (char*)[png_data bytes],
|
||||
[png_data length]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "shell/common/gin_converters/value_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/keyboard_util.h"
|
||||
#include "shell/common/v8_util.h"
|
||||
#include "shell/common/v8_value_serializer.h"
|
||||
#include "third_party/blink/public/common/context_menu_data/edit_flags.h"
|
||||
#include "third_party/blink/public/common/input/web_input_event.h"
|
||||
#include "third_party/blink/public/common/input/web_keyboard_event.h"
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include "shell/common/gin_converters/value_converter.h"
|
||||
#include "shell/common/gin_helper/promise.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "shell/common/v8_util.h"
|
||||
|
||||
namespace gin {
|
||||
|
||||
@@ -370,7 +369,10 @@ class ChunkedDataPipeReadableStream final
|
||||
num_bytes = *size_ - bytes_read_;
|
||||
MojoResult rv = data_pipe_->ReadData(
|
||||
MOJO_READ_DATA_FLAG_NONE,
|
||||
electron::util::as_byte_span(buf).first(num_bytes), num_bytes);
|
||||
base::span(static_cast<uint8_t*>(buf->Buffer()->Data()),
|
||||
buf->ByteLength())
|
||||
.subspan(buf->ByteOffset(), num_bytes),
|
||||
num_bytes);
|
||||
if (rv == MOJO_RESULT_OK) {
|
||||
bytes_read_ += num_bytes;
|
||||
// Not needed for correctness, but this allows the consumer to send the
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include "shell/common/heap_snapshot.h"
|
||||
|
||||
#include "base/containers/span.h"
|
||||
#include "base/files/file.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "v8/include/v8-profiler.h"
|
||||
@@ -25,13 +24,8 @@ class HeapSnapshotOutputStream : public v8::OutputStream {
|
||||
void EndOfStream() override { is_complete_ = true; }
|
||||
|
||||
v8::OutputStream::WriteResult WriteAsciiChunk(char* data, int size) override {
|
||||
const uint8_t* udata = reinterpret_cast<const uint8_t*>(data);
|
||||
const size_t usize = static_cast<size_t>(std::max(0, size));
|
||||
// SAFETY: since WriteAsciiChunk() only gives us data + size, our
|
||||
// UNSAFE_BUFFERS macro call is unavoidable here. It can be removed
|
||||
// if/when v8 changes WriteAsciiChunk() to pass a v8::MemorySpan.
|
||||
const auto data_span = UNSAFE_BUFFERS(base::span(udata, usize));
|
||||
return file_->WriteAtCurrentPosAndCheck(data_span) ? kContinue : kAbort;
|
||||
auto bytes_written = file_->WriteAtCurrentPos(data, size);
|
||||
return bytes_written == size ? kContinue : kAbort;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include "shell/common/node_util.h"
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/logging.h"
|
||||
#include "gin/converter.h"
|
||||
#include "gin/dictionary.h"
|
||||
@@ -66,14 +65,4 @@ void EmitWarning(v8::Isolate* isolate,
|
||||
emit_warning.Run(warning_msg, warning_type, "");
|
||||
}
|
||||
|
||||
// SAFETY: There is no node::Buffer API that passes the UNSAFE_BUFFER_USAGE
|
||||
// test, so let's isolate the unsafe API use into this function. Instead of
|
||||
// calling `Buffer::Data()` and `Buffer::Length()` directly, the rest of our
|
||||
// code should prefer to use spans returned by this function.
|
||||
base::span<uint8_t> as_byte_span(v8::Local<v8::Value> node_buffer) {
|
||||
auto* data = reinterpret_cast<uint8_t*>(node::Buffer::Data(node_buffer));
|
||||
const auto size = node::Buffer::Length(node_buffer);
|
||||
return UNSAFE_BUFFERS(base::span{data, size});
|
||||
}
|
||||
|
||||
} // namespace electron::util
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "base/containers/span.h"
|
||||
#include "v8/include/v8-forward.h"
|
||||
|
||||
namespace node {
|
||||
@@ -37,11 +36,6 @@ v8::MaybeLocal<v8::Value> CompileAndCall(
|
||||
std::vector<v8::Local<v8::String>>* parameters,
|
||||
std::vector<v8::Local<v8::Value>>* arguments);
|
||||
|
||||
// Convenience function to view a Node buffer's data as a base::span().
|
||||
// Analogous to base::as_byte_span()
|
||||
[[nodiscard]] base::span<uint8_t> as_byte_span(
|
||||
v8::Local<v8::Value> node_buffer);
|
||||
|
||||
} // namespace electron::util
|
||||
|
||||
#endif // ELECTRON_SHELL_COMMON_NODE_UTIL_H_
|
||||
|
||||
@@ -56,10 +56,11 @@ float GetScaleFactorFromPath(const base::FilePath& path) {
|
||||
}
|
||||
|
||||
bool AddImageSkiaRepFromPNG(gfx::ImageSkia* image,
|
||||
const base::span<const uint8_t> data,
|
||||
const unsigned char* data,
|
||||
size_t size,
|
||||
double scale_factor) {
|
||||
SkBitmap bitmap;
|
||||
if (!gfx::PNGCodec::Decode(data.data(), data.size(), &bitmap))
|
||||
if (!gfx::PNGCodec::Decode(data, size, &bitmap))
|
||||
return false;
|
||||
|
||||
image->AddRepresentation(gfx::ImageSkiaRep(bitmap, scale_factor));
|
||||
@@ -67,9 +68,10 @@ bool AddImageSkiaRepFromPNG(gfx::ImageSkia* image,
|
||||
}
|
||||
|
||||
bool AddImageSkiaRepFromJPEG(gfx::ImageSkia* image,
|
||||
const base::span<const uint8_t> data,
|
||||
const unsigned char* data,
|
||||
size_t size,
|
||||
double scale_factor) {
|
||||
auto bitmap = gfx::JPEGCodec::Decode(data.data(), data.size());
|
||||
auto bitmap = gfx::JPEGCodec::Decode(data, size);
|
||||
if (!bitmap)
|
||||
return false;
|
||||
|
||||
@@ -87,28 +89,29 @@ bool AddImageSkiaRepFromJPEG(gfx::ImageSkia* image,
|
||||
}
|
||||
|
||||
bool AddImageSkiaRepFromBuffer(gfx::ImageSkia* image,
|
||||
const base::span<const uint8_t> data,
|
||||
const unsigned char* data,
|
||||
size_t size,
|
||||
int width,
|
||||
int height,
|
||||
double scale_factor) {
|
||||
// Try PNG first.
|
||||
if (AddImageSkiaRepFromPNG(image, data, scale_factor))
|
||||
if (AddImageSkiaRepFromPNG(image, data, size, scale_factor))
|
||||
return true;
|
||||
|
||||
// Try JPEG second.
|
||||
if (AddImageSkiaRepFromJPEG(image, data, scale_factor))
|
||||
if (AddImageSkiaRepFromJPEG(image, data, size, scale_factor))
|
||||
return true;
|
||||
|
||||
if (width == 0 || height == 0)
|
||||
return false;
|
||||
|
||||
auto info = SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType);
|
||||
if (data.size() < info.computeMinByteSize())
|
||||
if (size < info.computeMinByteSize())
|
||||
return false;
|
||||
|
||||
SkBitmap bitmap;
|
||||
bitmap.allocN32Pixels(width, height, false);
|
||||
bitmap.writePixels({info, data.data(), bitmap.rowBytes()});
|
||||
bitmap.writePixels({info, data, bitmap.rowBytes()});
|
||||
|
||||
image->AddRepresentation(gfx::ImageSkiaRep(bitmap, scale_factor));
|
||||
return true;
|
||||
@@ -124,8 +127,11 @@ bool AddImageSkiaRepFromPath(gfx::ImageSkia* image,
|
||||
return false;
|
||||
}
|
||||
|
||||
return AddImageSkiaRepFromBuffer(image, base::as_byte_span(file_contents), 0,
|
||||
0, scale_factor);
|
||||
const auto* data =
|
||||
reinterpret_cast<const unsigned char*>(file_contents.data());
|
||||
size_t size = file_contents.size();
|
||||
|
||||
return AddImageSkiaRepFromBuffer(image, data, size, 0, 0, scale_factor);
|
||||
}
|
||||
|
||||
bool PopulateImageSkiaRepsFromPath(gfx::ImageSkia* image,
|
||||
|
||||
@@ -5,13 +5,9 @@
|
||||
#ifndef ELECTRON_SHELL_COMMON_SKIA_UTIL_H_
|
||||
#define ELECTRON_SHELL_COMMON_SKIA_UTIL_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "base/containers/span.h"
|
||||
|
||||
namespace base {
|
||||
class FilePath;
|
||||
} // namespace base
|
||||
}
|
||||
|
||||
namespace gfx {
|
||||
class ImageSkia;
|
||||
@@ -23,17 +19,20 @@ bool PopulateImageSkiaRepsFromPath(gfx::ImageSkia* image,
|
||||
const base::FilePath& path);
|
||||
|
||||
bool AddImageSkiaRepFromBuffer(gfx::ImageSkia* image,
|
||||
base::span<const uint8_t> data,
|
||||
const unsigned char* data,
|
||||
size_t size,
|
||||
int width,
|
||||
int height,
|
||||
double scale_factor);
|
||||
|
||||
bool AddImageSkiaRepFromJPEG(gfx::ImageSkia* image,
|
||||
base::span<const uint8_t> data,
|
||||
const unsigned char* data,
|
||||
size_t size,
|
||||
double scale_factor);
|
||||
|
||||
bool AddImageSkiaRepFromPNG(gfx::ImageSkia* image,
|
||||
base::span<const uint8_t> data,
|
||||
const unsigned char* data,
|
||||
size_t size,
|
||||
double scale_factor);
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/common/v8_util.h"
|
||||
#include "shell/common/v8_value_serializer.h"
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -240,23 +240,4 @@ v8::Local<v8::Value> DeserializeV8Value(v8::Isolate* isolate,
|
||||
return V8Deserializer(isolate, data).Deserialize();
|
||||
}
|
||||
|
||||
namespace util {
|
||||
|
||||
/**
|
||||
* SAFETY: There is not yet any v8::ArrayBufferView API that passes the
|
||||
* UNSAFE_BUFFER_USAGE test, so let's isolate the unsafe API here.
|
||||
*
|
||||
* Where possible, Electron should use spans returned here instead of
|
||||
* |v8::ArrayBufferView::Buffer()->Data()|,
|
||||
* |v8::ArrayBufferView::ByteOffset()|,
|
||||
* |v8::ArrayBufferView::ByteLength()|.
|
||||
*/
|
||||
base::span<uint8_t> as_byte_span(v8::Local<v8::ArrayBufferView> val) {
|
||||
uint8_t* data =
|
||||
static_cast<uint8_t*>(val->Buffer()->Data()) + val->ByteOffset();
|
||||
const size_t size = val->ByteLength();
|
||||
return UNSAFE_BUFFERS(base::span{data, size});
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace electron
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "ui/gfx/image/image_skia_rep.h"
|
||||
|
||||
namespace v8 {
|
||||
class ArrayBufferView;
|
||||
class Isolate;
|
||||
template <class T>
|
||||
class Local;
|
||||
@@ -30,12 +29,6 @@ v8::Local<v8::Value> DeserializeV8Value(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> DeserializeV8Value(v8::Isolate* isolate,
|
||||
base::span<const uint8_t> data);
|
||||
|
||||
namespace util {
|
||||
|
||||
[[nodiscard]] base::span<uint8_t> as_byte_span(
|
||||
v8::Local<v8::ArrayBufferView> abv);
|
||||
|
||||
} // namespace util
|
||||
} // namespace electron
|
||||
|
||||
#endif // ELECTRON_SHELL_COMMON_V8_VALUE_SERIALIZER_H_
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "shell/common/gin_helper/promise.h"
|
||||
#include "shell/common/node_bindings.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "shell/common/v8_util.h"
|
||||
#include "shell/common/v8_value_serializer.h"
|
||||
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
|
||||
#include "third_party/blink/public/web/web_local_frame.h"
|
||||
#include "third_party/blink/public/web/web_message_port_converter.h"
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include "base/containers/contains.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/numerics/safe_conversions.h"
|
||||
#include "base/strings/utf_string_conversion_utils.h"
|
||||
#include "base/task/single_thread_task_runner.h"
|
||||
#include "components/spellcheck/renderer/spellcheck_worditerator.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
@@ -30,9 +29,12 @@ namespace electron::api {
|
||||
|
||||
namespace {
|
||||
|
||||
bool HasWordCharacters(const std::u16string& text, size_t index) {
|
||||
base_icu::UChar32 code;
|
||||
while (base::ReadUnicodeCharacter(text.c_str(), text.size(), &index, &code)) {
|
||||
bool HasWordCharacters(const std::u16string& text, int index) {
|
||||
const char16_t* data = text.data();
|
||||
int length = text.length();
|
||||
while (index < length) {
|
||||
uint32_t code = 0;
|
||||
U16_NEXT(data, index, length, code);
|
||||
UErrorCode error = U_ZERO_ERROR;
|
||||
if (uscript_getScript(code, &error) != USCRIPT_COMMON)
|
||||
return true;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "shell/common/options_switches.h"
|
||||
#include "shell/common/thread_restrictions.h"
|
||||
#include "shell/common/v8_util.h"
|
||||
#include "shell/common/v8_value_serializer.h"
|
||||
#include "shell/renderer/electron_render_frame_observer.h"
|
||||
#include "shell/renderer/renderer_client_base.h"
|
||||
#include "third_party/blink/public/mojom/frame/user_activation_notification_type.mojom-shared.h"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/event_emitter_caller.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "shell/common/v8_util.h"
|
||||
#include "shell/common/v8_value_serializer.h"
|
||||
#include "third_party/blink/public/common/messaging/transferable_message_mojom_traits.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
8
spec/fixtures/chromium/visibilitystate.html
vendored
8
spec/fixtures/chromium/visibilitystate.html
vendored
@@ -7,6 +7,12 @@
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Visibility Test</h1>
|
||||
<script>
|
||||
const { ipcRenderer } = require('electron')
|
||||
ipcRenderer.send('initial-visibility-state', document.visibilityState)
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
ipcRenderer.send(`visibility-change-${document.visibilityState}`)
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -149,17 +149,7 @@ app.whenReady().then(async () => {
|
||||
|
||||
const { getFiles } = require('./get-files');
|
||||
const testFiles = await getFiles(__dirname, filter);
|
||||
const VISIBILITY_SPEC = ('visibility-state-spec.ts');
|
||||
const sortedFiles = testFiles.sort((a, b) => {
|
||||
// If visibility-state-spec is in the list, move it to the first position
|
||||
// so that it gets executed first to avoid other specs interferring with it.
|
||||
if (a.indexOf(VISIBILITY_SPEC) > -1) {
|
||||
return -1;
|
||||
} else {
|
||||
return a.localeCompare(b);
|
||||
}
|
||||
});
|
||||
for (const file of sortedFiles) {
|
||||
for (const file of testFiles.sort()) {
|
||||
mocha.addFile(file);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,37 +1,26 @@
|
||||
import { BaseWindow, BrowserWindow, BrowserWindowConstructorOptions, WebContents, WebContentsView } from 'electron/main';
|
||||
import { BaseWindow, BrowserWindow, BrowserWindowConstructorOptions, ipcMain, WebContents, WebContentsView } from 'electron/main';
|
||||
|
||||
import { expect } from 'chai';
|
||||
|
||||
import * as cp from 'node:child_process';
|
||||
import { once } from 'node:events';
|
||||
import * as path from 'node:path';
|
||||
import { setTimeout } from 'node:timers/promises';
|
||||
|
||||
import { ifdescribe, waitUntil } from './lib/spec-helpers';
|
||||
import { closeAllWindows } from './lib/window-helpers';
|
||||
import { ifdescribe } from './lib/spec-helpers';
|
||||
import { closeWindow } from './lib/window-helpers';
|
||||
|
||||
// visibilityState specs pass on linux with a real window manager but on CI
|
||||
// the environment does not let these specs pass
|
||||
ifdescribe(process.platform !== 'linux')('document.visibilityState', () => {
|
||||
let w: BaseWindow & {webContents: WebContents};
|
||||
|
||||
before(() => {
|
||||
for (const checkWin of BaseWindow.getAllWindows()) {
|
||||
console.log('WINDOW EXISTS BEFORE TEST STARTED:', checkWin.title, checkWin.id);
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await closeAllWindows();
|
||||
w = null as unknown as BrowserWindow;
|
||||
afterEach(() => {
|
||||
return closeWindow(w);
|
||||
});
|
||||
|
||||
const load = () => w.webContents.loadFile(path.resolve(__dirname, 'fixtures', 'chromium', 'visibilitystate.html'));
|
||||
|
||||
async function haveVisibilityState (state: string) {
|
||||
const docVisState = await w.webContents.executeJavaScript('document.visibilityState');
|
||||
return docVisState === state;
|
||||
}
|
||||
|
||||
const itWithOptions = (name: string, options: BrowserWindowConstructorOptions, fn: Mocha.Func) => {
|
||||
it(name, async function (...args) {
|
||||
w = new BrowserWindow({
|
||||
@@ -43,9 +32,6 @@ ifdescribe(process.platform !== 'linux')('document.visibilityState', () => {
|
||||
contextIsolation: false
|
||||
}
|
||||
});
|
||||
if (options.show && process.platform === 'darwin') {
|
||||
await once(w, 'show');
|
||||
}
|
||||
await Promise.resolve(fn.apply(this, args));
|
||||
});
|
||||
|
||||
@@ -56,30 +42,30 @@ ifdescribe(process.platform !== 'linux')('document.visibilityState', () => {
|
||||
const wcv = new WebContentsView({ webPreferences: { ...(options.webPreferences ?? {}), nodeIntegration: true, contextIsolation: false } });
|
||||
baseWindow.contentView = wcv;
|
||||
w = Object.assign(baseWindow, { webContents: wcv.webContents });
|
||||
if (options.show && process.platform === 'darwin') {
|
||||
await once(w, 'show');
|
||||
}
|
||||
await Promise.resolve(fn.apply(this, args));
|
||||
});
|
||||
};
|
||||
|
||||
itWithOptions('should be visible when the window is initially shown by default', {}, async () => {
|
||||
load();
|
||||
await expect(waitUntil(async () => await haveVisibilityState('visible'))).to.eventually.be.fulfilled();
|
||||
const [, state] = await once(ipcMain, 'initial-visibility-state');
|
||||
expect(state).to.equal('visible');
|
||||
});
|
||||
|
||||
itWithOptions('should be visible when the window is initially shown', {
|
||||
show: true
|
||||
}, async () => {
|
||||
load();
|
||||
await expect(waitUntil(async () => await haveVisibilityState('visible'))).to.eventually.be.fulfilled();
|
||||
const [, state] = await once(ipcMain, 'initial-visibility-state');
|
||||
expect(state).to.equal('visible');
|
||||
});
|
||||
|
||||
itWithOptions('should be hidden when the window is initially hidden', {
|
||||
show: false
|
||||
}, async () => {
|
||||
load();
|
||||
await expect(waitUntil(async () => await haveVisibilityState('hidden'))).to.eventually.be.fulfilled();
|
||||
const [, state] = await once(ipcMain, 'initial-visibility-state');
|
||||
expect(state).to.equal('hidden');
|
||||
});
|
||||
|
||||
itWithOptions('should be visible when the window is initially hidden but shown before the page is loaded', {
|
||||
@@ -87,40 +73,52 @@ ifdescribe(process.platform !== 'linux')('document.visibilityState', () => {
|
||||
}, async () => {
|
||||
w.show();
|
||||
load();
|
||||
await expect(waitUntil(async () => await haveVisibilityState('visible'))).to.eventually.be.fulfilled();
|
||||
const [, state] = await once(ipcMain, 'initial-visibility-state');
|
||||
expect(state).to.equal('visible');
|
||||
});
|
||||
|
||||
itWithOptions('should be hidden when the window is initially shown but hidden before the page is loaded', {
|
||||
show: true
|
||||
}, async () => {
|
||||
// TODO(MarshallOfSound): Figure out if we can work around this 1 tick issue for users
|
||||
if (process.platform === 'darwin') {
|
||||
// Wait for a tick, the window being "shown" takes 1 tick on macOS
|
||||
await setTimeout(10000);
|
||||
}
|
||||
w.hide();
|
||||
load();
|
||||
await expect(waitUntil(async () => await haveVisibilityState('hidden'))).to.eventually.be.fulfilled();
|
||||
const [, state] = await once(ipcMain, 'initial-visibility-state');
|
||||
expect(state).to.equal('hidden');
|
||||
});
|
||||
|
||||
itWithOptions('should be toggle between visible and hidden as the window is hidden and shown', {}, async () => {
|
||||
load();
|
||||
await expect(waitUntil(async () => await haveVisibilityState('visible'))).to.eventually.be.fulfilled();
|
||||
const [, initialState] = await once(ipcMain, 'initial-visibility-state');
|
||||
expect(initialState).to.equal('visible');
|
||||
w.hide();
|
||||
await expect(waitUntil(async () => await haveVisibilityState('hidden'))).to.eventually.be.fulfilled();
|
||||
await once(ipcMain, 'visibility-change-hidden');
|
||||
w.show();
|
||||
await expect(waitUntil(async () => await haveVisibilityState('visible'))).to.eventually.be.fulfilled();
|
||||
await once(ipcMain, 'visibility-change-visible');
|
||||
});
|
||||
|
||||
itWithOptions('should become hidden when a window is minimized', {}, async () => {
|
||||
load();
|
||||
await expect(waitUntil(async () => await haveVisibilityState('visible'))).to.eventually.be.fulfilled();
|
||||
const [, initialState] = await once(ipcMain, 'initial-visibility-state');
|
||||
expect(initialState).to.equal('visible');
|
||||
w.minimize();
|
||||
await expect(waitUntil(async () => await haveVisibilityState('hidden'))).to.eventually.be.fulfilled();
|
||||
const p = once(ipcMain, 'visibility-change-hidden');
|
||||
w.minimize();
|
||||
await p;
|
||||
});
|
||||
|
||||
itWithOptions('should become visible when a window is restored', {}, async () => {
|
||||
load();
|
||||
await expect(waitUntil(async () => await haveVisibilityState('visible'))).to.eventually.be.fulfilled();
|
||||
const [, initialState] = await once(ipcMain, 'initial-visibility-state');
|
||||
expect(initialState).to.equal('visible');
|
||||
w.minimize();
|
||||
await expect(waitUntil(async () => await haveVisibilityState('hidden'))).to.eventually.be.fulfilled();
|
||||
await once(ipcMain, 'visibility-change-hidden');
|
||||
w.restore();
|
||||
await expect(waitUntil(async () => await haveVisibilityState('visible'))).to.eventually.be.fulfilled();
|
||||
await once(ipcMain, 'visibility-change-visible');
|
||||
});
|
||||
|
||||
ifdescribe(process.platform === 'darwin')('on platforms that support occlusion detection', () => {
|
||||
@@ -154,7 +152,8 @@ ifdescribe(process.platform !== 'linux')('document.visibilityState', () => {
|
||||
height: 200
|
||||
});
|
||||
load();
|
||||
await expect(waitUntil(async () => await haveVisibilityState('visible'))).to.eventually.be.fulfilled();
|
||||
const [, state] = await once(ipcMain, 'initial-visibility-state');
|
||||
expect(state).to.equal('visible');
|
||||
});
|
||||
|
||||
itWithOptions('should be visible when two windows are on screen that overlap partially', {
|
||||
@@ -170,7 +169,8 @@ ifdescribe(process.platform !== 'linux')('document.visibilityState', () => {
|
||||
height: 200
|
||||
});
|
||||
load();
|
||||
await expect(waitUntil(async () => await haveVisibilityState('visible'))).to.eventually.be.fulfilled();
|
||||
const [, state] = await once(ipcMain, 'initial-visibility-state');
|
||||
expect(state).to.equal('visible');
|
||||
});
|
||||
|
||||
itWithOptions('should be hidden when a second window completely occludes the current window', {
|
||||
@@ -181,14 +181,15 @@ ifdescribe(process.platform !== 'linux')('document.visibilityState', () => {
|
||||
}, async function () {
|
||||
this.timeout(240000);
|
||||
load();
|
||||
await expect(waitUntil(async () => await haveVisibilityState('visible'))).to.eventually.be.fulfilled();
|
||||
const [, state] = await once(ipcMain, 'initial-visibility-state');
|
||||
expect(state).to.equal('visible');
|
||||
makeOtherWindow({
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 300,
|
||||
height: 300
|
||||
});
|
||||
await expect(waitUntil(async () => await haveVisibilityState('hidden'))).to.eventually.be.fulfilled();
|
||||
await once(ipcMain, 'visibility-change-hidden');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user