KeyCode to Character mapping

  • Hi

    I am developing a desktop application on cocoa and am trying to handle the
    menu keyboard shortcuts on my own.
    For this, I have to map the scan code that I receive into a character.

    I was trying to do this using [NSEvent charactersIgnoringModifiers]. But
    despite its promising name, it doesn't seem to be ignoring Shift and gives
    me for eg: @ on pressing Shift+2. I wanted a '2' as the character.

    On searching the net, I found a workaround of using the following code:

    NSString* str = nil;
    TISInputSourceRef inputSourceRef TISCopyCurrentKeyboardLayoutInputSource();
    if (inputSourceRef)
    {
    CFDataRef dataRef = (CFDataRef)TISGetInputSourceProperty(inputSourceRef,
    kTISPropertyUnicodeKeyLayoutData);
    if (dataRef)
    {
    const UCKeyboardLayout* keyboardLayout = (const
    UCKeyboardLayout*)CFDataGetBytePtr(dataRef);
    if (keyboardLayout)
    {
    const UniCharCount maxStrLen = 255;
    UniChar strBuff[maxStrLen];
    UniCharCount actualLength = 0;
    UInt32 deadKeyState = 0;
    OSStatus status = UCKeyTranslate(keyboardLayout, inScanCode,
    kUCKeyActionDown, inModifiers, LMGetKbdType(),
    kUCKeyTranslateNoDeadKeysBit, &deadKeyState, maxStrLen, &actualLength,
    strBuff);
    if (status == noErr && actualLength > 0)
    {
    str = [NSString stringWithCharacters:strBuff length:actualLength];
    }
    }
    }
    CFRelease(inputSourceRef);
    }

    This works fine for English language but when I use an IME, say for example
    Cangjie, Zhuyin,etc things start to mess up. I have for eg a keyboard
    shortcut of Cmd+N for opening a new file. But on pressing 'N' on these
    IME's I get a japanese/chinese character which obviously doesn't match up
    with 'N' and hence the shortcut doesn't work.

    What I want is that even on changing to different IME's my keyboard
    shortcuts should work just like US IME. On pressing 'N' I want to be able
    to translate the inScanCode to 'N' despite the current IME.

    For this I tried translating using TISCopy**********************************
    ********InputSource*F**o**r**L**a**n**g**u**a**g**e*(*(**C**F**S**t**r**i**n
    **g**R**e**f**)**@**"**e**n**"*) instead
    of TISCopyCurrentKeyboardLayoutInputSource(). Now, I am unable to support
    different Keyboard layouts. If someone plugs-in a non standard qwerty
    keyboard, the shortcuts again mess up.

    So basically, what I want is that I should be able to get the character
    according to the keyboard plugged-in, irrespective of the IME. I've tried a
    lot of ways but am somehow not able to get it right.
    Anyone knows a way I could do this?

    Or is my understanding of how keyboard shortcuts are supposed to work with
    different IME's and keyboard layouts a bit flawed? Views on that are
    welcome too.

    Regards,
    Akhil Jindal
  • On Jan 24, 2012, at 1:30 AM, Akhil Jindal wrote:

    > I am developing a desktop application on cocoa and am trying to handle the
    > menu keyboard shortcuts on my own.

    That's weird.  Why?  Maybe your reasons for doing so are based on faulty assumptions or what you're _really_ trying to accomplish -- since I very much doubt that handling menu keyboard shortcuts is a first-order interest of yours -- can be done a different way that doesn't require this.

    > OSStatus status = UCKeyTranslate(keyboardLayout, inScanCode,
    > kUCKeyActionDown, inModifiers, LMGetKbdType(),
    > kUCKeyTranslateNoDeadKeysBit, &deadKeyState, maxStrLen, &actualLength,
    > strBuff);

    > This works fine for English language but when I use an IME, say for example
    > Cangjie, Zhuyin,etc things start to mess up. I have for eg a keyboard
    > shortcut of Cmd+N for opening a new file. But on pressing 'N' on these
    > IME's I get a japanese/chinese character which obviously doesn't match up
    > with 'N' and hence the shortcut doesn't work.

    What are you passing in for the modifiers?  I would expect that passing in cmdKeyBit would result in UCKeyTranslate returning latin characters.

    Regards,
    Ken
  • On Wed, Jan 25, 2012 at 1:24 PM, Ken Thomases <ken...> wrote:

    > On Jan 24, 2012, at 1:30 AM, Akhil Jindal wrote:
    >
    >> I am developing a desktop application on cocoa and am trying to handle
    > the
    >> menu keyboard shortcuts on my own.
    >
    > That's weird.  Why?  Maybe your reasons for doing so are based on faulty
    > assumptions or what you're _really_ trying to accomplish -- since I very
    > much doubt that handling menu keyboard shortcuts is a first-order interest
    > of yours -- can be done a different way that doesn't require this.
    >
    >
    > Well, I would very much like it if I could let the OS handle it. The
    problem is that I have some keyboard shortcuts associated with hidden
    menus. Cocoa doesn't seem to be able to handle that!

    >> OSStatus status = UCKeyTranslate(keyboardLayout, inScanCode,
    >> kUCKeyActionDown, inModifiers, LMGetKbdType(),
    >> kUCKeyTranslateNoDeadKeysBit, &deadKeyState, maxStrLen, &actualLength,
    >> strBuff);
    >
    >> This works fine for English language but when I use an IME, say for
    > example
    >> Cangjie, Zhuyin,etc things start to mess up. I have for eg a keyboard
    >> shortcut of Cmd+N for opening a new file. But on pressing 'N' on these
    >> IME's I get a japanese/chinese character which obviously doesn't match up
    >> with 'N' and hence the shortcut doesn't work.
    >
    > What are you passing in for the modifiers?  I would expect that passing in
    > cmdKeyBit would result in UCKeyTranslate returning latin characters.
    >

    I'm not passing in any modifiers. I've initialised inModifiers as 0.
    I tried passing in cmdKeyBit as the modifier but with that UCKeyTranslate()
    is returning actualLength as 0 on pressing Cmd+N on US IME itself.

    > Regards,
    > Ken
    >
    >
  • On Jan 25, 2012, at 5:03 AM, Akhil Jindal wrote:

    > On Wed, Jan 25, 2012 at 1:24 PM, Ken Thomases <ken...> wrote:
    >
    >> What are you passing in for the modifiers?  I would expect that passing in cmdKeyBit would result in UCKeyTranslate returning latin characters.
    >
    > I'm not passing in any modifiers. I've initialised inModifiers as 0.
    > I tried passing in cmdKeyBit as the modifier but with that UCKeyTranslate() is returning actualLength as 0 on pressing Cmd+N on US IME itself.

    Oops, sorry.  I should have said "cmdKey" instead of "cmdKeyBit", and I should have also said it needs to be right-shifted by 8 bits.  So, try passing cmdKey >> 8.

    Cheers,
    Ken
  • On Wed, Jan 25, 2012 at 5:09 PM, Ken Thomases <ken...> wrote:

    > On Jan 25, 2012, at 5:03 AM, Akhil Jindal wrote:
    >
    >> On Wed, Jan 25, 2012 at 1:24 PM, Ken Thomases <ken...>
    > wrote:
    >>
    >>> What are you passing in for the modifiers?  I would expect that passing
    > in cmdKeyBit would result in UCKeyTranslate returning latin characters.
    >>
    >> I'm not passing in any modifiers. I've initialised inModifiers as 0.
    >> I tried passing in cmdKeyBit as the modifier but with that
    > UCKeyTranslate() is returning actualLength as 0 on pressing Cmd+N on US IME
    > itself.
    >
    > Oops, sorry.  I should have said "cmdKey" instead of "cmdKeyBit", and I
    > should have also said it needs to be right-shifted by 8 bits.  So, try
    > passing cmdKey >> 8.
    >

    Yes. That worked!
    Thanks a ton. I had spend so much time trying to figure this out.

    Could you point me to any documentation regarding this?

    > Cheers,
    > Ken
    >
    >
  • On Jan 25, 2012, at 5:51 AM, Akhil Jindal wrote:

    > On Wed, Jan 25, 2012 at 5:09 PM, Ken Thomases <ken...> wrote:
    >
    >> Oops, sorry.  I should have said "cmdKey" instead of "cmdKeyBit", and I
    >> should have also said it needs to be right-shifted by 8 bits.  So, try
    >> passing cmdKey >> 8.
    >
    > Yes. That worked!
    > Thanks a ton. I had spend so much time trying to figure this out.
    >
    > Could you point me to any documentation regarding this?

    Um, nothing exactly on point.  The UCKeyTranslate docs say to pass ((EventRecord.modifiers) >> 8) & 0xFF, and for an actual Command-N keyboard shortcut, that would be cmdKey >> 8.  (Admittedly, that is in terms of ancient, pre-Carbon-let-alone-Cocoa Mac event types.)  It just seems fairly self-evident that you'd want to / have to simulate what actually happens when a keyboard shortcut is processed.

    Also, if you have the Keyboard Viewer showing when a non-latin keyboard layout is selected, and you hold down the Command key, all of the keys show their latin key labels.

    Regards,
    Ken
previous month january 2012 next month
MTWTFSS
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
Go to today