From: Attila Fidan dev@print0.net
--- dlls/winewayland.drv/wayland_pointer.c | 41 ++++++++++++++++++++++---- dlls/winewayland.drv/waylanddrv.h | 2 ++ dlls/winewayland.drv/waylanddrv_main.c | 1 + 3 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index ea449dd3cc9..294a33588b6 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -808,9 +808,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) { @@ -929,6 +932,21 @@ 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; + + pthread_mutex_lock(&pointer->mutex); + pointer->pending_warp = TRUE; + pthread_mutex_unlock(&pointer->mutex); + + reapply_cursor_clipping(); + return TRUE; +} + /*********************************************************************** * WAYLAND_ClipCursor */ @@ -954,11 +972,24 @@ BOOL WAYLAND_ClipCursor(const RECT *clip, BOOL reset) } wayland_win_data_release(data);
- update_cursor_position_hint(hwnd); - /* Since we are running in the context of the foreground thread we know * that the wl_surface of the foreground HWND will not be invalidated, * so we can access it without having the win data lock. */ + + pthread_mutex_lock(&pointer->mutex); + if (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 && wl_surface) ? &confine_rect : NULL, + covers_vscreen); + } + pthread_mutex_unlock(&pointer->mutex); + + update_cursor_position_hint(hwnd); + pthread_mutex_lock(&pointer->mutex); wayland_pointer_update_constraint(wl_surface, (clip && wl_surface) ? &confine_rect : NULL, 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,