[gimp] Bug 730862 - Preview frozen while dragging selection tools...
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Bug 730862 - Preview frozen while dragging selection tools...
- Date: Fri, 30 May 2014 17:42:35 +0000 (UTC)
commit bb8d65bcee39b110168c4649a6325a125776a095
Author: Michael Natterer <mitch gimp org>
Date: Fri May 30 19:38:17 2014 +0200
Bug 730862 - Preview frozen while dragging selection tools...
...(crop, rectangle, etc) in large image zoomed-to-fit
Introduce a hash of the last 16 used icons in GimpStatusbar, it was
loading icons at a very high frequency. Found by Massimo.
app/display/gimpstatusbar.c | 92 ++++++++++++++++++++++++++++++++++++++++---
app/display/gimpstatusbar.h | 1 +
2 files changed, 87 insertions(+), 6 deletions(-)
---
diff --git a/app/display/gimpstatusbar.c b/app/display/gimpstatusbar.c
index 5f4ffd0..f568d53 100644
--- a/app/display/gimpstatusbar.c
+++ b/app/display/gimpstatusbar.c
@@ -73,6 +73,11 @@ static void gimp_statusbar_progress_iface_init (GimpProgressInterface *iface
static void gimp_statusbar_dispose (GObject *object);
static void gimp_statusbar_finalize (GObject *object);
+static void gimp_statusbar_screen_changed (GtkWidget *widget,
+ GdkScreen *previous);
+static void gimp_statusbar_style_set (GtkWidget *widget,
+ GtkStyle *prev_style);
+
static void gimp_statusbar_hbox_size_request (GtkWidget *widget,
GtkRequisition *requisition,
GimpStatusbar *statusbar);
@@ -122,6 +127,9 @@ static void gimp_statusbar_msg_free (GimpStatusbarMsg *msg);
static gchar * gimp_statusbar_vprintf (const gchar *format,
va_list args) G_GNUC_PRINTF (1, 0);
+static GdkPixbuf * gimp_statusbar_load_icon (GimpStatusbar *statusbar,
+ const gchar *icon_name);
+
G_DEFINE_TYPE_WITH_CODE (GimpStatusbar, gimp_statusbar, GTK_TYPE_STATUSBAR,
G_IMPLEMENT_INTERFACE (GIMP_TYPE_PROGRESS,
@@ -133,10 +141,14 @@ G_DEFINE_TYPE_WITH_CODE (GimpStatusbar, gimp_statusbar, GTK_TYPE_STATUSBAR,
static void
gimp_statusbar_class_init (GimpStatusbarClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->dispose = gimp_statusbar_dispose;
+ object_class->finalize = gimp_statusbar_finalize;
- object_class->dispose = gimp_statusbar_dispose;
- object_class->finalize = gimp_statusbar_finalize;
+ widget_class->screen_changed = gimp_statusbar_screen_changed;
+ widget_class->style_set = gimp_statusbar_style_set;
}
static void
@@ -296,6 +308,12 @@ gimp_statusbar_finalize (GObject *object)
statusbar->icon = NULL;
}
+ if (statusbar->icon_hash)
+ {
+ g_hash_table_unref (statusbar->icon_hash);
+ statusbar->icon_hash = NULL;
+ }
+
g_slist_free_full (statusbar->messages,
(GDestroyNotify) gimp_statusbar_msg_free);
statusbar->messages = NULL;
@@ -310,6 +328,37 @@ gimp_statusbar_finalize (GObject *object)
}
static void
+gimp_statusbar_screen_changed (GtkWidget *widget,
+ GdkScreen *previous)
+{
+ GimpStatusbar *statusbar = GIMP_STATUSBAR (widget);
+
+ if (GTK_WIDGET_CLASS (parent_class)->screen_changed)
+ GTK_WIDGET_CLASS (parent_class)->screen_changed (widget, previous);
+
+ if (statusbar->icon_hash)
+ {
+ g_hash_table_unref (statusbar->icon_hash);
+ statusbar->icon_hash = NULL;
+ }
+}
+
+static void
+gimp_statusbar_style_set (GtkWidget *widget,
+ GtkStyle *prev_style)
+{
+ GimpStatusbar *statusbar = GIMP_STATUSBAR (widget);
+
+ GTK_WIDGET_CLASS (parent_class)->style_set (widget, prev_style);
+
+ if (statusbar->icon_hash)
+ {
+ g_hash_table_unref (statusbar->icon_hash);
+ statusbar->icon_hash = NULL;
+ }
+}
+
+static void
gimp_statusbar_hbox_size_request (GtkWidget *widget,
GtkRequisition *requisition,
GimpStatusbar *statusbar)
@@ -551,7 +600,7 @@ gimp_statusbar_progress_message (GimpProgress *progress,
{
GdkPixbuf *pixbuf;
- pixbuf = gimp_widget_load_icon (statusbar->label, icon_name, 16);
+ pixbuf = gimp_statusbar_load_icon (statusbar, icon_name);
width += ICON_SPACING + gdk_pixbuf_get_width (pixbuf);
@@ -601,8 +650,7 @@ gimp_statusbar_set_text (GimpStatusbar *statusbar,
}
if (icon_name)
- statusbar->icon = gimp_widget_load_icon (statusbar->label,
- icon_name, 16);
+ statusbar->icon = gimp_statusbar_load_icon (statusbar, icon_name);
if (statusbar->icon)
{
@@ -1547,3 +1595,35 @@ gimp_statusbar_vprintf (const gchar *format,
return message;
}
+
+static GdkPixbuf *
+gimp_statusbar_load_icon (GimpStatusbar *statusbar,
+ const gchar *icon_name)
+{
+ GdkPixbuf *icon;
+
+ if (G_UNLIKELY (! statusbar->icon_hash))
+ {
+ statusbar->icon_hash =
+ g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_object_unref);
+ }
+
+ icon = g_hash_table_lookup (statusbar->icon_hash, icon_name);
+
+ if (icon)
+ return g_object_ref (icon);
+
+ icon = gimp_widget_load_icon (statusbar->label, icon_name, 16);
+
+ /* this is not optimal but so what */
+ if (g_hash_table_size (statusbar->icon_hash) > 16)
+ g_hash_table_remove_all (statusbar->icon_hash);
+
+ g_hash_table_insert (statusbar->icon_hash,
+ g_strdup (icon_name), g_object_ref (icon));
+
+ return icon;
+}
diff --git a/app/display/gimpstatusbar.h b/app/display/gimpstatusbar.h
index a0c7f8d..3d51724 100644
--- a/app/display/gimpstatusbar.h
+++ b/app/display/gimpstatusbar.h
@@ -45,6 +45,7 @@ struct _GimpStatusbar
guint seq_context_id;
GdkPixbuf *icon;
+ GHashTable *icon_hash;
guint temp_context_id;
guint temp_timeout_id;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]