From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Christophe Fergeau Date: Mon, 8 Aug 2016 17:19:29 +0200 Subject: [PATCH] mouse: Fix pointer grabbing in server mode Trying to click on spice-gtk window while in server mode should result in a pointer grab. This is currently failing, with the cursor wrapping to the top left corner of the window instead without being grabbed. This is caused by our use of gtk_event_box_set_above_child(), when clicking on the SpiceWidget, the grab is implicitly taken by the window which is above the event box (which is an internal GtkEventBox input-only GdkWindow). Then when we call gdk_pointer_grab() on the GtkEventBox::window, we get a grab-broken event indicating the grab was transferred from the internal input-only window to GtkEventBox::window (see gtk+ bug https://bugzilla.gnome.org/show_bug.cgi?id=769635#c2 for a detailed explanation). This commit ignores grab-broken events when the GdkWindow who got the grab corresponds to the one we called gdk_pointer_grab() on. An alternative would be to call gdk_pointer_grab() on the GdkWindow which received the button-press-event, but the call chain between button_event() and the eventual gdk_pointer_grab() call, so it would be not so elegant to pass the correct GdkWindow all the way. --- src/spice-widget.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/spice-widget.c b/src/spice-widget.c index 67e66b7..9c8f7d1 100644 --- a/src/spice-widget.c +++ b/src/spice-widget.c @@ -472,8 +472,19 @@ static GdkCursor* get_blank_cursor(void) static gboolean grab_broken(SpiceDisplay *self, GdkEventGrabBroken *event, gpointer user_data G_GNUC_UNUSED) { + GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(self)); SPICE_DEBUG("%s (implicit: %d, keyboard: %d)", __FUNCTION__, event->implicit, event->keyboard); + SPICE_DEBUG("%s (SpiceDisplay::GdkWindow %p, event->grab_window: %p)", + __FUNCTION__, window, event->grab_window); + if (window == event->grab_window) { + /* ignore grab-broken event moving the grab to GtkEventBox::window + * (from GtkEventBox::event_window) as we initially called + * gdk_pointer_grab() on GtkEventBox::window, see + * https://bugzilla.gnome.org/show_bug.cgi?id=769635 + */ + return false; + } if (event->keyboard) { try_keyboard_ungrab(self);