[gtk+/wip/cssnode3: 72/101] cssnode: Always return correct style values



commit 27c474c62722b242f9d5265d124a772db6ec70a4
Author: Benjamin Otte <otte redhat com>
Date:   Sun Feb 22 23:11:22 2015 +0100

    cssnode: Always return correct style values
    
    If CSS values are queried from a widget, recompute them if necessary. Do
    not emit style-updated until the validation phase however.
    
    This way, we don't run into performance traps when style-update causes
    invalidations that cause new style-updated to be emitted.

 gtk/gtkcsswidgetnode.c        |   42 ++++++++++++++++++++++++++++++++--------
 gtk/gtkcsswidgetnodeprivate.h |    1 +
 2 files changed, 34 insertions(+), 9 deletions(-)
---
diff --git a/gtk/gtkcsswidgetnode.c b/gtk/gtkcsswidgetnode.c
index 8fff931..f4c27fe 100644
--- a/gtk/gtkcsswidgetnode.c
+++ b/gtk/gtkcsswidgetnode.c
@@ -33,16 +33,35 @@
 
 G_DEFINE_TYPE (GtkCssWidgetNode, gtk_css_widget_node, GTK_TYPE_CSS_NODE)
 
+static void
+gtk_css_widget_node_finalize (GObject *object)
+{
+  GtkCssWidgetNode *node = GTK_CSS_WIDGET_NODE (object);
+
+  _gtk_bitmask_free (node->accumulated_changes);
+
+  G_OBJECT_CLASS (gtk_css_widget_node_parent_class)->finalize (object);
+}
+
 static GtkCssStyle *
 gtk_css_widget_node_update_style (GtkCssNode   *cssnode,
                                   GtkCssChange  pending_change,
                                   gint64        timestamp,
                                   GtkCssStyle  *old_style)
 {
-  if (old_style == NULL)
-    return GTK_CSS_NODE_CLASS (gtk_css_widget_node_parent_class)->update_style (cssnode, pending_change, 
timestamp, old_style);
+  GtkCssWidgetNode *node;
+  GtkCssStyle *new_style;
+  GtkBitmask *diff;
+
+  node = GTK_CSS_WIDGET_NODE (cssnode);
+
+  new_style = GTK_CSS_NODE_CLASS (gtk_css_widget_node_parent_class)->update_style (cssnode, pending_change, 
timestamp, old_style);
+
+  diff = gtk_css_style_get_difference (new_style, old_style);
+  node->accumulated_changes = _gtk_bitmask_union (node->accumulated_changes, diff);
+  _gtk_bitmask_free (diff);
 
-  return NULL;
+  return new_style;
 }
 
 static gboolean
@@ -170,13 +189,17 @@ gtk_css_widget_node_validate (GtkCssNode       *node,
       new_style = g_object_ref (style);
     }
 
-  changes = gtk_css_style_get_difference (new_style, style);
-
   if (GTK_IS_CSS_ANIMATED_STYLE (new_style) &&
       !gtk_css_animated_style_is_static (GTK_CSS_ANIMATED_STYLE (new_style)))
     gtk_css_node_set_invalid (node, TRUE);
 
-  gtk_style_context_validate (context, changes);
+  changes = gtk_css_style_get_difference (new_style, style);
+  widget_node->accumulated_changes = _gtk_bitmask_union (widget_node->accumulated_changes, changes);
+  _gtk_bitmask_free (changes);
+
+  gtk_style_context_validate (context, widget_node->accumulated_changes);
+  _gtk_bitmask_free (widget_node->accumulated_changes);
+  widget_node->accumulated_changes = _gtk_bitmask_new ();
 
   if (_gtk_bitmask_is_empty (changes) && !GTK_IS_CSS_ANIMATED_STYLE (new_style))
     {
@@ -184,8 +207,6 @@ gtk_css_widget_node_validate (GtkCssNode       *node,
       new_style = NULL;
     }
 
-  _gtk_bitmask_free (changes);
-
   return new_style;
 }
 
@@ -306,7 +327,9 @@ static void
 gtk_css_widget_node_class_init (GtkCssWidgetNodeClass *klass)
 {
   GtkCssNodeClass *node_class = GTK_CSS_NODE_CLASS (klass);
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+  object_class->finalize = gtk_css_widget_node_finalize;
   node_class->update_style = gtk_css_widget_node_update_style;
   node_class->validate = gtk_css_widget_node_validate;
   node_class->queue_validate = gtk_css_widget_node_queue_validate;
@@ -319,8 +342,9 @@ gtk_css_widget_node_class_init (GtkCssWidgetNodeClass *klass)
 }
 
 static void
-gtk_css_widget_node_init (GtkCssWidgetNode *cssnode)
+gtk_css_widget_node_init (GtkCssWidgetNode *node)
 {
+  node->accumulated_changes = _gtk_bitmask_new ();
 }
 
 GtkCssNode *
diff --git a/gtk/gtkcsswidgetnodeprivate.h b/gtk/gtkcsswidgetnodeprivate.h
index 28e6020..39dc200 100644
--- a/gtk/gtkcsswidgetnodeprivate.h
+++ b/gtk/gtkcsswidgetnodeprivate.h
@@ -39,6 +39,7 @@ struct _GtkCssWidgetNode
 
   GtkWidget *widget;
   guint validate_cb_id;
+  GtkBitmask *accumulated_changes;
 };
 
 struct _GtkCssWidgetNodeClass


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]