diff --git a/changes.txt b/changes.txt index 501769de..9c27ea15 100644 --- a/changes.txt +++ b/changes.txt @@ -1,5 +1,8 @@ -------------------------- 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. - 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) diff --git a/source/Irrlicht/CIrrDeviceLinux.cpp b/source/Irrlicht/CIrrDeviceLinux.cpp index 630078aa..b0914f4c 100644 --- a/source/Irrlicht/CIrrDeviceLinux.cpp +++ b/source/Irrlicht/CIrrDeviceLinux.cpp @@ -2154,6 +2154,9 @@ CIrrDeviceLinux::CCursorControl::CCursorControl(CIrrDeviceLinux* dev, bool null) : Device(dev) #ifdef _IRR_COMPILE_WITH_X11_ , PlatformBehavior(gui::ECPB_NONE), LastQuery(0) +#ifdef _IRR_LINUX_X11_XINPUT2_ + , DeviceId(0) +#endif #endif , IsVisible(true), Null(null), UseReferenceRect(false) , ActiveIcon(gui::ECI_NORMAL), ActiveIconStartTime(0) @@ -2161,6 +2164,10 @@ CIrrDeviceLinux::CCursorControl::CCursorControl(CIrrDeviceLinux* dev, bool null) #ifdef _IRR_COMPILE_WITH_X11_ if (!Null) { +#ifdef _IRR_LINUX_X11_XINPUT2_ + XIGetClientPointer(Device->XDisplay, Device->XWindow, &DeviceId); +#endif + XGCValues values; unsigned long valuemask = 0; diff --git a/source/Irrlicht/CIrrDeviceLinux.h b/source/Irrlicht/CIrrDeviceLinux.h index 64e95c13..ee71ca1c 100644 --- a/source/Irrlicht/CIrrDeviceLinux.h +++ b/source/Irrlicht/CIrrDeviceLinux.h @@ -37,6 +37,10 @@ #endif #include +#ifdef _IRR_LINUX_X11_XINPUT2_ +#include +#endif + #else #define KeySym s32 #endif @@ -224,22 +228,54 @@ namespace irr { if (UseReferenceRect) { - XWarpPointer(Device->XDisplay, - None, - Device->XWindow, 0, 0, - Device->Width, - Device->Height, - ReferenceRect.UpperLeftCorner.X + x, - ReferenceRect.UpperLeftCorner.Y + y); - +// NOTE: XIWarpPointer works when X11 has set a coordinate transformation matrix for the mouse unlike XWarpPointer +// which runs into a bug mentioned here: https://gitlab.freedesktop.org/xorg/xserver/-/issues/600 +// So also workaround for Irrlicht bug #450 +#ifdef _IRR_LINUX_X11_XINPUT2_ + if ( DeviceId != 0) + { + 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 { - XWarpPointer(Device->XDisplay, - None, - Device->XWindow, 0, 0, - Device->Width, - Device->Height, x, y); +#ifdef _IRR_LINUX_X11_XINPUT2_ + if ( DeviceId != 0) + { + XIWarpPointer(Device->XDisplay, + 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); } @@ -353,6 +389,10 @@ namespace irr u32 LastQuery; Cursor InvisCursor; +#ifdef _IRR_LINUX_X11_XINPUT2_ + int DeviceId; +#endif + struct CursorFrameX11 { CursorFrameX11() : IconHW(0) {}