diff options
Diffstat (limited to 'intern/ghost/intern/GHOST_SystemX11.cpp')
-rw-r--r-- | intern/ghost/intern/GHOST_SystemX11.cpp | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 28a228b2777..7ba8889fd1e 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -72,6 +72,9 @@ /* for debugging - so we can breakpoint X11 errors */ // #define USE_X11_ERROR_HANDLERS +/* see [#34039] Fix Alt key glitch on Unity desktop */ +#define USE_UNITY_WORKAROUND + static GHOST_TKey convertXKey(KeySym key); /* these are for copy and select copy */ @@ -234,6 +237,25 @@ getMainDisplayDimensions( GHOST_TUns32& height) const { if (m_display) { + /* note, for this to work as documented, + * we would need to use Xinerama check r54370 for code that did thia, + * we've since removed since its not worth the extra dep - campbell */ + getAllDisplayDimensions(width, height); + } +} + + +/** + * Returns the dimensions of the main display on this system. + * \return The dimension of the main display. + */ +void +GHOST_SystemX11:: +getAllDisplayDimensions( + GHOST_TUns32& width, + GHOST_TUns32& height) const +{ + if (m_display) { width = DisplayWidth(m_display, DefaultScreen(m_display)); height = DisplayHeight(m_display, DefaultScreen(m_display)); } @@ -496,6 +518,54 @@ processEvents( processEvent(&xevent); anyProcessed = true; + + +#ifdef USE_UNITY_WORKAROUND + /* note: processEvent() can't include this code because + * KeymapNotify event have no valid window information. */ + + /* the X server generates KeymapNotify event immediately after + * every EnterNotify and FocusIn event. we handle this event + * to correct modifier states. */ + if (xevent.type == FocusIn) { + /* use previous event's window, because KeymapNotify event + * has no window information. */ + GHOST_WindowX11 *window = findGhostWindow(xevent.xany.window); + if (window && XPending(m_display) >= 2) { + XNextEvent(m_display, &xevent); + + if (xevent.type == KeymapNotify) { + XEvent xev_next; + + /* check if KeyPress or KeyRelease event was generated + * in order to confirm the window is active. */ + XPeekEvent(m_display, &xev_next); + + if (xev_next.type == KeyPress || xev_next.type == KeyRelease) { + /* XK_Hyper_L/R currently unused */ + const static KeySym modifiers[8] = {XK_Shift_L, XK_Shift_R, + XK_Control_L, XK_Control_R, + XK_Alt_L, XK_Alt_R, + XK_Super_L, XK_Super_R}; + + for (int i = 0; i < (sizeof(modifiers) / sizeof(*modifiers)); i++) { + KeyCode kc = XKeysymToKeycode(m_display, modifiers[i]); + if (((xevent.xkeymap.key_vector[kc >> 3] >> (kc & 7)) & 1) != 0) { + pushEvent(new GHOST_EventKey( + getMilliSeconds(), + GHOST_kEventKeyDown, + window, + convertXKey(modifiers[i]), + '\0', + NULL)); + } + } + } + } + } + } +#endif /* USE_UNITY_WORKAROUND */ + } if (generateWindowExposeEvents()) { |