Handling key codes on OSX

keyboard
osx
keypress
macos

#1

I’ve written a tool utilizing onKeyDown(key, repeat, flags, view) which works fine on Windows, but not on OSX. After testing on a MacBook Air and a MacBook Pro, it seems I’ve been checking for the wrong key codes (for VK_MINUS and VK_EQUAL in particular) on OSX.

Most of the lists of OSX key codes I’ve found online (including the ones linked to from here) list VK_EQUAL and VK_MINUS as 0x18 and 0x1b respectively. I’m aware that keyboard layout may affect this, but this post seems to imply that it doesn’t (but maybe those keys in particular don’t change?). Should I be checking keyboard layout?

The key codes that I got were:

equal = 0x3d # expected 0x18
minus = 0x2d # expected 0x1b

What confused me even more is that when I was holding down modifier keys while I pressed them, the codes were different:

        option + equal = 0x2260
shift + option + equal = 0xb1
        option + minus = 0x2013
shift + option + minus = 0x2014

I don’t really how to properly handle this. Should I be bit twiddling? Should I be subtracting/adding a certain integer from them similar to this? Is it safe to assume that the key codes I got with modifier keys down are unique even with the modifier keys up? Also, is this changing of key codes normal behavior on OSX, or is this a SketchUp thing, or is it normal everywhere and I’ve only encountered it now?


#2

I don’t know of any official reference on how the SketchUp Ruby API generates the key codes it passes to onKeyDown. As noted in the topic you linked, there is a limited list of OS-independent constants in the method’s documentation. Codes for other keys are, as you have seen, not portable and in the specific case of VK_EQUAL and VK_MINUS are not even defined on Mac SketchUp. I’m pretty sure that the codes for modified keys are created by bitwise OR of a modifier key code with the base key code. I have to run now so I can’t investigate further at the moment, but maybe later today.

Edit: I’m back with more info. The value of key on Mac is the Unicode representation of the character.

I was incorrect (must be what happens in some other callback?): modifier keys don’t OR bits into the code. Rather, the Unicode value for the as-modified character is returned. Also, your onKeyDown will receive two callbacks, one for the modifier and another for the modified character.

In your examples, 0x3d is the basic Latin Unicode for ‘=’, 0x2d for ‘-’. The modifier keys produce extended characters. For example shift + ‘=’ gives ‘+’ (code 0x2b), as indicated on the keyboard. In your examples, option + = gives ≠ which codes to 0x2260 as you saw (and is what I pressed to get that symbol in this post!).

I don’t know what Apple does for international Macs or what happens if you attach a non-English keyboard as I have neither to test. That could be a gotcha if for example a shifted key has a different character on it than the US standard.

Also, and this is very important to know, keys and key combinations that are set as shortcuts are processed by SketchUp before they reach your Tool’s onKeyDown. So, for example, you will never see ‘space’ unless you have killed that default shortcut for the Selection Tool. Instead your Tool will be deactivated and the Selection Tool made active. Don’t try to use the Command key, as most command key chords are hardwired into menu items by the GUI and will be caught by the menu instead of your callback.

Edit 2: you can tell what modifier key(s) is currently pressed by bitwise OR of the flags value with
0x20000 -> shift (CONSTRAIN_MODIFIER_KEY also VK_SHIFT)
0x40000 -> control (no mask version on Mac, but VK_CONTROL works)
0x80000 -> alt/option (COPY_MODIFIER_MASK no known VK version on Mac)

There are strange variations between Windows and Mac. For example, on a Mac ALT_MODIFIER_MASK is for the command key whereas it is the alt key on a PC. COPY_MODIFIER_MASK is alt on a Mac whereas it is control on a PC. I think these conflicts arise from the way the keys were utilized in SketchUp’s built-in Tools.


#3

This was extremely helpful, especially since I don’t actually have a mac of my own to do more tests on whenever I want. I was wondering why plus and minus weren’t defined as constants in the API considering how they’re used in SketchUp’s own tools. This may be why. Thanks!

This is why I chose option, shift, + (or =), and -, actually. They’re used in a lot of SketchUp’s native tools as modifier keys so I doubt they’ll be used as shortcuts. Thank you again!


#4

Oops! That should have been bitwise AND (&)! The flags are built by OR’ing the flags together.


#5

No worries. I don’t use the flags anyway. I just keep track of which modifier keys are down myself. I tried using them before, but turns out they’re screwy on Windows (one of the onKeyXXX methods I think. I don’t remember which). There was a thread about it on here actually.

Edit: Apparently, it was on sketchucation: http://sketchucation.com/forums/viewtopic.php?f=180&t=67837


#6

There was also some weirdness where some keys are not caught by onKeyDown, but are by onKeyUp.