aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Kerr <charles.kerr@canonical.com>2013-07-01 11:56:15 -0500
committerCharles Kerr <charles.kerr@canonical.com>2013-07-01 11:56:15 -0500
commit059926df08da8b54e2fcee256a2ab977f4dfc307 (patch)
tree3cfb80f5cdb42fa9283823e1cf394a2c84cb9083
parente31ab7b930c33f13d9f123e17032ba37b7bbbdcf (diff)
downloadayatana-ido-059926df08da8b54e2fcee256a2ab977f4dfc307.tar.gz
ayatana-ido-059926df08da8b54e2fcee256a2ab977f4dfc307.tar.bz2
ayatana-ido-059926df08da8b54e2fcee256a2ab977f4dfc307.zip
don't load the icon twice
-rw-r--r--src/idousermenuitem.c161
1 files changed, 107 insertions, 54 deletions
diff --git a/src/idousermenuitem.c b/src/idousermenuitem.c
index d0fdb09..8ceb4ef 100644
--- a/src/idousermenuitem.c
+++ b/src/idousermenuitem.c
@@ -61,6 +61,103 @@ static gboolean ido_user_menu_item_primitive_draw_cb_gtk_3 (GtkWidget * image,
cairo_t * cr,
gpointer gself);
+/***
+**** Avatar
+***/
+
+static GdkPixbuf *
+load_gicon (GtkWidget * self, GIcon * icon, GError ** error)
+{
+ GtkSettings * settings;
+ gint width;
+ gint height;
+ GdkScreen * screen;
+ GtkIconTheme * icon_theme;
+ GtkIconInfo * info;
+ GtkStyleContext * style_context;
+ GdkPixbuf * pixbuf;
+
+ settings = gtk_widget_get_settings (self);
+ if (settings == NULL) /* not attached to a toplevel yet */
+ settings = gtk_settings_get_default ();
+
+ if (!gtk_icon_size_lookup_for_settings (settings,
+ GTK_ICON_SIZE_MENU,
+ &width,
+ &height))
+ {
+ /* arbitrary default size in case _size_lookup fails */
+ width = 12;
+ height = 12;
+ }
+
+ if ((screen = gtk_widget_get_screen (self)))
+ icon_theme = gtk_icon_theme_get_for_screen (screen);
+ else
+ icon_theme = gtk_icon_theme_get_default ();
+
+
+ info = gtk_icon_theme_lookup_by_gicon (icon_theme,
+ icon,
+ MIN (width, height),
+ GTK_ICON_LOOKUP_USE_BUILTIN |
+ GTK_ICON_LOOKUP_GENERIC_FALLBACK |
+ GTK_ICON_LOOKUP_FORCE_SIZE);
+
+ style_context = gtk_widget_get_style_context (self);
+
+ pixbuf = gtk_icon_info_load_symbolic_for_context (info,
+ style_context,
+ NULL,
+ error);
+
+ g_clear_object (&info);
+ return pixbuf;
+}
+
+static void
+update_avatar (IdoUserMenuItem * self)
+{
+ IdoUserMenuItemPrivate * p = self->priv;
+ GdkPixbuf * pixbuf;
+ GtkImage * image;
+
+ if (p->icon == NULL)
+ {
+ pixbuf = NULL;
+ }
+ else
+ {
+ GError * error = NULL;
+
+ pixbuf = load_gicon (GTK_WIDGET(self), p->icon, &error);
+
+ if (error != NULL)
+ {
+ g_warning ("Can't load user avatar icon: %s", error->message);
+ g_error_free (error);
+ }
+ }
+
+ image = GTK_IMAGE (p->user_image);
+
+ if (pixbuf != NULL)
+ {
+ gtk_image_set_from_pixbuf (image, pixbuf);
+ g_object_unref (G_OBJECT (pixbuf));
+ }
+ else
+ {
+ GIcon * icon;
+ icon = g_themed_icon_new_with_default_fallbacks (FALLBACK_ICON_NAME);
+ gtk_image_set_from_gicon (image, icon, GTK_ICON_SIZE_MENU);
+ g_object_unref (icon);
+ }
+}
+
+/***
+**** GObject virtual functions
+***/
static void
my_get_property (GObject * o,
@@ -241,6 +338,11 @@ ido_user_menu_item_init (IdoUserMenuItem *self)
g_signal_connect_after (GTK_WIDGET(self), "draw",
G_CALLBACK(ido_user_menu_item_primitive_draw_cb_gtk_3),
GTK_WIDGET(self));
+
+ /* load_gicon()'s behavior depends on the current screen/toplevel/etc,
+ so reload the avatar whenever the widget is realized */
+ g_signal_connect_swapped (self, "realize",
+ G_CALLBACK(update_avatar), self);
}
@@ -285,48 +387,6 @@ ido_user_menu_item_primitive_draw_cb_gtk_3 (GtkWidget * widget,
return FALSE;
}
-/* Tests for basic icon errors such as missing or unreadable icon files. */
-static gboolean
-icon_is_loadable (GtkWidget * self, GIcon * icon, GError ** error)
-{
- gint width;
- gint height;
- GtkIconInfo * info;
- GdkPixbuf * pixbuf;
- GtkStyleContext * style_context;
- gboolean is_loadable;
-
- style_context = gtk_widget_get_style_context (self);
-
- if (!gtk_icon_size_lookup_for_settings (gtk_settings_get_default(),
- GTK_ICON_SIZE_MENU,
- &width,
- &height))
- {
- /* arbitrary default size in case _size_lookup fails */
- width = 12;
- height = 12;
- }
-
- info = gtk_icon_theme_lookup_by_gicon (gtk_icon_theme_get_default(),
- icon,
- MIN (width, height),
- GTK_ICON_LOOKUP_USE_BUILTIN |
- GTK_ICON_LOOKUP_GENERIC_FALLBACK |
- GTK_ICON_LOOKUP_FORCE_SIZE);
-
- pixbuf = gtk_icon_info_load_symbolic_for_context (info,
- style_context,
- NULL,
- error);
-
- is_loadable = pixbuf != NULL;
-
- g_clear_object (&pixbuf);
- g_clear_object (&info);
- return is_loadable;
-}
-
/***
**** PUBLIC API
***/
@@ -335,22 +395,15 @@ void
ido_user_menu_item_set_icon (IdoUserMenuItem * self, GIcon * icon)
{
IdoUserMenuItemPrivate * p = self->priv;
- GtkImage * image = GTK_IMAGE (p->user_image);
- GError * error = NULL;
- if (icon && !icon_is_loadable (GTK_WIDGET(self), icon, &error))
+ if (p->icon != icon)
{
- g_warning ("Can't load user avatar icon: %s", error->message);
- g_error_free (error);
- icon = NULL;
- }
+ g_clear_object (&p->icon);
- if (icon != NULL)
- g_object_ref (icon);
- else
- icon = g_themed_icon_new_with_default_fallbacks (FALLBACK_ICON_NAME);
+ p->icon = g_object_ref (icon);
- gtk_image_set_from_gicon (image, icon, GTK_ICON_SIZE_MENU);
+ update_avatar (self);
+ }
}
void