Fix keyboard shortcuts not working with Korean (한글) input mode
When a non-Latin input source like Korean 두벌식 is active, event.charactersIgnoringModifiers returns Hangul characters (e.g. ㅅ for T key) instead of Latin letters. This caused all character-based shortcut matching to fail — Cmd+T, Cmd+D, Cmd+1-9, Ctrl+N/P, etc. Root cause: KeyboardLayout.character(forKeyCode:modifierFlags:) assumed CJK input sources lack kTISPropertyUnicodeKeyLayoutData, but Korean 두벌식 has it. UCKeyTranslate returned Korean characters and the ASCII fallback was never reached. Fix: - KeyboardLayout.character(): check result is ASCII before accepting; fall through to TISCopyCurrentASCIICapableKeyboardInputSource() when the current source returns non-ASCII characters - Add KeyboardLayout.normalizedCharacters(for:) helper that normalizes event.charactersIgnoringModifiers for shortcut comparison - Apply normalization in handleCustomShortcut (AppDelegate), BrowserPanelView omnibar key handler, and BrowserPopupWindowController Cmd+W handler Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6ff81579d9
commit
8cd9cd96c1
4 changed files with 31 additions and 8 deletions
|
|
@ -15,18 +15,22 @@ class KeyboardLayout {
|
|||
|
||||
/// Translate a physical keyCode to the character AppKit would use for shortcut matching,
|
||||
/// preserving command-aware layouts such as "Dvorak - QWERTY Command".
|
||||
/// CJK input sources (Korean, Chinese, Japanese) lack kTISPropertyUnicodeKeyLayoutData,
|
||||
/// so we fall back to TISCopyCurrentASCIICapableKeyboardInputSource() in that case.
|
||||
/// Some CJK input sources lack kTISPropertyUnicodeKeyLayoutData, and others (Korean
|
||||
/// 두벌식) have it but UCKeyTranslate still returns non-ASCII characters. In either
|
||||
/// case we fall back to TISCopyCurrentASCIICapableKeyboardInputSource().
|
||||
static func character(
|
||||
forKeyCode keyCode: UInt16,
|
||||
modifierFlags: NSEvent.ModifierFlags = []
|
||||
) -> String? {
|
||||
if let source = TISCopyCurrentKeyboardInputSource()?.takeRetainedValue(),
|
||||
let result = characterFromInputSource(source, forKeyCode: keyCode, modifierFlags: modifierFlags) {
|
||||
let result = characterFromInputSource(source, forKeyCode: keyCode, modifierFlags: modifierFlags),
|
||||
result.allSatisfy(\.isASCII) {
|
||||
return result
|
||||
}
|
||||
// Current input source has no Unicode layout data (e.g. Korean, Chinese, Japanese IME).
|
||||
// Fall back to the ASCII-capable source so shortcut matching still works.
|
||||
// Current input source has no Unicode layout data or returned a non-ASCII
|
||||
// character (e.g. Korean 두벌식 has layout data but UCKeyTranslate still
|
||||
// produces Hangul). Fall back to the ASCII-capable source so shortcut
|
||||
// matching still works.
|
||||
if let asciiSource = TISCopyCurrentASCIICapableKeyboardInputSource()?.takeRetainedValue(),
|
||||
let result = characterFromInputSource(asciiSource, forKeyCode: keyCode, modifierFlags: modifierFlags) {
|
||||
return result
|
||||
|
|
@ -34,6 +38,18 @@ class KeyboardLayout {
|
|||
return nil
|
||||
}
|
||||
|
||||
/// Return the ASCII-normalized equivalent of `event.charactersIgnoringModifiers`,
|
||||
/// falling back through the ASCII-capable input source for non-Latin input methods.
|
||||
/// Use this wherever code compares raw event characters against Latin shortcut keys.
|
||||
static func normalizedCharacters(for event: NSEvent) -> String {
|
||||
let raw = (event.charactersIgnoringModifiers ?? "").lowercased()
|
||||
if raw.allSatisfy(\.isASCII) { return raw }
|
||||
if let layoutChar = character(forKeyCode: event.keyCode, modifierFlags: []) {
|
||||
return layoutChar
|
||||
}
|
||||
return raw
|
||||
}
|
||||
|
||||
private static func characterFromInputSource(
|
||||
_ source: TISInputSource,
|
||||
forKeyCode keyCode: UInt16,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue