[PATCH 0/1] MR11356: winewayland: Store the pending warp position.
Otherwise, the win32u position might be updated by a motion event before we can warp the Wayland cursor to the appropriate position. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11356
From: Etaash Mathamsetty <etaash.mathamsetty@gmail.com> --- dlls/winewayland.drv/wayland_pointer.c | 7 +++++++ dlls/winewayland.drv/waylanddrv.h | 1 + 2 files changed, 8 insertions(+) diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index 0c190a9a48a..6c604f7ef37 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -997,6 +997,8 @@ BOOL WAYLAND_SetCursorPos(INT x, INT y) return FALSE; } pointer->pending_warp = TRUE; + pointer->warp.x = x; + pointer->warp.y = y; pthread_mutex_unlock(&pointer->mutex); TRACE("warping to %d,%d\n", x, y); @@ -1022,6 +1024,11 @@ BOOL WAYLAND_ClipCursor(const RECT *clip, BOOL reset) NtUserGetCursorPos(&cursor_pos); hwnd = NtUserGetForegroundWindow(); + /* the cursor pos may have changed between SetCursorPos and ClipCursor calls */ + pthread_mutex_lock(&pointer->mutex); + if (pointer->pending_warp) cursor_pos = pointer->warp; + pthread_mutex_unlock(&pointer->mutex); + if (!(data = wayland_win_data_get(hwnd))) return FALSE; if ((surface = data->wayland_surface)) { diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index fa590eecd13..08e4db099f5 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -115,6 +115,7 @@ struct wayland_pointer HWND constraint_hwnd; BOOL relative_mode; BOOL pending_warp; + POINT warp; uint32_t enter_serial; uint32_t button_serial; struct wayland_cursor cursor; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11356
Rémi Bernon (@rbernon) commented about dlls/winewayland.drv/wayland_pointer.c:
NtUserGetCursorPos(&cursor_pos); hwnd = NtUserGetForegroundWindow();
+ /* the cursor pos may have changed between SetCursorPos and ClipCursor calls */ + pthread_mutex_lock(&pointer->mutex); + if (pointer->pending_warp) cursor_pos = pointer->warp; + pthread_mutex_unlock(&pointer->mutex);
I think you can have either and both actual mouse motion and artificial motion from the warp request that have happened and been processed between the SetCursorPos and ClipCursor calls. You can't really tell whether the position returned by `NtUserGetCursorPos` is stale or fresh at this point? If you want to ignore warp induced mouse motion it needs to be done by synchronizing between whichever call may warp the pointer, and the motion event reception. I don't know how this can be done in Wayland, but in X11 we keep the serial of the warping requests and ignore any future event that has happened before the X server processed that request. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11356#note_145371
On Fri Jul 10 09:30:19 2026 +0000, Rémi Bernon wrote:
I think you can have either and both actual mouse motion and artificial motion from the warp request that have happened and been processed between the SetCursorPos and ClipCursor calls. You can't really tell whether the position returned by `NtUserGetCursorPos` is stale or fresh at this point? If you want to ignore warp induced mouse motion it needs to be done by synchronizing between whichever call may warp the pointer, and the motion event reception. I don't know how this can be done in Wayland, but in X11 we keep the serial of the warping requests and ignore any future event that has happened before the X server processed that request. On the Wayland driver ClipCursor also does the warp so how could the warp request occur between SetCursorPos and ClipCursor? But yes we cannot tell if the returned position of NtUserGetCursorPos is the current position of the pointer or the position that we were supposed to warp to.
As for your second point, it would be nice to be able to do that but I think it might only possible with wayland 1.26 which hasn't released yet -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11356#note_145413
On Sat Jul 11 00:19:08 2026 +0000, Etaash Mathamsetty wrote:
I'm not sure what you mean by actual and artificial, but yes we cannot tell if the returned position of NtUserGetCursorPos is the current position of the pointer (with no warp applied) or the position that we were supposed to warp to. As for your second point, it would be nice to be able to do that but I think it might only possible with wayland 1.26 which hasn't released yet Should I try your approach? IMO, the current solution is a lot easier and will be supported on any compositor with currently existing protocols. Even with a warp event, I don't really see any way to correlate which `wl_pointer::warp` event corresponds to the pointer warp request. (Also, newer `wl_seat` versions introduce some new questions, e.g should we switch to server-side key repeat?)
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/11356#note_148243
On Thu Aug 6 22:14:10 2026 +0000, Etaash Mathamsetty wrote:
Should I try your approach? IMO, the current solution is a lot easier and will be supported on any compositor with currently existing protocols. Even with a warp event, I don't really see any way to correlate which `wl_pointer::warp` event corresponds to the pointer warp request. (Also, newer `wl_seat` versions introduce some new questions, e.g should we switch to server-side key repeat?) Well I don't know what you mean by "my approach" exactly, but I don't think there should be any interaction between SetCursorPos and ClipCursor, they are two completely independent calls. There is no guarantee one will ever be called after the other. There seem to be way too much dependency between the two in `winewayland` already, I don't think we should be adding more.
Then `SetCursorPos` should be synchronized with the received input so that any input that actually happened before the call is discarded. I'm not familiar enough with Wayland to say how this can be done for sure. It might require flushing the event queue before warping the cursor, I don't know. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11356#note_148271
participants (3)
-
Etaash Mathamsetty -
Etaash Mathamsetty (@etaash.mathamsetty) -
Rémi Bernon (@rbernon)