cssnode: Handle invalidation

Handle invalidation of node inside the CssNode code, don't do it in the
stylecontext.
This commit is contained in:
Benjamin Otte 2015-01-25 02:40:40 +01:00
parent d79a44c1af
commit 7bafb63ec3
8 changed files with 123 additions and 78 deletions

View File

@ -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)
{

View File

@ -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);

View File

@ -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 *

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}
/**
@ -3007,28 +2977,24 @@ _gtk_style_context_validate (GtkStyleContext *context,
_gtk_bitmask_free (changes);
}
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);
}
/**

View File

@ -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,