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.
This commit is contained in:
@ -73,6 +73,11 @@ static void gimp_statusbar_progress_iface_init (GimpProgressInterface *iface
|
|||||||
static void gimp_statusbar_dispose (GObject *object);
|
static void gimp_statusbar_dispose (GObject *object);
|
||||||
static void gimp_statusbar_finalize (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,
|
static void gimp_statusbar_hbox_size_request (GtkWidget *widget,
|
||||||
GtkRequisition *requisition,
|
GtkRequisition *requisition,
|
||||||
GimpStatusbar *statusbar);
|
GimpStatusbar *statusbar);
|
||||||
@ -122,6 +127,9 @@ static void gimp_statusbar_msg_free (GimpStatusbarMsg *msg);
|
|||||||
static gchar * gimp_statusbar_vprintf (const gchar *format,
|
static gchar * gimp_statusbar_vprintf (const gchar *format,
|
||||||
va_list args) G_GNUC_PRINTF (1, 0);
|
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_DEFINE_TYPE_WITH_CODE (GimpStatusbar, gimp_statusbar, GTK_TYPE_STATUSBAR,
|
||||||
G_IMPLEMENT_INTERFACE (GIMP_TYPE_PROGRESS,
|
G_IMPLEMENT_INTERFACE (GIMP_TYPE_PROGRESS,
|
||||||
@ -133,10 +141,14 @@ G_DEFINE_TYPE_WITH_CODE (GimpStatusbar, gimp_statusbar, GTK_TYPE_STATUSBAR,
|
|||||||
static void
|
static void
|
||||||
gimp_statusbar_class_init (GimpStatusbarClass *klass)
|
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->dispose = gimp_statusbar_dispose;
|
||||||
object_class->finalize = gimp_statusbar_finalize;
|
object_class->finalize = gimp_statusbar_finalize;
|
||||||
|
|
||||||
|
widget_class->screen_changed = gimp_statusbar_screen_changed;
|
||||||
|
widget_class->style_set = gimp_statusbar_style_set;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -296,6 +308,12 @@ gimp_statusbar_finalize (GObject *object)
|
|||||||
statusbar->icon = NULL;
|
statusbar->icon = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (statusbar->icon_hash)
|
||||||
|
{
|
||||||
|
g_hash_table_unref (statusbar->icon_hash);
|
||||||
|
statusbar->icon_hash = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
g_slist_free_full (statusbar->messages,
|
g_slist_free_full (statusbar->messages,
|
||||||
(GDestroyNotify) gimp_statusbar_msg_free);
|
(GDestroyNotify) gimp_statusbar_msg_free);
|
||||||
statusbar->messages = NULL;
|
statusbar->messages = NULL;
|
||||||
@ -309,6 +327,37 @@ gimp_statusbar_finalize (GObject *object)
|
|||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (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
|
static void
|
||||||
gimp_statusbar_hbox_size_request (GtkWidget *widget,
|
gimp_statusbar_hbox_size_request (GtkWidget *widget,
|
||||||
GtkRequisition *requisition,
|
GtkRequisition *requisition,
|
||||||
@ -551,7 +600,7 @@ gimp_statusbar_progress_message (GimpProgress *progress,
|
|||||||
{
|
{
|
||||||
GdkPixbuf *pixbuf;
|
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);
|
width += ICON_SPACING + gdk_pixbuf_get_width (pixbuf);
|
||||||
|
|
||||||
@ -601,8 +650,7 @@ gimp_statusbar_set_text (GimpStatusbar *statusbar,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (icon_name)
|
if (icon_name)
|
||||||
statusbar->icon = gimp_widget_load_icon (statusbar->label,
|
statusbar->icon = gimp_statusbar_load_icon (statusbar, icon_name);
|
||||||
icon_name, 16);
|
|
||||||
|
|
||||||
if (statusbar->icon)
|
if (statusbar->icon)
|
||||||
{
|
{
|
||||||
@ -1547,3 +1595,35 @@ gimp_statusbar_vprintf (const gchar *format,
|
|||||||
|
|
||||||
return message;
|
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;
|
||||||
|
}
|
||||||
|
@ -45,6 +45,7 @@ struct _GimpStatusbar
|
|||||||
guint seq_context_id;
|
guint seq_context_id;
|
||||||
|
|
||||||
GdkPixbuf *icon;
|
GdkPixbuf *icon;
|
||||||
|
GHashTable *icon_hash;
|
||||||
|
|
||||||
guint temp_context_id;
|
guint temp_context_id;
|
||||||
guint temp_timeout_id;
|
guint temp_timeout_id;
|
||||||
|
Reference in New Issue
Block a user