Skip to content

Commit

Permalink
mac/input: add support for dead key reporting
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Akemi committed Apr 24, 2024
1 parent f7a32b5 commit 2e03e03
Showing 1 changed file with 20 additions and 1 deletion.
21 changes: 20 additions & 1 deletion osdep/mac/input_helper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 }
Expand Down

0 comments on commit 2e03e03

Please sign in to comment.