[gtk+] cssnode: Redo first/last-child change tracking
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] cssnode: Redo first/last-child change tracking
- Date: Wed, 16 Dec 2015 18:56:32 +0000 (UTC)
commit 2e362eafc7a22e007fddb4ee9c76dfffdbbf02b7
Author: Benjamin Otte <otte redhat com>
Date: Wed Dec 16 19:48:30 2015 +0100
cssnode: Redo first/last-child change tracking
Invisible nodes don't change the first/last-child status of the nodes
after/before them. That means we don't have to just check the state of
the adjacent node when modifying this state, but all their siblings
until we hit a visible node.
The same way, a node is not the first child if it has no previous
sibling, it is the first child if it has no previous visible sibling.
This is important for caching in the global lookup cache.
gtk/gtkcssnode.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 62 insertions(+), 10 deletions(-)
---
diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c
index 738d1e9..b129c01 100644
--- a/gtk/gtkcssnode.c
+++ b/gtk/gtkcssnode.c
@@ -253,6 +253,36 @@ gtk_css_node_finalize (GObject *object)
G_OBJECT_CLASS (gtk_css_node_parent_class)->finalize (object);
}
+static gboolean
+gtk_css_node_is_first_child (GtkCssNode *node)
+{
+ GtkCssNode *iter;
+
+ for (iter = node->previous_sibling;
+ iter != NULL;
+ iter = iter->previous_sibling)
+ {
+ if (iter->visible)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean
+gtk_css_node_is_last_child (GtkCssNode *node)
+{
+ GtkCssNode *iter;
+
+ for (iter = node->next_sibling;
+ iter != NULL;
+ iter = iter->next_sibling)
+ {
+ if (iter->visible)
+ return FALSE;
+ }
+ return TRUE;
+}
+
#define UNPACK_DECLARATION(packed) ((GtkCssNodeDeclaration *) (GPOINTER_TO_SIZE (packed) & ~0x3))
#define UNPACK_FLAGS(packed) (GPOINTER_TO_SIZE (packed) & 0x3)
#define PACK(decl, first_child, last_child) GSIZE_TO_POINTER (GPOINTER_TO_SIZE (decl) | ((first_child) ? 0x2
: 0) | ((last_child) ? 0x1 : 0))
@@ -292,8 +322,8 @@ lookup_in_global_parent_cache (GtkCssNode *node,
style = g_hash_table_lookup (cache,
PACK (decl,
- gtk_css_node_get_previous_sibling (node) == NULL,
- gtk_css_node_get_next_sibling (node) == NULL));
+ gtk_css_node_is_first_child (node),
+ gtk_css_node_is_last_child (node)));
return style;
}
@@ -376,8 +406,8 @@ store_in_global_parent_cache (GtkCssNode *node,
g_hash_table_insert (cache,
PACK (gtk_css_node_declaration_ref ((GtkCssNodeDeclaration *) decl),
- gtk_css_node_get_previous_sibling (node) == NULL,
- gtk_css_node_get_next_sibling (node) == NULL),
+ gtk_css_node_is_first_child (node),
+ gtk_css_node_is_last_child (node)),
g_object_ref (style));
}
@@ -1071,6 +1101,8 @@ void
gtk_css_node_set_visible (GtkCssNode *cssnode,
gboolean visible)
{
+ GtkCssNode *iter;
+
if (cssnode->visible == visible)
return;
@@ -1094,14 +1126,34 @@ gtk_css_node_set_visible (GtkCssNode *cssnode,
}
if (cssnode->next_sibling)
- gtk_css_node_invalidate (cssnode->next_sibling, GTK_CSS_CHANGE_ANY_SIBLING
- | GTK_CSS_CHANGE_NTH_CHILD
- | (cssnode->previous_sibling ? 0 :
GTK_CSS_CHANGE_FIRST_CHILD));
-
+ {
+ gtk_css_node_invalidate (cssnode->next_sibling, GTK_CSS_CHANGE_ANY_SIBLING | GTK_CSS_CHANGE_NTH_CHILD);
+ if (gtk_css_node_is_first_child (cssnode))
+ {
+ for (iter = cssnode->next_sibling;
+ iter != NULL;
+ iter = iter->next_sibling)
+ {
+ gtk_css_node_invalidate (iter, GTK_CSS_CHANGE_FIRST_CHILD);
+ if (iter->visible)
+ break;
+ }
+ }
+ }
+
if (cssnode->previous_sibling)
{
- if (cssnode->next_sibling)
- gtk_css_node_invalidate (cssnode->previous_sibling, GTK_CSS_CHANGE_LAST_CHILD);
+ if (gtk_css_node_is_last_child (cssnode))
+ {
+ for (iter = cssnode->previous_sibling;
+ iter != NULL;
+ iter = iter->previous_sibling)
+ {
+ gtk_css_node_invalidate (iter, GTK_CSS_CHANGE_LAST_CHILD);
+ if (iter->visible)
+ break;
+ }
+ }
gtk_css_node_invalidate (cssnode->parent->first_child, GTK_CSS_CHANGE_NTH_LAST_CHILD);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]