Hi.
I am working on a project which uses SFML and I use the keyboard as kind of piano keys. There is a problem with keyboard event handling. For example, when you press shift + number the produced event carries the key code 0 instead of the proper one.
Here is a bug report for reference:
https://github.com/SFML/SFML/issues/187Interestingly, this behavior in SFML is inconsistent. Here are two ways of checking the key code while pressing Shift+Num1, one works and one doesn't. I work on Linux.
In the first example the key code is '0' therefore nothing would be printed:
while(window.isOpen)
{
window.waitEvent(event);
if(event.type == sf::Event::KeyPressed)
{
if(event.key.code == sf::Keyboard::Num1)
cout<<"1 is pressed"<<endl;
}
}
In the second example the check correctly sees that Num1 is pressed therefore "1 is pressed" would be printed:
while(window.isOpen)
{
window.waitEvent(event);
if(event.type == sf::Event::KeyPressed)
{
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Num1))
cout<<"1 is pressed"<<endl;
}
}
The reason for the inconsistency lies in the implementation.
The first example uses the code from the file
InputImpl.cpp line 63. The function gets an SFML key value, converts it to an X11 keysym (layout dependent) and then to an X11 keycode. Then the keycode is checked with XQueryKeymap. This is good because the keysym is used only internally to get the keycode (layout independent).
The second example uses the code from the file
WindowImplX11 line 660. The keysym - which is layout dependent and changed by pressing shift which is undesired - is being requested from X11 with the function (line 666)
XLookupString(&windowEvent.xkey, buffer, sizeof(buffer), &symbol, &keyboard);
and then converted to an SFML key code with
event.key.code = keysymToSF(symbol);
The problem with this approach is that the keysym we get from X11 is layout and shift dependent. This is good if we want the inserted character, but if we want the key, we have to request the X11 keycode which is available from
XKeyEvent.keycode.
Since the problem seems to linger from the beginning of time (2008?) I assume you tried to fix it but there were problems. May I ask if you could share your opinion on the subject and the proposed change?
Thank you for the great library by the way.
Edit: Here is the output of xev (X events) when pressing Num1 and then Shift+Num1. I copied only the relevant parts:
KeyPress event, serial 42, synthetic NO, window 0x2600001,
root 0xb6, subw 0x0, time 19059638, (309,-46), root:(1119,686),
state 0x0, keycode 10 (keysym 0x31, 1), same_screen YES,
XLookupString gives 1 bytes: (31) "1"
XmbLookupString gives 1 bytes: (31) "1"
XFilterEvent returns: False
KeyRelease event, serial 45, synthetic NO, window 0x2600001,
root 0xb6, subw 0x0, time 19059710, (309,-46), root:(1119,686),
state 0x0, keycode 10 (keysym 0x31, 1), same_screen YES,
XLookupString gives 1 bytes: (31) "1"
XFilterEvent returns: False
KeyPress event, serial 45, synthetic NO, window 0x2600001,
root 0xb6, subw 0x0, time 19062213, (309,-46), root:(1119,686),
state 0x0, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyPress event, serial 45, synthetic NO, window 0x2600001,
root 0xb6, subw 0x0, time 19063011, (309,-46), root:(1119,686),
state 0x1, keycode 10 (keysym 0x21, exclam), same_screen YES,
XLookupString gives 1 bytes: (21) "!"
XmbLookupString gives 1 bytes: (21) "!"
XFilterEvent returns: False
KeyRelease event, serial 45, synthetic NO, window 0x2600001,
root 0xb6, subw 0x0, time 19063083, (309,-46), root:(1119,686),
state 0x1, keycode 10 (keysym 0x21, exclam), same_screen YES,
XLookupString gives 1 bytes: (21) "!"
XFilterEvent returns: False
KeyRelease event, serial 45, synthetic NO, window 0x2600001,
root 0xb6, subw 0x0, time 19063583, (309,-46), root:(1119,686),
state 0x1, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
The order is: 1 press, 1 release, shift press, 1 press, 1 release, shift release.
You can see that when pressing 1 with or without shift the keycode doesn't change while the keysym does change.