* feat: add `Notification.getHistory()` static method (macOS)
Add `Notification.getHistory()` which returns a `Promise<Notification[]>`
of all delivered notifications still present in Notification Center.
Each returned Notification is a live object connected to the corresponding
delivered notification — interaction events (click, reply, action, close)
will fire on these objects, enabling apps to re-attach event handlers after
a restart.
Key implementation details:
- Queries UNUserNotificationCenter's getDeliveredNotifications API
- Creates live Notification objects with populated id, groupId, title,
subtitle, and body properties from what macOS provides
- Registers each object with the presenter via Restore() so the
NotificationCenterDelegate routes events correctly
- Restored notifications use is_restored_ flag to prevent removal from
Notification Center when the JS object is garbage collected
- Requires code-signed builds (unsigned builds resolve with empty array)
Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com>
* test: fix typecheck
* fix: avoid dangling presenter pointer in GetHistory callback
* fix: document show() behavior
Notifications returned by getHistory() now set is_restored_ so that Dismiss() skips removal from Notification Center on GC. Calling show() on a restored notification removes the original from NC and posts a new one.
* fix: address code review feedback
* test: fix oxfmt linting
* docs: update docs/api/notification.md
Co-authored-by: Erick Zhao <erick@hotmail.ca>
---------
Co-authored-by: Claude <svc-devxp-claude@slack-corp.com>
Co-authored-by: Erick Zhao <erick@hotmail.ca>
* refactor: MessageChannel does not need to extend EventEmitter
Added in f66d4c7 but never used.
Apparently added as a copy-paste side effect when adding better interface
info into the lib types, eg extends/implements.
* refactor: ShareMenu does not need to extend EventEmitter
Added in f66d4c7 but never used.
Apparently added as a copy-paste side effect when adding better interface
info into the lib types, eg extends/implements.
* refactor: migrate electron::api::GlobalShortcut to cppgc
* refactor: lazy-create electron::api::GlobalShortcut
copy the lazy-create idom used by electron::api::Screen
* refactor: use gin::WeakCellFactory in GlobalCallbacks
* fix: make a copy of `callback` before running it
safeguard against the callback changing the map, invalidating `cb`
* chore: reduce unnecessary diffs with main
* fixup! refactor: use gin::WeakCellFactory in GlobalCallbacks
fix: must Trace() the weak cell factory
* fix: destruction order
- Setup isolate dispose observer to run destruction sequences
and remove self persistent reference
- Skip NOTREACHED check during destruction, it can happen
as a result of plaform listeners scheduling callbacks when Unregister is invoked.
- Fix the order of unregistration in GlobalShortcut::Unregister
- Add GlobalShortcut::UnregisterAllInternal to avoid any callsites
that can re-enter V8
* fix: crash during gc from incorrect cppgc object headers
* chore: update patches
* chore: cleanup
* chore: fix lint
---------
Co-authored-by: deepak1556 <hop2deep@gmail.com>
* build: add oxfmt for code formatting and import sorting
Adds oxfmt as a devDependency alongside oxlint and wires it into the
lint pipeline. The .oxfmtrc.json config matches Electron's current JS
style (single quotes, semicolons, 2-space indent, trailing commas off,
printWidth 100) and configures sortImports with custom groups that
mirror the import/order pathGroups previously enforced by ESLint:
@electron/internal, @electron/*, and {electron,electron/**} each get
their own ordered group ahead of external modules.
- `yarn lint:fmt` runs `oxfmt --check` over JS/TS sources and is
chained into `yarn lint` so CI enforces it automatically.
- `yarn format` runs `oxfmt --write` for local fix-up.
- lint-staged invokes `oxfmt --write` on staged .js/.ts/.mjs/.cjs
files before oxlint, so formatting is applied at commit time.
The next commit applies the formatter to the existing codebase so the
check actually passes.
* chore: apply oxfmt formatting to JS and TS sources
Runs `yarn format` across lib/, spec/, script/, build/, default_app/,
and npm/ to bring the codebase in line with the .oxfmtrc.json settings
added in the previous commit. This is a pure formatting pass: import
statements are sorted into the groups defined by the config, method
chains longer than printWidth are broken, single-quoted strings
containing apostrophes are switched to double quotes, and a handful of
single-statement `if` bodies are re-wrapped and get braces added by
`oxlint --fix` to satisfy the `curly: multi-line` rule.
No behavior changes.
fix: return numeric `blksize` and `blocks` from asar `fs.stat`
Previously, `fs.stat` on files inside `.asar` archives returned
`undefined` for `blksize` and `blocks`, violating the Node.js API
contract where these fields must be `number | bigint`.
Use `4096` for `blksize` (matching the convention used by `memfs` and
the proposed `node:vfs` module in nodejs/node#61478) and compute
`blocks` as `ceil(size / 512)` (standard 512-byte block units).
Fixes#42686
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: remove Electron links from default help menu
* fix: remove help menu entirely from default menu
* fix: move Electron help menu links to default app
* docs: update default menu items list in menu.md
Consolidates the root .eslintrc.json and five nested configs (build,
script, docs, default_app, spec) into a single .oxlintrc.json at the
repo root. script/lint.js now shells out to the oxlint binary from
node_modules/.bin instead of using the ESLint Node API, and emits
GitHub Actions annotations directly via --format=github in CI
(replacing the deleted eslint-stylish problem matcher).
Oxlint has no markdown processor, so the ESLint-based lint of JS code
blocks in docs/**/*.md is replaced with an inline regex check for bare
Node.js builtin imports. This preserves the rule docs/.eslintrc.json
was originally added for in #42113; the rest of the standard ruleset on
docs code blocks was already being enforced in parallel by
lint-roller-markdown-standard.
The frameNamesToWindow map was a holdover from the BrowserWindowProxy
IPC shim. Since nativeWindowOpen became the only code path, Blink's
FrameTree::FindOrCreateFrameForNavigation resolves named window targets
directly in the renderer, scoped to the opener's browsing context
group. When a matching named window exists, Blink navigates it without
ever sending a CreateNewWindow IPC to the browser, so this map was
never consulted in the legitimate same-opener case.
The only time the map found a match was when two unrelated renderers
happened to use the same target name, in which case openGuestWindow
would short-circuit before consuming the guest WebContents that
Chromium had already created for the new window, leaking it.
Adds a test verifying Blink handles same-opener named-target reuse
end-to-end without any browser-side tracking.
* feat: add copyVideoFrameAt and saveVideoFrameAs Method on Webcontent
chore: change the description of savevideoframe api
chore: add the description of the restrictive elements for using the APIs.
move to webframemain
fixed mediaPlayerAction to kSaveVideoFrameAs
Update spec/api-web-frame-main-spec.ts
Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
Update spec/api-web-frame-main-spec.ts
Co-authored-by: John Kleinschmidt <kleinschmidtorama@gmail.com>
fixed clipboard tests for video frame copying
fixed test for copying video frame to clipboard. check video loaded before copy video frame in test.
chore: try non-proprietary video format
Revert "chore: try non-proprietary video format"
This reverts commit ef085f88a1af53b6408a7af695cc60b8681398cf.
fix: format video as file url
* test: skip webFrameMain.copyVideoFrameAt on win32 CI due Chromium DCHECK
* build(deps-dev): replace timers-browserify
Co-Authored-By: Claude <noreply@anthropic.com>
Generated-By: GitHub Copilot
* update shim from js to ts
Co-Authored-By: Claude <noreply@anthropic.com>
Generated-By: GitHub Copilot
* remove timers-shim.js
* remove refs from package json and yarn lock
* update process in yarn lock
---------
Co-authored-by: Claude <noreply@anthropic.com>
The sender-mismatch check in invokeInWebContents and invokeInWebFrameMain
used a negative condition (`type === 'frame' && sender !== expected`),
which only rejected mismatched frame senders and accepted anything else.
Invert to a positive check so only the exact expected frame can resolve
the reply — matches the guard style used elsewhere in lib/browser/.
PowerMonitor registered OS-level callbacks (HWND UserData and
WTS/suspend notifications on Windows, shutdown handler and lock-screen
observer on macOS) but never cleaned them up in its destructor. The JS
layer also only held the native object in a closure-local variable,
allowing GC to reclaim it while those registrations still referenced
freed memory.
Retain the native PowerMonitor at module level in power-monitor.ts so
it cannot be garbage-collected. Add DestroyPlatformSpecificMonitors()
to properly tear down OS registrations on destruction: on Windows,
unregister WTS and suspend notifications, clear GWLP_USERDATA, and
destroy the HWND; on macOS, remove the emitter from the global
MacLockMonitor and reset the Browser shutdown handler.
ElectronRendererClient::DidCreateScriptContext (and the worker
equivalent) save Blink's fetch/Response/FormData/Request/Headers/
EventSource as temporary globalThis.blink* properties before Node
initialization may overwrite them. node/init.ts and worker/init.ts
restore the originals but previously never deleted the temporary
blink* globals.
They persisted as non-standard global pollution visible to page
content when contextIsolation is disabled -- a minor fingerprinting
signal and a bypass for any preload that wraps window.fetch (page
could call blinkfetch() instead).
* feat: webFrameMain.fromFrameToken
* refactor: return null instead of undefined
* docs: mention renderer webFrame property
* chore: undo null->undefined in wfm.fromId api
this will be updated in another pr
fix: window.open popups are always resizable
Closes https://github.com/electron/electron/issues/43591.
Per current WHATWG spec, the `window.open` API should always
create a resizable popup window. This change updates the
`parseFeaturesString` function to ensure that windows opened
with `window.open` are always resizable, regardless of the
`resizable` feature string.