From bae97a4c6bcb1c82d4a5f296c3d428173e31c6e4 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 30 Jan 2015 23:32:50 -0500 Subject: [PATCH] image: Optimize non-resize changes When the image content is changed, only queue a resize if the size is actually changing, otherwise just a redraw. Suggested by Owen in https://bugzilla.gnome.org/show_bug.cgi?id=613833 --- gtk/gtkimage.c | 107 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 90 insertions(+), 17 deletions(-) diff --git a/gtk/gtkimage.c b/gtk/gtkimage.c index 5763f06915..d501aef7da 100644 --- a/gtk/gtkimage.c +++ b/gtk/gtkimage.c @@ -155,6 +155,9 @@ static void gtk_image_size_allocate (GtkWidget *widget, static void gtk_image_unmap (GtkWidget *widget); static void gtk_image_realize (GtkWidget *widget); static void gtk_image_unrealize (GtkWidget *widget); +static void gtk_image_get_preferred_size (GtkImage *image, + gint *width_out, + gint *height_out); static void gtk_image_get_preferred_width (GtkWidget *widget, gint *minimum, gint *natural); @@ -934,8 +937,8 @@ gtk_image_set_from_file (GtkImage *image, priv = image->priv; g_object_freeze_notify (G_OBJECT (image)); - - gtk_image_clear (image); + + gtk_image_reset (image); if (filename == NULL) { @@ -948,9 +951,7 @@ gtk_image_set_from_file (GtkImage *image, if (anim == NULL) { - gtk_image_set_from_icon_name (image, - "image-missing", - DEFAULT_ICON_SIZE); + gtk_image_set_from_icon_name (image, "image-missing", DEFAULT_ICON_SIZE); g_object_thaw_notify (G_OBJECT (image)); return; } @@ -971,7 +972,21 @@ gtk_image_set_from_file (GtkImage *image, g_object_unref (anim); priv->filename = g_strdup (filename); - + + if (gtk_widget_get_visible (GTK_WIDGET (image))) + { + gint width, height; + + gtk_image_get_preferred_size (image, &width, &height); + if (width != gtk_widget_get_allocated_width (GTK_WIDGET (image)) || + height != gtk_widget_get_allocated_height (GTK_WIDGET (image))) + gtk_widget_queue_resize (GTK_WIDGET (image)); + else + gtk_widget_queue_draw (GTK_WIDGET (image)); + } + + g_object_notify (G_OBJECT (image), "file"); + g_object_thaw_notify (G_OBJECT (image)); } @@ -1008,9 +1023,7 @@ gtk_image_set_from_resource (GtkImage *image, if (animation == NULL) { - gtk_image_set_from_icon_name (image, - "image-missing", - DEFAULT_ICON_SIZE); + gtk_image_set_from_icon_name (image, "image-missing", DEFAULT_ICON_SIZE); g_object_thaw_notify (G_OBJECT (image)); return; } @@ -1046,18 +1059,29 @@ gtk_image_set_from_pixbuf (GtkImage *image, GtkImagePrivate *priv; g_return_if_fail (GTK_IS_IMAGE (image)); - g_return_if_fail (pixbuf == NULL || - GDK_IS_PIXBUF (pixbuf)); + g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf)); priv = image->priv; g_object_freeze_notify (G_OBJECT (image)); - - gtk_image_clear (image); + + gtk_image_reset (image); if (pixbuf != NULL) _gtk_icon_helper_set_pixbuf (priv->icon_helper, pixbuf); + if (gtk_widget_get_visible (GTK_WIDGET (image))) + { + gint width, height; + + gtk_image_get_preferred_size (image, &width, &height); + if (width != gtk_widget_get_allocated_width (GTK_WIDGET (image)) || + height != gtk_widget_get_allocated_height (GTK_WIDGET (image))) + gtk_widget_queue_resize (GTK_WIDGET (image)); + else + gtk_widget_queue_draw (GTK_WIDGET (image)); + } + g_object_notify (G_OBJECT (image), "pixbuf"); g_object_thaw_notify (G_OBJECT (image)); @@ -1171,7 +1195,7 @@ gtk_image_set_from_animation (GtkImage *image, if (animation) g_object_ref (animation); - gtk_image_clear (image); + gtk_image_reset (image); if (animation != NULL) { @@ -1179,6 +1203,18 @@ gtk_image_set_from_animation (GtkImage *image, g_object_unref (animation); } + if (gtk_widget_get_visible (GTK_WIDGET (image))) + { + gint width, height; + + gtk_image_get_preferred_size (image, &width, &height); + if (width != gtk_widget_get_allocated_width (GTK_WIDGET (image)) || + height != gtk_widget_get_allocated_height (GTK_WIDGET (image))) + gtk_widget_queue_resize (GTK_WIDGET (image)); + else + gtk_widget_queue_draw (GTK_WIDGET (image)); + } + g_object_notify (G_OBJECT (image), "pixbuf-animation"); g_object_thaw_notify (G_OBJECT (image)); @@ -1209,7 +1245,8 @@ gtk_image_set_from_icon_name (GtkImage *image, g_object_freeze_notify (G_OBJECT (image)); new_name = g_strdup (icon_name); - gtk_image_clear (image); + + gtk_image_reset (image); if (new_name) { @@ -1217,6 +1254,18 @@ gtk_image_set_from_icon_name (GtkImage *image, g_free (new_name); } + if (gtk_widget_get_visible (GTK_WIDGET (image))) + { + gint width, height; + + gtk_image_get_preferred_size (image, &width, &height); + if (width != gtk_widget_get_allocated_width (GTK_WIDGET (image)) || + height != gtk_widget_get_allocated_height (GTK_WIDGET (image))) + gtk_widget_queue_resize (GTK_WIDGET (image)); + else + gtk_widget_queue_draw (GTK_WIDGET (image)); + } + g_object_notify (G_OBJECT (image), "icon-name"); g_object_notify (G_OBJECT (image), "icon-size"); @@ -1249,7 +1298,7 @@ gtk_image_set_from_gicon (GtkImage *image, if (icon) g_object_ref (icon); - gtk_image_clear (image); + gtk_image_reset (image); if (icon) { @@ -1257,6 +1306,18 @@ gtk_image_set_from_gicon (GtkImage *image, g_object_unref (icon); } + if (gtk_widget_get_visible (GTK_WIDGET (image))) + { + gint width, height; + + gtk_image_get_preferred_size (image, &width, &height); + if (width != gtk_widget_get_allocated_width (GTK_WIDGET (image)) || + height != gtk_widget_get_allocated_height (GTK_WIDGET (image))) + gtk_widget_queue_resize (GTK_WIDGET (image)); + else + gtk_widget_queue_draw (GTK_WIDGET (image)); + } + g_object_notify (G_OBJECT (image), "gicon"); g_object_notify (G_OBJECT (image), "icon-size"); @@ -1287,7 +1348,7 @@ gtk_image_set_from_surface (GtkImage *image, if (surface) cairo_surface_reference (surface); - gtk_image_clear (image); + gtk_image_reset (image); if (surface) { @@ -1295,6 +1356,18 @@ gtk_image_set_from_surface (GtkImage *image, cairo_surface_destroy (surface); } + if (gtk_widget_get_visible (GTK_WIDGET (image))) + { + gint width, height; + + gtk_image_get_preferred_size (image, &width, &height); + if (width != gtk_widget_get_allocated_width (GTK_WIDGET (image)) || + height != gtk_widget_get_allocated_height (GTK_WIDGET (image))) + gtk_widget_queue_resize (GTK_WIDGET (image)); + else + gtk_widget_queue_draw (GTK_WIDGET (image)); + } + g_object_notify (G_OBJECT (image), "surface"); g_object_thaw_notify (G_OBJECT (image));