Blame SOURCES/0008-wayland-fix-mouse-lock-in-server-mode.patch

be82ae
From 16cdb3a8cdd60da9eef12d1d10a01d4eed21a5a7 Mon Sep 17 00:00:00 2001
be82ae
From: Francesco Giudici <fgiudici@redhat.com>
be82ae
Date: Mon, 20 Apr 2020 10:25:03 +0200
be82ae
Subject: [PATCH 8/9] wayland: fix mouse lock in server mode
be82ae
be82ae
We can now properly manage mouse pointer lock by using the wayland protocols.
be82ae
Includes fix from Frediano Ziglio to manage switching from mouse in
be82ae
server mode to client mode without releasing the pointer
be82ae
(see https://gitlab.freedesktop.org/fziglio/spice-gtk/-/commit/c14b047e45)
be82ae
be82ae
Signed-off-by: Francesco Giudici <fgiudici@redhat.com>
be82ae
Acked-by: Frediano Ziglio <fziglio@redhat.com>
be82ae
(cherry picked from commit dd7015d57ca936cc81060b1e2a09d3afc1478d4a)
be82ae
---
be82ae
 src/spice-widget.c | 85 +++++++++++++++++++++++++++++++++++-----------
be82ae
 1 file changed, 66 insertions(+), 19 deletions(-)
be82ae
be82ae
diff --git a/src/spice-widget.c b/src/spice-widget.c
be82ae
index 7700f47..6cfc72f 100644
be82ae
--- a/src/spice-widget.c
be82ae
+++ b/src/spice-widget.c
be82ae
@@ -34,7 +34,13 @@
be82ae
 #endif
be82ae
 #ifdef GDK_WINDOWING_WAYLAND
be82ae
 #include <gdk/gdkwayland.h>
be82ae
+#ifdef HAVE_WAYLAND_PROTOCOLS
be82ae
+#include "pointer-constraints-unstable-v1-client-protocol.h"
be82ae
+#include "relative-pointer-unstable-v1-client-protocol.h"
be82ae
+#include "wayland-extensions.h"
be82ae
 #endif
be82ae
+#endif
be82ae
+
be82ae
 #ifdef G_OS_WIN32
be82ae
 #include <windows.h>
be82ae
 #include <dinput.h>
be82ae
@@ -698,6 +704,11 @@ static void spice_display_init(SpiceDisplay *display)
be82ae
 
be82ae
     d->grabseq = spice_grab_sequence_new_from_string("Control_L+Alt_L");
be82ae
     d->activeseq = g_new0(gboolean, d->grabseq->nkeysyms);
be82ae
+
be82ae
+#ifdef HAVE_WAYLAND_PROTOCOLS
be82ae
+    if GDK_IS_WAYLAND_DISPLAY(gtk_widget_get_display(widget))
be82ae
+        spice_wayland_extensions_init(widget);
be82ae
+#endif
be82ae
 }
be82ae
 
be82ae
 static void
be82ae
@@ -900,7 +911,7 @@ static void ungrab_keyboard(SpiceDisplay *display)
be82ae
      * We simply issue a gdk_seat_ungrab() followed immediately by another
be82ae
      * gdk_seat_grab() on the pointer if the pointer grab is to be kept.
be82ae
      */
be82ae
-    if (GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) {
be82ae
+    if (GDK_IS_WAYLAND_DISPLAY(gtk_widget_get_display(GTK_WIDGET(display)))) {
be82ae
         SpiceDisplayPrivate *d = display->priv;
be82ae
 
be82ae
         gdk_seat_ungrab(seat);
be82ae
@@ -1055,15 +1066,49 @@ error:
be82ae
 }
be82ae
 #endif
be82ae
 
be82ae
+#ifdef HAVE_WAYLAND_PROTOCOLS
be82ae
+static void
be82ae
+relative_pointer_handle_relative_motion(void *data,
be82ae
+                                        struct zwp_relative_pointer_v1 *pointer,
be82ae
+                                        uint32_t time_hi,
be82ae
+                                        uint32_t time_lo,
be82ae
+                                        wl_fixed_t dx_w,
be82ae
+                                        wl_fixed_t dy_w,
be82ae
+                                        wl_fixed_t dx_unaccel_w,
be82ae
+                                        wl_fixed_t dy_unaccel_w)
be82ae
+{
be82ae
+    SpiceDisplay *display = SPICE_DISPLAY(data);
be82ae
+    GtkWidget *widget = GTK_WIDGET(display);
be82ae
+    SpiceDisplayPrivate *d = display->priv;
be82ae
+
be82ae
+    if (!d->inputs)
be82ae
+        return;
be82ae
+    if (d->disable_inputs)
be82ae
+        return;
be82ae
+    /* mode changed to client in the meantime */
be82ae
+    if (d->mouse_mode != SPICE_MOUSE_MODE_SERVER) {
be82ae
+        spice_wayland_extensions_disable_relative_pointer(widget);
be82ae
+        spice_wayland_extensions_unlock_pointer(widget);
be82ae
+        return;
be82ae
+    }
be82ae
+
be82ae
+    spice_inputs_channel_motion(d->inputs,
be82ae
+                                wl_fixed_to_int(dx_unaccel_w),
be82ae
+                                wl_fixed_to_int(dy_unaccel_w),
be82ae
+                                d->mouse_button_mask);
be82ae
+}
be82ae
+#endif
be82ae
+
be82ae
 static gboolean do_pointer_grab(SpiceDisplay *display)
be82ae
 {
be82ae
+    GtkWidget *widget = GTK_WIDGET(display);
be82ae
     SpiceDisplayPrivate *d = display->priv;
be82ae
-    GdkWindow *window = GDK_WINDOW(gtk_widget_get_window(GTK_WIDGET(display)));
be82ae
+    GdkWindow *window = GDK_WINDOW(gtk_widget_get_window(widget));
be82ae
     GdkGrabStatus status;
be82ae
     GdkCursor *blank = spice_display_get_blank_cursor(display);
be82ae
     gboolean grab_successful = FALSE;
be82ae
 
be82ae
-    if (!gtk_widget_get_realized(GTK_WIDGET(display)))
be82ae
+    if (!gtk_widget_get_realized(widget))
be82ae
         goto end;
be82ae
 
be82ae
 #ifdef G_OS_WIN32
be82ae
@@ -1080,6 +1125,14 @@ static gboolean do_pointer_grab(SpiceDisplay *display)
be82ae
                            NULL,
be82ae
                            NULL,
be82ae
                            NULL);
be82ae
+
be82ae
+#ifdef HAVE_WAYLAND_PROTOCOLS
be82ae
+    if (GDK_IS_WAYLAND_DISPLAY(gtk_widget_get_display(widget))) {
be82ae
+        spice_wayland_extensions_enable_relative_pointer(widget, relative_pointer_handle_relative_motion);
be82ae
+        spice_wayland_extensions_lock_pointer(widget, NULL, NULL);
be82ae
+    }
be82ae
+#endif
be82ae
+
be82ae
     grab_successful = (status == GDK_GRAB_SUCCESS);
be82ae
     if (!grab_successful) {
be82ae
         d->mouse_grab_active = false;
be82ae
@@ -1204,7 +1257,8 @@ static void ungrab_pointer(SpiceDisplay *display)
be82ae
      * immediately by another gdk_seat_grab() on the keyboard if the
be82ae
      * keyboard grab is to be kept.
be82ae
      */
be82ae
-    if (GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) {
be82ae
+    if (GDK_IS_WAYLAND_DISPLAY(gtk_widget_get_display(GTK_WIDGET(display)))) {
be82ae
+        GtkWidget *widget = GTK_WIDGET(display);
be82ae
         SpiceDisplayPrivate *d = display->priv;
be82ae
 
be82ae
         gdk_seat_ungrab(seat);
be82ae
@@ -1213,7 +1267,7 @@ static void ungrab_pointer(SpiceDisplay *display)
be82ae
             GdkGrabStatus status;
be82ae
 
be82ae
             status = gdk_seat_grab(seat,
be82ae
-                                   gtk_widget_get_window(GTK_WIDGET(display)),
be82ae
+                                   gtk_widget_get_window(widget),
be82ae
                                    GDK_SEAT_CAPABILITY_KEYBOARD,
be82ae
                                    FALSE,
be82ae
                                    NULL,
be82ae
@@ -1224,6 +1278,12 @@ static void ungrab_pointer(SpiceDisplay *display)
be82ae
                 g_warning("keyboard grab failed %u", status);
be82ae
                 d->keyboard_grab_active = false;
be82ae
             }
be82ae
+#ifdef HAVE_WAYLAND_PROTOCOLS
be82ae
+            if (d->mouse_mode == SPICE_MOUSE_MODE_SERVER) {
be82ae
+                spice_wayland_extensions_disable_relative_pointer(widget);
be82ae
+                spice_wayland_extensions_unlock_pointer(widget);
be82ae
+            }
be82ae
+#endif
be82ae
         }
be82ae
 
be82ae
         return;
be82ae
@@ -1860,21 +1920,8 @@ static gboolean leave_event(GtkWidget *widget, GdkEventCrossing *crossing G_GNUC
be82ae
 
be82ae
     DISPLAY_DEBUG(display, "%s", __FUNCTION__);
be82ae
 
be82ae
-    if (d->mouse_grab_active) {
be82ae
-#ifdef GDK_WINDOWING_WAYLAND
be82ae
-        /* On Wayland, there is no active pointer grab, so once the pointer
be82ae
-         * has left the window, the events are routed to the window with
be82ae
-         * pointer focus instead of ours, in which case we should just
be82ae
-         * ungrab to avoid nasty side effects. */
be82ae
-        if (GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) {
be82ae
-            GdkWindow *window = gtk_widget_get_window(widget);
be82ae
-
be82ae
-            if (window == crossing->window)
be82ae
-                try_mouse_ungrab(display);
be82ae
-        }
be82ae
-#endif
be82ae
+    if (d->mouse_grab_active)
be82ae
         return true;
be82ae
-    }
be82ae
 
be82ae
     d->mouse_have_pointer = false;
be82ae
     spice_gtk_session_set_mouse_has_pointer(d->gtk_session, false);
be82ae
-- 
be82ae
2.26.2
be82ae