1
0
mirror of https://github.com/wine-mirror/wine synced 2024-07-08 20:06:18 +00:00

winewayland.drv: Lock the pointer if confined without cursor.

Pointer confinement may only be enabled by the compositor if the pointer
enters the confine region. If the region is small (as in many
mouselook cases) it's very likely that this will never happen and the
pointer will remained unconfined.

To allow mouselook to work more reliably, prefer to lock the pointer if
a window is confined and the cursor is not visible.
This commit is contained in:
Alexandros Frantzis 2023-12-06 15:08:31 +02:00 committed by Alexandre Julliard
parent 4ab524ee4c
commit 140f0c03d0
2 changed files with 44 additions and 7 deletions

View File

@ -338,6 +338,11 @@ void wayland_pointer_deinit(void)
zwp_confined_pointer_v1_destroy(pointer->zwp_confined_pointer_v1);
pointer->zwp_confined_pointer_v1 = NULL;
}
if (pointer->zwp_locked_pointer_v1)
{
zwp_locked_pointer_v1_destroy(pointer->zwp_locked_pointer_v1);
pointer->zwp_locked_pointer_v1 = NULL;
}
if (pointer->zwp_relative_pointer_v1)
{
zwp_relative_pointer_v1_destroy(pointer->zwp_relative_pointer_v1);
@ -729,11 +734,30 @@ static void wayland_pointer_update_constraint(RECT *confine_rect,
struct wl_surface *wl_surface)
{
struct wayland_pointer *pointer = &process_wayland.pointer;
BOOL needs_relative;
BOOL needs_relative, needs_lock, needs_confine;
assert(!confine_rect || wl_surface);
if (confine_rect)
needs_lock = confine_rect && !pointer->cursor.wl_surface;
needs_confine = confine_rect && pointer->cursor.wl_surface;
if (!needs_confine && pointer->zwp_confined_pointer_v1)
{
TRACE("Unconfining from hwnd=%p\n", pointer->constraint_hwnd);
zwp_confined_pointer_v1_destroy(pointer->zwp_confined_pointer_v1);
pointer->zwp_confined_pointer_v1 = NULL;
pointer->constraint_hwnd = NULL;
}
if (!needs_lock && pointer->zwp_locked_pointer_v1)
{
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;
pointer->constraint_hwnd = NULL;
}
if (needs_confine)
{
HWND hwnd = wl_surface_get_user_data(wl_surface);
struct wl_region *region;
@ -770,12 +794,24 @@ static void wayland_pointer_update_constraint(RECT *confine_rect,
wl_region_destroy(region);
}
else if (pointer->zwp_confined_pointer_v1)
else if (needs_lock)
{
TRACE("Unconfining from hwnd=%p\n", pointer->constraint_hwnd);
zwp_confined_pointer_v1_destroy(pointer->zwp_confined_pointer_v1);
pointer->zwp_confined_pointer_v1 = NULL;
pointer->constraint_hwnd = NULL;
HWND hwnd = wl_surface_get_user_data(wl_surface);
if (!pointer->zwp_locked_pointer_v1 || pointer->constraint_hwnd != hwnd)
{
if (pointer->zwp_locked_pointer_v1)
zwp_locked_pointer_v1_destroy(pointer->zwp_locked_pointer_v1);
pointer->zwp_locked_pointer_v1 =
zwp_pointer_constraints_v1_lock_pointer(
process_wayland.zwp_pointer_constraints_v1,
wl_surface,
pointer->wl_pointer,
NULL,
ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
pointer->constraint_hwnd = hwnd;
TRACE("Locking to hwnd=%p\n", pointer->constraint_hwnd);
}
}
needs_relative = !pointer->cursor.wl_surface &&

View File

@ -92,6 +92,7 @@ struct wayland_pointer
{
struct wl_pointer *wl_pointer;
struct zwp_confined_pointer_v1 *zwp_confined_pointer_v1;
struct zwp_locked_pointer_v1 *zwp_locked_pointer_v1;
struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1;
HWND focused_hwnd;
HWND constraint_hwnd;