[gimp] Bug 730862 - Preview frozen while dragging selection tools...



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]