mirror of
https://github.com/electron/electron.git
synced 2026-05-02 03:00:22 -04:00
Compare commits
1 Commits
fix/esm-ru
...
sam/place-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
01416243d2 |
2
.github/workflows/audit-branch-ci.yml
vendored
2
.github/workflows/audit-branch-ci.yml
vendored
@@ -157,7 +157,7 @@ jobs:
|
||||
await core.summary.write();
|
||||
- name: Send Slack message if errors
|
||||
if: ${{ always() && steps.audit-errors.outputs.errorsFound && github.ref == 'refs/heads/main' }}
|
||||
uses: slackapi/slack-github-action@03ea5433c137af7c0495bc0cad1af10403fc800c # v3.0.2
|
||||
uses: slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95 # v3.0.1
|
||||
with:
|
||||
payload: |
|
||||
link: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||
|
||||
2
.github/workflows/branch-created.yml
vendored
2
.github/workflows/branch-created.yml
vendored
@@ -98,7 +98,7 @@ jobs:
|
||||
done
|
||||
- name: Generate GitHub App token
|
||||
if: ${{ steps.check-major-version.outputs.MAJOR }}
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.RELEASE_BOARD_GH_APP_CREDS }}
|
||||
|
||||
4
.github/workflows/issue-commented.yml
vendored
4
.github/workflows/issue-commented.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
AUTHOR_ASSOCIATION=$(gh api /repos/electron/electron/issues/comments/${{ github.event.comment.id }} --jq '.author_association')
|
||||
echo "author_association=$AUTHOR_ASSOCIATION" >> "$GITHUB_OUTPUT"
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
if: ${{ !contains(fromJSON('["MEMBER", "OWNER", "COLLABORATOR"]'), steps.get-author-association.outputs.author_association) }}
|
||||
id: generate-token
|
||||
with:
|
||||
@@ -45,7 +45,7 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: *get-author-association
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
if: ${{ contains(fromJSON('["MEMBER", "OWNER"]'), steps.get-author-association.outputs.author_association) }}
|
||||
id: generate-token
|
||||
with:
|
||||
|
||||
6
.github/workflows/issue-labeled.yml
vendored
6
.github/workflows/issue-labeled.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
fi
|
||||
- name: Generate GitHub App token
|
||||
if: ${{ steps.check-for-comment.outputs.SHOULD_COMMENT }}
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
|
||||
|
||||
4
.github/workflows/issue-opened.yml
vendored
4
.github/workflows/issue-opened.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
permissions: {}
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
permissions: {}
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
|
||||
|
||||
2
.github/workflows/issue-transferred.yml
vendored
2
.github/workflows/issue-transferred.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
if: ${{ !github.event.changes.new_repository.private }}
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
|
||||
|
||||
2
.github/workflows/issue-unlabeled.yml
vendored
2
.github/workflows/issue-unlabeled.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
fi
|
||||
- name: Generate GitHub App token
|
||||
if: ${{ steps.check-for-blocked-labels.outputs.NOT_BLOCKED }}
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
|
||||
|
||||
2
.github/workflows/pr-triage-automation.yml
vendored
2
.github/workflows/pr-triage-automation.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
|
||||
|
||||
6
.github/workflows/pull-request-labeled.yml
vendored
6
.github/workflows/pull-request-labeled.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
permissions: {}
|
||||
steps:
|
||||
- name: Trigger Slack workflow
|
||||
uses: slackapi/slack-github-action@03ea5433c137af7c0495bc0cad1af10403fc800c # v3.0.2
|
||||
uses: slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95 # v3.0.1
|
||||
with:
|
||||
webhook: ${{ secrets.BACKPORT_REQUESTED_SLACK_WEBHOOK_URL }}
|
||||
webhook-type: webhook-trigger
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
permissions: {}
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.RELEASE_BOARD_GH_APP_CREDS }}
|
||||
@@ -55,7 +55,7 @@ jobs:
|
||||
permissions: {}
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
|
||||
|
||||
2
.github/workflows/stable-prep-items.yml
vendored
2
.github/workflows/stable-prep-items.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
permissions: {}
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.RELEASE_BOARD_GH_APP_CREDS }}
|
||||
|
||||
4
.github/workflows/stale.yml
vendored
4
.github/workflows/stale.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
permissions: {}
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
needs: stale
|
||||
steps:
|
||||
- name: Generate GitHub App token
|
||||
uses: electron/github-app-auth-action@5f70a3726af01b612f29aac96d05aa524389c9e9 # v2.1.0
|
||||
uses: electron/github-app-auth-action@e14e47722ed120360649d0789e25b9baece12725 # v2.0.0
|
||||
id: generate-token
|
||||
with:
|
||||
creds: ${{ secrets.ISSUE_TRIAGE_GH_APP_CREDS }}
|
||||
|
||||
26
.yarn/patches/dbus-native-npm-0.4.0-fd59c31eb6.patch
Normal file
26
.yarn/patches/dbus-native-npm-0.4.0-fd59c31eb6.patch
Normal file
@@ -0,0 +1,26 @@
|
||||
diff --git a/lib/marshall.js b/lib/marshall.js
|
||||
index 5a7434162d97208ec34fb87bfce3c953fd90345a..86f0efd9d0c99ecb3ae4d12c46130778f813ac5b 100644
|
||||
--- a/lib/marshall.js
|
||||
+++ b/lib/marshall.js
|
||||
@@ -1,7 +1,7 @@
|
||||
const assert = require('assert');
|
||||
|
||||
const parseSignature = require('./signature');
|
||||
-const put = require('put');
|
||||
+const put = require('@nornagon/put');
|
||||
const Marshallers = require('./marshallers');
|
||||
const align = require('./align').align;
|
||||
|
||||
diff --git a/package.json b/package.json
|
||||
index 2519ac38fad44569cb8a156a91af25a70c8166a5..f7d88ac6cdb00a0a7064b0e39986821816c75554 100644
|
||||
--- a/package.json
|
||||
+++ b/package.json
|
||||
@@ -42,7 +42,7 @@
|
||||
"hexy": "^0.2.10",
|
||||
"long": "^4.0.0",
|
||||
"optimist": "^0.6.1",
|
||||
- "put": "0.0.6",
|
||||
+ "@nornagon/put": "0.0.8",
|
||||
"safe-buffer": "^5.1.1",
|
||||
"xml2js": "^0.4.17"
|
||||
},
|
||||
1
BUILD.gn
1
BUILD.gn
@@ -528,7 +528,6 @@ source_set("electron_lib") {
|
||||
"//content/public/utility",
|
||||
"//device/bluetooth",
|
||||
"//device/bluetooth/public/cpp",
|
||||
"//device/fido",
|
||||
"//gin",
|
||||
"//gpu/ipc/client",
|
||||
"//media/capture/mojom:video_capture",
|
||||
|
||||
2
DEPS
2
DEPS
@@ -2,7 +2,7 @@ gclient_gn_args_from = 'src'
|
||||
|
||||
vars = {
|
||||
'chromium_version':
|
||||
'149.0.7813.0',
|
||||
'149.0.7811.0',
|
||||
'node_version':
|
||||
'v24.15.0',
|
||||
'nan_version':
|
||||
|
||||
@@ -65,7 +65,6 @@ template("electron_extra_paks") {
|
||||
"$root_gen_dir/net/net_resources.pak",
|
||||
"$root_gen_dir/third_party/blink/public/resources/blink_resources.pak",
|
||||
"$root_gen_dir/third_party/blink/public/resources/inspector_overlay_resources.pak",
|
||||
"$root_gen_dir/third_party/blink/public/strings/permission_element_generated_strings.pak",
|
||||
"$target_gen_dir/electron_resources.pak",
|
||||
]
|
||||
deps = [
|
||||
@@ -84,7 +83,6 @@ template("electron_extra_paks") {
|
||||
"//net:net_resources",
|
||||
"//third_party/blink/public:devtools_inspector_resources",
|
||||
"//third_party/blink/public:resources",
|
||||
"//third_party/blink/public/strings:permission_element_generated_strings",
|
||||
"//ui/webui/resources",
|
||||
]
|
||||
if (defined(invoker.deps)) {
|
||||
@@ -189,7 +187,6 @@ template("electron_paks") {
|
||||
"${root_gen_dir}/extensions/strings/extensions_strings_",
|
||||
"${root_gen_dir}/services/strings/services_strings_",
|
||||
"${root_gen_dir}/third_party/blink/public/strings/blink_strings_",
|
||||
"${root_gen_dir}/third_party/blink/public/strings/permission_element_strings_",
|
||||
"${root_gen_dir}/ui/strings/app_locale_settings_",
|
||||
"${root_gen_dir}/ui/strings/auto_image_annotation_strings_",
|
||||
"${root_gen_dir}/ui/strings/ax_strings_",
|
||||
@@ -207,7 +204,6 @@ template("electron_paks") {
|
||||
"//extensions/strings",
|
||||
"//services/strings",
|
||||
"//third_party/blink/public/strings",
|
||||
"//third_party/blink/public/strings:permission_element_strings",
|
||||
"//ui/strings:app_locale_settings",
|
||||
"//ui/strings:auto_image_annotation_strings",
|
||||
"//ui/strings:ax_strings",
|
||||
|
||||
@@ -1233,51 +1233,6 @@ This API must be called after the `ready` event is emitted.
|
||||
[doh-providers]: https://source.chromium.org/chromium/chromium/src/+/main:net/dns/public/doh_provider_entry.cc;l=31?q=%22DohProviderEntry::GetList()%22&ss=chromium%2Fchromium%2Fsrc
|
||||
[RFC8484 § 3]: https://datatracker.ietf.org/doc/html/rfc8484#section-3
|
||||
|
||||
### `app.configureWebAuthn(options)` _macOS_
|
||||
|
||||
* `options` Object
|
||||
* `touchID` Object (optional) - Enables the Touch ID / Secure Enclave platform
|
||||
authenticator for [Web Authentication](https://www.w3.org/TR/webauthn-2/)
|
||||
requests.
|
||||
* `keychainAccessGroup` string - The keychain access group that WebAuthn
|
||||
credentials will be stored under. This value **must** also be present in
|
||||
your app's `keychain-access-groups` code-signing entitlement, and is
|
||||
typically of the form `<TEAM_ID>.<BUNDLE_ID>.webauthn`.
|
||||
|
||||
Configures platform authenticators for the Web Authentication API
|
||||
(`navigator.credentials.create()` / `navigator.credentials.get()`). Until this
|
||||
is called, `PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()`
|
||||
resolves to `false` and platform-authenticator requests are not serviced.
|
||||
|
||||
When `touchID` is provided, WebAuthn credentials are stored in the macOS
|
||||
keychain and bound to this device's Secure Enclave. Electron automatically
|
||||
generates and persists a per-[`session`](session.md) metadata secret so that
|
||||
credentials created in one partition are not visible to another.
|
||||
|
||||
```js
|
||||
const { app } = require('electron')
|
||||
|
||||
app.configureWebAuthn({
|
||||
touchID: {
|
||||
keychainAccessGroup: 'A1B2C3D4E5.com.example.app.webauthn'
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
With the matching entitlement in your app's `entitlements.plist`:
|
||||
|
||||
```xml
|
||||
<key>keychain-access-groups</key>
|
||||
<array>
|
||||
<string>A1B2C3D4E5.com.example.app.webauthn</string>
|
||||
</array>
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Touch ID WebAuthn credentials are device-bound and are not synced via iCloud
|
||||
> Keychain. They are only available on Macs with a Secure Enclave (Apple
|
||||
> silicon, or Intel Macs with a T2 chip).
|
||||
|
||||
### `app.disableHardwareAcceleration()`
|
||||
|
||||
Disables hardware acceleration for current app.
|
||||
|
||||
@@ -319,17 +319,6 @@ By default inspector websocket url is available in stderr and under /json/list e
|
||||
|
||||
Enable support for DevTools network inspector events, for visibility into requests made by the nodejs `http` and `https` modules.
|
||||
|
||||
### `--experimental-inspector-network-resource`
|
||||
|
||||
Enable support for resolving source maps over the network when using the Node.js inspector.
|
||||
|
||||
When enabled, DevTools can retrieve remote source maps for main and utility
|
||||
process scripts via the Node.js inspector.
|
||||
|
||||
**Note:** When enabled, the Node.js inspector will make network requests to
|
||||
URLs specified in source maps. Be mindful of this in environments where the
|
||||
process has access to internal networks.
|
||||
|
||||
### `--no-deprecation`
|
||||
|
||||
Silence deprecation warnings.
|
||||
|
||||
@@ -31,7 +31,6 @@ See [`Menu`](menu.md) for examples.
|
||||
* `header` - Only available on macOS 14 and up.
|
||||
* `palette` - Only available on macOS 14 and up.
|
||||
* `label` string (optional)
|
||||
* `accessibilityLabel` string (optional) _macOS_
|
||||
* `sublabel` string (optional) _macOS_ - Available in macOS >= 14.4
|
||||
* `toolTip` string (optional) _macOS_ - Hover text for this menu item.
|
||||
* `accelerator` string (optional) - An [Accelerator](../tutorial/keyboard-shortcuts.md#accelerators) string.
|
||||
@@ -84,12 +83,6 @@ A `string` indicating the item's visible label.
|
||||
|
||||
This property can be dynamically changed.
|
||||
|
||||
#### `menuItem.accessibilityLabel` _macOS_
|
||||
|
||||
A `string` indicating the item's accessibility label (used by assistive technology), if set.
|
||||
|
||||
This property can be dynamically changed.
|
||||
|
||||
#### `menuItem.click`
|
||||
|
||||
A `Function` that is fired when the MenuItem receives a click event.
|
||||
|
||||
@@ -629,54 +629,6 @@ Emitted after `USBDevice.forget()` has been called. This event can be used
|
||||
to help maintain persistent storage of permissions when
|
||||
`setDevicePermissionHandler` is used.
|
||||
|
||||
#### Event: 'select-webauthn-account'
|
||||
|
||||
Returns:
|
||||
|
||||
* `event` Event
|
||||
* `details` Object
|
||||
* `relyingPartyId` string - The relying party identifier from the WebAuthn request.
|
||||
* `accounts` [WebAuthnAccount[]](structures/webauthn-account.md)
|
||||
* `frame` [WebFrameMain](web-frame-main.md) | null - The frame initiating this event.
|
||||
May be `null` if accessed after the frame has either navigated or been destroyed.
|
||||
* `callback` Function
|
||||
* `credentialId` string | null (optional)
|
||||
|
||||
Emitted when a call to `navigator.credentials.get()` resolves multiple
|
||||
discoverable WebAuthn credentials and the user must choose one. `callback`
|
||||
should be called with the `credentialId` of the selected account; passing no
|
||||
arguments — or a `credentialId` that does not match one of the provided
|
||||
accounts — will cancel the request and the page will receive a
|
||||
`NotAllowedError`. If no listener is registered for this event, the request is
|
||||
cancelled with the same error. The credential request remains pending until
|
||||
the listener invokes the callback, so always invoke it exactly once — typically
|
||||
from a `try { … } finally { callback(…) }` block.
|
||||
|
||||
On macOS, the Touch ID platform authenticator surfaces accounts via this event
|
||||
once it has been configured with
|
||||
[`app.configureWebAuthn`](app.md#appconfigurewebauthnoptions-macos). The event
|
||||
may also fire on other platforms when a roaming FIDO2 authenticator returns
|
||||
multiple discoverable credentials.
|
||||
|
||||
```js
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
|
||||
let win = null
|
||||
|
||||
app.whenReady().then(() => {
|
||||
app.configureWebAuthn({
|
||||
touchID: { keychainAccessGroup: 'A1B2C3D4E5.com.example.app.webauthn' }
|
||||
})
|
||||
|
||||
win = new BrowserWindow()
|
||||
|
||||
win.webContents.session.on('select-webauthn-account', (event, details, callback) => {
|
||||
const selected = details.accounts.find((a) => a.name === 'alice@example.com')
|
||||
callback(selected?.credentialId)
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
### Instance Methods
|
||||
|
||||
The following methods are available on instances of `Session`:
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# WebAuthnAccount Object
|
||||
|
||||
* `credentialId` string - URL-safe base64-encoded (no padding) credential ID of
|
||||
the discoverable credential. Matches `PublicKeyCredential.id` returned by
|
||||
`navigator.credentials.get()` in the renderer.
|
||||
* `userHandle` string (optional) - URL-safe base64-encoded (no padding) user
|
||||
handle (`user.id`) that was provided when the credential was created.
|
||||
* `name` string (optional) - Human-palatable identifier for the account (for example, an email address or username).
|
||||
* `displayName` string (optional) - Human-palatable name for the account, intended for display.
|
||||
@@ -17,16 +17,6 @@ Process: [Main](../glossary.md#main-process)<br />
|
||||
* `env` Object (optional) - Environment key-value pairs. Default is `process.env`.
|
||||
* `execArgv` string[] (optional) - List of string arguments passed to the executable.
|
||||
* `cwd` string (optional) - Current working directory of the child process.
|
||||
* `session` [Session](session.md) (optional) - Sets the session used by the process for network
|
||||
requests. By default, network requests from the utility process will use the system network
|
||||
context which does not have HTTP cache support. Setting a session enables HTTP caching and
|
||||
other session-specific network features. See [session](session.md) for more information.
|
||||
* `partition` string (optional) - Sets the session used by the process according to the
|
||||
session's partition string. If `partition` starts with `persist:`, the process will use a
|
||||
persistent session available to all pages in the app with the same `partition`. If there is
|
||||
no `persist:` prefix, the process will use an in-memory session. By assigning the same
|
||||
`partition`, multiple processes can share the same session. If the `session` option is set,
|
||||
this option is ignored.
|
||||
* `stdio` (string[] | string) (optional) - Allows configuring the mode for `stdout` and `stderr`
|
||||
of the child process. Default is `inherit`.
|
||||
String value can be one of `pipe`, `ignore`, `inherit`, for more details on these values you can refer to
|
||||
@@ -54,9 +44,7 @@ Process: [Main](../glossary.md#main-process)<br />
|
||||
that run third-party or otherwise untrusted code. Default is `false`.
|
||||
* `respondToAuthRequestsFromMainProcess` boolean (optional) - With this flag, all HTTP 401 and 407 network
|
||||
requests created via the [net module](net.md) will allow responding to them via the
|
||||
[`login`](#event-login) event on the `UtilityProcess` instance when a `session` is provided, or via
|
||||
the [`app#login`](app.md#event-login) event in the main process when using the default system network
|
||||
context. Without this flag, auth challenges are handled by the default
|
||||
[`app#login`](app.md#event-login) event in the main process instead of the default
|
||||
[`login`](client-request.md#event-login) event on the [`ClientRequest`](client-request.md) object. Default is
|
||||
`false`.
|
||||
|
||||
@@ -188,45 +176,6 @@ Returns:
|
||||
|
||||
Emitted when the child process sends a message using [`process.parentPort.postMessage()`](process.md#processparentport).
|
||||
|
||||
#### Event: 'login'
|
||||
|
||||
Returns:
|
||||
|
||||
* `authenticationResponseDetails` Object
|
||||
* `url` URL
|
||||
* `pid` number
|
||||
* `authInfo` Object
|
||||
* `isProxy` boolean
|
||||
* `scheme` string
|
||||
* `host` string
|
||||
* `port` Integer
|
||||
* `realm` string
|
||||
* `callback` Function
|
||||
* `username` string (optional)
|
||||
* `password` string (optional)
|
||||
|
||||
Emitted when the utility process encounters an HTTP 401 or 407 authentication challenge, if the
|
||||
process was created with both `respondToAuthRequestsFromMainProcess: true` and a `session` option.
|
||||
The `callback` should be called with credentials to respond to the challenge. Calling `callback`
|
||||
without arguments will cancel the request.
|
||||
|
||||
This behaves the same as the [`login` event on `app`](app.md#event-login) but is scoped to the
|
||||
individual utility process instance.
|
||||
|
||||
```js
|
||||
const { session, utilityProcess } = require('electron')
|
||||
|
||||
const ses = session.defaultSession
|
||||
const child = utilityProcess.fork('./worker.js', [], {
|
||||
session: ses,
|
||||
respondToAuthRequestsFromMainProcess: true
|
||||
})
|
||||
|
||||
child.on('login', (authenticationResponseDetails, authInfo, callback) => {
|
||||
callback('username', 'password')
|
||||
})
|
||||
```
|
||||
|
||||
[`child_process.fork`]: https://nodejs.org/dist/latest-v16.x/docs/api/child_process.html#child_processforkmodulepath-args-options
|
||||
[Services API]: https://chromium.googlesource.com/chromium/src/+/main/docs/mojo_and_services.md
|
||||
[stdio]: https://nodejs.org/dist/latest/docs/api/child_process.html#optionsstdio
|
||||
|
||||
@@ -117,13 +117,6 @@ Examples of valid `color` values:
|
||||
> [!NOTE]
|
||||
> The area cutout of the view's border still captures clicks.
|
||||
|
||||
#### `view.setBackgroundBlur(blurRadius)`
|
||||
|
||||
* `blurRadius` Integer - The radius of the background blur effect (in pixels).
|
||||
|
||||
> [!NOTE]
|
||||
> You must set a background color with an alpha channel (e.g. `#80ffffff`) in order for the blur effect to be visible.
|
||||
|
||||
#### `view.setVisible(visible)`
|
||||
|
||||
* `visible` boolean - If false, the view will be hidden from display.
|
||||
|
||||
@@ -226,16 +226,7 @@ Returns:
|
||||
Only defined when the window is being created by a form that set
|
||||
`target=_blank`.
|
||||
* `disposition` string - Can be `default`, `foreground-tab`,
|
||||
`background-tab`, `new-window` or `other`. Corresponds to the manner
|
||||
an associated link was clicked. See Chromium's
|
||||
[WindowOpenDisposition](https://source.chromium.org/chromium/chromium/src/+/main:ui/base/window_open_disposition.h).
|
||||
* `default` - Indicates Chromium deems in-window navigation valid
|
||||
for a window open call.
|
||||
* `foreground-tab` - Corresponds to a left click or shift + middle click.
|
||||
* `background-tab` - Corresponds to a middle click or ctrl/cmd + click.
|
||||
* `new-window` - Corresponds to a shift + left click.
|
||||
* `other` - A catch-all for the remaining Chromium dispositions not
|
||||
handled by Electron.
|
||||
`background-tab`, `new-window` or `other`.
|
||||
|
||||
Emitted _after_ successful creation of a window via `window.open` in the renderer.
|
||||
Not emitted if the creation of the window is canceled from
|
||||
@@ -1458,17 +1449,8 @@ Ignore application menu shortcuts while this web contents is focused.
|
||||
* `url` string - The _resolved_ version of the URL passed to `window.open()`. e.g. opening a window with `window.open('foo')` will yield something like `https://the-origin/the/current/path/foo`.
|
||||
* `frameName` string - Name of the window provided in `window.open()`
|
||||
* `features` string - Comma separated list of window features provided to `window.open()`.
|
||||
* `disposition` string - Can be `default`, `foreground-tab`,
|
||||
`background-tab`, `new-window` or `other`. Corresponds to the manner
|
||||
an associated link was clicked. See Chromium's
|
||||
[WindowOpenDisposition](https://source.chromium.org/chromium/chromium/src/+/main:ui/base/window_open_disposition.h).
|
||||
* `default` - Indicates Chromium deems in-window navigation valid
|
||||
for a window open call.
|
||||
* `foreground-tab` - Corresponds to a left click or shift + middle click.
|
||||
* `background-tab` - Corresponds to a middle click or ctrl/cmd + click.
|
||||
* `new-window` - Corresponds to a shift + left click.
|
||||
* `other` - A catch-all for the remaining Chromium dispositions not
|
||||
handled by Electron.
|
||||
* `disposition` string - Can be `default`, `foreground-tab`, `background-tab`,
|
||||
`new-window` or `other`.
|
||||
* `referrer` [Referrer](structures/referrer.md) - The referrer that will be
|
||||
passed to the new window. May or may not result in the `Referer` header being
|
||||
sent, depending on the referrer policy.
|
||||
|
||||
@@ -14,17 +14,6 @@ This document uses the following convention to categorize breaking changes:
|
||||
|
||||
## Planned Breaking API Changes (43.0)
|
||||
|
||||
### Behavior Changed: `chrome.scripting` CSS injection matches more fallback frames
|
||||
|
||||
Extensions using `chrome.scripting.insertCSS()` or `chrome.scripting.removeCSS()`
|
||||
now follow Chrome's behavior when Electron cannot match a frame's URL directly,
|
||||
such as with `about:blank` or `data:` frames. If the extension has access to the
|
||||
page that created the frame, CSS may now be inserted into or removed from those
|
||||
fallback frames as well.
|
||||
|
||||
Apps or extensions that relied on Electron skipping those frames should narrow their
|
||||
injection target, frame IDs, or match patterns.
|
||||
|
||||
### Behavior Changed: Dialog methods default to Downloads directory
|
||||
|
||||
The `defaultPath` option for the following methods now defaults to the user's Downloads folder (or their home directory if Downloads doesn't exist) when not explicitly provided:
|
||||
@@ -134,12 +123,6 @@ When a cookie is deleted, the change cause remains `explicit`.
|
||||
When the cookie being set is identical to an existing one (same name, domain, path, and value, with no actual changes), the change cause is `inserted-no-change-overwrite`.
|
||||
When the value of the cookie being set remains unchanged but some of its attributes are updated, such as the expiration attribute, the change cause will be `inserted-no-value-change-overwrite`.
|
||||
|
||||
### Deprecated: `showHiddenFiles` in Dialogs on Linux
|
||||
|
||||
This property will still be honored on macOS and Windows, but support on Linux
|
||||
will be removed in Electron 42. GTK intends for this to be a user choice rather
|
||||
than an app choice and has removed the API to do this programmatically.
|
||||
|
||||
## Planned Breaking API Changes (40.0)
|
||||
|
||||
### Deprecated: `clipboard` API access from renderer processes
|
||||
@@ -153,6 +136,12 @@ your preload script and expose it using the [contextBridge](https://www.electron
|
||||
Debug symbols for MacOS (dSYM) now use xz compression in order to handle larger file sizes. `dsym.zip` files are now
|
||||
`dsym.tar.xz` files. End users using debug symbols may need to update their zip utilities.
|
||||
|
||||
### Deprecated: `showHiddenFiles` in Dialogs on Linux
|
||||
|
||||
This property will still be honored on macOS and Windows, but support on Linux
|
||||
will be removed in Electron 42. GTK intends for this to be a user choice rather
|
||||
than an app choice and has removed the API to do this programmatically.
|
||||
|
||||
## Planned Breaking API Changes (39.0)
|
||||
|
||||
### Deprecated: `--host-rules` command line switch
|
||||
|
||||
@@ -171,7 +171,6 @@ auto_filenames = {
|
||||
"docs/api/structures/web-preferences.md",
|
||||
"docs/api/structures/web-request-filter.md",
|
||||
"docs/api/structures/web-source.md",
|
||||
"docs/api/structures/webauthn-account.md",
|
||||
"docs/api/structures/window-open-handler-response.md",
|
||||
"docs/api/structures/window-session-end-event.md",
|
||||
]
|
||||
@@ -191,6 +190,7 @@ auto_filenames = {
|
||||
"../third_party/electron_node/src/base_object_types.h",
|
||||
"../third_party/electron_node/src/blob_serializer_deserializer-inl.h",
|
||||
"../third_party/electron_node/src/blob_serializer_deserializer.h",
|
||||
"../third_party/electron_node/src/builtin_info.h",
|
||||
"../third_party/electron_node/src/callback_queue-inl.h",
|
||||
"../third_party/electron_node/src/callback_queue.h",
|
||||
"../third_party/electron_node/src/cares_wrap.h",
|
||||
@@ -254,6 +254,7 @@ auto_filenames = {
|
||||
"../third_party/electron_node/src/inspector/protocol_helper.h",
|
||||
"../third_party/electron_node/src/inspector/runtime_agent.h",
|
||||
"../third_party/electron_node/src/inspector/target_agent.h",
|
||||
"../third_party/electron_node/src/inspector/target_manager.h",
|
||||
"../third_party/electron_node/src/inspector/tracing_agent.h",
|
||||
"../third_party/electron_node/src/inspector/worker_agent.h",
|
||||
"../third_party/electron_node/src/inspector/worker_inspector.h",
|
||||
@@ -289,6 +290,7 @@ auto_filenames = {
|
||||
"../third_party/electron_node/src/node_contextify.h",
|
||||
"../third_party/electron_node/src/node_crypto.h",
|
||||
"../third_party/electron_node/src/node_debug.h",
|
||||
"../third_party/electron_node/src/node_diagnostics_channel.h",
|
||||
"../third_party/electron_node/src/node_dir.h",
|
||||
"../third_party/electron_node/src/node_dotenv.h",
|
||||
"../third_party/electron_node/src/node_errors.h",
|
||||
|
||||
@@ -48,8 +48,8 @@ filenames = {
|
||||
"shell/browser/ui/views/opaque_frame_view.h",
|
||||
"shell/browser/ui/views/caption_button_placeholder_container.cc",
|
||||
"shell/browser/ui/views/caption_button_placeholder_container.h",
|
||||
"shell/browser/ui/views/native_frame_view_linux.cc",
|
||||
"shell/browser/ui/views/native_frame_view_linux.h",
|
||||
"shell/browser/ui/views/client_frame_view_linux.cc",
|
||||
"shell/browser/ui/views/client_frame_view_linux.h",
|
||||
"shell/browser/ui/views/linux_frame_layout.cc",
|
||||
"shell/browser/ui/views/linux_frame_layout.h",
|
||||
"shell/common/application_info_linux.cc",
|
||||
@@ -440,6 +440,8 @@ filenames = {
|
||||
"shell/browser/microtasks_runner.h",
|
||||
"shell/browser/native_window.cc",
|
||||
"shell/browser/native_window.h",
|
||||
"shell/browser/native_window_features.cc",
|
||||
"shell/browser/native_window_features.h",
|
||||
"shell/browser/native_window_observer.h",
|
||||
"shell/browser/net/asar/asar_file_validator.cc",
|
||||
"shell/browser/net/asar/asar_file_validator.h",
|
||||
@@ -564,8 +566,6 @@ filenames = {
|
||||
"shell/browser/web_view_guest_delegate.h",
|
||||
"shell/browser/web_view_manager.cc",
|
||||
"shell/browser/web_view_manager.h",
|
||||
"shell/browser/webauthn/electron_authenticator_request_client_delegate.cc",
|
||||
"shell/browser/webauthn/electron_authenticator_request_client_delegate.h",
|
||||
"shell/browser/webauthn/electron_authenticator_request_delegate.cc",
|
||||
"shell/browser/webauthn/electron_authenticator_request_delegate.h",
|
||||
"shell/browser/window_list.cc",
|
||||
@@ -774,6 +774,8 @@ filenames = {
|
||||
"shell/browser/extensions/api/resources_private/resources_private_api.h",
|
||||
"shell/browser/extensions/api/runtime/electron_runtime_api_delegate.cc",
|
||||
"shell/browser/extensions/api/runtime/electron_runtime_api_delegate.h",
|
||||
"shell/browser/extensions/api/scripting/scripting_api.cc",
|
||||
"shell/browser/extensions/api/scripting/scripting_api.h",
|
||||
"shell/browser/extensions/api/streams_private/streams_private_api.cc",
|
||||
"shell/browser/extensions/api/streams_private/streams_private_api.h",
|
||||
"shell/browser/extensions/api/tabs/tabs_api.cc",
|
||||
|
||||
@@ -158,8 +158,6 @@ libcxx_headers = [
|
||||
"//third_party/libc++/src/include/__algorithm/ranges_set_intersection.h",
|
||||
"//third_party/libc++/src/include/__algorithm/ranges_set_symmetric_difference.h",
|
||||
"//third_party/libc++/src/include/__algorithm/ranges_set_union.h",
|
||||
"//third_party/libc++/src/include/__algorithm/ranges_shift_left.h",
|
||||
"//third_party/libc++/src/include/__algorithm/ranges_shift_right.h",
|
||||
"//third_party/libc++/src/include/__algorithm/ranges_shuffle.h",
|
||||
"//third_party/libc++/src/include/__algorithm/ranges_sort.h",
|
||||
"//third_party/libc++/src/include/__algorithm/ranges_sort_heap.h",
|
||||
@@ -217,7 +215,6 @@ libcxx_headers = [
|
||||
"//third_party/libc++/src/include/__atomic/atomic_lock_free.h",
|
||||
"//third_party/libc++/src/include/__atomic/atomic_ref.h",
|
||||
"//third_party/libc++/src/include/__atomic/atomic_sync.h",
|
||||
"//third_party/libc++/src/include/__atomic/atomic_sync_timed.h",
|
||||
"//third_party/libc++/src/include/__atomic/atomic_waitable_traits.h",
|
||||
"//third_party/libc++/src/include/__atomic/check_memory_order.h",
|
||||
"//third_party/libc++/src/include/__atomic/contention_t.h",
|
||||
@@ -334,14 +331,11 @@ libcxx_headers = [
|
||||
"//third_party/libc++/src/include/__config",
|
||||
"//third_party/libc++/src/include/__config_site.in",
|
||||
"//third_party/libc++/src/include/__configuration/abi.h",
|
||||
"//third_party/libc++/src/include/__configuration/attributes.h",
|
||||
"//third_party/libc++/src/include/__configuration/availability.h",
|
||||
"//third_party/libc++/src/include/__configuration/compiler.h",
|
||||
"//third_party/libc++/src/include/__configuration/diagnostic_suppression.h",
|
||||
"//third_party/libc++/src/include/__configuration/experimental.h",
|
||||
"//third_party/libc++/src/include/__configuration/hardening.h",
|
||||
"//third_party/libc++/src/include/__configuration/language.h",
|
||||
"//third_party/libc++/src/include/__configuration/namespace.h",
|
||||
"//third_party/libc++/src/include/__configuration/platform.h",
|
||||
"//third_party/libc++/src/include/__coroutine/coroutine_handle.h",
|
||||
"//third_party/libc++/src/include/__coroutine/coroutine_traits.h",
|
||||
@@ -982,7 +976,6 @@ libcxx_headers = [
|
||||
"//third_party/libc++/src/include/__format/format_to_n_result.h",
|
||||
"//third_party/libc++/src/include/__format/formatter.h",
|
||||
"//third_party/libc++/src/include/__format/formatter_bool.h",
|
||||
"//third_party/libc++/src/include/__format/formatter_bool_impl.h",
|
||||
"//third_party/libc++/src/include/__format/formatter_char.h",
|
||||
"//third_party/libc++/src/include/__format/formatter_floating_point.h",
|
||||
"//third_party/libc++/src/include/__format/formatter_integer.h",
|
||||
@@ -1060,7 +1053,6 @@ libcxx_headers = [
|
||||
"//third_party/libc++/src/include/__iterator/aliasing_iterator.h",
|
||||
"//third_party/libc++/src/include/__iterator/back_insert_iterator.h",
|
||||
"//third_party/libc++/src/include/__iterator/bounded_iter.h",
|
||||
"//third_party/libc++/src/include/__iterator/capacity_aware_iterator.h",
|
||||
"//third_party/libc++/src/include/__iterator/common_iterator.h",
|
||||
"//third_party/libc++/src/include/__iterator/concepts.h",
|
||||
"//third_party/libc++/src/include/__iterator/counted_iterator.h",
|
||||
@@ -1307,7 +1299,6 @@ libcxx_headers = [
|
||||
"//third_party/libc++/src/include/__ranges/empty_view.h",
|
||||
"//third_party/libc++/src/include/__ranges/enable_borrowed_range.h",
|
||||
"//third_party/libc++/src/include/__ranges/enable_view.h",
|
||||
"//third_party/libc++/src/include/__ranges/enumerate_view.h",
|
||||
"//third_party/libc++/src/include/__ranges/filter_view.h",
|
||||
"//third_party/libc++/src/include/__ranges/from_range.h",
|
||||
"//third_party/libc++/src/include/__ranges/iota_view.h",
|
||||
@@ -1505,7 +1496,6 @@ libcxx_headers = [
|
||||
"//third_party/libc++/src/include/__utility/as_lvalue.h",
|
||||
"//third_party/libc++/src/include/__utility/auto_cast.h",
|
||||
"//third_party/libc++/src/include/__utility/cmp.h",
|
||||
"//third_party/libc++/src/include/__utility/constant_wrapper.h",
|
||||
"//third_party/libc++/src/include/__utility/convert_to_integral.h",
|
||||
"//third_party/libc++/src/include/__utility/declval.h",
|
||||
"//third_party/libc++/src/include/__utility/default_three_way_comparator.h",
|
||||
|
||||
@@ -30,7 +30,6 @@ const MenuItem = function (this: any, options: any) {
|
||||
|
||||
this.overrideProperty('icon');
|
||||
this.overrideProperty('label', roles.getDefaultLabel(this.role));
|
||||
this.overrideProperty('accessibilityLabel', '');
|
||||
this.overrideProperty('sublabel', '');
|
||||
this.overrideProperty('toolTip', '');
|
||||
this.overrideProperty('enabled', true);
|
||||
|
||||
@@ -57,10 +57,6 @@ Menu.prototype._getLabelForCommandId = function (id) {
|
||||
return this.commandsMap[id]?.label ?? '';
|
||||
};
|
||||
|
||||
Menu.prototype._getAccessibilityLabelForCommandId = function (id) {
|
||||
return this.commandsMap[id]?.accessibilityLabel ?? '';
|
||||
};
|
||||
|
||||
Menu.prototype._getSecondaryLabelForCommandId = function (id) {
|
||||
return this.commandsMap[id]?.sublabel ?? '';
|
||||
};
|
||||
|
||||
@@ -96,7 +96,7 @@ function extractFile(zipPath) {
|
||||
}
|
||||
|
||||
function getPlatformPath() {
|
||||
const platform = process.env.ELECTRON_INSTALL_PLATFORM || process.env.npm_config_platform || os.platform();
|
||||
const platform = process.env.npm_config_platform || os.platform();
|
||||
|
||||
switch (platform) {
|
||||
case 'mas':
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"@types/semver": "^7.5.8",
|
||||
"@types/stream-json": "^1.7.8",
|
||||
"@types/temp": "^0.9.4",
|
||||
"@xmldom/xmldom": "^0.8.13",
|
||||
"@xmldom/xmldom": "^0.8.12",
|
||||
"buffer": "^6.0.3",
|
||||
"chalk": "^4.1.0",
|
||||
"check-for-leaks": "^1.2.1",
|
||||
@@ -143,7 +143,8 @@
|
||||
"resolutions": {
|
||||
"dbus-native/xml2js": "0.5.0",
|
||||
"abstract-socket": "github:deepak1556/node-abstractsocket#928cc591decd12aff7dad96449da8afc29832c19",
|
||||
"minimist@npm:~0.0.1": "0.2.4"
|
||||
"minimist@npm:~0.0.1": "0.2.4",
|
||||
"put": "npm:@nornagon/put@0.0.8"
|
||||
},
|
||||
"packageManager": "yarn@4.12.0",
|
||||
"workspaces": [
|
||||
|
||||
@@ -152,5 +152,4 @@ chore_register_node_as_a_dynamic_trace_category_prefix.patch
|
||||
fix_make_macos_text_replacement_work_on_contenteditable.patch
|
||||
fix_allow_reentrancy_on_downloadmanagerimpl_observer_list.patch
|
||||
build_gn_arg_to_support_linker_wrapper_script_on_windows.patch
|
||||
fix_use_bundled_devtools_frontend_url_for_remote_debugging.patch
|
||||
fix_constrain_allowuniversalaccessfromfileurls_to_file_origins_in.patch
|
||||
chore_exclude_upstream_scripting_api_when_building_electron.patch
|
||||
|
||||
@@ -6,12 +6,12 @@ Subject: allow disabling blink scheduler throttling per RenderView
|
||||
This allows us to disable throttling for hidden windows.
|
||||
|
||||
diff --git a/content/browser/renderer_host/navigation_controller_impl_unittest.cc b/content/browser/renderer_host/navigation_controller_impl_unittest.cc
|
||||
index bdbcb809c4d0081aca93c4ed92912604abbf62bc..8c70713583e8a37201b6e037dae2e89838d382a6 100644
|
||||
index 913c92c8b224dc749c25864311d401b51b41d9b9..5c9772ede144b35792c59c4173935813cad7d0dd 100644
|
||||
--- a/content/browser/renderer_host/navigation_controller_impl_unittest.cc
|
||||
+++ b/content/browser/renderer_host/navigation_controller_impl_unittest.cc
|
||||
@@ -170,6 +170,12 @@ class MockPageBroadcast : public blink::mojom::PageBroadcast {
|
||||
|
||||
MOCK_METHOD(void, UpgradePrerenderUntilScriptToFullPrerender, (), (override));
|
||||
@@ -168,6 +168,12 @@ class MockPageBroadcast : public blink::mojom::PageBroadcast {
|
||||
(bool supports_draggable_regions),
|
||||
(override));
|
||||
|
||||
+ MOCK_METHOD(
|
||||
+ void,
|
||||
@@ -80,10 +80,10 @@ index 782bed0fdc08d57eceb059f398f253fab9233b1b..f1ab5b981ea68af1b11313e67f2c5060
|
||||
// This interface should only be implemented inside content.
|
||||
friend class RenderViewHostImpl;
|
||||
diff --git a/content/test/test_page_broadcast.h b/content/test/test_page_broadcast.h
|
||||
index 7f6223791c492d56412df57639ef988001b313fe..c6abcd08228a4fb0d9bc1bd4e7738864a281dd2c 100644
|
||||
index 4c8d44cdb2fde8e174b78aee7defb980651da18e..f8bf421b5b32af4cd197cbf23f4bd281c3a12514 100644
|
||||
--- a/content/test/test_page_broadcast.h
|
||||
+++ b/content/test/test_page_broadcast.h
|
||||
@@ -53,6 +53,7 @@ class TestPageBroadcast : public blink::mojom::PageBroadcast {
|
||||
@@ -52,6 +52,7 @@ class TestPageBroadcast : public blink::mojom::PageBroadcast {
|
||||
void UpdateColorProviders(
|
||||
const blink::ColorProviderColorMaps& color_provider_colors) override;
|
||||
void SetSupportsDraggableRegions(bool supports_draggable_regions) override;
|
||||
@@ -92,10 +92,10 @@ index 7f6223791c492d56412df57639ef988001b313fe..c6abcd08228a4fb0d9bc1bd4e7738864
|
||||
mojo::AssociatedReceiver<blink::mojom::PageBroadcast> receiver_;
|
||||
};
|
||||
diff --git a/third_party/blink/public/mojom/page/page.mojom b/third_party/blink/public/mojom/page/page.mojom
|
||||
index de0291118714296eb3a3114478fa4dbef15be06c..6c7012c00df45fb057113501b756ef3a57ee0c38 100644
|
||||
index b00bc8a8a5044fbf46f627f9db56cea7f09d7ef6..114c3a4522d11c1348f681af500c487ccd97eea9 100644
|
||||
--- a/third_party/blink/public/mojom/page/page.mojom
|
||||
+++ b/third_party/blink/public/mojom/page/page.mojom
|
||||
@@ -186,4 +186,7 @@ interface PageBroadcast {
|
||||
@@ -180,4 +180,7 @@ interface PageBroadcast {
|
||||
// Indicates that the page's main frame should collect draggable regions set
|
||||
// using the app-region CSS property.
|
||||
SetSupportsDraggableRegions(bool supports_draggable_regions);
|
||||
@@ -116,7 +116,7 @@ index 932658273154ef2e022358e493a8e7c00c86e732..57bbfb5cde62c9496c351c861880a189
|
||||
// Visibility -----------------------------------------------------------
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
|
||||
index 9b650e7079869dd074d24fd2e0f0d807af114c1f..756a6531f5db61adb5b17ce261719f29a9b6183a 100644
|
||||
index 135110e1ea397d52623bd1cd71759a2a014b454a..42b9ec3ca008be91318c843aba66a7a2e1c75ea5 100644
|
||||
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
|
||||
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
|
||||
@@ -2468,6 +2468,10 @@ void WebViewImpl::SetPageLifecycleStateInternal(
|
||||
@@ -130,7 +130,7 @@ index 9b650e7079869dd074d24fd2e0f0d807af114c1f..756a6531f5db61adb5b17ce261719f29
|
||||
bool storing_in_bfcache = new_state->is_in_back_forward_cache &&
|
||||
!old_state->is_in_back_forward_cache;
|
||||
bool restoring_from_bfcache = !new_state->is_in_back_forward_cache &&
|
||||
@@ -4022,10 +4026,23 @@ PageScheduler* WebViewImpl::Scheduler() const {
|
||||
@@ -4016,10 +4020,23 @@ PageScheduler* WebViewImpl::Scheduler() const {
|
||||
return GetPage()->GetPageScheduler();
|
||||
}
|
||||
|
||||
@@ -155,10 +155,10 @@ index 9b650e7079869dd074d24fd2e0f0d807af114c1f..756a6531f5db61adb5b17ce261719f29
|
||||
// Do not throttle if the page should be painting.
|
||||
bool is_visible =
|
||||
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h
|
||||
index 20212a57bb4dc13d9e384dffa5c564ed64655574..dd9e21d3e73f6ff14659b1e1fe7d837c5410695d 100644
|
||||
index f638ff2647fdeee4e1e180e1394b49a91227022b..698d1f78a0b2cabee59e3a7f0619935bea010b36 100644
|
||||
--- a/third_party/blink/renderer/core/exported/web_view_impl.h
|
||||
+++ b/third_party/blink/renderer/core/exported/web_view_impl.h
|
||||
@@ -438,6 +438,7 @@ class CORE_EXPORT WebViewImpl final : public WebView,
|
||||
@@ -437,6 +437,7 @@ class CORE_EXPORT WebViewImpl final : public WebView,
|
||||
LocalDOMWindow* PagePopupWindow() const;
|
||||
|
||||
PageScheduler* Scheduler() const override;
|
||||
@@ -166,7 +166,7 @@ index 20212a57bb4dc13d9e384dffa5c564ed64655574..dd9e21d3e73f6ff14659b1e1fe7d837c
|
||||
void SetVisibilityState(mojom::blink::PageVisibilityState visibility_state,
|
||||
bool is_initial_state) override;
|
||||
mojom::blink::PageVisibilityState GetVisibilityState() override;
|
||||
@@ -928,6 +929,8 @@ class CORE_EXPORT WebViewImpl final : public WebView,
|
||||
@@ -927,6 +928,8 @@ class CORE_EXPORT WebViewImpl final : public WebView,
|
||||
// If true, we send IPC messages when |preferred_size_| changes.
|
||||
bool send_preferred_size_changes_ = false;
|
||||
|
||||
|
||||
@@ -11,10 +11,10 @@ This patch can (and should) be removed when we can prevent those symbols
|
||||
from being stripped in the release build.
|
||||
|
||||
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni
|
||||
index 36fe79942794239edd00e7be0d94c33892acc5cc..68e4d13e785333b3bbd906f18b164686b67d223e 100644
|
||||
index d9cbf64ce68e21ea06a6bf2c213daa7d67b931f5..150736bcabec57bd262e0ebe1649096ba656b386 100644
|
||||
--- a/build/config/compiler/compiler.gni
|
||||
+++ b/build/config/compiler/compiler.gni
|
||||
@@ -154,7 +154,7 @@ declare_args() {
|
||||
@@ -151,7 +151,7 @@ declare_args() {
|
||||
# Chrome's clang. crbug.com/1033839
|
||||
use_thin_lto =
|
||||
is_cfi || (is_clang && is_official_build && chrome_pgo_phase != 1 &&
|
||||
|
||||
@@ -11,7 +11,7 @@ if we ever align our .pak file generation with Chrome we can remove this
|
||||
patch.
|
||||
|
||||
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
|
||||
index 171faeaa1c3ba08cc0cd166b492765c8204bb674..a4c8d2d33823e4825b80854db199d2f6542c3e2d 100644
|
||||
index 48f28a61eac4b31c3d9be62100c00cadff84174c..6c2632d85db3d2115bc0c0fc3dc6970e680877c2 100644
|
||||
--- a/chrome/BUILD.gn
|
||||
+++ b/chrome/BUILD.gn
|
||||
@@ -201,6 +201,12 @@ if (!is_android && !is_mac) {
|
||||
@@ -28,10 +28,10 @@ index 171faeaa1c3ba08cc0cd166b492765c8204bb674..a4c8d2d33823e4825b80854db199d2f6
|
||||
":chrome_dll",
|
||||
":chrome_exe_version",
|
||||
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
|
||||
index a824761a0bf0a3d827cc78bc644e8da877d603d3..dbf5e98c588a32265f65fa569f261129800c3375 100644
|
||||
index 684cc6c47f61e02831cfdb977b1719a0b0f899a5..ddbb1f4b58d8bee0b80410294c5a54d432d65a4f 100644
|
||||
--- a/chrome/test/BUILD.gn
|
||||
+++ b/chrome/test/BUILD.gn
|
||||
@@ -7761,6 +7761,10 @@ test("unit_tests") {
|
||||
@@ -7745,6 +7745,10 @@ test("unit_tests") {
|
||||
"//chrome/notification_helper",
|
||||
]
|
||||
|
||||
@@ -42,7 +42,7 @@ index a824761a0bf0a3d827cc78bc644e8da877d603d3..dbf5e98c588a32265f65fa569f261129
|
||||
deps += [
|
||||
"//chrome:other_version",
|
||||
"//chrome//services/util_win:unit_tests",
|
||||
@@ -8696,6 +8700,10 @@ test("unit_tests") {
|
||||
@@ -8683,6 +8687,10 @@ test("unit_tests") {
|
||||
"../browser/performance_manager/policies/background_tab_loading_policy_unittest.cc",
|
||||
]
|
||||
|
||||
@@ -53,7 +53,7 @@ index a824761a0bf0a3d827cc78bc644e8da877d603d3..dbf5e98c588a32265f65fa569f261129
|
||||
sources += [
|
||||
# The importer code is not used on Android.
|
||||
"../common/importer/firefox_importer_utils_unittest.cc",
|
||||
@@ -8739,7 +8747,7 @@ test("unit_tests") {
|
||||
@@ -8726,7 +8734,7 @@ test("unit_tests") {
|
||||
# TODO(crbug.com/417513088): Maybe merge with the non-android `deps` declaration above?
|
||||
deps += [
|
||||
"../browser/screen_ai:screen_ai_install_state",
|
||||
|
||||
@@ -7,10 +7,10 @@ Build libc++ as static library to compile and pass
|
||||
nan tests
|
||||
|
||||
diff --git a/buildtools/third_party/libc++/BUILD.gn b/buildtools/third_party/libc++/BUILD.gn
|
||||
index 62547f7df1860fdb49c3c09b9976da12743f5e24..9ac0b985a8f4175d5f0e8aefff002e0dc693fa47 100644
|
||||
index ce38758afaa191b394a014a68aded12417aa72a1..d846b89156182073cff1aaac6cd32888a73867b2 100644
|
||||
--- a/buildtools/third_party/libc++/BUILD.gn
|
||||
+++ b/buildtools/third_party/libc++/BUILD.gn
|
||||
@@ -477,6 +477,7 @@ target(libcxx_target_type, "libc++") {
|
||||
@@ -456,6 +456,7 @@ target(libcxx_target_type, "libc++") {
|
||||
# need to explicitly depend on libc++.
|
||||
visibility = [
|
||||
"//build/config:common_deps",
|
||||
|
||||
@@ -15,7 +15,7 @@ References:
|
||||
* third_party/libc++/src/include/__configuration/abi.h
|
||||
|
||||
diff --git a/buildtools/third_party/libc++/__config_site b/buildtools/third_party/libc++/__config_site
|
||||
index a9ab1614b67e2df7b379c1d8a4147265a15747db..f1c60c7d0a320e5a1e9a9e454ef0e084c594258c 100644
|
||||
index c94ace80e45de876a175506b66d4b96dba2f7c02..359f8688158fd5b57e819893047524dbbb1b1b45 100644
|
||||
--- a/buildtools/third_party/libc++/__config_site
|
||||
+++ b/buildtools/third_party/libc++/__config_site
|
||||
@@ -18,7 +18,11 @@
|
||||
|
||||
@@ -9,10 +9,10 @@ potentially prevent a window from being created.
|
||||
TODO(loc): this patch is currently broken.
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
index 8b04c911b759c45b94dfb0c5c859e9ddbf012937..944bb9ee39682f4e623477f98b1c407b0c6b0d6a 100644
|
||||
index b4b82c13852232443f15785a1e8f2820c20fa0ca..80d3b463984813ac1459b02fac41ee995b437353 100644
|
||||
--- a/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
@@ -10268,6 +10268,7 @@ void RenderFrameHostImpl::CreateNewWindow(
|
||||
@@ -10262,6 +10262,7 @@ void RenderFrameHostImpl::CreateNewWindow(
|
||||
last_committed_origin_, params->window_container_type,
|
||||
params->target_url, params->referrer.To<Referrer>(),
|
||||
params->frame_name, params->disposition, *params->features,
|
||||
@@ -77,7 +77,7 @@ index a2566982ff81db5166e41243232e23af94dc3c05..ff5c410e78fb171963122f8a24802b7b
|
||||
|
||||
// Operation result when the renderer asks the browser to create a new window.
|
||||
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
|
||||
index 4aed38dd5f1c1d95d04ab49dd6937114788dcb70..d98b527556464a60d9f0324410824ae1c468764a 100644
|
||||
index 0713f0cbbbd93be954758f0b1ddb20b9f9701228..9d2e8a70a4307f1d055b356e6bccd98f3e56109c 100644
|
||||
--- a/content/public/browser/content_browser_client.cc
|
||||
+++ b/content/public/browser/content_browser_client.cc
|
||||
@@ -858,6 +858,8 @@ bool ContentBrowserClient::CanCreateWindow(
|
||||
@@ -90,10 +90,10 @@ index 4aed38dd5f1c1d95d04ab49dd6937114788dcb70..d98b527556464a60d9f0324410824ae1
|
||||
bool opener_suppressed,
|
||||
bool* no_javascript_access) {
|
||||
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
|
||||
index 5ce463ef59a60feb82a608e60744d97934f8e604..972d1966d2d4c86e3258bc8d48009fbaf9086d79 100644
|
||||
index 124994cc22f2923247b831e30c3241751c7b4c92..9d164c9386fe1906216db656e3972ef5dc50c583 100644
|
||||
--- a/content/public/browser/content_browser_client.h
|
||||
+++ b/content/public/browser/content_browser_client.h
|
||||
@@ -205,6 +205,7 @@ class NetworkService;
|
||||
@@ -204,6 +204,7 @@ class NetworkService;
|
||||
class TrustedURLLoaderHeaderClient;
|
||||
} // namespace mojom
|
||||
struct ResourceRequest;
|
||||
@@ -101,7 +101,7 @@ index 5ce463ef59a60feb82a608e60744d97934f8e604..972d1966d2d4c86e3258bc8d48009fba
|
||||
} // namespace network
|
||||
|
||||
namespace sandbox {
|
||||
@@ -1412,6 +1413,8 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
@@ -1411,6 +1412,8 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
const std::string& frame_name,
|
||||
WindowOpenDisposition disposition,
|
||||
const blink::mojom::WindowFeatures& features,
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Electron Scripts <scripts@electron>
|
||||
Date: Sat, 25 Apr 2026 21:10:03 -0500
|
||||
Subject: chore: exclude upstream scripting API when building Electron
|
||||
|
||||
Electron provides its own implementation of the Scripting API at
|
||||
shell/browser/extensions/api/scripting/ that includes Electron-specific
|
||||
modifications. CL 7784831 moved the upstream implementation from
|
||||
//chrome to //extensions, which caused it to be transitively linked
|
||||
into Electron, resulting in duplicate symbols.
|
||||
|
||||
Exclude the upstream sources when is_electron_build is set.
|
||||
|
||||
diff --git a/extensions/browser/api/scripting/BUILD.gn b/extensions/browser/api/scripting/BUILD.gn
|
||||
index 14d18bfbc36673f3eb9ffe0777d34ddd2163af0d..cff84c1a9e713e2845b2331913dde9be730305b1 100644
|
||||
--- a/extensions/browser/api/scripting/BUILD.gn
|
||||
+++ b/extensions/browser/api/scripting/BUILD.gn
|
||||
@@ -12,6 +12,16 @@ source_set("scripting") {
|
||||
"scripting_api.cc",
|
||||
"scripting_api.h",
|
||||
]
|
||||
+
|
||||
+ # Electron provides its own scripting API implementation in
|
||||
+ # shell/browser/extensions/api/scripting/.
|
||||
+ if (is_electron_build) {
|
||||
+ sources -= [
|
||||
+ "scripting_api.cc",
|
||||
+ "scripting_api.h",
|
||||
+ ]
|
||||
+ }
|
||||
+
|
||||
public_deps = [
|
||||
"//extensions/browser:browser_sources",
|
||||
"//extensions/common/api",
|
||||
@@ -6,7 +6,7 @@ Subject: disable_hidden.patch
|
||||
Electron uses this to disable background throttling for hidden windows.
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
|
||||
index de47fa819ae4012d893bb561b4507a3e847c8b0b..91f5aa62f256a061199e7091069607ceafc02e0d 100644
|
||||
index 91c1bd0ee59e6f6819434631de3ed8b6b290540f..edd98668b9e8220ec26c901f69b8d3bee866aba5 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
|
||||
@@ -828,6 +828,10 @@ void RenderWidgetHostImpl::WasHidden() {
|
||||
@@ -21,10 +21,10 @@ index de47fa819ae4012d893bb561b4507a3e847c8b0b..91f5aa62f256a061199e7091069607ce
|
||||
// Prompts should remain open and functional across tab switches.
|
||||
if (!delegate_ || !delegate_->IsWaitingForPointerLockPrompt(this)) {
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
|
||||
index ac87b21a1cec649d01adbe92e08ef4bd5870336e..0b94b2bcf0b0fe643328a37ab8e8b29d8477d0f4 100644
|
||||
index ae9afcf250cd6de6fcf83a19f6be2a9294e020af..7e88b070bfaae3d6430fe66fdc5f1070b15ac68c 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_impl.h
|
||||
+++ b/content/browser/renderer_host/render_widget_host_impl.h
|
||||
@@ -1063,6 +1063,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl
|
||||
@@ -1061,6 +1061,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl
|
||||
|
||||
base::TimeDelta GetHungRendererDelayForTesting();
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ index 0ab8187b0db8ae6db46d81738f653a2bc4c566f6..de3d55e85c22317f7f9375eb94d0d5d4
|
||||
|
||||
} // namespace net
|
||||
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
|
||||
index 2cd26265e717998c690aa277ff6ca6aac7b7ad0d..78661bd270ae364b1a85035df8a7c56c42752919 100644
|
||||
index 4bf222c4e6688384c034ef16170ad4cd64c379b0..97e59f9453659a5bd6868cfceaaaa3ddcfe0e5c2 100644
|
||||
--- a/services/network/network_context.cc
|
||||
+++ b/services/network/network_context.cc
|
||||
@@ -2013,6 +2013,13 @@ void NetworkContext::SetNetworkConditions(
|
||||
@@ -51,7 +51,7 @@ index 2cd26265e717998c690aa277ff6ca6aac7b7ad0d..78661bd270ae364b1a85035df8a7c56c
|
||||
// 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 b4239d2ed5632e9c93f3b395091344164b8468cb..4e9927a5681c7276c747e1351788a44f9f3caada 100644
|
||||
index 18a5062bac18be40ecd9e4de12ca4556802403c7..4ef2d2034a32bc1b70797bc5897fa354ac9e8c84 100644
|
||||
--- a/services/network/network_context.h
|
||||
+++ b/services/network/network_context.h
|
||||
@@ -334,6 +334,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
|
||||
@@ -63,7 +63,7 @@ index b4239d2ed5632e9c93f3b395091344164b8468cb..4e9927a5681c7276c747e1351788a44f
|
||||
void SetEnableReferrers(bool enable_referrers) override;
|
||||
#if BUILDFLAG(IS_CT_SUPPORTED)
|
||||
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
|
||||
index a7bb27ab245729413b5624c382115a8072e764a5..cf59da2795f425ebebb6e16ff72e414c4f65c8fc 100644
|
||||
index 88ac7593a8317dc646a128cce81f163554407bbc..f6bb0b757b65002ff86fd1b3ba8f117d76c02344 100644
|
||||
--- a/services/network/public/mojom/network_context.mojom
|
||||
+++ b/services/network/public/mojom/network_context.mojom
|
||||
@@ -1309,6 +1309,9 @@ interface NetworkContext {
|
||||
@@ -77,7 +77,7 @@ index a7bb27ab245729413b5624c382115a8072e764a5..cf59da2795f425ebebb6e16ff72e414c
|
||||
SetAcceptLanguage(string new_accept_language);
|
||||
|
||||
diff --git a/services/network/test/test_network_context.h b/services/network/test/test_network_context.h
|
||||
index 69a62289cf6a9eff3265b16ea4fdf3bee7efbc7d..8fa03b0cceee589cc00a781cb1ec2ca6edcce5b4 100644
|
||||
index af46691e72faa7e1c59de51b099fa7923eb89ec6..e1077e04b223adb4d25f12fcef2184f76c8b023c 100644
|
||||
--- a/services/network/test/test_network_context.h
|
||||
+++ b/services/network/test/test_network_context.h
|
||||
@@ -157,6 +157,7 @@ class TestNetworkContext : public mojom::NetworkContext {
|
||||
|
||||
@@ -15,7 +15,7 @@ Ideally we could add an embedder observer pattern here but that can be
|
||||
done in future work.
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
|
||||
index 756a6531f5db61adb5b17ce261719f29a9b6183a..3605673e00c0ad5b54f0a22c7e739c9bcb07f5c5 100644
|
||||
index 42b9ec3ca008be91318c843aba66a7a2e1c75ea5..932e5f8b417a75df41eee430a00564f629b0e4f1 100644
|
||||
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
|
||||
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
|
||||
@@ -1848,6 +1848,8 @@ void WebView::ApplyWebPreferences(const web_pref::WebPreferences& prefs,
|
||||
|
||||
@@ -46,7 +46,7 @@ index 1c01e4d6699da8760e074a5825784e139ed58fd4..c678a3df0b9e5a8c9e0bd99c1aa540b2
|
||||
'internal-forced-visited-'):
|
||||
internal_visited_order = 0
|
||||
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5
|
||||
index 7e78dc9d943ab3e9a77e41000e27f002ccbfdb64..fc910bf0c2720424604a4fc653e3223b54ecdb38 100644
|
||||
index e6731ee14be233e023768fc8433a1cade4e12284..4d1b79641cb465225b56b8f7d261ba783762232e 100644
|
||||
--- a/third_party/blink/renderer/core/css/css_properties.json5
|
||||
+++ b/third_party/blink/renderer/core/css/css_properties.json5
|
||||
@@ -9787,6 +9787,27 @@
|
||||
@@ -91,7 +91,7 @@ index 19cf78803d61a33f08d023bef8799f18c52b6fe3..9f267dbb92ae6496da8f0f14e94d90ea
|
||||
return a.EmptyCells() == b.EmptyCells();
|
||||
case CSSPropertyID::kFill:
|
||||
diff --git a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
|
||||
index dc3bf090a63c79fd59461f55d0aac99c2f8aac85..1604aa8993368dd825c473d77c4f4b6baa2c907f 100644
|
||||
index 25028c2b98dc45a1f10feca152f1f2d7524ffbe7..392e343d97711f9909a8002f68e2d29732aa2c73 100644
|
||||
--- a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
|
||||
+++ b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
|
||||
@@ -12380,5 +12380,36 @@ const CSSValue* InternalEmptyLineHeight::ParseSingleValue(
|
||||
@@ -203,7 +203,7 @@ index 19cda703154dab9397827ab6ea66c2ca446c644d..dd5943c511886f4e39b2e7f10e67e60f
|
||||
return result;
|
||||
}
|
||||
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn
|
||||
index e9b598083915794b32733fa576c5733834596854..3349bee194d7e4d6e5f3913d1f2b90ea13275166 100644
|
||||
index b98b5459691c91367933e352a32a590a92b190fe..5b1b9036192ee6db2196c7dbadf3b0344a37bfc8 100644
|
||||
--- a/third_party/blink/renderer/platform/BUILD.gn
|
||||
+++ b/third_party/blink/renderer/platform/BUILD.gn
|
||||
@@ -1677,6 +1677,8 @@ component("platform") {
|
||||
@@ -314,7 +314,7 @@ index 398fc8badaaf1dddc3183211c9302460393da85f..b35c8261b27a2d5c5f6bd84b606925c9
|
||||
|
||||
auto DrawAsSinglePath = [&]() {
|
||||
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
|
||||
index fed46bb94e8a5753a4309ec4ad3d17390d97e8d6..0e806f15414eb2fc60d539d6a16dcc3e8eb77442 100644
|
||||
index 4112cd5508122424bf1a87ba3a670352bfb9a3fa..23ac385af23d58832467fdb59db9b9b7f6dee881 100644
|
||||
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
|
||||
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
|
||||
@@ -215,6 +215,10 @@
|
||||
|
||||
@@ -90,7 +90,7 @@ index 8af69cac78b7488d28f1f05ccb174793fe5148cd..9f74e511c263d147b5fbe81fe100d217
|
||||
private:
|
||||
const HWND hwnd_;
|
||||
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
|
||||
index 44072bd19a908aa0604e440e89c303cd8044f342..820c23869139d4293c26b6a854b7c08576c07a3c 100644
|
||||
index c1be2f1a8dc4d834ffa2e5944f7dd2753740a4c6..982327d24f0c3d1a4b90bea9a0e93c684aeab17f 100644
|
||||
--- a/components/viz/service/BUILD.gn
|
||||
+++ b/components/viz/service/BUILD.gn
|
||||
@@ -178,6 +178,8 @@ viz_component("service") {
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Calvin Watford <cwatford@makenotion.com>
|
||||
Date: Sun, 12 Apr 2026 21:24:57 -0700
|
||||
Subject: fix: constrain AllowUniversalAccessFromFileURLs to file: origins in
|
||||
agent assignment
|
||||
|
||||
HasPotentialUniversalAccessPrivilege() was treating the
|
||||
AllowUniversalAccessFromFileURLs setting as unconditional, returning
|
||||
true for all origins regardless of scheme. This caused non-file origins
|
||||
(http://, https://, and custom schemes) to lose their browser-provided
|
||||
AgentClusterKey when the setting was enabled, overriding it with a
|
||||
universal file agent key and routing them to universal_access_agent_
|
||||
which carries no key.
|
||||
|
||||
Electron enables AllowUniversalAccessFromFileURLs in all renderers via
|
||||
the grant_file_protocol_extra_privileges fuse (on by default). After
|
||||
https://crrev.com/c/7079680 moved cross-origin isolation status to the
|
||||
renderer's per-context agent cluster key, this caused
|
||||
self.crossOriginIsolated to return false even with COOP + COEP headers
|
||||
correctly set on non-file origins.
|
||||
|
||||
The fix splits the single has_potential_universal_access_privilege
|
||||
boolean in WindowAgentFactory::GetAgentForAgentClusterKey() into two
|
||||
separate parameters:
|
||||
|
||||
- web_security_disabled: applies to all origins when web security is
|
||||
off (--disable-web-security, --run-web-tests).
|
||||
- allow_universal_access_from_file_urls: only takes effect for file:
|
||||
scheme origins (those with IsUniversalFileAgent() agent cluster
|
||||
keys), preserving their existing routing to universal_access_agent_.
|
||||
|
||||
This aligns the agent assignment logic with the origin privilege
|
||||
granting code in the same file (DocumentLoader::CalculateOrigin), which
|
||||
already correctly gates AllowUniversalAccessFromFileURLs behind
|
||||
origin->IsLocal().
|
||||
|
||||
This patch should be upstreamed, with updates to surrounding doc
|
||||
comments + tests.
|
||||
|
||||
Upstream CL: https://chromium-review.googlesource.com/c/chromium/src/+/7795303
|
||||
Chromium bug: https://crbug.com/505299810
|
||||
|
||||
diff --git a/third_party/blink/renderer/core/execution_context/window_agent_factory.cc b/third_party/blink/renderer/core/execution_context/window_agent_factory.cc
|
||||
index 86ce2d493dc833dd1601787fc042b8a4a612fc2e..b9bd1f459f240401d7a6b0bce03cf82b6b54e9fc 100644
|
||||
--- a/third_party/blink/renderer/core/execution_context/window_agent_factory.cc
|
||||
+++ b/third_party/blink/renderer/core/execution_context/window_agent_factory.cc
|
||||
@@ -20,19 +20,27 @@ WindowAgentFactory::WindowAgentFactory(
|
||||
AgentGroupScheduler& agent_group_scheduler)
|
||||
: agent_group_scheduler_(agent_group_scheduler) {}
|
||||
|
||||
+WindowAgent* WindowAgentFactory::GetOrCreateUniversalAccessAgent() {
|
||||
+ if (!universal_access_agent_) {
|
||||
+ universal_access_agent_ =
|
||||
+ MakeGarbageCollected<WindowAgent>(*agent_group_scheduler_);
|
||||
+ }
|
||||
+ return universal_access_agent_.Get();
|
||||
+}
|
||||
+
|
||||
WindowAgent* WindowAgentFactory::GetAgentForAgentClusterKey(
|
||||
- bool has_potential_universal_access_privilege,
|
||||
+ bool is_web_security_disabled,
|
||||
+ bool allow_universal_access_from_file_urls,
|
||||
const AgentClusterKey& agent_cluster_key) {
|
||||
- if (has_potential_universal_access_privilege) {
|
||||
- if (!universal_access_agent_) {
|
||||
- universal_access_agent_ =
|
||||
- MakeGarbageCollected<WindowAgent>(*agent_group_scheduler_);
|
||||
- }
|
||||
- return universal_access_agent_.Get();
|
||||
+ if (is_web_security_disabled) {
|
||||
+ return GetOrCreateUniversalAccessAgent();
|
||||
}
|
||||
|
||||
// For `file:` scheme origins.
|
||||
if (agent_cluster_key.IsUniversalFileAgent()) {
|
||||
+ if (allow_universal_access_from_file_urls) {
|
||||
+ return GetOrCreateUniversalAccessAgent();
|
||||
+ }
|
||||
if (!file_url_agent_) {
|
||||
file_url_agent_ = MakeGarbageCollected<WindowAgent>(
|
||||
*agent_group_scheduler_, agent_cluster_key);
|
||||
diff --git a/third_party/blink/renderer/core/execution_context/window_agent_factory.h b/third_party/blink/renderer/core/execution_context/window_agent_factory.h
|
||||
index b5464975a3c365a29e342b0dd57a8a73a311924a..72ebd275330e61a8abebfe6d2c06f42544a83bec 100644
|
||||
--- a/third_party/blink/renderer/core/execution_context/window_agent_factory.h
|
||||
+++ b/third_party/blink/renderer/core/execution_context/window_agent_factory.h
|
||||
@@ -40,12 +40,15 @@ class WindowAgentFactory final : public GarbageCollected<WindowAgentFactory> {
|
||||
// * --run-web-tests is set,
|
||||
// * or, the Blink instance is running for Android WebView.
|
||||
WindowAgent* GetAgentForAgentClusterKey(
|
||||
- bool has_potential_universal_access_privilege,
|
||||
+ bool is_web_security_disabled,
|
||||
+ bool allow_universal_access_from_file_urls,
|
||||
const AgentClusterKey& agent_cluster_key);
|
||||
|
||||
void Trace(Visitor*) const;
|
||||
|
||||
private:
|
||||
+ WindowAgent* GetOrCreateUniversalAccessAgent();
|
||||
+
|
||||
// Use a shared instance of Agent for all frames if a frame may have the
|
||||
// universal access privilege.
|
||||
WeakMember<WindowAgent> universal_access_agent_;
|
||||
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc
|
||||
index 2344e1d62f4a2d7fdf139b64b6c71ede1e3094ce..f79f870408a71e107933219f30ea6dc3afaa8716 100644
|
||||
--- a/third_party/blink/renderer/core/loader/document_loader.cc
|
||||
+++ b/third_party/blink/renderer/core/loader/document_loader.cc
|
||||
@@ -2600,22 +2600,16 @@ bool ShouldReuseDOMWindow(LocalDOMWindow* window,
|
||||
return *window_coi_key == *navigation_coi_key;
|
||||
}
|
||||
|
||||
-namespace {
|
||||
-
|
||||
-bool HasPotentialUniversalAccessPrivilege(LocalFrame* frame) {
|
||||
- return !frame->GetSettings()->GetWebSecurityEnabled() ||
|
||||
- frame->GetSettings()->GetAllowUniversalAccessFromFileURLs();
|
||||
-}
|
||||
-
|
||||
-} // namespace
|
||||
-
|
||||
WindowAgent* GetWindowAgentForAgentClusterKey(
|
||||
LocalFrame* frame,
|
||||
const AgentClusterKey& agent_cluster_key) {
|
||||
// TODO(keishi): Also check if AllowUniversalAccessFromFileURLs might
|
||||
// dynamically change.
|
||||
+ Settings* settings = frame->GetSettings();
|
||||
return frame->window_agent_factory().GetAgentForAgentClusterKey(
|
||||
- HasPotentialUniversalAccessPrivilege(frame), agent_cluster_key);
|
||||
+ /*is_web_security_disabled=*/!settings->GetWebSecurityEnabled(),
|
||||
+ /*allow_universal_access_from_file_urls=*/
|
||||
+ settings->GetAllowUniversalAccessFromFileURLs(), agent_cluster_key);
|
||||
}
|
||||
|
||||
// Inheriting cases use their agent's AgentClusterKey value, which is set
|
||||
@@ -2716,7 +2710,7 @@ void DocumentLoader::InitializeWindow(Document* owner_document) {
|
||||
// WindowAgentFactory::GetAgentForOrigin(), as the two conditions below hand
|
||||
// out universal WindowAgent objects, and thus override the AgentClusterKey
|
||||
// provided by the browser process.
|
||||
- } else if (HasPotentialUniversalAccessPrivilege(frame_.Get()) ||
|
||||
+ } else if (!frame_->GetSettings()->GetWebSecurityEnabled() ||
|
||||
security_origin->IsLocal()) {
|
||||
// In this case we either have AllowUniversalAccessFromFileURLs enabled, or
|
||||
// WebSecurity is disabled, or it's a local scheme such as file://; any of
|
||||
@@ -28,10 +28,10 @@ The patch should be removed in favor of either:
|
||||
Upstream bug https://bugs.chromium.org/p/chromium/issues/detail?id=1081397.
|
||||
|
||||
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
|
||||
index 764142259d94c2ed32f05e3998b6be5bf651299a..4bce504ef8fbf2dda21b5c043496a22f48365a72 100644
|
||||
index 6eb61524c22e9fd60ebfd9cf6484622ed3ab28d4..62b5787e4bc3a9932125950b10ae6d3d0722a70c 100644
|
||||
--- a/content/browser/renderer_host/navigation_request.cc
|
||||
+++ b/content/browser/renderer_host/navigation_request.cc
|
||||
@@ -11946,6 +11946,11 @@ url::Origin NavigationRequest::GetOriginForURLLoaderFactoryUnchecked() {
|
||||
@@ -11958,6 +11958,11 @@ url::Origin NavigationRequest::GetOriginForURLLoaderFactoryUnchecked() {
|
||||
target_rph_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,10 +11,10 @@ This patch should be upstreamed as a conditional revert of the logic in desktop
|
||||
vs mobile runtimes. i.e. restore the old logic only on desktop platforms
|
||||
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
|
||||
index a5c13ea50845fede85741de7a6f3b1c327698110..50edc218dc16c85c3c870c744b9c14936a0e99d2 100644
|
||||
index c71887ba0658c98b7a3cf80064efb65f778ff426..ddafdbe57d3ba8f178f8a193a4ae1b59d1b47edf 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
|
||||
@@ -2173,9 +2173,8 @@ RenderWidgetHostImpl::GetWidgetInputHandler() {
|
||||
@@ -2165,9 +2165,8 @@ RenderWidgetHostImpl::GetWidgetInputHandler() {
|
||||
void RenderWidgetHostImpl::NotifyScreenInfoChanged() {
|
||||
// The resize message (which may not happen immediately) will carry with it
|
||||
// the screen info as well as the new size (if the screen has changed scale
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Om Ghante <omghante@users.noreply.github.com>
|
||||
Date: Tue, 21 Apr 2026 23:30:00 +0530
|
||||
Subject: fix: add ShouldUseBundledFrontendResources delegate for remote
|
||||
debugging
|
||||
|
||||
Adds a new `ShouldUseBundledFrontendResources()` virtual method to
|
||||
`DevToolsManagerDelegate` that embedders can override to control whether
|
||||
the bundled DevTools frontend URL is used in the `/json` response,
|
||||
regardless of `CHROMIUM_GIT_REVISION`.
|
||||
|
||||
This is needed because embedders like Electron ship bundled frontend
|
||||
resources, but the remote frontend on the CDN may not be available for
|
||||
their custom Chromium revisions or may expire before their extended
|
||||
release cycles end.
|
||||
|
||||
Without this, `GetFrontendURLInternal()` generates a
|
||||
`devtoolsFrontendUrl` pointing to
|
||||
`chrome-devtools-frontend.appspot.com`, which returns 404 for
|
||||
embedder-specific Chromium builds, causing Chrome's `chrome://inspect`
|
||||
page to show an empty DevTools window.
|
||||
|
||||
The default implementation returns `false` to preserve existing
|
||||
behavior for Chrome and other embedders.
|
||||
|
||||
Fixes: https://github.com/electron/electron/issues/51035
|
||||
|
||||
diff --git a/content/browser/devtools/devtools_http_handler.cc b/content/browser/devtools/devtools_http_handler.cc
|
||||
index fbfe1abebb19119387d55a1296aba5fd1ca7d99b..2c2d263bc026a0b63010498fb02d9bb897852bc8 100644
|
||||
--- a/content/browser/devtools/devtools_http_handler.cc
|
||||
+++ b/content/browser/devtools/devtools_http_handler.cc
|
||||
@@ -544,7 +544,8 @@ std::string DevToolsHttpHandler::GetFrontendURLInternal(
|
||||
const std::string& host) {
|
||||
std::string frontend_url;
|
||||
const std::string git_revision = CHROMIUM_GIT_REVISION;
|
||||
- if (git_revision == kMissingGitRevision &&
|
||||
+ if ((git_revision == kMissingGitRevision ||
|
||||
+ delegate_->ShouldUseBundledFrontendResources()) &&
|
||||
delegate_->HasBundledFrontendResources()) {
|
||||
frontend_url = "/devtools/inspector.html";
|
||||
} else {
|
||||
diff --git a/content/public/browser/devtools_manager_delegate.cc b/content/public/browser/devtools_manager_delegate.cc
|
||||
index 748e96014ce6144b38a8452774d520503721e59e..7cdeab0c1de9c6bbd400afd434b1603318af0c2e 100644
|
||||
--- a/content/public/browser/devtools_manager_delegate.cc
|
||||
+++ b/content/public/browser/devtools_manager_delegate.cc
|
||||
@@ -111,6 +111,10 @@ bool DevToolsManagerDelegate::HasBundledFrontendResources() {
|
||||
return false;
|
||||
}
|
||||
|
||||
+bool DevToolsManagerDelegate::ShouldUseBundledFrontendResources() {
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
bool DevToolsManagerDelegate::IsBrowserTargetDiscoverable() {
|
||||
return false;
|
||||
}
|
||||
diff --git a/content/public/browser/devtools_manager_delegate.h b/content/public/browser/devtools_manager_delegate.h
|
||||
index 1a053f63d3f2c16dd24a59537d5f381f55eb1ae7..78f8d70e0e8b56cc5a2d9f28e33d78e6a161aecc 100644
|
||||
--- a/content/public/browser/devtools_manager_delegate.h
|
||||
+++ b/content/public/browser/devtools_manager_delegate.h
|
||||
@@ -151,6 +151,13 @@ class CONTENT_EXPORT DevToolsManagerDelegate {
|
||||
// Returns whether frontend resources are bundled within the binary.
|
||||
virtual bool HasBundledFrontendResources();
|
||||
|
||||
+ // Returns whether the bundled frontend resources should be preferred over
|
||||
+ // the remote frontend served from the CDN. Embedders that ship bundled
|
||||
+ // frontend resources and whose Chromium revisions may not be available on
|
||||
+ // the CDN (or may expire before their release cycle ends) should override
|
||||
+ // this to return true.
|
||||
+ virtual bool ShouldUseBundledFrontendResources();
|
||||
+
|
||||
// Makes browser target easily discoverable for remote debugging.
|
||||
// This should only return true when remote debugging endpoint is not
|
||||
// accessible by the web (for example in Chrome for Android where it is
|
||||
@@ -20,10 +20,10 @@ index 9e1cfd02a369d865d24aa95d28b2597eec9dc614..63bd6220e49e933fca9258e1c01ab5c2
|
||||
}
|
||||
|
||||
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
|
||||
index 972d1966d2d4c86e3258bc8d48009fbaf9086d79..d5ead99c3efd2f0ca5b2252e3971c48a45c0c282 100644
|
||||
index 9d164c9386fe1906216db656e3972ef5dc50c583..8305651861ad5978cc91763da8b99da2c07adfd5 100644
|
||||
--- a/content/public/browser/content_browser_client.h
|
||||
+++ b/content/public/browser/content_browser_client.h
|
||||
@@ -350,6 +350,11 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
@@ -349,6 +349,11 @@ class CONTENT_EXPORT ContentBrowserClient {
|
||||
|
||||
virtual ~ContentBrowserClient() = default;
|
||||
|
||||
|
||||
@@ -6,10 +6,10 @@ Subject: gritsettings_resource_ids.patch
|
||||
Add electron resources file to the list of resource ids generation.
|
||||
|
||||
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec
|
||||
index d0620514c19f330dac4e33cb19bccea063919236..b20a1b116d8d9ed046193361149cf00023c48876 100644
|
||||
index d97cd9f349477ffaed02073948f4d93c9b10a49a..21be21d0bd82ccfcf79007d6ad58a0f89d7fa193 100644
|
||||
--- a/tools/gritsettings/resource_ids.spec
|
||||
+++ b/tools/gritsettings/resource_ids.spec
|
||||
@@ -1717,6 +1717,11 @@
|
||||
@@ -1709,6 +1709,11 @@
|
||||
"includes": [12000],
|
||||
},
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ system font by checking if it's kCTFontPriorityAttribute is set to
|
||||
system priority.
|
||||
|
||||
diff --git a/base/BUILD.gn b/base/BUILD.gn
|
||||
index 16fd234a12b251e943e1193998ac599cfa027860..57d283b024fa1d1f225ca76c7c7bff604be493bf 100644
|
||||
index b6eda46513f34c3000c53eff9cee40f587483054..36590c346e64a55ee07e25e8cc1939eb12ca3c82 100644
|
||||
--- a/base/BUILD.gn
|
||||
+++ b/base/BUILD.gn
|
||||
@@ -1124,6 +1124,7 @@ component("base") {
|
||||
@@ -869,10 +869,10 @@ index d58c5eff9f8fbca96d0912ab9a19d06974fd8016..94ee727830545ff1576685722c0fd0dd
|
||||
|
||||
void NativeWidgetNSWindowBridge::SetColorMode(
|
||||
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
|
||||
index 1001fc872ae76c80c285a00f96a43c12910937cc..44072bd19a908aa0604e440e89c303cd8044f342 100644
|
||||
index 86c7e67902a7e9c0f90c4d10ebabfef2f53c1ec4..c1be2f1a8dc4d834ffa2e5944f7dd2753740a4c6 100644
|
||||
--- a/components/viz/service/BUILD.gn
|
||||
+++ b/components/viz/service/BUILD.gn
|
||||
@@ -395,6 +395,7 @@ viz_component("service") {
|
||||
@@ -393,6 +393,7 @@ viz_component("service") {
|
||||
"frame_sinks/external_begin_frame_source_mojo_mac.h",
|
||||
]
|
||||
}
|
||||
@@ -880,7 +880,7 @@ index 1001fc872ae76c80c285a00f96a43c12910937cc..44072bd19a908aa0604e440e89c303cd
|
||||
}
|
||||
|
||||
if (is_ios) {
|
||||
@@ -740,6 +741,7 @@ viz_source_set("unit_tests") {
|
||||
@@ -738,6 +739,7 @@ viz_source_set("unit_tests") {
|
||||
"display_embedder/software_output_device_mac_unittest.mm",
|
||||
]
|
||||
frameworks = [ "IOSurface.framework" ]
|
||||
@@ -1342,7 +1342,7 @@ index 2939a4183785608041041642ee81287d0fbd605d..89081a4d8e1dedbe8d45a824c5823601
|
||||
|
||||
if (is_ios) {
|
||||
diff --git a/media/audio/apple/audio_low_latency_input.cc b/media/audio/apple/audio_low_latency_input.cc
|
||||
index 7cd1fdaf15b847e5241144b47a47fe6c1d3907a5..004fd96906f258e193ed5acd80e2405db011e039 100644
|
||||
index 75178516b53665c82195f795c5e4498c588e51c9..10e453a18813d3078dc4f01ab040acc66bf12bec 100644
|
||||
--- a/media/audio/apple/audio_low_latency_input.cc
|
||||
+++ b/media/audio/apple/audio_low_latency_input.cc
|
||||
@@ -26,6 +26,7 @@
|
||||
@@ -2495,7 +2495,7 @@ index 2914e7149f24fa903ca9861934a93e77f397e979..a258b94a8122c74b6f98f4b88b710371
|
||||
}
|
||||
|
||||
diff --git a/ui/views/controls/webview/BUILD.gn b/ui/views/controls/webview/BUILD.gn
|
||||
index e741b52a4db7ff481fe0f9c6d915465ccad8733d..2dd0d120848e8f2236f20bdaee20dd4b244891ff 100644
|
||||
index dfcff42888a014a1e1325fe164243051b616604a..603a18f125d1b2bf23a017c1ed97716e90842854 100644
|
||||
--- a/ui/views/controls/webview/BUILD.gn
|
||||
+++ b/ui/views/controls/webview/BUILD.gn
|
||||
@@ -48,6 +48,12 @@ component("webview") {
|
||||
|
||||
@@ -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 57155f8fe60279f1ac0c0cccf41ba4a468bf3bdb..2cd26265e717998c690aa277ff6ca6aac7b7ad0d 100644
|
||||
index bab46a7eb7b58356ea37702880a46d4e7bbc8f2f..4bf222c4e6688384c034ef16170ad4cd64c379b0 100644
|
||||
--- a/services/network/network_context.cc
|
||||
+++ b/services/network/network_context.cc
|
||||
@@ -174,6 +174,11 @@
|
||||
@@ -148,7 +148,7 @@ index 57155f8fe60279f1ac0c0cccf41ba4a468bf3bdb..2cd26265e717998c690aa277ff6ca6aa
|
||||
void NetworkContext::CreateURLLoaderFactory(
|
||||
mojo::PendingReceiver<mojom::URLLoaderFactory> receiver,
|
||||
mojom::URLLoaderFactoryParamsPtr params) {
|
||||
@@ -2820,6 +2937,10 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext(
|
||||
@@ -2819,6 +2936,10 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext(
|
||||
cert_verifier = std::make_unique<net::CachingCertVerifier>(
|
||||
std::make_unique<net::CoalescingCertVerifier>(
|
||||
std::move(cert_verifier)));
|
||||
@@ -160,7 +160,7 @@ index 57155f8fe60279f1ac0c0cccf41ba4a468bf3bdb..2cd26265e717998c690aa277ff6ca6aa
|
||||
|
||||
builder.SetCertVerifier(IgnoreErrorsCertVerifier::MaybeWrapCertVerifier(
|
||||
diff --git a/services/network/network_context.h b/services/network/network_context.h
|
||||
index 6bdcb6fac47513e8c4c4b6d0e24c74a8baad2b37..b4239d2ed5632e9c93f3b395091344164b8468cb 100644
|
||||
index 7de41be5dfb099b9e47d65416c548e033fcae684..18a5062bac18be40ecd9e4de12ca4556802403c7 100644
|
||||
--- a/services/network/network_context.h
|
||||
+++ b/services/network/network_context.h
|
||||
@@ -123,6 +123,7 @@ class SimpleUrlPatternMatcher;
|
||||
@@ -180,7 +180,7 @@ index 6bdcb6fac47513e8c4c4b6d0e24c74a8baad2b37..b4239d2ed5632e9c93f3b39509134416
|
||||
void ResetURLLoaderFactories() override;
|
||||
void GetViaObliviousHttp(
|
||||
mojom::ObliviousHttpRequestPtr request,
|
||||
@@ -1011,6 +1014,8 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
|
||||
@@ -1010,6 +1013,8 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
|
||||
std::vector<base::OnceClosure> dismount_closures_;
|
||||
#endif // BUILDFLAG(IS_DIRECTORY_TRANSFER_REQUIRED)
|
||||
|
||||
@@ -190,7 +190,7 @@ index 6bdcb6fac47513e8c4c4b6d0e24c74a8baad2b37..b4239d2ed5632e9c93f3b39509134416
|
||||
std::unique_ptr<HostResolver> internal_host_resolver_;
|
||||
std::set<std::unique_ptr<HostResolver>, base::UniquePtrComparator>
|
||||
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
|
||||
index 20314a191f4ba858b374921230b940802aaee56a..a7bb27ab245729413b5624c382115a8072e764a5 100644
|
||||
index 065da0cd7ec38f52c45f515f47ecf1ec81104598..88ac7593a8317dc646a128cce81f163554407bbc 100644
|
||||
--- a/services/network/public/mojom/network_context.mojom
|
||||
+++ b/services/network/public/mojom/network_context.mojom
|
||||
@@ -331,6 +331,17 @@ struct SocketBrokerRemotes {
|
||||
@@ -222,7 +222,7 @@ index 20314a191f4ba858b374921230b940802aaee56a..a7bb27ab245729413b5624c382115a80
|
||||
CreateURLLoaderFactory(
|
||||
pending_receiver<URLLoaderFactory> url_loader_factory,
|
||||
diff --git a/services/network/test/test_network_context.h b/services/network/test/test_network_context.h
|
||||
index 6bef01cbd02ba9bb665dcec76aa1eedd655ba56b..69a62289cf6a9eff3265b16ea4fdf3bee7efbc7d 100644
|
||||
index 61d23511df68e2efd1e5eb41d5a94457aca038ad..af46691e72faa7e1c59de51b099fa7923eb89ec6 100644
|
||||
--- a/services/network/test/test_network_context.h
|
||||
+++ b/services/network/test/test_network_context.h
|
||||
@@ -63,6 +63,8 @@ class TestNetworkContext : public mojom::NetworkContext {
|
||||
|
||||
@@ -7,7 +7,7 @@ Pass RenderFrameHost through to PlatformNotificationService
|
||||
so Electron can identify which renderer a notification came from.
|
||||
|
||||
diff --git a/chrome/browser/notifications/platform_notification_service_impl.cc b/chrome/browser/notifications/platform_notification_service_impl.cc
|
||||
index e617356dc4864d7e0fede7d2e1e104e6bd91b701..6f82bb909d24ae1d8f7e90f82b034cd142fc166e 100644
|
||||
index 16ef14e1fba28b43fe23214fb299eee3b152673d..5127f296bcf5f65c83b91defb1133de281a3ac19 100644
|
||||
--- a/chrome/browser/notifications/platform_notification_service_impl.cc
|
||||
+++ b/chrome/browser/notifications/platform_notification_service_impl.cc
|
||||
@@ -265,6 +265,7 @@ bool PlatformNotificationServiceImpl::WasClosedProgrammatically(
|
||||
|
||||
@@ -30,7 +30,7 @@ index d83118cbc1e4c1ecf4ba3f4df2d730800c5cf7dd..37b9dde276f27ce6aa8c7e8e5ecb9fba
|
||||
// RenderWidgetHost on the primary main frame, and false otherwise.
|
||||
virtual bool IsWidgetForPrimaryMainFrame(RenderWidgetHostImpl*);
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
|
||||
index 91f5aa62f256a061199e7091069607ceafc02e0d..a5c13ea50845fede85741de7a6f3b1c327698110 100644
|
||||
index edd98668b9e8220ec26c901f69b8d3bee866aba5..c71887ba0658c98b7a3cf80064efb65f778ff426 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
|
||||
@@ -2076,6 +2076,9 @@ void RenderWidgetHostImpl::SetCursor(const ui::Cursor& cursor) {
|
||||
|
||||
@@ -8,7 +8,7 @@ it in Electron and prevent drift from Chrome's blocklist. We should look for a w
|
||||
to upstream this change to Chrome.
|
||||
|
||||
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
|
||||
index 434db30ba5d8853147f36513049feb8b7f2e2fe1..2deaf6a1a187023febfff7398e20dea15bd18be9 100644
|
||||
index 069196b656b5273317934280b77a2a9160d0136a..429e862e6ee46b8a4fbcc6ba6c9ac1b2147a1596 100644
|
||||
--- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
|
||||
+++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
|
||||
@@ -84,11 +84,13 @@
|
||||
@@ -16,7 +16,7 @@ index 434db30ba5d8853147f36513049feb8b7f2e2fe1..2deaf6a1a187023febfff7398e20dea1
|
||||
#include "chrome/browser/ui/tabs/public/tab_features.h"
|
||||
#include "chrome/browser/ui/views/file_system_access/file_system_access_page_action_controller.h"
|
||||
+#if 0
|
||||
#include "chrome/browser/web_applications/proto/web_app_install_state.pb.h" // nogncheck
|
||||
#include "chrome/browser/web_applications/proto/web_app_install_state.pb.h"
|
||||
#include "chrome/browser/web_applications/web_app_install_manager.h"
|
||||
#include "chrome/browser/web_applications/web_app_install_manager_observer.h"
|
||||
#include "chrome/browser/web_applications/web_app_provider.h"
|
||||
|
||||
@@ -52,10 +52,10 @@ Some alternatives to this patch:
|
||||
None of these options seems like a substantial maintainability win over this patch to me (@nornagon).
|
||||
|
||||
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
|
||||
index a2fe0be293dfe7c0633651e64da1320047d102bb..171faeaa1c3ba08cc0cd166b492765c8204bb674 100644
|
||||
index 1f0485537a00754d1aa0064d7a51d3e3a2a5fd3b..48f28a61eac4b31c3d9be62100c00cadff84174c 100644
|
||||
--- a/chrome/BUILD.gn
|
||||
+++ b/chrome/BUILD.gn
|
||||
@@ -1565,7 +1565,7 @@ if (is_chrome_branded && !is_android) {
|
||||
@@ -1566,7 +1566,7 @@ if (is_chrome_branded && !is_android) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ index a2fe0be293dfe7c0633651e64da1320047d102bb..171faeaa1c3ba08cc0cd166b492765c8
|
||||
chrome_paks("packed_resources") {
|
||||
if (is_mac) {
|
||||
output_dir = "$root_gen_dir/repack"
|
||||
@@ -1593,6 +1593,12 @@ repack("browser_tests_pak") {
|
||||
@@ -1594,6 +1594,12 @@ repack("browser_tests_pak") {
|
||||
deps = [ "//chrome/test/data/webui:resources" ]
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ index 37b9dde276f27ce6aa8c7e8e5ecb9fba05324ca6..56df8d4d5db8b68f3a0b043096065aaf
|
||||
// event before sending it to the renderer. See enum for details on return
|
||||
// value.
|
||||
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
|
||||
index 50edc218dc16c85c3c870c744b9c14936a0e99d2..92d8b68a76cfba407b3337693718121c4edf9fbf 100644
|
||||
index ddafdbe57d3ba8f178f8a193a4ae1b59d1b47edf..5303507537061de5f515f199f95fbae16fcd996c 100644
|
||||
--- a/content/browser/renderer_host/render_widget_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
|
||||
@@ -1572,6 +1572,10 @@ void RenderWidgetHostImpl::ForwardMouseEventWithLatencyInfo(
|
||||
|
||||
@@ -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 944bb9ee39682f4e623477f98b1c407b0c6b0d6a..c29ece68e6fa5344e20db967b4acaf5229e9a8df 100644
|
||||
index 80d3b463984813ac1459b02fac41ee995b437353..abdcf9cd75790f06e5aa7bc3edc3b9ec3b7e6ec3 100644
|
||||
--- a/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
|
||||
@@ -9293,6 +9293,17 @@ void RenderFrameHostImpl::EnterFullscreen(
|
||||
|
||||
@@ -46,4 +46,3 @@ src_stop_using_v8_propertycallbackinfo_t_this.patch
|
||||
build_restore_macos_deployment_target_to_12_0.patch
|
||||
fix_add_externalpointertypetag_to_v8_external_api_calls.patch
|
||||
test_update_v8_serialization_wire_format_version_to_16.patch
|
||||
fix_add_missing_cstdlib_include_to_builtin_info.patch
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Charles Kerr <charles@charleskerr.com>
|
||||
Date: Mon, 27 Apr 2026 21:17:16 -0500
|
||||
Subject: fix: add missing cstdlib include to builtin_info
|
||||
|
||||
Node's builtin_info.cc uses abort() but doesn't include <cstdlib>.
|
||||
It used to pick up the declaration by a transitive include, but
|
||||
that broke in this libc++ roll.
|
||||
|
||||
This patch can be removed after it's been upstreamed to Node.js.
|
||||
|
||||
diff --git a/src/builtin_info.cc b/src/builtin_info.cc
|
||||
index d5309265ac373310c20ba4f2438a778c9753254a..2c8b2b62704aadac6d8f3afbb56a9d4d5461ad58 100644
|
||||
--- a/src/builtin_info.cc
|
||||
+++ b/src/builtin_info.cc
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "builtin_info.h"
|
||||
|
||||
+#include <cstdlib>
|
||||
+
|
||||
namespace node {
|
||||
namespace builtins {
|
||||
|
||||
@@ -41,7 +43,7 @@ std::string GetBuiltinSourceTypeName(BuiltinSourceType type) {
|
||||
case BuiltinSourceType::kSourceTextModule:
|
||||
return "kSourceTextModule";
|
||||
}
|
||||
- abort();
|
||||
+ std::abort();
|
||||
}
|
||||
|
||||
} // namespace builtins
|
||||
@@ -15,10 +15,10 @@ Rather than disabling builtins PGO entirely, warn and skip mismatched
|
||||
builtins so all other builtins still benefit from PGO.
|
||||
|
||||
diff --git a/BUILD.gn b/BUILD.gn
|
||||
index ebff41d33352be25a548efcbacdc97ae6494b416..0af77eb0b597022b3d8262b6eb76c0bdf38a61ce 100644
|
||||
index eedd49aa7f990912f46a27df5115917bd93e4c91..58c7fdfffba619637c430e783b57291f8cc586c8 100644
|
||||
--- a/BUILD.gn
|
||||
+++ b/BUILD.gn
|
||||
@@ -2825,9 +2825,11 @@ template("run_mksnapshot") {
|
||||
@@ -2826,9 +2826,11 @@ template("run_mksnapshot") {
|
||||
"--turbo-profiling-input",
|
||||
rebase_path(v8_builtins_profiling_log_file, root_build_dir),
|
||||
|
||||
|
||||
@@ -101,7 +101,6 @@
|
||||
#include "content/browser/mac_helpers.h"
|
||||
#include "shell/browser/electron_child_process_host_flags.h"
|
||||
#include "shell/browser/ui/cocoa/electron_bundle_mover.h"
|
||||
#include "shell/browser/webauthn/electron_authenticator_request_delegate.h"
|
||||
#include "shell/common/process_util.h"
|
||||
#endif
|
||||
|
||||
@@ -1665,29 +1664,6 @@ bool App::IsInApplicationsFolder() {
|
||||
return ElectronBundleMover::IsCurrentAppInApplicationsFolder();
|
||||
}
|
||||
|
||||
void App::ConfigureWebAuthn(gin_helper::ErrorThrower thrower,
|
||||
gin::Arguments* args) {
|
||||
gin_helper::Dictionary options;
|
||||
if (!args->GetNext(&options)) {
|
||||
thrower.ThrowTypeError("configureWebAuthn requires an options object");
|
||||
return;
|
||||
}
|
||||
|
||||
gin_helper::Dictionary touch_id;
|
||||
if (options.Get("touchID", &touch_id)) {
|
||||
std::string keychain_access_group;
|
||||
if (!touch_id.Get("keychainAccessGroup", &keychain_access_group) ||
|
||||
keychain_access_group.empty()) {
|
||||
thrower.ThrowTypeError(
|
||||
"configureWebAuthn: 'touchID.keychainAccessGroup' must be a "
|
||||
"non-empty string");
|
||||
return;
|
||||
}
|
||||
ElectronWebAuthenticationDelegate::SetTouchIdKeychainAccessGroup(
|
||||
std::move(keychain_access_group));
|
||||
}
|
||||
}
|
||||
|
||||
int DockBounce(gin::Arguments* args) {
|
||||
int request_id = -1;
|
||||
std::string type = "informational";
|
||||
@@ -1917,7 +1893,6 @@ gin::ObjectTemplateBuilder App::GetObjectTemplateBuilder(v8::Isolate* isolate) {
|
||||
.SetMethod("moveToApplicationsFolder", &App::MoveToApplicationsFolder)
|
||||
.SetMethod("isInApplicationsFolder", &App::IsInApplicationsFolder)
|
||||
.SetMethod("setActivationPolicy", &App::SetActivationPolicy)
|
||||
.SetMethod("configureWebAuthn", &App::ConfigureWebAuthn)
|
||||
#endif
|
||||
.SetMethod("setAboutPanelOptions",
|
||||
base::BindRepeating(&Browser::SetAboutPanelOptions, browser))
|
||||
|
||||
@@ -244,8 +244,6 @@ class App final : public gin::Wrappable<App>,
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
void SetActivationPolicy(gin_helper::ErrorThrower thrower,
|
||||
const std::string& policy);
|
||||
void ConfigureWebAuthn(gin_helper::ErrorThrower thrower,
|
||||
gin::Arguments* args);
|
||||
bool MoveToApplicationsFolder(gin_helper::ErrorThrower, gin::Arguments* args);
|
||||
bool IsInApplicationsFolder();
|
||||
v8::Local<v8::Value> GetDockAPI(v8::Isolate* isolate);
|
||||
|
||||
@@ -121,18 +121,6 @@ std::u16string Menu::GetLabelForCommandId(int command_id) const {
|
||||
return label;
|
||||
}
|
||||
|
||||
std::u16string Menu::GetAccessibilityLabelForCommandId(int command_id) const {
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::Local<v8::Value> val =
|
||||
gin_helper::CallMethod(isolate, const_cast<Menu*>(this),
|
||||
"_getAccessibilityLabelForCommandId", command_id);
|
||||
std::u16string label;
|
||||
if (!gin::ConvertFromV8(isolate, val, &label))
|
||||
label.clear();
|
||||
return label;
|
||||
}
|
||||
|
||||
std::u16string Menu::GetSecondaryLabelForCommandId(int command_id) const {
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
|
||||
@@ -74,8 +74,6 @@ class Menu : public gin::Wrappable<Menu>,
|
||||
bool IsCommandIdEnabled(int command_id) const override;
|
||||
bool IsCommandIdVisible(int command_id) const override;
|
||||
std::u16string GetLabelForCommandId(int command_id) const override;
|
||||
std::u16string GetAccessibilityLabelForCommandId(
|
||||
int command_id) const override;
|
||||
std::u16string GetSecondaryLabelForCommandId(int command_id) const override;
|
||||
ui::ImageModel GetIconForCommandId(int command_id) const override;
|
||||
bool ShouldCommandIdWorkWhenHidden(int command_id) const override;
|
||||
|
||||
@@ -18,16 +18,13 @@
|
||||
#include "content/browser/network_service_instance_impl.h" // nogncheck
|
||||
#include "content/public/browser/child_process_host.h"
|
||||
#include "content/public/browser/service_process_host.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "content/public/common/result_codes.h"
|
||||
#include "gin/object_template_builder.h"
|
||||
#include "gin/persistent.h"
|
||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
|
||||
#include "services/network/public/cpp/originating_process_id.h"
|
||||
#include "shell/browser/api/electron_api_session.h"
|
||||
#include "shell/browser/api/message_port.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/electron_browser_context.h"
|
||||
#include "shell/browser/electron_child_process_host_flags.h"
|
||||
#include "shell/browser/javascript_environment.h"
|
||||
#include "shell/browser/net/system_network_context_manager.h"
|
||||
@@ -95,9 +92,8 @@ UtilityProcessWrapper::UtilityProcessWrapper(
|
||||
base::FilePath current_working_directory,
|
||||
bool use_plugin_helper,
|
||||
bool create_network_observer,
|
||||
bool disclaim_responsibility,
|
||||
Session* session)
|
||||
: create_network_observer_(create_network_observer), session_(session) {
|
||||
bool disclaim_responsibility)
|
||||
: create_network_observer_(create_network_observer) {
|
||||
auto& allocation_handle =
|
||||
JavascriptEnvironment::GetIsolate()->GetCppHeap()->GetAllocationHandle();
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
@@ -455,7 +451,6 @@ UtilityProcessWrapper::CreateURLLoaderFactoryParams() {
|
||||
node::mojom::URLLoaderFactoryParamsPtr params =
|
||||
node::mojom::URLLoaderFactoryParams::New();
|
||||
mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory;
|
||||
network::mojom::NetworkContext* network_context;
|
||||
network::mojom::URLLoaderFactoryParamsPtr loader_params =
|
||||
network::mojom::URLLoaderFactoryParams::New();
|
||||
loader_params->process_id = network::OriginatingProcessId::browser();
|
||||
@@ -467,27 +462,11 @@ UtilityProcessWrapper::CreateURLLoaderFactoryParams() {
|
||||
url_loader_network_observer_->Bind();
|
||||
}
|
||||
|
||||
if (session_) {
|
||||
auto* browser_context = session_->browser_context();
|
||||
network_context =
|
||||
browser_context->GetDefaultStoragePartition()->GetNetworkContext();
|
||||
// Build a factory through CreateURLLoaderFactoryBuilder so requests go
|
||||
// through ProxyingURLLoaderFactory (enabling webRequest interception).
|
||||
auto [factory_builder, header_client] =
|
||||
browser_context->CreateURLLoaderFactoryBuilder();
|
||||
loader_params->header_client = std::move(header_client);
|
||||
url_loader_factory =
|
||||
std::move(factory_builder)
|
||||
.Finish<mojo::PendingRemote<network::mojom::URLLoaderFactory>>(
|
||||
network_context, std::move(loader_params));
|
||||
} else {
|
||||
network_context =
|
||||
g_browser_process->system_network_context_manager()->GetContext();
|
||||
network_context->CreateURLLoaderFactory(
|
||||
url_loader_factory.InitWithNewPipeAndPassReceiver(),
|
||||
std::move(loader_params));
|
||||
}
|
||||
|
||||
network::mojom::NetworkContext* network_context =
|
||||
g_browser_process->system_network_context_manager()->GetContext();
|
||||
network_context->CreateURLLoaderFactory(
|
||||
url_loader_factory.InitWithNewPipeAndPassReceiver(),
|
||||
std::move(loader_params));
|
||||
params->url_loader_factory = std::move(url_loader_factory);
|
||||
mojo::PendingRemote<network::mojom::HostResolver> host_resolver;
|
||||
network_context->CreateHostResolver(
|
||||
@@ -524,7 +503,6 @@ UtilityProcessWrapper* UtilityProcessWrapper::Create(
|
||||
bool use_plugin_helper = false;
|
||||
bool create_network_observer = false;
|
||||
bool disclaim_responsibility = false;
|
||||
api::Session* session = nullptr;
|
||||
std::map<IOHandle, IOType> stdio;
|
||||
base::FilePath current_working_directory;
|
||||
base::EnvironmentMap env_map;
|
||||
@@ -570,19 +548,12 @@ UtilityProcessWrapper* UtilityProcessWrapper::Create(
|
||||
opts.Get("allowLoadingUnsignedLibraries", &use_plugin_helper);
|
||||
opts.Get("disclaim", &disclaim_responsibility);
|
||||
#endif
|
||||
|
||||
std::string partition;
|
||||
if (opts.Get("session", &session) && session) {
|
||||
} else if (opts.Get("partition", &partition)) {
|
||||
session = Session::FromPartition(args->isolate(), partition);
|
||||
}
|
||||
}
|
||||
v8::Isolate* isolate = args->isolate();
|
||||
return cppgc::MakeGarbageCollected<UtilityProcessWrapper>(
|
||||
isolate->GetCppHeap()->GetAllocationHandle(), std::move(params),
|
||||
display_name, std::move(stdio), env_map, current_working_directory,
|
||||
use_plugin_helper, create_network_observer, disclaim_responsibility,
|
||||
session);
|
||||
use_plugin_helper, create_network_observer, disclaim_responsibility);
|
||||
}
|
||||
|
||||
gin::ObjectTemplateBuilder UtilityProcessWrapper::GetObjectTemplateBuilder(
|
||||
@@ -596,7 +567,6 @@ gin::ObjectTemplateBuilder UtilityProcessWrapper::GetObjectTemplateBuilder(
|
||||
|
||||
void UtilityProcessWrapper::Trace(cppgc::Visitor* visitor) const {
|
||||
gin::Wrappable<UtilityProcessWrapper>::Trace(visitor);
|
||||
visitor->Trace(session_);
|
||||
visitor->Trace(weak_factory_);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,8 +38,6 @@ class Connector;
|
||||
|
||||
namespace electron::api {
|
||||
|
||||
class Session;
|
||||
|
||||
class UtilityProcessWrapper final
|
||||
: public gin::Wrappable<UtilityProcessWrapper>,
|
||||
public gin_helper::EventEmitterMixin<UtilityProcessWrapper>,
|
||||
@@ -57,8 +55,7 @@ class UtilityProcessWrapper final
|
||||
base::FilePath current_working_directory,
|
||||
bool use_plugin_helper,
|
||||
bool create_network_observer,
|
||||
bool disclaim_responsibility,
|
||||
Session* session);
|
||||
bool disclaim_responsibility);
|
||||
~UtilityProcessWrapper() override;
|
||||
|
||||
static UtilityProcessWrapper* Create(gin::Arguments* args);
|
||||
@@ -66,8 +63,6 @@ class UtilityProcessWrapper final
|
||||
|
||||
void Shutdown(uint32_t exit_code);
|
||||
|
||||
bool has_session() const { return session_.Get(); }
|
||||
|
||||
// gin::Wrappable
|
||||
static const gin::WrapperInfo kWrapperInfo;
|
||||
static const char* GetClassName() { return "UtilityProcess"; }
|
||||
@@ -131,7 +126,6 @@ class UtilityProcessWrapper final
|
||||
GC_PLUGIN_IGNORE(
|
||||
"Context tracking of remote is not needed in the browser process.")
|
||||
mojo::Remote<node::mojom::NodeService> node_service_remote_;
|
||||
cppgc::Member<Session> session_;
|
||||
std::optional<electron::URLLoaderNetworkObserver>
|
||||
url_loader_network_observer_;
|
||||
base::CallbackListSubscription network_service_gone_subscription_;
|
||||
|
||||
@@ -517,21 +517,6 @@ void View::ApplyBorderRadius() {
|
||||
}
|
||||
}
|
||||
|
||||
void View::SetBackgroundBlur(int blur_radius) {
|
||||
if (!view_)
|
||||
return;
|
||||
|
||||
if (blur_radius < 0)
|
||||
blur_radius = 0;
|
||||
|
||||
ui::Layer* layer = GetLayer();
|
||||
|
||||
if (!layer)
|
||||
return;
|
||||
|
||||
layer->SetBackgroundBlur(blur_radius);
|
||||
}
|
||||
|
||||
void View::SetVisible(bool visible) {
|
||||
if (!view_)
|
||||
return;
|
||||
@@ -599,7 +584,6 @@ void View::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("getBounds", &View::GetBounds)
|
||||
.SetMethod("setBackgroundColor", &View::SetBackgroundColor)
|
||||
.SetMethod("setBorderRadius", &View::SetBorderRadius)
|
||||
.SetMethod("setBackgroundBlur", &View::SetBackgroundBlur)
|
||||
.SetMethod("setLayout", &View::SetLayout)
|
||||
.SetMethod("setVisible", &View::SetVisible)
|
||||
.SetMethod("getVisible", &View::GetVisible);
|
||||
|
||||
@@ -43,7 +43,6 @@ class View : public gin_helper::EventEmitter<View>,
|
||||
std::vector<v8::Local<v8::Value>> GetChildren();
|
||||
void SetBackgroundColor(std::optional<WrappedSkColor> color);
|
||||
void SetBorderRadius(int radius);
|
||||
void SetBackgroundBlur(int blur_radius);
|
||||
void SetVisible(bool visible);
|
||||
bool GetVisible() const;
|
||||
|
||||
|
||||
@@ -115,7 +115,6 @@
|
||||
#include "shell/browser/usb/electron_usb_delegate.h"
|
||||
#include "shell/browser/web_contents_permission_helper.h"
|
||||
#include "shell/browser/web_contents_preferences.h"
|
||||
#include "shell/browser/webauthn/electron_authenticator_request_client_delegate.h"
|
||||
#include "shell/browser/webauthn/electron_authenticator_request_delegate.h"
|
||||
#include "shell/browser/window_list.h"
|
||||
#include "shell/common/api/api.mojom.h"
|
||||
@@ -1128,7 +1127,6 @@ void ElectronBrowserClient::
|
||||
RegisterNonNetworkWorkerMainResourceURLLoaderFactories(
|
||||
content::BrowserContext* browser_context,
|
||||
const std::optional<url::Origin>& request_initiator,
|
||||
network::mojom::RequestDestination request_destination,
|
||||
NonNetworkURLLoaderFactoryMap* factories) {
|
||||
auto* protocol_registry =
|
||||
ProtocolRegistry::FromBrowserContext(browser_context);
|
||||
@@ -1926,13 +1924,4 @@ ElectronBrowserClient::GetWebAuthenticationDelegate() {
|
||||
return web_authentication_delegate_.get();
|
||||
}
|
||||
|
||||
#if !BUILDFLAG(IS_ANDROID)
|
||||
std::unique_ptr<content::AuthenticatorRequestClientDelegate>
|
||||
ElectronBrowserClient::GetWebAuthenticationRequestDelegate(
|
||||
content::RenderFrameHost* render_frame_host) {
|
||||
return std::make_unique<ElectronAuthenticatorRequestClientDelegate>(
|
||||
render_frame_host);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace electron
|
||||
|
||||
@@ -127,11 +127,6 @@ class ElectronBrowserClient : public content::ContentBrowserClient,
|
||||
content::UsbDelegate* GetUsbDelegate() override;
|
||||
|
||||
content::WebAuthenticationDelegate* GetWebAuthenticationDelegate() override;
|
||||
#if !BUILDFLAG(IS_ANDROID)
|
||||
std::unique_ptr<content::AuthenticatorRequestClientDelegate>
|
||||
GetWebAuthenticationRequestDelegate(
|
||||
content::RenderFrameHost* render_frame_host) override;
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
std::string GetChildProcessSuffix(int child_flags) override;
|
||||
@@ -231,7 +226,6 @@ class ElectronBrowserClient : public content::ContentBrowserClient,
|
||||
void RegisterNonNetworkWorkerMainResourceURLLoaderFactories(
|
||||
content::BrowserContext* browser_context,
|
||||
const std::optional<url::Origin>& request_initiator,
|
||||
network::mojom::RequestDestination request_destination,
|
||||
NonNetworkURLLoaderFactoryMap* factories) override;
|
||||
void RegisterNonNetworkSubresourceURLLoaderFactories(
|
||||
int render_process_id,
|
||||
|
||||
@@ -502,11 +502,6 @@ void ElectronBrowserContext::InitPrefs() {
|
||||
// Unique uuid for global shortcuts.
|
||||
registry->RegisterStringPref(electron::kElectronGlobalShortcutsUuid,
|
||||
std::string());
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
registry->RegisterStringPref(electron::kWebAuthnTouchIdMetadataSecretPrefName,
|
||||
std::string());
|
||||
#endif
|
||||
}
|
||||
|
||||
void ElectronBrowserContext::SetUserAgent(const std::string& user_agent) {
|
||||
|
||||
@@ -98,10 +98,6 @@ class ElectronBrowserContext : public content::BrowserContext {
|
||||
scoped_refptr<network::SharedURLLoaderFactory> InterceptURLLoaderFactory(
|
||||
scoped_refptr<network::SharedURLLoaderFactory> factory);
|
||||
|
||||
std::pair<network::URLLoaderFactoryBuilder,
|
||||
mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>>
|
||||
CreateURLLoaderFactoryBuilder();
|
||||
|
||||
std::string GetMediaDeviceIDSalt();
|
||||
|
||||
// content::BrowserContext:
|
||||
@@ -191,6 +187,10 @@ class ElectronBrowserContext : public content::BrowserContext {
|
||||
content::MediaResponseCallback callback,
|
||||
gin::Arguments* args);
|
||||
|
||||
std::pair<network::URLLoaderFactoryBuilder,
|
||||
mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>>
|
||||
CreateURLLoaderFactoryBuilder();
|
||||
|
||||
// Initialize pref registry.
|
||||
void InitPrefs();
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ function_registration("api_registration") {
|
||||
"//electron/shell/common/extensions/api/action.json",
|
||||
"//electron/shell/common/extensions/api/extension.json",
|
||||
"//electron/shell/common/extensions/api/resources_private.idl",
|
||||
"//electron/shell/common/extensions/api/scripting.idl",
|
||||
"//electron/shell/common/extensions/api/tabs.json",
|
||||
]
|
||||
|
||||
|
||||
1201
shell/browser/extensions/api/scripting/scripting_api.cc
Normal file
1201
shell/browser/extensions/api/scripting/scripting_api.cc
Normal file
File diff suppressed because it is too large
Load Diff
203
shell/browser/extensions/api/scripting/scripting_api.h
Normal file
203
shell/browser/extensions/api/scripting/scripting_api.h
Normal file
@@ -0,0 +1,203 @@
|
||||
// Copyright 2023 Microsoft, GmbH
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ELECTRON_SHELL_BROWSER_EXTENSIONS_API_SCRIPTING_SCRIPTING_API_H_
|
||||
#define ELECTRON_SHELL_BROWSER_EXTENSIONS_API_SCRIPTING_SCRIPTING_API_H_
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "extensions/browser/extension_function.h"
|
||||
#include "extensions/browser/script_executor.h"
|
||||
#include "extensions/browser/scripting_utils.h"
|
||||
#include "extensions/common/api/scripting.h"
|
||||
#include "extensions/common/mojom/code_injection.mojom.h"
|
||||
#include "extensions/common/user_script.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
class ScriptingExecuteScriptFunction : public ExtensionFunction {
|
||||
public:
|
||||
DECLARE_EXTENSION_FUNCTION("scripting.executeScript", SCRIPTING_EXECUTESCRIPT)
|
||||
|
||||
ScriptingExecuteScriptFunction();
|
||||
ScriptingExecuteScriptFunction(const ScriptingExecuteScriptFunction&) =
|
||||
delete;
|
||||
ScriptingExecuteScriptFunction& operator=(
|
||||
const ScriptingExecuteScriptFunction&) = delete;
|
||||
|
||||
// ExtensionFunction:
|
||||
ResponseAction Run() override;
|
||||
|
||||
private:
|
||||
~ScriptingExecuteScriptFunction() override;
|
||||
|
||||
// Called when the resource files to be injected has been loaded.
|
||||
void DidLoadResources(std::vector<scripting::InjectedFileSource> file_sources,
|
||||
std::optional<std::string> load_error);
|
||||
|
||||
// Triggers the execution of `sources` in the appropriate context.
|
||||
// Returns true on success; on failure, populates `error`.
|
||||
bool Execute(std::vector<mojom::JSSourcePtr> sources, std::string* error);
|
||||
|
||||
// Invoked when script execution is complete.
|
||||
void OnScriptExecuted(std::vector<ScriptExecutor::FrameResult> frame_results);
|
||||
|
||||
api::scripting::ScriptInjection injection_;
|
||||
};
|
||||
|
||||
class ScriptingInsertCSSFunction : public ExtensionFunction {
|
||||
public:
|
||||
DECLARE_EXTENSION_FUNCTION("scripting.insertCSS", SCRIPTING_INSERTCSS)
|
||||
|
||||
ScriptingInsertCSSFunction();
|
||||
ScriptingInsertCSSFunction(const ScriptingInsertCSSFunction&) = delete;
|
||||
ScriptingInsertCSSFunction& operator=(const ScriptingInsertCSSFunction&) =
|
||||
delete;
|
||||
|
||||
// ExtensionFunction:
|
||||
ResponseAction Run() override;
|
||||
|
||||
private:
|
||||
~ScriptingInsertCSSFunction() override;
|
||||
|
||||
// Called when the resource files to be injected has been loaded.
|
||||
void DidLoadResources(std::vector<scripting::InjectedFileSource> file_sources,
|
||||
std::optional<std::string> load_error);
|
||||
|
||||
// Triggers the execution of `sources` in the appropriate context.
|
||||
// Returns true on success; on failure, populates `error`.
|
||||
bool Execute(std::vector<mojom::CSSSourcePtr> sources, std::string* error);
|
||||
|
||||
// Called when the CSS insertion is complete.
|
||||
void OnCSSInserted(std::vector<ScriptExecutor::FrameResult> results);
|
||||
|
||||
api::scripting::CSSInjection injection_;
|
||||
};
|
||||
|
||||
class ScriptingRemoveCSSFunction : public ExtensionFunction {
|
||||
public:
|
||||
DECLARE_EXTENSION_FUNCTION("scripting.removeCSS", SCRIPTING_REMOVECSS)
|
||||
|
||||
ScriptingRemoveCSSFunction();
|
||||
ScriptingRemoveCSSFunction(const ScriptingRemoveCSSFunction&) = delete;
|
||||
ScriptingRemoveCSSFunction& operator=(const ScriptingRemoveCSSFunction&) =
|
||||
delete;
|
||||
|
||||
// ExtensionFunction:
|
||||
ResponseAction Run() override;
|
||||
|
||||
private:
|
||||
~ScriptingRemoveCSSFunction() override;
|
||||
|
||||
// Called when the CSS removal is complete.
|
||||
void OnCSSRemoved(std::vector<ScriptExecutor::FrameResult> results);
|
||||
};
|
||||
|
||||
class ScriptingRegisterContentScriptsFunction : public ExtensionFunction {
|
||||
public:
|
||||
DECLARE_EXTENSION_FUNCTION("scripting.registerContentScripts",
|
||||
SCRIPTING_REGISTERCONTENTSCRIPTS)
|
||||
|
||||
ScriptingRegisterContentScriptsFunction();
|
||||
ScriptingRegisterContentScriptsFunction(
|
||||
const ScriptingRegisterContentScriptsFunction&) = delete;
|
||||
ScriptingRegisterContentScriptsFunction& operator=(
|
||||
const ScriptingRegisterContentScriptsFunction&) = delete;
|
||||
|
||||
// ExtensionFunction:
|
||||
ResponseAction Run() override;
|
||||
|
||||
private:
|
||||
~ScriptingRegisterContentScriptsFunction() override;
|
||||
|
||||
// Called when script files have been checked.
|
||||
void OnContentScriptFilesValidated(
|
||||
std::set<std::string> persistent_script_ids,
|
||||
scripting::ValidateScriptsResult result);
|
||||
|
||||
// Called when content scripts have been registered.
|
||||
void OnContentScriptsRegistered(const std::optional<std::string>& error);
|
||||
};
|
||||
|
||||
class ScriptingGetRegisteredContentScriptsFunction : public ExtensionFunction {
|
||||
public:
|
||||
DECLARE_EXTENSION_FUNCTION("scripting.getRegisteredContentScripts",
|
||||
SCRIPTING_GETREGISTEREDCONTENTSCRIPTS)
|
||||
|
||||
ScriptingGetRegisteredContentScriptsFunction();
|
||||
ScriptingGetRegisteredContentScriptsFunction(
|
||||
const ScriptingGetRegisteredContentScriptsFunction&) = delete;
|
||||
ScriptingGetRegisteredContentScriptsFunction& operator=(
|
||||
const ScriptingGetRegisteredContentScriptsFunction&) = delete;
|
||||
|
||||
// ExtensionFunction:
|
||||
ResponseAction Run() override;
|
||||
|
||||
private:
|
||||
~ScriptingGetRegisteredContentScriptsFunction() override;
|
||||
};
|
||||
|
||||
class ScriptingUnregisterContentScriptsFunction : public ExtensionFunction {
|
||||
public:
|
||||
DECLARE_EXTENSION_FUNCTION("scripting.unregisterContentScripts",
|
||||
SCRIPTING_UNREGISTERCONTENTSCRIPTS)
|
||||
|
||||
ScriptingUnregisterContentScriptsFunction();
|
||||
ScriptingUnregisterContentScriptsFunction(
|
||||
const ScriptingUnregisterContentScriptsFunction&) = delete;
|
||||
ScriptingUnregisterContentScriptsFunction& operator=(
|
||||
const ScriptingUnregisterContentScriptsFunction&) = delete;
|
||||
|
||||
// ExtensionFunction:
|
||||
ResponseAction Run() override;
|
||||
|
||||
private:
|
||||
~ScriptingUnregisterContentScriptsFunction() override;
|
||||
|
||||
// Called when content scripts have been unregistered.
|
||||
void OnContentScriptsUnregistered(const std::optional<std::string>& error);
|
||||
};
|
||||
|
||||
class ScriptingUpdateContentScriptsFunction : public ExtensionFunction {
|
||||
public:
|
||||
DECLARE_EXTENSION_FUNCTION("scripting.updateContentScripts",
|
||||
SCRIPTING_UPDATECONTENTSCRIPTS)
|
||||
|
||||
ScriptingUpdateContentScriptsFunction();
|
||||
ScriptingUpdateContentScriptsFunction(
|
||||
const ScriptingUpdateContentScriptsFunction&) = delete;
|
||||
ScriptingUpdateContentScriptsFunction& operator=(
|
||||
const ScriptingUpdateContentScriptsFunction&) = delete;
|
||||
|
||||
// ExtensionFunction:
|
||||
ResponseAction Run() override;
|
||||
|
||||
private:
|
||||
~ScriptingUpdateContentScriptsFunction() override;
|
||||
|
||||
// Returns a UserScript object by updating the `original_script` with the
|
||||
// `new_script` given delta. If the updated script cannot be parsed, populates
|
||||
// `parse_error` and returns nullptr.
|
||||
std::unique_ptr<UserScript> ApplyUpdate(
|
||||
std::set<std::string>* script_ids_to_persist,
|
||||
api::scripting::RegisteredContentScript& new_script,
|
||||
api::scripting::RegisteredContentScript& original_script,
|
||||
std::u16string* parse_error);
|
||||
|
||||
// Called when script files have been checked.
|
||||
void OnContentScriptFilesValidated(
|
||||
std::set<std::string> persistent_script_ids,
|
||||
scripting::ValidateScriptsResult result);
|
||||
|
||||
// Called when content scripts have been updated.
|
||||
void OnContentScriptsUpdated(const std::optional<std::string>& error);
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
||||
#endif // ELECTRON_SHELL_BROWSER_EXTENSIONS_API_SCRIPTING_SCRIPTING_API_H_
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "extensions/browser/extension_function_registry.h"
|
||||
#include "shell/browser/extensions/api/extension_action/extension_action_api.h"
|
||||
#include "shell/browser/extensions/api/generated_api_registration.h"
|
||||
#include "shell/browser/extensions/api/scripting/scripting_api.h"
|
||||
#include "shell/browser/extensions/api/tabs/tabs_api.h"
|
||||
|
||||
namespace extensions {
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include "extensions/common/manifest_handlers/devtools_page_handler.h"
|
||||
#include "extensions/common/manifest_url_handlers.h"
|
||||
#include "services/network/public/mojom/url_loader.mojom.h"
|
||||
#include "shell/browser/api/electron_api_web_contents.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/electron_browser_client.h"
|
||||
#include "shell/browser/electron_browser_context.h"
|
||||
@@ -43,7 +42,6 @@
|
||||
#include "shell/browser/extensions/electron_component_extension_resource_manager.h"
|
||||
#include "shell/browser/extensions/electron_extension_host_delegate.h"
|
||||
#include "shell/browser/extensions/electron_extension_system_factory.h"
|
||||
#include "shell/browser/extensions/electron_extension_tab_util.h"
|
||||
#include "shell/browser/extensions/electron_extension_web_contents_observer.h"
|
||||
#include "shell/browser/extensions/electron_extensions_api_client.h"
|
||||
#include "shell/browser/extensions/electron_extensions_browser_api_provider.h"
|
||||
@@ -383,28 +381,6 @@ ElectronExtensionsBrowserClient::GetExtensionWebContentsObserver(
|
||||
web_contents);
|
||||
}
|
||||
|
||||
bool ElectronExtensionsBrowserClient::IsValidTabId(
|
||||
content::BrowserContext* browser_context,
|
||||
const int tab_id,
|
||||
const bool include_incognito,
|
||||
content::WebContents** web_contents) const {
|
||||
auto* contents = extensions::GetElectronTabById(tab_id, browser_context);
|
||||
if (!contents)
|
||||
return false;
|
||||
|
||||
if (web_contents)
|
||||
*web_contents = contents->web_contents();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
extensions::ScriptExecutor*
|
||||
ElectronExtensionsBrowserClient::GetScriptExecutorForTab(
|
||||
content::WebContents& web_contents) {
|
||||
auto* contents = electron::api::WebContents::From(&web_contents);
|
||||
return contents ? contents->script_executor() : nullptr;
|
||||
}
|
||||
|
||||
extensions::KioskDelegate* ElectronExtensionsBrowserClient::GetKioskDelegate() {
|
||||
if (!kiosk_delegate_)
|
||||
kiosk_delegate_ = std::make_unique<ElectronKioskDelegate>();
|
||||
|
||||
@@ -139,12 +139,6 @@ class ElectronExtensionsBrowserClient
|
||||
content::WebContents* web_contents) override;
|
||||
extensions::ExtensionWebContentsObserver* GetExtensionWebContentsObserver(
|
||||
content::WebContents* web_contents) override;
|
||||
bool IsValidTabId(content::BrowserContext* browser_context,
|
||||
int tab_id,
|
||||
bool include_incognito,
|
||||
content::WebContents** web_contents) const override;
|
||||
extensions::ScriptExecutor* GetScriptExecutorForTab(
|
||||
content::WebContents& web_contents) override;
|
||||
extensions::KioskDelegate* GetKioskDelegate() override;
|
||||
std::string GetApplicationLocale() override;
|
||||
void RegisterBrowserInterfaceBindersForFrame(
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "gin/arguments.h"
|
||||
#include "gin/dictionary.h"
|
||||
#include "shell/browser/api/electron_api_app.h"
|
||||
#include "shell/browser/api/electron_api_utility_process.h"
|
||||
#include "shell/browser/api/electron_api_web_contents.h"
|
||||
#include "shell/browser/javascript_environment.h"
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
@@ -101,17 +100,6 @@ void LoginHandler::EmitEvent(
|
||||
api_web_contents->Emit("login", std::move(details), auth_info,
|
||||
base::BindOnce(&LoginHandler::CallbackFromJS,
|
||||
weak_factory_.GetWeakPtr()));
|
||||
} else if (auto* utility_process =
|
||||
api::UtilityProcessWrapper::FromProcessId(process_id);
|
||||
utility_process && utility_process->has_session()) {
|
||||
// Route auth to the utility process wrapper when the request originated
|
||||
// from a utility process with a session and
|
||||
// respondToAuthRequestsFromMainProcess. Without a session, auth falls
|
||||
// through to app.on('login') for backward compatibility.
|
||||
default_prevented =
|
||||
utility_process->Emit("login", std::move(details), auth_info,
|
||||
base::BindOnce(&LoginHandler::CallbackFromJS,
|
||||
weak_factory_.GetWeakPtr()));
|
||||
} else {
|
||||
default_prevented =
|
||||
api::App::Get()->Emit("login", nullptr, std::move(details), auth_info,
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "shell/browser/background_throttling_source.h"
|
||||
#include "shell/browser/browser.h"
|
||||
#include "shell/browser/draggable_region_provider.h"
|
||||
#include "shell/browser/native_window_features.h"
|
||||
#include "shell/browser/ui/drag_util.h"
|
||||
#include "shell/browser/window_list.h"
|
||||
#include "shell/common/color_util.h"
|
||||
@@ -28,7 +29,6 @@
|
||||
|
||||
#if !BUILDFLAG(IS_MAC)
|
||||
#include "shell/browser/ui/views/frameless_view.h"
|
||||
#include "ui/views/view_utils.h"
|
||||
#endif
|
||||
|
||||
#if defined(USE_OZONE)
|
||||
@@ -649,13 +649,11 @@ int NativeWindow::NonClientHitTest(const gfx::Point& point) {
|
||||
#if !BUILDFLAG(IS_MAC)
|
||||
// We need to ensure we account for resizing borders on Windows and Linux.
|
||||
if ((!has_frame() || has_client_frame()) && IsResizable()) {
|
||||
auto* frame = views::AsViewClass<FramelessView>(
|
||||
widget()->non_client_view()->frame_view());
|
||||
if (frame) {
|
||||
int border_hit = frame->ResizingBorderHitTest(point);
|
||||
if (border_hit != HTNOWHERE)
|
||||
return border_hit;
|
||||
}
|
||||
auto* frame =
|
||||
static_cast<FramelessView*>(widget()->non_client_view()->frame_view());
|
||||
int border_hit = frame->ResizingBorderHitTest(point);
|
||||
if (border_hit != HTNOWHERE)
|
||||
return border_hit;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -782,6 +780,7 @@ bool NativeWindow::PlatformHasClientFrame() {
|
||||
// Ozone X11 likes to prefer custom frames,
|
||||
// but we don't need them unless on Wayland.
|
||||
static const bool has_client_frame =
|
||||
base::FeatureList::IsEnabled(features::kWaylandWindowDecorations) &&
|
||||
!ui::OzonePlatform::GetInstance()
|
||||
->GetPlatformRuntimeProperties()
|
||||
.supports_server_side_window_decorations;
|
||||
|
||||
11
shell/browser/native_window_features.cc
Normal file
11
shell/browser/native_window_features.cc
Normal file
@@ -0,0 +1,11 @@
|
||||
// Copyright (c) 2022 Slack Technologies, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/native_window_features.h"
|
||||
|
||||
namespace features {
|
||||
BASE_FEATURE(kWaylandWindowDecorations,
|
||||
"WaylandWindowDecorations",
|
||||
base::FEATURE_ENABLED_BY_DEFAULT);
|
||||
}
|
||||
14
shell/browser/native_window_features.h
Normal file
14
shell/browser/native_window_features.h
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright (c) 2022 Slack Technologies, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ELECTRON_SHELL_BROWSER_NATIVE_WINDOW_FEATURES_H_
|
||||
#define ELECTRON_SHELL_BROWSER_NATIVE_WINDOW_FEATURES_H_
|
||||
|
||||
#include "base/feature_list.h"
|
||||
|
||||
namespace features {
|
||||
extern const base::Feature kWaylandWindowDecorations;
|
||||
}
|
||||
|
||||
#endif // ELECTRON_SHELL_BROWSER_NATIVE_WINDOW_FEATURES_H_
|
||||
@@ -64,15 +64,12 @@
|
||||
#include "shell/browser/linux/unity_service.h"
|
||||
#include "shell/browser/linux/x11_util.h"
|
||||
#include "shell/browser/ui/electron_desktop_window_tree_host_linux.h"
|
||||
#include "shell/browser/ui/views/client_frame_view_linux.h"
|
||||
#include "shell/browser/ui/views/linux_frame_layout.h"
|
||||
#include "shell/browser/ui/views/native_frame_view.h"
|
||||
#include "shell/browser/ui/views/native_frame_view_linux.h"
|
||||
#include "shell/browser/ui/views/opaque_frame_view.h"
|
||||
#include "shell/common/platform_util.h"
|
||||
#include "ui/linux/linux_ui.h"
|
||||
#include "ui/linux/linux_ui_factory.h"
|
||||
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
|
||||
#include "ui/views/window/frame_view_linux.h"
|
||||
#include "ui/views/window/native_frame_view.h"
|
||||
|
||||
#if BUILDFLAG(SUPPORTS_OZONE_X11)
|
||||
@@ -511,10 +508,9 @@ void NativeWindowViews::SetTitleBarOverlay(
|
||||
|
||||
// If anything was updated, ensure the overlay is repainted.
|
||||
if (updated) {
|
||||
auto* fv = widget()->non_client_view()->frame_view();
|
||||
if (auto* frameless = views::AsViewClass<FramelessView>(fv)) {
|
||||
frameless->InvalidateCaptionButtons();
|
||||
}
|
||||
auto* frame_view =
|
||||
static_cast<FramelessView*>(widget()->non_client_view()->frame_view());
|
||||
frame_view->InvalidateCaptionButtons();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1287,11 +1283,9 @@ void NativeWindowViews::SetBackgroundColor(SkColor background_color) {
|
||||
SkColor compositor_color = background_color;
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
// Widget background needs to stay transparent for CSD shadow regions.
|
||||
auto* fvl = GetFrameViewLinux();
|
||||
LinuxFrameLayout* frame_layout = GetLinuxFrameLayout();
|
||||
const bool uses_csd =
|
||||
(fvl && fvl->ShouldDrawRestoredFrameShadow()) ||
|
||||
(frame_layout && frame_layout->SupportsClientFrameShadow());
|
||||
frame_layout && frame_layout->SupportsClientFrameShadow();
|
||||
if (transparent() || uses_csd)
|
||||
compositor_color = SK_ColorTRANSPARENT;
|
||||
#endif
|
||||
@@ -1516,13 +1510,9 @@ gfx::Insets NativeWindowViews::GetRestoredFrameBorderInsets() const {
|
||||
if (!frame_view)
|
||||
return gfx::Insets();
|
||||
|
||||
if (auto* frameless = views::AsViewClass<FramelessView>(frame_view))
|
||||
if (auto* frameless = views::AsViewClass<FramelessView>(frame_view)) {
|
||||
return frameless->RestoredFrameBorderInsets();
|
||||
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
if (auto* fvl = views::AsViewClass<views::FrameViewLinux>(frame_view))
|
||||
return fvl->GetRestoredFrameBorderInsets();
|
||||
#endif
|
||||
}
|
||||
|
||||
return gfx::Insets();
|
||||
}
|
||||
@@ -1935,21 +1925,8 @@ std::unique_ptr<views::FrameView> NativeWindowViews::CreateFrameView(
|
||||
if (!has_frame())
|
||||
return std::make_unique<OpaqueFrameView>(this, widget);
|
||||
|
||||
if (has_client_frame()) {
|
||||
auto* linux_ui_theme = ui::LinuxUiTheme::GetForProfile(nullptr);
|
||||
auto getter = base::BindRepeating(
|
||||
[](ui::LinuxUiTheme* theme, bool tiled,
|
||||
bool maximized) -> ui::WindowFrameProvider* {
|
||||
return theme->GetWindowFrameProvider(ui::FrameType::kDefault,
|
||||
/*solid_frame=*/false, tiled,
|
||||
maximized);
|
||||
},
|
||||
base::Unretained(linux_ui_theme));
|
||||
auto nav_button_provider =
|
||||
linux_ui_theme->CreateNavButtonProvider(ui::FrameType::kDefault);
|
||||
return std::make_unique<NativeFrameViewLinux>(
|
||||
this, widget, std::move(nav_button_provider), std::move(getter));
|
||||
}
|
||||
if (has_client_frame())
|
||||
return std::make_unique<ClientFrameViewLinux>(this, widget);
|
||||
|
||||
return std::make_unique<NativeFrameView>(this, widget);
|
||||
#endif
|
||||
@@ -1963,13 +1940,6 @@ LinuxFrameLayout* NativeWindowViews::GetLinuxFrameLayout() {
|
||||
auto* view = views::AsViewClass<FramelessView>(ncv->frame_view());
|
||||
return view ? view->GetLinuxFrameLayout() : nullptr;
|
||||
}
|
||||
|
||||
views::FrameViewLinux* NativeWindowViews::GetFrameViewLinux() const {
|
||||
auto* ncv = widget()->non_client_view();
|
||||
if (!ncv)
|
||||
return nullptr;
|
||||
return views::AsViewClass<views::FrameViewLinux>(ncv->frame_view());
|
||||
}
|
||||
#endif
|
||||
|
||||
void NativeWindowViews::OnWidgetMove() {
|
||||
|
||||
@@ -30,16 +30,10 @@ namespace gin {
|
||||
class Arguments;
|
||||
} // namespace gin
|
||||
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
namespace views {
|
||||
class FrameViewLinux;
|
||||
} // namespace views
|
||||
#endif
|
||||
|
||||
namespace electron {
|
||||
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
class NativeFrameViewLinux;
|
||||
class ClientFrameViewLinux;
|
||||
class GlobalMenuBarX11;
|
||||
class LinuxFrameLayout;
|
||||
#endif
|
||||
@@ -208,7 +202,6 @@ class NativeWindowViews : public NativeWindow,
|
||||
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
LinuxFrameLayout* GetLinuxFrameLayout();
|
||||
views::FrameViewLinux* GetFrameViewLinux() const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <shellapi.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/win/atl.h" // Must be before UIAutomationCore.h
|
||||
#include "base/win/registry.h"
|
||||
#include "base/win/scoped_handle.h"
|
||||
@@ -678,21 +677,8 @@ void NativeWindowViews::SetForwardMouseMessages(bool forward) {
|
||||
RemoveWindowSubclass(legacy_window_, SubclassProc, 1);
|
||||
|
||||
if (forwarding_windows_->empty()) {
|
||||
// If UnhookWindowsHookEx fails, the hook is still installed in the
|
||||
// system. Leave |mouse_hook_| pointing at the existing hook so that a
|
||||
// subsequent SetForwardMouseMessages(true) reuses it instead of
|
||||
// installing a duplicate hook.
|
||||
if (UnhookWindowsHookEx(mouse_hook_)) {
|
||||
mouse_hook_ = nullptr;
|
||||
} else {
|
||||
const DWORD error = ::GetLastError();
|
||||
if (error == ERROR_INVALID_HOOK_HANDLE) {
|
||||
mouse_hook_ = nullptr;
|
||||
} else {
|
||||
LOG(WARNING) << "Failed to unhook low-level mouse hook: "
|
||||
<< logging::SystemErrorCodeToString(error);
|
||||
}
|
||||
}
|
||||
UnhookWindowsHookEx(mouse_hook_);
|
||||
mouse_hook_ = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "base/strings/string_split.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "extensions/browser/extension_navigation_ui_data.h"
|
||||
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
|
||||
#include "net/base/completion_repeating_callback.h"
|
||||
#include "net/base/load_flags.h"
|
||||
#include "net/http/http_response_headers.h"
|
||||
@@ -30,30 +29,6 @@
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace {
|
||||
|
||||
class NoOpHeaderClient final : public network::mojom::TrustedHeaderClient {
|
||||
public:
|
||||
NoOpHeaderClient() = default;
|
||||
NoOpHeaderClient(const NoOpHeaderClient&) = delete;
|
||||
NoOpHeaderClient& operator=(const NoOpHeaderClient&) = delete;
|
||||
~NoOpHeaderClient() override = default;
|
||||
|
||||
void OnBeforeSendHeaders(const net::HttpRequestHeaders& headers,
|
||||
OnBeforeSendHeadersCallback callback) override {
|
||||
std::move(callback).Run(net::OK, std::nullopt);
|
||||
}
|
||||
|
||||
void OnHeadersReceived(const std::string& headers,
|
||||
const net::IPEndPoint& remote_endpoint,
|
||||
const std::optional<net::SSLInfo>& ssl_info,
|
||||
OnHeadersReceivedCallback callback) override {
|
||||
std::move(callback).Run(net::OK, std::nullopt, std::nullopt);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
ProxyingURLLoaderFactory::InProgressRequest::FollowRedirectParams::
|
||||
FollowRedirectParams() = default;
|
||||
ProxyingURLLoaderFactory::InProgressRequest::FollowRedirectParams::
|
||||
@@ -894,14 +869,8 @@ void ProxyingURLLoaderFactory::OnLoaderCreated(
|
||||
int32_t request_id,
|
||||
mojo::PendingReceiver<network::mojom::TrustedHeaderClient> receiver) {
|
||||
auto it = network_request_id_to_web_request_id_.find(request_id);
|
||||
if (it == network_request_id_to_web_request_id_.end()) {
|
||||
// Chromium can require the header client pipe to be bound even when
|
||||
// Electron is using the pass-through path. Dropping the receiver here
|
||||
// disconnects the URLLoader and causes the request to fail with ERR_FAILED.
|
||||
mojo::MakeSelfOwnedReceiver(std::make_unique<NoOpHeaderClient>(),
|
||||
std::move(receiver));
|
||||
if (it == network_request_id_to_web_request_id_.end())
|
||||
return;
|
||||
}
|
||||
|
||||
auto request_it = requests_.find(it->second);
|
||||
DCHECK(request_it != requests_.end());
|
||||
|
||||
@@ -323,17 +323,11 @@ NSArray* ConvertSharingItemToNS(const SharingItem& item) {
|
||||
fromModel:(electron::ElectronMenuModel*)model {
|
||||
std::u16string label16 = model->GetLabelAt(index);
|
||||
auto rawSecondaryLabel = model->GetSecondaryLabelAt(index);
|
||||
std::u16string accessibility_label16 = model->GetAccessibilityLabelAt(index);
|
||||
NSString* label = l10n_util::FixUpWindowsStyleLabel(label16);
|
||||
|
||||
NSMenuItem* item = [[NSMenuItem alloc] initWithTitle:label
|
||||
action:@selector(itemSelected:)
|
||||
keyEquivalent:@""];
|
||||
if (!accessibility_label16.empty()) {
|
||||
NSString* accessibility_label =
|
||||
base::SysUTF16ToNSString(accessibility_label16);
|
||||
item.accessibilityLabel = accessibility_label;
|
||||
}
|
||||
|
||||
if (!rawSecondaryLabel.empty()) {
|
||||
if (@available(macOS 14.4, *)) {
|
||||
@@ -505,14 +499,8 @@ NSArray* ConvertSharingItemToNS(const SharingItem& item) {
|
||||
item.state = model->IsItemCheckedAt(index) ? NSControlStateValueOn
|
||||
: NSControlStateValueOff;
|
||||
std::u16string label16 = model->GetLabelAt(index);
|
||||
std::u16string accessibility_label16 = model->GetAccessibilityLabelAt(index);
|
||||
NSString* label = l10n_util::FixUpWindowsStyleLabel(label16);
|
||||
item.title = label;
|
||||
if (!accessibility_label16.empty()) {
|
||||
NSString* accessibility_label =
|
||||
base::SysUTF16ToNSString(accessibility_label16);
|
||||
item.accessibilityLabel = accessibility_label;
|
||||
}
|
||||
|
||||
std::u16string rawSecondaryLabel = model->GetSecondaryLabelAt(index);
|
||||
if (!rawSecondaryLabel.empty()) {
|
||||
|
||||
@@ -138,10 +138,6 @@ bool DevToolsManagerDelegate::HasBundledFrontendResources() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DevToolsManagerDelegate::ShouldUseBundledFrontendResources() {
|
||||
return true;
|
||||
}
|
||||
|
||||
content::BrowserContext* DevToolsManagerDelegate::GetDefaultBrowserContext() {
|
||||
return ElectronBrowserContext::GetDefaultBrowserContext();
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ class DevToolsManagerDelegate : public content::DevToolsManagerDelegate {
|
||||
bool new_window) override;
|
||||
std::string GetDiscoveryPageHTML() override;
|
||||
bool HasBundledFrontendResources() override;
|
||||
bool ShouldUseBundledFrontendResources() override;
|
||||
content::BrowserContext* GetDefaultBrowserContext() override;
|
||||
};
|
||||
|
||||
|
||||
@@ -10,15 +10,19 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/feature_list.h"
|
||||
#include "base/i18n/rtl.h"
|
||||
#include "shell/browser/api/electron_api_web_contents.h"
|
||||
#include "shell/browser/linux/x11_util.h"
|
||||
#include "shell/browser/native_window_features.h"
|
||||
#include "shell/browser/native_window_views.h"
|
||||
#include "shell/browser/ui/views/linux_frame_layout.h"
|
||||
#include "third_party/skia/include/core/SkRegion.h"
|
||||
#include "ui/aura/window_delegate.h"
|
||||
#include "ui/base/hit_test.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "ui/gfx/geometry/skia_conversions.h"
|
||||
#include "ui/linux/linux_ui.h"
|
||||
#include "ui/ozone/public/ozone_platform.h"
|
||||
#include "ui/platform_window/extensions/wayland_extension.h"
|
||||
@@ -26,8 +30,6 @@
|
||||
#include "ui/platform_window/platform_window_init_properties.h"
|
||||
#include "ui/views/widget/desktop_aura/desktop_window_tree_host.h"
|
||||
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h"
|
||||
#include "ui/views/window/frame_view_linux.h"
|
||||
#include "ui/views/window/frame_view_utils_linux.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
@@ -48,12 +50,6 @@ bool ElectronDesktopWindowTreeHostLinux::SupportsClientFrameShadow() const {
|
||||
|
||||
void ElectronDesktopWindowTreeHostLinux::OnWidgetInitDone() {
|
||||
views::DesktopWindowTreeHostLinux::OnWidgetInitDone();
|
||||
|
||||
// SetSupportsClientFrameShadow must happen after widget init when
|
||||
// platform_window is available.
|
||||
if (auto* fvl = native_window_view_->GetFrameViewLinux())
|
||||
fvl->SetSupportsClientFrameShadow(SupportsClientFrameShadow());
|
||||
|
||||
UpdateFrameHints();
|
||||
}
|
||||
|
||||
@@ -82,22 +78,19 @@ void ElectronDesktopWindowTreeHostLinux::Show(
|
||||
DesktopWindowTreeHostLinux::SetWindowIcons(saved_window_icon_, {});
|
||||
}
|
||||
|
||||
gfx::Insets ElectronDesktopWindowTreeHostLinux::GetRestoredFrameBorderInsets()
|
||||
const {
|
||||
if (auto* fvl = native_window_view_->GetFrameViewLinux())
|
||||
return fvl->GetRestoredFrameBorderInsets();
|
||||
|
||||
auto* const layout = native_window_view_->GetLinuxFrameLayout();
|
||||
return layout ? layout->RestoredFrameBorderInsets() : gfx::Insets();
|
||||
}
|
||||
|
||||
gfx::Insets ElectronDesktopWindowTreeHostLinux::CalculateInsetsInDIP(
|
||||
ui::PlatformWindowState window_state) const {
|
||||
// If we are not showing frame, the insets should be zero.
|
||||
if (!IsShowingFrame(window_state))
|
||||
if (!IsShowingFrame(window_state)) {
|
||||
return gfx::Insets();
|
||||
}
|
||||
|
||||
return GetRestoredFrameBorderInsets();
|
||||
auto* const layout = native_window_view_->GetLinuxFrameLayout();
|
||||
if (!layout)
|
||||
return {};
|
||||
|
||||
gfx::Insets insets = layout->RestoredFrameBorderInsets();
|
||||
return insets;
|
||||
}
|
||||
|
||||
// Electron treats min/max constraints as the logical window size, but Chromium
|
||||
@@ -108,8 +101,11 @@ std::optional<gfx::Size>
|
||||
ElectronDesktopWindowTreeHostLinux::GetMinimumSizeForWindow() const {
|
||||
auto min_size = views::DesktopWindowTreeHostLinux::GetMinimumSizeForWindow();
|
||||
if (min_size.has_value()) {
|
||||
gfx::Insets insets = GetRestoredFrameBorderInsets();
|
||||
min_size->Enlarge(insets.width(), insets.height());
|
||||
auto* const layout = native_window_view_->GetLinuxFrameLayout();
|
||||
if (layout) {
|
||||
gfx::Insets insets = layout->RestoredFrameBorderInsets();
|
||||
min_size->Enlarge(insets.width(), insets.height());
|
||||
}
|
||||
}
|
||||
return min_size;
|
||||
}
|
||||
@@ -118,12 +114,15 @@ std::optional<gfx::Size>
|
||||
ElectronDesktopWindowTreeHostLinux::GetMaximumSizeForWindow() const {
|
||||
auto max_size = views::DesktopWindowTreeHostLinux::GetMaximumSizeForWindow();
|
||||
if (max_size.has_value()) {
|
||||
gfx::Insets insets = GetRestoredFrameBorderInsets();
|
||||
// 0 means no constraint, so don't inflate.
|
||||
if (max_size->width() > 0)
|
||||
max_size->set_width(max_size->width() + insets.width());
|
||||
if (max_size->height() > 0)
|
||||
max_size->set_height(max_size->height() + insets.height());
|
||||
auto* const layout = native_window_view_->GetLinuxFrameLayout();
|
||||
if (layout) {
|
||||
gfx::Insets insets = layout->RestoredFrameBorderInsets();
|
||||
// 0 means no constraint, so don't inflate.
|
||||
if (max_size->width() > 0)
|
||||
max_size->set_width(max_size->width() + insets.width());
|
||||
if (max_size->height() > 0)
|
||||
max_size->set_height(max_size->height() + insets.height());
|
||||
}
|
||||
}
|
||||
return max_size;
|
||||
}
|
||||
@@ -152,17 +151,15 @@ void ElectronDesktopWindowTreeHostLinux::OnWindowStateChanged(
|
||||
|
||||
void ElectronDesktopWindowTreeHostLinux::OnWindowTiledStateChanged(
|
||||
ui::WindowTiledEdges new_tiled_edges) {
|
||||
// GNOME on Ubuntu reports all edges as tiled even if the window is only
|
||||
// half-tiled, so do not trust individual edge values.
|
||||
bool maximized = native_window_view_->IsMaximized();
|
||||
bool tiled = new_tiled_edges.top || new_tiled_edges.left ||
|
||||
new_tiled_edges.bottom || new_tiled_edges.right;
|
||||
bool is_tiled = tiled && !maximized;
|
||||
|
||||
if (auto* fvl = native_window_view_->GetFrameViewLinux())
|
||||
fvl->SetTiled(is_tiled);
|
||||
else if (auto* layout = native_window_view_->GetLinuxFrameLayout())
|
||||
layout->set_tiled(is_tiled);
|
||||
if (auto* layout = native_window_view_->GetLinuxFrameLayout()) {
|
||||
// GNOME on Ubuntu reports all edges as tiled
|
||||
// even if the window is only half-tiled so do not trust individual edge
|
||||
// values.
|
||||
bool maximized = native_window_view_->IsMaximized();
|
||||
bool tiled = new_tiled_edges.top || new_tiled_edges.left ||
|
||||
new_tiled_edges.bottom || new_tiled_edges.right;
|
||||
layout->set_tiled(tiled && !maximized);
|
||||
}
|
||||
UpdateFrameHints();
|
||||
ScheduleRelayout();
|
||||
if (GetWidget()->non_client_view()) {
|
||||
@@ -216,61 +213,95 @@ void ElectronDesktopWindowTreeHostLinux::OnDeviceScaleFactorChanged() {
|
||||
}
|
||||
|
||||
void ElectronDesktopWindowTreeHostLinux::UpdateFrameHints() {
|
||||
if (native_window_view_->GetFrameViewLinux()) {
|
||||
views::DesktopWindowTreeHostLinux::UpdateFrameHints();
|
||||
// Clear the opaque region for translucent windows.
|
||||
if (native_window_view_->IsTranslucent() &&
|
||||
views::Widget::IsWindowCompositingSupported()) {
|
||||
platform_window()->SetOpaqueRegion(std::vector<gfx::Rect>{});
|
||||
if (base::FeatureList::IsEnabled(features::kWaylandWindowDecorations)) {
|
||||
auto* const layout = native_window_view_->GetLinuxFrameLayout();
|
||||
if (!layout)
|
||||
return;
|
||||
|
||||
ui::PlatformWindow* window = platform_window();
|
||||
auto window_state = window->GetPlatformWindowState();
|
||||
float scale = device_scale_factor();
|
||||
const gfx::Size widget_size = GetWidget()->GetWindowBoundsInScreen().size();
|
||||
|
||||
if (SupportsClientFrameShadow()) {
|
||||
auto insets = CalculateInsetsInDIP(window_state);
|
||||
if (insets.IsEmpty()) {
|
||||
window->SetInputRegion(std::nullopt);
|
||||
} else {
|
||||
gfx::Rect input_bounds(widget_size);
|
||||
input_bounds.Inset(insets - layout->GetInputInsets());
|
||||
input_bounds = gfx::ScaleToEnclosingRect(input_bounds, scale);
|
||||
window->SetInputRegion(
|
||||
std::optional<std::vector<gfx::Rect>>({input_bounds}));
|
||||
}
|
||||
}
|
||||
|
||||
if (ui::OzonePlatform::GetInstance()->IsWindowCompositingSupported()) {
|
||||
// Set the opaque region.
|
||||
std::vector<gfx::Rect> opaque_region;
|
||||
if (native_window_view_->IsTranslucent()) {
|
||||
// Leave opaque_region empty.
|
||||
} else if (IsShowingFrame(window_state)) {
|
||||
// The opaque region is a list of rectangles that contain only fully
|
||||
// opaque pixels of the window. We need to convert the clipping
|
||||
// rounded-rect into this format.
|
||||
SkRRect rrect = layout->GetRoundedWindowBounds();
|
||||
gfx::RectF rectf(layout->GetWindowBounds());
|
||||
rectf.Scale(scale);
|
||||
// It is acceptable to omit some pixels that are opaque, but the region
|
||||
// must not include any translucent pixels. Therefore, we must
|
||||
// conservatively scale to the enclosed rectangle.
|
||||
gfx::Rect rect = gfx::ToEnclosedRect(rectf);
|
||||
|
||||
// Create the initial region from the clipping rectangle without rounded
|
||||
// corners.
|
||||
SkRegion region(gfx::RectToSkIRect(rect));
|
||||
|
||||
// Now subtract out the small rectangles that cover the corners.
|
||||
struct {
|
||||
SkRRect::Corner corner;
|
||||
bool left;
|
||||
bool upper;
|
||||
} kCorners[] = {
|
||||
{SkRRect::kUpperLeft_Corner, true, true},
|
||||
{SkRRect::kUpperRight_Corner, false, true},
|
||||
{SkRRect::kLowerLeft_Corner, true, false},
|
||||
{SkRRect::kLowerRight_Corner, false, false},
|
||||
};
|
||||
for (const auto& corner : kCorners) {
|
||||
auto radii = rrect.radii(corner.corner);
|
||||
auto rx = std::ceil(scale * radii.x());
|
||||
auto ry = std::ceil(scale * radii.y());
|
||||
auto corner_rect = SkIRect::MakeXYWH(
|
||||
corner.left ? rect.x() : rect.right() - rx,
|
||||
corner.upper ? rect.y() : rect.bottom() - ry, rx, ry);
|
||||
region.op(corner_rect, SkRegion::kDifference_Op);
|
||||
}
|
||||
|
||||
auto translucent_top_area_rect = SkIRect::MakeXYWH(
|
||||
rect.x(), rect.y(), rect.width(),
|
||||
std::ceil(layout->GetTranslucentTopAreaHeight() * scale -
|
||||
rect.y()));
|
||||
region.op(translucent_top_area_rect, SkRegion::kDifference_Op);
|
||||
|
||||
// Convert the region to a list of rectangles.
|
||||
for (SkRegion::Iterator i(region); !i.done(); i.next()) {
|
||||
opaque_region.push_back(gfx::SkIRectToRect(i.rect()));
|
||||
}
|
||||
} else {
|
||||
// The entire window except for the translucent top is opaque.
|
||||
gfx::Rect opaque_region_dip(widget_size);
|
||||
gfx::Insets insets;
|
||||
insets.set_top(layout->GetTranslucentTopAreaHeight());
|
||||
opaque_region_dip.Inset(insets);
|
||||
opaque_region.push_back(
|
||||
gfx::ScaleToEnclosingRect(opaque_region_dip, scale));
|
||||
}
|
||||
window->SetOpaqueRegion(opaque_region);
|
||||
}
|
||||
|
||||
SizeConstraintsChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
auto* layout = native_window_view_->GetLinuxFrameLayout();
|
||||
if (!layout)
|
||||
return;
|
||||
|
||||
ui::PlatformWindow* window = platform_window();
|
||||
auto window_state = window->GetPlatformWindowState();
|
||||
float scale = device_scale_factor();
|
||||
const gfx::Size widget_size = GetWidget()->GetWindowBoundsInScreen().size();
|
||||
|
||||
if (SupportsClientFrameShadow()) {
|
||||
auto insets = CalculateInsetsInDIP(window_state);
|
||||
if (insets.IsEmpty()) {
|
||||
window->SetInputRegion(std::nullopt);
|
||||
} else {
|
||||
gfx::Rect input_bounds(widget_size);
|
||||
input_bounds.Inset(insets - layout->GetInputInsets());
|
||||
input_bounds = gfx::ScaleToEnclosingRect(input_bounds, scale);
|
||||
window->SetInputRegion(
|
||||
std::optional<std::vector<gfx::Rect>>({input_bounds}));
|
||||
}
|
||||
}
|
||||
|
||||
if (ui::OzonePlatform::GetInstance()->IsWindowCompositingSupported()) {
|
||||
// Set the opaque region.
|
||||
std::vector<gfx::Rect> opaque_region;
|
||||
if (native_window_view_->IsTranslucent()) {
|
||||
// Leave opaque_region empty.
|
||||
} else if (IsShowingFrame(window_state)) {
|
||||
opaque_region = views::GetRestoredOpaqueRegion(
|
||||
layout->GetRoundedWindowBounds(), scale,
|
||||
layout->GetTranslucentTopAreaHeight());
|
||||
} else {
|
||||
// The entire window except for the translucent top is opaque.
|
||||
gfx::Rect opaque_region_dip(widget_size);
|
||||
gfx::Insets insets;
|
||||
insets.set_top(layout->GetTranslucentTopAreaHeight());
|
||||
opaque_region_dip.Inset(insets);
|
||||
opaque_region.push_back(
|
||||
gfx::ScaleToEnclosingRect(opaque_region_dip, scale));
|
||||
}
|
||||
window->SetOpaqueRegion(opaque_region);
|
||||
}
|
||||
|
||||
SizeConstraintsChanged();
|
||||
}
|
||||
|
||||
void ElectronDesktopWindowTreeHostLinux::DispatchEvent(ui::Event* event) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "ui/gfx/image/image_skia.h"
|
||||
#include "ui/linux/device_scale_factor_observer.h"
|
||||
#include "ui/linux/linux_ui.h"
|
||||
#include "ui/native_theme/native_theme_observer.h"
|
||||
#include "ui/platform_window/platform_window.h"
|
||||
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h"
|
||||
|
||||
@@ -77,13 +78,12 @@ class ElectronDesktopWindowTreeHostLinux
|
||||
|
||||
bool IsShowingFrame(ui::PlatformWindowState window_state) const;
|
||||
|
||||
// Returns restored frame border insets regardless of current widget state.
|
||||
gfx::Insets GetRestoredFrameBorderInsets() const;
|
||||
|
||||
gfx::ImageSkia saved_window_icon_;
|
||||
|
||||
raw_ptr<NativeWindowViews> native_window_view_; // weak ref
|
||||
|
||||
base::ScopedObservation<ui::NativeTheme, ui::NativeThemeObserver>
|
||||
theme_observation_{this};
|
||||
base::ScopedObservation<ui::LinuxUi, ui::DeviceScaleFactorObserver>
|
||||
scale_observation_{this};
|
||||
ui::PlatformWindowState window_state_ = ui::PlatformWindowState::kUnknown;
|
||||
|
||||
@@ -49,12 +49,6 @@ std::u16string ElectronMenuModel::GetCustomTypeAt(size_t index) {
|
||||
return iter == std::end(customTypes_) ? std::u16string() : iter->second;
|
||||
}
|
||||
|
||||
std::u16string ElectronMenuModel::GetAccessibilityLabelAt(size_t index) const {
|
||||
if (delegate_)
|
||||
return delegate_->GetAccessibilityLabelForCommandId(GetCommandIdAt(index));
|
||||
return std::u16string();
|
||||
}
|
||||
|
||||
void ElectronMenuModel::SetRole(size_t index, const std::u16string& role) {
|
||||
int command_id = GetCommandIdAt(index);
|
||||
roles_[command_id] = role;
|
||||
|
||||
@@ -49,9 +49,6 @@ class ElectronMenuModel : public ui::SimpleMenuModel {
|
||||
|
||||
virtual bool ShouldCommandIdWorkWhenHidden(int command_id) const = 0;
|
||||
|
||||
virtual std::u16string GetAccessibilityLabelForCommandId(
|
||||
int command_id) const = 0;
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
virtual bool GetSharingItemForCommandId(int command_id,
|
||||
SharingItem* item) const = 0;
|
||||
@@ -89,7 +86,6 @@ class ElectronMenuModel : public ui::SimpleMenuModel {
|
||||
std::u16string GetToolTipAt(size_t index);
|
||||
void SetCustomType(size_t index, const std::u16string& customType);
|
||||
std::u16string GetCustomTypeAt(size_t index);
|
||||
std::u16string GetAccessibilityLabelAt(size_t index) const;
|
||||
void SetRole(size_t index, const std::u16string& role);
|
||||
std::u16string GetRoleAt(size_t index);
|
||||
std::u16string GetLabelAt(size_t index) const override;
|
||||
|
||||
455
shell/browser/ui/views/client_frame_view_linux.cc
Normal file
455
shell/browser/ui/views/client_frame_view_linux.cc
Normal file
@@ -0,0 +1,455 @@
|
||||
// Copyright (c) 2021 Ryan Gonzalez.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/ui/views/client_frame_view_linux.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "cc/paint/paint_filter.h"
|
||||
#include "cc/paint/paint_flags.h"
|
||||
#include "shell/browser/native_window_views.h"
|
||||
#include "shell/browser/ui/views/frameless_view.h"
|
||||
#include "shell/browser/ui/views/linux_frame_layout.h"
|
||||
#include "ui/base/hit_test.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/metadata/metadata_impl_macros.h"
|
||||
#include "ui/base/models/image_model.h"
|
||||
#include "ui/base/ui_base_types.h"
|
||||
#include "ui/gfx/canvas.h"
|
||||
#include "ui/gfx/font_list.h"
|
||||
#include "ui/gfx/geometry/insets.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "ui/gfx/text_constants.h"
|
||||
#include "ui/gtk/gtk_compat.h" // nogncheck
|
||||
#include "ui/gtk/gtk_util.h" // nogncheck
|
||||
#include "ui/linux/linux_ui.h"
|
||||
#include "ui/linux/nav_button_provider.h"
|
||||
#include "ui/native_theme/native_theme.h"
|
||||
#include "ui/strings/grit/ui_strings.h"
|
||||
#include "ui/views/accessibility/view_accessibility.h"
|
||||
#include "ui/views/controls/button/image_button.h"
|
||||
#include "ui/views/style/typography.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "ui/views/window/frame_buttons.h"
|
||||
#include "ui/views/window/window_button_order_provider.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace {
|
||||
|
||||
ui::NavButtonProvider::ButtonState ButtonStateToNavButtonProviderState(
|
||||
views::Button::ButtonState state) {
|
||||
switch (state) {
|
||||
case views::Button::STATE_NORMAL:
|
||||
return ui::NavButtonProvider::ButtonState::kNormal;
|
||||
case views::Button::STATE_HOVERED:
|
||||
return ui::NavButtonProvider::ButtonState::kHovered;
|
||||
case views::Button::STATE_PRESSED:
|
||||
return ui::NavButtonProvider::ButtonState::kPressed;
|
||||
case views::Button::STATE_DISABLED:
|
||||
return ui::NavButtonProvider::ButtonState::kDisabled;
|
||||
|
||||
case views::Button::STATE_COUNT:
|
||||
default:
|
||||
NOTREACHED();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ClientFrameViewLinux::ClientFrameViewLinux(NativeWindowViews* window,
|
||||
views::Widget* frame)
|
||||
: FramelessView{window, frame},
|
||||
theme_{ui::NativeTheme::GetInstanceForNativeUi()},
|
||||
nav_button_provider_(
|
||||
ui::LinuxUiTheme::GetForProfile(nullptr)->CreateNavButtonProvider(
|
||||
ui::FrameType::kDefault)),
|
||||
nav_buttons_{
|
||||
NavButton{ui::NavButtonProvider::FrameButtonDisplayType::kClose,
|
||||
views::FrameButton::kClose, &views::Widget::Close,
|
||||
IDS_APP_ACCNAME_CLOSE, HTCLOSE},
|
||||
NavButton{ui::NavButtonProvider::FrameButtonDisplayType::kMaximize,
|
||||
views::FrameButton::kMaximize, &views::Widget::Maximize,
|
||||
IDS_APP_ACCNAME_MAXIMIZE, HTMAXBUTTON},
|
||||
NavButton{ui::NavButtonProvider::FrameButtonDisplayType::kRestore,
|
||||
views::FrameButton::kMaximize, &views::Widget::Restore,
|
||||
IDS_APP_ACCNAME_RESTORE, HTMAXBUTTON},
|
||||
NavButton{ui::NavButtonProvider::FrameButtonDisplayType::kMinimize,
|
||||
views::FrameButton::kMinimize, &views::Widget::Minimize,
|
||||
IDS_APP_ACCNAME_MINIMIZE, HTMINBUTTON},
|
||||
},
|
||||
trailing_frame_buttons_{views::FrameButton::kMinimize,
|
||||
views::FrameButton::kMaximize,
|
||||
views::FrameButton::kClose} {
|
||||
for (auto& button : nav_buttons_) {
|
||||
auto image_button = std::make_unique<views::ImageButton>();
|
||||
image_button->SetImageVerticalAlignment(views::ImageButton::ALIGN_MIDDLE);
|
||||
image_button->GetViewAccessibility().SetName(
|
||||
l10n_util::GetStringUTF16(button.accessibility_id));
|
||||
button.button = AddChildView(std::move(image_button));
|
||||
}
|
||||
|
||||
auto title = std::make_unique<views::Label>();
|
||||
title->SetSubpixelRenderingEnabled(false);
|
||||
title->SetAutoColorReadabilityEnabled(false);
|
||||
title->SetHorizontalAlignment(gfx::ALIGN_CENTER);
|
||||
title->SetVerticalAlignment(gfx::ALIGN_MIDDLE);
|
||||
title->SetTextStyle(views::style::STYLE_TAB_ACTIVE);
|
||||
title_ = AddChildView(std::move(title));
|
||||
|
||||
native_theme_observer_.Observe(theme_);
|
||||
|
||||
if (auto* ui = ui::LinuxUi::instance()) {
|
||||
ui->AddWindowButtonOrderObserver(this);
|
||||
OnWindowButtonOrderingChange();
|
||||
}
|
||||
linux_frame_layout_ = std::make_unique<LinuxCSDNativeFrameLayout>(window);
|
||||
|
||||
// Unretained() is safe because the subscription is saved into an instance
|
||||
// member and thus will be cancelled upon the instance's destruction.
|
||||
paint_as_active_changed_subscription_ =
|
||||
frame->RegisterPaintAsActiveChangedCallback(base::BindRepeating(
|
||||
&ClientFrameViewLinux::PaintAsActiveChanged, base::Unretained(this)));
|
||||
|
||||
UpdateWindowTitle();
|
||||
|
||||
for (auto& button : nav_buttons_) {
|
||||
// Unretained() is safe because the buttons are added as children to, and
|
||||
// thus owned by, this view. Thus, the buttons themselves will be destroyed
|
||||
// when this view is destroyed, and the frame's life must never outlive the
|
||||
// view.
|
||||
button.button->SetCallback(
|
||||
base::BindRepeating(button.callback, base::Unretained(frame)));
|
||||
}
|
||||
|
||||
UpdateThemeValues();
|
||||
}
|
||||
|
||||
ClientFrameViewLinux::~ClientFrameViewLinux() {
|
||||
if (auto* ui = ui::LinuxUi::instance())
|
||||
ui->RemoveWindowButtonOrderObserver(this);
|
||||
theme_->RemoveObserver(this);
|
||||
}
|
||||
|
||||
gfx::Insets ClientFrameViewLinux::RestoredFrameBorderInsets() const {
|
||||
return linux_frame_layout_->RestoredFrameBorderInsets();
|
||||
}
|
||||
|
||||
LinuxFrameLayout* ClientFrameViewLinux::GetLinuxFrameLayout() const {
|
||||
return linux_frame_layout_.get();
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::OnNativeThemeUpdated(
|
||||
ui::NativeTheme* observed_theme) {
|
||||
UpdateThemeValues();
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::OnWindowButtonOrderingChange() {
|
||||
auto* provider = views::WindowButtonOrderProvider::GetInstance();
|
||||
leading_frame_buttons_ = provider->leading_buttons();
|
||||
trailing_frame_buttons_ = provider->trailing_buttons();
|
||||
|
||||
InvalidateLayout();
|
||||
}
|
||||
|
||||
int ClientFrameViewLinux::ResizingBorderHitTest(const gfx::Point& point) {
|
||||
return ResizingBorderHitTestImpl(
|
||||
point, linux_frame_layout_->GetResizeBorderInsets());
|
||||
}
|
||||
|
||||
gfx::Rect ClientFrameViewLinux::GetBoundsForClientView() const {
|
||||
gfx::Rect client_bounds = bounds();
|
||||
if (!frame_->IsFullscreen()) {
|
||||
client_bounds.Inset(linux_frame_layout_->FrameBorderInsets(false));
|
||||
client_bounds.Inset(
|
||||
gfx::Insets::TLBR(GetTitlebarBounds().height(), 0, 0, 0));
|
||||
}
|
||||
return client_bounds;
|
||||
}
|
||||
|
||||
gfx::Rect ClientFrameViewLinux::GetWindowBoundsForClientBounds(
|
||||
const gfx::Rect& client_bounds) const {
|
||||
gfx::Insets insets = bounds().InsetsFrom(GetBoundsForClientView());
|
||||
return gfx::Rect(std::max(0, client_bounds.x() - insets.left()),
|
||||
std::max(0, client_bounds.y() - insets.top()),
|
||||
client_bounds.width() + insets.width(),
|
||||
client_bounds.height() + insets.height());
|
||||
}
|
||||
|
||||
int ClientFrameViewLinux::NonClientHitTest(const gfx::Point& point) {
|
||||
int component = ResizingBorderHitTest(point);
|
||||
if (component != HTNOWHERE) {
|
||||
return component;
|
||||
}
|
||||
|
||||
for (auto& button : nav_buttons_) {
|
||||
if (button.button->GetVisible() &&
|
||||
button.button->GetMirroredBounds().Contains(point)) {
|
||||
return button.hit_test_id;
|
||||
}
|
||||
}
|
||||
|
||||
if (GetTitlebarBounds().Contains(point)) {
|
||||
return HTCAPTION;
|
||||
}
|
||||
|
||||
return FramelessView::NonClientHitTest(point);
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::GetWindowMask(const gfx::Size& size,
|
||||
SkPath* window_mask) {
|
||||
// Nothing to do here, as transparency is used for decorations, not masks.
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::UpdateWindowTitle() {
|
||||
title_->SetText(base::UTF8ToUTF16(window_->GetTitle()));
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::SizeConstraintsChanged() {
|
||||
InvalidateLayout();
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::Layout(PassKey) {
|
||||
LayoutSuperclass<FramelessView>(this);
|
||||
|
||||
if (frame_->IsFullscreen()) {
|
||||
// Just hide everything and return.
|
||||
for (NavButton& button : nav_buttons_) {
|
||||
button.button->SetVisible(false);
|
||||
}
|
||||
|
||||
title_->SetVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateButtonImages();
|
||||
LayoutButtons();
|
||||
|
||||
gfx::Rect title_bounds(GetTitlebarContentBounds());
|
||||
title_bounds.Inset(theme_values_.title_padding);
|
||||
|
||||
title_->SetVisible(true);
|
||||
title_->SetBoundsRect(title_bounds);
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::OnPaint(gfx::Canvas* canvas) {
|
||||
if (frame_->IsFullscreen()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (frame_->IsMaximized()) {
|
||||
// Some GTK themes (Breeze) still render shadow/border assets when
|
||||
// maximized, and we don't need a border when maximized anyway. Chromium
|
||||
// switches on this too: OpaqueBrowserFrameView::PaintMaximizedFrameBorder.
|
||||
PaintMaximizedFrameBorder(canvas);
|
||||
} else {
|
||||
PaintRestoredFrameBorder(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::PaintRestoredFrameBorder(gfx::Canvas* canvas) {
|
||||
if (auto* frame_provider = linux_frame_layout_->GetFrameProvider()) {
|
||||
frame_provider->PaintWindowFrame(
|
||||
canvas, GetLocalBounds(), GetTitlebarBounds().bottom(),
|
||||
ShouldPaintAsActive(), linux_frame_layout_->GetInputInsets());
|
||||
}
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::PaintMaximizedFrameBorder(gfx::Canvas* canvas) {
|
||||
ui::NativeTheme::FrameTopAreaExtraParams frame_top_area;
|
||||
frame_top_area.use_custom_frame = true;
|
||||
frame_top_area.is_active = ShouldPaintAsActive();
|
||||
frame_top_area.default_background_color = SK_ColorTRANSPARENT;
|
||||
ui::NativeTheme::ExtraParams params(frame_top_area);
|
||||
GetNativeTheme()->Paint(
|
||||
canvas->sk_canvas(), GetColorProvider(), ui::NativeTheme::kFrameTopArea,
|
||||
ui::NativeTheme::kNormal,
|
||||
gfx::Rect(0, 0, width(), GetTitlebarBounds().bottom()), params);
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::PaintAsActiveChanged() {
|
||||
UpdateThemeValues();
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::UpdateThemeValues() {
|
||||
gtk::GtkCssContext window_context =
|
||||
gtk::AppendCssNodeToStyleContext({}, "window.background.csd");
|
||||
gtk::GtkCssContext headerbar_context = gtk::AppendCssNodeToStyleContext(
|
||||
window_context, "headerbar.default-decoration.titlebar");
|
||||
gtk::GtkCssContext title_context =
|
||||
gtk::AppendCssNodeToStyleContext(headerbar_context, "label.title");
|
||||
// ShouldPaintAsActive asks the widget, so assume active if the widget is not
|
||||
// set yet.
|
||||
if (GetWidget() != nullptr && !ShouldPaintAsActive()) {
|
||||
gtk_style_context_set_state(window_context, GTK_STATE_FLAG_BACKDROP);
|
||||
gtk_style_context_set_state(headerbar_context, GTK_STATE_FLAG_BACKDROP);
|
||||
gtk_style_context_set_state(title_context, GTK_STATE_FLAG_BACKDROP);
|
||||
}
|
||||
|
||||
theme_values_.window_border_radius =
|
||||
linux_frame_layout_->GetTopCornerRadiusDip();
|
||||
|
||||
gtk::GtkStyleContextGet(headerbar_context, "min-height",
|
||||
&theme_values_.titlebar_min_height, nullptr);
|
||||
theme_values_.titlebar_padding =
|
||||
gtk::GtkStyleContextGetPadding(headerbar_context);
|
||||
|
||||
theme_values_.title_color = gtk::GtkStyleContextGetColor(title_context);
|
||||
theme_values_.title_padding = gtk::GtkStyleContextGetPadding(title_context);
|
||||
|
||||
title_->SetEnabledColor(theme_values_.title_color);
|
||||
|
||||
InvalidateLayout();
|
||||
SchedulePaint();
|
||||
}
|
||||
|
||||
ui::NavButtonProvider::FrameButtonDisplayType
|
||||
ClientFrameViewLinux::GetButtonTypeToSkip() const {
|
||||
return frame_->IsMaximized()
|
||||
? ui::NavButtonProvider::FrameButtonDisplayType::kMaximize
|
||||
: ui::NavButtonProvider::FrameButtonDisplayType::kRestore;
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::UpdateButtonImages() {
|
||||
int top_area_height = theme_values_.titlebar_min_height +
|
||||
theme_values_.titlebar_padding.height();
|
||||
nav_button_provider_->RedrawImages(top_area_height, frame_->IsMaximized(),
|
||||
ShouldPaintAsActive());
|
||||
|
||||
ui::NavButtonProvider::FrameButtonDisplayType skip_type =
|
||||
GetButtonTypeToSkip();
|
||||
|
||||
for (NavButton& button : nav_buttons_) {
|
||||
if (button.type == skip_type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (size_t state_id = 0; state_id < views::Button::STATE_COUNT;
|
||||
state_id++) {
|
||||
views::Button::ButtonState state =
|
||||
static_cast<views::Button::ButtonState>(state_id);
|
||||
button.button->SetImageModel(
|
||||
state, ui::ImageModel::FromImageSkia(nav_button_provider_->GetImage(
|
||||
button.type, ButtonStateToNavButtonProviderState(state))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::LayoutButtons() {
|
||||
for (NavButton& button : nav_buttons_) {
|
||||
button.button->SetVisible(false);
|
||||
}
|
||||
|
||||
gfx::Rect remaining_content_bounds = GetTitlebarContentBounds();
|
||||
LayoutButtonsOnSide(ButtonSide::kLeading, &remaining_content_bounds);
|
||||
LayoutButtonsOnSide(ButtonSide::kTrailing, &remaining_content_bounds);
|
||||
}
|
||||
|
||||
void ClientFrameViewLinux::LayoutButtonsOnSide(
|
||||
ButtonSide side,
|
||||
gfx::Rect* remaining_content_bounds) {
|
||||
ui::NavButtonProvider::FrameButtonDisplayType skip_type =
|
||||
GetButtonTypeToSkip();
|
||||
|
||||
std::vector<views::FrameButton> frame_buttons;
|
||||
|
||||
switch (side) {
|
||||
case ButtonSide::kLeading:
|
||||
frame_buttons = leading_frame_buttons_;
|
||||
break;
|
||||
case ButtonSide::kTrailing:
|
||||
frame_buttons = trailing_frame_buttons_;
|
||||
// We always lay buttons out going from the edge towards the center, but
|
||||
// they are given to us as left-to-right, so reverse them.
|
||||
std::ranges::reverse(frame_buttons);
|
||||
break;
|
||||
default:
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
for (views::FrameButton frame_button : frame_buttons) {
|
||||
auto button =
|
||||
std::ranges::find_if(nav_buttons_, [&](const NavButton& test) {
|
||||
return test.type != skip_type && test.frame_button == frame_button;
|
||||
});
|
||||
CHECK(button != nav_buttons_.end())
|
||||
<< "Failed to find frame button: " << static_cast<int>(frame_button);
|
||||
|
||||
if (button->type == skip_type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
button->button->SetVisible(true);
|
||||
|
||||
// CSS min-size/height/width is not enough to determine the actual size of
|
||||
// the buttons, so we sample the rendered image. See Chromium's
|
||||
// BrowserFrameViewLinuxNative::MaybeUpdateCachedFrameButtonImages.
|
||||
int button_width =
|
||||
nav_button_provider_
|
||||
->GetImage(button->type,
|
||||
ui::NavButtonProvider::ButtonState::kNormal)
|
||||
.width();
|
||||
int next_button_offset =
|
||||
button_width + nav_button_provider_->GetInterNavButtonSpacing();
|
||||
|
||||
int x_position = 0;
|
||||
gfx::Insets inset_after_placement;
|
||||
|
||||
switch (side) {
|
||||
case ButtonSide::kLeading:
|
||||
x_position = remaining_content_bounds->x();
|
||||
inset_after_placement.set_left(next_button_offset);
|
||||
break;
|
||||
case ButtonSide::kTrailing:
|
||||
x_position = remaining_content_bounds->right() - button_width;
|
||||
inset_after_placement.set_right(next_button_offset);
|
||||
break;
|
||||
default:
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
button->button->SetBounds(x_position, remaining_content_bounds->y(),
|
||||
button_width, remaining_content_bounds->height());
|
||||
remaining_content_bounds->Inset(inset_after_placement);
|
||||
}
|
||||
}
|
||||
|
||||
gfx::Rect ClientFrameViewLinux::GetTitlebarBounds() const {
|
||||
if (frame_->IsFullscreen()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
int font_height = gfx::FontList().GetHeight();
|
||||
int titlebar_height =
|
||||
std::max(font_height, theme_values_.titlebar_min_height) +
|
||||
GetTitlebarContentInsets().height();
|
||||
|
||||
gfx::Insets decoration_insets = linux_frame_layout_->FrameBorderInsets(false);
|
||||
|
||||
// We add the inset height here, so the .Inset() that follows won't reduce it
|
||||
// to be too small.
|
||||
gfx::Rect titlebar(width(), titlebar_height + decoration_insets.height());
|
||||
titlebar.Inset(decoration_insets);
|
||||
return titlebar;
|
||||
}
|
||||
|
||||
gfx::Insets ClientFrameViewLinux::GetTitlebarContentInsets() const {
|
||||
return theme_values_.titlebar_padding +
|
||||
nav_button_provider_->GetTopAreaSpacing();
|
||||
}
|
||||
|
||||
gfx::Rect ClientFrameViewLinux::GetTitlebarContentBounds() const {
|
||||
gfx::Rect titlebar(GetTitlebarBounds());
|
||||
titlebar.Inset(GetTitlebarContentInsets());
|
||||
return titlebar;
|
||||
}
|
||||
views::View* ClientFrameViewLinux::TargetForRect(views::View* root,
|
||||
const gfx::Rect& rect) {
|
||||
return views::FrameView::TargetForRect(root, rect);
|
||||
}
|
||||
|
||||
BEGIN_METADATA(ClientFrameViewLinux) END_METADATA
|
||||
|
||||
} // namespace electron
|
||||
135
shell/browser/ui/views/client_frame_view_linux.h
Normal file
135
shell/browser/ui/views/client_frame_view_linux.h
Normal file
@@ -0,0 +1,135 @@
|
||||
// Copyright (c) 2021 Ryan Gonzalez.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ELECTRON_SHELL_BROWSER_UI_VIEWS_CLIENT_FRAME_VIEW_LINUX_H_
|
||||
#define ELECTRON_SHELL_BROWSER_UI_VIEWS_CLIENT_FRAME_VIEW_LINUX_H_
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/memory/raw_ptr_exclusion.h"
|
||||
#include "base/scoped_observation.h"
|
||||
#include "shell/browser/ui/views/frameless_view.h"
|
||||
#include "shell/browser/ui/views/linux_frame_layout.h"
|
||||
#include "ui/base/metadata/metadata_header_macros.h"
|
||||
#include "ui/base/ui_base_types.h"
|
||||
#include "ui/linux/linux_ui.h"
|
||||
#include "ui/linux/nav_button_provider.h"
|
||||
#include "ui/linux/window_button_order_observer.h"
|
||||
#include "ui/native_theme/native_theme.h"
|
||||
#include "ui/native_theme/native_theme_observer.h"
|
||||
#include "ui/views/controls/button/image_button.h"
|
||||
#include "ui/views/controls/label.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "ui/views/window/frame_buttons.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
class NativeWindowViews;
|
||||
|
||||
class ClientFrameViewLinux : public FramelessView,
|
||||
private ui::NativeThemeObserver,
|
||||
private ui::WindowButtonOrderObserver {
|
||||
METADATA_HEADER(ClientFrameViewLinux, FramelessView)
|
||||
|
||||
public:
|
||||
ClientFrameViewLinux(NativeWindowViews* window, views::Widget* frame);
|
||||
~ClientFrameViewLinux() override;
|
||||
|
||||
// FramelessView:
|
||||
gfx::Insets RestoredFrameBorderInsets() const override;
|
||||
LinuxFrameLayout* GetLinuxFrameLayout() const override;
|
||||
|
||||
protected:
|
||||
// ui::NativeThemeObserver:
|
||||
void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override;
|
||||
|
||||
// views::WindowButtonOrderObserver:
|
||||
void OnWindowButtonOrderingChange() override;
|
||||
|
||||
// Overridden from FramelessView:
|
||||
int ResizingBorderHitTest(const gfx::Point& point) override;
|
||||
|
||||
// Overridden from views::FrameView:
|
||||
gfx::Rect GetBoundsForClientView() const override;
|
||||
gfx::Rect GetWindowBoundsForClientBounds(
|
||||
const gfx::Rect& client_bounds) const override;
|
||||
int NonClientHitTest(const gfx::Point& point) override;
|
||||
void GetWindowMask(const gfx::Size& size, SkPath* window_mask) override;
|
||||
void UpdateWindowTitle() override;
|
||||
void SizeConstraintsChanged() override;
|
||||
|
||||
// Overridden from View:
|
||||
void Layout(PassKey) override;
|
||||
void OnPaint(gfx::Canvas* canvas) override;
|
||||
|
||||
// Overridden from views::ViewTargeterDelegate
|
||||
views::View* TargetForRect(views::View* root, const gfx::Rect& rect) override;
|
||||
|
||||
private:
|
||||
static constexpr int kNavButtonCount = 4;
|
||||
|
||||
struct NavButton {
|
||||
ui::NavButtonProvider::FrameButtonDisplayType type;
|
||||
views::FrameButton frame_button;
|
||||
void (views::Widget::*callback)();
|
||||
int accessibility_id;
|
||||
int hit_test_id;
|
||||
raw_ptr<views::ImageButton> button = {};
|
||||
};
|
||||
|
||||
struct ThemeValues {
|
||||
float window_border_radius;
|
||||
|
||||
int titlebar_min_height;
|
||||
gfx::Insets titlebar_padding;
|
||||
|
||||
SkColor title_color;
|
||||
gfx::Insets title_padding;
|
||||
};
|
||||
|
||||
void PaintAsActiveChanged();
|
||||
void PaintRestoredFrameBorder(gfx::Canvas* canvas);
|
||||
void PaintMaximizedFrameBorder(gfx::Canvas* canvas);
|
||||
|
||||
void UpdateThemeValues();
|
||||
|
||||
enum class ButtonSide { kLeading, kTrailing };
|
||||
|
||||
ui::NavButtonProvider::FrameButtonDisplayType GetButtonTypeToSkip() const;
|
||||
void UpdateButtonImages();
|
||||
void LayoutButtons();
|
||||
void LayoutButtonsOnSide(ButtonSide side,
|
||||
gfx::Rect* remaining_content_bounds);
|
||||
|
||||
gfx::Rect GetTitlebarBounds() const;
|
||||
gfx::Insets GetTitlebarContentInsets() const;
|
||||
gfx::Rect GetTitlebarContentBounds() const;
|
||||
|
||||
std::unique_ptr<LinuxCSDNativeFrameLayout> linux_frame_layout_;
|
||||
|
||||
raw_ptr<ui::NativeTheme> theme_;
|
||||
ThemeValues theme_values_;
|
||||
|
||||
raw_ptr<views::Label> title_;
|
||||
|
||||
std::unique_ptr<ui::NavButtonProvider> nav_button_provider_;
|
||||
std::array<NavButton, kNavButtonCount> nav_buttons_;
|
||||
|
||||
std::vector<views::FrameButton> leading_frame_buttons_;
|
||||
std::vector<views::FrameButton> trailing_frame_buttons_;
|
||||
|
||||
base::ScopedObservation<ui::NativeTheme, ui::NativeThemeObserver>
|
||||
native_theme_observer_{this};
|
||||
base::ScopedObservation<ui::LinuxUi, ui::WindowButtonOrderObserver>
|
||||
window_button_order_observer_{this};
|
||||
|
||||
base::CallbackListSubscription paint_as_active_changed_subscription_;
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // ELECTRON_SHELL_BROWSER_UI_VIEWS_CLIENT_FRAME_VIEW_LINUX_H_
|
||||
@@ -1,52 +0,0 @@
|
||||
// Copyright (c) 2026 Athul Iddya.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/ui/views/native_frame_view_linux.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "shell/browser/native_window_views.h"
|
||||
#include "ui/base/hit_test.h"
|
||||
#include "ui/base/metadata/metadata_impl_macros.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
NativeFrameViewLinux::NativeFrameViewLinux(
|
||||
NativeWindowViews* window,
|
||||
views::Widget* widget,
|
||||
std::unique_ptr<ui::NavButtonProvider> nav_button_provider,
|
||||
views::NativeFrameViewLayoutLinux::FrameProviderGetter getter)
|
||||
: views::NativeFrameViewLinux(widget,
|
||||
std::move(nav_button_provider),
|
||||
std::move(getter)),
|
||||
window_(window) {
|
||||
InitViews();
|
||||
}
|
||||
|
||||
NativeFrameViewLinux::~NativeFrameViewLinux() = default;
|
||||
|
||||
int NativeFrameViewLinux::NonClientHitTest(const gfx::Point& point) {
|
||||
int result = views::NativeFrameViewLinux::NonClientHitTest(point);
|
||||
if (result != HTCLIENT)
|
||||
return result;
|
||||
|
||||
int contents_hit_test = window_->NonClientHitTest(point);
|
||||
if (contents_hit_test != HTNOWHERE)
|
||||
return contents_hit_test;
|
||||
|
||||
return HTCLIENT;
|
||||
}
|
||||
|
||||
gfx::Size NativeFrameViewLinux::GetMinimumSize() const {
|
||||
return window_->GetMinimumSize();
|
||||
}
|
||||
|
||||
gfx::Size NativeFrameViewLinux::GetMaximumSize() const {
|
||||
return window_->GetMaximumSize();
|
||||
}
|
||||
|
||||
BEGIN_METADATA(NativeFrameViewLinux)
|
||||
END_METADATA
|
||||
|
||||
} // namespace electron
|
||||
@@ -1,44 +0,0 @@
|
||||
// Copyright (c) 2026 Athul Iddya.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ELECTRON_SHELL_BROWSER_UI_VIEWS_NATIVE_FRAME_VIEW_LINUX_H_
|
||||
#define ELECTRON_SHELL_BROWSER_UI_VIEWS_NATIVE_FRAME_VIEW_LINUX_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "ui/base/metadata/metadata_header_macros.h"
|
||||
#include "ui/linux/nav_button_provider.h"
|
||||
#include "ui/views/window/native_frame_view_layout_linux.h"
|
||||
#include "ui/views/window/native_frame_view_linux.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
class NativeWindowViews;
|
||||
|
||||
// Extends views::NativeFrameViewLinux for Electron integration, such as
|
||||
// app-defined draggable regions and frame sizing.
|
||||
class NativeFrameViewLinux : public views::NativeFrameViewLinux {
|
||||
METADATA_HEADER(NativeFrameViewLinux, views::NativeFrameViewLinux)
|
||||
|
||||
public:
|
||||
NativeFrameViewLinux(
|
||||
NativeWindowViews* window,
|
||||
views::Widget* widget,
|
||||
std::unique_ptr<ui::NavButtonProvider> nav_button_provider,
|
||||
views::NativeFrameViewLayoutLinux::FrameProviderGetter getter);
|
||||
~NativeFrameViewLinux() override;
|
||||
|
||||
// views::FrameViewLinux:
|
||||
int NonClientHitTest(const gfx::Point& point) override;
|
||||
gfx::Size GetMinimumSize() const override;
|
||||
gfx::Size GetMaximumSize() const override;
|
||||
|
||||
private:
|
||||
raw_ptr<NativeWindowViews> window_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // ELECTRON_SHELL_BROWSER_UI_VIEWS_NATIVE_FRAME_VIEW_LINUX_H_
|
||||
@@ -1,204 +0,0 @@
|
||||
// Copyright (c) 2026 Anthropic, PBC.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/webauthn/electron_authenticator_request_client_delegate.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "base/base64url.h"
|
||||
#include "base/containers/span.h"
|
||||
#include "base/functional/bind.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "device/fido/authenticator_get_assertion_response.h"
|
||||
#include "device/fido/public/public_key_credential_descriptor.h"
|
||||
#include "device/fido/public/public_key_credential_user_entity.h"
|
||||
#include "gin/arguments.h"
|
||||
#include "gin/data_object_builder.h"
|
||||
#include "shell/browser/api/electron_api_session.h"
|
||||
#include "shell/browser/javascript_environment.h"
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
#include "shell/common/gin_converters/frame_converter.h"
|
||||
#include "shell/common/gin_helper/event.h"
|
||||
#include "shell/common/gin_helper/event_emitter_caller.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
namespace {
|
||||
|
||||
// WebAuthn's PublicKeyCredential.id is canonically URL-safe base64 with no
|
||||
// padding, so encode credential IDs and user handles the same way to keep the
|
||||
// event payload string-comparable to values returned by navigator.credentials.
|
||||
std::string Base64UrlEncodeNoPad(base::span<const uint8_t> input) {
|
||||
std::string out;
|
||||
base::Base64UrlEncode(input, base::Base64UrlEncodePolicy::OMIT_PADDING, &out);
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string CredentialIdFor(
|
||||
const device::AuthenticatorGetAssertionResponse& response) {
|
||||
if (response.credential) {
|
||||
return Base64UrlEncodeNoPad(response.credential->id);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ElectronAuthenticatorRequestClientDelegate::
|
||||
ElectronAuthenticatorRequestClientDelegate(
|
||||
content::RenderFrameHost* render_frame_host)
|
||||
: render_frame_host_id_(render_frame_host->GetGlobalId()) {}
|
||||
|
||||
ElectronAuthenticatorRequestClientDelegate::
|
||||
~ElectronAuthenticatorRequestClientDelegate() = default;
|
||||
|
||||
void ElectronAuthenticatorRequestClientDelegate::SetRelyingPartyId(
|
||||
const std::string& rp_id) {
|
||||
relying_party_id_ = rp_id;
|
||||
}
|
||||
|
||||
void ElectronAuthenticatorRequestClientDelegate::StartObserving(
|
||||
device::FidoRequestHandlerBase* request_handler) {
|
||||
request_handler_observation_.Observe(request_handler);
|
||||
}
|
||||
|
||||
void ElectronAuthenticatorRequestClientDelegate::StopObserving(
|
||||
device::FidoRequestHandlerBase* request_handler) {
|
||||
request_handler_observation_.Reset();
|
||||
}
|
||||
|
||||
void ElectronAuthenticatorRequestClientDelegate::RegisterActionCallbacks(
|
||||
base::OnceClosure cancel_callback,
|
||||
base::OnceClosure immediate_not_found_callback,
|
||||
base::RepeatingClosure start_over_callback,
|
||||
AccountPreselectedCallback account_preselected_callback,
|
||||
PasswordSelectedCallback password_selected_callback,
|
||||
device::FidoRequestHandlerBase::RequestCallback request_callback,
|
||||
base::OnceClosure cancel_ui_timeout_callback,
|
||||
base::RepeatingClosure bluetooth_adapter_power_on_callback,
|
||||
base::RepeatingCallback<
|
||||
void(device::FidoRequestHandlerBase::BlePermissionCallback)>
|
||||
request_ble_permission_callback) {
|
||||
cancel_callback_ = std::move(cancel_callback);
|
||||
}
|
||||
|
||||
void ElectronAuthenticatorRequestClientDelegate::SelectAccount(
|
||||
std::vector<device::AuthenticatorGetAssertionResponse> responses,
|
||||
base::OnceCallback<void(device::AuthenticatorGetAssertionResponse)>
|
||||
callback) {
|
||||
DCHECK(!responses.empty());
|
||||
|
||||
content::RenderFrameHost* rfh =
|
||||
content::RenderFrameHost::FromID(render_frame_host_id_);
|
||||
content::WebContents* web_contents =
|
||||
rfh ? content::WebContents::FromRenderFrameHost(rfh) : nullptr;
|
||||
gin::WeakCell<api::Session>* session =
|
||||
web_contents
|
||||
? api::Session::FromBrowserContext(web_contents->GetBrowserContext())
|
||||
: nullptr;
|
||||
|
||||
pending_responses_ = std::move(responses);
|
||||
select_account_callback_ = std::move(callback);
|
||||
|
||||
if (!session || !session->Get()) {
|
||||
CancelPendingAccountSelection();
|
||||
return;
|
||||
}
|
||||
|
||||
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
|
||||
v8::Local<v8::Array> accounts =
|
||||
v8::Array::New(isolate, static_cast<int>(pending_responses_.size()));
|
||||
for (size_t i = 0; i < pending_responses_.size(); ++i) {
|
||||
const auto& response = pending_responses_[i];
|
||||
gin::DataObjectBuilder account(isolate);
|
||||
account.Set("credentialId", CredentialIdFor(response));
|
||||
if (response.user_entity) {
|
||||
account.Set("userHandle", Base64UrlEncodeNoPad(response.user_entity->id));
|
||||
if (response.user_entity->name) {
|
||||
account.Set("name", *response.user_entity->name);
|
||||
}
|
||||
if (response.user_entity->display_name) {
|
||||
account.Set("displayName", *response.user_entity->display_name);
|
||||
}
|
||||
}
|
||||
accounts
|
||||
->CreateDataProperty(isolate->GetCurrentContext(),
|
||||
static_cast<uint32_t>(i), account.Build())
|
||||
.Check();
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> details = gin::DataObjectBuilder(isolate)
|
||||
.Set("relyingPartyId", relying_party_id_)
|
||||
.Set("accounts", accounts)
|
||||
.Set("frame", rfh)
|
||||
.Build();
|
||||
|
||||
v8::Local<v8::Object> session_wrapper;
|
||||
if (!session->Get()->GetWrapper(isolate).ToLocal(&session_wrapper)) {
|
||||
CancelPendingAccountSelection();
|
||||
return;
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> event_object = gin_helper::internal::Event::New(isolate)
|
||||
->GetWrapper(isolate)
|
||||
.ToLocalChecked();
|
||||
|
||||
v8::Local<v8::Value> emit_result = gin_helper::EmitEvent(
|
||||
isolate, session_wrapper, "select-webauthn-account", event_object,
|
||||
details,
|
||||
base::BindRepeating(
|
||||
&ElectronAuthenticatorRequestClientDelegate::OnAccountSelected,
|
||||
weak_factory_.GetWeakPtr()));
|
||||
|
||||
// EventEmitter.prototype.emit() returns true iff there was at least one
|
||||
// listener. With no listener there is no way for the app to choose an
|
||||
// account, so cancel rather than silently picking one.
|
||||
bool had_listener = false;
|
||||
if (!gin::ConvertFromV8(isolate, emit_result, &had_listener) ||
|
||||
!had_listener) {
|
||||
CancelPendingAccountSelection();
|
||||
}
|
||||
}
|
||||
|
||||
void ElectronAuthenticatorRequestClientDelegate::
|
||||
CancelPendingAccountSelection() {
|
||||
pending_responses_.clear();
|
||||
select_account_callback_.Reset();
|
||||
if (cancel_callback_) {
|
||||
std::move(cancel_callback_).Run();
|
||||
}
|
||||
}
|
||||
|
||||
void ElectronAuthenticatorRequestClientDelegate::OnAccountSelected(
|
||||
gin::Arguments* args) {
|
||||
if (!select_account_callback_) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string credential_id;
|
||||
if (!args->GetNext(&credential_id) || credential_id.empty()) {
|
||||
CancelPendingAccountSelection();
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& response : pending_responses_) {
|
||||
if (CredentialIdFor(response) == credential_id) {
|
||||
auto selected = std::move(response);
|
||||
pending_responses_.clear();
|
||||
std::move(select_account_callback_).Run(std::move(selected));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Unknown credentialId: cancel the pending request rather than leaving it
|
||||
// hanging. Matches the no-args branch above so the listener has a single,
|
||||
// consistent failure mode whether it cancels deliberately or by mistake.
|
||||
CancelPendingAccountSelection();
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
@@ -1,81 +0,0 @@
|
||||
// Copyright (c) 2026 Anthropic, PBC.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ELECTRON_SHELL_BROWSER_WEBAUTHN_ELECTRON_AUTHENTICATOR_REQUEST_CLIENT_DELEGATE_H_
|
||||
#define ELECTRON_SHELL_BROWSER_WEBAUTHN_ELECTRON_AUTHENTICATOR_REQUEST_CLIENT_DELEGATE_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/scoped_observation.h"
|
||||
#include "content/public/browser/authenticator_request_client_delegate.h"
|
||||
#include "content/public/browser/global_routing_id.h"
|
||||
|
||||
namespace content {
|
||||
class RenderFrameHost;
|
||||
}
|
||||
|
||||
namespace gin {
|
||||
class Arguments;
|
||||
}
|
||||
|
||||
namespace electron {
|
||||
|
||||
class ElectronAuthenticatorRequestClientDelegate
|
||||
: public content::AuthenticatorRequestClientDelegate {
|
||||
public:
|
||||
explicit ElectronAuthenticatorRequestClientDelegate(
|
||||
content::RenderFrameHost* render_frame_host);
|
||||
~ElectronAuthenticatorRequestClientDelegate() override;
|
||||
|
||||
// disable copy
|
||||
ElectronAuthenticatorRequestClientDelegate(
|
||||
const ElectronAuthenticatorRequestClientDelegate&) = delete;
|
||||
ElectronAuthenticatorRequestClientDelegate& operator=(
|
||||
const ElectronAuthenticatorRequestClientDelegate&) = delete;
|
||||
|
||||
// content::AuthenticatorRequestClientDelegate:
|
||||
void SetRelyingPartyId(const std::string& rp_id) override;
|
||||
void StartObserving(device::FidoRequestHandlerBase* request_handler) override;
|
||||
void StopObserving(device::FidoRequestHandlerBase* request_handler) override;
|
||||
void RegisterActionCallbacks(
|
||||
base::OnceClosure cancel_callback,
|
||||
base::OnceClosure immediate_not_found_callback,
|
||||
base::RepeatingClosure start_over_callback,
|
||||
AccountPreselectedCallback account_preselected_callback,
|
||||
PasswordSelectedCallback password_selected_callback,
|
||||
device::FidoRequestHandlerBase::RequestCallback request_callback,
|
||||
base::OnceClosure cancel_ui_timeout_callback,
|
||||
base::RepeatingClosure bluetooth_adapter_power_on_callback,
|
||||
base::RepeatingCallback<
|
||||
void(device::FidoRequestHandlerBase::BlePermissionCallback)>
|
||||
request_ble_permission_callback) override;
|
||||
void SelectAccount(
|
||||
std::vector<device::AuthenticatorGetAssertionResponse> responses,
|
||||
base::OnceCallback<void(device::AuthenticatorGetAssertionResponse)>
|
||||
callback) override;
|
||||
|
||||
private:
|
||||
void OnAccountSelected(gin::Arguments* args);
|
||||
void CancelPendingAccountSelection();
|
||||
|
||||
const content::GlobalRenderFrameHostId render_frame_host_id_;
|
||||
std::string relying_party_id_;
|
||||
base::OnceClosure cancel_callback_;
|
||||
|
||||
base::ScopedObservation<device::FidoRequestHandlerBase,
|
||||
device::FidoRequestHandlerBase::Observer>
|
||||
request_handler_observation_{this};
|
||||
|
||||
std::vector<device::AuthenticatorGetAssertionResponse> pending_responses_;
|
||||
base::OnceCallback<void(device::AuthenticatorGetAssertionResponse)>
|
||||
select_account_callback_;
|
||||
|
||||
base::WeakPtrFactory<ElectronAuthenticatorRequestClientDelegate>
|
||||
weak_factory_{this};
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // ELECTRON_SHELL_BROWSER_WEBAUTHN_ELECTRON_AUTHENTICATOR_REQUEST_CLIENT_DELEGATE_H_
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user