mirror of
https://github.com/stablyai/orca.git
synced 2026-09-23 16:02:24 +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>
60 lines
1.9 KiB
TypeScript
60 lines
1.9 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest'
|
|
import { createBrowserFindSubscriptions } from './browser-find-subscriptions'
|
|
|
|
const FIRST_SOURCE = {
|
|
browserPageId: 'page-1',
|
|
browserWorkspaceId: 'workspace-1'
|
|
}
|
|
const SAME_WORKSPACE_SOURCE = {
|
|
browserPageId: 'page-2',
|
|
browserWorkspaceId: FIRST_SOURCE.browserWorkspaceId
|
|
}
|
|
const SAME_PAGE_SOURCE = {
|
|
browserPageId: FIRST_SOURCE.browserPageId,
|
|
browserWorkspaceId: 'workspace-2'
|
|
}
|
|
|
|
describe('browser Find subscriptions', () => {
|
|
it('dispatches only to the exact browser page and workspace owner', () => {
|
|
const subscriptions = createBrowserFindSubscriptions()
|
|
const firstCallback = vi.fn()
|
|
const sameWorkspaceCallback = vi.fn()
|
|
const samePageCallback = vi.fn()
|
|
subscriptions.subscribe(FIRST_SOURCE, firstCallback)
|
|
subscriptions.subscribe(SAME_WORKSPACE_SOURCE, sameWorkspaceCallback)
|
|
subscriptions.subscribe(SAME_PAGE_SOURCE, samePageCallback)
|
|
|
|
subscriptions.dispatch(FIRST_SOURCE)
|
|
|
|
expect(firstCallback).toHaveBeenCalledOnce()
|
|
expect(sameWorkspaceCallback).not.toHaveBeenCalled()
|
|
expect(samePageCallback).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('rejects malformed and partial source identities', () => {
|
|
const subscriptions = createBrowserFindSubscriptions()
|
|
const callback = vi.fn()
|
|
subscriptions.subscribe(FIRST_SOURCE, callback)
|
|
|
|
subscriptions.dispatch(undefined)
|
|
subscriptions.dispatch({ browserPageId: FIRST_SOURCE.browserPageId })
|
|
subscriptions.dispatch({
|
|
browserPageId: FIRST_SOURCE.browserPageId,
|
|
browserWorkspaceId: ''
|
|
})
|
|
|
|
expect(callback).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('drops empty ownership entries when subscribers clean up', () => {
|
|
const subscriptions = createBrowserFindSubscriptions()
|
|
const callback = vi.fn()
|
|
const unsubscribe = subscriptions.subscribe(FIRST_SOURCE, callback)
|
|
|
|
unsubscribe()
|
|
subscriptions.dispatch(FIRST_SOURCE)
|
|
|
|
expect(callback).not.toHaveBeenCalled()
|
|
})
|
|
})
|