[gtk+] cssnode: Handle invalidation
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] cssnode: Handle invalidation
- Date: Wed, 18 Mar 2015 15:05:07 +0000 (UTC)
commit 7bafb63ec3b04764f8986b82f1a6c6e1e73eea3b
Author: Benjamin Otte <otte redhat com>
Date: Sun Jan 25 02:40:40 2015 +0100
cssnode: Handle invalidation
Handle invalidation of node inside the CssNode code, don't do it in the
stylecontext.
gtk/gtkcssnode.c | 47 ++++++++++++++++++-------
gtk/gtkcssnodeprivate.h | 16 +++++---
gtk/gtkcsspathnode.c | 31 +++++++++++++++-
gtk/gtkcsspathnodeprivate.h | 3 +-
gtk/gtkcsstransientnode.c | 8 ++++
gtk/gtkcsswidgetnode.c | 16 ++++++++
gtk/gtkstylecontext.c | 78 ++++++++++++------------------------------
gtk/gtkstylecontextprivate.h | 2 +
8 files changed, 123 insertions(+), 78 deletions(-)
---
diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c
index 86c0a07..6e0b962 100644
--- a/gtk/gtkcssnode.c
+++ b/gtk/gtkcssnode.c
@@ -33,6 +33,12 @@ gtk_css_node_finalize (GObject *object)
G_OBJECT_CLASS (gtk_css_node_parent_class)->finalize (object);
}
+static void
+gtk_css_node_real_invalidate (GtkCssNode *cssnode,
+ GtkCssChange change)
+{
+}
+
static GtkWidgetPath *
gtk_css_node_real_create_widget_path (GtkCssNode *cssnode)
{
@@ -52,6 +58,7 @@ gtk_css_node_class_init (GtkCssNodeClass *klass)
object_class->finalize = gtk_css_node_finalize;
+ klass->invalidate = gtk_css_node_real_invalidate;
klass->create_widget_path = gtk_css_node_real_create_widget_path;
klass->get_widget_path = gtk_css_node_real_get_widget_path;
}
@@ -101,7 +108,8 @@ void
gtk_css_node_set_widget_type (GtkCssNode *cssnode,
GType widget_type)
{
- gtk_css_node_declaration_set_type (&cssnode->decl, widget_type);
+ if (gtk_css_node_declaration_set_type (&cssnode->decl, widget_type))
+ gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_NAME);
}
GType
@@ -110,11 +118,12 @@ gtk_css_node_get_widget_type (GtkCssNode *cssnode)
return gtk_css_node_declaration_get_type (cssnode->decl);
}
-gboolean
+void
gtk_css_node_set_id (GtkCssNode *cssnode,
const char *id)
{
- return gtk_css_node_declaration_set_id (&cssnode->decl, id);
+ if (gtk_css_node_declaration_set_id (&cssnode->decl, id))
+ gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_ID);
}
const char *
@@ -123,11 +132,12 @@ gtk_css_node_get_id (GtkCssNode *cssnode)
return gtk_css_node_declaration_get_id (cssnode->decl);
}
-gboolean
+void
gtk_css_node_set_state (GtkCssNode *cssnode,
GtkStateFlags state_flags)
{
- return gtk_css_node_declaration_set_state (&cssnode->decl, state_flags);
+ if (gtk_css_node_declaration_set_state (&cssnode->decl, state_flags))
+ gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_STATE);
}
GtkStateFlags
@@ -149,18 +159,20 @@ gtk_css_node_get_junction_sides (GtkCssNode *cssnode)
return gtk_css_node_declaration_get_junction_sides (cssnode->decl);
}
-gboolean
+void
gtk_css_node_add_class (GtkCssNode *cssnode,
GQuark style_class)
{
- return gtk_css_node_declaration_add_class (&cssnode->decl, style_class);
+ if (gtk_css_node_declaration_add_class (&cssnode->decl, style_class))
+ gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_CLASS);
}
-gboolean
+void
gtk_css_node_remove_class (GtkCssNode *cssnode,
GQuark style_class)
{
- return gtk_css_node_declaration_remove_class (&cssnode->decl, style_class);
+ if (gtk_css_node_declaration_remove_class (&cssnode->decl, style_class))
+ gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_CLASS);
}
gboolean
@@ -176,19 +188,21 @@ gtk_css_node_list_classes (GtkCssNode *cssnode)
return gtk_css_node_declaration_list_classes (cssnode->decl);
}
-gboolean
+void
gtk_css_node_add_region (GtkCssNode *cssnode,
GQuark region,
GtkRegionFlags flags)
{
- return gtk_css_node_declaration_add_region (&cssnode->decl, region, flags);
+ if (gtk_css_node_declaration_add_region (&cssnode->decl, region, flags))
+ gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_REGION);
}
-gboolean
+void
gtk_css_node_remove_region (GtkCssNode *cssnode,
GQuark region)
{
- return gtk_css_node_declaration_remove_region (&cssnode->decl, region);
+ if (gtk_css_node_declaration_remove_region (&cssnode->decl, region))
+ gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_REGION);
}
gboolean
@@ -218,6 +232,13 @@ gtk_css_node_dup_declaration (GtkCssNode *cssnode)
return gtk_css_node_declaration_ref (cssnode->decl);
}
+void
+gtk_css_node_invalidate (GtkCssNode *cssnode,
+ GtkCssChange change)
+{
+ GTK_CSS_NODE_GET_CLASS (cssnode)->invalidate (cssnode, change);
+}
+
GtkWidgetPath *
gtk_css_node_create_widget_path (GtkCssNode *cssnode)
{
diff --git a/gtk/gtkcssnodeprivate.h b/gtk/gtkcssnodeprivate.h
index fb8bb4d..46aafb0 100644
--- a/gtk/gtkcssnodeprivate.h
+++ b/gtk/gtkcssnodeprivate.h
@@ -48,6 +48,8 @@ struct _GtkCssNodeClass
GtkWidgetPath * (* create_widget_path) (GtkCssNode *cssnode);
const GtkWidgetPath * (* get_widget_path) (GtkCssNode *cssnode);
+ void (* invalidate) (GtkCssNode *cssnode,
+ GtkCssChange change);
};
GType gtk_css_node_get_type (void) G_GNUC_CONST;
@@ -59,26 +61,26 @@ GtkCssNode * gtk_css_node_get_parent (GtkCssNode *
void gtk_css_node_set_widget_type (GtkCssNode *cssnode,
GType widget_type);
GType gtk_css_node_get_widget_type (GtkCssNode *cssnode);
-gboolean gtk_css_node_set_id (GtkCssNode *cssnode,
+void gtk_css_node_set_id (GtkCssNode *cssnode,
const char *id);
const char * gtk_css_node_get_id (GtkCssNode *cssnode);
-gboolean gtk_css_node_set_state (GtkCssNode *cssnode,
+void gtk_css_node_set_state (GtkCssNode *cssnode,
GtkStateFlags state_flags);
GtkStateFlags gtk_css_node_get_state (GtkCssNode *cssnode);
void gtk_css_node_set_junction_sides (GtkCssNode *cssnode,
GtkJunctionSides junction_sides);
GtkJunctionSides gtk_css_node_get_junction_sides (GtkCssNode *cssnode);
-gboolean gtk_css_node_add_class (GtkCssNode *cssnode,
+void gtk_css_node_add_class (GtkCssNode *cssnode,
GQuark style_class);
-gboolean gtk_css_node_remove_class (GtkCssNode *cssnode,
+void gtk_css_node_remove_class (GtkCssNode *cssnode,
GQuark style_class);
gboolean gtk_css_node_has_class (GtkCssNode *cssnode,
GQuark style_class);
GList * gtk_css_node_list_classes (GtkCssNode *cssnode);
-gboolean gtk_css_node_add_region (GtkCssNode *cssnode,
+void gtk_css_node_add_region (GtkCssNode *cssnode,
GQuark region,
GtkRegionFlags flags);
-gboolean gtk_css_node_remove_region (GtkCssNode *cssnode,
+void gtk_css_node_remove_region (GtkCssNode *cssnode,
GQuark region);
gboolean gtk_css_node_has_region (GtkCssNode *cssnode,
GQuark region,
@@ -94,6 +96,8 @@ GtkCssStyle * gtk_css_node_get_style (GtkCssNode *
void gtk_css_node_set_style (GtkCssNode *cssnode,
GtkCssStyle *style);
+void gtk_css_node_invalidate (GtkCssNode *cssnode,
+ GtkCssChange change);
GtkWidgetPath * gtk_css_node_create_widget_path (GtkCssNode *cssnode);
const GtkWidgetPath * gtk_css_node_get_widget_path (GtkCssNode *cssnode);
diff --git a/gtk/gtkcsspathnode.c b/gtk/gtkcsspathnode.c
index 39a2f07..2463dc0 100644
--- a/gtk/gtkcsspathnode.c
+++ b/gtk/gtkcsspathnode.c
@@ -19,9 +19,26 @@
#include "gtkcsspathnodeprivate.h"
#include "gtkprivate.h"
+#include "gtkstylecontextprivate.h"
G_DEFINE_TYPE (GtkCssPathNode, gtk_css_path_node, GTK_TYPE_CSS_NODE)
+static void
+gtk_css_path_node_invalidate (GtkCssNode *node,
+ GtkCssChange change)
+{
+ GtkCssPathNode *path_node = GTK_CSS_PATH_NODE (node);
+
+ gtk_css_node_set_style (node, NULL);
+
+ if (path_node->context)
+ {
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
+ gtk_style_context_invalidate (path_node->context);
+ G_GNUC_END_IGNORE_DEPRECATIONS;
+ }
+}
+
static GtkWidgetPath *
gtk_css_path_node_real_create_widget_path (GtkCssNode *node)
{
@@ -58,6 +75,7 @@ gtk_css_path_node_class_init (GtkCssPathNodeClass *klass)
{
GtkCssNodeClass *node_class = GTK_CSS_NODE_CLASS (klass);
+ node_class->invalidate = gtk_css_path_node_invalidate;
node_class->create_widget_path = gtk_css_path_node_real_create_widget_path;
node_class->get_widget_path = gtk_css_path_node_real_get_widget_path;
}
@@ -68,9 +86,16 @@ gtk_css_path_node_init (GtkCssPathNode *cssnode)
}
GtkCssNode *
-gtk_css_path_node_new (void)
+gtk_css_path_node_new (GtkStyleContext *context)
{
- return g_object_new (GTK_TYPE_CSS_PATH_NODE, NULL);
+ GtkCssPathNode *node;
+
+ g_return_val_if_fail (context == NULL || GTK_IS_STYLE_CONTEXT (context), NULL);
+
+ node = g_object_new (GTK_TYPE_CSS_PATH_NODE, NULL);
+ node->context = context;
+
+ return GTK_CSS_NODE (node);
}
void
@@ -89,6 +114,8 @@ gtk_css_path_node_set_widget_path (GtkCssPathNode *node,
gtk_widget_path_ref (path);
node->path = path;
+
+ gtk_css_node_invalidate (GTK_CSS_NODE (node), GTK_CSS_CHANGE_ANY);
}
GtkWidgetPath *
diff --git a/gtk/gtkcsspathnodeprivate.h b/gtk/gtkcsspathnodeprivate.h
index 0ff89e7..dd3831c 100644
--- a/gtk/gtkcsspathnodeprivate.h
+++ b/gtk/gtkcsspathnodeprivate.h
@@ -37,6 +37,7 @@ struct _GtkCssPathNode
{
GtkCssNode node;
+ GtkStyleContext *context;
GtkWidgetPath *path;
};
@@ -47,7 +48,7 @@ struct _GtkCssPathNodeClass
GType gtk_css_path_node_get_type (void) G_GNUC_CONST;
-GtkCssNode * gtk_css_path_node_new (void);
+GtkCssNode * gtk_css_path_node_new (GtkStyleContext *context);
void gtk_css_path_node_set_widget_path (GtkCssPathNode *node,
GtkWidgetPath *path);
diff --git a/gtk/gtkcsstransientnode.c b/gtk/gtkcsstransientnode.c
index 723c97a..726a485 100644
--- a/gtk/gtkcsstransientnode.c
+++ b/gtk/gtkcsstransientnode.c
@@ -22,6 +22,13 @@
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 GtkWidgetPath *
gtk_css_transient_node_create_widget_path (GtkCssNode *node)
{
@@ -57,6 +64,7 @@ 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->create_widget_path = gtk_css_transient_node_create_widget_path;
node_class->get_widget_path = gtk_css_transient_node_get_widget_path;
}
diff --git a/gtk/gtkcsswidgetnode.c b/gtk/gtkcsswidgetnode.c
index c9e156e..0a4b17b 100644
--- a/gtk/gtkcsswidgetnode.c
+++ b/gtk/gtkcsswidgetnode.c
@@ -19,10 +19,25 @@
#include "gtkcsswidgetnodeprivate.h"
#include "gtkprivate.h"
+#include "gtkstylecontextprivate.h"
#include "gtkwidgetprivate.h"
G_DEFINE_TYPE (GtkCssWidgetNode, gtk_css_widget_node, GTK_TYPE_CSS_NODE)
+static void
+gtk_css_widget_node_invalidate (GtkCssNode *node,
+ GtkCssChange change)
+{
+ GtkCssWidgetNode *widget_node = GTK_CSS_WIDGET_NODE (node);
+ GtkStyleContext *context;
+
+ if (widget_node->widget == NULL)
+ return;
+
+ context = gtk_widget_get_style_context (widget_node->widget);
+ _gtk_style_context_invalidate_root_node (context, change);
+}
+
static GtkWidgetPath *
gtk_css_widget_node_create_widget_path (GtkCssNode *node)
{
@@ -62,6 +77,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->create_widget_path = gtk_css_widget_node_create_widget_path;
node_class->get_widget_path = gtk_css_widget_node_get_widget_path;
}
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index 0ff387e..0459112 100644
--- a/gtk/gtkstylecontext.c
+++ b/gtk/gtkstylecontext.c
@@ -356,7 +356,7 @@ gtk_style_context_set_cascade (GtkStyleContext *context,
priv->cascade = cascade;
- if (cascade)
+ if (cascade && priv->cssnode != NULL)
gtk_style_context_cascade_changed (cascade, context);
}
@@ -370,14 +370,14 @@ gtk_style_context_init (GtkStyleContext *style_context)
priv->screen = gdk_screen_get_default ();
- /* Create default info store */
- priv->cssnode = gtk_css_path_node_new ();
- gtk_css_node_set_state (priv->cssnode, GTK_STATE_FLAG_DIR_LTR);
-
priv->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
gtk_style_context_set_cascade (style_context,
_gtk_settings_get_style_cascade (gtk_settings_get_for_screen
(priv->screen), 1));
+
+ /* Create default info store */
+ priv->cssnode = gtk_css_path_node_new (style_context);
+ gtk_css_node_set_state (priv->cssnode, GTK_STATE_FLAG_DIR_LTR);
}
static void
@@ -873,24 +873,6 @@ gtk_style_context_set_invalid (GtkStyleContext *context,
}
}
-static void
-gtk_style_context_queue_invalidate_internal (GtkStyleContext *context,
- GtkCssChange change)
-{
- GtkStyleContextPrivate *priv = context->priv;
- GtkCssNode *cssnode = priv->cssnode;
-
- if (gtk_style_context_is_saved (context))
- {
- gtk_css_node_set_style (cssnode, NULL);
- }
- else
- {
- _gtk_style_context_queue_invalidate (context, change);
- /* XXX: We need to invalidate siblings here somehow */
- }
-}
-
/**
* gtk_style_context_new:
*
@@ -1291,10 +1273,7 @@ gtk_style_context_set_id (GtkStyleContext *context,
{
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
- if (!gtk_css_node_set_id (context->priv->cssnode, id))
- return;
-
- gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_ID);
+ gtk_css_node_set_id (context->priv->cssnode, id);
}
/*
@@ -1332,14 +1311,11 @@ gtk_style_context_set_state (GtkStyleContext *context,
old_flags = gtk_css_node_get_state (context->priv->cssnode);
- if (!gtk_css_node_set_state (context->priv->cssnode, flags))
- return;
+ gtk_css_node_set_state (context->priv->cssnode, flags);
if (((old_flags ^ flags) & (GTK_STATE_FLAG_DIR_LTR | GTK_STATE_FLAG_DIR_RTL)) &&
!gtk_style_context_is_saved (context))
g_object_notify (G_OBJECT (context), "direction");
-
- gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_STATE);
}
/**
@@ -1486,8 +1462,6 @@ gtk_style_context_set_path (GtkStyleContext *context,
gtk_css_path_node_set_widget_path (GTK_CSS_PATH_NODE (root), NULL);
gtk_css_node_set_widget_type (root, G_TYPE_NONE);
}
-
- _gtk_style_context_queue_invalidate (context, GTK_CSS_CHANGE_ANY);
}
/**
@@ -1668,8 +1642,7 @@ gtk_style_context_add_class (GtkStyleContext *context,
priv = context->priv;
class_quark = g_quark_from_string (class_name);
- if (gtk_css_node_add_class (priv->cssnode, class_quark))
- gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_CLASS);
+ gtk_css_node_add_class (priv->cssnode, class_quark);
}
/**
@@ -1698,8 +1671,7 @@ gtk_style_context_remove_class (GtkStyleContext *context,
priv = context->priv;
- if (gtk_css_node_remove_class (priv->cssnode, class_quark))
- gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_CLASS);
+ gtk_css_node_remove_class (priv->cssnode, class_quark);
}
/**
@@ -1873,8 +1845,7 @@ gtk_style_context_add_region (GtkStyleContext *context,
priv = context->priv;
region_quark = g_quark_from_string (region_name);
- if (gtk_css_node_add_region (priv->cssnode, region_quark, flags))
- gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_REGION);
+ gtk_css_node_add_region (priv->cssnode, region_quark, flags);
}
/**
@@ -1905,8 +1876,7 @@ gtk_style_context_remove_region (GtkStyleContext *context,
priv = context->priv;
- if (gtk_css_node_remove_region (priv->cssnode, region_quark))
- gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_REGION);
+ gtk_css_node_remove_region (priv->cssnode, region_quark);
}
/**
@@ -3008,27 +2978,23 @@ _gtk_style_context_validate (GtkStyleContext *context,
}
void
+_gtk_style_context_invalidate_root_node (GtkStyleContext *context,
+ GtkCssChange change)
+{
+ GtkStyleContextPrivate *priv = context->priv;
+
+ priv->pending_changes |= change;
+ gtk_style_context_set_invalid (context, TRUE);
+}
+
+void
_gtk_style_context_queue_invalidate (GtkStyleContext *context,
GtkCssChange change)
{
- GtkStyleContextPrivate *priv;
-
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
g_return_if_fail (change != 0);
- priv = context->priv;
-
- if (GTK_IS_CSS_WIDGET_NODE (priv->cssnode))
- {
- priv->pending_changes |= change;
- gtk_style_context_set_invalid (context, TRUE);
- }
- else if (GTK_IS_CSS_PATH_NODE (priv->cssnode))
- {
- G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
- gtk_style_context_invalidate (context);
- G_GNUC_END_IGNORE_DEPRECATIONS;
- }
+ gtk_css_node_invalidate (gtk_style_context_get_root (context), change);
}
/**
diff --git a/gtk/gtkstylecontextprivate.h b/gtk/gtkstylecontextprivate.h
index a520bf7..59abbc6 100644
--- a/gtk/gtkstylecontextprivate.h
+++ b/gtk/gtkstylecontextprivate.h
@@ -48,6 +48,8 @@ void _gtk_style_context_validate (GtkStyleContext *c
const GtkBitmask*parent_changes);
void _gtk_style_context_queue_invalidate (GtkStyleContext *context,
GtkCssChange change);
+void _gtk_style_context_invalidate_root_node (GtkStyleContext *context,
+ GtkCssChange change);
gboolean _gtk_style_context_check_region_name (const gchar *str);
gboolean _gtk_style_context_resolve_color (GtkStyleContext *context,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]