diff --git a/src/SFML/Window/Unix/WindowImplX11.cpp b/src/SFML/Window/Unix/WindowImplX11.cpp index 59a0fbace..b78548717 100644 --- a/src/SFML/Window/Unix/WindowImplX11.cpp +++ b/src/SFML/Window/Unix/WindowImplX11.cpp @@ -34,6 +34,7 @@ #include #include #include +#include // defines min/max as macros, so has to come before that #include #include #include @@ -68,6 +69,7 @@ namespace { sf::priv::WindowImplX11* fullscreenWindow = NULL; std::vector allWindows; + std::bitset<256> isKeyFiltered; sf::Mutex allWindowsMutex; sf::String windowManagerName; @@ -1901,10 +1903,30 @@ bool WindowImplX11::processEvent(XEvent& windowEvent) event.key.control = windowEvent.xkey.state & ControlMask; event.key.shift = windowEvent.xkey.state & ShiftMask; event.key.system = windowEvent.xkey.state & Mod4Mask; - pushEvent(event); - // Generate a TextEntered event - if (!XFilterEvent(&windowEvent, None)) + const bool filtered = XFilterEvent(&windowEvent, None); + + // Generate a KeyPressed event if needed + if (filtered) + { + pushEvent(event); + isKeyFiltered.set(windowEvent.xkey.keycode); + } + else + { + // Push a KeyPressed event if the key has never been filtered before + // (a KeyPressed event would have already been pushed if it had been filtered). + // + // Some dummy IMs (like the built-in one you get by setting XMODIFIERS=@im=none) + // never filter events away, and we have to take care of that. + // + // In addition, ignore text-only KeyPress events generated by IMs (with keycode set to 0). + if (!isKeyFiltered.test(windowEvent.xkey.keycode) && windowEvent.xkey.keycode != 0) + pushEvent(event); + } + + // Generate TextEntered events if needed + if (!filtered) { #ifdef X_HAVE_UTF8_STRING if (m_inputContext)