From: Attila Fidan dev@print0.net
--- dlls/winewayland.drv/wayland_pointer.c | 35 +++++++++++++++++++++++--- dlls/winewayland.drv/waylanddrv.h | 2 ++ dlls/winewayland.drv/waylanddrv_main.c | 1 + 3 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index 52aaa337aac..e8e31252024 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -758,9 +758,12 @@ static void wayland_pointer_update_constraint(struct wl_surface *wl_surface, return; }
- needs_lock = wl_surface && (confine_rect || covers_vscreen) && - !pointer->cursor.wl_surface; - needs_confine = wl_surface && confine_rect && pointer->cursor.wl_surface; + needs_lock = wl_surface && (((confine_rect || covers_vscreen) && + !pointer->cursor.wl_surface) || pointer->pending_warp); + needs_confine = wl_surface && confine_rect && pointer->cursor.wl_surface && + !pointer->pending_warp; + + pointer->pending_warp = FALSE;
if (!needs_confine && pointer->zwp_confined_pointer_v1) { @@ -879,6 +882,22 @@ void WAYLAND_SetCursor(HWND hwnd, HCURSOR hcursor) wayland_set_cursor(hwnd, hcursor, TRUE); }
+/*********************************************************************** + * WAYLAND_SetCursorPos + */ +BOOL WAYLAND_SetCursorPos(INT x, INT y) +{ + struct wayland_pointer *pointer = &process_wayland.pointer; + TRACE("warping to %d,%d\n", x, y); + + pthread_mutex_lock(&pointer->mutex); + pointer->pending_warp = TRUE; + pthread_mutex_unlock(&pointer->mutex); + + reapply_cursor_clipping(); + return TRUE; +} + /*********************************************************************** * WAYLAND_ClipCursor */ @@ -913,6 +932,16 @@ BOOL WAYLAND_ClipCursor(const RECT *clip, BOOL reset) wayland_win_data_release(data);
pthread_mutex_lock(&pointer->mutex); + if (wl_surface && pointer->pending_warp) + { + /* If a warp is pending, ensure the pointer is locked at least + * temporarily before updating the position hint. It'll be unlocked + * after setting the position hint if it wasn't locked previously. */ + wayland_pointer_update_constraint(wl_surface, + clip ? &confine_rect : NULL, + covers_vscreen); + } + if (wl_surface && hwnd == pointer->constraint_hwnd && pointer->zwp_locked_pointer_v1) { zwp_locked_pointer_v1_set_cursor_position_hint( diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 5c5ce5bf130..43641976d93 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -106,6 +106,7 @@ struct wayland_pointer struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1; HWND focused_hwnd; HWND constraint_hwnd; + BOOL pending_warp; uint32_t enter_serial; uint32_t button_serial; struct wayland_cursor cursor; @@ -396,6 +397,7 @@ LRESULT WAYLAND_DesktopWindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); void WAYLAND_DestroyWindow(HWND hwnd); BOOL WAYLAND_SetIMECompositionRect(HWND hwnd, RECT rect); void WAYLAND_SetCursor(HWND hwnd, HCURSOR hcursor); +BOOL WAYLAND_SetCursorPos(INT x, INT y); void WAYLAND_SetWindowText(HWND hwnd, LPCWSTR text); LRESULT WAYLAND_SysCommand(HWND hwnd, WPARAM wparam, LPARAM lparam, const POINT *pos); UINT WAYLAND_UpdateDisplayDevices(const struct gdi_device_manager *device_manager, void *param); diff --git a/dlls/winewayland.drv/waylanddrv_main.c b/dlls/winewayland.drv/waylanddrv_main.c index 633b2f4a043..220d5e51863 100644 --- a/dlls/winewayland.drv/waylanddrv_main.c +++ b/dlls/winewayland.drv/waylanddrv_main.c @@ -42,6 +42,7 @@ static const struct user_driver_funcs waylanddrv_funcs = .pKbdLayerDescriptor = WAYLAND_KbdLayerDescriptor, .pReleaseKbdTables = WAYLAND_ReleaseKbdTables, .pSetCursor = WAYLAND_SetCursor, + .pSetCursorPos = WAYLAND_SetCursorPos, .pSetWindowText = WAYLAND_SetWindowText, .pSysCommand = WAYLAND_SysCommand, .pUpdateDisplayDevices = WAYLAND_UpdateDisplayDevices,