box: Use CSS nodes instead of widget paths

This is a very simple patch that causes a bunch of overhead. But it
works.
This commit is contained in:
Benjamin Otte 2015-02-09 22:51:28 +01:00
parent b92fe2fa85
commit ee91fb71ca
4 changed files with 46 additions and 6 deletions

View File

@ -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);

View File

@ -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)
{

View File

@ -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);

View File

@ -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));
}