From 556371ea107d16631f49275419f9616e7530162f Mon Sep 17 00:00:00 2001 From: binary1248 Date: Thu, 24 Dec 2015 18:31:15 +0100 Subject: [PATCH] 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 09156fa02..4f4ce64aa 100644 --- a/src/SFML/Window/Unix/WindowImplX11.cpp +++ b/src/SFML/Window/Unix/WindowImplX11.cpp @@ -1759,17 +1759,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; @@ -1828,15 +1834,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;