[gtk/controllers-list: 3/3] Go back to keeping a list of event controllers




commit 17208ca7fa793ce0281a223ef9ad4fbf08f5e305
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Aug 2 12:00:46 2020 -0400

    Go back to keeping a list of event controllers
    
    This reverts 4b9e5304cc1f675d2. It caused a number of regressions,
    such as event controller ordering changes.

 gtk/gtkwidget.c        | 241 ++++++++++++++++++-------------------------------
 gtk/gtkwidgetprivate.h |   2 +-
 2 files changed, 91 insertions(+), 152 deletions(-)
---
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 8afac750a7..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;
-
-  if (!priv->controllers)
-    goto out;
+  GList *l;
 
-  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,13 +10729,10 @@ 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);
+  priv->event_controllers = g_list_prepend (priv->event_controllers, controller);
 
   if (priv->controller_observer)
-    gtk_list_list_model_item_added_at (priv->controller_observer, priv->controllers->len - 1);
+    gtk_list_list_model_item_added_at (priv->controller_observer, 0);
 }
 
 /**
@@ -10784,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);
 
-  if (priv->controller_observer)
-    {
-      /* Here we care about the index */
-      guint index;
-
-      g_ptr_array_find (priv->controllers, controller, &index);
+  GTK_EVENT_CONTROLLER_GET_CLASS (controller)->unset_widget (controller);
 
-      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);
-    }
+  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);
 
-  gtk_widget_unset_controller (widget, controller);
+  if (priv->controller_observer)
+    gtk_list_list_model_item_removed (priv->controller_observer, before);
 }
 
 gboolean
@@ -10817,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))
@@ -10837,7 +10794,6 @@ gtk_widget_consumes_motion (GtkWidget        *widget,
             return TRUE;
         }
 
-next:
       widget = priv->parent;
       priv = gtk_widget_get_instance_private (widget);
     }
@@ -10849,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;
@@ -10873,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);
@@ -11099,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;
-
-  g_ptr_array_find (priv->controllers, item, &index);
-
-  if (index >= 0)
-    return g_ptr_array_index (priv->controllers, index - 1);
+  return g_list_previous (item);
+}
 
-  return NULL;
+static gpointer
+gtk_widget_controller_list_get_item (gpointer item,
+                                      gpointer widget)
+{
+  return g_object_ref (((GList *) item)->data);
 }
 
 /**
@@ -11167,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 3e48575f91..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;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]