We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 5000 - SDL2 lacks a way to get the real key that was pressed
Summary: SDL2 lacks a way to get the real key that was pressed
Status: REOPENED
Alias: None
Product: SDL
Classification: Unclassified
Component: events (show other bugs)
Version: 2.0.10
Hardware: All All
: P2 major
Assignee: Sam Lantinga
QA Contact: Sam Lantinga
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-02-22 06:50 UTC by Unarelith
Modified: 2020-10-21 00:39 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Unarelith 2020-02-22 06:50:37 UTC
On QWERTY keyboard, slash ('/') key is a physical key, so it has both a keycode and a scancode, and can be mapped into a game easily.

On AZERTY keyboard, slash key is the combination of colon (':') and shift key.

This causes some problems:
- It has no valid scancode on AZERTY
- It's impossible to detect it using keycodes, since event.key.keysym.sym will be SDLK_COLON in that case

SDL1 used to have event.key.keysym.unicode which could be converted to SDL_Keycode.

SDL2 doesn't provide a way to transform SDLK_COLON + shift modifier to SDLK_SLASH, making slash key mapping dependent on keyboard layout.

For example, if I say that SDLK_SLASH is the "command" key, it will work on QWERTY, but not on AZERTY.
If I say that SDLK_COLON + Shift (so basically: '/') is the "command" key, it will work on AZERTY but not on QWERTY.

So the problem is, SDL2 doesn't provide a way to know which key was actually pressed, even though SDL1 did.

It's still possible to use SDL_TEXTINPUT events to grab the keys and to convert them to SDL_Keycode, but this causes some issues:
- There will be three events, one for SDL_KEYDOWN, one for SDL_TEXTINPUT and one for SDL_KEYUP
- SDL_TEXTINPUT uses a string instead of just one char

So basically it's usable, it's just that the code needed to make SDL_TEXTINPUT working as a replacement of SDL_KEYDOWN in some specific cases, is not really worth it.

What I'd suggest to do in SDL2:

- Add back 'event.key.keysym.unicode' field, but add a warning in the documentation that it's not supposed to be used for getting text input, because that's what SDL_TEXTINPUT is for

OR

- Provide a new field, for example 'event.key.keysym.realsym' which will be equal to the keycode of the key that's actually pressed. So for 'Shift+:' on AZERTY, it would give SDLK_SLASH.
Comment 1 Sam Lantinga 2020-03-02 02:12:43 UTC
It sounds like you are trying to use keycodes as though they are scancodes. The scancodes are physical keys on the keyboard. Keycodes are the unshifted characters you get when the keys are pressed. The text events are the actual characters generated by the keyboard state when keys are pressed.

As you noted SDLK_SLASH may not exist on a keyboard, and you should never bind anything to it. You should instead bind to the scancode at that location, and when you're displaying the bindings, show the keycode that is in the current mapping.
Comment 2 Unarelith 2020-03-07 13:18:57 UTC
Sounds like you're misunderstanding me.

I'm looking for a way to actually recognize '/' key no matter what combination leads to it.

For an AZERTY keyboard, '/' key is SDLK_COLON + Shift.
For a QWERTY keyboard, '/' key is SDLK_SLASH.
For other keyboards, it may be another combination of a keycode + Shift.

SDL1 had the 'unicode' field that allowed recognizing SDLK_COLON + Shift as '/'.

SDL2 only has text events for that but they're really not practical. They give a string, and there's two events: one for the key press and one for the text event. This makes something like this waaaaay harder.

Adding back the 'unicode' field to SDL2 would be a great way to fix this issue actually. I don't know if that's possible or not though.
Comment 3 H. Peter Anvin 2020-10-21 00:39:12 UTC
So I would like to add my 2¢ to this.

I maintain a retro computer simulator. I *very much* do not want composition handling, dead keys, at so on.

What I would really like is to be able to answer the question: for scan code X, what are the symbols on the keycaps? For example, a Swedish keyboard has "¨^" where a U.S. keyboard has "] }". However, the former is a dead key; it will not, by itself, generate any text input event, and correctly so. But that is not my aim. SDL1 kind of happens to do "almost" the right thing, but what would be far better would be to be able to get *all* the keycaps printed (or normally printed) on a certain key; with a strong preference for having them in order of shift level (so a Swedish keyboard would report "+?\" for SDL_SCANCODE_MINUS.

That way I can produce a meaningful keyboard map that is a reasonable mapping onto the legacy computer keyboard on startup. For example, if I can see there is a key "[ {" like on a U.S. keyboard, I probably want to treat it as "{ [" *and* make it sensitive to Caps Lock. (ISO 646 fun.) This is really only possible if the whole keymap can be queried in bulk.