gesture: Handle GdkEventGrabBroken

That may happen separately from grab-notify, and also due to external
reasons, so ensure all sequences are cancelled if a grab is taken
in some GdkWindows that would obscure events on the controller.
This commit is contained in:
Carlos Garnacho
2014-05-10 20:46:47 +02:00
parent 6a290bdecb
commit 3d34f26a6a
2 changed files with 32 additions and 0 deletions

View File

@ -478,6 +478,27 @@ _gtk_gesture_cancel_all (GtkGesture *gesture)
_gtk_gesture_check_empty (gesture); _gtk_gesture_check_empty (gesture);
} }
static gboolean
gesture_within_window (GtkGesture *gesture,
GdkWindow *parent)
{
GdkWindow *window;
GtkWidget *widget;
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
window = gtk_widget_get_window (widget);
while (window)
{
if (window == parent)
return TRUE;
window = gdk_window_get_effective_parent (window);
}
return FALSE;
}
static gboolean static gboolean
gtk_gesture_handle_event (GtkEventController *controller, gtk_gesture_handle_event (GtkEventController *controller,
const GdkEvent *event) const GdkEvent *event)
@ -544,6 +565,12 @@ gtk_gesture_handle_event (GtkEventController *controller,
case GDK_TOUCH_CANCEL: case GDK_TOUCH_CANCEL:
_gtk_gesture_cancel_sequence (gesture, sequence); _gtk_gesture_cancel_sequence (gesture, sequence);
break; break;
case GDK_GRAB_BROKEN:
if (!event->grab_broken.grab_window ||
!gesture_within_window (gesture, event->grab_broken.grab_window))
_gtk_gesture_cancel_all (gesture);
return FALSE;
default: default:
/* Unhandled event */ /* Unhandled event */
return FALSE; return FALSE;

View File

@ -166,6 +166,11 @@ gtk_gesture_single_handle_event (GtkEventController *controller,
} }
break; break;
case GDK_TOUCH_CANCEL:
case GDK_GRAB_BROKEN:
return GTK_EVENT_CONTROLLER_CLASS (gtk_gesture_single_parent_class)->handle_event (controller,
event);
break;
default: default:
return FALSE; return FALSE;
} }