From ee91fb71ca5073d30bf7d4f651798d802f7bfa7f Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Mon, 9 Feb 2015 22:51:28 +0100 Subject: [PATCH] box: Use CSS nodes instead of widget paths This is a very simple patch that causes a bunch of overhead. But it works. --- gtk/gtkbox.c | 19 ++++++++++++++----- gtk/gtkcssnode.c | 24 ++++++++++++++++++++++++ gtk/gtkcssnodeprivate.h | 4 ++++ gtk/gtkcsswidgetnode.c | 5 ++++- 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/gtk/gtkbox.c b/gtk/gtkbox.c index 818e4d1a97..3a2fb5ac35 100644 --- a/gtk/gtkbox.c +++ b/gtk/gtkbox.c @@ -77,6 +77,7 @@ #include "gtkbox.h" #include "gtkboxprivate.h" +#include "gtkcssnodeprivate.h" #include "gtkintl.h" #include "gtkorientable.h" #include "gtkorientableprivate.h" @@ -1434,17 +1435,25 @@ gtk_box_buildable_init (GtkBuildableIface *iface) } static void -gtk_box_invalidate_order_foreach (GtkWidget *widget) +gtk_box_invalidate_order_foreach (GtkWidget *widget, + gpointer prev) { - _gtk_widget_invalidate_style_context (widget, GTK_CSS_CHANGE_POSITION | GTK_CSS_CHANGE_SIBLING_POSITION); + GtkCssNode **previous = prev; + GtkCssNode *cur = gtk_widget_get_css_node (widget); + + if (*previous) + gtk_css_node_set_after (cur, *previous); + + *previous = cur; } static void gtk_box_invalidate_order (GtkBox *box) { + GtkCssNode *previous = NULL; gtk_container_foreach (GTK_CONTAINER (box), - (GtkCallback) gtk_box_invalidate_order_foreach, - NULL); + gtk_box_invalidate_order_foreach, + &previous); } static void @@ -1490,8 +1499,8 @@ gtk_box_pack (GtkBox *box, gtk_widget_freeze_child_notify (child); - gtk_box_invalidate_order (box); gtk_widget_set_parent (child, GTK_WIDGET (box)); + gtk_box_invalidate_order (box); g_signal_connect (child, "notify::visible", G_CALLBACK (box_child_visibility_notify_cb), box); diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c index 92b165dfa3..402aa3366d 100644 --- a/gtk/gtkcssnode.c +++ b/gtk/gtkcssnode.c @@ -473,6 +473,30 @@ gtk_css_node_set_parent (GtkCssNode *node, gtk_css_node_reposition (node, parent, parent ? parent->last_child : NULL); } +void +gtk_css_node_set_after (GtkCssNode *cssnode, + GtkCssNode *previous_sibling) +{ + if (cssnode->previous_sibling == previous_sibling) + return; + + gtk_css_node_reposition (cssnode, + previous_sibling->parent, + previous_sibling); +} + +void +gtk_css_node_set_before (GtkCssNode *cssnode, + GtkCssNode *next_sibling) +{ + if (cssnode->next_sibling == next_sibling) + return; + + gtk_css_node_reposition (cssnode, + next_sibling->parent, + next_sibling->previous_sibling); +} + GtkCssNode * gtk_css_node_get_parent (GtkCssNode *cssnode) { diff --git a/gtk/gtkcssnodeprivate.h b/gtk/gtkcssnodeprivate.h index b1339b0b9c..3c6abfdb23 100644 --- a/gtk/gtkcssnodeprivate.h +++ b/gtk/gtkcssnodeprivate.h @@ -78,6 +78,10 @@ GType gtk_css_node_get_type (void) G_GNUC_CONST; void gtk_css_node_set_parent (GtkCssNode *cssnode, GtkCssNode *parent); +void gtk_css_node_set_after (GtkCssNode *cssnode, + GtkCssNode *previous_sibling); +void gtk_css_node_set_before (GtkCssNode *cssnode, + GtkCssNode *next_sibling); GtkCssNode * gtk_css_node_get_parent (GtkCssNode *cssnode); GtkCssNode * gtk_css_node_get_first_child (GtkCssNode *cssnode); GtkCssNode * gtk_css_node_get_last_child (GtkCssNode *cssnode); diff --git a/gtk/gtkcsswidgetnode.c b/gtk/gtkcsswidgetnode.c index e18cdc3127..5c89a98124 100644 --- a/gtk/gtkcsswidgetnode.c +++ b/gtk/gtkcsswidgetnode.c @@ -24,6 +24,8 @@ #include "gtkprivate.h" #include "gtkstylecontextprivate.h" #include "gtkwidgetprivate.h" +/* widgets for special casing go here */ +#include "gtkbox.h" /* When these change we do a full restyling. Otherwise we try to figure out * if we need to change things. */ @@ -173,7 +175,7 @@ typedef GtkWidgetPath * (* GetPathForChildFunc) (GtkContainer *, GtkWidget *); static gboolean widget_needs_widget_path (GtkWidget *widget) { - static GetPathForChildFunc funcs[1]; + static GetPathForChildFunc funcs[2]; GtkWidget *parent; GetPathForChildFunc parent_func; guint i; @@ -182,6 +184,7 @@ widget_needs_widget_path (GtkWidget *widget) { i = 0; funcs[i++] = GTK_CONTAINER_CLASS (g_type_class_ref (GTK_TYPE_CONTAINER))->get_path_for_child; + funcs[i++] = GTK_CONTAINER_CLASS (g_type_class_ref (GTK_TYPE_BOX))->get_path_for_child; g_assert (i == G_N_ELEMENTS (funcs)); }