From e3d21accd090183ba71502e140858f5d7cc500c6 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 21 Sep 2015 14:11:48 +0200 Subject: [PATCH] window: cancel unclaimed sequences after GtkEventController::handle_event. To GtkGesture machinery, if an event triggers a controller/gesture signal, and gesture reset/cancellation as a result, the event has been managed after all. Commit e3bd895667 effectively changed the return value of the wrapping gtk_event_controller_handle_event() function, which broke some paths (eg. gtk_popover_button_press() wouldn't while the GTK+ grab was active for this reason because the button press event was consumed early on gtk_window_check_handle_wm_event()). That patch is not too off-track given potential child widgets' behavior, we want nonetheless to distinguish the denied vs cancelled paths here (because GtkWindow itself relies on the GtkGesture behavior described in the first paragraph on the begin_move/resize paths), so just reset gestures after the event has already gone through the GtkEventController so the return value is unaffected. --- gtk/gtkwindow.c | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index bf6d510faf..a5930dd000 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -1451,14 +1451,6 @@ multipress_gesture_pressed_cb (GtkGestureMultiPress *gesture, { gtk_gesture_set_sequence_state (GTK_GESTURE (gesture), sequence, GTK_EVENT_SEQUENCE_DENIED); - - /* Reset immediately the gestures, here we don't get many guarantees - * about whether the target window event mask will be complete enough - * to keep gestures consistent, or whether any widget across the - * hierarchy will be inconsistent about event handler return values. - */ - gtk_event_controller_reset (GTK_EVENT_CONTROLLER (gesture)); - gtk_event_controller_reset (GTK_EVENT_CONTROLLER (priv->drag_gesture)); return; } /* fall thru */ @@ -7866,6 +7858,28 @@ get_active_region_type (GtkWindow *window, GdkEventAny *event, gint x, gint y) return GTK_WINDOW_REGION_CONTENT; } +static gboolean +controller_handle_wm_event (GtkGesture *gesture, + const GdkEvent *event) +{ + GdkEventSequence *seq; + gboolean retval; + + seq = gdk_event_get_event_sequence (event); + retval = gtk_event_controller_handle_event (GTK_EVENT_CONTROLLER (gesture), + event); + + /* Reset immediately the gestures, here we don't get many guarantees + * about whether the target window event mask will be complete enough + * to keep gestures consistent, or whether any widget across the + * hierarchy will be inconsistent about event handler return values. + */ + if (gtk_gesture_get_sequence_state (gesture, seq) == GTK_EVENT_SEQUENCE_DENIED) + gtk_event_controller_reset (GTK_EVENT_CONTROLLER (gesture)); + + return retval; +} + static gboolean gtk_window_handle_wm_event (GtkWindow *window, GdkEvent *event, @@ -7881,12 +7895,12 @@ gtk_window_handle_wm_event (GtkWindow *window, priv = window->priv; if (run_drag && priv->drag_gesture) - retval |= gtk_event_controller_handle_event (GTK_EVENT_CONTROLLER (priv->drag_gesture), - (const GdkEvent*) event); + retval |= controller_handle_wm_event (priv->drag_gesture, + (const GdkEvent*) event); if (priv->multipress_gesture) - retval |= gtk_event_controller_handle_event (GTK_EVENT_CONTROLLER (priv->multipress_gesture), - (const GdkEvent*) event); + retval |= controller_handle_wm_event (priv->multipress_gesture, + (const GdkEvent*) event); } return retval;