Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2017-10-25 12:12:12 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-10-25 12:12:12 +0300
commit2103194f794c9c5260583ceb7d7bbaf73f783f48 (patch)
treec1444f658ab8587ae2af28b9ce758b3f4e417ec4 /intern/ghost
parent83877632a37af921d94811f47798c65520974a92 (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/ghost')
-rw-r--r--intern/ghost/CMakeLists.txt7
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp72
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp6
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 */