terminal-focus-state.ts
1 // Terminal focus state signal — non-React access to DECSET 1004 focus events. 2 // 'unknown' is the default for terminals that don't support focus reporting; 3 // consumers treat 'unknown' identically to 'focused' (no throttling). 4 // Subscribers are notified synchronously when focus changes, used by 5 // TerminalFocusProvider to avoid polling. 6 export type TerminalFocusState = 'focused' | 'blurred' | 'unknown' 7 8 let focusState: TerminalFocusState = 'unknown' 9 const resolvers: Set<() => void> = new Set() 10 const subscribers: Set<() => void> = new Set() 11 12 export function setTerminalFocused(v: boolean): void { 13 focusState = v ? 'focused' : 'blurred' 14 // Notify useSyncExternalStore subscribers 15 for (const cb of subscribers) { 16 cb() 17 } 18 if (!v) { 19 for (const resolve of resolvers) { 20 resolve() 21 } 22 resolvers.clear() 23 } 24 } 25 26 export function getTerminalFocused(): boolean { 27 return focusState !== 'blurred' 28 } 29 30 export function getTerminalFocusState(): TerminalFocusState { 31 return focusState 32 } 33 34 // For useSyncExternalStore 35 export function subscribeTerminalFocus(cb: () => void): () => void { 36 subscribers.add(cb) 37 return () => { 38 subscribers.delete(cb) 39 } 40 } 41 42 export function resetTerminalFocusState(): void { 43 focusState = 'unknown' 44 for (const cb of subscribers) { 45 cb() 46 } 47 }