Chase Walden
Chase Walden

Reputation: 1302

theEvent charactersIgnoringModifiers - Get characters without modifiers

Im trying to implement a keyboard class in my game that has two modes. The game mode takes input that uses lowercase, unmodified keys (unmodified meaning if I type a '0' with the shift it still returns '0' instead of ')'). I have tracked it down as far as using the charactersIgnoringModifiers method of the NSEvent class but this method excludes all the modifier keys except for the shift key.

Upvotes: 6

Views: 887

Answers (2)

danneu
danneu

Reputation: 9444

The best option I could find so far for ignoring the <Shift> modifier is by using NSEvent.characters(byApplyingModifiers:) with a modifier that doesn't change the key glyph, i.e. .numericPad:

func onKeyDown(event: NSEvent) {
    let characters = event.characters(byApplyingModifiers: .numericPad)
    print("Key pressed: \(characters)")
}

Ideally you'd be able to pass in a mask that represents no modifiers at all, but the API doesn't seem to support it.

For completeness, here's how you could start writing a function that takes a UInt16 (CGKeyCode) and returns a string representation according to the user's keyboard:

func keyCodeToString(code: UInt16) -> String {
    switch code {
    // Keys that are the same across keyboards
    // TODO: Fill in the rest
    case 0x7A: return "<F1>"
    case 0x24: return "<Enter>"
    case 0x35: return "<Escape>"
        
    // Keys that change between keyboards
    default:
        let cgEvent = CGEvent(keyboardEventSource: nil, virtualKey: code, keyDown: true)!
        let nsEvent = NSEvent(cgEvent: cgEvent)!
        let characters = nsEvent.characters(byApplyingModifiers: .numericPad)
        return String(characters?.uppercased() ?? "<KeyCode: \(code)>")
    }
}

The goal being for the F1 key to display <F1>, but the ";" key to display ; on US keyboards but Ñ on Spanish keyboards.

Upvotes: 0

JWWalker
JWWalker

Reputation: 22707

You can use -[NSEvent keyCode] and then translate the key code to a character without using any modifiers. Doing the latter is easier said than done. Here's a long mailing list thread on the techniques and gotchas.

Upvotes: 5

Related Questions