diff options
-rw-r--r-- | gtk/gtkcontainer.c | 8 | ||||
-rw-r--r-- | gtk/gtkcssnode.c | 54 | ||||
-rw-r--r-- | gtk/gtkcssnodeprivate.h | 8 | ||||
-rw-r--r-- | gtk/gtkcsswidgetnode.c | 35 | ||||
-rw-r--r-- | gtk/gtkcsswidgetnodeprivate.h | 2 | ||||
-rw-r--r-- | gtk/gtkstylecontext.c | 56 | ||||
-rw-r--r-- | gtk/gtkstylecontextprivate.h | 3 | ||||
-rw-r--r-- | gtk/gtkwindow.c | 8 |
8 files changed, 97 insertions, 77 deletions
diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c index 0ec29c7923..186f89db08 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 891cf1f920..9ff83aa6f7 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 873ba67ba1..66ac247abb 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 e49a5609ed..66e08c1185 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 29286538dc..d34becc4b3 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 a141011f03..f6bf2d39c1 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 08b8ff63c6..8e616a07d4 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 60d66e5c47..32a3b2c1f7 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) |