From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Wed, 6 Feb 2019 15:42:53 +0100 Subject: [PATCH] spice-widget: Release GdkSeat cursor on pointer ungrab Using different GDK APIs to grab and ungrab the pointer device can lead to the cursor not reappearing on ungrab because GDK keeps a reference of the GdkSeat cursor. Use the GdkSeat API to set a `NULL` cursor prior to ungrab the pointer so that the cursor is recovered after the pointer is ungrabbed. Thanks-to: Peter Hutterer Signed-off-by: Olivier Fourdan Fixes: https://gitlab.freedesktop.org/spice/spice-gtk/issues/83 See-also: https://gitlab.gnome.org/GNOME/gtk/issues/787 --- src/spice-widget.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/spice-widget.c b/src/spice-widget.c index 8adcc38..853cdcb 100644 --- a/src/spice-widget.c +++ b/src/spice-widget.c @@ -32,6 +32,9 @@ #include #endif #endif +#ifdef GDK_WINDOWING_WAYLAND +#include +#endif #ifdef G_OS_WIN32 #include #include @@ -1151,9 +1154,31 @@ static void mouse_wrap(SpiceDisplay *display, GdkEventMotion *motion) static void ungrab_pointer(G_GNUC_UNUSED SpiceDisplay *display) { G_GNUC_BEGIN_IGNORE_DEPRECATIONS + GdkSeat *seat = spice_display_get_default_seat(display); + GdkDevice *pointer = gdk_seat_get_pointer(seat); + +#ifdef GDK_WINDOWING_WAYLAND + /* On Wayland, mixing the GdkSeat and the GdkDevice APIs leave the + * cursor unchanged because the GDK Wayland backend keeps a reference + * of the cursor set previously using gdk_seat_grab() attached to the + * GdkSeat. + * To avoid that issue, we simply issue another gdk_seat_grab() with + * a NULL cursor so that the previous reference (the blank cursor) + * held by the GdkSeat is released. + */ + if (GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) + gdk_seat_grab(seat, + gtk_widget_get_window(GTK_WIDGET(display)), + GDK_SEAT_CAPABILITY_ALL_POINTING, + TRUE, + NULL, + NULL, + NULL, + NULL); +#endif + /* we want to ungrab just the pointer - it is not possible using gdk_seat_ungrab(). See also https://bugzilla.gnome.org/show_bug.cgi?id=780133 */ - GdkDevice *pointer = gdk_seat_get_pointer(spice_display_get_default_seat(display)); gdk_device_ungrab(pointer, GDK_CURRENT_TIME); G_GNUC_END_IGNORE_DEPRECATIONS }