[gtk+] cssnode: Track invalid children
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] cssnode: Track invalid children
- Date: Wed, 18 Mar 2015 15:10:55 +0000 (UTC)
commit c7fba52a36092d16fcd38c87b6d2a29f160dc4ee
Author: Benjamin Otte <otte redhat com>
Date: Sun Mar 1 13:14:01 2015 +0100
cssnode: Track invalid children
We need to properly track if a node needs to propagate invalidation
state information to its children. We didn't do this properly before and
that could lead to us forgetting to invalidate nodes in corner cases.
gtk/gtkcssnode.c | 36 +++++++++++++++++++++++++-----------
gtk/gtkcssnodeprivate.h | 1 +
2 files changed, 26 insertions(+), 11 deletions(-)
---
diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c
index 547cfb9..462d550 100644
--- a/gtk/gtkcssnode.c
+++ b/gtk/gtkcssnode.c
@@ -499,6 +499,8 @@ gtk_css_node_reposition (GtkCssNode *node,
gtk_css_node_set_children_changed (parent);
g_object_ref (node);
+ if (node->pending_changes)
+ parent->needs_propagation = TRUE;
if (node->invalid && node->visible)
gtk_css_node_set_invalid (parent, TRUE);
}
@@ -621,7 +623,7 @@ gtk_css_node_propagate_pending_changes (GtkCssNode *cssnode,
if (style_changed)
change |= GTK_CSS_CHANGE_PARENT_STYLE;
- if (!cssnode->invalid && change == 0)
+ if (!cssnode->needs_propagation && change == 0)
return;
for (child = gtk_css_node_get_first_child (cssnode);
@@ -633,19 +635,20 @@ gtk_css_node_propagate_pending_changes (GtkCssNode *cssnode,
if (child->visible)
change |= _gtk_css_change_for_sibling (child_change);
}
+
+ cssnode->needs_propagation = FALSE;
}
static gboolean
gtk_css_node_needs_new_style (GtkCssNode *cssnode)
{
- return cssnode->style_is_invalid;
+ return cssnode->style_is_invalid || cssnode->needs_propagation;
}
static void
gtk_css_node_ensure_style (GtkCssNode *cssnode,
gint64 current_time)
{
- GtkCssStyle *new_style;
gboolean style_changed;
if (!gtk_css_node_needs_new_style (cssnode))
@@ -654,16 +657,25 @@ gtk_css_node_ensure_style (GtkCssNode *cssnode,
if (cssnode->parent)
gtk_css_node_ensure_style (cssnode->parent, current_time);
- if (cssnode->previous_sibling)
- gtk_css_node_ensure_style (cssnode->previous_sibling, current_time);
+ if (cssnode->style_is_invalid)
+ {
+ GtkCssStyle *new_style;
- new_style = GTK_CSS_NODE_GET_CLASS (cssnode)->update_style (cssnode,
- cssnode->pending_changes,
- current_time,
- cssnode->style);
+ if (cssnode->previous_sibling)
+ gtk_css_node_ensure_style (cssnode->previous_sibling, current_time);
- style_changed = gtk_css_node_set_style (cssnode, new_style);
- g_object_unref (new_style);
+ new_style = GTK_CSS_NODE_GET_CLASS (cssnode)->update_style (cssnode,
+ cssnode->pending_changes,
+ current_time,
+ cssnode->style);
+
+ style_changed = gtk_css_node_set_style (cssnode, new_style);
+ g_object_unref (new_style);
+ }
+ else
+ {
+ style_changed = FALSE;
+ }
gtk_css_node_propagate_pending_changes (cssnode, style_changed);
@@ -886,6 +898,8 @@ gtk_css_node_invalidate (GtkCssNode *cssnode,
GTK_CSS_NODE_GET_CLASS (cssnode)->invalidate (cssnode);
+ if (cssnode->parent)
+ cssnode->parent->needs_propagation = TRUE;
gtk_css_node_invalidate_style (cssnode);
}
diff --git a/gtk/gtkcssnodeprivate.h b/gtk/gtkcssnodeprivate.h
index 00a106a..611bc71 100644
--- a/gtk/gtkcssnodeprivate.h
+++ b/gtk/gtkcssnodeprivate.h
@@ -52,6 +52,7 @@ struct _GtkCssNode
guint visible :1; /* node will be skipped when validating or computing styles
*/
guint invalid :1; /* node or a child needs to be validated (even if just for
animation) */
guint children_changed :1; /* the children changed since last validation */
+ guint needs_propagation :1; /* children have state changes that need to be propagated to
their siblings */
/* Two invariants hold for this variable:
* style_is_invalid == TRUE => next_sibling->style_is_invalid == TRUE
* style_is_invalid == FALSE => first_child->style_is_invalid == TRUE
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]