diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-01-30 08:12:32 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-01-30 08:12:32 +0400 |
commit | 7b6a34a75682839fb45372a16efec1c1bb10146a (patch) | |
tree | f5e714d7fdbf357b04c8a09eac6bd7e606c56d41 | |
parent | 2f53741cfe66fca724712f46a1321999a32a92e7 (diff) |
patch [#34039] Fix Alt key glitch on Unity desktop
by Shinsuke Irie (irie) with own minor changes.
-rw-r--r-- | intern/ghost/intern/GHOST_SystemX11.cpp | 43 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowX11.cpp | 15 |
2 files changed, 50 insertions, 8 deletions
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 28a228b2777..7df7bed1f33 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 */ @@ -496,6 +499,46 @@ 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 || xevent.type == EnterNotify)) { + /* use previous event's window, because KeymapNotify event + * has no window information. */ + GHOST_WindowX11 *window = findGhostWindow(xevent.xany.window); + if (window) { + XNextEvent(m_display, &xevent); + + if (xevent.type == KeymapNotify) { + /* 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()) { diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index 2e9ac94b9c7..f53b5d9dd77 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -266,15 +266,14 @@ GHOST_WindowX11( /* Specify which events we are interested in hearing. */ xattributes.event_mask = - ExposureMask | StructureNotifyMask | - KeyPressMask | KeyReleaseMask | - EnterWindowMask | LeaveWindowMask | - ButtonPressMask | ButtonReleaseMask | - PointerMotionMask | FocusChangeMask | PropertyChangeMask; + ExposureMask | StructureNotifyMask | + KeyPressMask | KeyReleaseMask | + EnterWindowMask | LeaveWindowMask | + ButtonPressMask | ButtonReleaseMask | + PointerMotionMask | FocusChangeMask | + PropertyChangeMask | KeymapStateMask; /* create the window! */ - - ; if (parentWindow == 0) { m_window = XCreateWindow(m_display, RootWindow(m_display, m_visual->screen), @@ -508,7 +507,7 @@ bool GHOST_WindowX11::createX11_XIC() EnterWindowMask | LeaveWindowMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask | - PropertyChangeMask | fevent); + PropertyChangeMask | KeymapStateMask | fevent); return true; } #endif |