widget: Pass a GtkCssStyleChange instead of a bitmask

This commit is contained in:
Benjamin Otte 2015-12-13 04:08:44 +01:00
parent c219bdbecc
commit 5cbbc62026
14 changed files with 81 additions and 104 deletions

View File

@ -41,18 +41,7 @@ gtk_css_path_node_invalidate (GtkCssNode *node)
GtkCssPathNode *path_node = GTK_CSS_PATH_NODE (node); GtkCssPathNode *path_node = GTK_CSS_PATH_NODE (node);
if (path_node->context) if (path_node->context)
{ gtk_style_context_validate (path_node->context, NULL);
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);
}
} }
gboolean gboolean

View File

@ -32,7 +32,7 @@ gtk_css_style_change_init (GtkCssStyleChange *change,
change->n_compared = 0; change->n_compared = 0;
change->affects = 0; change->affects = 0;
change->has_change = FALSE; change->changes = _gtk_bitmask_new ();
} }
void void
@ -40,6 +40,7 @@ gtk_css_style_change_finish (GtkCssStyleChange *change)
{ {
g_object_unref (change->old_style); g_object_unref (change->old_style);
g_object_unref (change->new_style); g_object_unref (change->new_style);
_gtk_bitmask_free (change->changes);
} }
GtkCssStyle * 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), 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))) 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->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++; change->n_compared++;
@ -76,7 +77,7 @@ gboolean
gtk_css_style_change_has_change (GtkCssStyleChange *change) gtk_css_style_change_has_change (GtkCssStyleChange *change)
{ {
do { do {
if (change->has_change) if (!_gtk_bitmask_is_empty (change->changes))
return TRUE; return TRUE;
} while (gtk_css_style_compare_next_value (change)); } while (gtk_css_style_compare_next_value (change));
@ -95,3 +96,13 @@ gtk_css_style_change_affects (GtkCssStyleChange *change,
return FALSE; 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);
}

View File

@ -31,7 +31,7 @@ struct _GtkCssStyleChange {
guint n_compared; guint n_compared;
GtkCssAffects affects; GtkCssAffects affects;
guint has_change :1; GtkBitmask *changes;
}; };
void gtk_css_style_change_init (GtkCssStyleChange *change, 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_has_change (GtkCssStyleChange *change);
gboolean gtk_css_style_change_affects (GtkCssStyleChange *change, gboolean gtk_css_style_change_affects (GtkCssStyleChange *change,
GtkCssAffects affects); GtkCssAffects affects);
gboolean gtk_css_style_change_changes_property (GtkCssStyleChange *change,
guint id);
G_END_DECLS G_END_DECLS

View File

@ -39,7 +39,7 @@ gtk_css_widget_node_finalize (GObject *object)
{ {
GtkCssWidgetNode *node = GTK_CSS_WIDGET_NODE (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); 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_widget_clear_path (node->widget);
GTK_CSS_NODE_CLASS (gtk_css_widget_node_parent_class)->style_changed (cssnode, change); 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 static gboolean
@ -123,18 +119,28 @@ static void
gtk_css_widget_node_validate (GtkCssNode *node) gtk_css_widget_node_validate (GtkCssNode *node)
{ {
GtkCssWidgetNode *widget_node = GTK_CSS_WIDGET_NODE (node); GtkCssWidgetNode *widget_node = GTK_CSS_WIDGET_NODE (node);
GtkStyleContext *context; GtkCssStyleChange change;
GtkCssStyle *style;
if (widget_node->widget == NULL) if (widget_node->widget == NULL)
return; return;
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); context = _gtk_widget_peek_style_context (widget_node->widget);
if (context) if (context)
gtk_style_context_validate (context, widget_node->accumulated_changes); gtk_style_context_validate (context, &change);
else else
_gtk_widget_style_context_invalidated (widget_node->widget); _gtk_widget_style_context_invalidated (widget_node->widget);
_gtk_bitmask_free (widget_node->accumulated_changes); g_object_unref (widget_node->last_updated_style);
widget_node->accumulated_changes = _gtk_bitmask_new (); widget_node->last_updated_style = g_object_ref (style);
}
gtk_css_style_change_finish (&change);
} }
typedef GtkWidgetPath * (* GetPathForChildFunc) (GtkContainer *, GtkWidget *); typedef GtkWidgetPath * (* GetPathForChildFunc) (GtkContainer *, GtkWidget *);
@ -287,7 +293,7 @@ gtk_css_widget_node_class_init (GtkCssWidgetNodeClass *klass)
static void static void
gtk_css_widget_node_init (GtkCssWidgetNode *node) 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 * GtkCssNode *

View File

@ -39,7 +39,7 @@ struct _GtkCssWidgetNode
GtkWidget *widget; GtkWidget *widget;
guint validate_cb_id; guint validate_cb_id;
GtkBitmask *accumulated_changes; GtkCssStyle *last_updated_style;
}; };
struct _GtkCssWidgetNodeClass struct _GtkCssWidgetNodeClass

View File

@ -1464,8 +1464,8 @@ gtk_file_chooser_button_style_updated (GtkWidget *widget)
/* We need to update the icon surface, but only in case /* We need to update the icon surface, but only in case
* the icon theme really changed. */ * the icon theme really changed. */
GtkStyleContext *context = gtk_widget_get_style_context (widget); GtkStyleContext *context = gtk_widget_get_style_context (widget);
const GtkBitmask *changes = _gtk_style_context_get_changes (context); GtkCssStyleChange *change = gtk_style_context_get_change (context);
if (!changes || _gtk_bitmask_get (changes, GTK_CSS_PROPERTY_ICON_THEME)) if (!change || gtk_css_style_change_changes_property (change, GTK_CSS_PROPERTY_ICON_THEME))
change_icon_theme (GTK_FILE_CHOOSER_BUTTON (widget)); change_icon_theme (GTK_FILE_CHOOSER_BUTTON (widget));
} }
} }

View File

@ -1888,18 +1888,14 @@ icon_theme_changed (GtkImage *image)
static void static void
gtk_image_style_updated (GtkWidget *widget) gtk_image_style_updated (GtkWidget *widget)
{ {
static GtkBitmask *affects_icon = NULL;
GtkImage *image = GTK_IMAGE (widget); GtkImage *image = GTK_IMAGE (widget);
GtkImagePrivate *priv = image->priv; GtkImagePrivate *priv = image->priv;
const GtkBitmask *changes; GtkCssStyleChange *change;
GTK_WIDGET_CLASS (gtk_image_parent_class)->style_updated (widget); GTK_WIDGET_CLASS (gtk_image_parent_class)->style_updated (widget);
if (G_UNLIKELY (affects_icon == NULL)) change = gtk_style_context_get_change (gtk_widget_get_style_context (widget));
affects_icon = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_ICON); if (change == NULL || gtk_css_style_change_affects (change, 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))
icon_theme_changed (image); icon_theme_changed (image);
priv->baseline_align = 0.0; priv->baseline_align = 0.0;
} }

View File

@ -4188,21 +4188,17 @@ gtk_label_state_flags_changed (GtkWidget *widget,
static void static void
gtk_label_style_updated (GtkWidget *widget) gtk_label_style_updated (GtkWidget *widget)
{ {
static GtkBitmask *affects_text_attrs = NULL;
GtkLabel *label = GTK_LABEL (widget); GtkLabel *label = GTK_LABEL (widget);
GtkLabelPrivate *priv = label->priv; GtkLabelPrivate *priv = label->priv;
GtkStyleContext *context; GtkStyleContext *context;
const GtkBitmask *changes;; GtkCssStyleChange *change;
if (G_UNLIKELY (affects_text_attrs == NULL))
affects_text_attrs = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_TEXT_ATTRS);
GTK_WIDGET_CLASS (gtk_label_parent_class)->style_updated (widget); GTK_WIDGET_CLASS (gtk_label_parent_class)->style_updated (widget);
context = gtk_widget_get_style_context (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)) (priv->select_info && priv->select_info->links))
gtk_label_update_layout_attributes (label); gtk_label_update_layout_attributes (label);
} }

View File

@ -152,7 +152,7 @@ struct _GtkStyleContextPrivate
GdkFrameClock *frame_clock; GdkFrameClock *frame_clock;
const GtkBitmask *invalidating_context; GtkCssStyleChange *invalidating_context;
}; };
enum { enum {
@ -2365,9 +2365,11 @@ gtk_style_context_pop_animatable_region (GtkStyleContext *context)
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
} }
static void static GtkCssStyleChange magic_number;
gtk_style_context_do_invalidate (GtkStyleContext *context,
const GtkBitmask *changes) void
gtk_style_context_validate (GtkStyleContext *context,
GtkCssStyleChange *change)
{ {
GtkStyleContextPrivate *priv; GtkStyleContextPrivate *priv;
@ -2379,7 +2381,10 @@ gtk_style_context_do_invalidate (GtkStyleContext *context,
if (priv->invalidating_context) if (priv->invalidating_context)
return; return;
priv->invalidating_context = changes; if (change)
priv->invalidating_context = change;
else
priv->invalidating_context = &magic_number;
g_signal_emit (context, signals[CHANGED], 0); g_signal_emit (context, signals[CHANGED], 0);
@ -2388,14 +2393,6 @@ gtk_style_context_do_invalidate (GtkStyleContext *context,
priv->invalidating_context = NULL; 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: * gtk_style_context_invalidate:
* @context: a #GtkStyleContext. * @context: a #GtkStyleContext.
@ -2411,18 +2408,11 @@ gtk_style_context_validate (GtkStyleContext *context,
void void
gtk_style_context_invalidate (GtkStyleContext *context) gtk_style_context_invalidate (GtkStyleContext *context)
{ {
GtkBitmask *changes;
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
gtk_style_context_clear_property_cache (context); gtk_style_context_clear_property_cache (context);
changes = _gtk_bitmask_new (); gtk_style_context_validate (context, NULL);
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);
} }
static gboolean 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 * @context: the context to query
* *
* Queries the context for the changes for the currently executing * Queries the context for the changes for the currently executing
* GtkStyleContext::invalidate signal. If no signal is currently * 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. * FIXME 4.0: Make this part of the signal.
* *
* Returns: %NULL or the currently invalidating changes * Returns: %NULL or the currently invalidating changes
**/ **/
const GtkBitmask * GtkCssStyleChange *
_gtk_style_context_get_changes (GtkStyleContext *context) gtk_style_context_get_change (GtkStyleContext *context)
{ {
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL); 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; return context->priv->invalidating_context;
} }

View File

@ -41,8 +41,8 @@ void gtk_style_context_save_named (GtkStyleContext *c
void gtk_style_context_save_to_node (GtkStyleContext *context, void gtk_style_context_save_to_node (GtkStyleContext *context,
GtkCssNode *node); GtkCssNode *node);
const GtkBitmask * GtkCssStyleChange *
_gtk_style_context_get_changes (GtkStyleContext *context); gtk_style_context_get_change (GtkStyleContext *context);
GtkCssStyle * gtk_style_context_lookup_style (GtkStyleContext *context); GtkCssStyle * gtk_style_context_lookup_style (GtkStyleContext *context);
GtkCssValue * _gtk_style_context_peek_property (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, GType widget_type,
GParamSpec *pspec); GParamSpec *pspec);
void gtk_style_context_validate (GtkStyleContext *context, void gtk_style_context_validate (GtkStyleContext *context,
const GtkBitmask*changes); GtkCssStyleChange *change);
void gtk_style_context_clear_property_cache (GtkStyleContext *context); void gtk_style_context_clear_property_cache (GtkStyleContext *context);
gboolean _gtk_style_context_check_region_name (const gchar *str); gboolean _gtk_style_context_check_region_name (const gchar *str);

View File

@ -4801,15 +4801,11 @@ text_window_set_padding (GtkTextView *text_view,
static void static void
gtk_text_view_style_updated (GtkWidget *widget) gtk_text_view_style_updated (GtkWidget *widget)
{ {
static GtkBitmask *affects_font = NULL;
GtkTextView *text_view; GtkTextView *text_view;
GtkTextViewPrivate *priv; GtkTextViewPrivate *priv;
PangoContext *ltr_context, *rtl_context; PangoContext *ltr_context, *rtl_context;
GtkStyleContext *style_context; GtkStyleContext *style_context;
const GtkBitmask *changes; GtkCssStyleChange *change;
if (G_UNLIKELY (affects_font == NULL))
affects_font = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_FONT);
text_view = GTK_TEXT_VIEW (widget); text_view = GTK_TEXT_VIEW (widget);
priv = text_view->priv; 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); GTK_WIDGET_CLASS (gtk_text_view_parent_class)->style_updated (widget);
style_context = gtk_widget_get_style_context (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) priv->layout && priv->layout->default_style)
{ {
gtk_text_view_set_attributes_from_style (text_view, gtk_text_view_set_attributes_from_style (text_view,

View File

@ -8708,15 +8708,11 @@ gtk_tree_view_grab_focus (GtkWidget *widget)
static void static void
gtk_tree_view_style_updated (GtkWidget *widget) gtk_tree_view_style_updated (GtkWidget *widget)
{ {
static GtkBitmask *affects_size = NULL;
GtkTreeView *tree_view = GTK_TREE_VIEW (widget); GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
GList *list; GList *list;
GtkTreeViewColumn *column; GtkTreeViewColumn *column;
GtkStyleContext *style_context; GtkStyleContext *style_context;
const GtkBitmask *changes; GtkCssStyleChange *change;
if (G_UNLIKELY (affects_size == NULL))
affects_size = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_SIZE | GTK_CSS_AFFECTS_CLIP);
GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->style_updated (widget); 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); 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) for (list = tree_view->priv->columns; list; list = list->next)
{ {

View File

@ -8250,24 +8250,15 @@ gtk_widget_real_style_updated (GtkWidget *widget)
if (widget->priv->context) 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) if (widget->priv->anchored)
{ {
static GtkBitmask *affects_size, *affects_redraw, *affects_allocate; if (change == NULL || gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_SIZE))
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))
gtk_widget_queue_resize (widget); 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); 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); gtk_widget_queue_draw (widget);
} }
} }

View File

@ -8729,11 +8729,11 @@ gtk_window_state_flags_changed (GtkWidget *widget,
static void static void
gtk_window_style_updated (GtkWidget *widget) 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); 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)); update_themed_icon (GTK_WINDOW (widget));
} }