If a surface is being clipped and hides the cursor, drawing its own one, winewayland constrains using a pointer lock and enables Wayland relative motion. If the application decides to stop drawing its own cursor and make the cursor visible, winewayland will disable relative motion and pointer lock, and enable pointer confinement. The user will perceive a pointer jump from the win32/application drawn cursor to where the Wayland pointer is after being unlocked and an absolute motion event is received, because they were desynchronized due to the Wayland one being locked in place.
The pointer constraints protocol says this:
If the client is drawing its own cursor, it should update the position hint to the position of its own cursor. A compositor may use this information to warp the pointer upon unlock in order to avoid pointer jumps.
So, right before unlocking, make a request for the compositor to warp the pointer to the win32 position on pointer unlock.
From: Attila Fidan dev@print0.net
If a surface is being clipped and hides the cursor, drawing its own one, winewayland constrains using a pointer lock and enables Wayland relative motion. If the application decides to stop drawing its own cursor and make the cursor visible, winewayland will disable relative motion and pointer lock, and enable pointer confinement. The user will perceive a pointer jump from the win32/application drawn cursor to where the Wayland pointer is after being unlocked and an absolute motion event is received, because they were desynchronized due to the Wayland one being locked in place.
The pointer constraints protocol says this:
If the client is drawing its own cursor, it should update the position hint to the position of its own cursor. A compositor may use this information to warp the pointer upon unlock in order to avoid pointer jumps.
So, right before unlocking, make a request for the compositor to warp the pointer to the win32 position on pointer unlock. --- dlls/winewayland.drv/wayland_pointer.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index c20ba170285..2f46b4eb55b 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -772,6 +772,32 @@ static void wayland_pointer_update_constraint(struct wl_surface *wl_surface,
if (!needs_lock && pointer->zwp_locked_pointer_v1) { + POINT cursor_pos; + struct wayland_win_data *data; + struct wayland_surface *surface; + int warp_x, warp_y; + + NtUserGetCursorPos(&cursor_pos); + if (!(data = wayland_win_data_get(wl_surface_get_user_data(wl_surface)))) + goto unlock; + if (!(surface = data->wayland_surface)) + { + wayland_win_data_release(data); + goto unlock; + } + wayland_surface_coords_from_window(surface, + cursor_pos.x - surface->window.rect.left, + cursor_pos.y - surface->window.rect.top, + &warp_x, &warp_y); + wayland_win_data_release(data); + zwp_locked_pointer_v1_set_cursor_position_hint( + pointer->zwp_locked_pointer_v1, + wl_fixed_from_int(warp_x), + wl_fixed_from_int(warp_y)); + wl_surface_commit(wl_surface); + TRACE("Attempted warp to %d,%d, surface-local %d,%d.\n", + cursor_pos.x, cursor_pos.y, warp_x, warp_y); +unlock: TRACE("Unlocking from hwnd=%p\n", pointer->constraint_hwnd); zwp_locked_pointer_v1_destroy(pointer->zwp_locked_pointer_v1); pointer->zwp_locked_pointer_v1 = NULL;