mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-01 12:02:05 +00:00
refactor(desktop): generalize focus check to isFocusWithin primitive
Replace the one-off isTerminalFocused with isFocusWithin(selector) in the
keybinds lib (beside isEditableTarget) — the reusable primitive for any
focus-scoped shortcut. The terminal marks itself data-terminal and the ⌘W
handler routes via isFocusWithin('[data-terminal]'); future surfaces just add
their own marker.
This commit is contained in:
parent
2d55ff8fca
commit
b02f453496
4 changed files with 12 additions and 8 deletions
|
|
@ -10,6 +10,7 @@ import { GatewayConnectingOverlay } from '@/components/gateway-connecting-overla
|
|||
import { Pane, PaneMain } from '@/components/pane-shell'
|
||||
import { RemoteDisplayBanner } from '@/components/remote-display-banner'
|
||||
import { useMediaQuery } from '@/hooks/use-media-query'
|
||||
import { isFocusWithin } from '@/lib/keybinds/combo'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { useSkinCommand } from '@/themes/use-skin-command'
|
||||
|
||||
|
|
@ -129,7 +130,7 @@ import { ReviewPane } from './right-sidebar/review'
|
|||
import { $terminalTakeover } from './right-sidebar/store'
|
||||
import { TerminalPaneChrome } from './right-sidebar/terminal/chrome'
|
||||
import { PersistentTerminal } from './right-sidebar/terminal/persistent'
|
||||
import { closeActiveTerminal, isTerminalFocused } from './right-sidebar/terminal/terminals'
|
||||
import { closeActiveTerminal } from './right-sidebar/terminal/terminals'
|
||||
import { CRON_ROUTE, NEW_CHAT_ROUTE, routeSessionId, sessionRoute, SETTINGS_ROUTE } from './routes'
|
||||
import { SessionPickerOverlay } from './session-picker-overlay'
|
||||
import { SessionSwitcher } from './session-switcher'
|
||||
|
|
@ -397,7 +398,7 @@ export function DesktopController() {
|
|||
// Terminal focused: ⌘W closes the active terminal. Ctrl+W is left untouched
|
||||
// for the shell's werase, and nothing else may steal ⌘/Ctrl+W from a
|
||||
// focused terminal (so it never closes a preview tab out from under it).
|
||||
if (isTerminalFocused()) {
|
||||
if (isFocusWithin('[data-terminal]')) {
|
||||
if (event.metaKey && !event.ctrlKey) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ export function TerminalInstance({ id, active, cwd, onAddSelectionToChat }: Term
|
|||
'absolute inset-0 flex flex-col bg-(--ui-editor-surface-background) px-2 pb-2 pt-0',
|
||||
active ? 'visible' : 'invisible pointer-events-none'
|
||||
)}
|
||||
// Focus-scope marker so isFocusWithin('[data-terminal]') can route ⌘W here.
|
||||
data-terminal=""
|
||||
>
|
||||
{status === 'starting' && (
|
||||
<div className="pointer-events-none absolute inset-0 z-10 grid place-items-center">
|
||||
|
|
|
|||
|
|
@ -95,12 +95,6 @@ export function closeActiveTerminal(): void {
|
|||
}
|
||||
}
|
||||
|
||||
/** True while an in-app terminal's xterm holds focus (its helper textarea is the
|
||||
* active element) — lets ⌘W close the focused terminal without a ref dance. */
|
||||
export function isTerminalFocused(): boolean {
|
||||
return document.activeElement?.classList.contains('xterm-helper-textarea') ?? false
|
||||
}
|
||||
|
||||
export function closeOtherTerminals(id: string): void {
|
||||
const keep = $terminals.get().find(term => term.id === id)
|
||||
|
||||
|
|
|
|||
|
|
@ -175,6 +175,13 @@ export function formatCombo(combo: string): string {
|
|||
return IS_MAC ? tokens.join('') : tokens.join('+')
|
||||
}
|
||||
|
||||
// True when focus currently sits inside an element matching `selector`. The
|
||||
// primitive for focus-scoped shortcuts — e.g. routing ⌘W to whichever surface
|
||||
// (terminal, preview, …) owns focus.
|
||||
export function isFocusWithin(selector: string): boolean {
|
||||
return document.activeElement?.closest(selector) != null
|
||||
}
|
||||
|
||||
// True when focus is in a text-entry surface, so bare-key shortcuts don't fire
|
||||
// while the user is typing.
|
||||
export function isEditableTarget(target: EventTarget | null): boolean {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue