Certain keys not detectable via Keyboard.GetState().GetPressedKeys()

Hi there,
I was currently trying to implement a console to my game, I wanted to use the same key that basically every game has the console. The key right under Escape.

So for US keyboards this is probably ~
For my DE keyboard it is this key: ^
Now, that wouldn’t be the end of the world, except for the fact that this key is simply unknown to MonoGame as it seems.

I have this snippet:

DebugSystem.DebugString = "" + Keyboard.GetState().GetPressedKeys().FirstOrDefault();
DebugSystem.DebugString += "\nTotal pressed keys: " + Keyboard.GetState().GetPressedKeys().Length;

And if I press K or L or U then I will see that I pressed “K” or “L” or “U”
But if I press Ö or Ä or Ü or # or ^ then it will say that I pressed “None”.
If I press Ö and # together then it will also just count as 1 key press (accoding to GetPressedKeys().Length)

Is there any known way to work around this issue?
It seems like a really breaking issue for me, so surely there’s a good solution for this problem, right?

I am using the OpenGL MonoGame variant if that matters

The problem with the ‘^’ key is, that it is on different positions for almost every language out there also being a secondary for a different other key … I once stumbled upon some technical reason but forgot it.

(edit: on german layouts, the ‘^’ is left of the ‘1’ key, afaik it’s ‘~’ on us layout?)

So while I would be interested if there is an easy way to do it - what I did is just use a different key. Like the Pause Key which is standardized and its almost never been used for anything nowadays :slight_smile:

PS: nice logo :slight_smile:

This character:


Is Keys.OemTilde on my (US) keyboard. Is that not the universal key for it? I’m unfamiliar with DE keyboards so always just assumed this stuff was standardized lol

And ‘^’ is Keys.D6 (with shift modifier pressed) on my keyboard. ‘~’ is Keys.OemTilde (with shift modifier pressed) for me.

I have some code here that I use for converting a Keys enum value to a string with US keyboards.

@reiti.net thanks, your logo is nice too :slight_smile:
yeah, I realize for this specific function I could just use another key, but I really dislike the thought of players being unable to bind anything to ^ ü ö ä # or ´ just because I can’t detect those key presses in MonoGame.
Well MonoGame detects that a key is pressed, but refuses to tell me which one. It just says “Keys.None”

Because of the same reason checking if Keys.OemTilde or Keys.D6 or anything else doesn’t solve this problem, because accoding to MonoGame ^ (and all the other mentioned keys) are all the same “Keys.None”.
Out of curiosity I tried if MLEM solves this problem, but their InputHandler behaves the same as they seem to rely on MonoGame’s KeyboardState

//edit: I just tested it in Stardew Valley. Even there this bug exists.
You cannot use ö ä ü # ´ ^ as any sort of hotkey because it’s detected as “none”.
… with a german keyboard layout of course.

I mean it isn’t the biggest issue obviously, I just wonder if other keyboard layouts in different languages are affected even worse (russian, greek?)

//edit 2:
reference: Windows - [BUG] Game doesn't recognise keys, leads to issue with key-bindings/hotkeys | Stardew Valley Forums

I may be wrong, but afaik MG does map the keys manually in code somewhere - so you might be able to adapt the MG source at this point to get the keys you desire - at least that may be the reason why you get “Keys.None” for those. I think it was just a big switch block processing the systems messages or something like that

btw. the problem with using tilde for console exists in a lot of games actually :slight_smile:

You’re right.
They are mapped in KeyboardUtil.SDL.cs
They are manually creating a Dictionary and adding the keys there.
And I am not sure why the german keyboard layout has different keycodes (if that’s the right term?) than the US layout, but I can indeed “fix it” by adding those mappings:

            // Fixes for German Keyboard
            _map.Add(94, Keys.OemTilde);            // ^
            _map.Add(223, Keys.OemMinus);           // ß
            _map.Add(180, Keys.OemPlus);            // ´
            _map.Add(252, Keys.OemOpenBrackets);    // ü
            _map.Add(246, Keys.OemSemicolon);       // ö
            _map.Add(228, Keys.OemQuotes);          // ä
            _map.Add(35, Keys.OemPipe);             // #

Now I just have to think about how I’m gonna handle this going forward :slight_smile:
I am assuming if I suggest this dirty fix as a PR it won’t get merged, and I am not sure if I have the skills yet to create a clean solution for this.
Oh well, worst case I will have to use my own MonoGame fork.

Thank you for your suggestions!
I can definitely use these keys now and potentially manually fix this for several different keyboard layouts

I’m guessing you’re getting those Keys values based on the corresponding Key located at the same position on a US keyboard? This documentation is showing different values. For example the German ß key is Keys.Oem4 even though it’s located in the same spot as the Keys.OemMinus key of a US keyboard.

I see, yes you are right. Oem4 would be the correct one.
However, this does not exist by default in the Keys enum that MonoGame uses and while I obviously could add it, doing that for every (major) layout seems like a lot of work.

So what I tried instead is rewriting the KeyboardUtil dictionary to map the scancodes instead and use the scancode in SDLGamePlatform.SdlRunLoop().
I mapped them all to the Keys enum that fits the US keyboard layout.
So even if I click ^ now on my german keyboard, it will get detected as OemTilde. While this is not the cleanest solution, I think it is somewhere near the golden medium / happy mean for me personally.
I now know that whatever key I map, I just need to use the US key to get the “same” mapping for all keyboard layouts. So if I map walking to WASD then using ZQSD on an AZERTY keyboard will work just fine. I think I might actually submit a PR request for this and see what happens.

It certainly shouldn’t be any worse than the current solution where some keys are straight up not supported on other layouts and it also shouldn’t have any side effect to the default US layout

I opened an issue: Unable to use certain keys on non-US keyboard layout · Issue #8033 · MonoGame/MonoGame · GitHub
and PR: Use ScanCodes instead of KeyCodes for Keyboard mapping by rastla · Pull Request #8032 · MonoGame/MonoGame · GitHub
Let’s see how it goes