fix(desktop): gate the Ctrl/Cmd+F main-process hook to Linux only (#81727)

The before-input-event handler was registered on every platform, so on macOS
and Windows — where the renderer's rebindable view.findInPage keybind already
owns Ctrl/Cmd+F — the chord became un-rebindable and would double-open when a
user remapped or cleared it. Restrict the install to process.platform ===
'linux' (the only platform #81727 affects); mac/Windows keep the renderer's
own keybind registry path.

Also corrects the docstring: the prior claim that 'GNOME Files owns Ctrl+F at
the windowing layer' is not accurate (Nautilus does not install global grabs).
The interception layer varies by distro/desktop; the fix sidesteps it by
acting at before-input-event regardless of cause, which is what actually
matters. The handler function itself stays platform-agnostic and injectable
for tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Chen Jin
2026-08-13 10:27:34 +08:00
committed by Teknium
parent 75f0602301
commit f5e531ded0
2 changed files with 21 additions and 13 deletions
+13 -7
View File
@@ -123,17 +123,23 @@ export function installFoundInPageForwarder(webContents: Electron.WebContents |
* Install a main-process before-input-event hook that claims Ctrl/Cmd+F and
* forwards an "open the find bar" intent to the renderer.
*
* On Pop!_OS / GNOME-based Linux distros, the GTK compositor intercepts
* Ctrl+F at the windowing layer (GNOME Files owns it) before the renderer
* ever sees a keydown — so the renderer's own `view.findInPage` keybind is
* silently dead even though the binding is registered (#81727). Claiming
* the chord in the main process via `before-input-event` runs strictly
* before the GTK shortcut can grab it on these distros.
* Linux only (#81727): on Pop!_OS / GNOME-based distros the Ctrl+F keydown
* does not reach the renderer's `view.findInPage` binding, so the find bar
* stays closed. Routing the chord through `before-input-event` (which Chromium
* dispatches before the DOM keydown) lets us forward the intent directly.
* The exact interception layer varies by distro/desktop (COSMIC shortcut,
* webview focus split, etc.); this sidesteps it regardless of cause by acting
* at the earliest point the keystroke is observable.
*
* On macOS / Windows the renderer's own rebindable `view.findInPage` keybind
* (`mod+f`, clearable/rebindable via the keybind registry) owns Ctrl/Cmd+F, so
* the main-process hook is NOT installed there — installing it would make the
* chord un-rebindable and double-open on a rebound binding.
*
* The renderer's existing find-in-page pipeline still does the actual work
* (it owns the FindBar UI, the store, the `hermes:find-in-page` IPC to drive
* `webContents.findInPage`). This helper just guarantees that a Ctrl/Cmd+F
* press reaches that pipeline.
* press reaches that pipeline on Linux.
*
* `isMac` is injectable so the macOS-modifier branch can be exercised by
* unit tests without rebooting the process under a different platform.
+8 -6
View File
@@ -10016,12 +10016,14 @@ function wireCommonWindowHandlers(win, { zoom = true }: { zoom?: boolean } = {})
installPreviewShortcut(win)
installDevToolsShortcut(win)
// Claim Ctrl/Cmd+F in the main process — on Pop!_OS / GNOME-based Linux
// distros the GTK compositor grabs Ctrl+F at the windowing layer before
// the renderer's keydown listener fires (#81727). Routing it through
// `before-input-event` strictly precedes that compositor shortcut, and
// the renderer's find-in-page pipeline still owns the FindBar UI and the
// search itself.
installFindShortcut(win)
// distros the Ctrl+F keydown does not reach the renderer's `view.findInPage`
// binding (#81727). Routing it through `before-input-event` forwards the
// intent at the earliest observable point. macOS / Windows keep the
// renderer's own rebindable keybind, so the hook is Linux-only: installing
// it elsewhere would make Ctrl/Cmd+F un-rebindable and double-open.
if (process.platform === 'linux') {
installFindShortcut(win)
}
if (zoom) {
installZoomShortcuts(win)