[gnome-software: 11/18] lib: Drop gs_app_load_pixbuf() and use GIcons instead




commit 52fe59624429e3ed2b9311ee8223b77e52c7d4f3
Author: Philip Withnall <pwithnall endlessos org>
Date:   Fri Mar 5 11:28:26 2021 +0000

    lib: Drop gs_app_load_pixbuf() and use GIcons instead
    
    This simplifies the code a bit, but significantly allows for
    `GtkImage` to automatically reload icons if the icon theme changes, as
    it now has access to icon names (from the `GIcon`) rather than just
    already-loaded pixel data (in a `GdkPixbuf`). It also means the RTL
    variant of an icon can be loaded if in an RTL locale (and if the variant
    exists; I can find no apps which currently take advantage of this
    functionality).
    
    This doesn’t matter for most application icons, but could do if an icon
    theme distributed overridden versions of popular app icons.
    
    Signed-off-by: Philip Withnall <pwithnall endlessos org>
    
    Helps: #1147

 lib/gs-app.c                   | 106 +++++++++++++++++------------------------
 lib/gs-app.h                   |   3 --
 plugins/dummy/gs-self-test.c   |  12 ++---
 plugins/flatpak/gs-self-test.c |   6 +--
 plugins/snap/gs-self-test.c    |  15 ++++--
 src/gs-app-row.c               |  15 +++---
 src/gs-details-page.c          |  16 +++----
 src/gs-feature-tile.c          |  27 ++++++++---
 src/gs-popular-tile.c          |  15 +++---
 src/gs-shell-search-provider.c |  20 ++++----
 src/gs-summary-tile.c          |  16 +++----
 src/gs-update-dialog.c         |  31 ++++++++++--
 12 files changed, 150 insertions(+), 132 deletions(-)
---
diff --git a/lib/gs-app.c b/lib/gs-app.c
index 824991e4a..771743330 100644
--- a/lib/gs-app.c
+++ b/lib/gs-app.c
@@ -1777,65 +1777,6 @@ gs_app_set_developer_name (GsApp *app, const gchar *developer_name)
        _g_set_str (&priv->developer_name, developer_name);
 }
 
-/**
- * gs_app_has_pixbufs:
- * @app: a #GsApp
- *
- * Gets whether there are any pixbufs set for this app.
- *
- * Returns: %TRUE if one or more pixbufs are set for the app, %FALSE otherwise
- * Since: 40
- */
-gboolean
-gs_app_has_pixbufs (GsApp *app)
-{
-       GsAppPrivate *priv = gs_app_get_instance_private (app);
-
-       g_return_val_if_fail (GS_IS_APP (app), FALSE);
-
-       return (priv->icons != NULL && priv->icons->len > 0);
-}
-
-/**
- * gs_app_load_pixbuf:
- * @app: a #GsApp
- * @size: size (width or height, square) of the pixbuf to load, in device pixels
- *
- * Loads a pixbuf to represent the application. This might be provided by the
- * backend at the given @size, or downsized from a larger icon provided by the
- * backend. The return value is guaranteed to be at @size, if it’s not %NULL.
- *
- * If an image at least @size pixels in width isn’t available, %NULL will be
- * returned.
- *
- * This function may do disk I/O or image resizing, but it will not do network
- * I/O to load a pixbuf. It should be acceptable to call this from a UI thread.
- *
- * Returns: (transfer full) (nullable): a #GdkPixbuf, or %NULL
- *
- * Since: 40
- **/
-GdkPixbuf *
-gs_app_load_pixbuf (GsApp *app,
-                    guint  size)
-{
-       g_autoptr(GIcon) icon = NULL;
-       g_autoptr(GInputStream) input_stream = NULL;
-
-       g_return_val_if_fail (GS_IS_APP (app), NULL);
-       g_return_val_if_fail (size > 0, NULL);
-
-       icon = gs_app_get_icon_for_size (app, size, 1, NULL);
-       if (icon == NULL || !G_IS_LOADABLE_ICON (icon))
-               return NULL;
-
-       input_stream = g_loadable_icon_load (G_LOADABLE_ICON (icon), size, NULL, NULL, NULL);
-       if (input_stream == NULL)
-               return NULL;
-
-       return gdk_pixbuf_new_from_stream_at_scale (input_stream, size, size, TRUE, NULL, NULL);
-}
-
 /**
  * gs_app_get_icon_for_size:
  * @app: a #GsApp
@@ -4124,6 +4065,7 @@ static void
 calculate_key_colors (GsApp *app)
 {
        GsAppPrivate *priv = gs_app_get_instance_private (app);
+       g_autoptr(GIcon) icon_small = NULL;
        g_autoptr(GdkPixbuf) pb_small = NULL;
        const gchar *overrides_str;
 
@@ -4174,11 +4116,51 @@ calculate_key_colors (GsApp *app)
                }
        }
 
-       /* no pixbuf */
-       pb_small = gs_app_load_pixbuf (app, 32);
-       if (pb_small == NULL) {
+       /* Try and load the pixbuf. */
+       icon_small = gs_app_get_icon_for_size (app, 32, 1, NULL);
+
+       if (icon_small == NULL) {
                g_debug ("no pixbuf, so no key colors");
                return;
+       } else if (G_IS_LOADABLE_ICON (icon_small)) {
+               g_autoptr(GInputStream) icon_stream = g_loadable_icon_load (G_LOADABLE_ICON (icon_small), 32, 
NULL, NULL, NULL);
+               pb_small = gdk_pixbuf_new_from_stream_at_scale (icon_stream, 32, 32, TRUE, NULL, NULL);
+       } else if (G_IS_THEMED_ICON (icon_small)) {
+               g_autoptr(GtkIconTheme) theme = NULL;
+               g_autoptr(GtkIconInfo) icon_info = NULL;
+
+               if (gdk_screen_get_default () != NULL) {
+                       theme = g_object_ref (gtk_icon_theme_get_default ());
+               } else {
+                       const gchar *test_search_path;
+
+                       /* This fallback path is needed for the unit tests,
+                        * which run without a screen, and in an environment
+                        * where the XDG dir variables don’t point to the system
+                        * datadir which contains the system icon theme. */
+                       theme = gtk_icon_theme_new ();
+
+                       test_search_path = g_getenv ("GS_SELF_TEST_ICON_THEME_PATH");
+                       if (test_search_path != NULL) {
+                               g_auto(GStrv) dirs = g_strsplit (test_search_path, ":", -1);
+
+                               /* This prepends, so we have to iterate in reverse to preserve order */
+                               for (gsize i = g_strv_length (dirs); i > 0; i--)
+                                       gtk_icon_theme_prepend_search_path (theme, dirs[i - 1]);
+                       }
+               }
+
+               icon_info = gtk_icon_theme_lookup_by_gicon (theme, icon_small, 32, 
GTK_ICON_LOOKUP_USE_BUILTIN);
+               if (icon_info != NULL)
+                       pb_small = gtk_icon_info_load_icon (icon_info, NULL);
+       } else {
+               g_debug ("unsupported pixbuf, so no key colors");
+               return;
+       }
+
+       if (pb_small == NULL) {
+               g_debug ("pixbuf couldn’t be loaded, so no key colors");
+               return;
        }
 
        /* get a list of key colors */
diff --git a/lib/gs-app.h b/lib/gs-app.h
index d550d6b9f..3136b639f 100644
--- a/lib/gs-app.h
+++ b/lib/gs-app.h
@@ -353,9 +353,6 @@ void                 gs_app_set_update_urgency      (GsApp          *app,
 const gchar    *gs_app_get_management_plugin   (GsApp          *app);
 void            gs_app_set_management_plugin   (GsApp          *app,
                                                 const gchar    *management_plugin);
-gboolean        gs_app_has_pixbufs             (GsApp          *app);
-GdkPixbuf      *gs_app_load_pixbuf             (GsApp          *app,
-                                                guint           size);
 GIcon          *gs_app_get_icon_for_size       (GsApp          *app,
                                                 guint           size,
                                                 guint           scale,
diff --git a/plugins/dummy/gs-self-test.c b/plugins/dummy/gs-self-test.c
index 791997590..fe8a09993 100644
--- a/plugins/dummy/gs-self-test.c
+++ b/plugins/dummy/gs-self-test.c
@@ -349,7 +349,7 @@ gs_plugins_dummy_installed_func (GsPluginLoader *plugin_loader)
        g_autoptr(GError) error = NULL;
        g_autoptr(GsAppList) list = NULL;
        g_autoptr(GsPluginJob) plugin_job = NULL;
-       g_autoptr(GdkPixbuf) pixbuf = NULL;
+       g_autoptr(GIcon) icon = NULL;
 
        /* get installed packages */
        plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_GET_INSTALLED,
@@ -374,9 +374,9 @@ gs_plugins_dummy_installed_func (GsPluginLoader *plugin_loader)
        g_assert_cmpint (gs_app_get_state (app), ==, GS_APP_STATE_INSTALLED);
        g_assert_cmpstr (gs_app_get_name (app), ==, "Zeus");
        g_assert_cmpstr (gs_app_get_source_default (app), ==, "zeus");
-       pixbuf = gs_app_load_pixbuf (app, 48);
-       g_assert_nonnull (pixbuf);
-       g_clear_object (&pixbuf);
+       icon = gs_app_get_icon_for_size (app, 48, 1, NULL);
+       g_assert_nonnull (icon);
+       g_clear_object (&icon);
 
        /* check various bitfields */
        g_assert (gs_app_has_quirk (app, GS_APP_QUIRK_PROVENANCE));
@@ -405,8 +405,8 @@ gs_plugins_dummy_installed_func (GsPluginLoader *plugin_loader)
        g_assert_cmpstr (gs_app_get_source_default (addon), ==, "zeus-spell");
        g_assert_cmpstr (gs_app_get_license (addon), ==,
                         "LicenseRef-free=https://www.debian.org/";);
-       pixbuf = gs_app_load_pixbuf (addon, 48);
-       g_assert_null (pixbuf);
+       icon = gs_app_get_icon_for_size (addon, 48, 1, NULL);
+       g_assert_null (icon);
 }
 
 static void
diff --git a/plugins/flatpak/gs-self-test.c b/plugins/flatpak/gs-self-test.c
index 08c5b6a9f..3abe743ea 100644
--- a/plugins/flatpak/gs-self-test.c
+++ b/plugins/flatpak/gs-self-test.c
@@ -115,7 +115,7 @@ gs_plugins_flatpak_repo_func (GsPluginLoader *plugin_loader)
        g_autoptr(GsApp) app2 = NULL;
        g_autoptr(GsApp) app = NULL;
        g_autoptr(GsPluginJob) plugin_job = NULL;
-       g_autoptr(GdkPixbuf) pixbuf = NULL;
+       g_autoptr(GIcon) icon = NULL;
 
        /* no flatpak, abort */
        if (!gs_plugin_loader_get_enabled (plugin_loader, "flatpak"))
@@ -151,8 +151,8 @@ gs_plugins_flatpak_repo_func (GsPluginLoader *plugin_loader)
        g_assert_cmpstr (gs_app_get_description (app), ==,
                         "Longer multiline comment that does into detail.");
        g_assert_true (gs_app_get_local_file (app) != NULL);
-       pixbuf = gs_app_load_pixbuf (app, 64);
-       g_assert_nonnull (pixbuf);
+       icon = gs_app_get_icon_for_size (app, 64, 1, NULL);
+       g_assert_nonnull (icon);
 
        /* now install the remote */
        g_object_unref (plugin_job);
diff --git a/plugins/snap/gs-self-test.c b/plugins/snap/gs-self-test.c
index 41696c114..f78d9dc8b 100644
--- a/plugins/snap/gs-self-test.c
+++ b/plugins/snap/gs-self-test.c
@@ -261,6 +261,8 @@ gs_plugins_snap_test_func (GsPluginLoader *plugin_loader)
        GPtrArray *screenshots, *images;
        AsScreenshot *screenshot;
        AsImage *image;
+       g_autoptr(GIcon) icon = NULL;
+       g_autoptr(GInputStream) icon_stream = NULL;
        g_autoptr(GdkPixbuf) pixbuf = NULL;
        g_autoptr(GError) error = NULL;
 
@@ -300,8 +302,8 @@ gs_plugins_snap_test_func (GsPluginLoader *plugin_loader)
        g_assert_cmpstr (as_image_get_url (image), ==, "http://example.com/screenshot2.jpg";);
        g_assert_cmpint (as_image_get_width (image), ==, 1024);
        g_assert_cmpint (as_image_get_height (image), ==, 768);
-       pixbuf = gs_app_load_pixbuf (app, 64);
-       g_assert_null (pixbuf);
+       icon = gs_app_get_icon_for_size (app, 64, 1, NULL);
+       g_assert_null (icon);
        g_assert_cmpint (gs_app_get_size_installed (app), ==, 0);
        g_assert_cmpint (gs_app_get_size_download (app), ==, 500);
        g_assert_cmpint (gs_app_get_install_date (app), ==, 0);
@@ -319,7 +321,14 @@ gs_plugins_snap_test_func (GsPluginLoader *plugin_loader)
        g_assert_cmpint (gs_app_get_size_installed (app), ==, 1000);
        g_assert_cmpint (gs_app_get_install_date (app), ==, g_date_time_to_unix (g_date_time_new_utc (2017, 
1, 2, 11, 23, 58)));
 
-       pixbuf = gs_app_load_pixbuf (app, 128);
+       icon = gs_app_get_icon_for_size (app, 128, 1, NULL);
+       g_assert_nonnull (icon);
+       g_assert_true (G_IS_LOADABLE_ICON (icon));
+       icon_stream = g_loadable_icon_load (G_LOADABLE_ICON (icon), 128, NULL, &error);
+       g_assert_no_error (error);
+       g_assert_nonnull (icon_stream);
+       pixbuf = gdk_pixbuf_new_from_stream (icon_stream, NULL, &error);
+       g_assert_no_error (error);
        g_assert_nonnull (pixbuf);
        g_assert_cmpint (gdk_pixbuf_get_width (pixbuf), ==, 128);
        g_assert_cmpint (gdk_pixbuf_get_height (pixbuf), ==, 128);
diff --git a/src/gs-app-row.c b/src/gs-app-row.c
index bfd8f28c7..00f2f99ee 100644
--- a/src/gs-app-row.c
+++ b/src/gs-app-row.c
@@ -246,7 +246,7 @@ gs_app_row_actually_refresh (GsAppRow *app_row)
        const gchar *tmp;
        gboolean missing_search_result;
        guint64 size = 0;
-       g_autoptr(GdkPixbuf) pixbuf = NULL;
+       g_autoptr(GIcon) icon = NULL;
 
        if (priv->app == NULL)
                return;
@@ -389,14 +389,11 @@ gs_app_row_actually_refresh (GsAppRow *app_row)
        }
 
        /* pixbuf */
-       pixbuf = gs_app_load_pixbuf (priv->app, gtk_image_get_pixel_size (GTK_IMAGE (priv->image)) * 
gtk_widget_get_scale_factor (priv->image));
-       if (pixbuf == NULL) {
-               gtk_image_set_from_icon_name (GTK_IMAGE (priv->image),
-                                             "application-x-executable",
-                                             GTK_ICON_SIZE_DIALOG);
-       } else {
-               gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), pixbuf);
-       }
+       icon = gs_app_get_icon_for_size (priv->app,
+                                        gtk_image_get_pixel_size (GTK_IMAGE (priv->image)),
+                                        gtk_widget_get_scale_factor (priv->image),
+                                        "application-x-executable");
+       gtk_image_set_from_gicon (GTK_IMAGE (priv->image), icon, GTK_ICON_SIZE_DIALOG);
 
        context = gtk_widget_get_style_context (priv->image);
        if (missing_search_result)
diff --git a/src/gs-details-page.c b/src/gs-details-page.c
index 2959f6c8b..4b5ad230e 100644
--- a/src/gs-details-page.c
+++ b/src/gs-details-page.c
@@ -1101,7 +1101,7 @@ static void
 gs_details_page_refresh_all (GsDetailsPage *self)
 {
        GsAppList *history;
-       g_autoptr(GdkPixbuf) pixbuf = NULL;
+       g_autoptr(GIcon) icon = NULL;
        GList *addons;
        const gchar *tmp;
        gboolean ret;
@@ -1138,14 +1138,12 @@ gs_details_page_refresh_all (GsDetailsPage *self)
        gs_details_page_set_description (self, tmp);
 
        /* set the icon */
-       pixbuf = gs_app_load_pixbuf (self->app, gtk_image_get_pixel_size (GTK_IMAGE 
(self->application_details_icon)) * gtk_widget_get_scale_factor (self->application_details_icon));
-       if (pixbuf != NULL) {
-               gtk_image_set_from_pixbuf (GTK_IMAGE (self->application_details_icon), pixbuf);
-       } else {
-               gtk_image_set_from_icon_name (GTK_IMAGE (self->application_details_icon),
-                                             "application-x-executable",
-                                             GTK_ICON_SIZE_DIALOG);
-       }
+       icon = gs_app_get_icon_for_size (self->app,
+                                        gtk_image_get_pixel_size (GTK_IMAGE 
(self->application_details_icon)),
+                                        gtk_widget_get_scale_factor (self->application_details_icon),
+                                        "application-x-executable");
+       gtk_image_set_from_gicon (GTK_IMAGE (self->application_details_icon), icon,
+                                 GTK_ICON_SIZE_DIALOG);
 
        tmp = gs_app_get_url (self->app, AS_URL_KIND_HOMEPAGE);
        if (tmp != NULL && tmp[0] != '\0') {
diff --git a/src/gs-feature-tile.c b/src/gs-feature-tile.c
index 8c137c266..9eaef4c33 100644
--- a/src/gs-feature-tile.c
+++ b/src/gs-feature-tile.c
@@ -181,7 +181,8 @@ gs_feature_tile_refresh (GsAppTile *self)
        const gchar *markup = NULL;
        g_autofree gchar *name = NULL;
        GtkStyleContext *context;
-       g_autoptr(GdkPixbuf) pixbuf = NULL;
+       g_autoptr(GIcon) icon = NULL;
+       guint icon_size;
 
        if (app == NULL)
                return;
@@ -197,12 +198,24 @@ gs_feature_tile_refresh (GsAppTile *self)
 
        /* Update the icon. Try a 160px version if not in narrow mode, and it’s
         * available; otherwise use 128px. */
-       if (!tile->narrow_mode)
-               pixbuf = gs_app_load_pixbuf (app, 160 * gtk_widget_get_scale_factor (tile->image));
-       if (pixbuf == NULL)
-               pixbuf = gs_app_load_pixbuf (app, 128 * gtk_widget_get_scale_factor (tile->image));
-       if (pixbuf != NULL) {
-               gtk_image_set_from_pixbuf (GTK_IMAGE (tile->image), pixbuf);
+       if (!tile->narrow_mode) {
+               icon = gs_app_get_icon_for_size (app,
+                                                160,
+                                                gtk_widget_get_scale_factor (tile->image),
+                                                NULL);
+               icon_size = 160;
+       }
+       if (icon == NULL) {
+               icon = gs_app_get_icon_for_size (app,
+                                                128,
+                                                gtk_widget_get_scale_factor (tile->image),
+                                                NULL);
+               icon_size = 128;
+       }
+
+       if (icon != NULL) {
+               gtk_image_set_from_gicon (GTK_IMAGE (tile->image), icon, GTK_ICON_SIZE_INVALID);
+               gtk_image_set_pixel_size (GTK_IMAGE (tile->image), icon_size);
                gtk_widget_show (tile->image);
        } else {
                gtk_widget_hide (tile->image);
diff --git a/src/gs-popular-tile.c b/src/gs-popular-tile.c
index 75f8dbb6a..fe1e7a1af 100644
--- a/src/gs-popular-tile.c
+++ b/src/gs-popular-tile.c
@@ -48,7 +48,7 @@ gs_popular_tile_refresh (GsAppTile *self)
        gboolean installed;
        g_autofree gchar *name = NULL;
        const gchar *css;
-       g_autoptr(GdkPixbuf) pixbuf = NULL;
+       g_autoptr(GIcon) icon = NULL;
 
        if (app == NULL)
                return;
@@ -89,14 +89,11 @@ gs_popular_tile_refresh (GsAppTile *self)
        css = gs_app_get_metadata_item (app, "GnomeSoftware::PopularTile-css");
        gs_utils_widget_set_css (GTK_WIDGET (tile), &tile->tile_provider, "popular-tile", css);
 
-       pixbuf = gs_app_load_pixbuf (app, gtk_image_get_pixel_size (GTK_IMAGE (tile->image)) * 
gtk_widget_get_scale_factor (tile->image));
-       if (pixbuf != NULL) {
-               gtk_image_set_from_pixbuf (GTK_IMAGE (tile->image), pixbuf);
-       } else {
-               gtk_image_set_from_icon_name (GTK_IMAGE (tile->image),
-                                             "application-x-executable",
-                                             GTK_ICON_SIZE_DIALOG);
-       }
+       icon = gs_app_get_icon_for_size (app,
+                                        gtk_image_get_pixel_size (GTK_IMAGE (tile->image)),
+                                        gtk_widget_get_scale_factor (tile->image),
+                                        "application-x-executable");
+       gtk_image_set_from_gicon (GTK_IMAGE (tile->image), icon, GTK_ICON_SIZE_DIALOG);
 
        gtk_label_set_label (GTK_LABEL (tile->label), gs_app_get_name (app));
 }
diff --git a/src/gs-shell-search-provider.c b/src/gs-shell-search-provider.c
index 35c3913cf..8bafc9a8c 100644
--- a/src/gs-shell-search-provider.c
+++ b/src/gs-shell-search-provider.c
@@ -231,7 +231,7 @@ handle_get_result_metas (GsShellSearchProvider2     *skeleton,
 
        for (i = 0; results[i]; i++) {
                GsApp *app;
-               g_autoptr(GdkPixbuf) pixbuf = NULL;
+               g_autoptr(GIcon) icon = NULL;
                g_autofree gchar *description = NULL;
 
                /* already built */
@@ -248,14 +248,18 @@ handle_get_result_metas (GsShellSearchProvider2   *skeleton,
                g_variant_builder_init (&meta, G_VARIANT_TYPE ("a{sv}"));
                g_variant_builder_add (&meta, "{sv}", "id", g_variant_new_string (gs_app_get_unique_id 
(app)));
                g_variant_builder_add (&meta, "{sv}", "name", g_variant_new_string (gs_app_get_name (app)));
+
                /* ICON_SIZE is defined as 24px in js/ui/search.js in gnome-shell */
-               pixbuf = gs_app_load_pixbuf (app, 24);
-               if (pixbuf != NULL)
-                       g_variant_builder_add (&meta, "{sv}", "icon", g_icon_serialize (G_ICON (pixbuf)));
-               /* FIXME: Ideally we’d provide a `gicon` field here with the results of g_icon_to_string(),
-                * if possible, which would allow gnome-shell to load the app’s
-                * icon from the icon theme (if available) and potentially save
-                * time and memory */
+               icon = gs_app_get_icon_for_size (app, 24, 1, NULL);
+               if (icon != NULL) {
+                       g_autofree gchar *icon_str = g_icon_to_string (icon);
+                       if (icon_str != NULL) {
+                               g_variant_builder_add (&meta, "{sv}", "gicon", icon_str);
+                       } else {
+                               g_autoptr(GVariant) icon_serialized = g_icon_serialize (icon);
+                               g_variant_builder_add (&meta, "{sv}", "icon", icon_serialized);
+                       }
+               }
 
                if (gs_utils_list_has_component_fuzzy (self->search_results, app) &&
                    gs_app_get_origin_hostname (app) != NULL) {
diff --git a/src/gs-summary-tile.c b/src/gs-summary-tile.c
index e80022838..b69283d7f 100644
--- a/src/gs-summary-tile.c
+++ b/src/gs-summary-tile.c
@@ -40,7 +40,7 @@ gs_summary_tile_refresh (GsAppTile *self)
        GsApp *app = gs_app_tile_get_app (self);
        AtkObject *accessible;
        GtkStyleContext *context;
-       g_autoptr(GdkPixbuf) pixbuf = NULL;
+       g_autoptr(GIcon) icon = NULL;
        gboolean installed;
        g_autofree gchar *name = NULL;
        const gchar *summary;
@@ -60,14 +60,12 @@ gs_summary_tile_refresh (GsAppTile *self)
        gtk_label_set_label (GTK_LABEL (tile->summary), summary);
        gtk_widget_set_visible (tile->summary, summary && summary[0]);
 
-       pixbuf = gs_app_load_pixbuf (app, gtk_image_get_pixel_size (GTK_IMAGE (tile->image)) * 
gtk_widget_get_scale_factor (tile->image));
-       if (pixbuf != NULL) {
-               gtk_image_set_from_pixbuf (GTK_IMAGE (tile->image), pixbuf);
-       } else {
-               gtk_image_set_from_icon_name (GTK_IMAGE (tile->image),
-                                             "application-x-executable",
-                                             GTK_ICON_SIZE_DIALOG);
-       }
+       icon = gs_app_get_icon_for_size (app,
+                                        gtk_image_get_pixel_size (GTK_IMAGE (tile->image)),
+                                        gtk_widget_get_scale_factor (tile->image),
+                                        "application-x-executable");
+       gtk_image_set_from_gicon (GTK_IMAGE (tile->image), icon, GTK_ICON_SIZE_DIALOG);
+
        context = gtk_widget_get_style_context (tile->image);
        if (gs_app_get_use_drop_shadow (app))
                gtk_style_context_add_class (context, "icon-dropshadow");
diff --git a/src/gs-update-dialog.c b/src/gs-update-dialog.c
index cd8487236..64e347273 100644
--- a/src/gs-update-dialog.c
+++ b/src/gs-update-dialog.c
@@ -157,7 +157,8 @@ static void
 set_updates_description_ui (GsUpdateDialog *dialog, GsApp *app)
 {
        AsComponentKind kind;
-       g_autoptr(GdkPixbuf) pixbuf = NULL;
+       g_autoptr(GIcon) icon = NULL;
+       guint icon_size;
        const gchar *update_details;
 
        /* set window title */
@@ -192,9 +193,31 @@ set_updates_description_ui (GsUpdateDialog *dialog, GsApp *app)
        gtk_label_set_label (GTK_LABEL (dialog->label_name), gs_app_get_name (app));
        gtk_label_set_label (GTK_LABEL (dialog->label_summary), gs_app_get_summary (app));
 
-       pixbuf = gs_app_load_pixbuf (app, gtk_image_get_pixel_size (GTK_IMAGE (dialog->image_icon)) * 
gtk_widget_get_scale_factor (dialog->image_icon));
-       if (pixbuf != NULL)
-               gtk_image_set_from_pixbuf (GTK_IMAGE (dialog->image_icon), pixbuf);
+       /* set the icon; fall back to 64px if 96px isn’t available, which sometimes
+        * happens at 2× scale factor (hi-DPI) */
+       icon_size = 96;
+       icon = gs_app_get_icon_for_size (app,
+                                        icon_size,
+                                        gtk_widget_get_scale_factor (dialog->image_icon),
+                                        NULL);
+       if (icon == NULL) {
+               icon_size = 64;
+               icon = gs_app_get_icon_for_size (app,
+                                                icon_size,
+                                                gtk_widget_get_scale_factor (dialog->image_icon),
+                                                NULL);
+       }
+       if (icon == NULL) {
+               icon_size = 96;
+               icon = gs_app_get_icon_for_size (app,
+                                                icon_size,
+                                                gtk_widget_get_scale_factor (dialog->image_icon),
+                                                "application-x-executable");
+       }
+
+       gtk_image_set_pixel_size (GTK_IMAGE (dialog->image_icon), icon_size);
+       gtk_image_set_from_gicon (GTK_IMAGE (dialog->image_icon), icon,
+                                 GTK_ICON_SIZE_INVALID);
 
        /* show the back button if needed */
        gtk_widget_set_visible (dialog->button_back, !g_queue_is_empty (dialog->back_entry_stack));


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]