Blame SOURCES/0003-shell-app-system-Monitor-for-icon-theme-changes.patch

547cbf
From b3bdc04362e4a147a907b8b31f03ff02d0807c08 Mon Sep 17 00:00:00 2001
547cbf
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
547cbf
Date: Thu, 1 Aug 2019 20:58:20 -0300
547cbf
Subject: [PATCH 3/6] shell/app-system: Monitor for icon theme changes
547cbf
547cbf
Whenever an app is installed, the usual routine is
547cbf
to run 'gtk-update-icon-cache' after installing all
547cbf
of the app's files.
547cbf
547cbf
The side effect of that is that the .desktop file of
547cbf
the application is installed before the icon theme
547cbf
is updated. By the time GAppInfoMonitor emits the
547cbf
'changed' signal, the icon theme is not yet updated,
547cbf
leading to StIcon use the fallback icon.
547cbf
547cbf
Under some circumstances (e.g. on very slow spinning
547cbf
disks) the app icon is never actually loaded, and we
547cbf
see the fallback icon forever.
547cbf
547cbf
Monitor the icon theme for changes when an app is
547cbf
installed. Try as many as 6 times before giving up
547cbf
on detecting an icon theme update.
547cbf
547cbf
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/661
547cbf
---
547cbf
 src/shell-app-system.c    | 54 +++++++++++++++++++++++++++++++++++++++
547cbf
 src/st/st-texture-cache.c |  8 ++++++
547cbf
 src/st/st-texture-cache.h |  2 ++
547cbf
 3 files changed, 64 insertions(+)
547cbf
547cbf
diff --git a/src/shell-app-system.c b/src/shell-app-system.c
547cbf
index 58e0185d1..61ca1c35c 100644
547cbf
--- a/src/shell-app-system.c
547cbf
+++ b/src/shell-app-system.c
547cbf
@@ -14,6 +14,14 @@
547cbf
 #include "shell-app-system-private.h"
547cbf
 #include "shell-global.h"
547cbf
 #include "shell-util.h"
547cbf
+#include "st.h"
547cbf
+
547cbf
+/* Rescan for at most RESCAN_TIMEOUT_MS * MAX_RESCAN_RETRIES. That
547cbf
+ * should be plenty of time for even a slow spinning drive to update
547cbf
+ * the icon cache.
547cbf
+ */
547cbf
+#define RESCAN_TIMEOUT_MS 2500
547cbf
+#define MAX_RESCAN_RETRIES 6
547cbf
 
547cbf
 /* Vendor prefixes are something that can be preprended to a .desktop
547cbf
  * file name.  Undo this.
547cbf
@@ -51,6 +59,9 @@ struct _ShellAppSystemPrivate {
547cbf
   GHashTable *id_to_app;
547cbf
   GHashTable *startup_wm_class_to_id;
547cbf
   GList *installed_apps;
547cbf
+
547cbf
+  guint rescan_icons_timeout_id;
547cbf
+  guint n_rescan_retries;
547cbf
 };
547cbf
 
547cbf
 static void shell_app_system_finalize (GObject *object);
547cbf
@@ -157,12 +168,54 @@ stale_app_remove_func (gpointer key,
547cbf
   return app_is_stale (value);
547cbf
 }
547cbf
 
547cbf
+static gboolean
547cbf
+rescan_icon_theme_cb (gpointer user_data)
547cbf
+{
547cbf
+  ShellAppSystemPrivate *priv;
547cbf
+  ShellAppSystem *self;
547cbf
+  StTextureCache *texture_cache;
547cbf
+  gboolean rescanned;
547cbf
+
547cbf
+  self = (ShellAppSystem *) user_data;
547cbf
+  priv = self->priv;
547cbf
+
547cbf
+  texture_cache = st_texture_cache_get_default ();
547cbf
+  rescanned = st_texture_cache_rescan_icon_theme (texture_cache);
547cbf
+
547cbf
+  priv->n_rescan_retries++;
547cbf
+
547cbf
+  if (rescanned || priv->n_rescan_retries >= MAX_RESCAN_RETRIES)
547cbf
+    {
547cbf
+      priv->n_rescan_retries = 0;
547cbf
+      priv->rescan_icons_timeout_id = 0;
547cbf
+      return G_SOURCE_REMOVE;
547cbf
+    }
547cbf
+
547cbf
+  return G_SOURCE_CONTINUE;
547cbf
+}
547cbf
+
547cbf
+static void
547cbf
+rescan_icon_theme (ShellAppSystem *self)
547cbf
+{
547cbf
+  ShellAppSystemPrivate *priv = self->priv;
547cbf
+
547cbf
+  priv->n_rescan_retries = 0;
547cbf
+
547cbf
+  if (priv->rescan_icons_timeout_id > 0)
547cbf
+    return;
547cbf
+
547cbf
+  priv->rescan_icons_timeout_id = g_timeout_add (RESCAN_TIMEOUT_MS,
547cbf
+                                                 rescan_icon_theme_cb,
547cbf
+                                                 self);
547cbf
+}
547cbf
+
547cbf
 static void
547cbf
 installed_changed (GAppInfoMonitor *monitor,
547cbf
                    gpointer         user_data)
547cbf
 {
547cbf
   ShellAppSystem *self = user_data;
547cbf
 
547cbf
+  rescan_icon_theme (self);
547cbf
   scan_startup_wm_class_to_id (self);
547cbf
 
547cbf
   g_hash_table_foreach_remove (self->priv->id_to_app, stale_app_remove_func, NULL);
547cbf
@@ -200,6 +253,7 @@ shell_app_system_finalize (GObject *object)
547cbf
   g_hash_table_destroy (priv->id_to_app);
547cbf
   g_hash_table_destroy (priv->startup_wm_class_to_id);
547cbf
   g_list_free_full (priv->installed_apps, g_object_unref);
547cbf
+  g_clear_handle_id (&priv->rescan_icons_timeout_id, g_source_remove);
547cbf
 
547cbf
   G_OBJECT_CLASS (shell_app_system_parent_class)->finalize (object);
547cbf
 }
547cbf
diff --git a/src/st/st-texture-cache.c b/src/st/st-texture-cache.c
547cbf
index 0c794a3ab..ab6d494b7 100644
547cbf
--- a/src/st/st-texture-cache.c
547cbf
+++ b/src/st/st-texture-cache.c
547cbf
@@ -1425,3 +1425,11 @@ st_texture_cache_get_default (void)
547cbf
     instance = g_object_new (ST_TYPE_TEXTURE_CACHE, NULL);
547cbf
   return instance;
547cbf
 }
547cbf
+
547cbf
+gboolean
547cbf
+st_texture_cache_rescan_icon_theme (StTextureCache *cache)
547cbf
+{
547cbf
+  StTextureCachePrivate *priv = cache->priv;
547cbf
+
547cbf
+  return gtk_icon_theme_rescan_if_needed (priv->icon_theme);
547cbf
+}
547cbf
diff --git a/src/st/st-texture-cache.h b/src/st/st-texture-cache.h
547cbf
index 26f9c30ac..606694c86 100644
547cbf
--- a/src/st/st-texture-cache.h
547cbf
+++ b/src/st/st-texture-cache.h
547cbf
@@ -106,4 +106,6 @@ CoglTexture * st_texture_cache_load (StTextureCache       *cache,
547cbf
                                      void                 *data,
547cbf
                                      GError              **error);
547cbf
 
547cbf
+gboolean st_texture_cache_rescan_icon_theme (StTextureCache *cache);
547cbf
+
547cbf
 #endif /* __ST_TEXTURE_CACHE_H__ */
547cbf
-- 
547cbf
2.26.0
547cbf