[gtk+] Refactor gtk_widget_set_device_enabled_internal



commit 1cac30b6f3e020c4d8fd1843d631ccf0558943cc
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Sep 26 10:12:16 2015 -0400

    Refactor gtk_widget_set_device_enabled_internal
    
    Instead of constructing a single list of all windows associated
    to a widget, just iterate the children lists recursively, avoiding
    allocations.

 gtk/gtkwidget.c |  102 +++++++++++++++++++++++--------------------------------
 1 files changed, 43 insertions(+), 59 deletions(-)
---
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 9ee894d..9d5def5 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -4983,90 +4983,74 @@ _gtk_widget_enable_device_events (GtkWidget *widget)
     }
 }
 
-static GList *
-get_widget_windows (GtkWidget *widget)
-{
-  GList *window_list, *last, *l, *children, *ret;
-
-  if (_gtk_widget_get_has_window (widget))
-    window_list = g_list_prepend (NULL, gtk_widget_get_window (widget));
-  else
-    window_list = gdk_window_get_children (gtk_widget_get_window (widget));
-  last = g_list_last (window_list);
-  ret = NULL;
-
-  for (l = window_list; l; l = l->next)
-    {
-      GtkWidget *window_widget = NULL;
-
-      gdk_window_get_user_data (l->data, (gpointer *) &window_widget);
-
-      if (widget != window_widget)
-        continue;
-
-      ret = g_list_prepend (ret, l->data);
-      children = gdk_window_get_children (GDK_WINDOW (l->data));
-
-      if (children)
-        {
-          last = g_list_concat (last, children);
-          last = g_list_last (last);
-        }
-    }
-
-  g_list_free (window_list);
-
-  return ret;
-}
+typedef struct {
+  GtkWidget *widget;
+  GdkDevice *device;
+  gboolean enabled;
+} DeviceEnableData;
 
 static void
 device_enable_foreach (GtkWidget *widget,
                        gpointer   user_data)
 {
-  GdkDevice *device = user_data;
-  gtk_widget_set_device_enabled_internal (widget, device, TRUE, TRUE);
+  DeviceEnableData *data = user_data;
+  gtk_widget_set_device_enabled_internal (widget, data->device, TRUE, data->enabled);
 }
 
 static void
-device_disable_foreach (GtkWidget *widget,
-                        gpointer   user_data)
+device_enable_foreach_window (gpointer win,
+                              gpointer user_data)
 {
-  GdkDevice *device = user_data;
-  gtk_widget_set_device_enabled_internal (widget, device, TRUE, FALSE);
+  GdkWindow *window = win;
+  DeviceEnableData *data = user_data;
+  GdkEventMask events;
+  GtkWidget *window_widget;
+  GList *window_list;
+
+  gdk_window_get_user_data (window, (gpointer *) &window_widget);
+  if (data->widget != window_widget)
+    return;
+
+  if (data->enabled)
+    events = gdk_window_get_events (window);
+  else
+    events = 0;
+
+  gdk_window_set_device_events (window, data->device, events);
+
+  window_list = gdk_window_peek_children (window);
+  g_list_foreach (window_list, device_enable_foreach_window, data);
 }
 
-static void
+void
 gtk_widget_set_device_enabled_internal (GtkWidget *widget,
                                         GdkDevice *device,
                                         gboolean   recurse,
                                         gboolean   enabled)
 {
-  GList *window_list, *l;
+  DeviceEnableData data;
 
-  window_list = get_widget_windows (widget);
+  data.widget = widget;
+  data.device = device;
+  data.enabled = enabled;
 
-  for (l = window_list; l; l = l->next)
+  if (_gtk_widget_get_has_window (widget))
     {
-      GdkEventMask events = 0;
       GdkWindow *window;
 
-      window = l->data;
-
-      if (enabled)
-        events = gdk_window_get_events (window);
-
-      gdk_window_set_device_events (window, device, events);
+      window = gtk_widget_get_window (widget);
+      device_enable_foreach_window (window, &data);
     }
-
-  if (recurse && GTK_IS_CONTAINER (widget))
+  else
     {
-      if (enabled)
-        gtk_container_forall (GTK_CONTAINER (widget), device_enable_foreach, device);
-      else
-        gtk_container_forall (GTK_CONTAINER (widget), device_disable_foreach, device);
+      GList *window_list;
+
+      window_list = gdk_window_peek_children (gtk_widget_get_window (widget));
+      g_list_foreach (window_list, device_enable_foreach_window, &data);
     }
 
-  g_list_free (window_list);
+  if (recurse && GTK_IS_CONTAINER (widget))
+    gtk_container_forall (GTK_CONTAINER (widget), device_enable_foreach, &data);
 }
 
 static void


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