Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add a NSMenuItem.keyEquivalent compatible string transformation #10

Closed
DivineDominion opened this issue Mar 14, 2018 · 3 comments
Closed

Comments

@DivineDominion
Copy link
Contributor

DivineDominion commented Mar 14, 2018

I suggest adding a convenience function next to KeyCodeTransformer.transformValue(_:carbonModifiers:) that outputs a NSMenuItem-compatible String. Because transformValue produces a printable, upper-case letter, using this as NSMenuItem.keyEquivalent will result in always adding the ⇧ (Shift) modifier key.

The proposed KeyCodeTransformer.keyEquivalent should behave like this for example:

  • ⌃⇧T should return "T"
  • ⌥T should return "t"
  • ⌘⌥⇧⌃1 should return "1"

What do you think?


It's basically a refactoring:

    fileprivate func transformValue(_ keyCode: Int, modifiers: Int) -> String {
        return keyEquivalent(keyCode, modifiers).uppercased
    }

    fileprivate func keyEquivalent(_ keyCode: Int, modifiers: Int) -> String {
        // Return Special KeyCode
        if let unmappedString = transformSpecialKeyCode(keyCode) {
            return unmappedString
        }

        let source = TISCopyCurrentASCIICapableKeyboardLayoutInputSource().takeUnretainedValue()
        let layoutData = TISGetInputSourceProperty(source, kTISPropertyUnicodeKeyLayoutData)
        let dataRef = unsafeBitCast(layoutData, to: CFData.self)

        let keyLayout = unsafeBitCast(CFDataGetBytePtr(dataRef), to: UnsafePointer<CoreServices.UCKeyboardLayout>.self)

        let keyTranslateOptions = OptionBits(CoreServices.kUCKeyTranslateNoDeadKeysBit)
        var deadKeyState: UInt32 = 0
        let maxChars = 256
        var chars = [UniChar](repeating: 0, count: maxChars)
        var length = 0

        let error = CoreServices.UCKeyTranslate(keyLayout,
                                                UInt16(keyCode),
                                                UInt16(CoreServices.kUCKeyActionDisplay),
                                                UInt32(modifiers),
                                                UInt32(LMGetKbdType()),
                                                keyTranslateOptions,
                                                &deadKeyState,
                                                maxChars,
                                                &length,
                                                &chars)

        if error != noErr { return "" }

        return NSString(characters: &chars, length: length)
    }
@Econa77
Copy link
Member

Econa77 commented Apr 30, 2020

@DivineDominion KeyCodeTransformer.transformValue(_:carbonModifiers:) could not return T with ⇧T because it had not been able to correctly consider the modifier before.
From v3.0.0, string generation has been migrated to the Sauce.framework.
This library can be used to generate the correct string with modifiers 🎉

@DivineDominion
Copy link
Contributor Author

Good to know, and I'm glad to see progress on this because I really like the lib :)

@DivineDominion
Copy link
Contributor Author

@Econa77 FYI, I finally updated my dependencies and it works well with the Sauce framework transformations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants