From 5cbbc62026c412cb9e4c77db4e01f438c7de3fc7 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 13 Dec 2015 04:08:44 +0100 Subject: [PATCH] widget: Pass a GtkCssStyleChange instead of a bitmask --- gtk/gtkcsspathnode.c | 13 +--------- gtk/gtkcssstylechange.c | 17 ++++++++++--- gtk/gtkcssstylechangeprivate.h | 4 +++- gtk/gtkcsswidgetnode.c | 34 +++++++++++++++----------- gtk/gtkcsswidgetnodeprivate.h | 2 +- gtk/gtkfilechooserbutton.c | 4 ++-- gtk/gtkimage.c | 10 +++----- gtk/gtklabel.c | 10 +++----- gtk/gtkstylecontext.c | 44 +++++++++++++++------------------- gtk/gtkstylecontextprivate.h | 6 ++--- gtk/gtktextview.c | 10 +++----- gtk/gtktreeview.c | 10 +++----- gtk/gtkwidget.c | 17 ++++--------- gtk/gtkwindow.c | 4 ++-- 14 files changed, 81 insertions(+), 104 deletions(-) diff --git a/gtk/gtkcsspathnode.c b/gtk/gtkcsspathnode.c index fecb4552a9..0f2d14adb3 100644 --- a/gtk/gtkcsspathnode.c +++ b/gtk/gtkcsspathnode.c @@ -41,18 +41,7 @@ gtk_css_path_node_invalidate (GtkCssNode *node) GtkCssPathNode *path_node = GTK_CSS_PATH_NODE (node); if (path_node->context) - { - GtkBitmask *changes; - - changes = _gtk_bitmask_new (); - changes = _gtk_bitmask_invert_range (changes, - 0, - _gtk_css_style_property_get_n_properties ()); - - gtk_style_context_validate (path_node->context, changes); - - _gtk_bitmask_free (changes); - } + gtk_style_context_validate (path_node->context, NULL); } gboolean diff --git a/gtk/gtkcssstylechange.c b/gtk/gtkcssstylechange.c index 49cbc1cf13..50eac153e1 100644 --- a/gtk/gtkcssstylechange.c +++ b/gtk/gtkcssstylechange.c @@ -32,7 +32,7 @@ gtk_css_style_change_init (GtkCssStyleChange *change, change->n_compared = 0; change->affects = 0; - change->has_change = FALSE; + change->changes = _gtk_bitmask_new (); } void @@ -40,6 +40,7 @@ gtk_css_style_change_finish (GtkCssStyleChange *change) { g_object_unref (change->old_style); g_object_unref (change->new_style); + _gtk_bitmask_free (change->changes); } GtkCssStyle * @@ -63,8 +64,8 @@ gtk_css_style_compare_next_value (GtkCssStyleChange *change) if (!_gtk_css_value_equal (gtk_css_style_get_value (change->old_style, change->n_compared), gtk_css_style_get_value (change->new_style, change->n_compared))) { - change->has_change = TRUE; change->affects |= _gtk_css_style_property_get_affects (_gtk_css_style_property_lookup_by_id (change->n_compared)); + change->changes = _gtk_bitmask_set (change->changes, change->n_compared, TRUE); } change->n_compared++; @@ -76,7 +77,7 @@ gboolean gtk_css_style_change_has_change (GtkCssStyleChange *change) { do { - if (change->has_change) + if (!_gtk_bitmask_is_empty (change->changes)) return TRUE; } while (gtk_css_style_compare_next_value (change)); @@ -95,3 +96,13 @@ gtk_css_style_change_affects (GtkCssStyleChange *change, return FALSE; } +gboolean +gtk_css_style_change_changes_property (GtkCssStyleChange *change, + guint id) +{ + while (change->n_compared <= id) + gtk_css_style_compare_next_value (change); + + return _gtk_bitmask_get (change->changes, id); +} + diff --git a/gtk/gtkcssstylechangeprivate.h b/gtk/gtkcssstylechangeprivate.h index 2fb2aa3c70..078dee0944 100644 --- a/gtk/gtkcssstylechangeprivate.h +++ b/gtk/gtkcssstylechangeprivate.h @@ -31,7 +31,7 @@ struct _GtkCssStyleChange { guint n_compared; GtkCssAffects affects; - guint has_change :1; + GtkBitmask *changes; }; void gtk_css_style_change_init (GtkCssStyleChange *change, @@ -45,6 +45,8 @@ GtkCssStyle * gtk_css_style_change_get_new_style (GtkCssStyleChange gboolean gtk_css_style_change_has_change (GtkCssStyleChange *change); gboolean gtk_css_style_change_affects (GtkCssStyleChange *change, GtkCssAffects affects); +gboolean gtk_css_style_change_changes_property (GtkCssStyleChange *change, + guint id); G_END_DECLS diff --git a/gtk/gtkcsswidgetnode.c b/gtk/gtkcsswidgetnode.c index e6dc7019a6..614ce05465 100644 --- a/gtk/gtkcsswidgetnode.c +++ b/gtk/gtkcsswidgetnode.c @@ -39,7 +39,7 @@ gtk_css_widget_node_finalize (GObject *object) { GtkCssWidgetNode *node = GTK_CSS_WIDGET_NODE (object); - _gtk_bitmask_free (node->accumulated_changes); + g_object_unref (node->last_updated_style); G_OBJECT_CLASS (gtk_css_widget_node_parent_class)->finalize (object); } @@ -56,10 +56,6 @@ gtk_css_widget_node_style_changed (GtkCssNode *cssnode, gtk_widget_clear_path (node->widget); GTK_CSS_NODE_CLASS (gtk_css_widget_node_parent_class)->style_changed (cssnode, change); - - node->accumulated_changes = gtk_css_style_add_difference (node->accumulated_changes, - gtk_css_style_change_get_new_style (change), - gtk_css_style_change_get_old_style (change)); } static gboolean @@ -123,18 +119,28 @@ static void gtk_css_widget_node_validate (GtkCssNode *node) { GtkCssWidgetNode *widget_node = GTK_CSS_WIDGET_NODE (node); - GtkStyleContext *context; + GtkCssStyleChange change; + GtkCssStyle *style; if (widget_node->widget == NULL) return; - context = _gtk_widget_peek_style_context (widget_node->widget); - if (context) - gtk_style_context_validate (context, widget_node->accumulated_changes); - else - _gtk_widget_style_context_invalidated (widget_node->widget); - _gtk_bitmask_free (widget_node->accumulated_changes); - widget_node->accumulated_changes = _gtk_bitmask_new (); + style = gtk_css_node_get_style (node); + + gtk_css_style_change_init (&change, widget_node->last_updated_style, style); + if (gtk_css_style_change_has_change (&change)) + { + GtkStyleContext *context; + + context = _gtk_widget_peek_style_context (widget_node->widget); + if (context) + gtk_style_context_validate (context, &change); + else + _gtk_widget_style_context_invalidated (widget_node->widget); + g_object_unref (widget_node->last_updated_style); + widget_node->last_updated_style = g_object_ref (style); + } + gtk_css_style_change_finish (&change); } typedef GtkWidgetPath * (* GetPathForChildFunc) (GtkContainer *, GtkWidget *); @@ -287,7 +293,7 @@ gtk_css_widget_node_class_init (GtkCssWidgetNodeClass *klass) static void gtk_css_widget_node_init (GtkCssWidgetNode *node) { - node->accumulated_changes = _gtk_bitmask_new (); + node->last_updated_style = g_object_ref (gtk_css_static_style_get_default ()); } GtkCssNode * diff --git a/gtk/gtkcsswidgetnodeprivate.h b/gtk/gtkcsswidgetnodeprivate.h index 39dc20067e..bd39dd1ba1 100644 --- a/gtk/gtkcsswidgetnodeprivate.h +++ b/gtk/gtkcsswidgetnodeprivate.h @@ -39,7 +39,7 @@ struct _GtkCssWidgetNode GtkWidget *widget; guint validate_cb_id; - GtkBitmask *accumulated_changes; + GtkCssStyle *last_updated_style; }; struct _GtkCssWidgetNodeClass diff --git a/gtk/gtkfilechooserbutton.c b/gtk/gtkfilechooserbutton.c index 8ac5b9e36d..dd631bbc33 100644 --- a/gtk/gtkfilechooserbutton.c +++ b/gtk/gtkfilechooserbutton.c @@ -1464,8 +1464,8 @@ gtk_file_chooser_button_style_updated (GtkWidget *widget) /* We need to update the icon surface, but only in case * the icon theme really changed. */ GtkStyleContext *context = gtk_widget_get_style_context (widget); - const GtkBitmask *changes = _gtk_style_context_get_changes (context); - if (!changes || _gtk_bitmask_get (changes, GTK_CSS_PROPERTY_ICON_THEME)) + GtkCssStyleChange *change = gtk_style_context_get_change (context); + if (!change || gtk_css_style_change_changes_property (change, GTK_CSS_PROPERTY_ICON_THEME)) change_icon_theme (GTK_FILE_CHOOSER_BUTTON (widget)); } } diff --git a/gtk/gtkimage.c b/gtk/gtkimage.c index 7494f413d7..95d2d2d866 100644 --- a/gtk/gtkimage.c +++ b/gtk/gtkimage.c @@ -1888,18 +1888,14 @@ icon_theme_changed (GtkImage *image) static void gtk_image_style_updated (GtkWidget *widget) { - static GtkBitmask *affects_icon = NULL; GtkImage *image = GTK_IMAGE (widget); GtkImagePrivate *priv = image->priv; - const GtkBitmask *changes; + GtkCssStyleChange *change; GTK_WIDGET_CLASS (gtk_image_parent_class)->style_updated (widget); - if (G_UNLIKELY (affects_icon == NULL)) - affects_icon = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_ICON); - - changes = _gtk_style_context_get_changes (gtk_widget_get_style_context (widget)); - if (changes == NULL || _gtk_bitmask_intersects (changes, affects_icon)) + change = gtk_style_context_get_change (gtk_widget_get_style_context (widget)); + if (change == NULL || gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON)) icon_theme_changed (image); priv->baseline_align = 0.0; } diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index fd1adf355f..5f2df4520c 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -4188,21 +4188,17 @@ gtk_label_state_flags_changed (GtkWidget *widget, static void gtk_label_style_updated (GtkWidget *widget) { - static GtkBitmask *affects_text_attrs = NULL; GtkLabel *label = GTK_LABEL (widget); GtkLabelPrivate *priv = label->priv; GtkStyleContext *context; - const GtkBitmask *changes;; - - if (G_UNLIKELY (affects_text_attrs == NULL)) - affects_text_attrs = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_TEXT_ATTRS); + GtkCssStyleChange *change; GTK_WIDGET_CLASS (gtk_label_parent_class)->style_updated (widget); context = gtk_widget_get_style_context (widget); - changes = _gtk_style_context_get_changes (context); + change = gtk_style_context_get_change (context); - if (changes == NULL || _gtk_bitmask_intersects (changes, affects_text_attrs) || + if (change == NULL || gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_TEXT_ATTRS) || (priv->select_info && priv->select_info->links)) gtk_label_update_layout_attributes (label); } diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c index ddf4090f21..b4a967e81a 100644 --- a/gtk/gtkstylecontext.c +++ b/gtk/gtkstylecontext.c @@ -152,7 +152,7 @@ struct _GtkStyleContextPrivate GdkFrameClock *frame_clock; - const GtkBitmask *invalidating_context; + GtkCssStyleChange *invalidating_context; }; enum { @@ -2365,9 +2365,11 @@ gtk_style_context_pop_animatable_region (GtkStyleContext *context) g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); } -static void -gtk_style_context_do_invalidate (GtkStyleContext *context, - const GtkBitmask *changes) +static GtkCssStyleChange magic_number; + +void +gtk_style_context_validate (GtkStyleContext *context, + GtkCssStyleChange *change) { GtkStyleContextPrivate *priv; @@ -2379,7 +2381,10 @@ gtk_style_context_do_invalidate (GtkStyleContext *context, if (priv->invalidating_context) return; - priv->invalidating_context = changes; + if (change) + priv->invalidating_context = change; + else + priv->invalidating_context = &magic_number; g_signal_emit (context, signals[CHANGED], 0); @@ -2388,14 +2393,6 @@ gtk_style_context_do_invalidate (GtkStyleContext *context, priv->invalidating_context = NULL; } -void -gtk_style_context_validate (GtkStyleContext *context, - const GtkBitmask *changes) -{ - if (!_gtk_bitmask_is_empty (changes)) - gtk_style_context_do_invalidate (context, changes); -} - /** * gtk_style_context_invalidate: * @context: a #GtkStyleContext. @@ -2411,18 +2408,11 @@ gtk_style_context_validate (GtkStyleContext *context, void gtk_style_context_invalidate (GtkStyleContext *context) { - GtkBitmask *changes; - g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); gtk_style_context_clear_property_cache (context); - changes = _gtk_bitmask_new (); - changes = _gtk_bitmask_invert_range (changes, - 0, - _gtk_css_style_property_get_n_properties ()); - gtk_style_context_do_invalidate (context, changes); - _gtk_bitmask_free (changes); + gtk_style_context_validate (context, NULL); } static gboolean @@ -3015,22 +3005,26 @@ gtk_draw_insertion_cursor (GtkWidget *widget, } /** - * _gtk_style_context_get_changes: + * gtk_style_context_get_change: * @context: the context to query * * Queries the context for the changes for the currently executing * GtkStyleContext::invalidate signal. If no signal is currently - * emitted, this function returns %NULL. + * emitted or the signal has not been triggered by a CssNode + * invalidation, this function returns %NULL. * * FIXME 4.0: Make this part of the signal. * * Returns: %NULL or the currently invalidating changes **/ -const GtkBitmask * -_gtk_style_context_get_changes (GtkStyleContext *context) +GtkCssStyleChange * +gtk_style_context_get_change (GtkStyleContext *context) { g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL); + if (context->priv->invalidating_context == &magic_number) + return NULL; + return context->priv->invalidating_context; } diff --git a/gtk/gtkstylecontextprivate.h b/gtk/gtkstylecontextprivate.h index 7ff6aac579..31f71277e8 100644 --- a/gtk/gtkstylecontextprivate.h +++ b/gtk/gtkstylecontextprivate.h @@ -41,8 +41,8 @@ void gtk_style_context_save_named (GtkStyleContext *c void gtk_style_context_save_to_node (GtkStyleContext *context, GtkCssNode *node); -const GtkBitmask * - _gtk_style_context_get_changes (GtkStyleContext *context); +GtkCssStyleChange * + gtk_style_context_get_change (GtkStyleContext *context); GtkCssStyle * gtk_style_context_lookup_style (GtkStyleContext *context); GtkCssValue * _gtk_style_context_peek_property (GtkStyleContext *context, @@ -51,7 +51,7 @@ const GValue * _gtk_style_context_peek_style_property (GtkStyleContext *c GType widget_type, GParamSpec *pspec); void gtk_style_context_validate (GtkStyleContext *context, - const GtkBitmask*changes); + GtkCssStyleChange *change); void gtk_style_context_clear_property_cache (GtkStyleContext *context); gboolean _gtk_style_context_check_region_name (const gchar *str); diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index d6c4aa1c57..801a28fd56 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -4801,15 +4801,11 @@ text_window_set_padding (GtkTextView *text_view, static void gtk_text_view_style_updated (GtkWidget *widget) { - static GtkBitmask *affects_font = NULL; GtkTextView *text_view; GtkTextViewPrivate *priv; PangoContext *ltr_context, *rtl_context; GtkStyleContext *style_context; - const GtkBitmask *changes; - - if (G_UNLIKELY (affects_font == NULL)) - affects_font = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_FONT); + GtkCssStyleChange *change; text_view = GTK_TEXT_VIEW (widget); priv = text_view->priv; @@ -4817,9 +4813,9 @@ gtk_text_view_style_updated (GtkWidget *widget) GTK_WIDGET_CLASS (gtk_text_view_parent_class)->style_updated (widget); style_context = gtk_widget_get_style_context (widget); - changes = _gtk_style_context_get_changes (style_context); + change = gtk_style_context_get_change (style_context); - if ((changes == NULL || _gtk_bitmask_intersects (changes, affects_font)) && + if ((change == NULL || gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_FONT)) && priv->layout && priv->layout->default_style) { gtk_text_view_set_attributes_from_style (text_view, diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c index a4bd8aaadb..c14a4fbe41 100644 --- a/gtk/gtktreeview.c +++ b/gtk/gtktreeview.c @@ -8708,15 +8708,11 @@ gtk_tree_view_grab_focus (GtkWidget *widget) static void gtk_tree_view_style_updated (GtkWidget *widget) { - static GtkBitmask *affects_size = NULL; GtkTreeView *tree_view = GTK_TREE_VIEW (widget); GList *list; GtkTreeViewColumn *column; GtkStyleContext *style_context; - const GtkBitmask *changes; - - if (G_UNLIKELY (affects_size == NULL)) - affects_size = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_SIZE | GTK_CSS_AFFECTS_CLIP); + GtkCssStyleChange *change; GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->style_updated (widget); @@ -8727,9 +8723,9 @@ gtk_tree_view_style_updated (GtkWidget *widget) } style_context = gtk_widget_get_style_context (widget); - changes = _gtk_style_context_get_changes (style_context); + change = gtk_style_context_get_change (style_context); - if (changes == NULL || _gtk_bitmask_intersects (changes, affects_size)) + if (change == NULL || gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_SIZE | GTK_CSS_AFFECTS_CLIP)) { for (list = tree_view->priv->columns; list; list = list->next) { diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 7656bcd8a9..e8b30f0773 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -8250,24 +8250,15 @@ gtk_widget_real_style_updated (GtkWidget *widget) if (widget->priv->context) { - const GtkBitmask *changes = _gtk_style_context_get_changes (widget->priv->context); + GtkCssStyleChange *change = gtk_style_context_get_change (widget->priv->context); if (widget->priv->anchored) { - static GtkBitmask *affects_size, *affects_redraw, *affects_allocate; - - if (G_UNLIKELY (affects_size == NULL)) - { - affects_size = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_SIZE); - affects_allocate = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_CLIP); - affects_redraw = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_REDRAW); - } - - if (changes == NULL || _gtk_bitmask_intersects (changes, affects_size)) + if (change == NULL || gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_SIZE)) gtk_widget_queue_resize (widget); - else if (_gtk_bitmask_intersects (changes, affects_allocate)) + else if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_CLIP)) gtk_widget_queue_allocate (widget); - else if (_gtk_bitmask_intersects (changes, affects_redraw)) + else if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_REDRAW)) gtk_widget_queue_draw (widget); } } diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 97c6e1f0c3..014bbf81ad 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -8729,11 +8729,11 @@ gtk_window_state_flags_changed (GtkWidget *widget, static void gtk_window_style_updated (GtkWidget *widget) { - const GtkBitmask *changes = _gtk_style_context_get_changes (gtk_widget_get_style_context (widget)); + GtkCssStyleChange *change = gtk_style_context_get_change (gtk_widget_get_style_context (widget)); GTK_WIDGET_CLASS (gtk_window_parent_class)->style_updated (widget); - if (changes == NULL || _gtk_bitmask_get (changes, GTK_CSS_PROPERTY_ICON_THEME)) + if (change == NULL || gtk_css_style_change_changes_property (change, GTK_CSS_PROPERTY_ICON_THEME)) update_themed_icon (GTK_WINDOW (widget)); }