KeyboardEvent key values differ between Win and Mac

As per the title, running this simple script on Win and Mac results in different values for the same key (example: “S“ is 83 on Win and 1 on Mac). Is this expected? It would be weird if so, given that KeyboardEvent is a RhinoApp (and not a System) event, so it would make sense to have consistent codes for the same key in both OS.
If this is the expected behavior for some reason, how can I check that the same key (say “S“) is pressed when running on Win or on Mac? So far, I have used this check:

void OnKeyboardEvent(int key)
{
 switch(key)
     {
         case (int)KeyboardKey.S:
           // dosomethingelse
         break;

         case (int)KeyboardKey.W:
           // dosomethingelse
         break;
     }
}

But it seems like KeyboardKey is mapped only on Win-based values. Running a script with the same check on Mac and pressing “S” won’t trigger the expected case.

KeyboardEvent_test.cs (637 Bytes)

Hi @ale2x72,

On Windows, the value of key will be a virtual key code.

I don’t know the details of the Mac implementation. But I’m sure what is returned is not a Windows virtual key code.

What are you doing with the keyboard hook?

– Dale

The keyboard hook triggers a specific action (like rotating a selected geometry) in a plugin that, for now, I only tested on Windows; yesterday, I tried it on a Mac and found the problem. But the action per se is not important; let’s say I just want to print the key that was just pressed:

void OnKeyboardEvent(int key)
{
 switch(key)
     {
         case (int)KeyboardKey.S:
           Console.WriteLine("Hey, you pressed S!");
         break;

         case (int)KeyboardKey.W:
           Console.WriteLine("Hey, you pressed W!");
         break;
     }
}

If you try this implementation of OnKeyboardEvent in my previous script and test it on Windows and Mac, the Windows version will spot the W and S keys correctly, while the Mac version won’t.
Since KeyboardKey is an enum of Rhino.UI, I expected it to work in Rhino regardless of the OS Rhino is running on. It is counterintuitive that it doesn’t.
Sure, I can hardcode the key values specifically for Windows and Mac with a preliminary check, but I was hoping for a more elegant solution. Shouldn’t RhinoCommon be OS-independent? (I mean, usable in both OS equally)

I think that the key values will be the untranslated ones that the OS will give you. It isn’t necessarily the key that your chosen key layout would lead you believe is being pressed.

For instance my key layout has the top letter row where QWERTY is a pretty regular layout give me the characters PHRK>. There are multiple cases where many apps, not just Rhino, just get confused. Where I press my P (like in Visual Studio Code) the app thinks I press Q, which is closing the current window. You probably have some AZERTY or at least non-QWERTY layout in use?

I don’t know how to fix your case though, just wanted to give you some info on what might be going on.

Thank you @jesterking , but I already solved the issue using a preprocessor directive to recognize the OS and initializing a custom enum according to the different codes for the same keys:

#if WINDOWS
enum Keys
{ Q=81,W=87,E=69,A=65,S=83,D=68,F=70 }
#elif MACOS
enum Keys
{ Q=12,W=13,E=14,A=0,S=1,D=2,F=3 }
#endif

So that my OnKeyboardEvent looks like this:

void OnKeyboardEvent(int key)
{
 switch(key)
     {
         case (int)Key.S:
           // dosomethingelse
         break;

         case (int)Key.W:
           // dosomethingelse
         break;
     }
}

The values for the KeyboardKey enum do not depend on the OS; I assumed this just as you did (btw, I tested on QWERTY keyboards on both Win and MacOS, on different computers), but, as Dale pointed out, are virtual key codes:
https://developer.rhino3d.com/api/rhinocommon/rhino.ui.keyboardkey
Those values are valid for Windows only, but this is not specified in the documentation. When using an API for an application that works on more than one OS, it makes sense that, unless otherwise specified, its properties, fields, methods, etc. work the same in all of them. I think this particular enum should be marked as Windows only to avoid such confusion in the future.