forked from bartvdbraak/blender
Fix T53004: XWayland ignores cursor-warp calls
There is currently a limitation in XWayland, the cursor needs to be hidden during warp calls.
This commit is contained in:
parent
83877632a3
commit
2103194f79
@ -285,6 +285,7 @@ endif()
|
||||
if(WITH_X11)
|
||||
option(WITH_X11_XINPUT "Enable X11 Xinput (tablet support and unicode input)" ON)
|
||||
option(WITH_X11_XF86VMODE "Enable X11 video mode switching" ON)
|
||||
option(WITH_X11_XFIXES "Enable X11 XWayland cursor warping workaround" ON)
|
||||
option(WITH_X11_ALPHA "Enable X11 transparent background" ON)
|
||||
endif()
|
||||
|
||||
@ -687,6 +688,7 @@ if(WITH_GHOST_SDL OR WITH_HEADLESS)
|
||||
set(WITH_X11 OFF)
|
||||
set(WITH_X11_XINPUT OFF)
|
||||
set(WITH_X11_XF86VMODE OFF)
|
||||
set(WITH_X11_XFIXES OFF)
|
||||
set(WITH_X11_ALPHA OFF)
|
||||
set(WITH_GHOST_XDND OFF)
|
||||
set(WITH_INPUT_IME OFF)
|
||||
@ -838,6 +840,14 @@ if(WITH_X11)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_X11_XFIXES)
|
||||
if(X11_Xfixes_LIB)
|
||||
list(APPEND PLATFORM_LINKLIBS ${X11_Xfixes_LIB})
|
||||
else()
|
||||
set(WITH_X11_XFIXES OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_X11_ALPHA)
|
||||
find_library(X11_Xrender_LIB Xrender ${X11_LIB_SEARCH_PATH})
|
||||
mark_as_advanced(X11_Xrender_LIB)
|
||||
@ -1707,6 +1717,7 @@ if(FIRST_RUN)
|
||||
info_cfg_option(WITH_INSTALL_PORTABLE)
|
||||
info_cfg_option(WITH_X11_ALPHA)
|
||||
info_cfg_option(WITH_X11_XF86VMODE)
|
||||
info_cfg_option(WITH_X11_XFIXES)
|
||||
info_cfg_option(WITH_X11_XINPUT)
|
||||
info_cfg_option(WITH_MEM_JEMALLOC)
|
||||
info_cfg_option(WITH_MEM_VALGRIND)
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user