SDL
SDL copied to clipboard
On Linux/X11, dead keys don't produce valid keycode
This bug report was migrated from our old Bugzilla tracker.
These attachments are available in the static archive:
- ~~patch for SDL2/X11/keyboard support to fall back to default keycode if X11 couldn't map the scancode to a valid keycode (sdl2-default-keycode.patch, text/plain, 2017-04-07 16:00:58 +0000, 590 bytes)~~
- ~~Translate deadkeys to their normal form (sdl2-translate-deadkeys.patch, text/plain, 2017-04-07 23:53:33 +0000, 881 bytes)~~
- Translate dead keys to their normal form (sdl2-translate-deadkeys-v2.patch, text/plain, 2017-04-08 01:08:41 +0000, 1442 bytes)
Reported in version: 2.0.5 Reported for operating system, platform: Linux, x86_64
Comments on the original bug report:
On 2017-04-07 16:00:58 +0000, Daniel Gibson wrote:
Created attachment 2715 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.
On 2017-04-07 18:39:50 +0000, Mickaël Thomas wrote:
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.
On 2017-04-07 23:53:33 +0000, Mickaël Thomas wrote:
Created attachment 2718 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).
On 2017-04-08 00:05:35 +0000, Daniel Gibson wrote:
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).
On 2017-04-08 00:42:15 +0000, Mickaël Thomas wrote:
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*[\sdead_[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 -> ???
On 2017-04-08 01:08:41 +0000, Mickaël Thomas wrote:
Created attachment 2719 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