From e54e48f6d16f2053ab22895ed44fab84c6a0a64d Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 16 Feb 2020 02:20:34 -0500 Subject: [PATCH] Explicitly pass the target to handle_event Pass the event propagation target explicitly down to the event controllers. This is a step towards getting rid of gdk_event_set_target. --- gtk/gtkeventcontroller.c | 131 +++++++++++++++++--------------- gtk/gtkeventcontroller.h | 1 + gtk/gtkeventcontrollerkey.c | 6 +- gtk/gtkeventcontrollerprivate.h | 3 - gtk/gtkmain.c | 10 ++- gtk/gtkwidget.c | 25 +++--- gtk/gtkwidget.h | 3 +- gtk/gtkwidgetprivate.h | 4 +- gtk/gtkwindow.c | 6 +- 9 files changed, 102 insertions(+), 87 deletions(-) diff --git a/gtk/gtkeventcontroller.c b/gtk/gtkeventcontroller.c index 8d1fa5d709..34594efa46 100644 --- a/gtk/gtkeventcontroller.c +++ b/gtk/gtkeventcontroller.c @@ -79,60 +79,10 @@ gtk_event_controller_unset_widget (GtkEventController *self) priv->widget = NULL; } -static gboolean -same_native (GtkWidget *widget, - GtkWidget *target) -{ - GtkWidget *native; - GtkWidget *native2; - - if (!widget || !target) - return TRUE; - - native = GTK_WIDGET (gtk_widget_get_native (widget)); - native2 = GTK_WIDGET (gtk_widget_get_native (widget)); - - return native == native2; -} - static gboolean gtk_event_controller_filter_event_default (GtkEventController *self, const GdkEvent *event) { - GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self); - - if (priv->widget && !gtk_widget_is_sensitive (priv->widget)) - return TRUE; - - if (priv->limit == GTK_LIMIT_SAME_NATIVE) - { - if (same_native (priv->widget, GTK_WIDGET (gdk_event_get_target (event)))) - return FALSE; - - return TRUE; - } - - return FALSE; -} - -static gboolean -gtk_event_controller_filter_crossing_default (GtkEventController *self, - const GtkCrossingData *crossing) -{ - GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self); - - if (priv->widget && !gtk_widget_is_sensitive (priv->widget)) - return TRUE; - - if (priv->limit == GTK_LIMIT_SAME_NATIVE) - { - if (same_native (priv->widget, crossing->old_target) && - same_native (priv->widget, crossing->new_target)) - return FALSE; - - return TRUE; - } - return FALSE; } @@ -229,7 +179,6 @@ gtk_event_controller_class_init (GtkEventControllerClass *klass) klass->set_widget = gtk_event_controller_set_widget; klass->unset_widget = gtk_event_controller_unset_widget; klass->filter_event = gtk_event_controller_filter_event_default; - klass->filter_crossing = gtk_event_controller_filter_crossing_default; klass->handle_event = gtk_event_controller_handle_event_default; klass->handle_crossing = gtk_event_controller_handle_crossing_default; @@ -295,10 +244,68 @@ gtk_event_controller_init (GtkEventController *controller) priv->limit = GTK_LIMIT_SAME_NATIVE; } +static gboolean +same_native (GtkWidget *widget, + GtkWidget *target) +{ + GtkWidget *native; + GtkWidget *native2; + + if (!widget || !target) + return TRUE; + + native = GTK_WIDGET (gtk_widget_get_native (widget)); + native2 = GTK_WIDGET (gtk_widget_get_native (widget)); + + return native == native2; +} + +static gboolean +gtk_event_controller_filter_event (GtkEventController *controller, + const GdkEvent *event, + GtkWidget *target) +{ + GtkEventControllerPrivate *priv; + GtkEventControllerClass *controller_class; + + priv = gtk_event_controller_get_instance_private (controller); + + if (priv->widget && !gtk_widget_is_sensitive (priv->widget)) + return TRUE; + + if (priv->limit == GTK_LIMIT_SAME_NATIVE && + !same_native (priv->widget, target)) + return TRUE; + + controller_class = GTK_EVENT_CONTROLLER_GET_CLASS (controller); + + return controller_class->filter_event (controller, event); +} + +static gboolean +gtk_event_controller_filter_crossing (GtkEventController *controller, + const GtkCrossingData *data) +{ + GtkEventControllerPrivate *priv; + + priv = gtk_event_controller_get_instance_private (controller); + + if (priv->widget && !gtk_widget_is_sensitive (priv->widget)) + return TRUE; + + if (priv->limit == GTK_LIMIT_SAME_NATIVE && + (!same_native (priv->widget, data->old_target) || + !same_native (priv->widget, data->new_target))) + return TRUE; + + return FALSE; +} + /** * gtk_event_controller_handle_event: * @controller: a #GtkEventController * @event: a #GdkEvent + * @target: the target widget * @x: event position in widget coordinates, or 0 if not a pointer event * @y: event position in widget coordinates, or 0 if not a pointer event * @@ -311,6 +318,7 @@ gtk_event_controller_init (GtkEventController *controller) gboolean gtk_event_controller_handle_event (GtkEventController *controller, const GdkEvent *event, + GtkWidget *target, double x, double y) { @@ -320,17 +328,14 @@ gtk_event_controller_handle_event (GtkEventController *controller, g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER (controller), FALSE); g_return_val_if_fail (event != NULL, FALSE); - controller_class = GTK_EVENT_CONTROLLER_GET_CLASS (controller); - - if (controller_class->filter_event (controller, event)) + if (gtk_event_controller_filter_event (controller, event, target)) return retval; - if (controller_class->handle_event) - { - g_object_ref (controller); - retval = controller_class->handle_event (controller, event, x, y); - g_object_unref (controller); - } + controller_class = GTK_EVENT_CONTROLLER_GET_CLASS (controller); + + g_object_ref (controller); + retval = controller_class->handle_event (controller, event, x, y); + g_object_unref (controller); return retval; } @@ -356,11 +361,11 @@ gtk_event_controller_handle_crossing (GtkEventController *controller, g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller)); g_return_if_fail (crossing != NULL); - controller_class = GTK_EVENT_CONTROLLER_GET_CLASS (controller); - - if (controller_class->filter_crossing (controller, crossing)) + if (gtk_event_controller_filter_crossing (controller, crossing)) return; + controller_class = GTK_EVENT_CONTROLLER_GET_CLASS (controller); + g_object_ref (controller); controller_class->handle_crossing (controller, crossing, x, y); g_object_unref (controller); diff --git a/gtk/gtkeventcontroller.h b/gtk/gtkeventcontroller.h index 1c60d96e77..2ca16342a7 100644 --- a/gtk/gtkeventcontroller.h +++ b/gtk/gtkeventcontroller.h @@ -77,6 +77,7 @@ GtkWidget * gtk_event_controller_get_widget (GtkEventController *controller GDK_AVAILABLE_IN_ALL gboolean gtk_event_controller_handle_event (GtkEventController *controller, const GdkEvent *event, + GtkWidget *target, double x, double y); GDK_AVAILABLE_IN_ALL diff --git a/gtk/gtkeventcontrollerkey.c b/gtk/gtkeventcontrollerkey.c index 5e8b5924ee..51d1185cc1 100644 --- a/gtk/gtkeventcontrollerkey.c +++ b/gtk/gtkeventcontrollerkey.c @@ -474,13 +474,13 @@ gtk_event_controller_key_forward (GtkEventControllerKey *controller, if (!gtk_widget_get_realized (widget)) gtk_widget_realize (widget); - if (gtk_widget_run_controllers (widget, controller->current_event, 0, 0, + if (gtk_widget_run_controllers (widget, controller->current_event, widget, 0, 0, GTK_PHASE_CAPTURE)) return TRUE; - if (gtk_widget_run_controllers (widget, controller->current_event, 0, 0, + if (gtk_widget_run_controllers (widget, controller->current_event, widget, 0, 0, GTK_PHASE_TARGET)) return TRUE; - if (gtk_widget_run_controllers (widget, controller->current_event, 0, 0, + if (gtk_widget_run_controllers (widget, controller->current_event, widget, 0, 0, GTK_PHASE_BUBBLE)) return TRUE; diff --git a/gtk/gtkeventcontrollerprivate.h b/gtk/gtkeventcontrollerprivate.h index 461b25dd75..79a61d0314 100644 --- a/gtk/gtkeventcontrollerprivate.h +++ b/gtk/gtkeventcontrollerprivate.h @@ -53,9 +53,6 @@ struct _GtkEventControllerClass gboolean (* filter_event) (GtkEventController *controller, const GdkEvent *event); - gboolean (* filter_crossing) (GtkEventController *controller, - const GtkCrossingData *crossing); - gpointer padding[10]; }; diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index 7870375eb8..5f756d5fa4 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -1716,8 +1716,8 @@ gtk_main_do_event (GdkEvent *event) case GDK_FOCUS_CHANGE: case GDK_GRAB_BROKEN: - if (!_gtk_widget_captured_event (target_widget, event)) - gtk_widget_event (target_widget, event); + if (!_gtk_widget_captured_event (target_widget, event, target_widget)) + gtk_widget_event (target_widget, event, target_widget); break; case GDK_KEY_PRESS: @@ -2222,6 +2222,7 @@ propagate_event_up (GtkWidget *widget, GtkWidget *topmost) { gboolean handled_event = FALSE; + GtkWidget *target = widget; /* Propagate event up the widget tree so that * parents can see the button and motion @@ -2241,7 +2242,7 @@ propagate_event_up (GtkWidget *widget, if (!gtk_widget_is_sensitive (widget)) handled_event = event->any.type != GDK_SCROLL; else if (gtk_widget_get_realized (widget)) - handled_event = gtk_widget_event (widget, event); + handled_event = gtk_widget_event (widget, event, target); handled_event |= !gtk_widget_get_realized (widget); @@ -2268,6 +2269,7 @@ propagate_event_down (GtkWidget *widget, gint handled_event = FALSE; GList *widgets = NULL; GList *l; + GtkWidget *target = widget; widgets = g_list_prepend (widgets, g_object_ref (widget)); while (widget && widget != topmost) @@ -2297,7 +2299,7 @@ propagate_event_down (GtkWidget *widget, handled_event = TRUE; } else if (gtk_widget_get_realized (widget)) - handled_event = _gtk_widget_captured_event (widget, event); + handled_event = _gtk_widget_captured_event (widget, event, target); handled_event |= !gtk_widget_get_realized (widget); } diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 705c811926..d915402a4f 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -635,7 +635,8 @@ static void gtk_widget_propagate_state (GtkWidget static void gtk_widget_update_alpha (GtkWidget *widget); static gboolean gtk_widget_event_internal (GtkWidget *widget, - GdkEvent *event); + GdkEvent *event, + GtkWidget *target); static gboolean gtk_widget_real_mnemonic_activate (GtkWidget *widget, gboolean group_cycling); static void gtk_widget_real_measure (GtkWidget *widget, @@ -4783,17 +4784,19 @@ gtk_widget_real_mnemonic_activate (GtkWidget *widget, **/ gboolean gtk_widget_event (GtkWidget *widget, - GdkEvent *event) + GdkEvent *event, + GtkWidget *target) { g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE); g_return_val_if_fail (WIDGET_REALIZED_FOR_EVENT (widget, event), TRUE); - return gtk_widget_event_internal (widget, event); + return gtk_widget_event_internal (widget, event, target); } gboolean gtk_widget_run_controllers (GtkWidget *widget, const GdkEvent *event, + GtkWidget *target, double x, double y, GtkPropagationPhase phase) @@ -4831,7 +4834,7 @@ gtk_widget_run_controllers (GtkWidget *widget, gboolean is_gesture; is_gesture = GTK_IS_GESTURE (controller); - this_handled = gtk_event_controller_handle_event (controller, event, x, y); + this_handled = gtk_event_controller_handle_event (controller, event, target, x, y); handled |= this_handled; @@ -4881,7 +4884,8 @@ translate_event_coordinates (GdkEvent *event, gboolean _gtk_widget_captured_event (GtkWidget *widget, - GdkEvent *event) + GdkEvent *event, + GtkWidget *target) { gboolean return_val = FALSE; double x, y; @@ -4894,7 +4898,7 @@ _gtk_widget_captured_event (GtkWidget *widget, translate_event_coordinates (event, &x, &y, widget); - return_val = gtk_widget_run_controllers (widget, event, x, y, GTK_PHASE_CAPTURE); + return_val = gtk_widget_run_controllers (widget, event, target, x, y, GTK_PHASE_CAPTURE); return_val |= !WIDGET_REALIZED_FOR_EVENT (widget, event); return return_val; @@ -4968,7 +4972,8 @@ translate_event_coordinates (GdkEvent *event, static gboolean gtk_widget_event_internal (GtkWidget *widget, - GdkEvent *event) + GdkEvent *event, + GtkWidget *target) { gboolean return_val = FALSE; double x, y; @@ -4986,11 +4991,11 @@ gtk_widget_event_internal (GtkWidget *widget, translate_event_coordinates (event, &x, &y, widget); - if (widget == GTK_WIDGET (gdk_event_get_target (event))) - return_val |= gtk_widget_run_controllers (widget, event, x, y, GTK_PHASE_TARGET); + if (widget == target) + return_val |= gtk_widget_run_controllers (widget, event, target, x, y, GTK_PHASE_TARGET); if (return_val == FALSE) - return_val |= gtk_widget_run_controllers (widget, event, x, y, GTK_PHASE_BUBBLE); + return_val |= gtk_widget_run_controllers (widget, event, target, x, y, GTK_PHASE_BUBBLE); if (return_val == FALSE && (event->any.type == GDK_KEY_PRESS || diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h index 6c3f758409..4e43fff36a 100644 --- a/gtk/gtkwidget.h +++ b/gtk/gtkwidget.h @@ -399,7 +399,8 @@ gboolean gtk_widget_mnemonic_activate (GtkWidget *widget, gboolean group_cycling); GDK_AVAILABLE_IN_ALL gboolean gtk_widget_event (GtkWidget *widget, - GdkEvent *event); + GdkEvent *event, + GtkWidget *target); GDK_AVAILABLE_IN_ALL gboolean gtk_widget_activate (GtkWidget *widget); diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h index ea9653e557..c035204154 100644 --- a/gtk/gtkwidgetprivate.h +++ b/gtk/gtkwidgetprivate.h @@ -276,7 +276,8 @@ void _gtk_widget_buildable_finish_accelerator (GtkWidget *widget, GtkStyleContext * _gtk_widget_peek_style_context (GtkWidget *widget); gboolean _gtk_widget_captured_event (GtkWidget *widget, - GdkEvent *event); + GdkEvent *event, + GtkWidget *target); void gtk_widget_css_changed (GtkWidget *widget, GtkCssStyleChange *change); @@ -344,6 +345,7 @@ void gtk_widget_cancel_event_sequence (GtkWidget gboolean gtk_widget_run_controllers (GtkWidget *widget, const GdkEvent *event, + GtkWidget *target, double x, double y, GtkPropagationPhase phase); diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index bd1afe5b4d..97a51e720b 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -6012,7 +6012,7 @@ gtk_window_propagate_key_event (GtkWindow *window, { GtkWindowPrivate *priv = gtk_window_get_instance_private (window); gboolean handled = FALSE; - GtkWidget *widget, *focus; + GtkWidget *widget, *focus, *target; g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE); @@ -6022,6 +6022,8 @@ gtk_window_propagate_key_event (GtkWindow *window, if (focus) g_object_ref (focus); + target = focus; + while (!handled && focus && focus != widget && gtk_widget_get_root (focus) == GTK_ROOT (widget)) @@ -6030,7 +6032,7 @@ gtk_window_propagate_key_event (GtkWindow *window, if (gtk_widget_is_sensitive (focus)) { - handled = gtk_widget_event (focus, (GdkEvent *)event); + handled = gtk_widget_event (focus, (GdkEvent *)event, target); if (handled) break; }