[gnome-software/1514-gnome-os-most-system-apps-have-no-icons-in-installed-list: 9/9] appstream: Lookup app icons from .desktop files, if none found
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/1514-gnome-os-most-system-apps-have-no-icons-in-installed-list: 9/9] appstream: Lookup app icons from .desktop files, if none found
- Date: Tue, 26 Apr 2022 07:08:54 +0000 (UTC)
commit e97a6d357f8a4eb29b3025b1a96b55691b28b977
Author: Milan Crha <mcrha redhat com>
Date: Wed Apr 13 12:29:39 2022 +0200
appstream: Lookup app icons from .desktop files, if none found
The installed apps, coming from .appdata.xml files, usually do not have
set any icon. Try to lookup icons from the .desktop files in such cases,
thus, when the .appdata.xml files have properly set references between
then and their .desktop files, the expected icons are shown.
Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1514
lib/gs-appstream.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 67 insertions(+), 7 deletions(-)
---
diff --git a/lib/gs-appstream.c b/lib/gs-appstream.c
index b0aea1f3e..1908e5eef 100644
--- a/lib/gs-appstream.c
+++ b/lib/gs-appstream.c
@@ -251,13 +251,11 @@ app_add_icon (GsApp *app,
}
static void
-gs_appstream_refine_icon (GsApp *app, XbNode *component)
+traverse_component_icons (GsApp *app,
+ XbNode *component,
+ GPtrArray *icons)
{
- g_autoptr(GError) local_error = NULL;
- g_autoptr(GPtrArray) icons = NULL; /* (element-type XbNode) */
-
- icons = xb_node_query (component, "icon", 0, &local_error);
- if (icons == NULL)
+ if (!icons)
return;
/* This code deliberately does *not* check that the icon files or theme
@@ -281,6 +279,68 @@ gs_appstream_refine_icon (GsApp *app, XbNode *component)
}
}
+static void
+traverse_components_xpath_for_icons (GsApp *app,
+ XbSilo *silo,
+ const gchar *xpath,
+ gboolean try_with_launchable)
+{
+ g_autoptr(GPtrArray) components = NULL;
+ g_autoptr(GError) local_error = NULL;
+
+ components = xb_silo_query (silo, xpath, 0, &local_error);
+ if (components) {
+ for (guint i = 0; i < components->len; i++) {
+ g_autoptr(GPtrArray) icons = NULL; /* (element-type XbNode) */
+ XbNode *component = g_ptr_array_index (components, i);
+ g_autofree gchar *xml = xb_node_export (component, 0, NULL);
+ icons = xb_node_query (component, "icon", 0, NULL);
+ traverse_component_icons (app, component, icons);
+
+ if (try_with_launchable && gs_app_get_icons (app) == NULL) {
+ const gchar *launchable_id = xb_node_query_text (component,
"launchable[@type='desktop-id']", NULL);
+ if (launchable_id != NULL) {
+ g_autofree gchar *xpath2 = NULL;
+
+ /* Inherit the icon from the .desktop file */
+ xpath2 = g_strdup_printf
("/component[@type='desktop-application']/launchable[@type='desktop-id'][text()='%s']/..",
+ launchable_id);
+ traverse_components_xpath_for_icons (app, silo, xpath2, FALSE);
+ }
+ }
+ }
+ }
+}
+
+static void
+gs_appstream_refine_icon (GsApp *app,
+ XbSilo *silo,
+ XbNode *component)
+{
+ g_autoptr(GError) local_error = NULL;
+ g_autoptr(GPtrArray) icons = NULL; /* (element-type XbNode) */
+
+ icons = xb_node_query (component, "icon", 0, &local_error);
+ traverse_component_icons (app, component, icons);
+ g_clear_pointer (&icons, g_ptr_array_unref);
+
+ /* If no icon found, try to inherit the icon from the .desktop file */
+ if (gs_app_get_icons (app) == NULL) {
+ g_autofree gchar *xpath = NULL;
+ const gchar *launchable_id = xb_node_query_text (component, "launchable[@type='desktop-id']",
NULL);
+ if (launchable_id != NULL) {
+ xpath = g_strdup_printf
("/component[@type='desktop-application']/launchable[@type='desktop-id'][text()='%s']/..",
+ launchable_id);
+ traverse_components_xpath_for_icons (app, silo, xpath, FALSE);
+ g_clear_pointer (&xpath, g_free);
+ }
+
+ xpath = g_strdup_printf
("/component[@type='desktop-application']/launchable[@type='desktop-id'][text()='%s']/..",
+ gs_app_get_id (app));
+ traverse_components_xpath_for_icons (app, silo, xpath, FALSE);
+ }
+}
+
static gboolean
gs_appstream_refine_add_addons (GsPlugin *plugin,
GsApp *app,
@@ -1101,7 +1161,7 @@ gs_appstream_refine_app (GsPlugin *plugin,
/* set icon */
if ((refine_flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON) > 0 &&
gs_app_get_icons (app) == NULL)
- gs_appstream_refine_icon (app, component);
+ gs_appstream_refine_icon (app, silo, component);
/* set categories */
if (refine_flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_CATEGORIES) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]