diff --git a/gtk/gtkentrycompletion.c b/gtk/gtkentrycompletion.c index d048112b93..05b965f2aa 100644 --- a/gtk/gtkentrycompletion.c +++ b/gtk/gtkentrycompletion.c @@ -2046,7 +2046,7 @@ connect_completion_signals (GtkEntryCompletion *completion) gtk_event_controller_set_name (controller, "gtk-entry-completion"); g_signal_connect (controller, "key-pressed", G_CALLBACK (gtk_entry_completion_key_pressed), completion); - gtk_widget_prepend_controller (GTK_WIDGET (text), controller); + gtk_widget_add_controller (GTK_WIDGET (text), controller); controller = completion->entry_focus_controller = gtk_event_controller_focus_new (); gtk_event_controller_set_name (controller, "gtk-entry-completion"); g_signal_connect_swapped (controller, "leave", G_CALLBACK (text_focus_out), completion); diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index c7b0117538..890e0440b5 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -798,16 +798,14 @@ _gtk_widget_grab_notify (GtkWidget *widget, gboolean was_grabbed) { GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); - int i; + GList *l; - if (!priv->controllers) - return; if (was_grabbed) return; - for (i = (int)priv->controllers->len - 1; i >= 0; i--) + for (l = g_list_last (priv->event_controllers); l; l = l->prev) { - GtkEventController *controller = g_ptr_array_index (priv->controllers, i); + GtkEventController *controller = l->data; gtk_event_controller_reset (controller); } @@ -817,19 +815,14 @@ static void gtk_widget_real_root (GtkWidget *widget) { GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); - guint i; + GList *l; gtk_widget_forall (widget, (GtkCallback) gtk_widget_root, NULL); - if (!priv->controllers) - return; - - for (i = 0; i < priv->controllers->len; i++) + for (l = priv->event_controllers; l; l = l->next) { - GtkEventController *controller = g_ptr_array_index (priv->controllers, i); - - if (GTK_IS_SHORTCUT_CONTROLLER (controller)) - gtk_shortcut_controller_root (GTK_SHORTCUT_CONTROLLER (controller)); + if (GTK_IS_SHORTCUT_CONTROLLER (l->data)) + gtk_shortcut_controller_root (GTK_SHORTCUT_CONTROLLER (l->data)); } } @@ -837,17 +830,12 @@ static void gtk_widget_real_unroot (GtkWidget *widget) { GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); - guint i; + GList *l; - if (priv->controllers) + for (l = priv->event_controllers; l; l = l->next) { - for (i = 0; i < priv->controllers->len; i++) - { - GtkEventController *controller = g_ptr_array_index (priv->controllers, i); - - if (GTK_IS_SHORTCUT_CONTROLLER (controller)) - gtk_shortcut_controller_unroot (GTK_SHORTCUT_CONTROLLER (controller)); - } + if (GTK_IS_SHORTCUT_CONTROLLER (l->data)) + gtk_shortcut_controller_unroot (GTK_SHORTCUT_CONTROLLER (l->data)); } gtk_widget_forall (widget, (GtkCallback) gtk_widget_unroot, NULL); @@ -1988,15 +1976,13 @@ _gtk_widget_get_last_event (GtkWidget *widget, GtkWidget **target) { GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); + GtkEventController *controller; GdkEvent *event; - guint i; + GList *l; - if (!priv->controllers) - goto out; - - for (i = 0; i < priv->controllers->len; i++) + for (l = priv->event_controllers; l; l = l->next) { - GtkEventController *controller = g_ptr_array_index (priv->controllers, i); + controller = l->data; if (!GTK_IS_GESTURE (controller)) continue; @@ -2009,7 +1995,6 @@ _gtk_widget_get_last_event (GtkWidget *widget, } } -out: *target = NULL; return NULL; } @@ -2037,13 +2022,14 @@ _gtk_widget_get_emulating_sequence (GtkWidget *widget, gdk_touch_event_get_emulating_pointer (last_event)) return TRUE; } - else if (priv->controllers) + else { - guint i; + GList *l; + /* For a NULL(pointer) sequence, find the pointer emulating one */ - for (i = 0; i < priv->controllers->len; i++) + for (l = priv->event_controllers; l; l = l->next) { - GtkEventController *controller = g_ptr_array_index (priv->controllers, i); + GtkEventController *controller = l->data; if (!GTK_IS_GESTURE (controller)) continue; @@ -2063,17 +2049,14 @@ gtk_widget_needs_press_emulation (GtkWidget *widget, { GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); gboolean sequence_press_handled = FALSE; - guint i; - - if (!priv->controllers) - return FALSE; + GList *l; /* Check whether there is any remaining gesture in * the capture phase that handled the press event */ - for (i = 0; i < priv->controllers->len; i++) + for (l = priv->event_controllers; l; l = l->next) { - GtkEventController *controller = g_ptr_array_index (priv->controllers, i); + GtkEventController *controller = l->data; GtkPropagationPhase phase; GtkGesture *gesture; @@ -2103,13 +2086,11 @@ _gtk_widget_set_sequence_state_internal (GtkWidget *widget, gboolean emulates_pointer, sequence_handled = FALSE; GdkEvent *mimic_event; GtkWidget *target; - GList *group = NULL; + GList *group = NULL, *l; GdkEventSequence *seq; int n_handled = 0; - guint i; - if (state != GTK_EVENT_SEQUENCE_CLAIMED && - (!priv->controllers || priv->controllers->len == 0)) + if (!priv->event_controllers && state != GTK_EVENT_SEQUENCE_CLAIMED) return TRUE; if (emitter) @@ -2118,14 +2099,15 @@ _gtk_widget_set_sequence_state_internal (GtkWidget *widget, emulates_pointer = _gtk_widget_get_emulating_sequence (widget, sequence, &seq); mimic_event = _gtk_widget_get_last_event (widget, seq, &target); - for (i = 0; i < priv->controllers->len; i++) + for (l = priv->event_controllers; l; l = l->next) { - GtkEventController *controller = g_ptr_array_index (priv->controllers, i); + GtkEventController *controller; GtkEventSequenceState gesture_state; GtkGesture *gesture; gboolean retval; seq = sequence; + controller = l->data; gesture_state = state; if (!GTK_IS_GESTURE (controller)) @@ -2192,19 +2174,17 @@ _gtk_widget_cancel_sequence (GtkWidget *widget, gboolean emulates_pointer; gboolean handled = FALSE; GdkEventSequence *seq; - guint i; - - if (!priv->controllers) - return FALSE; + GList *l; emulates_pointer = _gtk_widget_get_emulating_sequence (widget, sequence, &seq); - for (i = 0; i < priv->controllers->len; i++) + for (l = priv->event_controllers; l; l = l->next) { - GtkEventController *controller = g_ptr_array_index (priv->controllers, i); + GtkEventController *controller; GtkGesture *gesture; seq = sequence; + controller = l->data; if (!GTK_IS_GESTURE (controller)) continue; @@ -4313,28 +4293,28 @@ gtk_widget_run_controllers (GtkWidget *widget, GtkWidget *target, double x, double y, - GtkPropagationPhase phase) + GtkPropagationPhase phase) { GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); + GtkEventController *controller; gboolean handled = FALSE; - guint i; - - if (!priv->controllers) - return FALSE; + GList *l; g_object_ref (widget); - for (i = 0; i < priv->controllers->len; i++) + l = priv->event_controllers; + while (l != NULL) { - GtkEventController *controller = g_ptr_array_index (priv->controllers, i); + GList *next = l->next; if (!WIDGET_REALIZED_FOR_EVENT (widget, event)) break; + controller = l->data; + if (controller == NULL) { - g_ptr_array_remove_index (priv->controllers, i); - i--; /* Need to check this index again */ + priv->event_controllers = g_list_delete_link (priv->event_controllers, l); } else { @@ -4376,6 +4356,8 @@ gtk_widget_run_controllers (GtkWidget *widget, break; } } + + l = next; } g_object_unref (widget); @@ -4390,16 +4372,13 @@ gtk_widget_handle_crossing (GtkWidget *widget, double y) { GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); - guint i; - - if (!priv->controllers) - return; + GList *l; g_object_ref (widget); - for (i = 0; i < priv->controllers->len; i++) + for (l = priv->event_controllers; l; l = l->next) { - GtkEventController *controller = g_ptr_array_index (priv->controllers, i); + GtkEventController *controller = l->data; gtk_event_controller_handle_crossing (controller, crossing, x, y); } @@ -5554,10 +5533,10 @@ gtk_widget_get_mapped (GtkWidget *widget) **/ void gtk_widget_set_sensitive (GtkWidget *widget, - gboolean sensitive) + gboolean sensitive) { GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); - guint i; + GList *l; g_return_if_fail (GTK_IS_WIDGET (widget)); @@ -5568,14 +5547,11 @@ gtk_widget_set_sensitive (GtkWidget *widget, priv->sensitive = sensitive; - if (priv->controllers) + for (l = priv->event_controllers; l; l = l->next) { - for (i = 0; i < priv->controllers->len; i++) - { - GtkEventController *controller = g_ptr_array_index (priv->controllers, i); + GtkEventController *controller = l->data; - gtk_event_controller_reset (controller); - } + gtk_event_controller_reset (controller); } gtk_accessible_update_state (GTK_ACCESSIBLE (widget), @@ -7208,19 +7184,12 @@ gtk_widget_real_destroy (GtkWidget *object) destroy_surface_transform_data (widget); } -static void -gtk_widget_unset_controller (GtkWidget *widget, - GtkEventController *controller) -{ - GTK_EVENT_CONTROLLER_GET_CLASS (controller)->unset_widget (controller); - g_object_unref (controller); -} - static void gtk_widget_finalize (GObject *object) { GtkWidget *widget = GTK_WIDGET (object); GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); + GList *l; gtk_grab_remove (widget); @@ -7238,17 +7207,18 @@ gtk_widget_finalize (GObject *object) _gtk_size_request_cache_free (&priv->requests); - if (priv->controllers) + l = priv->event_controllers; + while (l) { - guint i; - for (i = 0; i < priv->controllers->len; i++) - { - GtkEventController *controller = g_ptr_array_index (priv->controllers, i); + GList *next = l->next; + GtkEventController *controller = l->data; - gtk_widget_unset_controller (widget, controller); - } - g_ptr_array_free (priv->controllers, TRUE); + if (controller) + gtk_widget_remove_controller (widget, controller); + + l = next; } + g_assert (priv->event_controllers == NULL); if (_gtk_widget_get_first_child (widget) != NULL) { @@ -10759,27 +10729,7 @@ gtk_widget_add_controller (GtkWidget *widget, GTK_EVENT_CONTROLLER_GET_CLASS (controller)->set_widget (controller, widget); - if (G_UNLIKELY (!priv->controllers)) - priv->controllers = g_ptr_array_new (); - - g_ptr_array_add (priv->controllers, controller); - - if (priv->controller_observer) - gtk_list_list_model_item_added_at (priv->controller_observer, priv->controllers->len - 1); -} - -void -gtk_widget_prepend_controller (GtkWidget *widget, - GtkEventController *controller) -{ - GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); - - GTK_EVENT_CONTROLLER_GET_CLASS (controller)->set_widget (controller, widget); - - if (G_UNLIKELY (!priv->controllers)) - priv->controllers = g_ptr_array_new (); - - g_ptr_array_insert (priv->controllers, 0, controller); + priv->event_controllers = g_list_prepend (priv->event_controllers, controller); if (priv->controller_observer) gtk_list_list_model_item_added_at (priv->controller_observer, 0); @@ -10801,28 +10751,21 @@ gtk_widget_remove_controller (GtkWidget *widget, GtkEventController *controller) { GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); + GList *before, *list; g_return_if_fail (GTK_IS_WIDGET (widget)); g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller)); g_return_if_fail (gtk_event_controller_get_widget (controller) == widget); + GTK_EVENT_CONTROLLER_GET_CLASS (controller)->unset_widget (controller); + + list = g_list_find (priv->event_controllers, controller); + before = list->prev; + priv->event_controllers = g_list_delete_link (priv->event_controllers, list); + g_object_unref (controller); + if (priv->controller_observer) - { - /* Here we care about the index */ - guint index; - - g_ptr_array_find (priv->controllers, controller, &index); - - gtk_list_list_model_item_removed_at (priv->controller_observer, index); - g_ptr_array_remove_index_fast (priv->controllers, index); - } - else - { - /* XXX _fast really possible? */ - g_ptr_array_remove_fast (priv->controllers, controller); - } - - gtk_widget_unset_controller (widget, controller); + gtk_list_list_model_item_removed (priv->controller_observer, before); } gboolean @@ -10834,14 +10777,11 @@ gtk_widget_consumes_motion (GtkWidget *widget, while (widget != NULL && widget != parent) { - guint i; + GList *l; - if (!priv->controllers) - goto next; - - for (i = 0; i < priv->controllers->len; i++) + for (l = priv->event_controllers; l; l = l->next) { - GtkEventController *controller = g_ptr_array_index (priv->controllers, i); + GtkEventController *controller = l->data; if (controller == NULL || !GTK_IS_GESTURE (controller)) @@ -10854,7 +10794,6 @@ gtk_widget_consumes_motion (GtkWidget *widget, return TRUE; } -next: widget = priv->parent; priv = gtk_widget_get_instance_private (widget); } @@ -10866,15 +10805,12 @@ void gtk_widget_reset_controllers (GtkWidget *widget) { GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); - guint i; - - if (!priv->controllers) - return; + GList *l; /* Reset all controllers */ - for (i = 0; i < priv->controllers->len; i++) + for (l = priv->event_controllers; l; l = l->next) { - GtkEventController *controller = g_ptr_array_index (priv->controllers, i); + GtkEventController *controller = l->data; if (controller == NULL) continue; @@ -10890,13 +10826,13 @@ gtk_widget_list_controllers (GtkWidget *widget, { GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); GPtrArray *controllers = g_ptr_array_new (); - guint i; + GList *l; g_assert (out_n_controllers); - for (i = 0; i < priv->controllers->len; i++) + for (l = priv->event_controllers; l; l = l->next) { - GtkEventController *controller = g_ptr_array_index (priv->controllers, i); + GtkEventController *controller = l->data; if (gtk_event_controller_get_propagation_phase (controller) == phase) g_ptr_array_add (controllers, controller); @@ -11116,42 +11052,28 @@ gtk_widget_controller_observer_destroyed (gpointer widget) static gpointer gtk_widget_controller_list_get_first (gpointer widget) { - GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); - - if (priv->controllers) - return g_ptr_array_index (priv->controllers, 0); - - return NULL; + return GTK_WIDGET (widget)->priv->event_controllers; } static gpointer gtk_widget_controller_list_get_next (gpointer item, gpointer widget) { - GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); - guint index; - - g_ptr_array_find (priv->controllers, item, &index); - - if (index + 1 <= priv->controllers->len - 1) - return g_ptr_array_index (priv->controllers, index + 1); - - return NULL; + return g_list_next (item); } static gpointer gtk_widget_controller_list_get_prev (gpointer item, gpointer widget) { - GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); - guint index; + return g_list_previous (item); +} - g_ptr_array_find (priv->controllers, item, &index); - - if (index >= 0) - return g_ptr_array_index (priv->controllers, index - 1); - - return NULL; +static gpointer +gtk_widget_controller_list_get_item (gpointer item, + gpointer widget) +{ + return g_object_ref (((GList *) item)->data); } /** @@ -11184,7 +11106,7 @@ gtk_widget_observe_controllers (GtkWidget *widget) gtk_widget_controller_list_get_next, gtk_widget_controller_list_get_prev, NULL, - (gpointer) g_object_ref, + gtk_widget_controller_list_get_item, widget, gtk_widget_controller_observer_destroyed); diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h index b5af950cf4..136533622a 100644 --- a/gtk/gtkwidgetprivate.h +++ b/gtk/gtkwidgetprivate.h @@ -171,7 +171,7 @@ struct _GtkWidgetPrivate GSList *paintables; - GPtrArray *controllers; + GList *event_controllers; /* Widget tree */ GtkWidget *parent; @@ -337,9 +337,6 @@ gboolean gtk_widget_run_controllers (GtkWidget double x, double y, GtkPropagationPhase phase); - -void gtk_widget_prepend_controller (GtkWidget *widget, - GtkEventController *controller); void gtk_widget_handle_crossing (GtkWidget *widget, const GtkCrossingData *crossing, double x,