mirror of
https://github.com/stablyai/orca.git
synced 2026-10-20 08:03:28 +00:00
* fix(browser): scope Cmd/Ctrl+F find to the focused split (#11348) The browser pane's renderer-path Find handler is a window-global capture-phase keydown listener, but it armed on `isActive` (the active tab within its own group) rather than on whether its split holds focus. In a terminal+browser split, the browser was therefore `isActive` even while the terminal held keyboard focus, so it swallowed Cmd/Ctrl+F and opened find-in-page in the browser instead of find-in-terminal. Thread a focused-split signal (`isFocused`) from BrowserPaneOverlayLayer — derived from `activeGroupIdByWorktree` — down to the Find handler and gate the listener on it. This mirrors how terminal leaves already gate global shortcuts via `focusedGroupId` in TabGroupSplitLayout. Floating browser panels omit the prop and fall back to `isActive`, preserving their behavior. The IPC path (webview guest focused) is unchanged; it only fires when the guest genuinely has focus. Not platform-specific: the chord resolves through `keybindingMatchesAction` (Mod -> metaKey on macOS, ctrlKey elsewhere), so the same path is fixed on macOS, Linux, and Windows. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(browser): preserve Find before split focus settles * fix(browser): handle stale focused split IDs * fix(browser): route guest Find to source page * test(browser): wait for split address bar * test(browser): focus split before Find routing --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
52 lines
1.5 KiB
TypeScript
52 lines
1.5 KiB
TypeScript
import { isBrowserFindSource, type BrowserFindSource } from '../shared/browser-find-source'
|
|
|
|
type BrowserFindCallback = () => void
|
|
|
|
export function createBrowserFindSubscriptions(): {
|
|
dispatch: (source: unknown) => void
|
|
subscribe: (source: BrowserFindSource, callback: BrowserFindCallback) => () => void
|
|
} {
|
|
const callbacksByWorkspace = new Map<string, Map<string, Set<BrowserFindCallback>>>()
|
|
|
|
return {
|
|
dispatch: (source) => {
|
|
if (!isBrowserFindSource(source)) {
|
|
return
|
|
}
|
|
const callbacks = callbacksByWorkspace
|
|
.get(source.browserWorkspaceId)
|
|
?.get(source.browserPageId)
|
|
if (!callbacks) {
|
|
return
|
|
}
|
|
for (const callback of callbacks) {
|
|
callback()
|
|
}
|
|
},
|
|
subscribe: (source, callback) => {
|
|
let callbacksByPage = callbacksByWorkspace.get(source.browserWorkspaceId)
|
|
if (!callbacksByPage) {
|
|
callbacksByPage = new Map()
|
|
callbacksByWorkspace.set(source.browserWorkspaceId, callbacksByPage)
|
|
}
|
|
let callbacks = callbacksByPage.get(source.browserPageId)
|
|
if (!callbacks) {
|
|
callbacks = new Set()
|
|
callbacksByPage.set(source.browserPageId, callbacks)
|
|
}
|
|
callbacks.add(callback)
|
|
|
|
return () => {
|
|
callbacks.delete(callback)
|
|
if (callbacks.size > 0) {
|
|
return
|
|
}
|
|
callbacksByPage.delete(source.browserPageId)
|
|
if (callbacksByPage.size === 0) {
|
|
callbacksByWorkspace.delete(source.browserWorkspaceId)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|