From f037c2775bf69f56acce7cc353f91c5460d1aad6 Mon Sep 17 00:00:00 2001 From: binary1248 Date: Thu, 24 Dec 2015 18:31:15 +0100 Subject: [PATCH 1/2] Fixed modifiers causing sf::Keyboard::Unknown being returned in key events on Unix (#1012). On Unix, SFML now tries harder to create proper key events on keyboards that shift keys which are typically unshifted on QWERTY layouts (this makes the numeric codes usable even on AZERTY layouts). --- src/SFML/Window/Unix/WindowImplX11.cpp | 35 ++++++++++++++++++-------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/SFML/Window/Unix/WindowImplX11.cpp b/src/SFML/Window/Unix/WindowImplX11.cpp index 7aaf4e46..39fdf22d 100644 --- a/src/SFML/Window/Unix/WindowImplX11.cpp +++ b/src/SFML/Window/Unix/WindowImplX11.cpp @@ -1757,17 +1757,23 @@ bool WindowImplX11::processEvent(XEvent windowEvent) // Key down event case KeyPress: { - // Get the keysym of the key that has been pressed - static XComposeStatus keyboard; - char buffer[32]; - KeySym symbol; - XLookupString(&windowEvent.xkey, buffer, sizeof(buffer), &symbol, &keyboard); + Keyboard::Key key = Keyboard::Unknown; + + // Try each KeySym index (modifier group) until we get a match + for (int i = 0; i < 4; ++i) + { + // Get the SFML keyboard code from the keysym of the key that has been pressed + key = keysymToSF(XLookupKeysym(&windowEvent.xkey, i)); + + if (key != Keyboard::Unknown) + break; + } // Fill the event parameters // TODO: if modifiers are wrong, use XGetModifierMapping to retrieve the actual modifiers mapping Event event; event.type = Event::KeyPressed; - event.key.code = keysymToSF(symbol); + event.key.code = key; event.key.alt = windowEvent.xkey.state & Mod1Mask; event.key.control = windowEvent.xkey.state & ControlMask; event.key.shift = windowEvent.xkey.state & ShiftMask; @@ -1826,15 +1832,22 @@ bool WindowImplX11::processEvent(XEvent windowEvent) // Key up event case KeyRelease: { - // Get the keysym of the key that has been pressed - char buffer[32]; - KeySym symbol; - XLookupString(&windowEvent.xkey, buffer, 32, &symbol, NULL); + Keyboard::Key key = Keyboard::Unknown; + + // Try each KeySym index (modifier group) until we get a match + for (int i = 0; i < 4; ++i) + { + // Get the SFML keyboard code from the keysym of the key that has been released + key = keysymToSF(XLookupKeysym(&windowEvent.xkey, i)); + + if (key != Keyboard::Unknown) + break; + } // Fill the event parameters Event event; event.type = Event::KeyReleased; - event.key.code = keysymToSF(symbol); + event.key.code = key; event.key.alt = windowEvent.xkey.state & Mod1Mask; event.key.control = windowEvent.xkey.state & ControlMask; event.key.shift = windowEvent.xkey.state & ShiftMask; From 4a12244aab5f5d24330faa1cdea94fa7ad2a0b88 Mon Sep 17 00:00:00 2001 From: Stefan Schindler Date: Wed, 20 Jan 2016 20:44:49 +0100 Subject: [PATCH 2/2] Added more keysym checks for Linux to detect RAlt (mod5). --- src/SFML/Window/Unix/WindowImplX11.cpp | 206 +++++++++++++------------ 1 file changed, 104 insertions(+), 102 deletions(-) diff --git a/src/SFML/Window/Unix/WindowImplX11.cpp b/src/SFML/Window/Unix/WindowImplX11.cpp index 39fdf22d..479e1e2b 100644 --- a/src/SFML/Window/Unix/WindowImplX11.cpp +++ b/src/SFML/Window/Unix/WindowImplX11.cpp @@ -242,108 +242,110 @@ namespace { switch (symbol) { - case XK_Shift_L: return sf::Keyboard::LShift; - case XK_Shift_R: return sf::Keyboard::RShift; - case XK_Control_L: return sf::Keyboard::LControl; - case XK_Control_R: return sf::Keyboard::RControl; - case XK_Alt_L: return sf::Keyboard::LAlt; - case XK_Alt_R: return sf::Keyboard::RAlt; - case XK_Super_L: return sf::Keyboard::LSystem; - case XK_Super_R: return sf::Keyboard::RSystem; - case XK_Menu: return sf::Keyboard::Menu; - case XK_Escape: return sf::Keyboard::Escape; - case XK_semicolon: return sf::Keyboard::SemiColon; - case XK_slash: return sf::Keyboard::Slash; - case XK_equal: return sf::Keyboard::Equal; - case XK_minus: return sf::Keyboard::Dash; - case XK_bracketleft: return sf::Keyboard::LBracket; - case XK_bracketright: return sf::Keyboard::RBracket; - case XK_comma: return sf::Keyboard::Comma; - case XK_period: return sf::Keyboard::Period; - case XK_apostrophe: return sf::Keyboard::Quote; - case XK_backslash: return sf::Keyboard::BackSlash; - case XK_grave: return sf::Keyboard::Tilde; - case XK_space: return sf::Keyboard::Space; - case XK_Return: return sf::Keyboard::Return; - case XK_KP_Enter: return sf::Keyboard::Return; - case XK_BackSpace: return sf::Keyboard::BackSpace; - case XK_Tab: return sf::Keyboard::Tab; - case XK_Prior: return sf::Keyboard::PageUp; - case XK_Next: return sf::Keyboard::PageDown; - case XK_End: return sf::Keyboard::End; - case XK_Home: return sf::Keyboard::Home; - case XK_Insert: return sf::Keyboard::Insert; - case XK_Delete: return sf::Keyboard::Delete; - case XK_KP_Add: return sf::Keyboard::Add; - case XK_KP_Subtract: return sf::Keyboard::Subtract; - case XK_KP_Multiply: return sf::Keyboard::Multiply; - case XK_KP_Divide: return sf::Keyboard::Divide; - case XK_Pause: return sf::Keyboard::Pause; - case XK_F1: return sf::Keyboard::F1; - case XK_F2: return sf::Keyboard::F2; - case XK_F3: return sf::Keyboard::F3; - case XK_F4: return sf::Keyboard::F4; - case XK_F5: return sf::Keyboard::F5; - case XK_F6: return sf::Keyboard::F6; - case XK_F7: return sf::Keyboard::F7; - case XK_F8: return sf::Keyboard::F8; - case XK_F9: return sf::Keyboard::F9; - case XK_F10: return sf::Keyboard::F10; - case XK_F11: return sf::Keyboard::F11; - case XK_F12: return sf::Keyboard::F12; - case XK_F13: return sf::Keyboard::F13; - case XK_F14: return sf::Keyboard::F14; - case XK_F15: return sf::Keyboard::F15; - case XK_Left: return sf::Keyboard::Left; - case XK_Right: return sf::Keyboard::Right; - case XK_Up: return sf::Keyboard::Up; - case XK_Down: return sf::Keyboard::Down; - case XK_KP_Insert: return sf::Keyboard::Numpad0; - case XK_KP_End: return sf::Keyboard::Numpad1; - case XK_KP_Down: return sf::Keyboard::Numpad2; - case XK_KP_Page_Down: return sf::Keyboard::Numpad3; - case XK_KP_Left: return sf::Keyboard::Numpad4; - case XK_KP_Begin: return sf::Keyboard::Numpad5; - case XK_KP_Right: return sf::Keyboard::Numpad6; - case XK_KP_Home: return sf::Keyboard::Numpad7; - case XK_KP_Up: return sf::Keyboard::Numpad8; - case XK_KP_Page_Up: return sf::Keyboard::Numpad9; - case XK_a: return sf::Keyboard::A; - case XK_b: return sf::Keyboard::B; - case XK_c: return sf::Keyboard::C; - case XK_d: return sf::Keyboard::D; - case XK_e: return sf::Keyboard::E; - case XK_f: return sf::Keyboard::F; - case XK_g: return sf::Keyboard::G; - case XK_h: return sf::Keyboard::H; - case XK_i: return sf::Keyboard::I; - case XK_j: return sf::Keyboard::J; - case XK_k: return sf::Keyboard::K; - case XK_l: return sf::Keyboard::L; - case XK_m: return sf::Keyboard::M; - case XK_n: return sf::Keyboard::N; - case XK_o: return sf::Keyboard::O; - case XK_p: return sf::Keyboard::P; - case XK_q: return sf::Keyboard::Q; - case XK_r: return sf::Keyboard::R; - case XK_s: return sf::Keyboard::S; - case XK_t: return sf::Keyboard::T; - case XK_u: return sf::Keyboard::U; - case XK_v: return sf::Keyboard::V; - case XK_w: return sf::Keyboard::W; - case XK_x: return sf::Keyboard::X; - case XK_y: return sf::Keyboard::Y; - case XK_z: return sf::Keyboard::Z; - case XK_0: return sf::Keyboard::Num0; - case XK_1: return sf::Keyboard::Num1; - case XK_2: return sf::Keyboard::Num2; - case XK_3: return sf::Keyboard::Num3; - case XK_4: return sf::Keyboard::Num4; - case XK_5: return sf::Keyboard::Num5; - case XK_6: return sf::Keyboard::Num6; - case XK_7: return sf::Keyboard::Num7; - case XK_8: return sf::Keyboard::Num8; - case XK_9: return sf::Keyboard::Num9; + case XK_Shift_L: return sf::Keyboard::LShift; + case XK_Shift_R: return sf::Keyboard::RShift; + case XK_Control_L: return sf::Keyboard::LControl; + case XK_Control_R: return sf::Keyboard::RControl; + case XK_Alt_L: return sf::Keyboard::LAlt; + case XK_ISO_Level3_Shift: + case XK_Mode_switch: + case XK_Alt_R: return sf::Keyboard::RAlt; + case XK_Super_L: return sf::Keyboard::LSystem; + case XK_Super_R: return sf::Keyboard::RSystem; + case XK_Menu: return sf::Keyboard::Menu; + case XK_Escape: return sf::Keyboard::Escape; + case XK_semicolon: return sf::Keyboard::SemiColon; + case XK_slash: return sf::Keyboard::Slash; + case XK_equal: return sf::Keyboard::Equal; + case XK_minus: return sf::Keyboard::Dash; + case XK_bracketleft: return sf::Keyboard::LBracket; + case XK_bracketright: return sf::Keyboard::RBracket; + case XK_comma: return sf::Keyboard::Comma; + case XK_period: return sf::Keyboard::Period; + case XK_apostrophe: return sf::Keyboard::Quote; + case XK_backslash: return sf::Keyboard::BackSlash; + case XK_grave: return sf::Keyboard::Tilde; + case XK_space: return sf::Keyboard::Space; + case XK_Return: return sf::Keyboard::Return; + case XK_KP_Enter: return sf::Keyboard::Return; + case XK_BackSpace: return sf::Keyboard::BackSpace; + case XK_Tab: return sf::Keyboard::Tab; + case XK_Prior: return sf::Keyboard::PageUp; + case XK_Next: return sf::Keyboard::PageDown; + case XK_End: return sf::Keyboard::End; + case XK_Home: return sf::Keyboard::Home; + case XK_Insert: return sf::Keyboard::Insert; + case XK_Delete: return sf::Keyboard::Delete; + case XK_KP_Add: return sf::Keyboard::Add; + case XK_KP_Subtract: return sf::Keyboard::Subtract; + case XK_KP_Multiply: return sf::Keyboard::Multiply; + case XK_KP_Divide: return sf::Keyboard::Divide; + case XK_Pause: return sf::Keyboard::Pause; + case XK_F1: return sf::Keyboard::F1; + case XK_F2: return sf::Keyboard::F2; + case XK_F3: return sf::Keyboard::F3; + case XK_F4: return sf::Keyboard::F4; + case XK_F5: return sf::Keyboard::F5; + case XK_F6: return sf::Keyboard::F6; + case XK_F7: return sf::Keyboard::F7; + case XK_F8: return sf::Keyboard::F8; + case XK_F9: return sf::Keyboard::F9; + case XK_F10: return sf::Keyboard::F10; + case XK_F11: return sf::Keyboard::F11; + case XK_F12: return sf::Keyboard::F12; + case XK_F13: return sf::Keyboard::F13; + case XK_F14: return sf::Keyboard::F14; + case XK_F15: return sf::Keyboard::F15; + case XK_Left: return sf::Keyboard::Left; + case XK_Right: return sf::Keyboard::Right; + case XK_Up: return sf::Keyboard::Up; + case XK_Down: return sf::Keyboard::Down; + case XK_KP_Insert: return sf::Keyboard::Numpad0; + case XK_KP_End: return sf::Keyboard::Numpad1; + case XK_KP_Down: return sf::Keyboard::Numpad2; + case XK_KP_Page_Down: return sf::Keyboard::Numpad3; + case XK_KP_Left: return sf::Keyboard::Numpad4; + case XK_KP_Begin: return sf::Keyboard::Numpad5; + case XK_KP_Right: return sf::Keyboard::Numpad6; + case XK_KP_Home: return sf::Keyboard::Numpad7; + case XK_KP_Up: return sf::Keyboard::Numpad8; + case XK_KP_Page_Up: return sf::Keyboard::Numpad9; + case XK_a: return sf::Keyboard::A; + case XK_b: return sf::Keyboard::B; + case XK_c: return sf::Keyboard::C; + case XK_d: return sf::Keyboard::D; + case XK_e: return sf::Keyboard::E; + case XK_f: return sf::Keyboard::F; + case XK_g: return sf::Keyboard::G; + case XK_h: return sf::Keyboard::H; + case XK_i: return sf::Keyboard::I; + case XK_j: return sf::Keyboard::J; + case XK_k: return sf::Keyboard::K; + case XK_l: return sf::Keyboard::L; + case XK_m: return sf::Keyboard::M; + case XK_n: return sf::Keyboard::N; + case XK_o: return sf::Keyboard::O; + case XK_p: return sf::Keyboard::P; + case XK_q: return sf::Keyboard::Q; + case XK_r: return sf::Keyboard::R; + case XK_s: return sf::Keyboard::S; + case XK_t: return sf::Keyboard::T; + case XK_u: return sf::Keyboard::U; + case XK_v: return sf::Keyboard::V; + case XK_w: return sf::Keyboard::W; + case XK_x: return sf::Keyboard::X; + case XK_y: return sf::Keyboard::Y; + case XK_z: return sf::Keyboard::Z; + case XK_0: return sf::Keyboard::Num0; + case XK_1: return sf::Keyboard::Num1; + case XK_2: return sf::Keyboard::Num2; + case XK_3: return sf::Keyboard::Num3; + case XK_4: return sf::Keyboard::Num4; + case XK_5: return sf::Keyboard::Num5; + case XK_6: return sf::Keyboard::Num6; + case XK_7: return sf::Keyboard::Num7; + case XK_8: return sf::Keyboard::Num8; + case XK_9: return sf::Keyboard::Num9; } return sf::Keyboard::Unknown;