[gnome-software/1514-gnome-os-most-system-apps-have-no-icons-in-installed-list] 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] appstream: Lookup app icons from .desktop files, if none found
- Date: Wed, 13 Apr 2022 10:32:03 +0000 (UTC)
commit 3d8083ee82f0d4508f49a8051de18808bd36c3dd
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 | 90 +++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 83 insertions(+), 7 deletions(-)
---
diff --git a/lib/gs-appstream.c b/lib/gs-appstream.c
index b0aea1f3e..ef0b03a93 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,84 @@ 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);
+ }
+
+ if (gs_app_get_icons (app) == NULL) {
+ const gchar *provides_id = xb_node_query_text (component, "provides/id", NULL);
+ if (provides_id != NULL) {
+ g_autofree gchar *xpath = NULL;
+
+ xpath = g_strdup_printf
("/components/component[@type='desktop-application']/id[text()='%s']/..",
+ provides_id);
+ traverse_components_xpath_for_icons (app, silo, xpath, TRUE);
+ g_clear_pointer (&xpath, g_free);
+
+ xpath = g_strdup_printf ("/component[@type='desktop-application']/id[text()='%s']/..",
+ provides_id);
+ traverse_components_xpath_for_icons (app, silo, xpath, TRUE);
+ }
+ }
+}
+
static gboolean
gs_appstream_refine_add_addons (GsPlugin *plugin,
GsApp *app,
@@ -1101,7 +1177,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]