From: Attila Fidan dev@print0.net
--- dlls/winewayland.drv/wayland_pointer.c | 42 ++++++++++++++++++++++---- dlls/winewayland.drv/waylanddrv.h | 2 ++ dlls/winewayland.drv/waylanddrv_main.c | 1 + 3 files changed, 39 insertions(+), 6 deletions(-)
diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index 52aaa337aac..e2b31e02011 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -745,7 +745,8 @@ static BOOL wayland_surface_client_covers_vscreen(struct wayland_surface *surfac */ static void wayland_pointer_update_constraint(struct wl_surface *wl_surface, RECT *confine_rect, - BOOL covers_vscreen) + BOOL covers_vscreen, + BOOL force_lock) { struct wayland_pointer *pointer = &process_wayland.pointer; BOOL needs_relative, needs_lock, needs_confine; @@ -758,9 +759,10 @@ 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) || force_lock); + needs_confine = wl_surface && confine_rect && pointer->cursor.wl_surface && + !force_lock;
if (!needs_confine && pointer->zwp_confined_pointer_v1) { @@ -866,7 +868,7 @@ static void wayland_pointer_update_constraint(struct wl_surface *wl_surface,
void wayland_pointer_clear_constraint(void) { - wayland_pointer_update_constraint(NULL, NULL, FALSE); + wayland_pointer_update_constraint(NULL, NULL, FALSE, FALSE); }
/*********************************************************************** @@ -879,6 +881,27 @@ 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); + if (pointer->zwp_relative_pointer_v1) + { + pthread_mutex_unlock(&pointer->mutex); + return FALSE; + } + pointer->pending_warp = TRUE; + pthread_mutex_unlock(&pointer->mutex); + + TRACE("warping to %d,%d\n", x, y); + reapply_cursor_clipping(); + return TRUE; +} + /*********************************************************************** * WAYLAND_ClipCursor */ @@ -913,6 +936,12 @@ BOOL WAYLAND_ClipCursor(const RECT *clip, BOOL reset) wayland_win_data_release(data);
pthread_mutex_lock(&pointer->mutex); + if (wl_surface && pointer->pending_warp) + { + wayland_pointer_update_constraint(wl_surface, NULL, FALSE, TRUE); + pointer->pending_warp = FALSE; + } + if (wl_surface && hwnd == pointer->constraint_hwnd && pointer->zwp_locked_pointer_v1) { zwp_locked_pointer_v1_set_cursor_position_hint( @@ -934,7 +963,8 @@ BOOL WAYLAND_ClipCursor(const RECT *clip, BOOL reset) * so we can access it without having the win data lock. */ wayland_pointer_update_constraint(wl_surface, (clip && wl_surface) ? &confine_rect : NULL, - covers_vscreen); + covers_vscreen, + FALSE); pthread_mutex_unlock(&pointer->mutex);
wl_display_flush(process_wayland.wl_display); 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,