summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2017-05-28 15:56:20 +0200
committerPeter Hutterer <peter.hutterer@who-t.net>2017-06-07 14:48:32 +1000
commitca17f3e9fd3b59fdc5ffd0e5d78e4db6ddc87aa1 (patch)
treef44637d2793b7d6386c22f897e4cd5ae156b0fe4 /hw
parent513e3bd3870fdb8a8e0e2e52c0fa93872300bc8b (diff)
xwayland: Lock the pointer if it is confined and has no cursor
In the typical pattern in games of "hide cursor, grab with a confineTo, warp constantly the pointer to the middle of the window" the last warping step is actually rather optional. Some games may choose to just set up a grab with confineTo argument, and trust that they'll get correct relative X/Y axis values despite the hidden cursor hitting the confinement window edge. To cater for these cases, lock the pointer whenever there is a pointer confinement and the cursor is hidden. This ensures the pointer position is in sync with the compositor's when it's next shown again, and more importantly resorts to the relative pointer for event delivery. Signed-off-by: Carlos Garnacho <carlosg@gnome.org> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'hw')
-rw-r--r--hw/xwayland/xwayland-input.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 557aac8ed..02fdf6eef 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -2615,11 +2615,35 @@ xwl_seat_emulate_pointer_warp(struct xwl_seat *xwl_seat,
x, y);
}
+static Bool
+xwl_seat_maybe_lock_on_hidden_cursor(struct xwl_seat *xwl_seat)
+{
+ /* Some clients use hidden cursor+confineTo+relative motion
+ * to implement infinite panning (eg. 3D views), lock the
+ * pointer for so the relative pointer is used.
+ */
+ if (xwl_seat->x_cursor ||
+ !xwl_seat->cursor_confinement_window)
+ return FALSE;
+
+ if (xwl_seat->confined_pointer)
+ xwl_seat_destroy_confined_pointer(xwl_seat);
+
+ xwl_seat_create_pointer_warp_emulator(xwl_seat);
+ xwl_pointer_warp_emulator_lock(xwl_seat->pointer_warp_emulator);
+ return TRUE;
+}
+
void
xwl_seat_cursor_visibility_changed(struct xwl_seat *xwl_seat)
{
- if (xwl_seat->pointer_warp_emulator && xwl_seat->x_cursor != NULL)
+ if (xwl_seat->pointer_warp_emulator && xwl_seat->x_cursor != NULL) {
xwl_seat_destroy_pointer_warp_emulator(xwl_seat);
+ } else if (!xwl_seat->x_cursor && xwl_seat->cursor_confinement_window) {
+ /* If the cursor goes hidden as is confined, lock it for
+ * relative motion to work. */
+ xwl_seat_maybe_lock_on_hidden_cursor(xwl_seat);
+ }
}
void
@@ -2658,6 +2682,9 @@ xwl_seat_confine_pointer(struct xwl_seat *xwl_seat,
if (xwl_seat->pointer_warp_emulator)
return;
+ if (xwl_seat_maybe_lock_on_hidden_cursor(xwl_seat))
+ return;
+
xwl_seat->confined_pointer =
zwp_pointer_constraints_v1_confine_pointer(pointer_constraints,
xwl_window->surface,