| Summary: | On Linux/X11, dead keys don't produce valid keycode | ||
|---|---|---|---|
| Product: | SDL | Reporter: | Daniel Gibson <metalcaedes> |
| Component: | events | Assignee: | Sam Lantinga <slouken> |
| Status: | ASSIGNED --- | QA Contact: | Sam Lantinga <slouken> |
| Severity: | normal | ||
| Priority: | P2 | CC: | mickael9 |
| Version: | 2.0.5 | ||
| Hardware: | x86_64 | ||
| OS: | Linux | ||
| Attachments: |
patch for SDL2/X11/keyboard support to fall back to default keycode if X11 couldn't map the scancode to a valid keycode
Translate deadkeys to their normal form Translate dead keys to their normal form |
||
I think the underlying issue could be fixed by adding the Unicode codepoints for the dead keys in video/x11/imKStoUCS.c (in a new table). I have no idea where those table were generated from in the first place, but I could hack a python script to generate the one we need using imKStoUCS.c and /usr/include/X11/keysymdef.h That or we could simply add another translation layer that would translate the dead key sym to their non-dead equivalent before calling into imKStoUCS.c I'd like to hear more from the people experienced with Xlib, in case there is a better way to do this. Created attachment 2718 [details]
Translate deadkeys to their normal form
My proposed method was much harder than expected since the key naming scheme isn't really consistent so I went with a simpler way of simply converting the most common dead keys. Hopefully that'll cover most cases (eg French or German keyboard, possibly others).
Yeah, that could help with the most common western dead keys - maybe we could find translations of the other XK_dead_* constants as well? In any case I'd suggest to also add my change as a fallback (for if the translation fails). I don't think all of them are relevant though, since we should only need those having a corresponding keyboard label (not in the shift/altgr group)
I made a list of these using this:
$ echo $(grep -REo 'key\s*<[^>]+>\s*\{\s*\[\s*dead_[a-z]+' /usr/share/X11/xkb/symbols/ | grep -Eo 'dead_.*$' | sort | uniq)
dead_abovedot dead_abovering dead_acute dead_caron dead_cedilla dead_circumflex dead_diaeresis dead_grave dead_iota dead_macron dead_tilde
Extending the list up to XK_dead_iota will include all of them, I just don't know what to replace these with:
- XK_dead_abovering -> ???
- XK_dead_iota -> ???
Created attachment 2719 [details] Translate dead keys to their normal form This should do it, I found the missing codepoints (and traced them back to the matching Keysym) using this: https://gist.github.com/mickael9/d6378c60c2e509e4d5b05ba2ecc072c9 |
Created attachment 2715 [details] patch for SDL2/X11/keyboard support to fall back to default keycode if X11 couldn't map the scancode to a valid keycode Starting with 2.0.5, SDL2 finally generates key events for dead keys, which is great! However, at least when I tested (with German keyboard, Sun dead keys, on ^ key, which is SDL_SCANCODE_GRAVE), it doesn't produce a valid keycode. The scancode in the SDL_Keysym is SDL_SCANCODE_GRAVE, as expected, but sym is SDLK_SCANCODE_MASK. The problem appears to be that in X11_UpdateKeymap() X11_KeyCodeToUcs4() returns 0 (which is ok so far) and X11_KeyCodeToSDLScancode() also returns 0, so that switch/case thing goes to the default case and does keymap[scancode] = SDL_SCANCODE_TO_KEYCODE(keyScancode); with keyScancode == 0 => we end up with just SDLK_SCANCODE_MASK I'd suggest checking for 0 (SDL_SCANCODE_UNKNOWN) and in that case just leave that entry in the keymap unmodified - it's initialized by SDL_GetDefaultKeymap() so it already contains a mapping that's not completely stupid: the keycode matching the scancode, in this case SDLK_BACKQUOTE, which is not really what that key is, but better than nothing. (I think that this is the behavior I already got when I wrote the first patch attempt for dead keys not generating key events at all, must have broken afterwards somehow) The attached patch implements this behavior.