From b79a187d47ee5c45952fab60c141fcaed7e05ef6 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Fri, 11 Dec 2015 15:12:19 +0100 Subject: [PATCH] iconhelper: Handle invalidation When CSS, direction or scale factor change, handle the invalidation inside the iconhelper. This way the widgets using them don't have to. --- gtk/gtkentry.c | 18 -------- gtk/gtkiconhelper.c | 87 ++++++++++++++++++++------------------ gtk/gtkiconhelperprivate.h | 1 - gtk/gtkimage.c | 32 -------------- 4 files changed, 47 insertions(+), 91 deletions(-) diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 411abcad07..7083adad25 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -5231,22 +5231,6 @@ gtk_entry_get_selection_bounds (GtkEditable *editable, return (priv->selection_bound != priv->current_pos); } -static void -icon_theme_changed (GtkEntry *entry) -{ - GtkEntryPrivate *priv = entry->priv; - gint i; - - for (i = 0; i < MAX_ICONS; i++) - { - EntryIconInfo *icon_info = priv->icons[i]; - if (icon_info != NULL) - _gtk_icon_helper_invalidate (icon_info->icon_helper); - } - - gtk_widget_queue_draw (GTK_WIDGET (entry)); -} - static void gtk_entry_update_cached_style_values (GtkEntry *entry) { @@ -5272,8 +5256,6 @@ gtk_entry_style_updated (GtkWidget *widget) GTK_WIDGET_CLASS (gtk_entry_parent_class)->style_updated (widget); gtk_entry_update_cached_style_values (entry); - - icon_theme_changed (entry); } /* GtkCellEditable method implementations diff --git a/gtk/gtkiconhelper.c b/gtk/gtkiconhelper.c index 1dcd607332..bc82ee0a43 100644 --- a/gtk/gtkiconhelper.c +++ b/gtk/gtkiconhelper.c @@ -27,6 +27,7 @@ #include "gtkcssiconthemevalueprivate.h" #include "gtkcssnodeprivate.h" #include "gtkcssstyleprivate.h" +#include "gtkcssstylepropertyprivate.h" #include "gtkiconthemeprivate.h" #include "gtkrendericonprivate.h" #include "deprecated/gtkiconfactoryprivate.h" @@ -42,11 +43,20 @@ struct _GtkIconHelperPrivate { guint force_scale_pixbuf : 1; cairo_surface_t *rendered_surface; - gint last_surface_scale; }; G_DEFINE_TYPE_WITH_PRIVATE (GtkIconHelper, gtk_icon_helper, GTK_TYPE_CSS_GADGET) +static void +gtk_icon_helper_invalidate (GtkIconHelper *self) +{ + if (self->priv->rendered_surface != NULL) + { + cairo_surface_destroy (self->priv->rendered_surface); + self->priv->rendered_surface = NULL; + } +} + static void gtk_icon_helper_take_definition (GtkIconHelper *self, GtkImageDefinition *def) @@ -59,7 +69,7 @@ gtk_icon_helper_take_definition (GtkIconHelper *self, gtk_image_definition_unref (self->priv->def); self->priv->def = def; - _gtk_icon_helper_invalidate (self); + gtk_icon_helper_invalidate (self); } void @@ -71,23 +81,40 @@ _gtk_icon_helper_clear (GtkIconHelper *self) self->priv->def = gtk_image_definition_new_empty (); self->priv->icon_size = GTK_ICON_SIZE_INVALID; - self->priv->last_surface_scale = 0; } -void -_gtk_icon_helper_invalidate (GtkIconHelper *self) +static void +gtk_icon_helper_style_changed (GtkCssGadget *gadget, + GtkCssStyleChange *change) { - if (self->priv->rendered_surface != NULL) - { - cairo_surface_destroy (self->priv->rendered_surface); - self->priv->rendered_surface = NULL; - } + if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON)) + gtk_icon_helper_invalidate (GTK_ICON_HELPER (gadget)); + + GTK_CSS_GADGET_CLASS (gtk_icon_helper_parent_class)->style_changed (gadget, change); +} + +static void +gtk_icon_helper_constructed (GObject *object) +{ + GtkIconHelper *self = GTK_ICON_HELPER (object); + GtkWidget *widget; + + widget = gtk_css_gadget_get_owner (GTK_CSS_GADGET (self)); + + g_signal_connect_swapped (widget, "direction-changed", G_CALLBACK (gtk_icon_helper_invalidate), self); + g_signal_connect_swapped (widget, "notify::scale-factor", G_CALLBACK (gtk_icon_helper_invalidate), self); + + G_OBJECT_CLASS (gtk_icon_helper_parent_class)->constructed (object); } static void gtk_icon_helper_finalize (GObject *object) { GtkIconHelper *self = GTK_ICON_HELPER (object); + GtkWidget *widget; + + widget = gtk_css_gadget_get_owner (GTK_CSS_GADGET (self)); + g_signal_handlers_disconnect_by_func (widget, G_CALLBACK (gtk_icon_helper_invalidate), self); _gtk_icon_helper_clear (self); gtk_image_definition_unref (self->priv->def); @@ -98,10 +125,13 @@ gtk_icon_helper_finalize (GObject *object) static void gtk_icon_helper_class_init (GtkIconHelperClass *klass) { - GObjectClass *oclass; + GtkCssGadgetClass *gadget_class = GTK_CSS_GADGET_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + gadget_class->style_changed = gtk_icon_helper_style_changed; - oclass = G_OBJECT_CLASS (klass); - oclass->finalize = gtk_icon_helper_finalize; + object_class->constructed = gtk_icon_helper_constructed; + object_class->finalize = gtk_icon_helper_finalize; } static void @@ -209,26 +239,6 @@ get_surface_size (GtkIconHelper *self, cairo_destroy (cr); } -static gboolean -check_invalidate_surface (GtkIconHelper *self) -{ - int scale; - - scale = gtk_widget_get_scale_factor (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))); - - if ((self->priv->rendered_surface != NULL) && - (self->priv->last_surface_scale == scale)) - return FALSE; - - self->priv->last_surface_scale = scale; - - if (self->priv->rendered_surface) - cairo_surface_destroy (self->priv->rendered_surface); - self->priv->rendered_surface = NULL; - - return TRUE; -} - static cairo_surface_t * ensure_surface_from_surface (GtkIconHelper *self, cairo_surface_t *orig_surface) @@ -503,9 +513,6 @@ gtk_icon_helper_ensure_surface (GtkIconHelper *self) { int scale; - if (!check_invalidate_surface (self)) - return; - scale = gtk_widget_get_scale_factor (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))); self->priv->rendered_surface = gtk_icon_helper_load_surface (self, scale); @@ -659,7 +666,7 @@ _gtk_icon_helper_set_icon_size (GtkIconHelper *self, if (self->priv->icon_size != icon_size) { self->priv->icon_size = icon_size; - _gtk_icon_helper_invalidate (self); + gtk_icon_helper_invalidate (self); return TRUE; } return FALSE; @@ -672,7 +679,7 @@ _gtk_icon_helper_set_pixel_size (GtkIconHelper *self, if (self->priv->pixel_size != pixel_size) { self->priv->pixel_size = pixel_size; - _gtk_icon_helper_invalidate (self); + gtk_icon_helper_invalidate (self); return TRUE; } return FALSE; @@ -685,7 +692,7 @@ _gtk_icon_helper_set_use_fallback (GtkIconHelper *self, if (self->priv->use_fallback != use_fallback) { self->priv->use_fallback = use_fallback; - _gtk_icon_helper_invalidate (self); + gtk_icon_helper_invalidate (self); return TRUE; } return FALSE; @@ -812,7 +819,7 @@ _gtk_icon_helper_set_force_scale_pixbuf (GtkIconHelper *self, if (self->priv->force_scale_pixbuf != force_scale) { self->priv->force_scale_pixbuf = force_scale; - _gtk_icon_helper_invalidate (self); + gtk_icon_helper_invalidate (self); } } diff --git a/gtk/gtkiconhelperprivate.h b/gtk/gtkiconhelperprivate.h index 1f869d42a7..fc3acf0c7b 100644 --- a/gtk/gtkiconhelperprivate.h +++ b/gtk/gtkiconhelperprivate.h @@ -72,7 +72,6 @@ GtkIconHelper *gtk_icon_helper_new (GtkCssNode *node, GtkWidget *owner); void _gtk_icon_helper_clear (GtkIconHelper *self); -void _gtk_icon_helper_invalidate (GtkIconHelper *self); gboolean _gtk_icon_helper_get_is_empty (GtkIconHelper *self); diff --git a/gtk/gtkimage.c b/gtk/gtkimage.c index b8530b201f..c9b454c737 100644 --- a/gtk/gtkimage.c +++ b/gtk/gtkimage.c @@ -191,8 +191,6 @@ static gboolean gtk_image_render_contents (GtkCssGadget *gadget, gpointer data); static void gtk_image_style_updated (GtkWidget *widget); -static void gtk_image_screen_changed (GtkWidget *widget, - GdkScreen *prev_screen); static void gtk_image_finalize (GObject *object); static void gtk_image_reset (GtkImage *image); @@ -205,8 +203,6 @@ static void gtk_image_get_property (GObject *object, GValue *value, GParamSpec *pspec); -static void icon_theme_changed (GtkImage *image); - enum { PROP_0, @@ -253,7 +249,6 @@ gtk_image_class_init (GtkImageClass *class) widget_class->unmap = gtk_image_unmap; widget_class->unrealize = gtk_image_unrealize; widget_class->style_updated = gtk_image_style_updated; - widget_class->screen_changed = gtk_image_screen_changed; image_props[PROP_PIXBUF] = g_param_spec_object ("pixbuf", @@ -1917,44 +1912,17 @@ gtk_image_get_preferred_height_and_baseline_for_width (GtkWidget *widget, minimum_baseline, natural_baseline); } -static void -icon_theme_changed (GtkImage *image) -{ - GtkImagePrivate *priv = image->priv; - - _gtk_icon_helper_invalidate (priv->icon_helper); - gtk_widget_queue_draw (GTK_WIDGET (image)); -} - static void gtk_image_style_updated (GtkWidget *widget) { GtkImage *image = GTK_IMAGE (widget); GtkImagePrivate *priv = image->priv; - GtkCssStyleChange *change; GTK_WIDGET_CLASS (gtk_image_parent_class)->style_updated (widget); - 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; } -static void -gtk_image_screen_changed (GtkWidget *widget, - GdkScreen *prev_screen) -{ - GtkImage *image; - - image = GTK_IMAGE (widget); - - if (GTK_WIDGET_CLASS (gtk_image_parent_class)->screen_changed) - GTK_WIDGET_CLASS (gtk_image_parent_class)->screen_changed (widget, prev_screen); - - icon_theme_changed (image); -} - /** * gtk_image_set_pixel_size: * @image: a #GtkImage