diff options
author | Charles Kerr <charles.kerr@canonical.com> | 2013-07-01 11:56:15 -0500 |
---|---|---|
committer | Charles Kerr <charles.kerr@canonical.com> | 2013-07-01 11:56:15 -0500 |
commit | 059926df08da8b54e2fcee256a2ab977f4dfc307 (patch) | |
tree | 3cfb80f5cdb42fa9283823e1cf394a2c84cb9083 | |
parent | e31ab7b930c33f13d9f123e17032ba37b7bbbdcf (diff) | |
download | ayatana-ido-059926df08da8b54e2fcee256a2ab977f4dfc307.tar.gz ayatana-ido-059926df08da8b54e2fcee256a2ab977f4dfc307.tar.bz2 ayatana-ido-059926df08da8b54e2fcee256a2ab977f4dfc307.zip |
don't load the icon twice
-rw-r--r-- | src/idousermenuitem.c | 161 |
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 |