[gtk/wip/baedert/for-master] widget: Return an array from list_devices



commit df12fbe4c32894b3fb500363539371dce5cc8b66
Author: Timm Bäder <mail baedert org>
Date:   Fri Apr 10 09:55:18 2020 +0200

    widget: Return an array from list_devices
    
    To forther reduce the GList usage in the code base.

 gtk/gtkmain.c          | 34 +++++++++++++++++++---------------
 gtk/gtkwidget.c        | 40 +++++++++++++++++++++++++---------------
 gtk/gtkwidgetprivate.h |  3 ++-
 3 files changed, 46 insertions(+), 31 deletions(-)
---
diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c
index b4d3fea234..0c5c0b2f71 100644
--- a/gtk/gtkmain.c
+++ b/gtk/gtkmain.c
@@ -1784,15 +1784,18 @@ typedef struct
 } GrabNotifyInfo;
 
 static void
-synth_crossing_for_grab_notify (GtkWidget       *from,
-                                GtkWidget       *to,
-                                GrabNotifyInfo  *info,
-                                GList           *devices,
-                                GdkCrossingMode  mode)
+synth_crossing_for_grab_notify (GtkWidget        *from,
+                                GtkWidget        *to,
+                                GrabNotifyInfo   *info,
+                                GdkDevice       **devices,
+                                guint             n_devices,
+                                GdkCrossingMode   mode)
 {
-  while (devices)
+  guint i;
+
+  for (i = 0; i < n_devices; i++)
     {
-      GdkDevice *device = devices->data;
+      GdkDevice *device = devices[i];
       GdkSurface *from_surface, *to_surface;
 
       /* Do not propagate events more than once to
@@ -1834,8 +1837,6 @@ synth_crossing_for_grab_notify (GtkWidget       *from,
           if (to_surface)
             info->notified_surfaces = g_list_prepend (info->notified_surfaces, to_surface);
         }
-
-      devices = devices->next;
     }
 }
 
@@ -1845,7 +1846,8 @@ gtk_grab_notify_foreach (GtkWidget *child,
 {
   GrabNotifyInfo *info = data;
   gboolean was_grabbed, is_grabbed, was_shadowed, is_shadowed;
-  GList *devices;
+  GdkDevice **devices;
+  guint n_devices;
 
   was_grabbed = info->was_grabbed;
   is_grabbed = info->is_grabbed;
@@ -1874,10 +1876,12 @@ gtk_grab_notify_foreach (GtkWidget *child,
       _gtk_widget_get_device_surface (child, info->device))
     {
       /* Device specified and is on widget */
-      devices = g_list_prepend (NULL, info->device);
+      devices = g_new (GdkDevice *, 1);
+      devices[0] = info->device;
+      n_devices = 1;
     }
   else
-    devices = _gtk_widget_list_devices (child);
+    devices = _gtk_widget_list_devices (child, &n_devices);
 
   if (is_shadowed)
     {
@@ -1885,7 +1889,7 @@ gtk_grab_notify_foreach (GtkWidget *child,
       if (!was_shadowed && devices &&
           gtk_widget_is_sensitive (child))
         synth_crossing_for_grab_notify (child, info->new_grab_widget,
-                                        info, devices,
+                                        info, devices, n_devices,
                                         GDK_CROSSING_GTK_GRAB);
     }
   else
@@ -1894,7 +1898,7 @@ gtk_grab_notify_foreach (GtkWidget *child,
       if (was_shadowed && devices &&
           gtk_widget_is_sensitive (child))
         synth_crossing_for_grab_notify (info->old_grab_widget, child,
-                                        info, devices,
+                                        info, devices, n_devices,
                                         info->from_grab ? GDK_CROSSING_GTK_GRAB :
                                         GDK_CROSSING_GTK_UNGRAB);
     }
@@ -1903,7 +1907,7 @@ gtk_grab_notify_foreach (GtkWidget *child,
     _gtk_widget_grab_notify (child, was_shadowed);
 
   g_object_unref (child);
-  g_list_free (devices);
+  g_free (devices);
 
   info->was_grabbed = was_grabbed;
   info->is_grabbed = is_grabbed;
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 50cdc28caf..826e4ebff2 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -7619,38 +7619,47 @@ _gtk_widget_get_device_surface (GtkWidget *widget,
  *
  * Returns the list of pointer #GdkDevices that are currently
  * on top of any surface belonging to @widget. Free the list
- * with g_list_free(), the elements are owned by GTK+ and must
+ * with g_free(), the elements are owned by GTK+ and must
  * not be freed.
  */
-GList *
-_gtk_widget_list_devices (GtkWidget *widget)
+GdkDevice **
+_gtk_widget_list_devices (GtkWidget *widget,
+                          guint     *out_n_devices)
 {
+  GPtrArray *result;
   GdkSeat *seat;
-  GList *result = NULL;
   GList *devices;
   GList *l;
   GdkDevice *device;
 
   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+  g_assert (out_n_devices);
 
   if (!_gtk_widget_get_mapped (widget))
-    return NULL;
+    {
+      *out_n_devices = 0;
+      return NULL;
+    }
 
+  result = g_ptr_array_new ();
   seat = gdk_display_get_default_seat (_gtk_widget_get_display (widget));
   device = gdk_seat_get_pointer (seat);
   if (is_my_surface (widget, gdk_device_get_last_event_surface (device)))
-    result = g_list_prepend (result, device);
+    {
+      g_ptr_array_add (result, device);
+    }
 
   devices = gdk_seat_get_slaves (seat, GDK_SEAT_CAPABILITY_ALL_POINTING);
   for (l = devices; l; l = l->next)
     {
       device = l->data;
       if (is_my_surface (widget, gdk_device_get_last_event_surface (device)))
-        result = g_list_prepend (result, device);
+        g_ptr_array_add (result, device);
     }
   g_list_free (devices);
 
-  return result;
+  *out_n_devices = result->len;
+  return (GdkDevice **)g_ptr_array_free (result, FALSE);
 }
 
 /*
@@ -7741,17 +7750,18 @@ gtk_widget_propagate_state (GtkWidget          *widget,
       if (!priv->shadowed &&
           (new_flags & GTK_STATE_FLAG_INSENSITIVE) != (old_flags & GTK_STATE_FLAG_INSENSITIVE))
         {
+          guint i, n_devices;
+          GdkDevice **devices;
           GList *event_surfaces = NULL;
-          GList *devices, *d;
 
-          devices = _gtk_widget_list_devices (widget);
+          devices = _gtk_widget_list_devices (widget, &n_devices);
 
-          for (d = devices; d; d = d->next)
+          for (i = 0; i < n_devices; i++)
             {
               GdkSurface *surface;
               GdkDevice *device;
 
-              device = d->data;
+              device = devices[i];
               surface = _gtk_widget_get_device_surface (widget, device);
 
               /* Do not propagate more than once to the
@@ -7762,17 +7772,17 @@ gtk_widget_propagate_state (GtkWidget          *widget,
                 continue;
 
               if (!gtk_widget_is_sensitive (widget))
-                _gtk_widget_synthesize_crossing (widget, NULL, d->data,
+                _gtk_widget_synthesize_crossing (widget, NULL, device,
                                                  GDK_CROSSING_STATE_CHANGED);
               else
-                _gtk_widget_synthesize_crossing (NULL, widget, d->data,
+                _gtk_widget_synthesize_crossing (NULL, widget, device,
                                                  GDK_CROSSING_STATE_CHANGED);
 
               event_surfaces = g_list_prepend (event_surfaces, surface);
             }
 
           g_list_free (event_surfaces);
-          g_list_free (devices);
+          g_free (devices);
         }
 
       if (!gtk_widget_is_sensitive (widget))
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index b2a4836ca0..91574f8824 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -266,7 +266,8 @@ void              _gtk_widget_set_device_surface           (GtkWidget *widget,
                                                             GdkSurface *pointer_window);
 GdkSurface *       _gtk_widget_get_device_surface          (GtkWidget *widget,
                                                             GdkDevice *device);
-GList *           _gtk_widget_list_devices                 (GtkWidget *widget);
+GdkDevice **       _gtk_widget_list_devices                 (GtkWidget *widget,
+                                                             guint     *out_n_devices);
 
 void              _gtk_widget_synthesize_crossing          (GtkWidget       *from,
                                                             GtkWidget       *to,


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