[gnome-shell/T29763: 36/249] shell-app-system: Add a new app-info-changed signal



commit cc185963cad1f5fc541f5383ebc92975029735f1
Author: Mario Sanchez Prada <mario endlessm com>
Date:   Mon Jun 5 17:20:37 2017 +0100

    shell-app-system: Add a new app-info-changed signal
    
    This will help us identifying when an application has actually changed.

 src/shell-app-system.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 88 insertions(+), 5 deletions(-)
---
diff --git a/src/shell-app-system.c b/src/shell-app-system.c
index 67f425cf6d..d8738dc141 100644
--- a/src/shell-app-system.c
+++ b/src/shell-app-system.c
@@ -56,6 +56,7 @@ enum {
 enum {
   APP_STATE_CHANGED,
   INSTALLED_CHANGED,
+  APP_INFO_CHANGED,
   LAST_SIGNAL
 };
 
@@ -107,6 +108,15 @@ static void shell_app_system_class_init(ShellAppSystemClass *klass)
                   0,
                   NULL, NULL, NULL,
                  G_TYPE_NONE, 0);
+
+  signals[APP_INFO_CHANGED] =
+    g_signal_new ("app-info-changed",
+                  SHELL_TYPE_APP_SYSTEM,
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 1,
+                  SHELL_TYPE_APP);
 }
 
 static void
@@ -210,12 +220,85 @@ app_is_stale (ShellApp *app)
   return !is_unchanged;
 }
 
+static GDesktopAppInfo *
+get_new_desktop_app_info_from_app (ShellApp *app)
+{
+  const char *id;
+
+  if (shell_app_is_window_backed (app))
+    return NULL;
+
+  /* If g_app_info_delete() was called, such as when a custom desktop
+   * icon is removed, the desktop ID of the underlying GDesktopAppInfo
+   * will be set to NULL.
+   * So we explicitly check for that case and mark the app as stale.
+   * See https://git.gnome.org/browse/glib/tree/gio/gdesktopappinfo.c?h=glib-2-44&id=2.44.0#n3682
+   */
+  id = shell_app_get_id (app);
+  if (id == NULL)
+    return NULL;
+
+  return g_desktop_app_info_new (id);
+}
+
 static gboolean
-stale_app_remove_func (gpointer key,
-                       gpointer value,
-                       gpointer user_data)
+app_info_changed (ShellApp        *app,
+                  GDesktopAppInfo *desk_new_info)
+{
+  GIcon *app_icon;
+  GIcon *new_icon;
+  GDesktopAppInfo *desk_app_info = shell_app_get_app_info (app);
+  GAppInfo *app_info = G_APP_INFO (desk_app_info);
+  GAppInfo *new_info = G_APP_INFO (desk_new_info);
+
+  if (!app_info)
+    return TRUE;
+
+  app_icon = g_app_info_get_icon (app_info);
+  new_icon = g_app_info_get_icon (new_info);
+
+  return !(g_app_info_equal (app_info, new_info) &&
+           g_icon_equal (app_icon, new_icon) &&
+           g_app_info_should_show (app_info) == g_app_info_should_show (new_info) &&
+           strcmp (g_desktop_app_info_get_filename (desk_app_info),
+                   g_desktop_app_info_get_filename (desk_new_info)) == 0 &&
+           g_strcmp0 (g_app_info_get_executable (app_info),
+                      g_app_info_get_executable (new_info)) == 0 &&
+           g_strcmp0 (g_app_info_get_commandline (app_info),
+                      g_app_info_get_commandline (new_info)) == 0 &&
+           strcmp (g_app_info_get_name (app_info),
+                   g_app_info_get_name (new_info)) == 0 &&
+           strcmp (g_app_info_get_display_name (app_info),
+                   g_app_info_get_display_name (new_info)) == 0 &&
+           g_strcmp0 (g_app_info_get_description (app_info),
+                      g_app_info_get_description (new_info)) == 0);
+}
+
+static void
+remove_or_update_app_from_info (ShellAppSystem *self)
 {
-  return app_is_stale (value);
+  GHashTableIter iter;
+  ShellApp *app;
+
+  g_hash_table_iter_init (&iter, self->priv->id_to_app);
+  while (g_hash_table_iter_next (&iter, NULL, (gpointer) &app))
+    {
+      g_autoptr(GDesktopAppInfo) app_info = NULL;
+
+      if (app_is_stale (app))
+        {
+          /* App is stale, we remove it */
+          g_hash_table_iter_remove (&iter);
+          continue;
+        }
+
+      app_info = get_new_desktop_app_info_from_app (app);
+      if (app_info_changed (app, app_info))
+        {
+          _shell_app_set_app_info (app, app_info);
+          g_signal_emit (self, signals[APP_INFO_CHANGED], 0, app);
+        }
+    }
 }
 
 static gboolean
@@ -268,7 +351,7 @@ installed_changed (ShellAppCache  *cache,
 
   scan_startup_wm_class_to_id (self);
 
-  g_hash_table_foreach_remove (self->priv->id_to_app, stale_app_remove_func, NULL);
+  remove_or_update_app_from_info (self);
 
   g_signal_emit (self, signals[INSTALLED_CHANGED], 0, NULL);
 }


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