cssnode: Automatically recreate style on get_style() call
authorBenjamin Otte <otte@redhat.com>
Wed, 4 Feb 2015 03:43:55 +0000 (04:43 +0100)
committerBenjamin Otte <otte@redhat.com>
Wed, 18 Mar 2015 14:23:30 +0000 (15:23 +0100)
When the style is invalid, redo it.

Make this a vfunc, so the widget nodes can opt out.

gtk/gtkcssnode.c
gtk/gtkcssnodeprivate.h
gtk/gtkcsspathnode.c
gtk/gtkcsstransientnode.c
gtk/gtkcsswidgetnode.c
gtk/gtkstylecontext.c

index b4ea530694a81506ce8b7cedd96f57767c470baa..b331f26b73670947cb7f6df7f81038660e03ddec 100644 (file)
@@ -222,9 +222,16 @@ gtk_css_node_create_style (GtkCssNode *cssnode)
   return style;
 }
 
+static GtkCssStyle *
+gtk_css_node_real_update_style (GtkCssNode   *cssnode,
+                                GtkCssChange  pending_change,
+                                GtkCssStyle  *old_style)
+{
+  return gtk_css_node_create_style (cssnode);
+}
+
 static void
-gtk_css_node_real_invalidate (GtkCssNode   *cssnode,
-                              GtkCssChange  change)
+gtk_css_node_real_invalidate (GtkCssNode *node)
 {
 }
 
@@ -276,6 +283,7 @@ gtk_css_node_class_init (GtkCssNodeClass *klass)
   object_class->dispose = gtk_css_node_dispose;
   object_class->finalize = gtk_css_node_finalize;
 
+  klass->update_style = gtk_css_node_real_update_style;
   klass->invalidate = gtk_css_node_real_invalidate;
   klass->validate = gtk_css_node_real_validate;
   klass->set_invalid = gtk_css_node_real_set_invalid;
@@ -288,6 +296,8 @@ static void
 gtk_css_node_init (GtkCssNode *cssnode)
 {
   cssnode->decl = gtk_css_node_declaration_new ();
+
+  cssnode->style = g_object_ref (gtk_css_static_style_get_default ());
 }
 
 void
@@ -402,6 +412,21 @@ gtk_css_node_set_style (GtkCssNode  *cssnode,
 GtkCssStyle *
 gtk_css_node_get_style (GtkCssNode *cssnode)
 {
+  GtkCssStyle *new_style;
+
+  if (cssnode->pending_changes)
+    {
+      new_style = GTK_CSS_NODE_GET_CLASS (cssnode)->update_style (cssnode,
+                                                                  cssnode->pending_changes,
+                                                                  cssnode->style);
+      if (new_style)
+        {
+          gtk_css_node_set_style (cssnode, new_style);
+          g_object_unref (new_style);
+          cssnode->pending_changes = 0;
+        }
+    }
+
   return cssnode->style;
 }
 
@@ -533,7 +558,7 @@ gtk_css_node_invalidate (GtkCssNode   *cssnode,
 {
   cssnode->pending_changes |= change;
 
-  GTK_CSS_NODE_GET_CLASS (cssnode)->invalidate (cssnode, change);
+  GTK_CSS_NODE_GET_CLASS (cssnode)->invalidate (cssnode);
 
   gtk_css_node_set_invalid (cssnode, TRUE);
 }
index 7d6cbed226e06de5a99248f635d69fc271fe3314..d368a50682f0eef90a8681f1fe4fdd800daf0c02 100644 (file)
@@ -59,8 +59,10 @@ struct _GtkCssNodeClass
   GtkWidgetPath *       (* create_widget_path)          (GtkCssNode            *cssnode);
   const GtkWidgetPath * (* get_widget_path)             (GtkCssNode            *cssnode);
   GtkStyleProviderPrivate *(* get_style_provider)       (GtkCssNode            *cssnode);
-  void                  (* invalidate)                  (GtkCssNode            *cssnode,
-                                                         GtkCssChange           change);
+  GtkCssStyle *         (* update_style)                (GtkCssNode            *cssnode,
+                                                         GtkCssChange           pending_changes,
+                                                         GtkCssStyle           *old_style);
+  void                  (* invalidate)                  (GtkCssNode            *node);
   void                  (* set_invalid)                 (GtkCssNode            *node,
                                                          gboolean               invalid);
   GtkBitmask *          (* validate)                    (GtkCssNode            *cssnode,
index b3588ea54c5d36268aefc4f9685f4d05746de931..aeecc4d583191baf22fe9a3e94f455112a5aa65b 100644 (file)
 G_DEFINE_TYPE (GtkCssPathNode, gtk_css_path_node, GTK_TYPE_CSS_NODE)
 
 static void
-gtk_css_path_node_invalidate (GtkCssNode   *node,
-                              GtkCssChange  change)
+gtk_css_path_node_invalidate (GtkCssNode *node)
 {
   GtkCssPathNode *path_node = GTK_CSS_PATH_NODE (node);
 
-  gtk_css_node_set_style (node, NULL);
-
   if (path_node->context)
     {
       G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
index ef553f67c93b095e5208704c355102374e9a3c13..f2602e5059384b5fcc45c1a78f236ad8cdad5fe9 100644 (file)
 
 G_DEFINE_TYPE (GtkCssTransientNode, gtk_css_transient_node, GTK_TYPE_CSS_NODE)
 
-static void
-gtk_css_transient_node_invalidate (GtkCssNode   *node,
-                                   GtkCssChange  change)
-{
-  gtk_css_node_set_style (node, NULL);
-}
-
 static void
 gtk_css_transient_node_set_invalid (GtkCssNode *node,
                                     gboolean    invalid)
@@ -71,7 +64,6 @@ gtk_css_transient_node_class_init (GtkCssTransientNodeClass *klass)
 {
   GtkCssNodeClass *node_class = GTK_CSS_NODE_CLASS (klass);
 
-  node_class->invalidate = gtk_css_transient_node_invalidate;
   node_class->set_invalid = gtk_css_transient_node_set_invalid;
   node_class->create_widget_path = gtk_css_transient_node_create_widget_path;
   node_class->get_widget_path = gtk_css_transient_node_get_widget_path;
index 0f7e8708a9d17dbc2bccd5b2df3dc2ef6992adb5..f3a91a75e28ad3eeb1a543e593c72cc17268e85e 100644 (file)
 
 G_DEFINE_TYPE (GtkCssWidgetNode, gtk_css_widget_node, GTK_TYPE_CSS_NODE)
 
+static GtkCssStyle *
+gtk_css_widget_node_update_style (GtkCssNode   *cssnode,
+                                  GtkCssChange  pending_change,
+                                  GtkCssStyle  *old_style)
+{
+  return NULL;
+}
+
 static void
 gtk_css_widget_node_set_invalid (GtkCssNode *node,
                                  gboolean    invalid)
@@ -206,6 +214,7 @@ gtk_css_widget_node_class_init (GtkCssWidgetNodeClass *klass)
 {
   GtkCssNodeClass *node_class = GTK_CSS_NODE_CLASS (klass);
 
+  node_class->update_style = gtk_css_widget_node_update_style;
   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;
index 0112ec5439ff681ba65461113e95343448579908..cd24f7b36b479242eead52123a4aaf7085f7a5f1 100644 (file)
@@ -608,24 +608,8 @@ gtk_style_context_has_custom_cascade (GtkStyleContext *context)
 GtkCssStyle *
 gtk_style_context_lookup_style (GtkStyleContext *context)
 {
-  GtkStyleContextPrivate *priv;
-  GtkCssStyle *values;
-  GtkCssNode *cssnode;
-
-  priv = context->priv;
-  cssnode = priv->cssnode;
-
-  /* Current data in use is cached, just return it */
-  values = gtk_css_node_get_style (cssnode);
-  if (values)
-    return values;
-
-  values = gtk_css_node_create_style (cssnode);
-  
-  gtk_css_node_set_style (cssnode, values);
-  g_object_unref (values);
-
-  return values;
+  /* Code will recreate style if it was changed */
+  return gtk_css_node_get_style (context->priv->cssnode);
 }
 
 static GtkCssStyle *
@@ -702,7 +686,6 @@ _gtk_style_context_set_widget (GtkStyleContext *context,
       g_object_unref (priv->cssnode);
       priv->cssnode = gtk_css_widget_node_new (widget);
       gtk_css_node_set_state (priv->cssnode, GTK_STATE_FLAG_DIR_LTR);
-      gtk_css_node_set_style (priv->cssnode, gtk_css_static_style_get_default ());
     }
 
   if (widget)