mac/input: add support for dead key reporting

dead keys like tilde and accents were not reported because they returned
an empty string from the NSEvent.

try to retrieve dead key with alternative Carbon API when an empty key
is reported.
This commit is contained in:
der richter 2024-04-21 17:02:36 +02:00
parent f7a32b5f29
commit 2e03e0305c
1 changed files with 20 additions and 1 deletions

View File

@ -107,7 +107,9 @@ class InputHelper: NSObject {
}
guard let chars = event.characters, let charsNoMod = event.charactersIgnoringModifiers else { return false }
let key = (useAltGr() && event.modifierFlags.contains(.optionRight)) ? chars : charsNoMod
var key = (useAltGr() && event.modifierFlags.contains(.optionRight)) ? chars : charsNoMod
if key.isEmpty { key = mapDeadKey(event) }
if key.isEmpty { return false }
key.withCString {
var bstr = bstr0($0)
putKey(bstr_decode_utf8(bstr, &bstr), modifiers: event.modifierFlags, type: event.type)
@ -230,6 +232,23 @@ class InputHelper: NSObject {
return Int32(buttonMapping[button] ?? SWIFT_MBTN9 + Int32(button - 5));
}
func mapDeadKey(_ event: NSEvent) -> String {
let keyboard = TISCopyCurrentKeyboardInputSource().takeRetainedValue()
let layoutPtr = TISGetInputSourceProperty(keyboard, kTISPropertyUnicodeKeyLayoutData)
let layoutData = unsafeBitCast(layoutPtr, to: CFData.self)
let layout = unsafeBitCast(CFDataGetBytePtr(layoutData), to: UnsafePointer<UCKeyboardLayout>.self)
let maxLength = 2
let modifiers: UInt32 = UInt32(event.modifierFlags.rawValue >> 16) & 0xff
var deadKeyState: UInt32 = 0
var length = 0
var chars = [UniChar](repeating: 0, count: maxLength)
let err = UCKeyTranslate(layout, event.keyCode, UInt16(kUCKeyActionDisplay), modifiers,
UInt32(LMGetKbdType()), 0, &deadKeyState, maxLength, &length, &chars)
if err != noErr || length < 1 { return "" }
return String(utf16CodeUnits: chars, count: length)
}
@objc func open(files: [String], append: Bool = false) {
lock.withLock {
guard let input = input else { return }