Compare commits

..

52 Commits

Author SHA1 Message Date
trop[bot]
6de96fb83b ci: fixup diagnose_goma_log.py call (#40149)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-10-09 18:44:51 -04:00
trop[bot]
cf0e974ce1 fix: failing build with enable_electron_extensions=false (#40087)
* fix: ENABLE_EXTENSIONS -> ENABLE_ELECTRON_EXTENSIONS

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* fix: extension guard fixes

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* chore: fix linker errors

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-10-09 18:43:40 -04:00
trop[bot]
7e2073226a fix: crashed events deprecation (#40111)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-10-09 15:19:53 +02:00
trop[bot]
8f370cd2e3 fix: fix vibrancy applying without transparency on MacOS (#40130)
* fix: fix vibrancy applying without transparency

Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>

* fix: initiate backgroundMaterial and vibrancy earlier in native window

Co-authored-by: samuelmaddock <samuelmaddock@electronjs.org>

Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
2023-10-09 15:19:30 +02:00
Milan Burda
82d4e9427f test: fix "crashed event does not crash main process when destroying WebContents in it" (#40144) 2023-10-09 15:18:46 +02:00
trop[bot]
f0b742f2d6 test: add back smoke test for removed API (#40139)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
2023-10-09 15:41:39 +09:00
trop[bot]
2bc07b098b chore: cherry-pick c03569f from libuv (#40126)
* chore: cherry-pick c03569f from libuv

Refs c03569f0df

Co-authored-by: deepak1556 <hop2deep@gmail.com>

* chore: update .patches

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-10-09 08:45:34 +09:00
trop[bot]
d95f28c194 fix: toggling DevTools while minimized on Windows (#40116)
fix: toggling devtools while minimized on Windows

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-10-06 11:46:55 -04:00
trop[bot]
22ea11175b fix: error using webcrypto.subtle.importKey() (#40100)
* fix: error using webcrypto.subtle.importKey()

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* chore: update .patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-10-06 10:42:49 -04:00
trop[bot]
5b44e82eb4 fix: all children showing when showing child window (#40105)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-10-06 09:56:23 -04:00
electron-roller[bot]
4c4a3e7594 chore: bump chromium to 118.0.5993.54 (27-x-y) (#40103)
* chore: bump chromium in DEPS to 118.0.5993.54

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-10-05 19:53:06 -04:00
trop[bot]
bf7474d3f4 feat: add tabbingIdentifier property to BrowserWindow (#40082)
feat: add tabbingIdentifier property to BrowserWindow

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-10-05 09:13:05 -04:00
George Xu
3f142ad039 feat: expose app accessibility transparency settings api (#40074)
feat: expose app accessibility transparency settings api (#39631)

* feat: expose app accessibility transparency settings api

* docs: fix typo

* chore: add doc

* change to property

* add as property instead of method

* chore: fix lint

* rename function name in header

---------

Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
2023-10-04 16:36:04 -07:00
electron-roller[bot]
10db23828e chore: bump chromium to 118.0.5993.32 (27-x-y) (#40044)
* chore: bump chromium in DEPS to 118.0.5993.32

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-10-02 14:37:40 -04:00
trop[bot]
43ba54e61f docs: add PipeWire integration instructions for snaps (#40068)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Athul Iddya <athul@iddya.com>
2023-10-02 11:05:52 -04:00
trop[bot]
3fdfcbb5dd chore: update extensions url handling to match upstream (#40063)
- https://chromium-review.googlesource.com/c/chromium/src/+/4772028
- https://chromium-review.googlesource.com/c/chromium/src/+/4264656
- https://chromium-review.googlesource.com/c/chromium/src/+/4712150

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-10-02 13:12:47 +02:00
trop[bot]
9e8cba981a fix: BroadcastChannel initialization location (#40067)
fix: `BroadcastChannel` initialization location (#37421)

* fix: BroadcastChannel initialization location

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-10-02 13:10:46 +02:00
trop[bot]
a85c6cf0e5 fix: detect screen readers by testing their existences (#40065)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2023-10-02 13:07:27 +02:00
trop[bot]
7e536dfd8e fix: propagate layout call to all children of InspectableWebContentsViewViews (#40037)
Propagate layout call to all children of InspectableWebContentsViewViews.

When BrowserView bounds are set from js, those might not trigger layout
immediately, sometimes propagating InvalidateLayout call to parent.
View is marked as needing layout, expecting to receive it from parent on
next layout call. The problem is that BrowserView's view is added as child
of InspectableWebContentsViews which does not call setBounds (which
would trigger layout) on all of it's children when doing it's layout,
so it skips propagating Layout call to its children BrowserViews views,
even though those were marked as needing layout.
Call base class View::Layout which will iterate over views' children
and call Layout on those that were marked as needing them.

Fixes #39993.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Marek Haranczyk <marek@openfin.co>
2023-09-28 18:55:24 -04:00
trop[bot]
7d21d113d2 fix: failure on immutable webContents.print(options) (#40030)
fix: failure on immutable webContents.print(options)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-09-28 12:48:44 -04:00
Samuel Attard
7ed33db12e chore: cherry-pick 3fbd1dca6a4d from libvpx (#40022)
* chore: cherry-pick 3fbd1dca6a4d from libvpx

* build: update patches config

* chore: update patches

* chore: update patches

---------

Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-09-28 03:31:46 -07:00
trop[bot]
66c4f9cb6f fix: rounded corners on vibrant macOS modals (#39996)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-09-28 10:33:39 +02:00
trop[bot]
a00155dcfc fix: set window contents as opaque to decrease DWM GPU usage (#40003)
* set window contents as opaque to decrease DWM GPU usage

Co-authored-by: brhenrique <bruno.d@miro.com>

* chore: add more context to ShouldWindowContentsBeTransparent

Co-authored-by: brhenrique <bruno.d@miro.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: brhenrique <bruno.d@miro.com>
2023-09-28 10:33:29 +02:00
trop[bot]
3e4adb91c5 feat: enable dark mode on GTK UIs (#40010)
feat: port DarkModeManagerLinux

This is needed after https://bugs.chromium.org/p/chromium/issues/detail?id=998903
and replaces the previous workaround to detect dark mode on GTK.
Detect system dark theme preference via xdg settings portal:
https://flatpak.github.io/xdg-desktop-portal/#gdbus-org.freedesktop.portal.Settings

Closes: https://github.com/electron/electron/issues/38961
Closes: https://github.com/electron/electron/issues/28838

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Robert Günzler <r@gnzler.io>
2023-09-27 16:44:34 -04:00
trop[bot]
f63f02fbb2 docs: document type-specific module aliases (#40005)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Erick Zhao <erick@hotmail.ca>
2023-09-27 16:35:32 -04:00
trop[bot]
a3a6e8ff26 build: fix with enable_pdf_viewer = false (#40001)
build: fix with enable_pdf_viewer = false

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-09-27 19:57:48 +02:00
trop[bot]
e70a25d5a3 fix: apply size constraints to NSWindow (#39992)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
2023-09-27 16:54:19 +02:00
Keeley Hammond
8e2cf54f29 fix: revert SameParty cookie attribute removal (#39976) 2023-09-26 14:17:23 -07:00
trop[bot]
a3614983de chore: add deprecated app.runningUnderRosettaTranslation to breaking-changes.md (#39984)
chore: add deprecated app.runningUnderRosettaTranslation to breaking-changes.md

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-09-26 16:57:42 -04:00
David Sanders
686adf9d15 chore: remove deprecated systemPreferences APIs (#39804)
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-09-26 14:45:49 +09:00
John Kleinschmidt
25dccaa1b1 test: fixup parallel/test-node-output-error test (#39973) 2023-09-25 17:03:41 -04:00
trop[bot]
175cd9111e refactor: use type enum in file stats for asar archive (#39968)
refactor: use type enum in file stats for asar archive (#39889)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-09-25 11:14:05 -04:00
trop[bot]
70236258cf docs: correct v24 Alpha date (#39966)
docs: correct v27 Alpha date

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Leon <xuminjieleon@163.com>
2023-09-25 12:43:16 +02:00
electron-roller[bot]
d0d9011fc9 chore: bump chromium to 118.0.5993.18 (27-x-y) (#39943)
* chore: bump chromium in DEPS to 118.0.5993.18

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-09-22 10:04:12 +02:00
trop[bot]
8423a014ed chore: cherry-pick tls shutdown crash fix from upstream (#39947)
* chore: cherry-pick tls shutdown crash fix from upstream

Co-authored-by: deepak1556 <hop2deep@gmail.com>

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-09-21 19:39:21 +02:00
trop[bot]
4ba1b219a5 fix: app.runningUnderARM64Translation() always returning true on Windows ARM64 (#39931)
fix: app.runningUnderARM64Translation() always returning true on ARM64

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-09-21 10:09:17 -04:00
trop[bot]
e721b683bf ci: fix linux builds of forks (#39940)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-09-21 10:07:51 -04:00
John Kleinschmidt
271be9c8e4 chore: fixup node flakes (#39917)
(cherry picked from commit 80a9b9d654)
2023-09-19 15:29:00 -04:00
trop[bot]
946df59915 build: use afs on aks instead of circle cache (#39910)
* build: use afs on aks instead of circle cache

* build: do not use aks logic on linux hosts checking out for macOS

* build: fix gn-check could-be-aks

* build: sigh

* build: no ls mnt

* build: keep build alive while debugging

* build: make debuggable

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <sam@electronjs.org>
2023-09-19 10:51:41 -04:00
trop[bot]
77a02d858b docs: add a more detailed explanation to cookies.flushStore() (#39904)
* docs: cookies.flushStore()

Co-authored-by: Spencer17x <1253478653@qq.com>

* docs: modify cookies.flushStore()

Co-authored-by: Spencer17x <1253478653@qq.com>

* Update docs/api/cookies.md

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

Co-authored-by: spencer17x <1253478653@qq.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Spencer17x <1253478653@qq.com>
2023-09-19 15:48:08 +02:00
trop[bot]
f648dbe081 build: fixup autoninja (#39902)
chore: set GOMA_DIR for autoninja

(cherry picked from commit 94f24bde4d)
(cherry picked from commit 90c1f6e1cb8d22d94dd01791dc4b9c3e0a7e86fc)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-09-18 20:35:51 -04:00
trop[bot]
c572477606 fix: prevent gin_helper::Locker heap allocation (#39872)
fix: prevent gin_helper::Locker heap allocation

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Milan Burda <milan.burda@gmail.com>
2023-09-18 13:19:42 -04:00
trop[bot]
3b07ed95a4 build: run on circle hosts for forks (#39868)
Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
2023-09-18 11:07:06 -04:00
trop[bot]
d689830214 fix: check PipeWire init before creating generic capturer (#39874)
Check if PipeWire can be initialized before creating generic capturer.
This harmonizes the conditions with the ones used in Linux
implementations of DesktopCapturer::CreateRawScreenCapturer and
DesktopCapturer::CreateRawWindowCapturer.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Athul Iddya <athul@iddya.com>
2023-09-15 20:23:58 +02:00
electron-roller[bot]
e53d5f4949 chore: bump chromium to 118.0.5993.11 (27-x-y) (#39854)
* chore: bump chromium in DEPS to 118.0.5993.11

* chore: update patches

---------

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-09-14 14:43:14 -04:00
Charles Kerr
6a59b373a6 refactor: remove unused Locker fields (#39842)
refactor: remove unused fields, methods in gin_helper::Locker (#39803)

* refactor: remove unused field gin_helper::Locker::g_is_browser_process

refactor: remove unused field gin_helper::Locker::g_is_renderer_process

refactor: make field const gin_helper::Locker::locker_

* refactor: remove unused declaration gin_helper::Locker::new()

refactor: remove unused declaration gin_helper::Locker::delete()

* refactor: make field const electron::JavascriptEnvironment::locker_

* refactor: remove unused #include gin_helper/locker.h
2023-09-13 09:52:39 +02:00
trop[bot]
036a382d66 fix: NodeService order-of-destruction issue (#39829)
* refactor: make ElectronRendererClient::node_bindings_ a const ptr

refactor: make ElectronRendererClient::electron_bindings_ a const ptr

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* fix: order-of-destruction bug in NodeService

js_env_ depends on the uv_loop from node_bindings_, but is destroyed after node_bindings_

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* chore: revert unintentional commit

Co-authored-by: Charles Kerr <charles@charleskerr.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
2023-09-12 16:53:33 -07:00
Samuel Attard
c4a54202b9 chore: cherry-pick b2eab7500a18 from chromium (#39823)
* chore: cherry-pick b2eab7500a18 from chromium

* chore: update patch

* chore: update patches

---------

Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org>
2023-09-12 11:44:00 -07:00
trop[bot]
c128893a4c fix: keyCodes being incorrectly converted in webContents.sendInputEvent() (#39822)
fix: sendInputEvent keyCodes being incorrectly converted

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
2023-09-12 16:03:41 +02:00
trop[bot]
b9e0f097bd fix: ensure app load is limited to real asar files when appropriate (#39807)
* fix: ensure app load is limited to real asar files when appropriate

Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>

* chore: update line numbers in node test

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
2023-09-11 17:23:56 -07:00
trop[bot]
78a99d673e build: update @electron/typescript-definitions to fix titlebaroverlay (#39806)
build: update @electron/typescript-definitions to fix titlebarstyle

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Samuel Attard <marshallofsound@electronjs.org>
2023-09-11 14:03:51 -07:00
trop[bot]
75f5706d6c fix: frameless mica/acrylic windows (#39802)
* fix: backgroundMaterial works with frameless

* TODO: fix frameless mica/acrylic windows

* update caption color appropriately

* set background color properly

* refactor translucency method

* actualization

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Calvin <clavin@users.noreply.github.com>
2023-09-11 22:20:45 +02:00
100 changed files with 4131 additions and 598 deletions

View File

@@ -65,6 +65,9 @@ jobs:
curl -fLSs https://raw.githubusercontent.com/CircleCI-Public/circleci-cli/main/install.sh | DESTDIR=$CIRCLECI_BINARY bash
node build.js
name: Pack config.yml
- run:
name: Set params
command: node .circleci/config/params.js
- continuation/continue:
configuration_path: .circleci/config-staging/built.yml
parameters: /tmp/pipeline-parameters.json

View File

@@ -35,6 +35,16 @@ parameters:
default: all
enum: ["all", "osx-x64", "osx-arm64", "mas-x64", "mas-arm64"]
medium-linux-executor:
type: enum
default: electronjs/aks-linux-medium
enum: ["electronjs/aks-linux-medium", "medium"]
large-linux-executor:
type: enum
default: electronjs/aks-linux-large
enum: ["electronjs/aks-linux-large", "2xlarge"]
# Executors
executors:
linux-docker:
@@ -42,9 +52,9 @@ executors:
size:
description: "Docker executor size"
type: enum
# aks-linux-medium === 8 core (32 core host, shared with other builds)
# aks-linux-large === 32 core
enum: ["medium", "xlarge", "electronjs/aks-linux-medium", "electronjs/aks-linux-large"]
# 2xlarge should not be used directly, use the pipeline param instead
enum: ["medium", "electronjs/aks-linux-medium", "xlarge", "electronjs/aks-linux-large", "2xlarge"]
docker:
- image: ghcr.io/electron/build:e6bebd08a51a0d78ec23e5b3fd7e7c0846412328
resource_class: << parameters.size >>
@@ -349,7 +359,7 @@ step-setup-goma-for-build: &step-setup-goma-for-build
exit 1
fi
echo 'export GN_GOMA_FILE='`node -e "console.log(require('./src/utils/goma.js').gnFilePath)"` >> $BASH_ENV
echo 'export LOCAL_GOMA_DIR='`node -e "console.log(require('./src/utils/goma.js').dir)"` >> $BASH_ENV
echo 'export GOMA_DIR='`node -e "console.log(require('./src/utils/goma.js').dir)"` >> $BASH_ENV
echo 'export GOMA_FALLBACK_ON_AUTH_FAILURE=true' >> $BASH_ENV
cd ..
touch "${TMPDIR:=/tmp}"/.goma-ready
@@ -744,8 +754,8 @@ step-show-goma-stats: &step-show-goma-stats
command: |
set +e
set +o pipefail
$LOCAL_GOMA_DIR/goma_ctl.py stat
$LOCAL_GOMA_DIR/diagnose_goma_log.py
python3 $GOMA_DIR/goma_ctl.py stat
python3 $GOMA_DIR/diagnose_goma_log.py
true
when: always
background: true
@@ -895,14 +905,26 @@ step-touch-sync-done: &step-touch-sync-done
step-maybe-restore-src-cache: &step-maybe-restore-src-cache
restore_cache:
keys:
- v16-src-cache-{{ checksum "src/electron/.depshash" }}
- v17-src-cache-{{ checksum "src/electron/.depshash" }}
name: Restoring src cache
step-maybe-restore-src-cache-marker: &step-maybe-restore-src-cache-marker
restore_cache:
keys:
- v16-src-cache-marker-{{ checksum "src/electron/.depshash" }}
- v17-src-cache-marker-{{ checksum "src/electron/.depshash" }}
name: Restoring src cache marker
step-maybe-restore-src-cache-aks: &step-maybe-restore-src-cache-aks
restore_cache_aks:
step-name: Restoring src cache
cache_key: v17-src-cache-$(shasum src/electron/.depshash | cut -f1 -d' ')
cache_path: /var/portal
step-maybe-restore-src-cache-marker-aks: &step-maybe-restore-src-cache-marker-aks
restore_cache_aks:
step-name: Restoring src cache marker
cache_key: v17-src-cache-marker-$(shasum src/electron/.depshash | cut -f1 -d' ')
cache_path: "."
# Restore exact or closest git cache based on the hash of DEPS and .circle-sync-done
# If the src cache was restored above then this will match an empty cache
# If the src cache was not restored above then this will match a close git cache
@@ -915,6 +937,12 @@ step-maybe-restore-git-cache: &step-maybe-restore-git-cache
- v1-git-cache-{{ checksum "src/electron/.circle-sync-done" }}
name: Conditionally restoring git cache
step-maybe-restore-git-cache-aks: &step-maybe-restore-git-cache-aks
restore_cache_aks:
step-name: Conditionally restoring git cache (aks)
cache_key: v1-git-cache-$(shasum src/electron/.circle-sync-done | cut -f1 -d' ')-$(shasum src/electron/DEPS | cut -f1 -d' ') v1-git-cache-$(shasum src/electron/.circle-sync-done | cut -f1 -d' ')
cache_path: git-cache
step-set-git-cache-path: &step-set-git-cache-path
run:
name: Set GIT_CACHE_PATH to make gclient to use the cache
@@ -932,6 +960,12 @@ step-save-git-cache: &step-save-git-cache
key: v1-git-cache-{{ checksum "src/electron/.circle-sync-done" }}-{{ checksum "src/electron/DEPS" }}
name: Persisting git cache
step-save-git-cache-aks: &step-save-git-cache-aks
save_cache_aks:
step-name: Persisting git cache (AKS)
cache_key: v1-git-cache-$(shasum src/electron/.circle-sync-done | cut -f1 -d' ')-$(shasum src/electron/DEPS | cut -f1 -d' ')
cache_path: git-cache
step-run-electron-only-hooks: &step-run-electron-only-hooks
run:
name: Run Electron Only Hooks
@@ -969,7 +1003,7 @@ step-save-src-cache: &step-save-src-cache
save_cache:
paths:
- /var/portal
key: v16-src-cache-{{ checksum "/var/portal/src/electron/.depshash" }}
key: v17-src-cache-{{ checksum "/var/portal/src/electron/.depshash" }}
name: Persisting src cache
step-make-src-cache-marker: &step-make-src-cache-marker
run:
@@ -979,7 +1013,17 @@ step-save-src-cache-marker: &step-save-src-cache-marker
save_cache:
paths:
- .src-cache-marker
key: v16-src-cache-marker-{{ checksum "/var/portal/src/electron/.depshash" }}
key: v17-src-cache-marker-{{ checksum "/var/portal/src/electron/.depshash" }}
step-save-src-cache-aks: &step-save-src-cache-aks
save_cache_aks:
step-name: Persisting src cache (aks)
cache_key: v17-src-cache-$(shasum /var/portal/src/electron/.depshash | cut -f1 -d' ')
cache_path: /var/portal
step-save-src-cache-marker-aks: &step-save-src-cache-marker-aks
save_cache_aks:
step-name: Persisting src cache marker (aks)
cache_key: v17-src-cache-marker-$(shasum /var/portal/src/electron/.depshash | cut -f1 -d' ')
cache_path: .src-cache-marker
step-maybe-early-exit-no-doc-change: &step-maybe-early-exit-no-doc-change
run:
@@ -1005,15 +1049,6 @@ step-ts-compile: &step-ts-compile
done
# List of all steps.
steps-electron-gn-check: &steps-electron-gn-check
steps:
- *step-setup-goma-for-build
- checkout-from-cache
- *step-setup-env-for-build
- *step-wait-for-goma
- *step-gn-gen-default
- *step-gn-check
steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-change
steps:
# Checkout - Copied from steps-checkout
@@ -1025,11 +1060,92 @@ steps-electron-ts-compile-for-doc-change: &steps-electron-ts-compile-for-doc-cha
# Command Aliases
commands:
aks-specific-step:
parameters:
circle:
type: steps
aks:
type: steps
could-be-aks:
type: boolean
description: Only set this to true on linux hosts
steps:
- when:
condition:
or:
- equal: [<< parameters.could-be-aks >>, false]
- equal: [<< pipeline.parameters.large-linux-executor >>, 2xlarge]
steps: << parameters.circle >>
- when:
condition:
and:
- equal: [<< parameters.could-be-aks >>, true]
- equal: [<< pipeline.parameters.large-linux-executor >>, electronjs/aks-linux-large]
steps: << parameters.aks >>
save_cache_aks:
parameters:
step-name:
type: string
cache_key:
type: string
cache_path:
type: string
steps:
- run:
name: << parameters.step-name >>
command: |
cache_key="<< parameters.cache_key >>"
final_cache_path=/mnt/cross-instance-cache/${cache_key}.tar
echo "Using cache key: $cache_key"
echo "Checking path: $final_cache_path"
if [ ! -f "$final_cache_path" ]; then
echo "Cache key not founding, storing tarball"
tmp_container=/mnt/cross-instance-cache/tmp/$CIRCLE_WORKFLOW_JOB_ID
tmp_cache_path=$tmp_container/${cache_key}.tar
mkdir -p $tmp_container
if [ -f "<< parameters.cache_path >>" ]; then
tar -cf $tmp_cache_path -C $(dirname << parameters.cache_path >>) ./$(basename << parameters.cache_path >>)
else
tar -cf $tmp_cache_path -C << parameters.cache_path >>/ ./
fi
mv -vn $tmp_cache_path $final_cache_path
rm -rf $tmp_container
else
echo "Cache key already exists, skipping.."
fi
restore_cache_aks:
parameters:
step-name:
type: string
cache_key:
type: string
cache_path:
type: string
steps:
- run:
name: << parameters.step-name >>
command: |
df -h
for cache_key in << parameters.cache_key >>; do
cache_path=/mnt/cross-instance-cache/${cache_key}.tar
echo "Using cache key: $cache_key"
echo "Checking path: $cache_path"
if [ ! -f "$cache_path" ]; then
echo "Cache key not found, nothing to restore..."
else
echo "Cache key found, restoring to path..."
mkdir -p << parameters.cache_path >>/
tar -xf /mnt/cross-instance-cache/${cache_key}.tar -C << parameters.cache_path >>/
exit 0
fi
done
maybe-restore-portaled-src-cache:
parameters:
halt-if-successful:
type: boolean
default: false
could-be-aks:
type: boolean
steps:
- run:
name: Prepare for cross-OS sync restore
@@ -1039,23 +1155,44 @@ commands:
- when:
condition: << parameters.halt-if-successful >>
steps:
- *step-maybe-restore-src-cache-marker
- aks-specific-step:
circle:
- *step-maybe-restore-src-cache-marker
aks:
- *step-maybe-restore-src-cache-marker-aks
could-be-aks: << parameters.could-be-aks >>
- run:
name: Halt the job early if the src cache exists
command: |
if [ -f ".src-cache-marker" ]; then
circleci-agent step halt
fi
- *step-maybe-restore-src-cache
- aks-specific-step:
circle:
- *step-maybe-restore-src-cache
aks:
- *step-maybe-restore-src-cache-aks
could-be-aks: << parameters.could-be-aks >>
- run:
name: Fix the src cache restore point on macOS
name: Fix the src cache restore point
command: |
if [ -d "/var/portal/src" ]; then
echo Relocating Cache
rm -rf src
mv /var/portal/src ./
fi
run-gn-check:
parameters:
could-be-aks:
type: boolean
steps:
- *step-setup-goma-for-build
- checkout-from-cache:
could-be-aks: << parameters.could-be-aks >>
- *step-setup-env-for-build
- *step-wait-for-goma
- *step-gn-gen-default
- *step-gn-check
build_and_save_artifacts:
parameters:
artifact-key:
@@ -1169,12 +1306,16 @@ commands:
mv_if_exist cross-arch-snapshots src
checkout-from-cache:
parameters:
could-be-aks:
type: boolean
steps:
- *step-checkout-electron
- *step-depot-tools-get
- *step-depot-tools-add-to-path
- *step-generate-deps-hash
- maybe-restore-portaled-src-cache
- maybe-restore-portaled-src-cache:
could-be-aks: << parameters.could-be-aks >>
- run:
name: Ensure src checkout worked
command: |
@@ -1286,6 +1427,8 @@ commands:
after-persist:
type: steps
default: []
could-be-aks:
type: boolean
steps:
- when:
condition: << parameters.attach >>
@@ -1303,7 +1446,8 @@ commands:
- when:
condition: << parameters.checkout-and-assume-cache >>
steps:
- checkout-from-cache
- checkout-from-cache:
could-be-aks: << parameters.could-be-aks >>
- when:
condition: << parameters.checkout >>
steps:
@@ -1319,8 +1463,15 @@ commands:
steps:
- maybe-restore-portaled-src-cache:
halt-if-successful: << parameters.checkout-to-create-src-cache >>
- *step-maybe-restore-git-cache
could-be-aks: << parameters.could-be-aks >>
- aks-specific-step:
circle:
- *step-maybe-restore-git-cache
aks:
- *step-maybe-restore-git-cache-aks
could-be-aks: << parameters.could-be-aks >>
- *step-set-git-cache-path
- *step-fix-known-hosts-linux
# This sync call only runs if .circle-sync-done is an EMPTY file
- *step-gclient-sync
- store_artifacts:
@@ -1336,7 +1487,12 @@ commands:
- when:
condition: << parameters.save-git-cache >>
steps:
- *step-save-git-cache
- aks-specific-step:
circle:
- *step-save-git-cache
aks:
- *step-save-git-cache-aks
could-be-aks: << parameters.could-be-aks >>
# Mark sync as done _after_ saving the git cache so that it is uploaded
# only when the src cache was not present
# Their are theoretically two cases for this cache key
@@ -1386,9 +1542,19 @@ commands:
sudo mkdir -p /var/portal
sudo chown -R $(id -u):$(id -g) /var/portal
mv ./src /var/portal
- *step-save-src-cache
- aks-specific-step:
circle:
- *step-save-src-cache
aks:
- *step-save-src-cache-aks
could-be-aks: << parameters.could-be-aks >>
- *step-make-src-cache-marker
- *step-save-src-cache-marker
- aks-specific-step:
circle:
- *step-save-src-cache-marker
aks:
- *step-save-src-cache-marker-aks
could-be-aks: << parameters.could-be-aks >>
- when:
condition: << parameters.build >>
@@ -1442,6 +1608,18 @@ commands:
condition: << parameters.build >>
steps:
- *step-maybe-notify-slack-failure
- when:
condition: << parameters.could-be-aks >>
steps:
- run:
name: Wait for active debug sessions
command: |
while [ -f /var/.ssh-lock ]
do
sleep 60
done
no_output_timeout: 2h
when: always
electron-tests:
parameters:
@@ -1628,7 +1806,7 @@ jobs:
linux-make-src-cache:
executor:
name: linux-docker
size: xlarge
size: << pipeline.parameters.large-linux-executor >>
environment:
<<: *env-linux-2xlarge
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
@@ -1641,6 +1819,7 @@ jobs:
checkout-to-create-src-cache: true
artifact-key: 'nil'
build-type: 'nil'
could-be-aks: true
mac-checkout:
executor:
@@ -1660,6 +1839,7 @@ jobs:
restore-src-cache: false
artifact-key: 'nil'
build-type: 'nil'
could-be-aks: false
mac-make-src-cache-x64:
executor:
@@ -1679,6 +1859,7 @@ jobs:
checkout-to-create-src-cache: true
artifact-key: 'nil'
build-type: 'nil'
could-be-aks: false
mac-make-src-cache-arm64:
executor:
@@ -1698,12 +1879,13 @@ jobs:
checkout-to-create-src-cache: true
artifact-key: 'nil'
build-type: 'nil'
could-be-aks: false
# Layer 2: Builds.
linux-x64-testing:
executor:
name: linux-docker
size: electronjs/aks-linux-large
size: << pipeline.parameters.large-linux-executor >>
environment:
<<: *env-global
<<: *env-testing-build
@@ -1716,11 +1898,12 @@ jobs:
checkout-and-assume-cache: true
artifact-key: 'linux-x64'
build-type: 'Linux'
could-be-aks: true
linux-x64-testing-asan:
executor:
name: linux-docker
size: electronjs/aks-linux-large
size: << pipeline.parameters.large-linux-executor >>
environment:
<<: *env-global
<<: *env-testing-build
@@ -1731,25 +1914,29 @@ jobs:
steps:
- electron-build:
persist: true
checkout: true
checkout: false
checkout-and-assume-cache: true
build-nonproprietary-ffmpeg: false
artifact-key: 'linux-x64-asan'
build-type: 'Linux'
could-be-aks: true
linux-x64-testing-gn-check:
executor:
name: linux-docker
size: medium
size: << pipeline.parameters.medium-linux-executor >>
environment:
<<: *env-linux-medium
<<: *env-testing-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-gn-check
steps:
- run-gn-check:
could-be-aks: true
linux-x64-publish:
executor:
name: linux-docker
size: electronjs/aks-linux-large
size: << pipeline.parameters.large-linux-executor >>
environment:
<<: *env-linux-2xlarge-release
<<: *env-release-build
@@ -1772,7 +1959,7 @@ jobs:
linux-arm-testing:
executor:
name: linux-docker
size: electronjs/aks-linux-large
size: << pipeline.parameters.large-linux-executor >>
environment:
<<: *env-global
<<: *env-arm
@@ -1788,11 +1975,12 @@ jobs:
checkout-and-assume-cache: true
artifact-key: 'linux-arm'
build-type: 'Linux ARM'
could-be-aks: true
linux-arm-publish:
executor:
name: linux-docker
size: electronjs/aks-linux-large
size: << pipeline.parameters.large-linux-executor >>
environment:
<<: *env-linux-2xlarge-release
<<: *env-arm
@@ -1817,7 +2005,7 @@ jobs:
linux-arm64-testing:
executor:
name: linux-docker
size: electronjs/aks-linux-large
size: << pipeline.parameters.large-linux-executor >>
environment:
<<: *env-global
<<: *env-arm64
@@ -1833,22 +2021,25 @@ jobs:
checkout-and-assume-cache: true
artifact-key: 'linux-arm64'
build-type: 'Linux ARM64'
could-be-aks: true
linux-arm64-testing-gn-check:
executor:
name: linux-docker
size: medium
size: << pipeline.parameters.medium-linux-executor >>
environment:
<<: *env-linux-medium
<<: *env-arm64
<<: *env-testing-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
<<: *steps-electron-gn-check
steps:
- run-gn-check:
could-be-aks: true
linux-arm64-publish:
executor:
name: linux-docker
size: electronjs/aks-linux-large
size: << pipeline.parameters.large-linux-executor >>
environment:
<<: *env-linux-2xlarge-release
<<: *env-arm64
@@ -1903,6 +2094,7 @@ jobs:
root: .
paths:
- generated_artifacts_mas-x64
could-be-aks: false
osx-testing-x64-gn-check:
executor:
@@ -1912,7 +2104,9 @@ jobs:
<<: *env-machine-mac
<<: *env-testing-build
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
<<: *steps-electron-gn-check
steps:
- run-gn-check:
could-be-aks: false
osx-publish-x64:
executor:
@@ -1994,6 +2188,7 @@ jobs:
root: .
paths:
- generated_artifacts_mas-arm64
could-be-aks: false
mas-publish-x64:
executor:

View File

@@ -0,0 +1,12 @@
const fs = require('fs');
const PARAMS_PATH = '/tmp/pipeline-parameters.json';
const content = JSON.parse(fs.readFileSync(PARAMS_PATH, 'utf-8'));
// Choose resource class for linux hosts
const currentBranch = process.env.CIRCLE_BRANCH || '';
content['large-linux-executor'] = /^pull\/[0-9-]+$/.test(currentBranch) ? '2xlarge' : 'electronjs/aks-linux-large';
content['medium-linux-executor'] = /^pull\/[0-9-]+$/.test(currentBranch) ? 'medium' : 'electronjs/aks-linux-medium';
fs.writeFileSync(PARAMS_PATH, JSON.stringify(content));

2
DEPS
View File

@@ -2,7 +2,7 @@ gclient_gn_args_from = 'src'
vars = {
'chromium_version':
'118.0.5993.5',
'118.0.5993.54',
'node_version':
'v18.17.1',
'nan_version':

View File

@@ -202,6 +202,10 @@ static_library("chrome") {
"//chrome/browser/ui/views/status_icons/status_icon_linux_dbus.cc",
"//chrome/browser/ui/views/status_icons/status_icon_linux_dbus.h",
]
sources += [
"//chrome/browser/ui/views/dark_mode_manager_linux.cc",
"//chrome/browser/ui/views/dark_mode_manager_linux.h",
]
public_deps += [
"//components/dbus/menu",
"//components/dbus/thread_linux",
@@ -319,6 +323,34 @@ static_library("chrome") {
"//components/pdf/renderer",
]
}
} else {
# These are required by the webRequest module.
sources += [
"//extensions/browser/api/declarative_net_request/request_action.cc",
"//extensions/browser/api/declarative_net_request/request_action.h",
"//extensions/browser/api/web_request/form_data_parser.cc",
"//extensions/browser/api/web_request/form_data_parser.h",
"//extensions/browser/api/web_request/upload_data_presenter.cc",
"//extensions/browser/api/web_request/upload_data_presenter.h",
"//extensions/browser/api/web_request/web_request_api_constants.cc",
"//extensions/browser/api/web_request/web_request_api_constants.h",
"//extensions/browser/api/web_request/web_request_info.cc",
"//extensions/browser/api/web_request/web_request_info.h",
"//extensions/browser/api/web_request/web_request_resource_type.cc",
"//extensions/browser/api/web_request/web_request_resource_type.h",
"//extensions/browser/extension_api_frame_id_map.cc",
"//extensions/browser/extension_api_frame_id_map.h",
"//extensions/browser/extension_navigation_ui_data.cc",
"//extensions/browser/extension_navigation_ui_data.h",
"//extensions/browser/extensions_browser_client.cc",
"//extensions/browser/extensions_browser_client.h",
"//extensions/browser/guest_view/web_view/web_view_renderer_state.cc",
"//extensions/browser/guest_view/web_view/web_view_renderer_state.h",
]
public_deps += [
"//extensions/browser/api/declarative_net_request/flat:extension_ruleset",
]
}
if (!is_mas_build) {

View File

@@ -505,6 +505,10 @@ events.
A `Integer` property representing the unique ID of the window. Each ID is unique among all `BrowserWindow` instances of the entire Electron application.
#### `win.tabbingIdentifier` _macOS_ _Readonly_
A `string` (optional) property that is equal to the `tabbingIdentifier` passed to the `BrowserWindow` constructor or `undefined` if none was set.
#### `win.autoHideMenuBar`
A `boolean` property that determines whether the window menu bar should hide itself automatically. Once set, the menu bar will only show when users press the single `Alt` key.

View File

@@ -119,4 +119,8 @@ Removes the cookies matching `url` and `name`
Returns `Promise<void>` - A promise which resolves when the cookie store has been flushed
Writes any unwritten cookies data to disk.
Writes any unwritten cookies data to disk
Cookies written by any method will not be written to disk immediately, but will be written every 30 seconds or 512 operations
Calling this method can cause the cookie to be written to disk immediately.

View File

@@ -273,7 +273,6 @@ This API is only available on macOS 10.14 Mojave or newer.
* `window-frame` - Window frame.
* `window-text` - Text in windows.
* On **macOS**
* `alternate-selected-control-text` - The text on a selected surface in a list or table. _Deprecated_
* `control-background` - The background of a large interface element, such as a browser or table.
* `control` - The surface of a control.
* `control-text` -The text of a control that isnt disabled.
@@ -339,21 +338,6 @@ Returns `string` - Can be `dark`, `light` or `unknown`.
Gets the macOS appearance setting that is currently applied to your application,
maps to [NSApplication.effectiveAppearance](https://developer.apple.com/documentation/appkit/nsapplication/2967171-effectiveappearance?language=objc)
### `systemPreferences.getAppLevelAppearance()` _macOS_ _Deprecated_
Returns `string` | `null` - Can be `dark`, `light` or `unknown`.
Gets the macOS appearance setting that you have declared you want for
your application, maps to [NSApplication.appearance](https://developer.apple.com/documentation/appkit/nsapplication/2967170-appearance?language=objc).
You can use the `setAppLevelAppearance` API to set this value.
### `systemPreferences.setAppLevelAppearance(appearance)` _macOS_ _Deprecated_
* `appearance` string | null - Can be `dark` or `light`
Sets the appearance setting for your application, this should override the
system default and override the value of `getEffectiveAppearance`.
### `systemPreferences.canPromptTouchID()` _macOS_
Returns `boolean` - whether or not this device has the ability to use Touch ID.
@@ -417,15 +401,9 @@ Returns an object with system animation settings.
## Properties
### `systemPreferences.appLevelAppearance` _macOS_ _Deprecated_
### `systemPreferences.accessibilityDisplayShouldReduceTransparency()` _macOS_
A `string` property that can be `dark`, `light` or `unknown`. It determines the macOS appearance setting for
your application. This maps to values in: [NSApplication.appearance](https://developer.apple.com/documentation/appkit/nsapplication/2967170-appearance?language=objc). Setting this will override the
system default as well as the value of `getEffectiveAppearance`.
Possible values that can be set are `dark` and `light`, and possible return values are `dark`, `light`, and `unknown`.
This property is only available on macOS 10.14 Mojave or newer.
A `boolean` property which determines whether the app avoids using semitransparent backgrounds. This maps to [NSWorkspace.accessibilityDisplayShouldReduceTransparency](https://developer.apple.com/documentation/appkit/nsworkspace/1533006-accessibilitydisplayshouldreduce)
### `systemPreferences.effectiveAppearance` _macOS_ _Readonly_

View File

@@ -61,6 +61,41 @@ w.webContents.getPrintersAsync().then((printers) => {
})
```
### Removed: `systemPreferences.{get,set}AppLevelAppearance` and `systemPreferences.appLevelAppearance`
The `systemPreferences.getAppLevelAppearance` and `systemPreferences.setAppLevelAppearance`
methods have been removed, as well as the `systemPreferences.appLevelAppearance` property.
Use the `nativeTheme` module instead.
```js
// Removed
systemPreferences.getAppLevelAppearance()
// Replace with
nativeTheme.shouldUseDarkColors
// Removed
systemPreferences.appLevelAppearance
// Replace with
nativeTheme.shouldUseDarkColors
// Removed
systemPreferences.setAppLevelAppearance('dark')
// Replace with
nativeTheme.themeSource = 'dark'
```
### Removed: `alternate-selected-control-text` value for `systemPreferences.getColor`
The `alternate-selected-control-text` value for `systemPreferences.getColor`
has been removed. Use `selected-content-background` instead.
```js
// Removed
systemPreferences.getColor('alternate-selected-control-text')
// Replace with
systemPreferences.getColor('selected-content-background')
```
## Planned Breaking API Changes (26.0)
### Deprecated: `webContents.getPrinters`
@@ -635,6 +670,18 @@ to open synchronously scriptable child windows, among other incompatibilities.
See the documentation for [window.open in Electron](api/window-open.md)
for more details.
### Deprecated: `app.runningUnderRosettaTranslation`
The `app.runningUnderRosettaTranslation` property has been deprecated.
Use `app.runningUnderARM64Translation` instead.
```js
// Deprecated
console.log(app.runningUnderRosettaTranslation)
// Replace with
console.log(app.runningUnderARM64Translation)
```
## Planned Breaking API Changes (14.0)
### Removed: `remote` module

View File

@@ -12,7 +12,7 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
| 27.0.0 | 2023-Aug-17 | 2023-Sep-13 | 2023-Oct-10 | TBD | M118 | TBD | ✅ |
| 26.0.0 | 2023-Jun-01 | 2023-Jun-27 | 2023-Aug-15 | 2024-Feb-27 | M116 | v18.16 | ✅ |
| 25.0.0 | 2023-Apr-10 | 2023-May-02 | 2023-May-30 | 2024-Jan-02 | M114 | v18.15 | ✅ |
| 24.0.0 | 2022-Feb-09 | 2023-Mar-07 | 2023-Apr-04 | 2023-Oct-10 | M112 | v18.14 | ✅ |
| 24.0.0 | 2023-Feb-09 | 2023-Mar-07 | 2023-Apr-04 | 2023-Oct-10 | M112 | v18.14 | ✅ |
| 23.0.0 | 2022-Dec-01 | 2023-Jan-10 | 2023-Feb-07 | 2023-Aug-15 | M110 | v18.12 | 🚫 |
| 22.0.0 | 2022-Sep-29 | 2022-Oct-25 | 2022-Nov-29 | 2023-Oct-10 | M108 | v16.17 | ✅ |
| 21.0.0 | 2022-Aug-04 | 2022-Aug-30 | 2022-Sep-27 | 2023-Apr-04 | M106 | v16.16 | 🚫 |

View File

@@ -228,6 +228,23 @@ channel with a renderer process using [`MessagePort`][]s. An Electron app can
always prefer the [UtilityProcess][] API over Node.js [`child_process.fork`][] API when
there is need to fork a child process from the main process.
## Process-specific module aliases (TypeScript)
Electron's npm package also exports subpaths that contain a subset of
Electron's TypeScript type definitions.
- `electron/main` includes types for all main process modules.
- `electron/renderer` includes types for all renderer process modules.
- `electron/common` includes types for modules that can run in main and renderer processes.
These aliases have no impact on runtime, but can be used for typechecking
and autocomplete.
```js title="Usage example"
const { app } = require('electron/main')
const { shell } = require('electron/common')
```
[window-mdn]: https://developer.mozilla.org/en-US/docs/Web/API/Window
[`MessagePort`]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort
[`child_process.fork`]: https://nodejs.org/dist/latest-v16.x/docs/api/child_process.html#child_processforkmodulepath-args-options

View File

@@ -91,14 +91,14 @@ version: '0.1'
summary: Hello World Electron app
description: |
Simple Hello World Electron app as an example
base: core18
base: core22
confinement: strict
grade: stable
apps:
electron-packager-hello-world:
command: electron-quick-start/electron-quick-start --no-sandbox
extensions: [gnome-3-34]
extensions: [gnome]
plugs:
- browser-support
- network
@@ -237,6 +237,34 @@ apps:
desktop: usr/share/applications/desktop.desktop
```
## Optional: Enabling desktop capture
Capturing the desktop requires PipeWire library in some Linux configurations that use
the Wayland protocol. To bundle PipeWire with your application, ensure that the base
snap is set to `core22` or newer. Next, create a part called `pipewire` and add it to
the `after` section of your application:
```yaml
pipewire:
plugin: nil
build-packages: [libpipewire-0.3-dev]
stage-packages: [pipewire]
prime:
- usr/lib/*/pipewire-*
- usr/lib/*/spa-*
- usr/lib/*/libpipewire*.so*
- usr/share/pipewire
```
Finally, configure your application's environment for PipeWire:
```yaml
environment:
SPA_PLUGIN_DIR: $SNAP/usr/lib/$CRAFT_ARCH_TRIPLET/spa-0.2
PIPEWIRE_CONFIG_NAME: $SNAP/usr/share/pipewire/pipewire.conf
PIPEWIRE_MODULE_DIR: $SNAP/usr/lib/$CRAFT_ARCH_TRIPLET/pipewire-0.3
```
[snapcraft-syntax]: https://docs.snapcraft.io/build-snaps/syntax
[electron-packager]: https://github.com/electron/electron-packager
[electron-forge]: https://github.com/electron/forge

View File

@@ -222,14 +222,26 @@ with CommonJS module syntax:
- [app][app], which controls your application's event lifecycle.
- [BrowserWindow][browser-window], which creates and manages app windows.
:::info Capitalization conventions
<details><summary>Module capitalization conventions</summary>
You might have noticed the capitalization difference between the **a**pp
and **B**rowser**W**indow modules. Electron follows typical JavaScript conventions here,
where PascalCase modules are instantiable class constructors (e.g. BrowserWindow, Tray,
Notification) whereas camelCase modules are not instantiable (e.g. app, ipcRenderer, webContents).
:::
</details>
<details><summary>Typed import aliases</summary>
For better type checking when writing TypeScript code, you can choose to import
main process modules from <code>electron/main</code>.
```js
const { app, BrowserWindow } = require('electron/main')
```
For more information, see the [Process Model docs](../tutorial/process-model.md#process-specific-module-aliases-typescript).
</details>
:::warning ES Modules in Electron

View File

@@ -1,4 +1,5 @@
import { Buffer } from 'buffer';
import { constants } from 'fs';
import * as path from 'path';
import * as util from 'util';
import type * as Crypto from 'crypto';
@@ -27,7 +28,7 @@ const cachedArchives = new Map<string, NodeJS.AsarArchive>();
const getOrCreateArchive = (archivePath: string) => {
const isCached = cachedArchives.has(archivePath);
if (isCached) {
return cachedArchives.get(archivePath);
return cachedArchives.get(archivePath)!;
}
try {
@@ -39,6 +40,8 @@ const getOrCreateArchive = (archivePath: string) => {
}
};
process._getOrCreateArchive = getOrCreateArchive;
const asarRe = /\.asar/i;
// Separate asar package's path from full path.
@@ -65,18 +68,22 @@ const gid = process.getgid?.() ?? 0;
const fakeTime = new Date();
enum AsarFileType {
kFile = (constants as any).UV_DIRENT_FILE,
kDirectory = (constants as any).UV_DIRENT_DIR,
kLink = (constants as any).UV_DIRENT_LINK,
}
const fileTypeToMode = new Map<AsarFileType, number>([
[AsarFileType.kFile, constants.S_IFREG],
[AsarFileType.kDirectory, constants.S_IFDIR],
[AsarFileType.kLink, constants.S_IFLNK]
]);
const asarStatsToFsStats = function (stats: NodeJS.AsarFileStat) {
const { Stats, constants } = require('fs');
const { Stats } = require('fs');
let mode = constants.S_IROTH ^ constants.S_IRGRP ^ constants.S_IRUSR ^ constants.S_IWUSR;
if (stats.isFile) {
mode ^= constants.S_IFREG;
} else if (stats.isDirectory) {
mode ^= constants.S_IFDIR;
} else if (stats.isLink) {
mode ^= constants.S_IFLNK;
}
const mode = constants.S_IROTH | constants.S_IRGRP | constants.S_IRUSR | constants.S_IWUSR | fileTypeToMode.get(stats.type)!;
return new Stats(
1, // dev
@@ -239,7 +246,6 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
const logASARAccess = (asarPath: string, filePath: string, offset: number) => {
if (!process.env.ELECTRON_LOG_ASAR_READS) return;
if (!logFDs.has(asarPath)) {
const path = require('path');
const logFilename = `${path.basename(asarPath, '.asar')}-access-log.txt`;
const logPath = path.join(require('os').tmpdir(), logFilename);
logFDs.set(asarPath, fs.openSync(logPath, 'a'));
@@ -655,13 +661,7 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
nextTick(callback!, [error]);
return;
}
if (stats.isFile) {
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
} else if (stats.isDirectory) {
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_DIR));
} else if (stats.isLink) {
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_LINK));
}
dirents.push(new fs.Dirent(file, stats.type));
}
nextTick(callback!, [null, dirents]);
return;
@@ -698,13 +698,7 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
if (!stats) {
throw createError(AsarError.NOT_FOUND, { asarPath, filePath: childPath });
}
if (stats.isFile) {
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_FILE));
} else if (stats.isDirectory) {
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_DIR));
} else if (stats.isLink) {
dirents.push(new fs.Dirent(file, fs.constants.UV_DIRENT_LINK));
}
dirents.push(new fs.Dirent(file, stats.type));
}
return dirents;
}
@@ -755,7 +749,7 @@ export const wrapFsWithAsar = (fs: Record<string, any>) => {
const stats = archive.stat(filePath);
if (!stats) return -34;
return (stats.isDirectory) ? 1 : 0;
return (stats.type === AsarFileType.kDirectory) ? 1 : 0;
};
// Calling mkdir for directory inside asar archive should throw ENOTDIR

View File

@@ -114,5 +114,11 @@ for (const name of events) {
}
// Deprecation.
deprecate.event(app, 'gpu-process-crashed', 'child-process-gone');
deprecate.event(app, 'renderer-process-crashed', 'render-process-gone');
deprecate.event(app, 'gpu-process-crashed', 'child-process-gone', () => {
// the old event is still emitted by App::OnGpuProcessCrashed()
return undefined;
});
deprecate.event(app, 'renderer-process-crashed', 'render-process-gone', (event: Electron.Event, webContents: Electron.WebContents, details: Electron.RenderProcessGoneDetails) => {
return [event, webContents, details.reason === 'killed'];
});

View File

@@ -1,33 +1,5 @@
import * as deprecate from '@electron/internal/common/deprecate';
const { systemPreferences } = process._linkedBinding('electron_browser_system_preferences');
if ('getAppLevelAppearance' in systemPreferences) {
const nativeALAGetter = systemPreferences.getAppLevelAppearance;
const nativeALASetter = systemPreferences.setAppLevelAppearance;
const warnALA = deprecate.warnOnce('appLevelAppearance');
const warnALAGetter = deprecate.warnOnce('getAppLevelAppearance function');
const warnALASetter = deprecate.warnOnce('setAppLevelAppearance function');
Object.defineProperty(systemPreferences, 'appLevelAppearance', {
get: () => {
warnALA();
return nativeALAGetter.call(systemPreferences);
},
set: (appearance) => {
warnALA();
nativeALASetter.call(systemPreferences, appearance);
}
});
systemPreferences.getAppLevelAppearance = () => {
warnALAGetter();
return nativeALAGetter.call(systemPreferences);
};
systemPreferences.setAppLevelAppearance = (appearance) => {
warnALASetter();
nativeALASetter.call(systemPreferences, appearance);
};
}
if ('getEffectiveAppearance' in systemPreferences) {
const nativeEAGetter = systemPreferences.getEffectiveAppearance;
Object.defineProperty(systemPreferences, 'effectiveAppearance', {

View File

@@ -337,49 +337,53 @@ WebContents.prototype.printToPDF = async function (options) {
// TODO(codebytere): deduplicate argument sanitization by moving rest of
// print param logic into new file shared between printToPDF and print
WebContents.prototype.print = function (options: ElectronInternal.WebContentsPrintOptions, callback) {
if (typeof options === 'object') {
const pageSize = options.pageSize ?? 'A4';
if (typeof pageSize === 'object') {
if (!pageSize.height || !pageSize.width) {
throw new Error('height and width properties are required for pageSize');
}
if (typeof options !== 'object') {
throw new Error('webContents.print(): Invalid print settings specified.');
}
// Dimensions in Microns - 1 meter = 10^6 microns
const height = Math.ceil(pageSize.height);
const width = Math.ceil(pageSize.width);
if (!isValidCustomPageSize(width, height)) {
throw new Error('height and width properties must be minimum 352 microns.');
}
const printSettings: Record<string, any> = { ...options };
options.mediaSize = {
name: 'CUSTOM',
custom_display_name: 'Custom',
height_microns: height,
width_microns: width,
imageable_area_left_microns: 0,
imageable_area_bottom_microns: 0,
imageable_area_right_microns: width,
imageable_area_top_microns: height
};
} else if (typeof pageSize === 'string' && PDFPageSizes[pageSize]) {
const mediaSize = PDFPageSizes[pageSize];
options.mediaSize = {
...mediaSize,
imageable_area_left_microns: 0,
imageable_area_bottom_microns: 0,
imageable_area_right_microns: mediaSize.width_microns,
imageable_area_top_microns: mediaSize.height_microns
};
} else {
throw new Error(`Unsupported pageSize: ${pageSize}`);
const pageSize = options.pageSize ?? 'A4';
if (typeof pageSize === 'object') {
if (!pageSize.height || !pageSize.width) {
throw new Error('height and width properties are required for pageSize');
}
// Dimensions in Microns - 1 meter = 10^6 microns
const height = Math.ceil(pageSize.height);
const width = Math.ceil(pageSize.width);
if (!isValidCustomPageSize(width, height)) {
throw new Error('height and width properties must be minimum 352 microns.');
}
printSettings.mediaSize = {
name: 'CUSTOM',
custom_display_name: 'Custom',
height_microns: height,
width_microns: width,
imageable_area_left_microns: 0,
imageable_area_bottom_microns: 0,
imageable_area_right_microns: width,
imageable_area_top_microns: height
};
} else if (typeof pageSize === 'string' && PDFPageSizes[pageSize]) {
const mediaSize = PDFPageSizes[pageSize];
printSettings.mediaSize = {
...mediaSize,
imageable_area_left_microns: 0,
imageable_area_bottom_microns: 0,
imageable_area_right_microns: mediaSize.width_microns,
imageable_area_top_microns: mediaSize.height_microns
};
} else {
throw new Error(`Unsupported pageSize: ${pageSize}`);
}
if (this._print) {
if (callback) {
this._print(options, callback);
this._print(printSettings, callback);
} else {
this._print(options);
this._print(printSettings);
}
} else {
console.error('Error: Printing feature is disabled.');
@@ -653,8 +657,8 @@ WebContents.prototype._init = function () {
ipcMain.emit(channel, event, message);
});
this.on('crashed', (event, ...args) => {
app.emit('renderer-process-crashed', event, this, ...args);
deprecate.event(this, 'crashed', 'render-process-gone', (event: Electron.Event, details: Electron.RenderProcessGoneDetails) => {
return [event, details.reason === 'killed'];
});
this.on('render-process-gone', (event, details) => {

View File

@@ -84,11 +84,20 @@ const v8Util = process._linkedBinding('electron_common_v8_util');
let packagePath = null;
let packageJson = null;
const searchPaths: string[] = v8Util.getHiddenValue(global, 'appSearchPaths');
const searchPathsOnlyLoadASAR: boolean = v8Util.getHiddenValue(global, 'appSearchPathsOnlyLoadASAR');
// Borrow the _getOrCreateArchive asar helper
const getOrCreateArchive = process._getOrCreateArchive;
delete process._getOrCreateArchive;
if (process.resourcesPath) {
for (packagePath of searchPaths) {
try {
packagePath = path.join(process.resourcesPath, packagePath);
if (searchPathsOnlyLoadASAR) {
if (!getOrCreateArchive?.(packagePath)) {
continue;
}
}
packageJson = Module._load(path.join(packagePath, 'package.json'));
break;
} catch {

View File

@@ -66,14 +66,17 @@ export function renameFunction<T extends Function> (fn: T, newName: string): T {
}
// change the name of an event
export function event (emitter: NodeJS.EventEmitter, oldName: string, newName: string) {
export function event (emitter: NodeJS.EventEmitter, oldName: string, newName: string, transformer: (...args: any[]) => any[] | undefined = (...args) => args) {
const warn = newName.startsWith('-') /* internal event */
? warnOnce(`${oldName} event`)
: warnOnce(`${oldName} event`, `${newName} event`);
return emitter.on(newName, function (this: NodeJS.EventEmitter, ...args) {
if (this.listenerCount(oldName) !== 0) {
warn();
this.emit(oldName, ...args);
const transformedArgs = transformer(...args);
if (transformedArgs) {
this.emit(oldName, ...transformedArgs);
}
}
});
}

View File

@@ -128,5 +128,7 @@ fix_harden_blink_scriptstate_maybefrom.patch
chore_add_buildflag_guard_around_new_include.patch
fix_use_delegated_generic_capturer_when_available.patch
build_remove_ent_content_analysis_assert.patch
fix_activate_background_material_on_windows.patch
fix_move_autopipsettingshelper_behind_branding_buildflag.patch
revert_remove_the_allowaggressivethrottlingwithwebsocket_feature.patch
revert_same_party_cookie_attribute_removal.patch

View File

@@ -33,10 +33,10 @@ index 41ce32113ec2679b76d5a4fd69a7109c832ac7a1..1cd35794bf78f3d92b42634d9494c85a
"//base",
"//build:branding_buildflags",
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 1a9bff4a3efb7fd802db7ae9696027ee318eb7eb..85d2bc48117c7e41cfa49ea204d2c46f79a1c117 100644
index 9ab6c039d18f8759b8d7db9742d3570a7734f893..ae347df7a1b1a48723160787f71cfd1340f430ef 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -4723,7 +4723,7 @@ static_library("browser") {
@@ -4725,7 +4725,7 @@ static_library("browser") {
# On Windows, the hashes are embedded in //chrome:chrome_initial rather
# than here in :chrome_dll.
@@ -46,10 +46,10 @@ index 1a9bff4a3efb7fd802db7ae9696027ee318eb7eb..85d2bc48117c7e41cfa49ea204d2c46f
sources += [ "certificate_viewer_stub.cc" ]
}
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 6a2501dde4552c2b0d96dd54fc1b94ba1e610b0c..8d3cb67ae6d4fe65cfbb907309af734906b49949 100644
index 823cc89dd28ea78e12723fb3ff9389b05192b4ee..67f58bde17e0f2c0bf44139137411e8da60b3601 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -6838,7 +6838,6 @@ test("unit_tests") {
@@ -6841,7 +6841,6 @@ test("unit_tests") {
deps += [
"//chrome:other_version",
@@ -57,7 +57,7 @@ index 6a2501dde4552c2b0d96dd54fc1b94ba1e610b0c..8d3cb67ae6d4fe65cfbb907309af7349
"//chrome//services/util_win:unit_tests",
"//chrome/app:chrome_dll_resources",
"//chrome/app:win_unit_tests",
@@ -6864,6 +6863,10 @@ test("unit_tests") {
@@ -6867,6 +6866,10 @@ test("unit_tests") {
"//ui/resources",
]
@@ -68,7 +68,7 @@ index 6a2501dde4552c2b0d96dd54fc1b94ba1e610b0c..8d3cb67ae6d4fe65cfbb907309af7349
ldflags = [
"/DELAYLOAD:api-ms-win-core-winrt-error-l1-1-0.dll",
"/DELAYLOAD:api-ms-win-core-winrt-l1-1-0.dll",
@@ -7831,7 +7834,6 @@ test("unit_tests") {
@@ -7834,7 +7837,6 @@ test("unit_tests") {
}
deps += [
@@ -76,7 +76,7 @@ index 6a2501dde4552c2b0d96dd54fc1b94ba1e610b0c..8d3cb67ae6d4fe65cfbb907309af7349
"//chrome/browser/apps:icon_standardizer",
"//chrome/browser/apps/app_service",
"//chrome/browser/apps/app_service:app_registry_cache_waiter",
@@ -7918,6 +7920,10 @@ test("unit_tests") {
@@ -7921,6 +7923,10 @@ test("unit_tests") {
"//ui/webui/resources/js/browser_command:mojo_bindings",
]

View File

@@ -74,7 +74,7 @@ index 729753a72edd761ec831f79828742a26f9dd2417..45858456c9c8c82870c41b0edd1359d1
if (is_win) {
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 718ad3e088f6730bb00f1e3674effae6c429b9b6..77af941f2dd2d3074f5596cee24be47dc8175434 100644
index 368cf7aaffeef5f9796f78a72f13eddb6c44dec9..ade39af8ac41c91d4fd4b9a905ce5d836bea7d87 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -56,6 +56,7 @@ source_set("browser") {
@@ -110,10 +110,10 @@ index b16be8f9992b23ce93d174531f2debd7f18bb436..119038743dc222907cb74c2c3ea34d23
public_deps = [
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 581571b6bb1a655319b247d7cc85bb2a4dd7db1c..09779610326da207062a59ba572b2d7c13efd26f 100644
index 9efe02bc63033f9d2e39a97c95038eb27a1c2f93..1535e9346218c4b0dd71be53e8830b8d299561cc 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -480,6 +480,7 @@ static_library("test_support") {
@@ -481,6 +481,7 @@ static_library("test_support") {
configs += [
"//build/config:precompiled_headers",
"//v8:external_startup_data",

View File

@@ -9,7 +9,7 @@ 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 50d873e238b04eb6d461dc929d98dfe171cc491c..586aa87098bd3db10440fe865a02c05e7b3be14f 100644
index a1ccfc3c3081dc267414ff0fa52cc6b3e6e06140..9b6ce4a1a495986333a0d173749a9a095c2e5603 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -8206,6 +8206,7 @@ void RenderFrameHostImpl::CreateNewWindow(

View File

@@ -6,7 +6,7 @@ Subject: chore: patch out Profile methods in titlebar_config
Make this code linkable in Electron by removing Profile references.
diff --git a/chrome/browser/win/titlebar_config.cc b/chrome/browser/win/titlebar_config.cc
index 92d0e8165a264c7ef2701a66e0f7179f0d080f47..b0c91778399f811a5d1b0f208488667cb38459e1 100644
index f088a7071b1e0e1e05aee5637484b1dea3e2a6fa..8d411e550f6a8ca1a4070bf5d5719703f90b3dfa 100644
--- a/chrome/browser/win/titlebar_config.cc
+++ b/chrome/browser/win/titlebar_config.cc
@@ -19,8 +19,10 @@ BASE_FEATURE(kWindows11MicaTitlebar,

View File

@@ -22,7 +22,7 @@ index 42da00a0f473928263df89f11d80830b6986292b..6a556939d0acfbd910ebb0923e198e2f
virtual int GetSourceCount() const = 0;
virtual const Source& GetSource(int index) const = 0;
diff --git a/chrome/browser/media/webrtc/desktop_media_list_base.cc b/chrome/browser/media/webrtc/desktop_media_list_base.cc
index 0389599ac786b6abd61ca921347fe12ddd5d0ee7..780927301744ea7312f230cec76a24a33d71f767 100644
index 489e6f7b7b0bb52b938a4fc137b983f3330cd4d2..1f2754dae9b81a7d233539a7e4e6ac77b3c5941f 100644
--- a/chrome/browser/media/webrtc/desktop_media_list_base.cc
+++ b/chrome/browser/media/webrtc/desktop_media_list_base.cc
@@ -69,12 +69,12 @@ void DesktopMediaListBase::StartUpdating(DesktopMediaListObserver* observer) {
@@ -41,7 +41,7 @@ index 0389599ac786b6abd61ca921347fe12ddd5d0ee7..780927301744ea7312f230cec76a24a3
int DesktopMediaListBase::GetSourceCount() const {
diff --git a/chrome/browser/media/webrtc/desktop_media_list_base.h b/chrome/browser/media/webrtc/desktop_media_list_base.h
index b65012985ff1797203160d9e26af17fefee5c244..9ee211fb487007bd37b57cfa7b4ffbe5307af637 100644
index 2cd1000b90fb5af464f81ac25b63092b638c6d40..8f18adb5641b3fa5f9defd3490e20a5d86b672e9 100644
--- a/chrome/browser/media/webrtc/desktop_media_list_base.h
+++ b/chrome/browser/media/webrtc/desktop_media_list_base.h
@@ -39,7 +39,7 @@ class DesktopMediaListBase : public DesktopMediaList {
@@ -82,10 +82,10 @@ index 33ca7a53dfb6d2c9e3a33f0065a3acd806e82e01..9fdf2e8ff0056ff407015b914c6b03eb
const Source& GetSource(int index) const override;
DesktopMediaList::Type GetMediaListType() const override;
diff --git a/chrome/browser/media/webrtc/native_desktop_media_list.cc b/chrome/browser/media/webrtc/native_desktop_media_list.cc
index 81d4416e270e1a4548866a56222c47cb616385e3..22f55d22b0406f0d1aa642dcea44403ac1636057 100644
index c2c7d86ed1f089ca6abbb026b4cf4e2857ef66c1..d65182dbae1447d95230a581943d23ee144d9dbe 100644
--- a/chrome/browser/media/webrtc/native_desktop_media_list.cc
+++ b/chrome/browser/media/webrtc/native_desktop_media_list.cc
@@ -159,7 +159,7 @@ BOOL CALLBACK AllHwndCollector(HWND hwnd, LPARAM param) {
@@ -160,7 +160,7 @@ BOOL CALLBACK AllHwndCollector(HWND hwnd, LPARAM param) {
#if BUILDFLAG(IS_MAC)
BASE_FEATURE(kWindowCaptureMacV2,
"WindowCaptureMacV2",
@@ -94,7 +94,7 @@ index 81d4416e270e1a4548866a56222c47cb616385e3..22f55d22b0406f0d1aa642dcea44403a
#endif
} // namespace
@@ -235,7 +235,7 @@ class NativeDesktopMediaList::Worker
@@ -244,7 +244,7 @@ class NativeDesktopMediaList::Worker
base::WeakPtr<NativeDesktopMediaList> media_list_;
DesktopMediaList::Type type_;
@@ -103,7 +103,7 @@ index 81d4416e270e1a4548866a56222c47cb616385e3..22f55d22b0406f0d1aa642dcea44403a
const ThumbnailCapturer::FrameDeliveryMethod frame_delivery_method_;
const bool add_current_process_windows_;
@@ -529,6 +529,12 @@ void NativeDesktopMediaList::Worker::RefreshNextThumbnail() {
@@ -531,6 +531,12 @@ void NativeDesktopMediaList::Worker::RefreshNextThumbnail() {
FROM_HERE,
base::BindOnce(&NativeDesktopMediaList::UpdateNativeThumbnailsFinished,
media_list_));
@@ -116,7 +116,7 @@ index 81d4416e270e1a4548866a56222c47cb616385e3..22f55d22b0406f0d1aa642dcea44403a
}
void NativeDesktopMediaList::Worker::OnCaptureResult(
@@ -935,6 +941,11 @@ void NativeDesktopMediaList::RefreshForVizFrameSinkWindows(
@@ -964,6 +970,11 @@ void NativeDesktopMediaList::RefreshForVizFrameSinkWindows(
FROM_HERE, base::BindOnce(&Worker::RefreshThumbnails,
base::Unretained(worker_.get()),
std::move(native_ids), thumbnail_size_));

View File

@@ -148,7 +148,7 @@ index 6892376fa33d006453977c354734d880a7ef7c91..4cd7b762d5fe1c54f5b06cc0d8f50560
}
diff --git a/third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.cc b/third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.cc
index 368105b62e1650255e28cf71fcac2b956e811658..2dbbef93571ff5d41fc70a339d22470fdc5f5529 100644
index b35f43f7051c2aabf6a49dd9af6627c9fbb2e99f..688954856aaf12565f4c63b3ffbb5459fe634693 100644
--- a/third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.cc
+++ b/third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.cc
@@ -30,6 +30,7 @@
@@ -159,7 +159,7 @@ index 368105b62e1650255e28cf71fcac2b956e811658..2dbbef93571ff5d41fc70a339d22470f
#include "ui/native_theme/native_theme_features.h"
#include "ui/native_theme/overlay_scrollbar_constants_aura.h"
@@ -332,6 +333,9 @@ cc::LayerTreeSettings GenerateLayerTreeSettings(
@@ -318,6 +319,9 @@ cc::LayerTreeSettings GenerateLayerTreeSettings(
settings.main_frame_before_activation_enabled =
cmd.HasSwitch(cc::switches::kEnableMainFrameBeforeActivation);

View File

@@ -33,10 +33,10 @@ index 0ab8187b0db8ae6db46d81738f653a2bc4c566f6..de3d55e85c22317f7f9375eb94d0d5d4
} // namespace net
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index cb05975b622eee25217d9f2477c5e53ace017db8..e264713f4361a588e0ec8b4f6f37ab76ad642116 100644
index 30c2fb786dac5f38104ecdac170bdd2e76f1ab6f..f857ea2d258a5ee734ec9e0d40696d5feacbf23a 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -1559,6 +1559,13 @@ void NetworkContext::SetNetworkConditions(
@@ -1561,6 +1561,13 @@ void NetworkContext::SetNetworkConditions(
std::move(network_conditions));
}
@@ -51,7 +51,7 @@ index cb05975b622eee25217d9f2477c5e53ace017db8..e264713f4361a588e0ec8b4f6f37ab76
// This may only be called on NetworkContexts created with the constructor
// that calls MakeURLRequestContext().
diff --git a/services/network/network_context.h b/services/network/network_context.h
index 25f9dab24b27ad2b3d6ca01690e9f5c3fea96d32..b230036559cdc44b97b3a5ca5f359a0b4512ccd7 100644
index 17ecfd109db3e9dbcc27ec291f6c6021c9b6f0eb..80a75a25595718a2c4e655f75620d18b274b24cd 100644
--- a/services/network/network_context.h
+++ b/services/network/network_context.h
@@ -316,6 +316,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
@@ -63,7 +63,7 @@ index 25f9dab24b27ad2b3d6ca01690e9f5c3fea96d32..b230036559cdc44b97b3a5ca5f359a0b
void SetEnableReferrers(bool enable_referrers) override;
#if BUILDFLAG(IS_CHROMEOS)
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
index 6ebade992b628fee18d23e5e29d2d7d6190261a7..21039664d38fb228a9319d296276c33de7a0a265 100644
index 64a840b13bc6c07112060f48d4f77507eb84994a..7482c19600f48bf7ae4a37ce55ffcbea922b8d42 100644
--- a/services/network/public/mojom/network_context.mojom
+++ b/services/network/public/mojom/network_context.mojom
@@ -1233,6 +1233,9 @@ interface NetworkContext {

View File

@@ -13,10 +13,10 @@ uses internally for things like menus and devtools.
We can remove this patch once it has in some shape been upstreamed.
diff --git a/ui/native_theme/native_theme.cc b/ui/native_theme/native_theme.cc
index f6556e141a76b0766f672bfa5819256e635c60af..06c7ac178cefc149732294ed790f2b7cbb328d34 100644
index af49c133fb2b176139263553d2afff33e96a94b1..699c38b2046e267619eef103c83eff258887e0c0 100644
--- a/ui/native_theme/native_theme.cc
+++ b/ui/native_theme/native_theme.cc
@@ -153,6 +153,8 @@ NativeTheme::NativeTheme(bool should_use_dark_colors,
@@ -156,6 +156,8 @@ NativeTheme::NativeTheme(bool should_use_dark_colors,
NativeTheme::~NativeTheme() = default;
bool NativeTheme::ShouldUseDarkColors() const {
@@ -26,7 +26,7 @@ index f6556e141a76b0766f672bfa5819256e635c60af..06c7ac178cefc149732294ed790f2b7c
}
diff --git a/ui/native_theme/native_theme.h b/ui/native_theme/native_theme.h
index 6f51a8ffec973d6c2acacabb951c7cc4e36b639c..889e655fccc115faae932236cc28c6386cf19c1e 100644
index 341248a6b15b280c382c965009540fbdb64b0978..c9bead90658ac0e2d503c90c6ce380a318fee457 100644
--- a/ui/native_theme/native_theme.h
+++ b/ui/native_theme/native_theme.h
@@ -433,6 +433,23 @@ class NATIVE_THEME_EXPORT NativeTheme {
@@ -53,7 +53,7 @@ index 6f51a8ffec973d6c2acacabb951c7cc4e36b639c..889e655fccc115faae932236cc28c638
// Returns a shared instance of the native theme that should be used for web
// rendering. Do not use it in a normal application context (i.e. browser).
// The returned object should not be deleted by the caller. This function is
@@ -643,6 +660,7 @@ class NATIVE_THEME_EXPORT NativeTheme {
@@ -654,6 +671,7 @@ class NATIVE_THEME_EXPORT NativeTheme {
bool inverted_colors_ = false;
PreferredColorScheme preferred_color_scheme_ = PreferredColorScheme::kLight;
PreferredContrast preferred_contrast_ = PreferredContrast::kNoPreference;
@@ -62,10 +62,10 @@ index 6f51a8ffec973d6c2acacabb951c7cc4e36b639c..889e655fccc115faae932236cc28c638
SEQUENCE_CHECKER(sequence_checker_);
};
diff --git a/ui/native_theme/native_theme_win.cc b/ui/native_theme/native_theme_win.cc
index faa15be0b3e08360c702b32968d3b1633038d776..7a6c284143e873b408333fa2052e05863935cb89 100644
index 595b7185832126dd3d8ca85c445b835e5969adcb..58c64b98a0f94b0be7e7819999cf81dedf9bbe08 100644
--- a/ui/native_theme/native_theme_win.cc
+++ b/ui/native_theme/native_theme_win.cc
@@ -658,6 +658,8 @@ bool NativeThemeWin::ShouldUseDarkColors() const {
@@ -663,6 +663,8 @@ bool NativeThemeWin::ShouldUseDarkColors() const {
// ...unless --force-dark-mode was specified in which case caveat emptor.
if (InForcedColorsMode() && !IsForcedDarkMode())
return false;

View File

@@ -514,7 +514,7 @@ index 796ae2688436eb07f19909641d1620dd02f10cdb..c9e0eee0b329caf46669b419b1cd10cf
waiting_on_draw_ack_ = true;
diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
index c70b0af70a68386c5d36833e621dd1b5cdc1522a..17e5c96cbb4ef2f575fd5ba7bd8b0c7bd58da5e7 100644
index 1c59eb0cdf1786a19f74f165acc3fb071dcf2fa1..ddb2389f548a8558f79d7cf32ffd6ce0a7751553 100644
--- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
+++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
@@ -97,7 +97,8 @@ RootCompositorFrameSinkImpl::Create(

View File

@@ -0,0 +1,24 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: clavin <clavin@electronjs.org>
Date: Wed, 30 Aug 2023 18:15:36 -0700
Subject: fix: activate background material on windows
This patch adds a condition to the HWND message handler to allow windows
with translucent background materials to become activated.
This patch likely can't be upstreamed as-is, as Chromium doesn't have
this use case in mind currently.
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
index 13268bd89c710690eed5296f4b2157e9476f195e..37de479e95d49f4d2b1d8164c9e3f6a7bcd82612 100644
--- a/ui/views/win/hwnd_message_handler.cc
+++ b/ui/views/win/hwnd_message_handler.cc
@@ -1094,7 +1094,7 @@ void HWNDMessageHandler::FrameTypeChanged() {
void HWNDMessageHandler::PaintAsActiveChanged() {
if (!delegate_->HasNonClientView() || !delegate_->CanActivate() ||
- !delegate_->HasFrame() ||
+ (!delegate_->HasFrame() && !is_translucent_) ||
(delegate_->GetFrameMode() == FrameMode::CUSTOM_DRAWN)) {
return;
}

View File

@@ -17,7 +17,7 @@ policy->CanCommitOriginAndUrl.
Upstreamed at https://chromium-review.googlesource.com/c/chromium/src/+/3856266.
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index e91fb6b203b55d4937e9f4b4ed8fd5e8efb5aa10..855cb90260de04b90b8bbf4a8733e0869cda551d 100644
index 5cf177fc73dd2b3038754b11d23ad637e7709f88..72103151867a9c1154b83da83b52a5b3b7b988ed 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -7543,10 +7543,11 @@ NavigationRequest::GetOriginForURLLoaderFactoryAfterResponseWithDebugInfo() {

View File

@@ -25,10 +25,10 @@ index c9a13aee1e64f359cd1d5c2e440b4df204420997..7790c311400fc84bfda6c99e1ebd8da7
// Returns true if duplex mode is set.
bool SetDuplexModeInPrintSettings(mojom::DuplexMode mode);
diff --git a/printing/printing_context_mac.mm b/printing/printing_context_mac.mm
index ee900c7541af99c61844920433ae39e2648ae90b..59137008aeddc03d60c58a463206dc91a0ef5c1f 100644
index 7c9204db9b4c8f36e4c7405e3bd9c8b311753f04..4bff296ea2c55175416aaa778856e6182866664f 100644
--- a/printing/printing_context_mac.mm
+++ b/printing/printing_context_mac.mm
@@ -464,7 +464,8 @@ void ApplySystemPrintDialogData(
@@ -473,7 +473,8 @@ void ApplySystemPrintDialogData(
!SetCollateInPrintSettings(settings_->collate()) ||
!SetDuplexModeInPrintSettings(settings_->duplex_mode()) ||
!SetOutputColor(static_cast<int>(settings_->color())) ||
@@ -38,7 +38,7 @@ index ee900c7541af99c61844920433ae39e2648ae90b..59137008aeddc03d60c58a463206dc91
return OnError();
}
}
@@ -617,6 +618,22 @@ void ApplySystemPrintDialogData(
@@ -626,6 +627,22 @@ void ApplySystemPrintDialogData(
return PMSetCopies(print_settings, copies, false) == noErr;
}
@@ -100,10 +100,10 @@ index 07847521e7217c78480205812a73cc89503c00d2..586e866ca7ec0eb0b573d23e3bd95792
} else {
// No need to bother, we don't know how many pages are available.
diff --git a/ui/gtk/printing/print_dialog_gtk.cc b/ui/gtk/printing/print_dialog_gtk.cc
index e270fa36d775333aaa30f1ff0104062c544d1058..e4a6213e19e4f23834802784a43db22c9d02d891 100644
index dcabfdab6cc5a0f0a79f797d3660118b780bd110..bcbfeef775e40c1b0c1bbac49dd520e602bc4cb9 100644
--- a/ui/gtk/printing/print_dialog_gtk.cc
+++ b/ui/gtk/printing/print_dialog_gtk.cc
@@ -245,6 +245,24 @@ void PrintDialogGtk::UpdateSettings(
@@ -248,6 +248,24 @@ void PrintDialogGtk::UpdateSettings(
gtk_print_settings_set_n_copies(gtk_settings_, settings->copies());
gtk_print_settings_set_collate(gtk_settings_, settings->collate());

View File

@@ -238,7 +238,7 @@ index 835cce73b7ab8b38c37d3e2650e12303d9d918e3..4460a00497dfaee0ba90cd5d14888055
+
#endif // UI_BASE_COCOA_REMOTE_ACCESSIBILITY_API_H_
diff --git a/ui/views/cocoa/native_widget_mac_ns_window_host.h b/ui/views/cocoa/native_widget_mac_ns_window_host.h
index 2daaf2b78b7a60d340c2ff1651f8b5450db4af0f..3080adea0402f9d57cbde5d4350605d463ee5c8e 100644
index 6c2761b68d895fb1964e98865dd96cc37226fce0..563ee4da217ff4aabf2ef3452322da9e9ccefe4f 100644
--- a/ui/views/cocoa/native_widget_mac_ns_window_host.h
+++ b/ui/views/cocoa/native_widget_mac_ns_window_host.h
@@ -30,7 +30,9 @@
@@ -251,7 +251,7 @@ index 2daaf2b78b7a60d340c2ff1651f8b5450db4af0f..3080adea0402f9d57cbde5d4350605d4
@class NSView;
namespace remote_cocoa {
@@ -454,10 +456,12 @@ class VIEWS_EXPORT NativeWidgetMacNSWindowHost
@@ -456,10 +458,12 @@ class VIEWS_EXPORT NativeWidgetMacNSWindowHost
mojo::AssociatedRemote<remote_cocoa::mojom::NativeWidgetNSWindow>
remote_ns_window_remote_;
@@ -265,10 +265,10 @@ index 2daaf2b78b7a60d340c2ff1651f8b5450db4af0f..3080adea0402f9d57cbde5d4350605d4
// Used to force the NSApplication's focused accessibility element to be the
// views::Views accessibility tree when the NSView for this is focused.
diff --git a/ui/views/cocoa/native_widget_mac_ns_window_host.mm b/ui/views/cocoa/native_widget_mac_ns_window_host.mm
index 53bdb4d62294f128b8f4b7bdcddf1052e15f331f..d052f5bb619bf4092810c6d5dd489a38a60026b0 100644
index 6e0f07f5e1107341d0232e4a76b7332620315c04..0135aada72ef0c3a85ab8d134462754eb31ad2df 100644
--- a/ui/views/cocoa/native_widget_mac_ns_window_host.mm
+++ b/ui/views/cocoa/native_widget_mac_ns_window_host.mm
@@ -339,7 +339,11 @@ void HandleAccelerator(const ui::Accelerator& accelerator,
@@ -352,7 +352,11 @@ void HandleAccelerator(const ui::Accelerator& accelerator,
NativeWidgetMacNSWindowHost::GetNativeViewAccessibleForNSView() const {
if (in_process_ns_window_bridge_)
return in_process_ns_window_bridge_->ns_view();
@@ -280,7 +280,7 @@ index 53bdb4d62294f128b8f4b7bdcddf1052e15f331f..d052f5bb619bf4092810c6d5dd489a38
}
gfx::NativeViewAccessible
@@ -354,7 +358,11 @@ void HandleAccelerator(const ui::Accelerator& accelerator,
@@ -367,7 +371,11 @@ void HandleAccelerator(const ui::Accelerator& accelerator,
return [in_process_ns_window_bridge_->ns_view() window];
}
@@ -292,7 +292,7 @@ index 53bdb4d62294f128b8f4b7bdcddf1052e15f331f..d052f5bb619bf4092810c6d5dd489a38
}
remote_cocoa::mojom::NativeWidgetNSWindow*
@@ -1353,20 +1361,24 @@ void HandleAccelerator(const ui::Accelerator& accelerator,
@@ -1382,20 +1390,24 @@ void HandleAccelerator(const ui::Accelerator& accelerator,
void NativeWidgetMacNSWindowHost::SetRemoteAccessibilityTokens(
const std::vector<uint8_t>& window_token,
const std::vector<uint8_t>& view_token) {

View File

@@ -7,7 +7,7 @@ This adds a callback from the network service that's used to implement
session.setCertificateVerifyCallback.
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index f076c5dc62ca5975865e3966381257684503eeb8..cb05975b622eee25217d9f2477c5e53ace017db8 100644
index a107e19d2aa1cab31c88688904db128e61bcdc5e..30c2fb786dac5f38104ecdac170bdd2e76f1ab6f 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -146,6 +146,11 @@
@@ -122,7 +122,7 @@ index f076c5dc62ca5975865e3966381257684503eeb8..cb05975b622eee25217d9f2477c5e53a
constexpr uint32_t NetworkContext::kMaxOutstandingRequestsPerProcess;
NetworkContext::NetworkContextHttpAuthPreferences::
@@ -824,6 +922,13 @@ void NetworkContext::SetClient(
@@ -826,6 +924,13 @@ void NetworkContext::SetClient(
client_.Bind(std::move(client));
}
@@ -136,7 +136,7 @@ index f076c5dc62ca5975865e3966381257684503eeb8..cb05975b622eee25217d9f2477c5e53a
void NetworkContext::CreateURLLoaderFactory(
mojo::PendingReceiver<mojom::URLLoaderFactory> receiver,
mojom::URLLoaderFactoryParamsPtr params) {
@@ -2383,6 +2488,9 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext(
@@ -2385,6 +2490,9 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext(
std::move(cert_verifier));
cert_verifier = base::WrapUnique(cert_verifier_with_trust_anchors_.get());
#endif // BUILDFLAG(IS_CHROMEOS)
@@ -147,7 +147,7 @@ index f076c5dc62ca5975865e3966381257684503eeb8..cb05975b622eee25217d9f2477c5e53a
builder.SetCertVerifier(IgnoreErrorsCertVerifier::MaybeWrapCertVerifier(
diff --git a/services/network/network_context.h b/services/network/network_context.h
index d046d6909a9e648ddc86cbed9cb118d29223155e..25f9dab24b27ad2b3d6ca01690e9f5c3fea96d32 100644
index a1ac41b0850de88c3334d7b7aa3bfc470365b873..17ecfd109db3e9dbcc27ec291f6c6021c9b6f0eb 100644
--- a/services/network/network_context.h
+++ b/services/network/network_context.h
@@ -114,6 +114,7 @@ class URLMatcher;
@@ -177,7 +177,7 @@ index d046d6909a9e648ddc86cbed9cb118d29223155e..25f9dab24b27ad2b3d6ca01690e9f5c3
std::unique_ptr<HostResolver> internal_host_resolver_;
// Map values set to non-null only if that HostResolver has its own private
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
index 039407080ba9b234b0472afd7d56d44802fd3c0e..6ebade992b628fee18d23e5e29d2d7d6190261a7 100644
index 6164ab364a4044b9ca63d78dd5cc8c94ede7894c..64a840b13bc6c07112060f48d4f77507eb84994a 100644
--- a/services/network/public/mojom/network_context.mojom
+++ b/services/network/public/mojom/network_context.mojom
@@ -317,6 +317,17 @@ struct NetworkContextFilePaths {

View File

@@ -61,10 +61,10 @@ index f1aadfefe2b35ff4f292a04d834679e1c3fe89e9..7cb39e4059719a4fc323586e83aba47d
}
diff --git a/ui/color/win/native_color_mixers_win.cc b/ui/color/win/native_color_mixers_win.cc
index d9df0c0be6abf72c4756fb8e0f1e4b8c308a09f3..07ad3bf7e422272f017695c8b0e0aebedb8d8330 100644
index a0eb66d2a28b19ee92e2c3c23fd3eff5d64d502d..1d3b62d504884e036365256443c1a1b4f0c796ab 100644
--- a/ui/color/win/native_color_mixers_win.cc
+++ b/ui/color/win/native_color_mixers_win.cc
@@ -202,6 +202,10 @@ void AddNativeUiColorMixer(ColorProvider* provider,
@@ -205,6 +205,10 @@ void AddNativeUiColorMixer(ColorProvider* provider,
SetAlpha(kColorNotificationInputForeground, gfx::kGoogleGreyAlpha700);
mixer[kColorSliderTrack] = AlphaBlend(
kColorNativeHighlight, kColorNativeWindow, gfx::kGoogleGreyAlpha400);
@@ -75,7 +75,7 @@ index d9df0c0be6abf72c4756fb8e0f1e4b8c308a09f3..07ad3bf7e422272f017695c8b0e0aebe
// Window Background
mixer[kColorBubbleFooterBackground] = {kColorNativeWindow};
@@ -211,6 +215,7 @@ void AddNativeUiColorMixer(ColorProvider* provider,
@@ -214,6 +218,7 @@ void AddNativeUiColorMixer(ColorProvider* provider,
mixer[kColorFrameInactive] = {kColorNativeWindow};
mixer[kColorPrimaryBackground] = {kColorNativeWindow};
mixer[kColorTooltipBackground] = {kColorNativeWindow};
@@ -83,7 +83,7 @@ index d9df0c0be6abf72c4756fb8e0f1e4b8c308a09f3..07ad3bf7e422272f017695c8b0e0aebe
// Window Text
mixer[kColorAlertLowSeverity] = {kColorNativeWindowText};
@@ -225,6 +230,7 @@ void AddNativeUiColorMixer(ColorProvider* provider,
@@ -228,6 +233,7 @@ void AddNativeUiColorMixer(ColorProvider* provider,
mixer[kColorTableGroupingIndicator] = {kColorNativeWindowText};
mixer[kColorThrobber] = {kColorNativeWindowText};
mixer[kColorTooltipForeground] = {kColorNativeWindowText};
@@ -91,7 +91,7 @@ index d9df0c0be6abf72c4756fb8e0f1e4b8c308a09f3..07ad3bf7e422272f017695c8b0e0aebe
// Hyperlinks
mixer[kColorForcedHotlight] = {kColorNativeHotlight};
@@ -271,6 +277,7 @@ void AddNativeUiColorMixer(ColorProvider* provider,
@@ -274,6 +280,7 @@ void AddNativeUiColorMixer(ColorProvider* provider,
mixer[kColorTextfieldForeground] = {kColorNativeBtnText};
mixer[kColorTextfieldForegroundPlaceholder] = {kColorNativeBtnText};
mixer[kColorTextfieldForegroundDisabled] = {kColorNativeBtnText};

View File

@@ -706,7 +706,7 @@ index 3f9a514fb41d72c5d06de6ac989f9d7c0513a4e7..0e7ada9df962808dad7caf074a08ebde
// Tells the browser printing failed.
PrintingFailed(int32 cookie, PrintFailureReason reason);
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc
index 658a3c59993ac30feaea4d86148ed5adc9dcbdb1..afa788bbefc8f814af9b70ff5b5ebbc86a1777cd 100644
index 5a58210461222ed431624bf161b32770c5ae97e6..aec69c525cefd73e50f50883ac0dc8bee94e78c0 100644
--- a/components/printing/renderer/print_render_frame_helper.cc
+++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -45,6 +45,7 @@
@@ -717,7 +717,7 @@ index 658a3c59993ac30feaea4d86148ed5adc9dcbdb1..afa788bbefc8f814af9b70ff5b5ebbc8
#include "printing/units.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
@@ -1322,14 +1323,14 @@ void PrintRenderFrameHelper::ScriptedPrint(bool user_initiated) {
@@ -1237,14 +1238,14 @@ void PrintRenderFrameHelper::ScriptedPrint(bool user_initiated) {
}
print_in_progress_ = true;
@@ -734,7 +734,7 @@ index 658a3c59993ac30feaea4d86148ed5adc9dcbdb1..afa788bbefc8f814af9b70ff5b5ebbc8
if (!weak_this) {
return;
}
@@ -1360,7 +1361,7 @@ void PrintRenderFrameHelper::BindPrintRenderFrameReceiver(
@@ -1275,7 +1276,7 @@ void PrintRenderFrameHelper::BindPrintRenderFrameReceiver(
receivers_.Add(this, std::move(receiver));
}
@@ -743,7 +743,7 @@ index 658a3c59993ac30feaea4d86148ed5adc9dcbdb1..afa788bbefc8f814af9b70ff5b5ebbc8
ScopedIPC scoped_ipc(weak_ptr_factory_.GetWeakPtr());
if (ipc_nesting_level_ > kAllowedIpcDepthForPrint)
return;
@@ -1375,7 +1376,7 @@ void PrintRenderFrameHelper::PrintRequestedPages() {
@@ -1290,7 +1291,7 @@ void PrintRenderFrameHelper::PrintRequestedPages() {
// plugin node and print that instead.
auto plugin = delegate_->GetPdfElement(frame);
@@ -752,7 +752,7 @@ index 658a3c59993ac30feaea4d86148ed5adc9dcbdb1..afa788bbefc8f814af9b70ff5b5ebbc8
if (render_frame_gone_) {
return;
@@ -1462,7 +1463,8 @@ void PrintRenderFrameHelper::PrintForSystemDialog() {
@@ -1377,7 +1378,8 @@ void PrintRenderFrameHelper::PrintForSystemDialog() {
}
Print(frame, print_preview_context_.source_node(),
@@ -762,7 +762,7 @@ index 658a3c59993ac30feaea4d86148ed5adc9dcbdb1..afa788bbefc8f814af9b70ff5b5ebbc8
if (render_frame_gone_) {
return;
}
@@ -1525,6 +1527,8 @@ void PrintRenderFrameHelper::PrintPreview(base::Value::Dict settings) {
@@ -1440,6 +1442,8 @@ void PrintRenderFrameHelper::PrintPreview(base::Value::Dict settings) {
if (ipc_nesting_level_ > kAllowedIpcDepthForPrint)
return;
@@ -771,7 +771,7 @@ index 658a3c59993ac30feaea4d86148ed5adc9dcbdb1..afa788bbefc8f814af9b70ff5b5ebbc8
print_preview_context_.OnPrintPreview();
#if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -2158,7 +2162,8 @@ void PrintRenderFrameHelper::PrintNode(const blink::WebNode& node) {
@@ -2065,7 +2069,8 @@ void PrintRenderFrameHelper::PrintNode(const blink::WebNode& node) {
}
Print(duplicate_node.GetDocument().GetFrame(), duplicate_node,
@@ -781,7 +781,7 @@ index 658a3c59993ac30feaea4d86148ed5adc9dcbdb1..afa788bbefc8f814af9b70ff5b5ebbc8
// Check if `this` is still valid.
if (!weak_this) {
return;
@@ -2174,7 +2179,9 @@ void PrintRenderFrameHelper::PrintNode(const blink::WebNode& node) {
@@ -2081,7 +2086,9 @@ void PrintRenderFrameHelper::PrintNode(const blink::WebNode& node) {
void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
const blink::WebNode& node,
@@ -792,7 +792,7 @@ index 658a3c59993ac30feaea4d86148ed5adc9dcbdb1..afa788bbefc8f814af9b70ff5b5ebbc8
// If still not finished with earlier print request simply ignore.
if (prep_frame_view_)
return;
@@ -2182,7 +2189,7 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
@@ -2089,7 +2096,7 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
FrameReference frame_ref(frame);
uint32_t expected_page_count = 0;
@@ -801,7 +801,7 @@ index 658a3c59993ac30feaea4d86148ed5adc9dcbdb1..afa788bbefc8f814af9b70ff5b5ebbc8
DidFinishPrinting(PrintingResult::kFailPrintInit);
return; // Failed to init print page settings.
}
@@ -2201,8 +2208,15 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
@@ -2108,8 +2115,15 @@ void PrintRenderFrameHelper::Print(blink::WebLocalFrame* frame,
print_pages_params_->params->print_scaling_option;
auto self = weak_ptr_factory_.GetWeakPtr();
@@ -818,7 +818,7 @@ index 658a3c59993ac30feaea4d86148ed5adc9dcbdb1..afa788bbefc8f814af9b70ff5b5ebbc8
// Check if `this` is still valid.
if (!self)
return;
@@ -2446,35 +2460,47 @@ void PrintRenderFrameHelper::IPCProcessed() {
@@ -2349,35 +2363,47 @@ void PrintRenderFrameHelper::IPCProcessed() {
}
}
@@ -876,7 +876,7 @@ index 658a3c59993ac30feaea4d86148ed5adc9dcbdb1..afa788bbefc8f814af9b70ff5b5ebbc8
return false;
}
@@ -2579,7 +2605,7 @@ mojom::PrintPagesParamsPtr PrintRenderFrameHelper::GetPrintSettingsFromUser(
@@ -2482,7 +2508,7 @@ mojom::PrintPagesParamsPtr PrintRenderFrameHelper::GetPrintSettingsFromUser(
std::move(params),
base::BindOnce(
[](base::OnceClosure quit_closure, mojom::PrintPagesParamsPtr* output,
@@ -886,7 +886,7 @@ index 658a3c59993ac30feaea4d86148ed5adc9dcbdb1..afa788bbefc8f814af9b70ff5b5ebbc8
std::move(quit_closure).Run();
},
diff --git a/components/printing/renderer/print_render_frame_helper.h b/components/printing/renderer/print_render_frame_helper.h
index 8d65b7b6440c8e653eb1b3f9c50b40944b7ae61b..eb6b4a42d507ff216fc07328c1907815a082ef19 100644
index 5cbb2940f83af329ea38efca5bf3216056269654..8cf783d37589fdca88592eeb9b8cc91b6ae60203 100644
--- a/components/printing/renderer/print_render_frame_helper.h
+++ b/components/printing/renderer/print_render_frame_helper.h
@@ -247,7 +247,7 @@ class PrintRenderFrameHelper
@@ -927,10 +927,10 @@ index 8d65b7b6440c8e653eb1b3f9c50b40944b7ae61b..eb6b4a42d507ff216fc07328c1907815
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
// Set options for print preset from source PDF document.
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 89b2e2bd7d6091501756b4d31726c49b00ffd0c7..718ad3e088f6730bb00f1e3674effae6c429b9b6 100644
index 755bfcc4ed84f44d0d8bb53615637ccd69a858e7..368cf7aaffeef5f9796f78a72f13eddb6c44dec9 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -2953,8 +2953,9 @@ source_set("browser") {
@@ -2955,8 +2955,9 @@ source_set("browser") {
"//ppapi/shared_impl",
]

File diff suppressed because it is too large Load Diff

View File

@@ -15,7 +15,7 @@ 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 586aa87098bd3db10440fe865a02c05e7b3be14f..cb372df065f83614ff6c2954035795e67eb69d0c 100644
index 9b6ce4a1a495986333a0d173749a9a095c2e5603..7c9773236ada4ac921c73483f82a80b94ae2b129 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -7417,6 +7417,17 @@ void RenderFrameHostImpl::EnterFullscreen(

0
patches/libvpx/.patches Normal file
View File

View File

@@ -42,3 +42,10 @@ fix_isurl_implementation.patch
ci_ensure_node_tests_set_electron_run_as_node.patch
chore_update_fixtures_errors_force_colors_snapshot.patch
fix_assert_module_in_the_renderer_process.patch
tls_ensure_tls_sockets_are_closed_if_the_underlying_wrap_closes.patch
test_deflake_test-tls-socket-close.patch
net_fix_crash_due_to_simultaneous_close_shutdown_on_js_stream.patch
net_use_asserts_in_js_socket_stream_to_catch_races_in_future.patch
lib_fix_broadcastchannel_initialization_location.patch
fix_handle_possible_disabled_sharedarraybuffer.patch
win_process_avoid_assert_after_spawning_store_app_4152.patch

View File

@@ -11,7 +11,7 @@ trying to see whether or not the lines are greyed out. One possibility
would be to upstream a changed test that doesn't hardcode line numbers.
diff --git a/test/fixtures/errors/force_colors.snapshot b/test/fixtures/errors/force_colors.snapshot
index 0334a0b4faa3633aa8617b9538873e7f3540513b..28ba4d18fe5e3caf4d904a055550110fd4faa609 100644
index 0334a0b4faa3633aa8617b9538873e7f3540513b..fa9989f55980aeddd3fa944318488c0289e3ab6e 100644
--- a/test/fixtures/errors/force_colors.snapshot
+++ b/test/fixtures/errors/force_colors.snapshot
@@ -4,11 +4,12 @@ throw new Error('Should include grayed stack trace')
@@ -27,7 +27,7 @@ index 0334a0b4faa3633aa8617b9538873e7f3540513b..28ba4d18fe5e3caf4d904a055550110f
+ at Object..js (node:internal*modules*cjs*loader:1326:10)
+ at Module.load (node:internal*modules*cjs*loader:1126:32)
+ at node:internal*modules*cjs*loader:967:12
+ at Function._load (node:electron*js2c*asar_bundle:756:32)
+ at Function._load (node:electron*js2c*asar_bundle:743:32)
+ at Function.executeUserEntryPoint [as runMain] (node:internal*modules*run_main:96:12)
 at node:internal*main*run_main_module:23:47

View File

@@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Mon, 2 Oct 2023 16:03:43 +0200
Subject: fix: handle possible disabled SharedArrayBuffer
It's possible for SharedArrayBuffer to be disabled with the -no-harmony-sharedarraybuffer
flag, and so we should guard uses with a check for potential undefined-ness.
This should be upstreamed to Node.js.
diff --git a/lib/internal/crypto/webidl.js b/lib/internal/crypto/webidl.js
index 9f5340c223902c5ff61def05e8a4f470b4f328e8..d6dbfa482f9ebff3f99fb810e072cf9a03d1cd4d 100644
--- a/lib/internal/crypto/webidl.js
+++ b/lib/internal/crypto/webidl.js
@@ -183,7 +183,10 @@ function isNonSharedArrayBuffer(V) {
return ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, V);
}
+// SharedArrayBuffers can be disabled with --no-harmony-sharedarraybuffer.
function isSharedArrayBuffer(V) {
+ if (SharedArrayBuffer === undefined)
+ return false;
return ObjectPrototypeIsPrototypeOf(SharedArrayBuffer.prototype, V);
}
diff --git a/lib/internal/main/worker_thread.js b/lib/internal/main/worker_thread.js
index be4d82086199855a10108528b3dacc663b839454..10c33bacc0529e12f52aaf1baf6d42489b2a75a7 100644
--- a/lib/internal/main/worker_thread.js
+++ b/lib/internal/main/worker_thread.js
@@ -108,6 +108,7 @@ port.on('message', (message) => {
require('internal/worker').assignEnvironmentData(environmentData);
+ // SharedArrayBuffers can be disabled with --no-harmony-sharedarraybuffer.
if (SharedArrayBuffer !== undefined) {
// The counter is only passed to the workers created by the main thread,
// not to workers created by other workers.

View File

@@ -0,0 +1,44 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Mon, 27 Feb 2023 12:56:15 +0100
Subject: lib: fix BroadcastChannel initialization location
Refs https://github.com/nodejs/node/pull/40532.
Fixes a bug in the above, wherein BroadcastChannel should have been
initialized in bootstrap/browser instead of bootstrap/node. That
inadvertently made it such that there was incorrect handling of the
DOM vs Node.js implementations of BroadcastChannel.
This will be upstreamed.
diff --git a/lib/internal/bootstrap/browser.js b/lib/internal/bootstrap/browser.js
index 5be4dd6176482c724455cbbeeaa9680e849a091b..29ccee75d77da072735032f0a25363ac88a023ba 100644
--- a/lib/internal/bootstrap/browser.js
+++ b/lib/internal/bootstrap/browser.js
@@ -12,6 +12,10 @@ const {
} = require('internal/util');
const config = internalBinding('config');
+// Non-standard extensions:
+const { BroadcastChannel } = require('internal/worker/io');
+exposeInterface(globalThis, 'BroadcastChannel', BroadcastChannel);
+
// https://console.spec.whatwg.org/#console-namespace
exposeNamespace(globalThis, 'console',
createGlobalConsole());
diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js
index 13ea68c96fd415f976aab0f291a1b7c688db1c58..0ca3de08fffb344c0330ce0f8d28b2d3d0b24350 100644
--- a/lib/internal/bootstrap/node.js
+++ b/lib/internal/bootstrap/node.js
@@ -238,10 +238,6 @@ const {
queueMicrotask,
} = require('internal/process/task_queues');
-// Non-standard extensions:
-const { BroadcastChannel } = require('internal/worker/io');
-exposeInterface(globalThis, 'BroadcastChannel', BroadcastChannel);
-
defineOperation(globalThis, 'queueMicrotask', queueMicrotask);
const timers = require('timers');

View File

@@ -0,0 +1,171 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tim Perry <pimterry@gmail.com>
Date: Thu, 24 Aug 2023 16:05:02 +0100
Subject: net: fix crash due to simultaneous close/shutdown on JS Stream
Sockets
A JS stream socket wraps a stream, exposing it as a socket for something
on top which needs a socket specifically (e.g. an HTTP server).
If the internal stream is closed in the same tick as the layer on top
attempts to close this stream, the race between doShutdown and doClose
results in an uncatchable exception. A similar race can happen with
doClose and doWrite.
It seems legitimate these can happen in parallel, so this resolves that
by explicitly detecting and handling that situation: if a close is in
progress, both doShutdown & doWrite allow doClose to run
finishShutdown/Write for them, cancelling the operation, without trying
to use this._handle (which will be null) in the meantime.
PR-URL: https://github.com/nodejs/node/pull/49400
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
diff --git a/lib/internal/js_stream_socket.js b/lib/internal/js_stream_socket.js
index 8bc19296620b3fd0e5487165743f0f1bc2d342e7..68e1802a63b012b59418b79a0e68de5147543a23 100644
--- a/lib/internal/js_stream_socket.js
+++ b/lib/internal/js_stream_socket.js
@@ -21,6 +21,7 @@ const { ERR_STREAM_WRAP } = require('internal/errors').codes;
const kCurrentWriteRequest = Symbol('kCurrentWriteRequest');
const kCurrentShutdownRequest = Symbol('kCurrentShutdownRequest');
const kPendingShutdownRequest = Symbol('kPendingShutdownRequest');
+const kPendingClose = Symbol('kPendingClose');
function isClosing() { return this[owner_symbol].isClosing(); }
@@ -94,6 +95,7 @@ class JSStreamSocket extends Socket {
this[kCurrentWriteRequest] = null;
this[kCurrentShutdownRequest] = null;
this[kPendingShutdownRequest] = null;
+ this[kPendingClose] = false;
this.readable = stream.readable;
this.writable = stream.writable;
@@ -135,10 +137,17 @@ class JSStreamSocket extends Socket {
this[kPendingShutdownRequest] = req;
return 0;
}
+
assert(this[kCurrentWriteRequest] === null);
assert(this[kCurrentShutdownRequest] === null);
this[kCurrentShutdownRequest] = req;
+ if (this[kPendingClose]) {
+ // If doClose is pending, the stream & this._handle are gone. We can't do
+ // anything. doClose will call finishShutdown with ECANCELED for us shortly.
+ return 0;
+ }
+
const handle = this._handle;
process.nextTick(() => {
@@ -164,6 +173,13 @@ class JSStreamSocket extends Socket {
assert(this[kCurrentWriteRequest] === null);
assert(this[kCurrentShutdownRequest] === null);
+ if (this[kPendingClose]) {
+ // If doClose is pending, the stream & this._handle are gone. We can't do
+ // anything. doClose will call finishWrite with ECANCELED for us shortly.
+ this[kCurrentWriteRequest] = req; // Store req, for doClose to cancel
+ return 0;
+ }
+
const handle = this._handle;
const self = this;
@@ -217,6 +233,8 @@ class JSStreamSocket extends Socket {
}
doClose(cb) {
+ this[kPendingClose] = true;
+
const handle = this._handle;
// When sockets of the "net" module destroyed, they will call
@@ -234,6 +252,8 @@ class JSStreamSocket extends Socket {
this.finishWrite(handle, uv.UV_ECANCELED);
this.finishShutdown(handle, uv.UV_ECANCELED);
+ this[kPendingClose] = false;
+
cb();
});
}
diff --git a/test/parallel/test-http2-client-connection-tunnelling.js b/test/parallel/test-http2-client-connection-tunnelling.js
new file mode 100644
index 0000000000000000000000000000000000000000..6e04121ca71ea81f49c7f50ec11d7fac735c80a9
--- /dev/null
+++ b/test/parallel/test-http2-client-connection-tunnelling.js
@@ -0,0 +1,71 @@
+'use strict';
+
+const common = require('../common');
+const fixtures = require('../common/fixtures');
+if (!common.hasCrypto)
+ common.skip('missing crypto');
+const assert = require('assert');
+const net = require('net');
+const tls = require('tls');
+const h2 = require('http2');
+
+// This test sets up an H2 proxy server, and tunnels a request over one of its streams
+// back to itself, via TLS, and then closes the TLS connection. On some Node versions
+// (v18 & v20 up to 20.5.1) the resulting JS Stream Socket fails to shutdown correctly
+// in this case, and crashes due to a null pointer in finishShutdown.
+
+const tlsOptions = {
+ key: fixtures.readKey('agent1-key.pem'),
+ cert: fixtures.readKey('agent1-cert.pem'),
+ ALPNProtocols: ['h2']
+};
+
+const netServer = net.createServer((socket) => {
+ socket.allowHalfOpen = false;
+ // ^ This allows us to trigger this reliably, but it's not strictly required
+ // for the bug and crash to happen, skipping this just fails elsewhere later.
+
+ h2Server.emit('connection', socket);
+});
+
+const h2Server = h2.createSecureServer(tlsOptions, (req, res) => {
+ res.writeHead(200);
+ res.end();
+});
+
+h2Server.on('connect', (req, res) => {
+ res.writeHead(200, {});
+ netServer.emit('connection', res.stream);
+});
+
+netServer.listen(0, common.mustCall(() => {
+ const proxyClient = h2.connect(`https://localhost:${netServer.address().port}`, {
+ rejectUnauthorized: false
+ });
+
+ const proxyReq = proxyClient.request({
+ ':method': 'CONNECT',
+ ':authority': 'example.com:443'
+ });
+
+ proxyReq.on('response', common.mustCall((response) => {
+ assert.strictEqual(response[':status'], 200);
+
+ // Create a TLS socket within the tunnel, and start sending a request:
+ const tlsSocket = tls.connect({
+ socket: proxyReq,
+ ALPNProtocols: ['h2'],
+ rejectUnauthorized: false
+ });
+
+ proxyReq.on('close', common.mustCall(() => {
+ proxyClient.close();
+ netServer.close();
+ }));
+
+ // Forcibly kill the TLS socket
+ tlsSocket.destroy();
+
+ // This results in an async error in affected Node versions, before the 'close' event
+ }));
+}));

View File

@@ -0,0 +1,30 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tim Perry <pimterry@gmail.com>
Date: Fri, 25 Aug 2023 14:16:35 +0100
Subject: net: use asserts in JS Socket Stream to catch races in future
PR-URL: https://github.com/nodejs/node/pull/49400
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
diff --git a/lib/internal/js_stream_socket.js b/lib/internal/js_stream_socket.js
index 68e1802a63b012b59418b79a0e68de5147543a23..70d6d03069f3f1e85e66864c6c1e6de6084f5ea6 100644
--- a/lib/internal/js_stream_socket.js
+++ b/lib/internal/js_stream_socket.js
@@ -149,6 +149,7 @@ class JSStreamSocket extends Socket {
}
const handle = this._handle;
+ assert(handle !== null);
process.nextTick(() => {
// Ensure that write is dispatched asynchronously.
@@ -181,6 +182,8 @@ class JSStreamSocket extends Socket {
}
const handle = this._handle;
+ assert(handle !== null);
+
const self = this;
let pending = bufs.length;

View File

@@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Luigi Pinca <luigipinca@gmail.com>
Date: Wed, 13 Sep 2023 08:04:39 +0200
Subject: test: deflake test-tls-socket-close
Move the check for the destroyed state of the remote socket to the inner
`setImmediate()`.
Refs: https://github.com/nodejs/node/pull/49327#issuecomment-1712525257
PR-URL: https://github.com/nodejs/node/pull/49575
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
diff --git a/test/parallel/test-tls-socket-close.js b/test/parallel/test-tls-socket-close.js
index 667b291309a4c5636a2c658fa8204b32c2e4df46..70af760d53bb4ddab62c99180d505e943ec269f6 100644
--- a/test/parallel/test-tls-socket-close.js
+++ b/test/parallel/test-tls-socket-close.js
@@ -44,9 +44,9 @@ function connectClient(server) {
setImmediate(() => {
assert.strictEqual(netSocket.destroyed, true);
- assert.strictEqual(clientTlsSocket.destroyed, true);
setImmediate(() => {
+ assert.strictEqual(clientTlsSocket.destroyed, true);
assert.strictEqual(serverTlsSocket.destroyed, true);
tlsServer.close();

View File

@@ -7,10 +7,10 @@ Instead of disabling the tests, flag them as flaky so they still run
but don't cause CI failures on flakes.
diff --git a/test/parallel/parallel.status b/test/parallel/parallel.status
index 913ae4b0b10a7d508d864539cf075fa9c2f9362c..985f1c0d0c0c6afc049bf1d89f91412ecf431215 100644
index 913ae4b0b10a7d508d864539cf075fa9c2f9362c..0539a599e57d40c5da650dcf5ffe9a67763506e1 100644
--- a/test/parallel/parallel.status
+++ b/test/parallel/parallel.status
@@ -5,6 +5,12 @@ prefix parallel
@@ -5,6 +5,13 @@ prefix parallel
# sample-test : PASS,FLAKY
[true] # This section applies to all platforms
@@ -20,6 +20,7 @@ index 913ae4b0b10a7d508d864539cf075fa9c2f9362c..985f1c0d0c0c6afc049bf1d89f91412e
+test-fetch: PASS, FLAKY
+test-cluster-bind-privileged-port: PASS, FLAKY
+test-cluster-shared-handle-bind-privileged-port: PASS, FLAKY
+test-debugger-random-port-with-inspect-port: PASS, FLAKY
[$system==win32]
# https://github.com/nodejs/node/issues/24497

View File

@@ -0,0 +1,204 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tim Perry <1526883+pimterry@users.noreply.github.com>
Date: Fri, 1 Sep 2023 09:00:05 +0200
Subject: tls: ensure TLS Sockets are closed if the underlying wrap closes
This fixes a potential segfault, among various other likely-related
issues, which all occur because TLSSockets were not informed if their
underlying stream was closed in many cases.
This also significantly modifies an existing TLS test. With this change
in place, that test no longer works, as it tries to mess with internals
to trigger a race, and those internals are now cleaned up earlier. This
test has been simplified to a more general TLS shutdown test.
PR-URL: https://github.com/nodejs/node/pull/49327
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Debadree Chatterjee <debadree333@gmail.com>
diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js
index 1eff3b3fba8a05d5fade43c6cb00b6621daa8c3d..5bed23e1355e5e5a1965f15ca270fb372f751d66 100644
--- a/lib/_tls_wrap.js
+++ b/lib/_tls_wrap.js
@@ -629,6 +629,9 @@ TLSSocket.prototype._wrapHandle = function(wrap, handle) {
defineHandleReading(this, handle);
this.on('close', onSocketCloseDestroySSL);
+ if (wrap) {
+ wrap.on('close', () => this.destroy());
+ }
return res;
};
diff --git a/test/parallel/test-http2-socket-close.js b/test/parallel/test-http2-socket-close.js
new file mode 100644
index 0000000000000000000000000000000000000000..02db77bcf8480c79c77175ba802f9fe10ffc4efe
--- /dev/null
+++ b/test/parallel/test-http2-socket-close.js
@@ -0,0 +1,67 @@
+'use strict';
+
+const common = require('../common');
+const fixtures = require('../common/fixtures');
+if (!common.hasCrypto)
+ common.skip('missing crypto');
+const assert = require('assert');
+const net = require('net');
+const h2 = require('http2');
+
+const tlsOptions = {
+ key: fixtures.readKey('agent1-key.pem'),
+ cert: fixtures.readKey('agent1-cert.pem'),
+ ALPNProtocols: ['h2']
+};
+
+// Create a net server that upgrades sockets to HTTP/2 manually, handles the
+// request, and then shuts down via a short socket timeout and a longer H2 session
+// timeout. This is an unconventional way to shut down a session (the underlying
+// socket closing first) but it should work - critically, it shouldn't segfault
+// (as it did until Node v20.5.1).
+
+let serverRawSocket;
+let serverH2Session;
+
+const netServer = net.createServer((socket) => {
+ serverRawSocket = socket;
+ h2Server.emit('connection', socket);
+});
+
+const h2Server = h2.createSecureServer(tlsOptions, (req, res) => {
+ res.writeHead(200);
+ res.end();
+});
+
+h2Server.on('session', (session) => {
+ serverH2Session = session;
+});
+
+netServer.listen(0, common.mustCall(() => {
+ const proxyClient = h2.connect(`https://localhost:${netServer.address().port}`, {
+ rejectUnauthorized: false
+ });
+
+ proxyClient.on('close', common.mustCall(() => {
+ netServer.close();
+ }));
+
+ const req = proxyClient.request({
+ ':method': 'GET',
+ ':path': '/'
+ });
+
+ req.on('response', common.mustCall((response) => {
+ assert.strictEqual(response[':status'], 200);
+
+ // Asynchronously shut down the server's connections after the response,
+ // but not in the order it typically expects:
+ setTimeout(() => {
+ serverRawSocket.destroy();
+
+ setTimeout(() => {
+ serverH2Session.close();
+ }, 10);
+ }, 10);
+ }));
+}));
diff --git a/test/parallel/test-tls-socket-close.js b/test/parallel/test-tls-socket-close.js
index 87355cf8d7bd2d07bb0fab59491b68f3963f8809..667b291309a4c5636a2c658fa8204b32c2e4df46 100644
--- a/test/parallel/test-tls-socket-close.js
+++ b/test/parallel/test-tls-socket-close.js
@@ -8,37 +8,18 @@ const tls = require('tls');
const net = require('net');
const fixtures = require('../common/fixtures');
-// Regression test for https://github.com/nodejs/node/issues/8074
-//
-// This test has a dependency on the order in which the TCP connection is made,
-// and TLS server handshake completes. It assumes those server side events occur
-// before the client side write callback, which is not guaranteed by the TLS
-// API. It usually passes with TLS1.3, but TLS1.3 didn't exist at the time the
-// bug existed.
-//
-// Pin the test to TLS1.2, since the test shouldn't be changed in a way that
-// doesn't trigger a segfault in Node.js 7.7.3:
-// https://github.com/nodejs/node/issues/13184#issuecomment-303700377
-tls.DEFAULT_MAX_VERSION = 'TLSv1.2';
-
const key = fixtures.readKey('agent2-key.pem');
const cert = fixtures.readKey('agent2-cert.pem');
-let tlsSocket;
-// tls server
+let serverTlsSocket;
const tlsServer = tls.createServer({ cert, key }, (socket) => {
- tlsSocket = socket;
- socket.on('error', common.mustCall((error) => {
- assert.strictEqual(error.code, 'EINVAL');
- tlsServer.close();
- netServer.close();
- }));
+ serverTlsSocket = socket;
});
+// A plain net server, that manually passes connections to the TLS
+// server to be upgraded
let netSocket;
-// plain tcp server
const netServer = net.createServer((socket) => {
- // If client wants to use tls
tlsServer.emit('connection', socket);
netSocket = socket;
@@ -46,35 +27,32 @@ const netServer = net.createServer((socket) => {
connectClient(netServer);
}));
+// A client that connects, sends one message, and closes the raw connection:
function connectClient(server) {
- const tlsConnection = tls.connect({
+ const clientTlsSocket = tls.connect({
host: 'localhost',
port: server.address().port,
rejectUnauthorized: false
});
- tlsConnection.write('foo', 'utf8', common.mustCall(() => {
+ clientTlsSocket.write('foo', 'utf8', common.mustCall(() => {
assert(netSocket);
netSocket.setTimeout(common.platformTimeout(10), common.mustCall(() => {
- assert(tlsSocket);
- // This breaks if TLSSocket is already managing the socket:
+ assert(serverTlsSocket);
+
netSocket.destroy();
- const interval = setInterval(() => {
- // Checking this way allows us to do the write at a time that causes a
- // segmentation fault (not always, but often) in Node.js 7.7.3 and
- // earlier. If we instead, for example, wait on the `close` event, then
- // it will not segmentation fault, which is what this test is all about.
- if (tlsSocket._handle._parent.bytesRead === 0) {
- tlsSocket.write('bar');
- clearInterval(interval);
- }
- }, 1);
+
+ setImmediate(() => {
+ assert.strictEqual(netSocket.destroyed, true);
+ assert.strictEqual(clientTlsSocket.destroyed, true);
+
+ setImmediate(() => {
+ assert.strictEqual(serverTlsSocket.destroyed, true);
+
+ tlsServer.close();
+ netServer.close();
+ });
+ });
}));
}));
- tlsConnection.on('error', (e) => {
- // Tolerate the occasional ECONNRESET.
- // Ref: https://github.com/nodejs/node/issues/13184
- if (e.code !== 'ECONNRESET')
- throw e;
- });
}

View File

@@ -0,0 +1,85 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jameson Nash <vtjnash@gmail.com>
Date: Mon, 2 Oct 2023 15:15:18 +0200
Subject: win,process: avoid assert after spawning Store app (#4152)
Make sure this handle is functional. The Windows kernel seems to have a
bug that if the first use of AssignProcessToJobObject is for a Windows
Store program, subsequent attempts to use the handle with fail with
INVALID_PARAMETER (87). This is possilby because all uses of the handle
must be for the same Terminal Services session. We can ensure it is
tied to our current session now by adding ourself to it. We could
remove ourself afterwards, but there doesn't seem to be a reason to.
Secondly, we start the process suspended so that we can make sure we
added it to the job control object before it does anything itself (such
as launch more jobs or exit).
Fixes: https://github.com/JuliaLang/julia/issues/51461
diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c
index 24c633393fd15dcf87726b174d6b027a969e0f0d..4ad9fec900fa66b0e8c6894701e94f420de903a8 100644
--- a/deps/uv/src/win/process.c
+++ b/deps/uv/src/win/process.c
@@ -102,6 +102,21 @@ static void uv__init_global_job_handle(void) {
&info,
sizeof info))
uv_fatal_error(GetLastError(), "SetInformationJobObject");
+
+
+ if (!AssignProcessToJobObject(uv_global_job_handle_, GetCurrentProcess())) {
+ /* Make sure this handle is functional. The Windows kernel has a bug that
+ * if the first use of AssignProcessToJobObject is for a Windows Store
+ * program, subsequent attempts to use the handle with fail with
+ * INVALID_PARAMETER (87). This is possibly because all uses of the handle
+ * must be for the same Terminal Services session. We can ensure it is tied
+ * to our current session now by adding ourself to it. We could remove
+ * ourself afterwards, but there doesn't seem to be a reason to.
+ */
+ DWORD err = GetLastError();
+ if (err != ERROR_ACCESS_DENIED)
+ uv_fatal_error(err, "AssignProcessToJobObject");
+ }
}
@@ -1098,6 +1113,7 @@ int uv_spawn(uv_loop_t* loop,
* breakaway.
*/
process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP;
+ process_flags |= CREATE_SUSPENDED;
}
if (!CreateProcessW(application_path,
@@ -1115,11 +1131,6 @@ int uv_spawn(uv_loop_t* loop,
goto done;
}
- /* Spawn succeeded. Beyond this point, failure is reported asynchronously. */
-
- process->process_handle = info.hProcess;
- process->pid = info.dwProcessId;
-
/* If the process isn't spawned as detached, assign to the global job object
* so windows will kill it when the parent process dies. */
if (!(options->flags & UV_PROCESS_DETACHED)) {
@@ -1142,6 +1153,19 @@ int uv_spawn(uv_loop_t* loop,
}
}
+ if (process_flags & CREATE_SUSPENDED) {
+ if (ResumeThread(info.hThread) == ((DWORD)-1)) {
+ err = GetLastError();
+ TerminateProcess(info.hProcess, 1);
+ goto done;
+ }
+ }
+
+ /* Spawn succeeded. Beyond this point, failure is reported asynchronously. */
+
+ process->process_handle = info.hProcess;
+ process->pid = info.dwProcessId;
+
/* Set IPC pid to all IPC pipes. */
for (i = 0; i < options->stdio_count; i++) {
const uv_stdio_container_t* fdopt = &options->stdio[i];

View File

@@ -1,2 +1,3 @@
fix_fallback_to_x11_capturer_on_wayland.patch
fix_mark_pipewire_capturer_as_failed_after_session_is_closed.patch
fix_check_pipewire_init_before_creating_generic_capturer.patch

View File

@@ -0,0 +1,23 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Athul Iddya <athul@iddya.com>
Date: Tue, 12 Sep 2023 22:19:46 -0700
Subject: fix: check PipeWire init before creating generic capturer
Check if PipeWire can be initialized before creating generic capturer.
This harmonizes the conditions with the ones used in Linux
implementations of DesktopCapturer::CreateRawScreenCapturer and
DesktopCapturer::CreateRawWindowCapturer.
diff --git a/modules/desktop_capture/desktop_capturer.cc b/modules/desktop_capture/desktop_capturer.cc
index a52a76c2625cf0a2eae7ab5b841e0bf4ff499d88..099313bc1b4e75ebbe62c30190a068f68bfe5366 100644
--- a/modules/desktop_capture/desktop_capturer.cc
+++ b/modules/desktop_capture/desktop_capturer.cc
@@ -113,7 +113,7 @@ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateGenericCapturer(
std::unique_ptr<DesktopCapturer> capturer;
#if defined(WEBRTC_USE_PIPEWIRE)
- if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) {
+ if (options.allow_pipewire() && BaseCapturerPipeWire::IsSupported()) {
capturer = std::make_unique<BaseCapturerPipeWire>(
options, CaptureType::kAnyScreenContent);
}

View File

@@ -19,6 +19,7 @@
#include "base/path_service.h"
#include "base/system/sys_info.h"
#include "base/values.h"
#include "base/win/windows_version.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/icon_manager.h"
#include "chrome/common/chrome_features.h"
@@ -1478,23 +1479,8 @@ void App::SetUserAgentFallback(const std::string& user_agent) {
}
#if BUILDFLAG(IS_WIN)
bool App::IsRunningUnderARM64Translation() const {
USHORT processMachine = 0;
USHORT nativeMachine = 0;
auto IsWow64Process2 = reinterpret_cast<decltype(&::IsWow64Process2)>(
GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process2"));
if (IsWow64Process2 == nullptr) {
return false;
}
if (!IsWow64Process2(GetCurrentProcess(), &processMachine, &nativeMachine)) {
return false;
}
return nativeMachine == IMAGE_FILE_MACHINE_ARM64;
return base::win::OSInfo::IsRunningEmulatedOnArm64();
}
#endif

View File

@@ -953,6 +953,14 @@ void BaseWindow::AddTabbedWindow(NativeWindow* window,
args->ThrowError("AddTabbedWindow cannot be called by a window on itself.");
}
v8::Local<v8::Value> BaseWindow::GetTabbingIdentifier() {
auto tabbing_id = window_->GetTabbingIdentifier();
if (!tabbing_id.has_value())
return v8::Undefined(isolate());
return gin::ConvertToV8(isolate(), tabbing_id.value());
}
void BaseWindow::SetAutoHideMenuBar(bool auto_hide) {
window_->SetAutoHideMenuBar(auto_hide);
}
@@ -1305,6 +1313,7 @@ void BaseWindow::BuildPrototype(v8::Isolate* isolate,
.SetMethod("moveTabToNewWindow", &BaseWindow::MoveTabToNewWindow)
.SetMethod("toggleTabBar", &BaseWindow::ToggleTabBar)
.SetMethod("addTabbedWindow", &BaseWindow::AddTabbedWindow)
.SetProperty("tabbingIdentifier", &BaseWindow::GetTabbingIdentifier)
.SetMethod("setWindowButtonVisibility",
&BaseWindow::SetWindowButtonVisibility)
.SetMethod("_getWindowButtonVisibility",

View File

@@ -198,9 +198,7 @@ class BaseWindow : public gin_helper::TrackableObject<BaseWindow>,
bool GetWindowButtonVisibility() const;
void SetWindowButtonPosition(absl::optional<gfx::Point> position);
absl::optional<gfx::Point> GetWindowButtonPosition() const;
#endif
#if BUILDFLAG(IS_MAC)
bool IsHiddenInMissionControl();
void SetHiddenInMissionControl(bool hidden);
#endif
@@ -215,6 +213,7 @@ class BaseWindow : public gin_helper::TrackableObject<BaseWindow>,
void MoveTabToNewWindow();
void ToggleTabBar();
void AddTabbedWindow(NativeWindow* window, gin_helper::Arguments* args);
v8::Local<v8::Value> GetTabbingIdentifier();
void SetAutoHideMenuBar(bool auto_hide);
bool IsMenuBarAutoHide();
void SetMenuBarVisibility(bool visible);

View File

@@ -43,19 +43,11 @@ BrowserWindow::BrowserWindow(gin::Arguments* args,
gin::Dictionary::CreateEmpty(isolate);
options.Get(options::kWebPreferences, &web_preferences);
bool transparent = false;
options.Get(options::kTransparent, &transparent);
std::string vibrancy_type;
#if BUILDFLAG(IS_MAC)
options.Get(options::kVibrancyType, &vibrancy_type);
#endif
// Copy the backgroundColor to webContents.
std::string color;
if (options.Get(options::kBackgroundColor, &color)) {
web_preferences.SetHidden(options::kBackgroundColor, color);
} else if (!vibrancy_type.empty() || transparent) {
} else if (window_->IsTranslucent()) {
// If the BrowserWindow is transparent or a vibrancy type has been set,
// also propagate transparency to the WebContents unless a separate
// backgroundColor has been set.

View File

@@ -90,16 +90,15 @@ gin::ObjectTemplateBuilder SystemPreferences::GetObjectTemplateBuilder(
&SystemPreferences::IsSwipeTrackingFromScrollEventsEnabled)
.SetMethod("getEffectiveAppearance",
&SystemPreferences::GetEffectiveAppearance)
.SetMethod("getAppLevelAppearance",
&SystemPreferences::GetAppLevelAppearance)
.SetMethod("setAppLevelAppearance",
&SystemPreferences::SetAppLevelAppearance)
.SetMethod("getSystemColor", &SystemPreferences::GetSystemColor)
.SetMethod("canPromptTouchID", &SystemPreferences::CanPromptTouchID)
.SetMethod("promptTouchID", &SystemPreferences::PromptTouchID)
.SetMethod("isTrustedAccessibilityClient",
&SystemPreferences::IsTrustedAccessibilityClient)
.SetMethod("askForMediaAccess", &SystemPreferences::AskForMediaAccess)
.SetProperty(
"accessibilityDisplayShouldReduceTransparency",
&SystemPreferences::AccessibilityDisplayShouldReduceTransparency)
#endif
.SetMethod("getAnimationSettings",
&SystemPreferences::GetAnimationSettings);

View File

@@ -96,6 +96,7 @@ class SystemPreferences
gin::Arguments* args);
void RemoveUserDefault(const std::string& name);
bool IsSwipeTrackingFromScrollEventsEnabled();
bool AccessibilityDisplayShouldReduceTransparency();
std::string GetSystemColor(gin_helper::ErrorThrower thrower,
const std::string& color);
@@ -112,8 +113,6 @@ class SystemPreferences
// TODO(MarshallOfSound): Write tests for these methods once we
// are running tests on a Mojave machine
v8::Local<v8::Value> GetEffectiveAppearance(v8::Isolate* isolate);
v8::Local<v8::Value> GetAppLevelAppearance(v8::Isolate* isolate);
void SetAppLevelAppearance(gin::Arguments* args);
#endif
v8::Local<v8::Value> GetAnimationSettings(v8::Isolate* isolate);

View File

@@ -475,14 +475,7 @@ bool SystemPreferences::IsTrustedAccessibilityClient(bool prompt) {
std::string SystemPreferences::GetColor(gin_helper::ErrorThrower thrower,
const std::string& color) {
NSColor* sysColor = nil;
if (color == "alternate-selected-control-text") {
sysColor = [NSColor alternateSelectedControlTextColor];
EmitWarning(
node::Environment::GetCurrent(thrower.isolate()),
"'alternate-selected-control-text' is deprecated as an input to "
"getColor. Use 'selected-content-background' instead.",
"electron");
} else if (color == "control-background") {
if (color == "control-background") {
sysColor = [NSColor controlBackgroundColor];
} else if (color == "control") {
sysColor = [NSColor controlColor];
@@ -609,19 +602,9 @@ v8::Local<v8::Value> SystemPreferences::GetEffectiveAppearance(
isolate, [NSApplication sharedApplication].effectiveAppearance);
}
v8::Local<v8::Value> SystemPreferences::GetAppLevelAppearance(
v8::Isolate* isolate) {
return gin::ConvertToV8(isolate,
[NSApplication sharedApplication].appearance);
}
void SystemPreferences::SetAppLevelAppearance(gin::Arguments* args) {
NSAppearance* appearance;
if (args->GetNext(&appearance)) {
[[NSApplication sharedApplication] setAppearance:appearance];
} else {
args->ThrowError();
}
bool SystemPreferences::AccessibilityDisplayShouldReduceTransparency() {
return [[NSWorkspace sharedWorkspace]
accessibilityDisplayShouldReduceTransparency];
}
} // namespace electron::api

View File

@@ -1726,13 +1726,6 @@ void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) {
void WebContents::PrimaryMainFrameRenderProcessGone(
base::TerminationStatus status) {
auto weak_this = GetWeakPtr();
Emit("crashed", status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED);
// User might destroy WebContents in the crashed event.
if (!weak_this || !web_contents())
return;
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
v8::HandleScope handle_scope(isolate);
gin_helper::Dictionary details = gin_helper::Dictionary::CreateEmpty(isolate);

View File

@@ -57,7 +57,7 @@
#include "crypto/crypto_buildflags.h"
#include "electron/buildflags/buildflags.h"
#include "electron/shell/common/api/api.mojom.h"
#include "extensions/browser/api/messaging/messaging_api_message_filter.h"
#include "extensions/browser/extension_navigation_ui_data.h"
#include "mojo/public/cpp/bindings/binder_map.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "net/ssl/ssl_private_key.h"
@@ -114,6 +114,7 @@
#include "shell/common/options_switches.h"
#include "shell/common/platform_util.h"
#include "shell/common/thread_restrictions.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
#include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h"
#include "third_party/blink/public/common/tokens/tokens.h"
@@ -147,6 +148,7 @@
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/file_url_loader.h"
#include "content/public/browser/web_ui_url_loader_factory.h"
#include "extensions/browser/api/messaging/messaging_api_message_filter.h"
#include "extensions/browser/api/mime_handler_private/mime_handler_private.h"
#include "extensions/browser/api/web_request/web_request_api.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
@@ -154,7 +156,6 @@
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_message_filter.h"
#include "extensions/browser/extension_navigation_throttle.h"
#include "extensions/browser/extension_navigation_ui_data.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_protocols.h"
#include "extensions/browser/extension_registry.h"
@@ -172,7 +173,6 @@
#include "shell/browser/extensions/electron_extension_message_filter.h"
#include "shell/browser/extensions/electron_extension_system.h"
#include "shell/browser/extensions/electron_extension_web_contents_observer.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#endif
#if BUILDFLAG(ENABLE_PLUGINS)
@@ -1220,12 +1220,12 @@ void ElectronBrowserClient::
protocol_registry->RegisterURLLoaderFactories(factories,
false /* allow_file_access */);
#if BUILDFLAG(ENABLE_EXTENSIONS)
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
factories->emplace(
extensions::kExtensionScheme,
extensions::CreateExtensionServiceWorkerScriptURLLoaderFactory(
browser_context));
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
}
bool ElectronBrowserClient::ShouldTreatURLSchemeAsFirstPartyWhenTopLevel(
@@ -1413,9 +1413,10 @@ void ElectronBrowserClient::OverrideURLLoaderFactoryParams(
factory_params->disable_web_security = true;
}
}
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
extensions::URLLoaderFactoryManager::OverrideURLLoaderFactoryParams(
browser_context, origin, is_for_isolated_world, factory_params);
#endif
}
void ElectronBrowserClient::
@@ -1473,7 +1474,7 @@ void ElectronBrowserClient::
},
&render_frame_host));
#endif
#if BUILDFLAG(ENABLE_EXTENSIONS)
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
associated_registry.AddInterface<extensions::mojom::LocalFrameHost>(
base::BindRepeating(
[](content::RenderFrameHost* render_frame_host,

View File

@@ -79,12 +79,12 @@
#if BUILDFLAG(IS_LINUX)
#include "base/environment.h"
#include "chrome/browser/ui/views/dark_mode_manager_linux.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/dbus/dbus_bluez_manager_wrapper_linux.h"
#include "electron/electron_gtk_stubs.h"
#include "ui/base/cursor/cursor_factory.h"
#include "ui/base/ime/linux/linux_input_method_context_factory.h"
#include "ui/gfx/color_utils.h"
#include "ui/gtk/gtk_compat.h" // nogncheck
#include "ui/gtk/gtk_util.h" // nogncheck
#include "ui/linux/linux_ui.h"
@@ -169,36 +169,8 @@ std::u16string MediaStringProvider(media::MessageId id) {
}
}
#if BUILDFLAG(IS_LINUX)
// GTK does not provide a way to check if current theme is dark, so we compare
// the text and background luminosity to get a result.
// This trick comes from FireFox.
void UpdateDarkThemeSetting() {
float bg = color_utils::GetRelativeLuminance(gtk::GetBgColor("GtkLabel"));
float fg = color_utils::GetRelativeLuminance(gtk::GetFgColor("GtkLabel"));
bool is_dark = fg > bg;
// Pass it to NativeUi theme, which is used by the nativeTheme module and most
// places in Electron.
ui::NativeTheme::GetInstanceForNativeUi()->set_use_dark_colors(is_dark);
// Pass it to Web Theme, to make "prefers-color-scheme" media query work.
ui::NativeTheme::GetInstanceForWeb()->set_use_dark_colors(is_dark);
}
#endif
} // namespace
#if BUILDFLAG(IS_LINUX)
class DarkThemeObserver : public ui::NativeThemeObserver {
public:
DarkThemeObserver() = default;
// ui::NativeThemeObserver:
void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override {
UpdateDarkThemeSetting();
}
};
#endif
// static
ElectronBrowserMainParts* ElectronBrowserMainParts::self_ = nullptr;
@@ -432,17 +404,10 @@ void ElectronBrowserMainParts::ToolkitInitialized() {
CHECK(electron::IsElectron_gdk_pixbufInitialized())
<< "Failed to initialize libgdk_pixbuf-2.0.so.0";
// Chromium does not respect GTK dark theme setting, but they may change
// in future and this code might be no longer needed. Check the Chromium
// issue to keep updated:
// https://bugs.chromium.org/p/chromium/issues/detail?id=998903
UpdateDarkThemeSetting();
// Update the native theme when GTK theme changes. The GetNativeTheme
// here returns a NativeThemeGtk, which monitors GTK settings.
dark_theme_observer_ = std::make_unique<DarkThemeObserver>();
auto* linux_ui_theme = ui::LinuxUiTheme::GetForProfile(nullptr);
CHECK(linux_ui_theme);
linux_ui_theme->GetNativeTheme()->AddObserver(dark_theme_observer_.get());
// source theme changes from system settings, including settings portal:
// https://flatpak.github.io/xdg-desktop-portal/#gdbus-org.freedesktop.portal.Settings
dark_mode_manager_ = std::make_unique<ui::DarkModeManagerLinux>();
ui::LinuxUi::SetInstance(linux_ui);
// Cursor theme changes are tracked by LinuxUI (via a CursorThemeManager

View File

@@ -43,7 +43,8 @@ class Environment;
namespace ui {
class LinuxUiGetter;
}
class DarkModeManagerLinux;
} // namespace ui
namespace electron {
@@ -65,10 +66,6 @@ class ViewsDelegate;
class ViewsDelegateMac;
#endif
#if BUILDFLAG(IS_LINUX)
class DarkThemeObserver;
#endif
class ElectronBrowserMainParts : public content::BrowserMainParts {
public:
ElectronBrowserMainParts();
@@ -145,9 +142,7 @@ class ElectronBrowserMainParts : public content::BrowserMainParts {
#endif
#if BUILDFLAG(IS_LINUX)
// Used to notify the native theme of changes to dark mode.
std::unique_ptr<DarkThemeObserver> dark_theme_observer_;
std::unique_ptr<ui::DarkModeManagerLinux> dark_mode_manager_;
std::unique_ptr<ui::LinuxUiGetter> linux_ui_getter_;
#endif

View File

@@ -13,15 +13,15 @@
#include "chrome/grit/generated_resources.h"
#include "components/strings/grit/components_strings.h"
#include "components/zoom/page_zoom_constants.h"
#include "pdf/buildflags.h"
#include "electron/buildflags/buildflags.h"
#include "printing/buildflags/buildflags.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/webui/web_ui_util.h"
#if BUILDFLAG(ENABLE_PDF)
#if BUILDFLAG(ENABLE_PDF_VIEWER)
#include "chrome/browser/pdf/pdf_extension_util.h"
#include "pdf/pdf_features.h"
#endif // BUILDFLAG(ENABLE_PDF)
#endif // BUILDFLAG(ENABLE_PDF_VIEWER)
// To add a new component to this API, simply:
// 1. Add your component to the Component enum in
@@ -48,7 +48,7 @@ ExtensionFunction::ResponseAction ResourcesPrivateGetStringsFunction::Run() {
switch (component) {
case api::resources_private::COMPONENT_PDF:
#if BUILDFLAG(ENABLE_PDF)
#if BUILDFLAG(ENABLE_PDF_VIEWER)
pdf_extension_util::AddStrings(
pdf_extension_util::PdfViewerContext::kPdfViewer, &dict);
pdf_extension_util::AddAdditionalData(true, false, &dict);

View File

@@ -7,20 +7,27 @@
#include <memory>
#include <utility>
#include "base/command_line.h"
#include "base/strings/pattern.h"
#include "base/types/expected_macros.h"
#include "chrome/common/url_constants.h"
#include "components/url_formatter/url_fixer.h"
#include "content/public/browser/navigation_entry.h"
#include "extensions/browser/extension_api_frame_id_map.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/extension_features.h"
#include "extensions/common/feature_switch.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/mojom/host_id.mojom.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/switches.h"
#include "shell/browser/api/electron_api_web_contents.h"
#include "shell/browser/native_window.h"
#include "shell/browser/web_contents_zoom_controller.h"
#include "shell/browser/window_list.h"
#include "shell/common/extensions/api/tabs.h"
#include "third_party/blink/public/common/chrome_debug_urls.h"
#include "third_party/blink/public/common/page/page_zoom.h"
#include "url/gurl.h"
@@ -468,17 +475,25 @@ bool IsKillURL(const GURL& url) {
DCHECK(url.IsAboutBlank() || url.IsAboutSrcdoc());
#endif
static const char* const kill_hosts[] = {
chrome::kChromeUICrashHost, chrome::kChromeUIDelayedHangUIHost,
chrome::kChromeUIHangUIHost, chrome::kChromeUIKillHost,
// Disallow common renderer debug URLs.
// Note: this would also disallow JavaScript URLs, but we already explicitly
// check for those before calling into here from PrepareURLForNavigation.
if (blink::IsRendererDebugURL(url)) {
return true;
}
if (!url.SchemeIs(content::kChromeUIScheme)) {
return false;
}
// Also disallow a few more hosts which are not covered by the check above.
static const char* const kKillHosts[] = {
chrome::kChromeUIDelayedHangUIHost, chrome::kChromeUIHangUIHost,
chrome::kChromeUIQuitHost, chrome::kChromeUIRestartHost,
content::kChromeUIBrowserCrashHost, content::kChromeUIMemoryExhaustHost,
};
if (!url.SchemeIs(content::kChromeUIScheme))
return false;
return base::Contains(kill_hosts, url.host_piece());
return base::Contains(kKillHosts, url.host_piece());
}
GURL ResolvePossiblyRelativeURL(const std::string& url_string,
@@ -489,10 +504,18 @@ GURL ResolvePossiblyRelativeURL(const std::string& url_string,
return url;
}
bool PrepareURLForNavigation(const std::string& url_string,
const Extension* extension,
GURL* return_url,
std::string* error) {
bool AllowFileAccess(const ExtensionId& extension_id,
content::BrowserContext* context) {
return base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableExtensionsFileAccessCheck) ||
ExtensionPrefs::Get(context)->AllowFileAccess(extension_id);
}
base::expected<GURL, std::string> PrepareURLForNavigation(
const std::string& url_string,
const Extension* extension,
content::BrowserContext* browser_context) {
GURL url = ResolvePossiblyRelativeURL(url_string, extension);
// Ideally, the URL would only be "fixed" for user input (e.g. for URLs
@@ -504,34 +527,62 @@ bool PrepareURLForNavigation(const std::string& url_string,
// Reject invalid URLs.
if (!url.is_valid()) {
const char kInvalidUrlError[] = "Invalid url: \"*\".";
*error = ErrorUtils::FormatErrorMessage(kInvalidUrlError, url_string);
return false;
return base::unexpected(
ErrorUtils::FormatErrorMessage(kInvalidUrlError, url_string));
}
// Don't let the extension use JavaScript URLs in API triggered navigations.
if (url.SchemeIs(url::kJavaScriptScheme)) {
const char kJavaScriptUrlsNotAllowedInExtensionNavigations[] =
"JavaScript URLs are not allowed in API based extension navigations. "
"Use "
"chrome.scripting.executeScript instead.";
return base::unexpected(kJavaScriptUrlsNotAllowedInExtensionNavigations);
}
// Don't let the extension crash the browser or renderers.
if (IsKillURL(url)) {
const char kNoCrashBrowserError[] =
"I'm sorry. I'm afraid I can't do that.";
*error = kNoCrashBrowserError;
return false;
return base::unexpected(kNoCrashBrowserError);
}
// Don't let the extension navigate directly to devtools scheme pages, unless
// they have applicable permissions.
if (url.SchemeIs(content::kChromeDevToolsScheme) &&
!(extension->permissions_data()->HasAPIPermission(
extensions::mojom::APIPermissionID::kDevtools) ||
extension->permissions_data()->HasAPIPermission(
extensions::mojom::APIPermissionID::kDebugger))) {
const char kCannotNavigateToDevtools[] =
"Cannot navigate to a devtools:// page without either the devtools or "
"debugger permission.";
*error = kCannotNavigateToDevtools;
return false;
if (url.SchemeIs(content::kChromeDevToolsScheme)) {
bool has_permission =
extension && (extension->permissions_data()->HasAPIPermission(
mojom::APIPermissionID::kDevtools) ||
extension->permissions_data()->HasAPIPermission(
mojom::APIPermissionID::kDebugger));
if (!has_permission) {
const char kCannotNavigateToDevtools[] =
"Cannot navigate to a devtools:// page without either the devtools "
"or "
"debugger permission.";
return base::unexpected(kCannotNavigateToDevtools);
}
}
return_url->Swap(&url);
return true;
// Don't let the extension navigate directly to chrome-untrusted scheme pages.
if (url.SchemeIs(content::kChromeUIUntrustedScheme)) {
const char kCannotNavigateToChromeUntrusted[] =
"Cannot navigate to a chrome-untrusted:// page.";
return base::unexpected(kCannotNavigateToChromeUntrusted);
}
// Don't let the extension navigate directly to file scheme pages, unless
// they have file access.
if (url.SchemeIsFile() &&
!AllowFileAccess(extension->id(), browser_context) &&
base::FeatureList::IsEnabled(
extensions_features::kRestrictFileURLNavigation)) {
const char kFileUrlsNotAllowedInExtensionNavigations[] =
"Cannot navigate to a file URL without local file access.";
return base::unexpected(kFileUrlsNotAllowedInExtensionNavigations);
}
return url;
}
TabsUpdateFunction::TabsUpdateFunction() : web_contents_(nullptr) {}
@@ -566,22 +617,14 @@ ExtensionFunction::ResponseAction TabsUpdateFunction::Run() {
bool TabsUpdateFunction::UpdateURL(const std::string& url_string,
int tab_id,
std::string* error) {
GURL url;
if (!PrepareURLForNavigation(url_string, extension(), &url, error)) {
auto url =
PrepareURLForNavigation(url_string, extension(), browser_context());
if (!url.has_value()) {
*error = std::move(url.error());
return false;
}
const bool is_javascript_scheme = url.SchemeIs(url::kJavaScriptScheme);
// JavaScript URLs are forbidden in chrome.tabs.update().
if (is_javascript_scheme) {
const char kJavaScriptUrlsNotAllowedInTabsUpdate[] =
"JavaScript URLs are not allowed in chrome.tabs.update. Use "
"chrome.tabs.executeScript instead.";
*error = kJavaScriptUrlsNotAllowedInTabsUpdate;
return false;
}
content::NavigationController::LoadURLParams load_params(url);
content::NavigationController::LoadURLParams load_params(*url);
// Treat extension-initiated navigations as renderer-initiated so that the URL
// does not show in the omnibox until it commits. This avoids URL spoofs

View File

@@ -11,6 +11,7 @@
#include "base/containers/contains.h"
#include "chrome/common/chrome_features.h"
#include "content/public/browser/web_contents.h"
#include "electron/buildflags/buildflags.h"
#include "services/device/public/cpp/hid/hid_switches.h"
#include "shell/browser/electron_permission_manager.h"
#include "shell/browser/hid/hid_chooser_context.h"
@@ -19,9 +20,9 @@
#include "shell/browser/web_contents_permission_helper.h"
#include "third_party/blink/public/common/permissions/permission_utils.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
#include "extensions/common/constants.h"
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
namespace {
@@ -128,14 +129,14 @@ bool ElectronHidDelegate::IsFidoAllowedForOrigin(
bool ElectronHidDelegate::IsServiceWorkerAllowedForOrigin(
const url::Origin& origin) {
#if BUILDFLAG(ENABLE_EXTENSIONS)
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
// WebHID is only available on extension service workers with feature flag
// enabled for now.
if (base::FeatureList::IsEnabled(
features::kEnableWebHidOnExtensionServiceWorker) &&
origin.scheme() == extensions::kExtensionScheme)
return true;
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
return false;
}

View File

@@ -49,7 +49,7 @@ class JavascriptEnvironment {
const raw_ptr<v8::Isolate> isolate_;
// depends-on: isolate_
v8::Locker locker_;
const v8::Locker locker_;
std::unique_ptr<MicrotasksRunner> microtasks_runner_;
};

View File

@@ -13,6 +13,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "content/public/browser/web_contents_user_data.h"
#include "include/core/SkColor.h"
#include "shell/browser/browser.h"
#include "shell/browser/native_window_features.h"
#include "shell/browser/ui/drag_util.h"
@@ -98,6 +99,11 @@ NativeWindow::NativeWindow(const gin_helper::Dictionary& options,
options.Get(options::kTransparent, &transparent_);
options.Get(options::kEnableLargerThanScreen, &enable_larger_than_screen_);
options.Get(options::kTitleBarStyle, &title_bar_style_);
#if BUILDFLAG(IS_WIN)
options.Get(options::kBackgroundMaterial, &background_material_);
#elif BUILDFLAG(IS_MAC)
options.Get(options::kVibrancyType, &vibrancy_);
#endif
v8::Local<v8::Value> titlebar_overlay;
if (options.Get(options::ktitleBarOverlay, &titlebar_overlay)) {
@@ -259,13 +265,15 @@ void NativeWindow::InitFromOptions(const gin_helper::Dictionary& options) {
SetBackgroundMaterial(material);
}
#endif
std::string color;
if (options.Get(options::kBackgroundColor, &color)) {
SetBackgroundColor(ParseCSSColor(color));
} else if (!transparent()) {
// For normal window, use white as default background.
SetBackgroundColor(SK_ColorWHITE);
SkColor background_color = SK_ColorWHITE;
if (std::string color; options.Get(options::kBackgroundColor, &color)) {
background_color = ParseCSSColor(color);
} else if (IsTranslucent()) {
background_color = SK_ColorTRANSPARENT;
}
SetBackgroundColor(background_color);
std::string title(Browser::Get()->GetName());
options.Get(options::kTitle, &title);
SetTitle(title);
@@ -349,10 +357,14 @@ void NativeWindow::SetContentSizeConstraints(
size_constraints_.reset();
}
// Windows/Linux:
// The return value of GetContentSizeConstraints will be passed to Chromium
// to set min/max sizes of window. Note that we are returning content size
// instead of window size because that is what Chromium expects, see the
// comment of |WidgetSizeIsClientSize| in Chromium's codebase to learn more.
//
// macOS:
// The min/max sizes are set directly by calling NSWindow's methods.
extensions::SizeConstraints NativeWindow::GetContentSizeConstraints() const {
if (content_size_constraints_)
return *content_size_constraints_;
@@ -472,9 +484,17 @@ bool NativeWindow::AddTabbedWindow(NativeWindow* window) {
return true; // for non-Mac platforms
}
void NativeWindow::SetVibrancy(const std::string& type) {}
absl::optional<std::string> NativeWindow::GetTabbingIdentifier() const {
return ""; // for non-Mac platforms
}
void NativeWindow::SetBackgroundMaterial(const std::string& type) {}
void NativeWindow::SetVibrancy(const std::string& type) {
vibrancy_ = type;
}
void NativeWindow::SetBackgroundMaterial(const std::string& type) {
background_material_ = type;
}
void NativeWindow::SetTouchBar(
std::vector<gin_helper::PersistentDictionary> items) {}
@@ -798,6 +818,30 @@ void NativeWindow::HandlePendingFullscreenTransitions() {
// static
int32_t NativeWindow::next_id_ = 0;
bool NativeWindow::IsTranslucent() const {
// Transparent windows are translucent
if (transparent()) {
return true;
}
#if BUILDFLAG(IS_MAC)
// Windows with vibrancy set are translucent
if (!vibrancy().empty()) {
return true;
}
#endif
#if BUILDFLAG(IS_WIN)
// Windows with certain background materials may be translucent
const std::string& bg_material = background_material();
if (!bg_material.empty() && bg_material != "none") {
return true;
}
#endif
return false;
}
// static
void NativeWindowRelay::CreateForWebContents(
content::WebContents* web_contents,

View File

@@ -218,8 +218,12 @@ class NativeWindow : public base::SupportsUserData,
virtual void SetAutoHideCursor(bool auto_hide);
// Vibrancy API
const std::string& vibrancy() const { return vibrancy_; }
virtual void SetVibrancy(const std::string& type);
const std::string& background_material() const {
return background_material_;
}
virtual void SetBackgroundMaterial(const std::string& type);
// Traffic Light API
@@ -251,6 +255,7 @@ class NativeWindow : public base::SupportsUserData,
virtual void MoveTabToNewWindow();
virtual void ToggleTabBar();
virtual bool AddTabbedWindow(NativeWindow* window);
virtual absl::optional<std::string> GetTabbingIdentifier() const;
// Toggle the menu bar.
virtual void SetAutoHideMenuBar(bool auto_hide);
@@ -395,6 +400,8 @@ class NativeWindow : public base::SupportsUserData,
void AddDraggableRegionProvider(DraggableRegionProvider* provider);
void RemoveDraggableRegionProvider(DraggableRegionProvider* provider);
bool IsTranslucent() const;
protected:
friend class api::BrowserView;
@@ -492,6 +499,9 @@ class NativeWindow : public base::SupportsUserData,
// Accessible title.
std::u16string accessible_title_;
std::string vibrancy_;
std::string background_material_;
gfx::Rect overlay_rect_;
base::WeakPtrFactory<NativeWindow> weak_factory_{this};

View File

@@ -58,6 +58,8 @@ class NativeWindowMac : public NativeWindow,
gfx::Rect GetBounds() override;
bool IsNormal() override;
gfx::Rect GetNormalBounds() override;
void SetSizeConstraints(
const extensions::SizeConstraints& window_constraints) override;
void SetContentSizeConstraints(
const extensions::SizeConstraints& size_constraints) override;
void SetResizable(bool resizable) override;
@@ -143,6 +145,7 @@ class NativeWindowMac : public NativeWindow,
void MoveTabToNewWindow() override;
void ToggleTabBar() override;
bool AddTabbedWindow(NativeWindow* window) override;
absl::optional<std::string> GetTabbingIdentifier() const override;
void SetAspectRatio(double aspect_ratio,
const gfx::Size& extra_size) override;
void PreviewFile(const std::string& path,
@@ -186,6 +189,9 @@ class NativeWindowMac : public NativeWindow,
has_deferred_window_close_ = defer_close;
}
void set_wants_to_be_visible(bool visible) { wants_to_be_visible_ = visible; }
bool wants_to_be_visible() const { return wants_to_be_visible_; }
enum class VisualEffectState {
kFollowWindow,
kActive,
@@ -252,6 +258,10 @@ class NativeWindowMac : public NativeWindow,
// transition is complete.
bool has_deferred_window_close_ = false;
// If true, the window is either visible, or wants to be visible but is
// currently hidden due to having a hidden parent.
bool wants_to_be_visible_ = false;
NSInteger attention_request_id_ = 0; // identifier from requestUserAttention
// The presentation options before entering kiosk mode.

View File

@@ -496,6 +496,8 @@ void NativeWindowMac::Show() {
return;
}
set_wants_to_be_visible(true);
// Reattach the window to the parent to actually show it.
if (parent())
InternalSetParentWindow(parent(), true);
@@ -528,6 +530,10 @@ void NativeWindowMac::Hide() {
return;
}
// If the window wants to be visible and has a parent, then the parent may
// order it back in (in the period between orderOut: and close).
set_wants_to_be_visible(false);
DetachChildren();
// Detach the window from the parent before.
@@ -663,6 +669,9 @@ void NativeWindowMac::RemoveChildFromParentWindow() {
void NativeWindowMac::AttachChildren() {
for (auto* child : child_windows_) {
if (!static_cast<NativeWindowMac*>(child)->wants_to_be_visible())
continue;
auto* child_nswindow = child->GetNativeWindow().GetNativeNSWindow();
if ([child_nswindow parentWindow] == window_)
continue;
@@ -676,8 +685,6 @@ void NativeWindowMac::AttachChildren() {
}
void NativeWindowMac::DetachChildren() {
DCHECK(child_windows_.size() == [[window_ childWindows] count]);
// Hide all children before hiding/minimizing the window.
// NativeWidgetNSWindowBridge::NotifyVisibilityChangeDown()
// will DCHECK otherwise.
@@ -774,6 +781,16 @@ gfx::Rect NativeWindowMac::GetNormalBounds() {
// return widget()->GetRestoredBounds();
}
void NativeWindowMac::SetSizeConstraints(
const extensions::SizeConstraints& window_constraints) {
// Apply the size constraints to NSWindow.
if (window_constraints.HasMinimumSize())
[window_ setMinSize:window_constraints.GetMinimumSize().ToCGSize()];
if (window_constraints.HasMaximumSize())
[window_ setMaxSize:window_constraints.GetMaximumSize().ToCGSize()];
NativeWindow::SetSizeConstraints(window_constraints);
}
void NativeWindowMac::SetContentSizeConstraints(
const extensions::SizeConstraints& size_constraints) {
auto convertSize = [this](const gfx::Size& size) {
@@ -788,6 +805,7 @@ void NativeWindowMac::SetContentSizeConstraints(
}
};
// Apply the size constraints to NSWindow.
NSView* content = [window_ contentView];
if (size_constraints.HasMinimumSize()) {
NSSize min_size = convertSize(size_constraints.GetMinimumSize());
@@ -1422,11 +1440,21 @@ void NativeWindowMac::UpdateVibrancyRadii(bool fullscreen) {
if (vibrantView != nil && !vibrancy_type_.empty()) {
const bool no_rounded_corner = !HasStyleMask(NSWindowStyleMaskTitled);
if (!has_frame() && !is_modal() && !no_rounded_corner) {
const int macos_version = base::mac::MacOSMajorVersion();
// Modal window corners are rounded on macOS >= 11 or higher if the user
// hasn't passed noRoundedCorners.
bool should_round_modal =
!no_rounded_corner && (macos_version >= 11 ? true : !is_modal());
// Nonmodal window corners are rounded if they're frameless and the user
// hasn't passed noRoundedCorners.
bool should_round_nonmodal = !no_rounded_corner && !has_frame();
if (should_round_nonmodal || should_round_modal) {
CGFloat radius;
if (fullscreen) {
radius = 0.0f;
} else if (@available(macOS 11.0, *)) {
} else if (macos_version >= 11) {
radius = 9.0f;
} else {
// Smaller corner radius on versions prior to Big Sur.
@@ -1460,6 +1488,8 @@ void NativeWindowMac::UpdateWindowOriginalFrame() {
}
void NativeWindowMac::SetVibrancy(const std::string& type) {
NativeWindow::SetVibrancy(type);
NSVisualEffectView* vibrantView = [window_ vibrantView];
if (type.empty()) {
@@ -1633,6 +1663,13 @@ bool NativeWindowMac::AddTabbedWindow(NativeWindow* window) {
return true;
}
absl::optional<std::string> NativeWindowMac::GetTabbingIdentifier() const {
if ([window_ tabbingMode] == NSWindowTabbingModeDisallowed)
return absl::nullopt;
return base::SysNSStringToUTF8([window_ tabbingIdentifier]);
}
void NativeWindowMac::SetAspectRatio(double aspect_ratio,
const gfx::Size& extra_size) {
NativeWindow::SetAspectRatio(aspect_ratio, extra_size);

View File

@@ -280,12 +280,12 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
params.remove_standard_frame = !has_frame() || has_client_frame();
// If a client frame, we need to draw our own shadows.
if (transparent() || has_client_frame())
if (IsTranslucent() || has_client_frame())
params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent;
// The given window is most likely not rectangular since it uses
// transparency and has no standard frame, don't show a shadow for it.
if (transparent() && !has_frame())
// The given window is most likely not rectangular since it is translucent and
// has no standard frame, don't show a shadow for it.
if (IsTranslucent() && !has_frame())
params.shadow_type = views::Widget::InitParams::ShadowType::kNone;
bool focusable;
@@ -1453,6 +1453,8 @@ bool NativeWindowViews::IsMenuBarVisible() {
}
void NativeWindowViews::SetBackgroundMaterial(const std::string& material) {
NativeWindow::SetBackgroundMaterial(material);
#if BUILDFLAG(IS_WIN)
// DWMWA_USE_HOSTBACKDROPBRUSH is only supported on Windows 11 22H2 and up.
if (base::win::GetVersion() < base::win::Version::WIN11_22H2)
@@ -1464,6 +1466,20 @@ void NativeWindowViews::SetBackgroundMaterial(const std::string& material) {
&backdrop_type, sizeof(backdrop_type));
if (FAILED(result))
LOG(WARNING) << "Failed to set background material to " << material;
// For frameless windows with a background material set, we also need to
// remove the caption color so it doesn't render a caption bar (since the
// window is frameless)
COLORREF caption_color = DWMWA_COLOR_DEFAULT;
if (backdrop_type != DWMSBT_NONE && backdrop_type != DWMSBT_AUTO &&
!has_frame()) {
caption_color = DWMWA_COLOR_NONE;
}
result = DwmSetWindowAttribute(GetAcceleratedWidget(), DWMWA_CAPTION_COLOR,
&caption_color, sizeof(caption_color));
if (FAILED(result))
LOG(WARNING) << "Failed to set caption color to transparent";
#endif
}

View File

@@ -7,6 +7,7 @@
#include <wrl/client.h>
#include "base/win/atl.h" // Must be before UIAutomationCore.h
#include "base/win/scoped_handle.h"
#include "content/public/browser/browser_accessibility_state.h"
#include "shell/browser/browser.h"
#include "shell/browser/native_window_views.h"
@@ -165,10 +166,41 @@ gfx::ResizeEdge GetWindowResizeEdge(WPARAM param) {
}
}
bool IsMutexPresent(const wchar_t* name) {
base::win::ScopedHandle mutex_holder(::CreateMutex(nullptr, false, name));
return ::GetLastError() == ERROR_ALREADY_EXISTS;
}
bool IsLibraryLoaded(const wchar_t* name) {
HMODULE hmodule = nullptr;
::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, name,
&hmodule);
return hmodule != nullptr;
}
// The official way to get screen reader status is to call:
// SystemParametersInfo(SPI_GETSCREENREADER) && UiaClientsAreListening()
// However it has false positives (for example when user is using touch screens)
// and will cause performance issues in some apps.
bool IsScreenReaderActive() {
UINT screenReader = 0;
SystemParametersInfo(SPI_GETSCREENREADER, 0, &screenReader, 0);
return screenReader && UiaClientsAreListening();
if (IsMutexPresent(L"NarratorRunning"))
return true;
static const wchar_t* names[] = {// NVDA
L"nvdaHelperRemote.dll",
// JAWS
L"jhook.dll",
// Window-Eyes
L"gwhk64.dll", L"gwmhook.dll",
// ZoomText
L"AiSquared.Infuser.HookLib.dll"};
for (auto* name : names) {
if (IsLibraryLoaded(name))
return true;
}
return false;
}
} // namespace

View File

@@ -9,11 +9,11 @@
#include "base/containers/contains.h"
#include "base/values.h"
#include "content/public/common/webplugininfo.h"
#include "extensions/buildflags/buildflags.h"
#include "electron/buildflags/buildflags.h"
#include "url/gurl.h"
#include "url/origin.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_util.h"
#include "extensions/common/constants.h"
@@ -36,7 +36,7 @@ base::flat_map<std::string, std::string>
PluginUtils::GetMimeTypeToExtensionIdMap(
content::BrowserContext* browser_context) {
base::flat_map<std::string, std::string> mime_type_to_extension_id_map;
#if BUILDFLAG(ENABLE_EXTENSIONS)
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
std::vector<std::string> allowed_extension_ids =
MimeTypesHandler::GetMIMETypeAllowlist();
// Go through the white-listed extensions and try to use them to intercept

View File

@@ -262,6 +262,7 @@ using FullScreenTransitionState =
[super windowDidMiniaturize:notification];
is_minimized_ = true;
shell_->set_wants_to_be_visible(false);
shell_->NotifyWindowMinimize();
}
@@ -269,6 +270,7 @@ using FullScreenTransitionState =
[super windowDidDeminiaturize:notification];
is_minimized_ = false;
shell_->set_wants_to_be_visible(true);
shell_->AttachChildren();
shell_->SetWindowLevel(level_);
shell_->NotifyWindowRestore();

View File

@@ -142,8 +142,11 @@ void InspectableWebContentsViewViews::CloseDevTools() {
devtools_visible_ = false;
if (devtools_window_) {
inspectable_web_contents()->SaveDevToolsBounds(
devtools_window_->GetWindowBoundsInScreen());
auto save_bounds = devtools_window_->IsMinimized()
? devtools_window_->GetRestoredBounds()
: devtools_window_->GetWindowBoundsInScreen();
inspectable_web_contents()->SaveDevToolsBounds(save_bounds);
devtools_window_.reset();
devtools_window_web_view_ = nullptr;
devtools_window_delegate_ = nullptr;
@@ -216,6 +219,8 @@ const std::u16string InspectableWebContentsViewViews::GetTitle() {
void InspectableWebContentsViewViews::Layout() {
if (!devtools_web_view_->GetVisible()) {
contents_web_view_->SetBoundsRect(GetContentsBounds());
// Propagate layout call to all children, for example browser views.
View::Layout();
return;
}
@@ -233,6 +238,9 @@ void InspectableWebContentsViewViews::Layout() {
devtools_web_view_->SetBoundsRect(new_devtools_bounds);
contents_web_view_->SetBoundsRect(new_contents_bounds);
// Propagate layout call to all children, for example browser views.
View::Layout();
if (GetDelegate())
GetDelegate()->DevToolsResized();
}

View File

@@ -133,4 +133,14 @@ void ElectronDesktopWindowTreeHostWin::OnNativeThemeUpdated(
}
}
bool ElectronDesktopWindowTreeHostWin::ShouldWindowContentsBeTransparent()
const {
// Window should be marked as opaque if no transparency setting has been set,
// otherwise videos rendered in the window will trigger a DirectComposition
// redraw for every frame.
// https://github.com/electron/electron/pull/39895
return native_window_view_->GetOpacity() < 1.0 ||
native_window_view_->transparent();
}
} // namespace electron

View File

@@ -40,6 +40,7 @@ class ElectronDesktopWindowTreeHostWin : public views::DesktopWindowTreeHostWin,
// ui::NativeThemeObserver:
void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override;
bool ShouldWindowContentsBeTransparent() const override;
private:
raw_ptr<NativeWindowViews> native_window_view_; // weak ref

View File

@@ -13,7 +13,7 @@
#include "base/scoped_observation.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "extensions/buildflags/buildflags.h"
#include "electron/buildflags/buildflags.h"
#include "services/device/public/mojom/usb_enumeration_options.mojom.h"
#include "shell/browser/electron_permission_manager.h"
#include "shell/browser/usb/usb_chooser_context.h"
@@ -21,7 +21,7 @@
#include "shell/browser/usb/usb_chooser_controller.h"
#include "shell/browser/web_contents_permission_helper.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
#include "base/containers/fixed_flat_set.h"
#include "chrome/common/chrome_features.h"
#include "extensions/browser/extension_registry.h"
@@ -41,7 +41,7 @@ electron::UsbChooserContext* GetChooserContext(
browser_context);
}
#if BUILDFLAG(ENABLE_EXTENSIONS)
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
// These extensions can claim the smart card USB class and automatically gain
// permissions for devices that have an interface with this class.
constexpr auto kSmartCardPrivilegedExtensionIds =
@@ -65,12 +65,12 @@ bool DeviceHasInterfaceWithClass(
}
return false;
}
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
bool IsDevicePermissionAutoGranted(
const url::Origin& origin,
const device::mojom::UsbDeviceInfo& device_info) {
#if BUILDFLAG(ENABLE_EXTENSIONS)
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
// Note: The `DeviceHasInterfaceWithClass()` call is made after checking the
// origin, since that method call is expensive.
if (origin.scheme() == extensions::kExtensionScheme &&
@@ -79,7 +79,7 @@ bool IsDevicePermissionAutoGranted(
device::mojom::kUsbSmartCardClass)) {
return true;
}
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
return false;
}
@@ -251,14 +251,14 @@ ElectronUsbDelegate::GetContextObserver(
bool ElectronUsbDelegate::IsServiceWorkerAllowedForOrigin(
const url::Origin& origin) {
#if BUILDFLAG(ENABLE_EXTENSIONS)
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
// WebUSB is only available on extension service workers for now.
if (base::FeatureList::IsEnabled(
features::kEnableWebUsbOnExtensionServiceWorker) &&
origin.scheme() == extensions::kExtensionScheme) {
return true;
}
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
return false;
}
@@ -289,7 +289,7 @@ void ElectronUsbDelegate::DeleteControllerForFrame(
bool ElectronUsbDelegate::PageMayUseUsb(content::Page& page) {
content::RenderFrameHost& main_rfh = page.GetMainDocument();
#if BUILDFLAG(ENABLE_EXTENSIONS)
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
// WebViewGuests have no mechanism to show permission prompts and their
// embedder can't grant USB access through its permissionrequest API. Also
// since webviews use a separate StoragePartition, they must not gain access
@@ -297,7 +297,7 @@ bool ElectronUsbDelegate::PageMayUseUsb(content::Page& page) {
if (extensions::WebViewGuest::FromRenderFrameHost(&main_rfh)) {
return false;
}
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
// USB permissions are scoped to a BrowserContext instead of a
// StoragePartition, so we need to be careful about usage across

View File

@@ -121,9 +121,7 @@ class Archive : public node::ObjectWrap {
gin_helper::Dictionary dict(isolate, v8::Object::New(isolate));
dict.Set("size", stats.size);
dict.Set("offset", stats.offset);
dict.Set("isFile", stats.is_file);
dict.Set("isDirectory", stats.is_directory);
dict.Set("isLink", stats.is_link);
dict.Set("type", static_cast<int>(stats.type));
args.GetReturnValue().Set(dict.GetHandle());
}

View File

@@ -311,14 +311,12 @@ bool Archive::Stat(const base::FilePath& path, Stats* stats) const {
return false;
if (node->Find("link")) {
stats->is_file = false;
stats->is_link = true;
stats->type = FileType::kLink;
return true;
}
if (node->Find("files")) {
stats->is_file = false;
stats->is_directory = true;
stats->type = FileType::kDirectory;
return true;
}

View File

@@ -10,6 +10,8 @@
#include <unordered_map>
#include <vector>
#include <uv.h>
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/synchronization/lock.h"
@@ -49,11 +51,14 @@ class Archive {
absl::optional<IntegrityPayload> integrity;
};
enum class FileType {
kFile = UV_DIRENT_FILE,
kDirectory = UV_DIRENT_DIR,
kLink = UV_DIRENT_LINK,
};
struct Stats : public FileInfo {
Stats() : is_file(true), is_directory(false), is_link(false) {}
bool is_file;
bool is_directory;
bool is_link;
FileType type = FileType::kFile;
};
explicit Archive(const base::FilePath& path);

View File

@@ -10,6 +10,7 @@
#include "base/containers/fixed_flat_map.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversion_utils.h"
#include "base/strings/utf_string_conversions.h"
#include "gin/converter.h"
#include "gin/data_object_builder.h"
@@ -275,11 +276,18 @@ bool Converter<blink::WebKeyboardEvent>::FromV8(v8::Isolate* isolate,
if ((out->GetType() == blink::WebInputEvent::Type::kChar ||
out->GetType() == blink::WebInputEvent::Type::kRawKeyDown)) {
// If the keyCode is e.g. Space or Plus we want to use the character
// instead of the keyCode: ' ' instead of 'Space', '+' instead of 'Plus'.
std::string character_str;
if (str.size() > 1 && domKey.IsCharacter())
base::WriteUnicodeCharacter(domKey.ToCharacter(), &character_str);
// Make sure to not read beyond the buffer in case some bad code doesn't
// NULL-terminate it (this is called from plugins).
size_t text_length_cap = blink::WebKeyboardEvent::kTextLengthCap;
std::u16string text16 = base::UTF8ToUTF16(str);
std::u16string text16 = character_str.empty()
? base::UTF8ToUTF16(str)
: base::UTF8ToUTF16(character_str);
std::fill_n(out->text, text_length_cap, 0);
std::fill_n(out->unmodified_text, text_length_cap, 0);
for (size_t i = 0; i < std::min(text_length_cap - 1, text16.size()); ++i) {

View File

@@ -4,7 +4,6 @@
#include "shell/common/gin_helper/event_emitter_caller.h"
#include "shell/common/gin_helper/locker.h"
#include "shell/common/gin_helper/microtasks_scope.h"
#include "shell/common/node_includes.h"

View File

@@ -8,10 +8,9 @@
namespace gin_helper {
Locker::Locker(v8::Isolate* isolate) {
if (electron::IsBrowserProcess())
locker_ = std::make_unique<v8::Locker>(isolate);
}
Locker::Locker(v8::Isolate* isolate)
: locker_{electron::IsBrowserProcess() ? new v8::Locker{isolate}
: nullptr} {}
Locker::~Locker() = default;

View File

@@ -21,13 +21,12 @@ class Locker {
Locker(const Locker&) = delete;
Locker& operator=(const Locker&) = delete;
// prevent heap allocation
void* operator new(size_t size) = delete;
void operator delete(void*, size_t) = delete;
private:
void* operator new(size_t size);
void operator delete(void*, size_t);
std::unique_ptr<v8::Locker> locker_;
static bool g_is_browser_process;
const std::unique_ptr<v8::Locker> locker_;
};
} // namespace gin_helper

View File

@@ -30,7 +30,6 @@
#include "shell/common/gin_helper/dictionary.h"
#include "shell/common/gin_helper/event.h"
#include "shell/common/gin_helper/event_emitter_caller.h"
#include "shell/common/gin_helper/locker.h"
#include "shell/common/gin_helper/microtasks_scope.h"
#include "shell/common/mac/main_application_bundle.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_initializer.h" // nogncheck
@@ -523,6 +522,13 @@ std::shared_ptr<node::Environment> NodeBindings::CreateEnvironment(
electron::fuses::IsOnlyLoadAppFromAsarEnabled()
? app_asar_search_paths
: search_paths));
context->Global()->SetPrivate(
context,
v8::Private::ForApi(
isolate, gin::ConvertToV8(isolate, "appSearchPathsOnlyLoadASAR")
.As<v8::String>()),
gin::ConvertToV8(isolate,
electron::fuses::IsOnlyLoadAppFromAsarEnabled()));
}
base::FilePath resources_path = GetResourcesPath();

View File

@@ -7,15 +7,15 @@
#include <utility>
#include "content/public/renderer/render_frame.h"
#include "extensions/buildflags/buildflags.h"
#include "electron/buildflags/buildflags.h"
#include "third_party/blink/public/web/web_element.h"
#include "third_party/blink/public/web/web_local_frame.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
#include "chrome/common/pdf_util.h"
#include "extensions/common/constants.h"
#include "extensions/renderer/guest_view/mime_handler_view/post_message_support.h"
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
namespace electron {
@@ -26,14 +26,14 @@ PrintRenderFrameHelperDelegate::~PrintRenderFrameHelperDelegate() = default;
// Return the PDF object element if |frame| is the out of process PDF extension.
blink::WebElement PrintRenderFrameHelperDelegate::GetPdfElement(
blink::WebLocalFrame* frame) {
#if BUILDFLAG(ENABLE_EXTENSIONS)
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
if (frame->Parent() &&
IsPdfInternalPluginAllowedOrigin(frame->Parent()->GetSecurityOrigin())) {
auto plugin_element = frame->GetDocument().QuerySelector("embed");
DCHECK(!plugin_element.IsNull());
return plugin_element;
}
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
return blink::WebElement();
}
@@ -43,7 +43,7 @@ bool PrintRenderFrameHelperDelegate::IsPrintPreviewEnabled() {
bool PrintRenderFrameHelperDelegate::OverridePrint(
blink::WebLocalFrame* frame) {
#if BUILDFLAG(ENABLE_EXTENSIONS)
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
auto* post_message_support =
extensions::PostMessageSupport::FromWebLocalFrame(frame);
if (post_message_support) {
@@ -56,7 +56,7 @@ bool PrintRenderFrameHelperDelegate::OverridePrint(
post_message_support->PostMessageFromValue(base::Value(std::move(message)));
return true;
}
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
#endif // BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
return false;
}

View File

@@ -235,14 +235,6 @@ void RendererClientBase::RenderThreadStarted() {
extensions::ExtensionsRendererClient::Set(extensions_renderer_client_.get());
thread->AddObserver(extensions_renderer_client_->GetDispatcher());
#endif
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
spellcheck_ = std::make_unique<SpellCheck>(this);
#endif
blink::WebCustomElement::AddEmbedderCustomElementName("webview");
blink::WebCustomElement::AddEmbedderCustomElementName("browserplugin");
WTF::String extension_scheme(extensions::kExtensionScheme);
// Extension resources are HTTP-like and safe to expose to the fetch API. The
@@ -255,6 +247,14 @@ void RendererClientBase::RenderThreadStarted() {
extension_scheme);
blink::SchemeRegistry::RegisterURLSchemeAsBypassingContentSecurityPolicy(
extension_scheme);
#endif
#if BUILDFLAG(ENABLE_BUILTIN_SPELLCHECKER)
spellcheck_ = std::make_unique<SpellCheck>(this);
#endif
blink::WebCustomElement::AddEmbedderCustomElementName("webview");
blink::WebCustomElement::AddEmbedderCustomElementName("browserplugin");
std::vector<std::string> fetch_enabled_schemes =
ParseSchemesCLISwitch(command_line, switches::kFetchSchemes);

View File

@@ -20,10 +20,10 @@ namespace electron {
NodeService::NodeService(
mojo::PendingReceiver<node::mojom::NodeService> receiver)
: node_bindings_(
NodeBindings::Create(NodeBindings::BrowserEnvironment::kUtility)),
electron_bindings_(
std::make_unique<ElectronBindings>(node_bindings_->uv_loop())) {
: node_bindings_{NodeBindings::Create(
NodeBindings::BrowserEnvironment::kUtility)},
electron_bindings_{
std::make_unique<ElectronBindings>(node_bindings_->uv_loop())} {
if (receiver.is_valid())
receiver_.Bind(std::move(receiver));
}

View File

@@ -37,10 +37,18 @@ class NodeService : public node::mojom::NodeService {
private:
bool node_env_stopped_ = false;
const std::unique_ptr<NodeBindings> node_bindings_;
// depends-on: node_bindings_'s uv_loop
const std::unique_ptr<ElectronBindings> electron_bindings_;
// depends-on: node_bindings_'s uv_loop
std::unique_ptr<JavascriptEnvironment> js_env_;
std::unique_ptr<NodeBindings> node_bindings_;
std::unique_ptr<ElectronBindings> electron_bindings_;
// depends-on: js_env_'s isolate
std::shared_ptr<node::Environment> node_env_;
mojo::Receiver<node::mojom::NodeService> receiver_{this};
};

View File

@@ -2066,10 +2066,7 @@ describe('BrowserWindow module', () => {
beforeEach(() => {
w = new BrowserWindow({ show: false });
});
afterEach(async () => {
await closeWindow(w);
w = null as unknown as BrowserWindow;
});
afterEach(closeAllWindows);
describe('BrowserWindow.selectPreviousTab()', () => {
it('does not throw', () => {
@@ -2138,6 +2135,18 @@ describe('BrowserWindow module', () => {
}).to.throw('AddTabbedWindow cannot be called by a window on itself.');
});
});
describe('BrowserWindow.tabbingIdentifier', () => {
it('is undefined if no tabbingIdentifier was set', () => {
const w = new BrowserWindow({ show: false });
expect(w.tabbingIdentifier).to.be.undefined('tabbingIdentifier');
});
it('returns the window tabbingIdentifier', () => {
const w = new BrowserWindow({ show: false, tabbingIdentifier: 'group1' });
expect(w.tabbingIdentifier).to.equal('group1');
});
});
});
describe('autoHideMenuBar state', () => {
@@ -4716,7 +4725,27 @@ describe('BrowserWindow module', () => {
expect(w.getChildWindows().length).to.equal(0);
});
ifit(process.platform === 'darwin')('child window matches visibility when visibility changes', async () => {
ifit(process.platform === 'darwin')('only shows the intended window when a child with siblings is shown', async () => {
const w = new BrowserWindow({ show: false });
const childOne = new BrowserWindow({ show: false, parent: w });
const childTwo = new BrowserWindow({ show: false, parent: w });
const parentShown = once(w, 'show');
w.show();
await parentShown;
expect(childOne.isVisible()).to.be.false('childOne is visible');
expect(childTwo.isVisible()).to.be.false('childTwo is visible');
const childOneShown = once(childOne, 'show');
childOne.show();
await childOneShown;
expect(childOne.isVisible()).to.be.true('childOne is not visible');
expect(childTwo.isVisible()).to.be.false('childTwo is visible');
});
ifit(process.platform === 'darwin')('child matches parent visibility when parent visibility changes', async () => {
const w = new BrowserWindow({ show: false });
const c = new BrowserWindow({ show: false, parent: w });
@@ -4743,7 +4772,7 @@ describe('BrowserWindow module', () => {
expect(c.isVisible()).to.be.true('child is visible');
});
ifit(process.platform === 'darwin')('matches child window visibility when visibility changes', async () => {
ifit(process.platform === 'darwin')('parent matches child visibility when child visibility changes', async () => {
const w = new BrowserWindow({ show: false });
const c = new BrowserWindow({ show: false, parent: w });

View File

@@ -1,11 +1,9 @@
import { expect } from 'chai';
import { nativeTheme, systemPreferences, BrowserWindow, ipcMain } from 'electron/main';
import { nativeTheme, BrowserWindow, ipcMain } from 'electron/main';
import { once } from 'node:events';
import * as path from 'node:path';
import { setTimeout } from 'node:timers/promises';
import { expectDeprecationMessages } from './lib/deprecate-helpers';
import { ifdescribe } from './lib/spec-helpers';
import { closeAllWindows } from './lib/window-helpers';
describe('nativeTheme module', () => {
@@ -59,20 +57,6 @@ describe('nativeTheme module', () => {
expect(called).to.equal(false);
});
ifdescribe(process.platform === 'darwin')('on macOS', () => {
it('should update appLevelAppearance when set', async () => {
await expectDeprecationMessages(
() => {
nativeTheme.themeSource = 'dark';
expect(systemPreferences.appLevelAppearance).to.equal('dark');
nativeTheme.themeSource = 'light';
expect(systemPreferences.appLevelAppearance).to.equal('light');
},
"(electron) 'appLevelAppearance' is deprecated and will be removed."
);
});
});
const getPrefersColorSchemeIsDark = async (w: Electron.BrowserWindow) => {
const isDark: boolean = await w.webContents.executeJavaScript(
'matchMedia("(prefers-color-scheme: dark)").matches'

View File

@@ -1,6 +1,5 @@
import { expect } from 'chai';
import { systemPreferences } from 'electron/main';
import { expectDeprecationMessages } from './lib/deprecate-helpers';
import { ifdescribe } from './lib/spec-helpers';
describe('systemPreferences module', () => {
@@ -215,52 +214,6 @@ describe('systemPreferences module', () => {
const sysColor = systemPreferences.getColor(color);
expect(sysColor).to.be.a('string');
});
await expectDeprecationMessages(
() => {
const sysColor = systemPreferences.getColor('alternate-selected-control-text');
expect(sysColor).to.be.a('string');
},
"'alternate-selected-control-text' is deprecated as an input to getColor. Use 'selected-content-background' instead."
);
});
});
ifdescribe(process.platform === 'darwin')('systemPreferences.appLevelAppearance', () => {
const options = ['dark', 'light', 'unknown', null];
describe('with properties', () => {
it('returns a valid appearance', () => {
const appearance = systemPreferences.appLevelAppearance;
expect(options).to.include(appearance);
});
it('can be changed', () => {
systemPreferences.appLevelAppearance = 'dark';
expect(systemPreferences.appLevelAppearance).to.eql('dark');
});
});
describe('with functions', () => {
it('returns a valid appearance', async () => {
await expectDeprecationMessages(
() => {
const appearance = systemPreferences.getAppLevelAppearance();
expect(options).to.include(appearance);
},
"(electron) 'getAppLevelAppearance function' is deprecated and will be removed."
);
});
it('can be changed', async () => {
await expectDeprecationMessages(
() => {
systemPreferences.setAppLevelAppearance('dark');
const appearance = systemPreferences.getAppLevelAppearance();
expect(appearance).to.eql('dark');
},
"(electron) 'setAppLevelAppearance function' is deprecated and will be removed."
);
});
});
});

View File

@@ -839,6 +839,20 @@ describe('webContents module', () => {
expect(altKey).to.be.false();
});
it('can correctly convert accelerators to key codes', async () => {
const keyup = once(ipcMain, 'keyup');
w.webContents.sendInputEvent({ keyCode: 'Plus', type: 'char' });
w.webContents.sendInputEvent({ keyCode: 'Space', type: 'char' });
w.webContents.sendInputEvent({ keyCode: 'Plus', type: 'char' });
w.webContents.sendInputEvent({ keyCode: 'Space', type: 'char' });
w.webContents.sendInputEvent({ keyCode: 'Plus', type: 'char' });
w.webContents.sendInputEvent({ keyCode: 'Plus', type: 'keyUp' });
await keyup;
const inputText = await w.webContents.executeJavaScript('document.getElementById("input").value');
expect(inputText).to.equal('+ + +');
});
it('can send char events with modifiers', async () => {
const keypress = once(ipcMain, 'keypress');
w.webContents.sendInputEvent({ type: 'keyDown', keyCode: 'Z' });
@@ -2256,13 +2270,13 @@ describe('webContents module', () => {
});
describe('crashed event', () => {
it('does not crash main process when destroying WebContents in it', async () => {
it('does not crash main process when destroying WebContents in it', (done) => {
const contents = (webContents as typeof ElectronInternal.WebContents).create({ nodeIntegration: true });
const crashEvent = once(contents, 'render-process-gone');
await contents.loadURL('about:blank');
contents.forcefullyCrashRenderer();
await crashEvent;
contents.destroy();
contents.once('crashed', () => {
contents.destroy();
done();
});
contents.loadURL('about:blank').then(() => contents.forcefullyCrashRenderer());
});
});

View File

@@ -1039,33 +1039,77 @@ describe('chrome extensions', () => {
});
});
it('update', async () => {
await w.loadURL(url);
describe('update', () => {
it('can update muted status', async () => {
await w.loadURL(url);
const message = { method: 'update', args: [{ muted: true }] };
w.webContents.executeJavaScript(`window.postMessage('${JSON.stringify(message)}', '*')`);
const message = { method: 'update', args: [{ muted: true }] };
w.webContents.executeJavaScript(`window.postMessage('${JSON.stringify(message)}', '*')`);
const [,, responseString] = await once(w.webContents, 'console-message');
const response = JSON.parse(responseString);
const [,, responseString] = await once(w.webContents, 'console-message');
const response = JSON.parse(responseString);
expect(response).to.have.property('url').that.is.a('string');
expect(response).to.have.property('title').that.is.a('string');
expect(response).to.have.property('active').that.is.a('boolean');
expect(response).to.have.property('autoDiscardable').that.is.a('boolean');
expect(response).to.have.property('discarded').that.is.a('boolean');
expect(response).to.have.property('groupId').that.is.a('number');
expect(response).to.have.property('highlighted').that.is.a('boolean');
expect(response).to.have.property('id').that.is.a('number');
expect(response).to.have.property('incognito').that.is.a('boolean');
expect(response).to.have.property('index').that.is.a('number');
expect(response).to.have.property('pinned').that.is.a('boolean');
expect(response).to.have.property('selected').that.is.a('boolean');
expect(response).to.have.property('windowId').that.is.a('number');
expect(response).to.have.property('mutedInfo').that.is.a('object');
const { mutedInfo } = response;
expect(mutedInfo).to.deep.eq({
muted: true,
reason: 'user'
expect(response).to.have.property('mutedInfo').that.is.a('object');
const { mutedInfo } = response;
expect(mutedInfo).to.deep.eq({
muted: true,
reason: 'user'
});
});
it('fails when navigating to an invalid url', async () => {
await w.loadURL(url);
const message = { method: 'update', args: [{ url: 'chrome://crash' }] };
w.webContents.executeJavaScript(`window.postMessage('${JSON.stringify(message)}', '*')`);
const [,, responseString] = await once(w.webContents, 'console-message');
const { error } = JSON.parse(responseString);
expect(error).to.eq('I\'m sorry. I\'m afraid I can\'t do that.');
});
it('fails when navigating to prohibited url', async () => {
await w.loadURL(url);
const message = { method: 'update', args: [{ url: 'chrome://crash' }] };
w.webContents.executeJavaScript(`window.postMessage('${JSON.stringify(message)}', '*')`);
const [,, responseString] = await once(w.webContents, 'console-message');
const { error } = JSON.parse(responseString);
expect(error).to.eq('I\'m sorry. I\'m afraid I can\'t do that.');
});
it('fails when navigating to a devtools url without permission', async () => {
await w.loadURL(url);
const message = { method: 'update', args: [{ url: 'devtools://blah' }] };
w.webContents.executeJavaScript(`window.postMessage('${JSON.stringify(message)}', '*')`);
const [, , responseString] = await once(w.webContents, 'console-message');
const { error } = JSON.parse(responseString);
expect(error).to.eq('Cannot navigate to a devtools:// page without either the devtools or debugger permission.');
});
it('fails when navigating to a chrome-untrusted url', async () => {
await w.loadURL(url);
const message = { method: 'update', args: [{ url: 'chrome-untrusted://blah' }] };
w.webContents.executeJavaScript(`window.postMessage('${JSON.stringify(message)}', '*')`);
const [, , responseString] = await once(w.webContents, 'console-message');
const { error } = JSON.parse(responseString);
expect(error).to.eq('Cannot navigate to a chrome-untrusted:// page.');
});
it('fails when navigating to a file url withotut file access', async () => {
await w.loadURL(url);
const message = { method: 'update', args: [{ url: 'file://blah' }] };
w.webContents.executeJavaScript(`window.postMessage('${JSON.stringify(message)}', '*')`);
const [, , responseString] = await once(w.webContents, 'console-message');
const { error } = JSON.parse(responseString);
expect(error).to.eq('Cannot navigate to a file URL without local file access.');
});
});

View File

@@ -1,6 +1,6 @@
/* global chrome */
const handleRequest = (request, sender, sendResponse) => {
const handleRequest = async (request, sender, sendResponse) => {
const { method, args = [] } = request;
const tabId = sender.tab.id;
@@ -53,7 +53,12 @@ const handleRequest = (request, sender, sendResponse) => {
case 'update': {
const [params] = args;
chrome.tabs.update(tabId, params).then(sendResponse);
try {
const response = await chrome.tabs.update(tabId, params);
sendResponse(response);
} catch (error) {
sendResponse({ error: error.message });
}
break;
}
}

View File

@@ -1,11 +1,17 @@
<html>
<body>
<input type="text" id="input" autofocus/>
<script type="text/javascript" charset="utf-8">
const { ipcRenderer } = require('electron')
document.onkeydown = function (e) {
require('electron').ipcRenderer.send('keydown', e.key, e.code, e.keyCode, e.shiftKey, e.ctrlKey, e.altKey)
ipcRenderer.send('keydown', e.key, e.code, e.keyCode, e.shiftKey, e.ctrlKey, e.altKey)
}
document.onkeypress = function (e) {
require('electron').ipcRenderer.send('keypress', e.key, e.code, e.keyCode, e.shiftKey, e.ctrlKey, e.altKey)
ipcRenderer.send('keypress', e.key, e.code, e.keyCode, e.shiftKey, e.ctrlKey, e.altKey)
}
document.onkeyup = function (e) {
ipcRenderer.send('keyup', e.key, e.code, e.keyCode, e.shiftKey, e.ctrlKey, e.altKey)
}
</script>
</body>

View File

@@ -377,6 +377,14 @@ if (process.platform === 'darwin') {
console.log(value);
const value2 = systemPreferences.getUserDefault('Foo', 'boolean');
console.log(value2);
// @ts-expect-error Removed API
console.log(systemPreferences.getAppLevelAppearance());
// @ts-expect-error Removed API
systemPreferences.setAppLevelAppearance('dark');
// @ts-expect-error Removed API
console.log(systemPreferences.appLevelAppearance);
// @ts-expect-error Removed API
console.log(systemPreferences.getColor('alternate-selected-control-text'));
}
// Create the window.

View File

@@ -62,9 +62,7 @@ declare namespace NodeJS {
type AsarFileStat = {
size: number;
offset: number;
isFile: boolean;
isDirectory: boolean;
isLink: boolean;
type: number;
}
interface AsarArchive {
@@ -244,6 +242,7 @@ declare namespace NodeJS {
// Additional properties
_firstFileName?: string;
_serviceStartupScript: string;
_getOrCreateArchive?: (path: string) => NodeJS.AsarArchive | null;
helperExecPath: string;
mainModule?: NodeJS.Module | undefined;

View File

@@ -220,9 +220,9 @@
vscode-uri "^3.0.7"
"@electron/typescript-definitions@^8.14.5":
version "8.14.5"
resolved "https://registry.yarnpkg.com/@electron/typescript-definitions/-/typescript-definitions-8.14.5.tgz#07ffc7dac6008e0f659215e3b88bc0d7c6bc6ece"
integrity sha512-68JfMTcj6X7B0dhjhj8lGGnnOlfuiR4f+2UBEtQDYRHfeSuFriKErno3Lh+jAolGSqhw39qr4lLO+FGToVdCew==
version "8.14.6"
resolved "https://registry.yarnpkg.com/@electron/typescript-definitions/-/typescript-definitions-8.14.6.tgz#78ba1fa8314f06255bb9309791b33c9695ac42ef"
integrity sha512-HK70Q3nrp6h4cCxb/P65vFixdJ99vABLIG8TpqU21/fmuHdYboL4zcleWaYhXhU2EwduuOPfORFMrUTdBRc+lw==
dependencies:
"@types/node" "^11.13.7"
chalk "^2.4.2"