diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-10-25 12:12:12 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-10-25 12:12:12 +0300 |
commit | 2103194f794c9c5260583ceb7d7bbaf73f783f48 (patch) | |
tree | c1444f658ab8587ae2af28b9ce758b3f4e417ec4 /intern | |
parent | 83877632a37af921d94811f47798c65520974a92 (diff) |
Fix T53004: XWayland ignores cursor-warp calls
There is currently a limitation in XWayland,
the cursor needs to be hidden during warp calls.
Diffstat (limited to 'intern')
-rw-r--r-- | intern/ghost/CMakeLists.txt | 7 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemX11.cpp | 72 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowX11.cpp | 6 |
3 files changed, 71 insertions, 14 deletions
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index 31e92c94eed..5a97da28d17 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -219,6 +219,13 @@ elseif(WITH_X11) ) endif() + if(WITH_X11_XFIXES) + add_definitions(-DWITH_X11_XFIXES) + list(APPEND INC_SYS + ${X11_Xfixes_INCLUDE_PATH} + ) + endif() + if(WITH_X11_ALPHA) add_definitions(-DWITH_X11_ALPHA) endif() diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 8fff565338f..9b617a34e1a 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -61,6 +61,12 @@ #include <X11/XF86keysym.h> #endif +#ifdef WITH_X11_XFIXES +# include <X11/extensions/Xfixes.h> +/* Workaround for XWayland grab glitch: T53004. */ +#define WITH_XWAYLAND_HACK +#endif + /* for XIWarpPointer */ #ifdef WITH_X11_XINPUT # include <X11/extensions/XInput2.h> @@ -95,6 +101,10 @@ static GHOST_TKey convertXKey(KeySym key); static char *txt_cut_buffer = NULL; static char *txt_select_buffer = NULL; +#ifdef WITH_XWAYLAND_HACK +static bool use_xwayland_hack = false; +#endif + using namespace std; GHOST_SystemX11:: @@ -176,7 +186,11 @@ GHOST_SystemX11( if (use_xkb) { XkbSetDetectableAutoRepeat(m_display, true, NULL); } - + +#ifdef WITH_XWAYLAND_HACK + use_xwayland_hack = getenv("WAYLAND_DISPLAY") != NULL; +#endif + #ifdef WITH_X11_XINPUT /* detect if we have xinput (for reuse) */ { @@ -1472,23 +1486,21 @@ getButtons( return GHOST_kSuccess; } - -GHOST_TSuccess -GHOST_SystemX11:: -getCursorPosition( - GHOST_TInt32& x, - GHOST_TInt32& y) const +static GHOST_TSuccess getCursorPosition_impl( + Display *display, + GHOST_TInt32& x, + GHOST_TInt32& y, + Window *child_return) { - - Window root_return, child_return; int rx, ry, wx, wy; unsigned int mask_return; + Window root_return; if (XQueryPointer( - m_display, - RootWindow(m_display, DefaultScreen(m_display)), + display, + RootWindow(display, DefaultScreen(display)), &root_return, - &child_return, + child_return, &rx, &ry, &wx, &wy, &mask_return @@ -1498,10 +1510,20 @@ getCursorPosition( else { x = rx; y = ry; - } + } return GHOST_kSuccess; } +GHOST_TSuccess +GHOST_SystemX11:: +getCursorPosition( + GHOST_TInt32& x, + GHOST_TInt32& y) const +{ + Window child_return; + return getCursorPosition_impl(m_display, x, y, &child_return); +} + GHOST_TSuccess GHOST_SystemX11:: @@ -1515,13 +1537,29 @@ setCursorPosition( * current pointer position. */ int cx, cy; + +#ifdef WITH_XWAYLAND_HACK + Window child_return = None; + if (getCursorPosition_impl(m_display, cx, cy, &child_return) == GHOST_kFailure) { + return GHOST_kFailure; + } +#else if (getCursorPosition(cx, cy) == GHOST_kFailure) { return GHOST_kFailure; } +#endif int relx = x - cx; int rely = y - cy; +#ifdef WITH_XWAYLAND_HACK + if (use_xwayland_hack) { + if (child_return != None) { + XFixesHideCursor(m_display, child_return); + } + } +#endif + #ifdef WITH_X11_XINPUT if ((m_xinput_version.present) && (m_xinput_version.major_version >= 2)) @@ -1538,6 +1576,14 @@ setCursorPosition( XWarpPointer(m_display, None, None, 0, 0, 0, 0, relx, rely); } +#ifdef WITH_XWAYLAND_HACK + if (use_xwayland_hack) { + if (child_return != None) { + XFixesShowCursor(m_display, child_return); + } + } +#endif + XSync(m_display, 0); /* Sync to process all requests */ return GHOST_kSuccess; diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index 9e019b233f6..1abdec37403 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -1526,7 +1526,6 @@ setWindowCursorGrab( else { if (m_cursorGrab == GHOST_kGrabHide) { m_system->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); - setWindowCursorVisibility(true); } if (m_cursorGrab != GHOST_kGrabNormal) { @@ -1550,6 +1549,11 @@ setWindowCursorGrab( } } + /* Perform this last so to workaround XWayland bug, see: T53004. */ + if (m_cursorGrab == GHOST_kGrabHide) { + setWindowCursorVisibility(true); + } + /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */ setCursorGrabAccum(0, 0); m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; /* disable */ |