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

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