mirror of
https://github.com/stablyai/orca.git
synced 2026-10-06 08:02:28 +00:00
fix: stop carried IME shortcuts at renderer owner
This commit is contained in:
@@ -1952,6 +1952,9 @@ function App(): React.JSX.Element {
|
||||
const gesture = resolveImeModifierGesture(imeOwnedModifierGesture, e)
|
||||
imeOwnedModifierGesture = gesture.active
|
||||
if (gesture.owned || isImeOwnedKeyboardEvent(e)) {
|
||||
if (gesture.preventDefault) {
|
||||
e.preventDefault()
|
||||
}
|
||||
doubleTapDetector.reset()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -4,10 +4,21 @@ import {
|
||||
nativeChatToggleShortcutLabel
|
||||
} from './native-chat-shortcut'
|
||||
|
||||
type Combo = Pick<KeyboardEvent, 'key' | 'metaKey' | 'ctrlKey' | 'shiftKey' | 'altKey'>
|
||||
type Combo = Pick<
|
||||
KeyboardEvent,
|
||||
'key' | 'metaKey' | 'ctrlKey' | 'shiftKey' | 'altKey' | 'defaultPrevented'
|
||||
>
|
||||
|
||||
function combo(overrides: Partial<Combo>): Combo {
|
||||
return { key: 'j', metaKey: false, ctrlKey: false, shiftKey: false, altKey: false, ...overrides }
|
||||
return {
|
||||
key: 'j',
|
||||
metaKey: false,
|
||||
ctrlKey: false,
|
||||
shiftKey: false,
|
||||
altKey: false,
|
||||
defaultPrevented: false,
|
||||
...overrides
|
||||
}
|
||||
}
|
||||
|
||||
describe('nativeChatToggleShortcutLabel', () => {
|
||||
@@ -54,4 +65,13 @@ describe('matchesNativeChatToggleShortcut', () => {
|
||||
matchesNativeChatToggleShortcut(combo({ key: 'k', metaKey: true, shiftKey: true }), true)
|
||||
).toBe(false)
|
||||
})
|
||||
|
||||
it('yields events already owned by the app dispatcher', () => {
|
||||
expect(
|
||||
matchesNativeChatToggleShortcut(
|
||||
combo({ ctrlKey: true, shiftKey: true, defaultPrevented: true }),
|
||||
false
|
||||
)
|
||||
).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -17,10 +17,13 @@ export function nativeChatToggleShortcutLabel(isMac: boolean): string {
|
||||
/** True when the event is the native-chat toggle chord for the given platform.
|
||||
* Pure so it can be unit-tested without a DOM. */
|
||||
export function matchesNativeChatToggleShortcut(
|
||||
e: Pick<KeyboardEvent, 'key' | 'metaKey' | 'ctrlKey' | 'shiftKey' | 'altKey'>,
|
||||
e: Pick<
|
||||
KeyboardEvent,
|
||||
'key' | 'metaKey' | 'ctrlKey' | 'shiftKey' | 'altKey' | 'defaultPrevented'
|
||||
>,
|
||||
isMac: boolean
|
||||
): boolean {
|
||||
if (e.altKey || !e.shiftKey) {
|
||||
if (e.defaultPrevented || e.altKey || !e.shiftKey) {
|
||||
return false
|
||||
}
|
||||
// Primary modifier is Cmd on Mac, Ctrl on Linux/Windows — and must be the
|
||||
|
||||
@@ -98,9 +98,9 @@ export function useNativeChatToggleShortcut(worktreeId: string, isWorktreeActive
|
||||
e.stopPropagation()
|
||||
state.toggleTabViewMode(tab.id)
|
||||
}
|
||||
window.addEventListener('keydown', onKeyDown, { capture: true })
|
||||
window.addEventListener('keydown', onKeyDown)
|
||||
return () => {
|
||||
window.removeEventListener('keydown', onKeyDown, { capture: true })
|
||||
window.removeEventListener('keydown', onKeyDown)
|
||||
}
|
||||
}, [worktreeId, isWorktreeActive])
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ describe('isImeCompositionKeyDown', () => {
|
||||
ctrlKey: true,
|
||||
isComposing: true
|
||||
})
|
||||
expect(gesture).toEqual({ active: true, owned: true })
|
||||
expect(gesture).toEqual({ active: true, owned: true, preventDefault: false })
|
||||
|
||||
gesture = resolveImeModifierGesture(gesture.active, {
|
||||
ctrlKey: true,
|
||||
@@ -62,18 +62,18 @@ describe('isImeCompositionKeyDown', () => {
|
||||
shiftKey: true,
|
||||
isComposing: false
|
||||
})
|
||||
expect(gesture).toEqual({ active: true, owned: true })
|
||||
expect(gesture).toEqual({ active: true, owned: true, preventDefault: true })
|
||||
|
||||
gesture = resolveImeModifierGesture(gesture.active, {
|
||||
isComposing: false
|
||||
})
|
||||
expect(gesture).toEqual({ active: false, owned: true })
|
||||
expect(gesture).toEqual({ active: false, owned: true, preventDefault: true })
|
||||
expect(
|
||||
resolveImeModifierGesture(false, {
|
||||
ctrlKey: true,
|
||||
shiftKey: true,
|
||||
isComposing: false
|
||||
})
|
||||
).toEqual({ active: false, owned: false })
|
||||
).toEqual({ active: false, owned: false, preventDefault: false })
|
||||
})
|
||||
})
|
||||
|
||||
@@ -27,10 +27,11 @@ export function isImeOwnedKeyboardEvent(event: object): boolean {
|
||||
export function resolveImeModifierGesture(
|
||||
active: boolean,
|
||||
event: ImeModifierGestureEvent
|
||||
): { active: boolean; owned: boolean } {
|
||||
): { active: boolean; owned: boolean; preventDefault: boolean } {
|
||||
const hasModifier = Boolean(event.altKey || event.ctrlKey || event.metaKey || event.shiftKey)
|
||||
const owned = active || (hasModifier && isImeOwnedKeyboardEvent(event))
|
||||
return { active: owned && hasModifier, owned }
|
||||
const marked = isImeOwnedKeyboardEvent(event)
|
||||
const owned = active || (hasModifier && marked)
|
||||
return { active: owned && hasModifier, owned, preventDefault: active && !marked }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user