diff options
author | Alexander Larsson <alexl@redhat.com> | 2013-05-03 10:42:40 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2013-05-03 10:42:40 +0200 |
commit | e8e21e701275a5d311e7eede6afe0d717bc064d1 (patch) | |
tree | c59677144b087b274125e224d1498fb6b383be46 | |
parent | 97ad2d7897f222598c3d36d4cf0e707a320a959d (diff) | |
download | gtk+-e8e21e701275a5d311e7eede6afe0d717bc064d1.tar.gz |
GtkWidget: Use gdk_window_get_children_for_user_data
This makes iterating over the children a lot faster, as we're
not doing lots of intra-library calls and type checks. We're still
in some sence O(n^2) since we iterate over each child window for each
widget, but the profiles look much better.
-rw-r--r-- | gtk/gtkwidget.c | 55 |
1 files changed, 25 insertions, 30 deletions
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 2d43ee906a..76742b5568 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -6391,7 +6391,7 @@ _gtk_widget_draw_windows (GdkWindow *window, cairo_pattern_t *pattern; gboolean do_clip; GtkWidget *widget = NULL; - GList *l; + GList *children, *l; int x, y; if (!gdk_window_is_viewable (window)) @@ -6427,29 +6427,26 @@ _gtk_widget_draw_windows (GdkWindow *window, _gtk_widget_draw_internal (widget, cr, do_clip, window); cairo_restore (cr); - for (l = g_list_last (gdk_window_peek_children (window)); - l != NULL; - l = l->prev) + children = gdk_window_get_children_with_user_data (window, widget); + for (l = children; l != NULL; l = l->next) { GdkWindow *child_window = l->data; - gpointer child_data; GdkWindowType type; int wx, wy; - type = gdk_window_get_window_type (child_window); if (!gdk_window_is_visible (child_window) || - gdk_window_is_input_only (child_window) || - type == GDK_WINDOW_OFFSCREEN || + gdk_window_is_input_only (child_window)) + continue; + + type = gdk_window_get_window_type (child_window); + if (type == GDK_WINDOW_OFFSCREEN || type == GDK_WINDOW_FOREIGN) continue; - gdk_window_get_user_data (child_window, &child_data); - if (child_data == (gpointer)widget) - { - gdk_window_get_position (child_window, &wx, &wy); - _gtk_widget_draw_windows (child_window, cr, wx,wy); - } + gdk_window_get_position (child_window, &wx, &wy); + _gtk_widget_draw_windows (child_window, cr, wx,wy); } + g_list_free (children); } cairo_restore (cr); @@ -6460,8 +6457,7 @@ _gtk_widget_draw (GtkWidget *widget, cairo_t *cr) { GdkWindow *window, *child_window; - gpointer child_data; - GList *l; + GList *children, *l; int wx, wy; gboolean push_group; GdkWindowType type; @@ -6509,27 +6505,26 @@ _gtk_widget_draw (GtkWidget *widget, /* But, it may also have child windows in the parent which we should * draw (after having drawn on the parent) */ - for (l = g_list_last (gdk_window_peek_children (window)); - l != NULL; - l = l->prev) + children = gdk_window_get_children_with_user_data (window, widget); + for (l = children; l != NULL; l = l->next) { child_window = l->data; - type = gdk_window_get_window_type (child_window); + if (!gdk_window_is_visible (child_window) || - gdk_window_is_input_only (child_window) || - type == GDK_WINDOW_OFFSCREEN || + gdk_window_is_input_only (child_window)) + continue; + + type = gdk_window_get_window_type (child_window); + if (type == GDK_WINDOW_OFFSCREEN || type == GDK_WINDOW_FOREIGN) continue; - gdk_window_get_user_data (child_window, &child_data); - if (child_data == (gpointer)widget) - { - gdk_window_get_position (child_window, &wx, &wy); - _gtk_widget_draw_windows (child_window, cr, - wx - widget->priv->allocation.x, - wy - widget->priv->allocation.y); - } + gdk_window_get_position (child_window, &wx, &wy); + _gtk_widget_draw_windows (child_window, cr, + wx - widget->priv->allocation.x, + wy - widget->priv->allocation.y); } + g_list_free (children); } if (push_group) |