fix(keymap): Don't run the Enter that commits an input-method candidate

WebKit sends the Enter (or Space) that commits a candidate after compositionend,
with isComposing already false and keyCode 229. Handlers that checked isComposing
alone ran it: dialogs confirmed and shortcuts fired while typing Chinese or
Japanese. isImeKey() checks both, and every keydown handler that skipped
composition uses it.
Цей коміт міститься в:
l0ng-ai committed 2026-10-27 17:16:46 +08:00
1 джерело 2c576418cb
коміт f73c0a6b1d
10 files changed
+26 -9

No files matched your search

+8
Переглянути файл
@@ -0,0 +1,8 @@
/**
* True while an input method is composing, including the key that ends it: WebKit sends the
* Enter / Space that commits a candidate after `compositionend`, with `isComposing` already
* false and keyCode 229, so a handler checking `isComposing` alone runs that Enter.
*/
export function isImeKey(e: KeyboardEvent): boolean {
return e.isComposing || e.keyCode === 229;
}
+2 -1
Переглянути файл
@@ -18,6 +18,7 @@ import { intellijWindows } from "./keymaps/intellij-windows";
import { vscodeMacos } from "./keymaps/vscode-macos";
import { vscodeWindows } from "./keymaps/vscode-windows";
import { usePlatform } from "./platformInfo";
import { isImeKey } from "./ime";
export type Keymap = Record<string, string[]>;
@@ -439,7 +440,7 @@ export function installKeyboardDispatcher(target: Window = window, now: () => nu
if (runHeldGesture(e)) return reset();
resetTap();
otherKeyAt = e.key === "Escape" || e.key === "Tab" ? -Infinity : now();
if (e.isComposing) return;
if (isImeKey(e)) return;
const stroke = strokeOf(e);
if (!stroke) return;
const chord = pending.length > 0;