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 3624 - On Linux/X11, dead keys don't produce valid keycode
Summary: On Linux/X11, dead keys don't produce valid keycode
Status: ASSIGNED
Alias: None
Product: SDL
Classification: Unclassified
Component: events (show other bugs)
Version: 2.0.5
Hardware: x86_64 Linux
: P2 normal
Assignee: Sam Lantinga
QA Contact: Sam Lantinga
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-04-07 16:00 UTC by Daniel Gibson
Modified: 2017-08-11 18:46 UTC (History)
1 user (show)

See Also:


Attachments
patch for SDL2/X11/keyboard support to fall back to default keycode if X11 couldn't map the scancode to a valid keycode (590 bytes, patch)
2017-04-07 16:00 UTC, Daniel Gibson
Details | Diff
Translate deadkeys to their normal form (881 bytes, patch)
2017-04-07 23:53 UTC, Mickaël Thomas
Details | Diff
Translate dead keys to their normal form (1.41 KB, patch)
2017-04-08 01:08 UTC, Mickaël Thomas
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Daniel Gibson 2017-04-07 16:00:58 UTC
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.
Comment 1 Mickaël Thomas 2017-04-07 18:39:50 UTC
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.
Comment 2 Mickaël Thomas 2017-04-07 23:53:33 UTC
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).
Comment 3 Daniel Gibson 2017-04-08 00:05:35 UTC
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).
Comment 4 Mickaël Thomas 2017-04-08 00:42:15 UTC
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 -> ???
Comment 5 Mickaël Thomas 2017-04-08 01:08:41 UTC
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