From 0df1c97af741bd1659780ce8c150ed8d357e9a4e Mon Sep 17 00:00:00 2001 From: binary1248 Date: Sat, 23 May 2015 19:32:41 +0200 Subject: [PATCH] Fixed keyboard mapping not being correct after the user changes their keyboard layout while an SFML application is running. Fixes #895 --- src/SFML/Window/Unix/Display.cpp | 146 ++++++++--------- src/SFML/Window/Unix/Display.hpp | 6 + src/SFML/Window/Unix/InputImpl.cpp | 216 +++++++++++++------------ src/SFML/Window/Unix/InputImpl.hpp | 6 + src/SFML/Window/Unix/WindowImplX11.cpp | 56 +++++++ 5 files changed, 251 insertions(+), 179 deletions(-) diff --git a/src/SFML/Window/Unix/Display.cpp b/src/SFML/Window/Unix/Display.cpp index e537224c..cf1357db 100644 --- a/src/SFML/Window/Unix/Display.cpp +++ b/src/SFML/Window/Unix/Display.cpp @@ -145,77 +145,6 @@ namespace return keysym; } - - void buildMap() - { - // Open a connection with the X server - xcb_connection_t* connection = sf::priv::OpenConnection(); - - firstKeycode = xcb_get_setup(connection)->min_keycode; - lastKeycode = xcb_get_setup(connection)->max_keycode; - - sf::priv::ScopedXcbPtr error(NULL); - - sf::priv::ScopedXcbPtr keyboardMapping(xcb_get_keyboard_mapping_reply( - connection, - xcb_get_keyboard_mapping( - connection, - firstKeycode, - lastKeycode - firstKeycode + 1 - ), - &error - )); - - sf::priv::CloseConnection(connection); - - if (error || !keyboardMapping) - { - sf::err() << "Failed to get keyboard mapping" << std::endl; - return; - } - - uint8_t keysymsPerKeycode = keyboardMapping->keysyms_per_keycode; - - if (!keysymsPerKeycode) - { - sf::err() << "Error: No keysyms per keycode" << std::endl; - return; - } - - const xcb_keysym_t* keysyms = xcb_get_keyboard_mapping_keysyms(keyboardMapping.get()); - - if (!keysyms) - { - sf::err() << "Failed to get keyboard mapping keysyms" << std::endl; - return; - } - - xcb_keycode_t range = lastKeycode - firstKeycode + 1; - - std::fill(keysymMap, keysymMap + 256, XK_VoidSymbol); - - for (xcb_keycode_t i = firstKeycode; ; ++i) - { - const xcb_keysym_t* keysym = &keysyms[(i - firstKeycode) * keysymsPerKeycode]; - - if ((keysymsPerKeycode == 1) || (keysym[1] == XCB_NO_SYMBOL)) - { - keysymMap[i] = keysymToLower(keysym[0]); - - if (i == lastKeycode) - break; - - continue; - } - - keysymMap[i] = keysym[0]; - - if (i == lastKeycode) - break; - } - - mapBuilt = true; - } } namespace sf @@ -344,11 +273,84 @@ xcb_atom_t getAtom(const std::string& name, bool onlyIfExists) const xcb_keysym_t* getKeysymMap() { if (!mapBuilt) - buildMap(); + buildKeysymMap(); return keysymMap; } + +//////////////////////////////////////////////////////////// +void buildKeysymMap() +{ + // Open a connection with the X server + xcb_connection_t* connection = sf::priv::OpenConnection(); + + firstKeycode = xcb_get_setup(connection)->min_keycode; + lastKeycode = xcb_get_setup(connection)->max_keycode; + + sf::priv::ScopedXcbPtr error(NULL); + + sf::priv::ScopedXcbPtr keyboardMapping(xcb_get_keyboard_mapping_reply( + connection, + xcb_get_keyboard_mapping( + connection, + firstKeycode, + lastKeycode - firstKeycode + 1 + ), + &error + )); + + sf::priv::CloseConnection(connection); + + if (error || !keyboardMapping) + { + sf::err() << "Failed to get keyboard mapping" << std::endl; + return; + } + + uint8_t keysymsPerKeycode = keyboardMapping->keysyms_per_keycode; + + if (!keysymsPerKeycode) + { + sf::err() << "Error: No keysyms per keycode" << std::endl; + return; + } + + const xcb_keysym_t* keysyms = xcb_get_keyboard_mapping_keysyms(keyboardMapping.get()); + + if (!keysyms) + { + sf::err() << "Failed to get keyboard mapping keysyms" << std::endl; + return; + } + + xcb_keycode_t range = lastKeycode - firstKeycode + 1; + + std::fill(keysymMap, keysymMap + 256, XK_VoidSymbol); + + for (xcb_keycode_t i = firstKeycode; ; ++i) + { + const xcb_keysym_t* keysym = &keysyms[(i - firstKeycode) * keysymsPerKeycode]; + + if ((keysymsPerKeycode == 1) || (keysym[1] == XCB_NO_SYMBOL)) + { + keysymMap[i] = keysymToLower(keysym[0]); + + if (i == lastKeycode) + break; + + continue; + } + + keysymMap[i] = keysym[0]; + + if (i == lastKeycode) + break; + } + + mapBuilt = true; +} + } // namespace priv } // namespace sf diff --git a/src/SFML/Window/Unix/Display.hpp b/src/SFML/Window/Unix/Display.hpp index bddd9a7b..da29d510 100644 --- a/src/SFML/Window/Unix/Display.hpp +++ b/src/SFML/Window/Unix/Display.hpp @@ -127,6 +127,12 @@ xcb_atom_t getAtom(const std::string& name, bool onlyIfExists = false); //////////////////////////////////////////////////////////// const xcb_keysym_t* getKeysymMap(); +//////////////////////////////////////////////////////////// +/// \brief Build the keysym map +/// +//////////////////////////////////////////////////////////// +void buildKeysymMap(); + } // namespace priv } // namespace sf diff --git a/src/SFML/Window/Unix/InputImpl.cpp b/src/SFML/Window/Unix/InputImpl.cpp index 4d815f84..39491151 100644 --- a/src/SFML/Window/Unix/InputImpl.cpp +++ b/src/SFML/Window/Unix/InputImpl.cpp @@ -59,113 +59,6 @@ namespace return 255; } - - void buildMap() - { - keycodeMap[sf::Keyboard::A] = getKeycode(XK_a); - keycodeMap[sf::Keyboard::B] = getKeycode(XK_b); - keycodeMap[sf::Keyboard::C] = getKeycode(XK_c); - keycodeMap[sf::Keyboard::D] = getKeycode(XK_d); - keycodeMap[sf::Keyboard::E] = getKeycode(XK_e); - keycodeMap[sf::Keyboard::F] = getKeycode(XK_f); - keycodeMap[sf::Keyboard::G] = getKeycode(XK_g); - keycodeMap[sf::Keyboard::H] = getKeycode(XK_h); - keycodeMap[sf::Keyboard::I] = getKeycode(XK_i); - keycodeMap[sf::Keyboard::J] = getKeycode(XK_j); - keycodeMap[sf::Keyboard::K] = getKeycode(XK_k); - keycodeMap[sf::Keyboard::L] = getKeycode(XK_l); - keycodeMap[sf::Keyboard::M] = getKeycode(XK_m); - keycodeMap[sf::Keyboard::N] = getKeycode(XK_n); - keycodeMap[sf::Keyboard::O] = getKeycode(XK_o); - keycodeMap[sf::Keyboard::P] = getKeycode(XK_p); - keycodeMap[sf::Keyboard::Q] = getKeycode(XK_q); - keycodeMap[sf::Keyboard::R] = getKeycode(XK_r); - keycodeMap[sf::Keyboard::S] = getKeycode(XK_s); - keycodeMap[sf::Keyboard::T] = getKeycode(XK_t); - keycodeMap[sf::Keyboard::U] = getKeycode(XK_u); - keycodeMap[sf::Keyboard::V] = getKeycode(XK_v); - keycodeMap[sf::Keyboard::W] = getKeycode(XK_w); - keycodeMap[sf::Keyboard::X] = getKeycode(XK_x); - keycodeMap[sf::Keyboard::Y] = getKeycode(XK_y); - keycodeMap[sf::Keyboard::Z] = getKeycode(XK_z); - keycodeMap[sf::Keyboard::Num0] = getKeycode(XK_0); - keycodeMap[sf::Keyboard::Num1] = getKeycode(XK_1); - keycodeMap[sf::Keyboard::Num2] = getKeycode(XK_2); - keycodeMap[sf::Keyboard::Num3] = getKeycode(XK_3); - keycodeMap[sf::Keyboard::Num4] = getKeycode(XK_4); - keycodeMap[sf::Keyboard::Num5] = getKeycode(XK_5); - keycodeMap[sf::Keyboard::Num6] = getKeycode(XK_6); - keycodeMap[sf::Keyboard::Num7] = getKeycode(XK_7); - keycodeMap[sf::Keyboard::Num8] = getKeycode(XK_8); - keycodeMap[sf::Keyboard::Num9] = getKeycode(XK_9); - keycodeMap[sf::Keyboard::Escape] = getKeycode(XK_Escape); - keycodeMap[sf::Keyboard::LControl] = getKeycode(XK_Control_L); - keycodeMap[sf::Keyboard::LShift] = getKeycode(XK_Shift_L); - keycodeMap[sf::Keyboard::LAlt] = getKeycode(XK_Alt_L); - keycodeMap[sf::Keyboard::LSystem] = getKeycode(XK_Super_L); - keycodeMap[sf::Keyboard::RControl] = getKeycode(XK_Control_R); - keycodeMap[sf::Keyboard::RShift] = getKeycode(XK_Shift_R); - keycodeMap[sf::Keyboard::RAlt] = getKeycode(XK_Alt_R); - keycodeMap[sf::Keyboard::RSystem] = getKeycode(XK_Super_R); - keycodeMap[sf::Keyboard::Menu] = getKeycode(XK_Menu); - keycodeMap[sf::Keyboard::LBracket] = getKeycode(XK_bracketleft); - keycodeMap[sf::Keyboard::RBracket] = getKeycode(XK_bracketright); - keycodeMap[sf::Keyboard::SemiColon] = getKeycode(XK_semicolon); - keycodeMap[sf::Keyboard::Comma] = getKeycode(XK_comma); - keycodeMap[sf::Keyboard::Period] = getKeycode(XK_period); - keycodeMap[sf::Keyboard::Quote] = getKeycode(XK_apostrophe); - keycodeMap[sf::Keyboard::Slash] = getKeycode(XK_slash); - keycodeMap[sf::Keyboard::BackSlash] = getKeycode(XK_backslash); - keycodeMap[sf::Keyboard::Tilde] = getKeycode(XK_grave); - keycodeMap[sf::Keyboard::Equal] = getKeycode(XK_equal); - keycodeMap[sf::Keyboard::Dash] = getKeycode(XK_minus); - keycodeMap[sf::Keyboard::Space] = getKeycode(XK_space); - keycodeMap[sf::Keyboard::Return] = getKeycode(XK_Return); - keycodeMap[sf::Keyboard::BackSpace] = getKeycode(XK_BackSpace); - keycodeMap[sf::Keyboard::Tab] = getKeycode(XK_Tab); - keycodeMap[sf::Keyboard::PageUp] = getKeycode(XK_Prior); - keycodeMap[sf::Keyboard::PageDown] = getKeycode(XK_Next); - keycodeMap[sf::Keyboard::End] = getKeycode(XK_End); - keycodeMap[sf::Keyboard::Home] = getKeycode(XK_Home); - keycodeMap[sf::Keyboard::Insert] = getKeycode(XK_Insert); - keycodeMap[sf::Keyboard::Delete] = getKeycode(XK_Delete); - keycodeMap[sf::Keyboard::Add] = getKeycode(XK_KP_Add); - keycodeMap[sf::Keyboard::Subtract] = getKeycode(XK_KP_Subtract); - keycodeMap[sf::Keyboard::Multiply] = getKeycode(XK_KP_Multiply); - keycodeMap[sf::Keyboard::Divide] = getKeycode(XK_KP_Divide); - keycodeMap[sf::Keyboard::Left] = getKeycode(XK_Left); - keycodeMap[sf::Keyboard::Right] = getKeycode(XK_Right); - keycodeMap[sf::Keyboard::Up] = getKeycode(XK_Up); - keycodeMap[sf::Keyboard::Down] = getKeycode(XK_Down); - keycodeMap[sf::Keyboard::Numpad0] = getKeycode(XK_KP_0); - keycodeMap[sf::Keyboard::Numpad1] = getKeycode(XK_KP_1); - keycodeMap[sf::Keyboard::Numpad2] = getKeycode(XK_KP_2); - keycodeMap[sf::Keyboard::Numpad3] = getKeycode(XK_KP_3); - keycodeMap[sf::Keyboard::Numpad4] = getKeycode(XK_KP_4); - keycodeMap[sf::Keyboard::Numpad5] = getKeycode(XK_KP_5); - keycodeMap[sf::Keyboard::Numpad6] = getKeycode(XK_KP_6); - keycodeMap[sf::Keyboard::Numpad7] = getKeycode(XK_KP_7); - keycodeMap[sf::Keyboard::Numpad8] = getKeycode(XK_KP_8); - keycodeMap[sf::Keyboard::Numpad9] = getKeycode(XK_KP_9); - keycodeMap[sf::Keyboard::F1] = getKeycode(XK_F1); - keycodeMap[sf::Keyboard::F2] = getKeycode(XK_F2); - keycodeMap[sf::Keyboard::F3] = getKeycode(XK_F3); - keycodeMap[sf::Keyboard::F4] = getKeycode(XK_F4); - keycodeMap[sf::Keyboard::F5] = getKeycode(XK_F5); - keycodeMap[sf::Keyboard::F6] = getKeycode(XK_F6); - keycodeMap[sf::Keyboard::F7] = getKeycode(XK_F7); - keycodeMap[sf::Keyboard::F8] = getKeycode(XK_F8); - keycodeMap[sf::Keyboard::F9] = getKeycode(XK_F9); - keycodeMap[sf::Keyboard::F10] = getKeycode(XK_F10); - keycodeMap[sf::Keyboard::F11] = getKeycode(XK_F11); - keycodeMap[sf::Keyboard::F12] = getKeycode(XK_F12); - keycodeMap[sf::Keyboard::F13] = getKeycode(XK_F13); - keycodeMap[sf::Keyboard::F14] = getKeycode(XK_F14); - keycodeMap[sf::Keyboard::F15] = getKeycode(XK_F15); - keycodeMap[sf::Keyboard::Pause] = getKeycode(XK_Pause); - - mapBuilt = true; - } } @@ -423,6 +316,115 @@ Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/, const Window& /*re return Vector2i(); } + +//////////////////////////////////////////////////////////// +void InputImpl::buildMap() +{ + keycodeMap[sf::Keyboard::A] = getKeycode(XK_a); + keycodeMap[sf::Keyboard::B] = getKeycode(XK_b); + keycodeMap[sf::Keyboard::C] = getKeycode(XK_c); + keycodeMap[sf::Keyboard::D] = getKeycode(XK_d); + keycodeMap[sf::Keyboard::E] = getKeycode(XK_e); + keycodeMap[sf::Keyboard::F] = getKeycode(XK_f); + keycodeMap[sf::Keyboard::G] = getKeycode(XK_g); + keycodeMap[sf::Keyboard::H] = getKeycode(XK_h); + keycodeMap[sf::Keyboard::I] = getKeycode(XK_i); + keycodeMap[sf::Keyboard::J] = getKeycode(XK_j); + keycodeMap[sf::Keyboard::K] = getKeycode(XK_k); + keycodeMap[sf::Keyboard::L] = getKeycode(XK_l); + keycodeMap[sf::Keyboard::M] = getKeycode(XK_m); + keycodeMap[sf::Keyboard::N] = getKeycode(XK_n); + keycodeMap[sf::Keyboard::O] = getKeycode(XK_o); + keycodeMap[sf::Keyboard::P] = getKeycode(XK_p); + keycodeMap[sf::Keyboard::Q] = getKeycode(XK_q); + keycodeMap[sf::Keyboard::R] = getKeycode(XK_r); + keycodeMap[sf::Keyboard::S] = getKeycode(XK_s); + keycodeMap[sf::Keyboard::T] = getKeycode(XK_t); + keycodeMap[sf::Keyboard::U] = getKeycode(XK_u); + keycodeMap[sf::Keyboard::V] = getKeycode(XK_v); + keycodeMap[sf::Keyboard::W] = getKeycode(XK_w); + keycodeMap[sf::Keyboard::X] = getKeycode(XK_x); + keycodeMap[sf::Keyboard::Y] = getKeycode(XK_y); + keycodeMap[sf::Keyboard::Z] = getKeycode(XK_z); + keycodeMap[sf::Keyboard::Num0] = getKeycode(XK_0); + keycodeMap[sf::Keyboard::Num1] = getKeycode(XK_1); + keycodeMap[sf::Keyboard::Num2] = getKeycode(XK_2); + keycodeMap[sf::Keyboard::Num3] = getKeycode(XK_3); + keycodeMap[sf::Keyboard::Num4] = getKeycode(XK_4); + keycodeMap[sf::Keyboard::Num5] = getKeycode(XK_5); + keycodeMap[sf::Keyboard::Num6] = getKeycode(XK_6); + keycodeMap[sf::Keyboard::Num7] = getKeycode(XK_7); + keycodeMap[sf::Keyboard::Num8] = getKeycode(XK_8); + keycodeMap[sf::Keyboard::Num9] = getKeycode(XK_9); + keycodeMap[sf::Keyboard::Escape] = getKeycode(XK_Escape); + keycodeMap[sf::Keyboard::LControl] = getKeycode(XK_Control_L); + keycodeMap[sf::Keyboard::LShift] = getKeycode(XK_Shift_L); + keycodeMap[sf::Keyboard::LAlt] = getKeycode(XK_Alt_L); + keycodeMap[sf::Keyboard::LSystem] = getKeycode(XK_Super_L); + keycodeMap[sf::Keyboard::RControl] = getKeycode(XK_Control_R); + keycodeMap[sf::Keyboard::RShift] = getKeycode(XK_Shift_R); + keycodeMap[sf::Keyboard::RAlt] = getKeycode(XK_Alt_R); + keycodeMap[sf::Keyboard::RSystem] = getKeycode(XK_Super_R); + keycodeMap[sf::Keyboard::Menu] = getKeycode(XK_Menu); + keycodeMap[sf::Keyboard::LBracket] = getKeycode(XK_bracketleft); + keycodeMap[sf::Keyboard::RBracket] = getKeycode(XK_bracketright); + keycodeMap[sf::Keyboard::SemiColon] = getKeycode(XK_semicolon); + keycodeMap[sf::Keyboard::Comma] = getKeycode(XK_comma); + keycodeMap[sf::Keyboard::Period] = getKeycode(XK_period); + keycodeMap[sf::Keyboard::Quote] = getKeycode(XK_apostrophe); + keycodeMap[sf::Keyboard::Slash] = getKeycode(XK_slash); + keycodeMap[sf::Keyboard::BackSlash] = getKeycode(XK_backslash); + keycodeMap[sf::Keyboard::Tilde] = getKeycode(XK_grave); + keycodeMap[sf::Keyboard::Equal] = getKeycode(XK_equal); + keycodeMap[sf::Keyboard::Dash] = getKeycode(XK_minus); + keycodeMap[sf::Keyboard::Space] = getKeycode(XK_space); + keycodeMap[sf::Keyboard::Return] = getKeycode(XK_Return); + keycodeMap[sf::Keyboard::BackSpace] = getKeycode(XK_BackSpace); + keycodeMap[sf::Keyboard::Tab] = getKeycode(XK_Tab); + keycodeMap[sf::Keyboard::PageUp] = getKeycode(XK_Prior); + keycodeMap[sf::Keyboard::PageDown] = getKeycode(XK_Next); + keycodeMap[sf::Keyboard::End] = getKeycode(XK_End); + keycodeMap[sf::Keyboard::Home] = getKeycode(XK_Home); + keycodeMap[sf::Keyboard::Insert] = getKeycode(XK_Insert); + keycodeMap[sf::Keyboard::Delete] = getKeycode(XK_Delete); + keycodeMap[sf::Keyboard::Add] = getKeycode(XK_KP_Add); + keycodeMap[sf::Keyboard::Subtract] = getKeycode(XK_KP_Subtract); + keycodeMap[sf::Keyboard::Multiply] = getKeycode(XK_KP_Multiply); + keycodeMap[sf::Keyboard::Divide] = getKeycode(XK_KP_Divide); + keycodeMap[sf::Keyboard::Left] = getKeycode(XK_Left); + keycodeMap[sf::Keyboard::Right] = getKeycode(XK_Right); + keycodeMap[sf::Keyboard::Up] = getKeycode(XK_Up); + keycodeMap[sf::Keyboard::Down] = getKeycode(XK_Down); + keycodeMap[sf::Keyboard::Numpad0] = getKeycode(XK_KP_0); + keycodeMap[sf::Keyboard::Numpad1] = getKeycode(XK_KP_1); + keycodeMap[sf::Keyboard::Numpad2] = getKeycode(XK_KP_2); + keycodeMap[sf::Keyboard::Numpad3] = getKeycode(XK_KP_3); + keycodeMap[sf::Keyboard::Numpad4] = getKeycode(XK_KP_4); + keycodeMap[sf::Keyboard::Numpad5] = getKeycode(XK_KP_5); + keycodeMap[sf::Keyboard::Numpad6] = getKeycode(XK_KP_6); + keycodeMap[sf::Keyboard::Numpad7] = getKeycode(XK_KP_7); + keycodeMap[sf::Keyboard::Numpad8] = getKeycode(XK_KP_8); + keycodeMap[sf::Keyboard::Numpad9] = getKeycode(XK_KP_9); + keycodeMap[sf::Keyboard::F1] = getKeycode(XK_F1); + keycodeMap[sf::Keyboard::F2] = getKeycode(XK_F2); + keycodeMap[sf::Keyboard::F3] = getKeycode(XK_F3); + keycodeMap[sf::Keyboard::F4] = getKeycode(XK_F4); + keycodeMap[sf::Keyboard::F5] = getKeycode(XK_F5); + keycodeMap[sf::Keyboard::F6] = getKeycode(XK_F6); + keycodeMap[sf::Keyboard::F7] = getKeycode(XK_F7); + keycodeMap[sf::Keyboard::F8] = getKeycode(XK_F8); + keycodeMap[sf::Keyboard::F9] = getKeycode(XK_F9); + keycodeMap[sf::Keyboard::F10] = getKeycode(XK_F10); + keycodeMap[sf::Keyboard::F11] = getKeycode(XK_F11); + keycodeMap[sf::Keyboard::F12] = getKeycode(XK_F12); + keycodeMap[sf::Keyboard::F13] = getKeycode(XK_F13); + keycodeMap[sf::Keyboard::F14] = getKeycode(XK_F14); + keycodeMap[sf::Keyboard::F15] = getKeycode(XK_F15); + keycodeMap[sf::Keyboard::Pause] = getKeycode(XK_Pause); + + mapBuilt = true; +} + } // namespace priv } // namespace sf diff --git a/src/SFML/Window/Unix/InputImpl.hpp b/src/SFML/Window/Unix/InputImpl.hpp index 9425c3df..ec4f11e9 100644 --- a/src/SFML/Window/Unix/InputImpl.hpp +++ b/src/SFML/Window/Unix/InputImpl.hpp @@ -158,6 +158,12 @@ public: /// //////////////////////////////////////////////////////////// static Vector2i getTouchPosition(unsigned int finger, const Window& relativeTo); + + //////////////////////////////////////////////////////////// + /// \brief Build the SFML to X11 keymap + /// + //////////////////////////////////////////////////////////// + static void buildMap(); }; } // namespace priv diff --git a/src/SFML/Window/Unix/WindowImplX11.cpp b/src/SFML/Window/Unix/WindowImplX11.cpp index 07f27a85..7d8f984a 100644 --- a/src/SFML/Window/Unix/WindowImplX11.cpp +++ b/src/SFML/Window/Unix/WindowImplX11.cpp @@ -28,6 +28,7 @@ #include // important to be included first (conflict with None) #include #include +#include #include #include #include @@ -50,6 +51,10 @@ #define XCB_DRI2_BUFFER_SWAP_COMPLETE 0 #define XCB_DRI2_INVALIDATE_BUFFERS 1 +// So we don't have to require xcb xkb to be present +#define XCB_XKB_NEW_KEYBOARD_NOTIFY 0 +#define XCB_XKB_MAP_NOTIFY 1 + #ifdef SFML_OPENGL_ES #include typedef sf::priv::EglContext ContextType; @@ -2317,6 +2322,57 @@ bool WindowImplX11::processEvent(xcb_generic_event_t* windowEvent) } } + // XKEYBOARD + // When the X server sends us XKEYBOARD events, it means that + // the user probably changed the layout of their keyboard + // We update our keymaps in that case + static xcb_query_extension_reply_t xkeyboardExtension = getXExtension("XKEYBOARD"); + if (xkeyboardExtension.present && (responseType == xkeyboardExtension.first_event)) + { + // We do this so we don't have to include the xkb header for the struct declaration + uint8_t xkbType = reinterpret_cast(windowEvent)[1]; + + // We only bother rebuilding our maps if the xkb mapping actually changes + if ((xkbType == XCB_XKB_NEW_KEYBOARD_NOTIFY) || (xkbType == XCB_XKB_MAP_NOTIFY)) + { + // keysym map + buildKeysymMap(); + + // keycode to SFML + buildMap(); + + // SFML to keycode + InputImpl::buildMap(); + + // XInputMethod expects keyboard mapping changes to be propagated to it + // Same idea here as with the DRI2 events above + + // We lock/unlock the display to protect against concurrent access + XLockDisplay(m_display); + + typedef Bool (*wireEventHandler)(Display*, XEvent*, xEvent*); + + // Probe for any handlers that are registered for this event type + wireEventHandler handler = XESetWireToEvent(m_display, responseType, 0); + + if (handler) + { + // Restore the previous handler if one was registered + XESetWireToEvent(m_display, responseType, handler); + + XEvent event; + windowEvent->sequence = LastKnownRequestProcessed(m_display); + + // Pretend to be the Xlib event queue + handler(m_display, &event, reinterpret_cast(windowEvent)); + } + + XUnlockDisplay(m_display); + } + + break; + } + // Print any surprises to stderr (would be nice if people report when this happens) dumpUnhandledEvent(responseType);