How to recognise keyboard layout?

I would like to know if the computer the software is running on has qwerty or qwertz keyboard layout. Is there a way to recognise this?

There was one thread about this topic but that’s over a decade old and had no answer to this question. So I wonder if the situation has changed?

Not sure if the thread you are mentioning is this one, or if it is what you are trying to achieve by detecting the keyboard layout, but there is a patch for retrieving the key scancode of the last key pressed here (the scancode of a key is independent of the kbd layout): How to get current Input Language? . I’m still using it to trigger MIDI events when the user is playing on his computer keyboard, it works fine.

1 Like

That’s a different thread to the one I mentioned.

What I’m trying to achieve is to create a playable keyboard out of the computer keyboard. I.e. what trackers do by default. Since there are wildly varying keyboard layouts around the globe, I’m trying to figure out the easiest way to decide which letters/characters/etc. I would map to each note.

For example lowest row of the keyboard would act as the white keys of octave 1. The row below the number keys would act as octave 2.

Here are two snippets of code I managed to find from the internet which look for the layout’s name. But there are different variations of each layout as far as I’m aware.

Mac

#import <Carbon/Carbon.h>

TISInputSourceRef source = TISCopyCurrentKeyboardInputSource();
NSString *s = (__bridge NSString *)(TISGetInputSourceProperty(source, kTISPropertyInputSourceID));

Windows

bool bIsAzertyKeyboard = false;
bool bIsQwertzKeyboard = false;
bool bIsQwertyKeyboard = false;
 
void DetectKeyboardType()
{
    bIsAzertyKeyboard = false;
    bIsQwertzKeyboard = false;
    bIsQwertyKeyboard = true;
    switch (PRIMARYLANGID(HIWORD(GetKeyboardLayout(0))))
    {
    case LANG_FRENCH:
        bIsQwertyKeyboard = false;
        bIsAzertyKeyboard = true;
        break;
    case LANG_GERMAN:
        bIsQwertyKeyboard = false;
        bIsQwertzKeyboard = true;
        break;
    }
}

I haven’t tried those out yet. But with those I would be able to at least figure out the general layout of the keyboard. Not the exact special characters which might be found when pressing Shift+numbers for example.

EDIT:
After quickly testing the Mac version, that thing won’t compile because that seems to be Objective-C code and there will be ambiguous symbols. Shame…

Hmm, some old post on Microsofts website seems to indicate that scan codes aren’t necessarily same for all keyboards. Not sure if it still applies to modern keyboards or not:

https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/cb9a64a0-a119-43b7-b5a4-109c27a58c7c/dealing-with-keyboard-layouts-in-cdirectx-11-games?forum=wingameswithdirectx

But do I understand correctly that at least in theory scan codes should be the same for all keyboard layouts, meaning that QWERTY keyboard’s “Q” would have the same scan code as AZERTY keyboard’s “A”?

I’ll conduct a test if the KeyPress key codes are actually same on different keyboard layouts. I’ll report back once I have done the test.

After testing what comes out of QWERTY vs. QWERTZ keyboard layouts, it is confirmed that at least what JUCE outputs is same key codes (and of course ASCII/whatever codes) for same characters. So the key code outputs are unfortunately not physical location based on the keyboard, but are always same for the same character. I.e. “a” is always “65” (key code) and 97 (wchar_t value), regardless of where in the keyboard it is physically located.

This means that I have to map the characters myself and somehow recognise which keyboard layout is in use on any given computer.

Did you come to an solution on this?

Yes. I went with the implementation jpo mentioned:

I decided to implement a key command manager. So the user can configure it’s own key map.

As far as I can tell, the keycodes used in jpo’s system are the same for each keyboard layout. I.e. for all windows machines when you press key at location “X”, the keycode is the same regardless of what the exact letter is printed on that keyboard’s key.

So if your keys are location dependent on the keyboard instead of what letter is actually on them, then jpo’s system is a good idea.

I am not sure if it relates to the OP, but you are aware of the ApplicationCommandManager and the KeyPressMappingSet?

I think despite the name, it works in a plugin as well.

The problem shown in this thread is IIUC to get the position of a key, because they should be physically next to another.

1 Like

Yes, this is how I implemented this in my app. If the preset keymap don’t fit for the user he/her can change it in a keymappingEditor. I really don’t understand the code that jpo is mentioned. Also I’m not sure if this code will work on all platforms and all circumstances in all times. To let the user setup this seems the best solution for me. I need the applicationCommandManager anyway. But I don’t know if this is the best solution.