Best way to handle different keyboard layouts?

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

I want to handle different keyboard layouts (QWERTY/QWERTZ/AZERTY) so that a key at the same place in different keyboards do the exact same thing (for PC and Mac). Like in trackers how they handle music note playing from computers keyboard. For example Renoise seems to handle this automatically. How did they achieve this in practise?

What's the best way to achieve this? I'm using JUCE for development.

Also I'm looking for people who'd like to run a quick test application on their PC, which outputs key codes and character codes from their keyboard layout, so I can see what their keyboards are actually outputting in practise. I'm looking for people with QWERTY (standard and Scandic), QWERTZ and AZERTY keyboards. If you feel. you can spare about one minute of time to run the application and send me the results, I'd much appreciate it.

Post

In windows you can do this via scancode:

case WM_KEYUP:
case WM_KEYDOWN:
{
int nVirtKey = (int) wParam;
int scanCode = (lParam>>16)&0xff;

Post

Kraku wrote: Thu Jun 30, 2022 8:02 am I want to handle different keyboard layouts (QWERTY/QWERTZ/AZERTY) so that a key at the same place in different keyboards do the exact same thing (for PC and Mac). Like in trackers how they handle music note playing from computers keyboard. For example Renoise seems to handle this automatically. How did they achieve this in practise?
Operating systems will generally give you "raw" keycodes for the physical keys as part of the keydown/keyup events. On Windows that's the VK_ stuff in wParam of WM_KEYDOWN/_KEYUP and on macOS it's the [event keyCode] delivered to keyDown: and keyUp: methods. The actual codes are OS specific so you'll basically need a table lookup to make it platform independent, but that's it.

The actual translation from physical keys to whatever the layout says is actually done by the application. On Windows if the messageloop calls TranslateMessage that'll synthesize WM_CHAR/WM_UNICHAR. In Cocoa NSView has interpretKeyEvents: that'll translate and call insertText: for you. In both cases you can also translate yourself if you feel like it.
What's the best way to achieve this? I'm using JUCE for development.
Unfortunately looking at modules/juce_gui_basics/native/juce_win32_Windowing.cpp it looks like JUCE appears to be doing the wrong(*) thing and translates (MapVirtualKey) the keydown/keyup messages, so I think you'd basically have to modify the keyboard handling in JUCE's native wrappers or translate backwards (which is potentially lossy).

(*) At least "wrong" for our purposes.
Also I'm looking for people who'd like to run a quick test application on their PC, which outputs key codes and character codes from their keyboard layout, so I can see what their keyboards are actually outputting in practise. I'm looking for people with QWERTY (standard and Scandic), QWERTZ and AZERTY keyboards. If you feel. you can spare about one minute of time to run the application and send me the results, I'd much appreciate it.
Why not just install a selection of layouts on your development system?

Post

mystran wrote: Thu Jun 30, 2022 9:49 am
What's the best way to achieve this? I'm using JUCE for development.
Unfortunately looking at modules/juce_gui_basics/native/juce_win32_Windowing.cpp it looks like JUCE appears to be doing the wrong(*) thing and translates (MapVirtualKey) the keydown/keyup messages, so I think you'd basically have to modify the keyboard handling in JUCE's native wrappers or translate backwards (which is potentially lossy).

(*) At least "wrong" for our purposes.
Thanks, very informative!

I'll see if I can figure out an easy way to expand JUCE to handle what I want it to do.

mystran wrote: Thu Jun 30, 2022 9:49 am
Also I'm looking for people who'd like to run a quick test application on their PC, which outputs key codes and character codes from their keyboard layout, so I can see what their keyboards are actually outputting in practise. I'm looking for people with QWERTY (standard and Scandic), QWERTZ and AZERTY keyboards. If you feel. you can spare about one minute of time to run the application and send me the results, I'd much appreciate it.
Why not just install a selection of layouts on your development system?
I'm already doing that, but since I'm not very familiar with how operating systems and keyboard hardware handle the key codes, I wanted to test what's really coming out of the keyboard.

How does the keyboard hardware / OS handle such situations, where there are extra keys on some key rows? For example in Finnish keyboard there is a key for "<>" characters right after the left Shift key. On some keyboard layouts that key is missing. Does that key appear with the same key code on all keyboards that have a key at that location? What about the key right next to it, if/if not that extra key is present on the given keyboard?

Post

Kraku wrote: Fri Jul 01, 2022 9:24 am How does the keyboard hardware / OS handle such situations, where there are extra keys on some key rows? For example in Finnish keyboard there is a key for "<>" characters right after the left Shift key. On some keyboard layouts that key is missing. Does that key appear with the same key code on all keyboards that have a key at that location? What about the key right next to it, if/if not that extra key is present on the given keyboard?
For the most part all the keys that are common between keyboards have the same codes everywhere and those keys only present on certain keyboards have their own codes that are just missing from keyboards where those keys are not present.

That particular key is what SDL for example calls NONUSBACKSLASH (the name is because it's backslash key on UK layout) and there's some oddities with that particular key, like on macOS it's keycodes are swapped with GRAVE (§ on finnish layout) if the keyboard is in ISO mode.. and I can't remember if there was some weirdness on Windows too, but like physically when the key is present it's always the same "nonusbackslash" key.

ps. For emphasis, the actual US backslash key is missing from basically all european keyboards, but from the point of view of hardware keycodes it's a different key, so it's fine to assume that any given "scancode" is found in certain place on the keyboard as long as it's one of the standard hardware layouts.

Post

mystran wrote: Fri Jul 01, 2022 9:41 am ps. For emphasis, the actual US backslash key is missing from basically all european keyboards, but from the point of view of hardware keycodes it's a different key, so it's fine to assume that any given "scancode" is found in certain place on the keyboard as long as it's one of the standard hardware layouts.
Makes sense.

I think I'll see if JUCE lets me hack some simple callback function into its code which gets called with he hardware keycode every time key goes down/up.

Post

Hmm, my initial test don't seem to agree with what has been said on this thread so far:

I tried hacking my own test into Mac side of JUCE, into:

bool handleKeyEvent (NSEvent* ev, bool isKeyDown)
which can be found in juce_mac_NSViewComponentPeer.mm

I copy/pasted the following lines from JUCE to see what the NSEvent says the keycode is:

String unmodified = nsStringToJuce ([ev charactersIgnoringModifiers]);
auto keyCode = (int) unmodified[0];

I get different key code when I switch between QWERY and AZERTY keyboard layouts. I tried pressing Q key with both layouts. Then Z key. Both times the input keycode was different between the layouts.
Last edited by Kraku on Fri Jul 01, 2022 11:40 am, edited 1 time in total.

Post

Kraku wrote: Fri Jul 01, 2022 11:14 am I copy/pasted the following lines from JUCE to see what the NSEvent says the keycode is:
String unmodified = nsStringToJuce ([ev charactersIgnoringModifiers]);
auto keyCode = (int) unmodified[0];
You want [ev keyCode] rather than [ev charactersIgnoringModifiers] because "keyCode" is the physical key and "charactersIgnoringModifiers" is the letter printed on the keycap (assuming the layout is set to match, obviously). These are fundamentally two different things.

Post

mystran wrote: Fri Jul 01, 2022 11:31 am You want [ev keyCode] rather than [ev charactersIgnoringModifiers] because "keyCode" is the physical key and "charactersIgnoringModifiers" is the letter printed on the keycap (assuming the layout is set to match, obviously). These are fundamentally two different things.
Aha! Indeed it works with that modification. Thank you! :)

I'll check the windows side next.

Post Reply

Return to “DSP and Plugin Development”