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 2096 - Mapping from scancode to keycode doesn't work for remapped modifier keys
Summary: Mapping from scancode to keycode doesn't work for remapped modifier keys
Status: RESOLVED FIXED
Alias: None
Product: SDL
Classification: Unclassified
Component: events (show other bugs)
Version: HG 2.1
Hardware: All All
: P2 normal
Assignee: Sam Lantinga
QA Contact: Sam Lantinga
URL:
Keywords: target-2.0.4
: 2819 2978 (view as bug list)
Depends on:
Blocks:
 
Reported: 2013-09-11 04:35 UTC by Jacob Lee
Modified: 2015-05-29 02:06 UTC (History)
7 users (show)

See Also:


Attachments
video/x11: improve keyboard mapping (690 bytes, patch)
2014-08-23 18:51 UTC, Benoit Pierre
Details | Diff
events: improve keyboard modifiers handling (5.29 KB, patch)
2014-08-23 18:51 UTC, Benoit Pierre
Details | Diff
x11keyboard: Specifically remap scan codes for return, escape, backspace, tab, and delete (1.33 KB, patch)
2015-05-29 01:15 UTC, Zack Middleton (zturtleman)
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jacob Lee 2013-09-11 04:35:26 UTC
If a user has a non-standard keyboard mapping -- say, their caps lock key has been mapped to Ctrl -- then SDL_GetModState() is no longer accurate: it only considers the unmapped keys. This is a regression from SDL 1.2.

I think there are two parts to this bug: first, GetModState should use keycodes, rather than scancodes, which is easy enough.

Unfortunately, on my system, SDL considers Caps Lock, even when mapped as Control, to be both SDL_SCANCODE_CAPSLOCK and SDLK_CAPSLOCK. The output from checkkeys for it is:

INFO: Key pressed :  scancode 57 = CapsLock, keycode 0x40000039 = CapsLock  modifiers: CAPS

Whereas the output for xev is:

KeyPress event, serial 41, synthetic NO, window 0x4a00001,
    root 0x9a, subw 0x0, time 40218333, (144,177), root:(1458,222),
    state 0x10, keycode 66 (keysym 0xffe3, Control_L), same_screen YES,
    XKeysymToKeycode returns keycode: 37
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

I think the problem is that X11_UpdateKeymap in SDL_x11keyboard.c only builds a mapping for keycodes associated with a Unicode character (anything where X11_KeyCodeToUcs returns a value). In the case of caps lock, SDL scancode 57 becomes x11 keycode 66, which becomes x11 keysym 65507(Control_L), which does not have a unicode value.

To fix this, I suspect that SDL needs a mapping of the rest of the x11 keysyms to their corresponding SDL key codes.
Comment 1 Benoit Pierre 2014-08-23 18:50:39 UTC
The 2 attached patches fix this issue for me:

1. video/x11: improve keyboard mapping by handling keycodes not associated with a Unicode character in X11_UpdateKeymap

2. events: improve keyboard modifiers handling by using remapped key codes, instead of scan codes, to track modifiers state
Comment 2 Benoit Pierre 2014-08-23 18:51:18 UTC
Created attachment 1839 [details]
video/x11: improve keyboard mapping
Comment 3 Benoit Pierre 2014-08-23 18:51:51 UTC
Created attachment 1840 [details]
events: improve keyboard modifiers handling
Comment 4 Sam Lantinga 2014-08-24 07:16:15 UTC
The intent is that if you remap the capslock key to control, you'll get scancode capslock and keycode control. I can't test it here, does that happen with your patch?

The second patch looks fine and makes sense to me.
Comment 5 Benoit Pierre 2014-08-24 14:43:37 UTC
Yes, I use a modified colemak layout: backspace and capslock switched, right alt and control switched, left alt activating a 3rd layer overlay with left/right/up/down/home/end near the right home row, and with this patch all keys are properly remapped. You can test the patch easily on Linux by switching the layout to colemak and checking capslock is now backspace: setxkbmap us -variant colemak
Comment 6 raincomplex 2014-09-09 05:47:30 UTC
Confirming that the patch works on a layout where ctrl and caps are swapped (both keyboard event's keysym and SDL_GetModState() behave). Also the example code on https://wiki.libsdl.org/SDL_Scancode produces correct output:

scancode CapsLock acting as Left Ctrl
scancode Left Ctrl acting as CapsLock
Comment 7 Benoit Pierre 2015-01-05 18:32:12 UTC
So... Anything else I can do to get those 2 patches merged?
Comment 8 Ryan C. Gordon 2015-02-19 04:24:12 UTC
*** Bug 2819 has been marked as a duplicate of this bug. ***
Comment 9 Ryan C. Gordon 2015-02-19 05:22:23 UTC
Marking a large number of bugs with the "triage-2.0.4" keyword at once. Sorry if you got a lot of email from this. This is to help me sort through some bugs in regards to a 2.0.4 release. We may or may not fix this bug for 2.0.4, though!
Comment 10 Sam Lantinga 2015-05-28 19:48:47 UTC
Your patches are in, thanks!
https://hg.libsdl.org/SDL/rev/9e8323b058d6
Comment 11 Daniel Gibson 2015-05-28 20:06:14 UTC
*** Bug 2978 has been marked as a duplicate of this bug. ***
Comment 12 Benoit Pierre 2015-05-28 20:34:11 UTC
Great, thanks!
Comment 13 Zack Middleton (zturtleman) 2015-05-29 01:11:52 UTC
This breaks SDL key codes that do not have a Ucs4 character and are not XOR'd with SDLK_SCANCODE_MASK such as backspace and return.

The change to the keymap to use SDL_SCANCODE_TO_KEYCODE in SDL_x11keyboard.c causes all SDL scancodes without a Usc4 character to be XOR'd with SDLK_SCANCODE_MASK, but not all key code are suppose to be (as seen in include/SDL_keycodes.h). SDLK_BACKSPACE is not 0x4000002A.

I think the full list of keys affected are return, escape, backspace, tab, and delete.
Comment 14 Zack Middleton (zturtleman) 2015-05-29 01:15:24 UTC
Created attachment 2166 [details]
x11keyboard: Specifically remap scan codes for return, escape, backspace, tab, and delete

Fix remapping scan codes to key codes for keymap in SDL_x11keyboard.c.
Comment 15 Sam Lantinga 2015-05-29 02:06:49 UTC
Looks good, thanks!
https://hg.libsdl.org/SDL/rev/0265666d0238