Add a workaround for XWarpPointer bug mentioned reported by vikaig (#450)

Problem is that the mouse jumps when users have set a coordinate transformation matrix for their mouse on X11.
XWarpPointer first sets the correct coordinates, but X11 then moves the mouse wrongly to the scaled position on the next mouse event.
On X-Org bugtracker it's this bug: https://gitlab.freedesktop.org/xorg/xserver/-/issues/600
The fix needs compiling with _IRR_LINUX_X11_XINPUT2_ enabled (so far disabled by default)
Note: We only use XINPUT2 so far for touch-input... I hope this patch won't conflict with that.
Also I mix now IInput2 and X11 functions as getting the mouse-position still uses X11. But seems to work in my tests.


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6230 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
cutealien 2021-08-19 17:25:08 +00:00
parent 34f4ae4797
commit 84b1fa30f0
3 changed files with 63 additions and 13 deletions

@ -1,5 +1,8 @@
-------------------------- --------------------------
Changes in 1.9 (not yet released) Changes in 1.9 (not yet released)
- Add a workaround for XWarpPointer bug that causes mouse to jump when users have set a Coordinate Transformation Matrix for their mouse on X11.
This was mentioned in bug #450 by vikaig.
The fix needs compiling with _IRR_LINUX_X11_XINPUT2_ enabled (so far disabled by default)
- Add IGeometryCreator::createTorusMesh to create donuts. - Add IGeometryCreator::createTorusMesh to create donuts.
- Don't try loading broken image files twice with same loader anymore. - Don't try loading broken image files twice with same loader anymore.
- Make CImageLoaderJPG thread safe. Thanks @ Edoardo Lolletti for report and patch (patch #324) - Make CImageLoaderJPG thread safe. Thanks @ Edoardo Lolletti for report and patch (patch #324)

@ -2154,6 +2154,9 @@ CIrrDeviceLinux::CCursorControl::CCursorControl(CIrrDeviceLinux* dev, bool null)
: Device(dev) : Device(dev)
#ifdef _IRR_COMPILE_WITH_X11_ #ifdef _IRR_COMPILE_WITH_X11_
, PlatformBehavior(gui::ECPB_NONE), LastQuery(0) , PlatformBehavior(gui::ECPB_NONE), LastQuery(0)
#ifdef _IRR_LINUX_X11_XINPUT2_
, DeviceId(0)
#endif
#endif #endif
, IsVisible(true), Null(null), UseReferenceRect(false) , IsVisible(true), Null(null), UseReferenceRect(false)
, ActiveIcon(gui::ECI_NORMAL), ActiveIconStartTime(0) , ActiveIcon(gui::ECI_NORMAL), ActiveIconStartTime(0)
@ -2161,6 +2164,10 @@ CIrrDeviceLinux::CCursorControl::CCursorControl(CIrrDeviceLinux* dev, bool null)
#ifdef _IRR_COMPILE_WITH_X11_ #ifdef _IRR_COMPILE_WITH_X11_
if (!Null) if (!Null)
{ {
#ifdef _IRR_LINUX_X11_XINPUT2_
XIGetClientPointer(Device->XDisplay, Device->XWindow, &DeviceId);
#endif
XGCValues values; XGCValues values;
unsigned long valuemask = 0; unsigned long valuemask = 0;

@ -37,6 +37,10 @@
#endif #endif
#include <X11/keysym.h> #include <X11/keysym.h>
#ifdef _IRR_LINUX_X11_XINPUT2_
#include <X11/extensions/XInput2.h>
#endif
#else #else
#define KeySym s32 #define KeySym s32
#endif #endif
@ -224,22 +228,54 @@ namespace irr
{ {
if (UseReferenceRect) if (UseReferenceRect)
{ {
XWarpPointer(Device->XDisplay, // NOTE: XIWarpPointer works when X11 has set a coordinate transformation matrix for the mouse unlike XWarpPointer
None, // which runs into a bug mentioned here: https://gitlab.freedesktop.org/xorg/xserver/-/issues/600
Device->XWindow, 0, 0, // So also workaround for Irrlicht bug #450
Device->Width, #ifdef _IRR_LINUX_X11_XINPUT2_
Device->Height, if ( DeviceId != 0)
ReferenceRect.UpperLeftCorner.X + x, {
ReferenceRect.UpperLeftCorner.Y + y); XIWarpPointer(Device->XDisplay,
DeviceId,
None,
Device->XWindow, 0, 0,
Device->Width,
Device->Height,
ReferenceRect.UpperLeftCorner.X + x,
ReferenceRect.UpperLeftCorner.Y + y);
}
else
#endif
{
XWarpPointer(Device->XDisplay,
None,
Device->XWindow, 0, 0,
Device->Width,
Device->Height,
ReferenceRect.UpperLeftCorner.X + x,
ReferenceRect.UpperLeftCorner.Y + y);
}
} }
else else
{ {
XWarpPointer(Device->XDisplay, #ifdef _IRR_LINUX_X11_XINPUT2_
None, if ( DeviceId != 0)
Device->XWindow, 0, 0, {
Device->Width, XIWarpPointer(Device->XDisplay,
Device->Height, x, y); DeviceId,
None,
Device->XWindow, 0, 0,
Device->Width,
Device->Height, x, y);
}
else
#endif
{
XWarpPointer(Device->XDisplay,
None,
Device->XWindow, 0, 0,
Device->Width,
Device->Height, x, y);
}
} }
XFlush(Device->XDisplay); XFlush(Device->XDisplay);
} }
@ -353,6 +389,10 @@ namespace irr
u32 LastQuery; u32 LastQuery;
Cursor InvisCursor; Cursor InvisCursor;
#ifdef _IRR_LINUX_X11_XINPUT2_
int DeviceId;
#endif
struct CursorFrameX11 struct CursorFrameX11
{ {
CursorFrameX11() : IconHW(0) {} CursorFrameX11() : IconHW(0) {}