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:
@ -478,6 +478,27 @@ _gtk_gesture_cancel_all (GtkGesture *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
|
||||
gtk_gesture_handle_event (GtkEventController *controller,
|
||||
const GdkEvent *event)
|
||||
@ -544,6 +565,12 @@ gtk_gesture_handle_event (GtkEventController *controller,
|
||||
case GDK_TOUCH_CANCEL:
|
||||
_gtk_gesture_cancel_sequence (gesture, sequence);
|
||||
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:
|
||||
/* Unhandled event */
|
||||
return FALSE;
|
||||
|
||||
@ -166,6 +166,11 @@ gtk_gesture_single_handle_event (GtkEventController *controller,
|
||||
}
|
||||
|
||||
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:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user