[gtk+] stylecontext: Move validation into GtkCssNode



commit 4cc2af2db13bbeda0a10adb3bce7b1fa4f28b03b
Author: Benjamin Otte <otte redhat com>
Date:   Fri Jan 30 16:27:17 2015 +0100

    stylecontext: Move validation into GtkCssNode

 gtk/gtkcontainer.c            |    8 +++---
 gtk/gtkcssnode.c              |   54 +++++++++++++++++++++++++++++++++++++++
 gtk/gtkcssnodeprivate.h       |    8 ++++++
 gtk/gtkcsswidgetnode.c        |   35 ++++++++++++++++---------
 gtk/gtkcsswidgetnodeprivate.h |    2 -
 gtk/gtkstylecontext.c         |   56 ++--------------------------------------
 gtk/gtkstylecontextprivate.h  |    3 +-
 gtk/gtkwindow.c               |    8 +++---
 8 files changed, 97 insertions(+), 77 deletions(-)
---
diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c
index 0ec29c7..186f89d 100644
--- a/gtk/gtkcontainer.c
+++ b/gtk/gtkcontainer.c
@@ -1853,10 +1853,10 @@ gtk_container_idle_sizer (GdkFrameClock *clock,
       current_time = g_get_monotonic_time ();
 
       container->priv->restyle_pending = FALSE;
-      _gtk_style_context_validate (gtk_widget_get_style_context (GTK_WIDGET (container)),
-                                   current_time,
-                                   0,
-                                   empty);
+      gtk_css_node_validate (gtk_style_context_get_root (gtk_widget_get_style_context (GTK_WIDGET 
(container))),
+                             current_time,
+                             0,
+                             empty);
 
       _gtk_bitmask_free (empty);
     }
diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c
index 891cf1f..9ff83aa 100644
--- a/gtk/gtkcssnode.c
+++ b/gtk/gtkcssnode.c
@@ -20,6 +20,7 @@
 #include "gtkcssnodeprivate.h"
 
 #include "gtkcsstransientnodeprivate.h"
+#include "gtkdebug.h"
 
 G_DEFINE_TYPE (GtkCssNode, gtk_css_node, G_TYPE_OBJECT)
 
@@ -74,6 +75,15 @@ gtk_css_node_real_set_invalid (GtkCssNode *node,
     gtk_css_node_set_invalid (node->parent, invalid);
 }
 
+static GtkBitmask *
+gtk_css_node_real_validate (GtkCssNode       *cssnode,
+                            gint64            timestamp,
+                            GtkCssChange      change,
+                            const GtkBitmask *parent_changes)
+{
+  return _gtk_bitmask_new ();
+}
+
 static GtkWidgetPath *
 gtk_css_node_real_create_widget_path (GtkCssNode *cssnode)
 {
@@ -95,6 +105,7 @@ gtk_css_node_class_init (GtkCssNodeClass *klass)
   object_class->finalize = gtk_css_node_finalize;
 
   klass->invalidate = gtk_css_node_real_invalidate;
+  klass->validate = gtk_css_node_real_validate;
   klass->set_invalid = gtk_css_node_real_set_invalid;
   klass->create_widget_path = gtk_css_node_real_create_widget_path;
   klass->get_widget_path = gtk_css_node_real_get_widget_path;
@@ -358,6 +369,49 @@ gtk_css_node_invalidate (GtkCssNode   *cssnode,
   gtk_css_node_set_invalid (cssnode, TRUE);
 }
 
+void
+gtk_css_node_validate (GtkCssNode            *cssnode,
+                       gint64                 timestamp,
+                       GtkCssChange           change,
+                       const GtkBitmask      *parent_changes)
+{
+  GtkCssNode *child;
+  GtkBitmask *changes;
+
+  /* If you run your application with
+   *   GTK_DEBUG=no-css-cache
+   * every invalidation will purge the cache and completely query
+   * everything anew form the cache. This is slow (in particular
+   * when animating), but useful for figuring out bugs.
+   *
+   * We achieve that by pretending that everything that could have
+   * changed has and so we of course totally need to redo everything.
+   *
+   * Note that this also completely revalidates child widgets all
+   * the time.
+   */
+  if (G_UNLIKELY (gtk_get_debug_flags () & GTK_DEBUG_NO_CSS_CACHE))
+    change = GTK_CSS_CHANGE_ANY;
+
+  if (!cssnode->invalid && change == 0 && _gtk_bitmask_is_empty (parent_changes))
+    return;
+
+  gtk_css_node_set_invalid (cssnode, FALSE);
+
+  changes = GTK_CSS_NODE_GET_CLASS (cssnode)->validate (cssnode, timestamp, change, parent_changes);
+
+  change = _gtk_css_change_for_child (change);
+
+  for (child = gtk_css_node_get_first_child (cssnode);
+       child;
+       child = gtk_css_node_get_next_sibling (child))
+    {
+      gtk_css_node_validate (child, timestamp, change, changes);
+    }
+
+  _gtk_bitmask_free (changes);
+}
+
 GtkWidgetPath *
 gtk_css_node_create_widget_path (GtkCssNode *cssnode)
 {
diff --git a/gtk/gtkcssnodeprivate.h b/gtk/gtkcssnodeprivate.h
index 873ba67..66ac247 100644
--- a/gtk/gtkcssnodeprivate.h
+++ b/gtk/gtkcssnodeprivate.h
@@ -60,6 +60,10 @@ struct _GtkCssNodeClass
                                                          GtkCssChange           change);
   void                  (* set_invalid)                 (GtkCssNode            *node,
                                                          gboolean               invalid);
+  GtkBitmask *          (* validate)                    (GtkCssNode            *cssnode,
+                                                         gint64                 timestamp,
+                                                         GtkCssChange           change,
+                                                         const GtkBitmask      *parent_changes);
 };
 
 GType                   gtk_css_node_get_type           (void) G_GNUC_CONST;
@@ -112,6 +116,10 @@ void                    gtk_css_node_set_style          (GtkCssNode            *
 
 void                    gtk_css_node_invalidate         (GtkCssNode            *cssnode,
                                                          GtkCssChange           change);
+void                    gtk_css_node_validate           (GtkCssNode            *cssnode,
+                                                         gint64                 timestamp,
+                                                         GtkCssChange           change,
+                                                         const GtkBitmask      *parent_changes);
 void                    gtk_css_node_set_invalid        (GtkCssNode            *node,
                                                          gboolean               invalid);
 GtkWidgetPath *         gtk_css_node_create_widget_path (GtkCssNode            *cssnode);
diff --git a/gtk/gtkcsswidgetnode.c b/gtk/gtkcsswidgetnode.c
index e49a560..66e08c1 100644
--- a/gtk/gtkcsswidgetnode.c
+++ b/gtk/gtkcsswidgetnode.c
@@ -53,6 +53,27 @@ gtk_css_widget_node_set_invalid (GtkCssNode *node,
   G_GNUC_END_IGNORE_DEPRECATIONS
 }
 
+static GtkBitmask *
+gtk_css_widget_node_validate (GtkCssNode       *node,
+                              gint64            timestamp,
+                              GtkCssChange      change,
+                              const GtkBitmask *parent_changes)
+{
+  GtkCssWidgetNode *widget_node = GTK_CSS_WIDGET_NODE (node);
+
+  change |= widget_node->pending_changes;
+  widget_node->pending_changes = 0;
+
+  if (widget_node->widget == NULL)
+    return _gtk_bitmask_new ();
+
+  return _gtk_style_context_validate (gtk_widget_get_style_context (widget_node->widget),
+                                      node,
+                                      timestamp,
+                                      change,
+                                      parent_changes);
+}
+
 static GtkWidgetPath *
 gtk_css_widget_node_create_widget_path (GtkCssNode *node)
 {
@@ -93,6 +114,7 @@ gtk_css_widget_node_class_init (GtkCssWidgetNodeClass *klass)
   GtkCssNodeClass *node_class = GTK_CSS_NODE_CLASS (klass);
 
   node_class->invalidate = gtk_css_widget_node_invalidate;
+  node_class->validate = gtk_css_widget_node_validate;
   node_class->set_invalid = gtk_css_widget_node_set_invalid;
   node_class->create_widget_path = gtk_css_widget_node_create_widget_path;
   node_class->get_widget_path = gtk_css_widget_node_get_widget_path;
@@ -136,16 +158,3 @@ gtk_css_widget_node_get_widget (GtkCssWidgetNode *node)
   return node->widget;
 }
 
-GtkCssChange
-gtk_css_widget_node_reset_change (GtkCssWidgetNode *node)
-{
-  GtkCssChange result;
-
-  gtk_internal_return_val_if_fail (GTK_IS_CSS_WIDGET_NODE (node), 0);
-
-  result = node->pending_changes;
-  node->pending_changes = 0;
-
-  return result;
-}
-
diff --git a/gtk/gtkcsswidgetnodeprivate.h b/gtk/gtkcsswidgetnodeprivate.h
index 2928653..d34becc 100644
--- a/gtk/gtkcsswidgetnodeprivate.h
+++ b/gtk/gtkcsswidgetnodeprivate.h
@@ -55,8 +55,6 @@ void                    gtk_css_widget_node_widget_destroyed    (GtkCssWidgetNod
 
 GtkWidget *             gtk_css_widget_node_get_widget          (GtkCssWidgetNode       *node);
 
-GtkCssChange            gtk_css_widget_node_reset_change        (GtkCssWidgetNode       *node);
-
 G_END_DECLS
 
 #endif /* __GTK_CSS_WIDGET_NODE_PRIVATE_H__ */
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index a141011..f6bf2d3 100644
--- a/gtk/gtkstylecontext.c
+++ b/gtk/gtkstylecontext.c
@@ -2802,62 +2802,19 @@ gtk_style_context_should_create_transitions (GtkStyleContext *context,
   return animate;
 }
 
-void
+GtkBitmask *
 _gtk_style_context_validate (GtkStyleContext  *context,
+                             GtkCssNode       *cssnode,
                              gint64            timestamp,
                              GtkCssChange      change,
                              const GtkBitmask *parent_changes)
 {
   GtkStyleContextPrivate *priv;
-  GtkCssNode *cssnode;
   GtkCssStyle *current;
   GtkBitmask *changes;
-  GSList *list;
-
-  g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
 
   priv = context->priv;
 
-  if (G_UNLIKELY (gtk_style_context_is_saved (context)))
-    {
-      cssnode = gtk_style_context_get_root (context);
-      if (GTK_IS_CSS_WIDGET_NODE (cssnode))
-        {
-          GtkWidget *widget = gtk_css_widget_node_get_widget (GTK_CSS_WIDGET_NODE (cssnode));
-          g_warning ("unmatched gtk_style_context_save/restore() detected while validating context for %s 
%p",
-                     gtk_widget_get_name (widget), widget);
-        }
-      else
-        {
-          g_warning ("unmatched gtk_style_context_save/restore() detected while validating context");
-        }
-    }
-  else
-    cssnode = priv->cssnode;
-
-  if (GTK_IS_CSS_WIDGET_NODE (cssnode))
-    change |= gtk_css_widget_node_reset_change (GTK_CSS_WIDGET_NODE (cssnode));
-  
-  /* If you run your application with
-   *   GTK_DEBUG=no-css-cache
-   * every invalidation will purge the cache and completely query
-   * everything anew form the cache. This is slow (in particular
-   * when animating), but useful for figuring out bugs.
-   *
-   * We achieve that by pretending that everything that could have
-   * changed has and so we of course totally need to redo everything.
-   *
-   * Note that this also completely revalidates child widgets all
-   * the time.
-   */
-  if (G_UNLIKELY (gtk_get_debug_flags () & GTK_DEBUG_NO_CSS_CACHE))
-    change = GTK_CSS_CHANGE_ANY;
-
-  if (!cssnode->invalid && change == 0 && _gtk_bitmask_is_empty (parent_changes))
-    return;
-
-  gtk_css_node_set_invalid (cssnode, FALSE);
-
   current = gtk_css_node_get_style (cssnode);
   if (current == NULL)
     current = gtk_css_static_style_get_default ();
@@ -2933,16 +2890,9 @@ _gtk_style_context_validate (GtkStyleContext  *context,
   if (!_gtk_bitmask_is_empty (changes))
     gtk_style_context_do_invalidate (context, changes);
 
-  change = _gtk_css_change_for_child (change);
-  
   gtk_style_context_clear_property_cache (context);
 
-  for (list = priv->children; list; list = list->next)
-    {
-      _gtk_style_context_validate (list->data, timestamp, change, changes);
-    }
-
-  _gtk_bitmask_free (changes);
+  return changes;
 }
 
 /**
diff --git a/gtk/gtkstylecontextprivate.h b/gtk/gtkstylecontextprivate.h
index 08b8ff6..8e616a0 100644
--- a/gtk/gtkstylecontextprivate.h
+++ b/gtk/gtkstylecontextprivate.h
@@ -44,7 +44,8 @@ GtkCssValue   * _gtk_style_context_peek_property             (GtkStyleContext *c
 const GValue * _gtk_style_context_peek_style_property        (GtkStyleContext *context,
                                                               GType            widget_type,
                                                               GParamSpec      *pspec);
-void           _gtk_style_context_validate                   (GtkStyleContext *context,
+GtkBitmask *   _gtk_style_context_validate                   (GtkStyleContext *context,
+                                                              GtkCssNode      *cssnode,
                                                               gint64           timestamp,
                                                               GtkCssChange     change,
                                                               const GtkBitmask*parent_changes);
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 60d66e5..32a3b2c 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -5849,10 +5849,10 @@ gtk_window_show (GtkWidget *widget)
   need_resize = _gtk_widget_get_alloc_needed (widget) || !gtk_widget_get_realized (widget);
 
   empty = _gtk_bitmask_new ();
-  _gtk_style_context_validate (gtk_widget_get_style_context (widget),
-                               g_get_monotonic_time (),
-                               0,
-                               empty);
+  gtk_css_node_validate (gtk_style_context_get_root (gtk_widget_get_style_context (widget)),
+                         g_get_monotonic_time (),
+                         0,
+                         empty);
   _gtk_bitmask_free (empty);
 
   if (need_resize)


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