diff --git a/src/renderer/src/components/editor/useRichMarkdownSearch.adversarial.test.tsx b/src/renderer/src/components/editor/useRichMarkdownSearch.adversarial.test.tsx index 8eb7f376d47..5e36e7762b6 100644 --- a/src/renderer/src/components/editor/useRichMarkdownSearch.adversarial.test.tsx +++ b/src/renderer/src/components/editor/useRichMarkdownSearch.adversarial.test.tsx @@ -91,6 +91,43 @@ afterEach(() => { }) describe('rich Markdown search adversarial interactions', () => { + it.each([{ isComposing: true }, { keyCode: 229 }])( + 'keeps Find open when Escape belongs to the IME (%o)', + (init) => { + const { hook, input, query } = mountSearch() + query('beta') + const event = new KeyboardEvent('keydown', { + key: 'Escape', + bubbles: true, + cancelable: true, + ...init + }) + + act(() => input.dispatchEvent(event)) + + expect(hook.result.current.searchState.isSearchOpen).toBe(true) + expect(hook.result.current.searchState.searchQuery).toBe('beta') + expect(document.activeElement).toBe(input) + expect(event.defaultPrevented).toBe(false) + } + ) + + it('still closes Find and returns to the editor on plain Escape', () => { + const { hook, editor, input } = mountSearch() + const event = new KeyboardEvent('keydown', { + key: 'Escape', + bubbles: true, + cancelable: true + }) + + act(() => input.dispatchEvent(event)) + act(() => vi.runOnlyPendingTimers()) + + expect(hook.result.current.searchState.isSearchOpen).toBe(false) + expect(document.activeElement).toBe(editor.view.dom) + expect(event.defaultPrevented).toBe(true) + }) + it('does not revive a delayed search after a document click and another control focus', () => { const { editor, hook, otherControl, query, documentCaret, scrollTo } = mountSearch() query('beta') diff --git a/src/renderer/src/components/editor/useRichMarkdownSearch.ts b/src/renderer/src/components/editor/useRichMarkdownSearch.ts index d0adaa2ae09..79a2a2582a0 100644 --- a/src/renderer/src/components/editor/useRichMarkdownSearch.ts +++ b/src/renderer/src/components/editor/useRichMarkdownSearch.ts @@ -15,6 +15,7 @@ import { import { createRichMarkdownSearchMatchesCache } from './rich-markdown-search-matches-cache' import { useRichMarkdownSearchHighlights } from './useRichMarkdownSearchHighlights' import { addAppKeyListener, removeAppKeyListener } from '@/lib/app-keyboard-router' +import { isImeOwnedKeyboardEvent } from '@/lib/ime-composition-keyboard-event' export function useRichMarkdownSearch({ editor, @@ -269,7 +270,7 @@ export function useRichMarkdownSearch({ useEffect(() => { const handleKeyDown = (event: KeyboardEvent): void => { const root = rootRef.current - if (!root) { + if (!root || isImeOwnedKeyboardEvent(event)) { return }