[gnome-shell] Bug 581944 - Fully rebase on ShellAppSystem, don't use Gio to load apps



commit 5416f53351345655f9a893f508b76b12fdbc472c
Author: Colin Walters <walters verbum org>
Date:   Thu May 14 14:14:18 2009 -0400

    Bug 581944 - Fully rebase on ShellAppSystem, don't use Gio to load apps
    
    To avoid loading applications from two different systems, use
    ShellAppSystem solely.  This unifies the initial load and the
    reload.
    
    Extend ShellAppSystem to also load settings/preferences, and
    ensure they appear in the search.
---
 js/ui/appDisplay.js    |   54 +++++++++++-----
 src/shell-app-system.c |  155 +++++++++++++++++++++++++++++++++---------------
 src/shell-app-system.h |    6 +-
 3 files changed, 148 insertions(+), 67 deletions(-)

diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index fd47596..6b2279e 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -237,7 +237,7 @@ AppDisplay.prototype = {
             this._redisplayMenus();
         }));
         this._appMonitor.connect('changed', Lang.bind(this, function(monitor) {
-            this._redisplay(false)
+            this._redisplay(false);
         }));
 
         // Load the GAppInfos now so it doesn't slow down the first
@@ -345,6 +345,18 @@ AppDisplay.prototype = {
         }
     },
 
+    addApp: function(appId) {
+        let appInfo = Gio.DesktopAppInfo.new(appId);
+        if (appInfo != null) {
+            this._allItems[appId] = appInfo;
+            // [] is returned if we could not get the categories or the list of categories was empty
+            let categories = Shell.get_categories_for_desktop_file(appId);
+            this._appCategories[appId] = categories;
+        } else {
+            log("appInfo for " + appId + " was not found.");
+        }
+    },
+
     //// Protected method overrides //// 
 
     // Gets information about all applications by calling Gio.app_info_get_all().
@@ -357,19 +369,25 @@ AppDisplay.prototype = {
 
         this._menus = this._appSystem.get_menus();
 
-        let apps = Gio.app_info_get_all();
-        for (let i = 0; i < apps.length; i++) {
-            let appInfo = apps[i];
-            
-            if (!appInfo.should_show())
-                continue;
-            
-            let appId = appInfo.get_id();
-            this._allItems[appId] = appInfo;
-            // [] is returned if we could not get the categories or the list of categories was empty
-            let categories = Shell.get_categories_for_desktop_file(appId);
-            this._appCategories[appId] = categories;
+        // Loop over the toplevel menu items, load the set of desktop file ids
+        // associated with each one
+        for (let i = 0; i < this._menus.length; i++) {
+            let menu = this._menus[i];
+            let menuApps = this._appSystem.get_applications_for_menu(menu.id);
+            for (let j = 0; j < menuApps.length; j++) {
+                let appId = menuApps[j];
+                this._addApp(appId);
+            }
         }
+
+        // Now grab the desktop file ids for settings/preferences.
+        // These show up in search, but not with the rest of apps.
+        let settings = this._appSystem.get_all_settings();
+        for (let i = 0; i < settings.length; i++) {
+            let appId = settings[i];
+			this._addApp(appId);
+        }
+
         this._appsStale = false;
     },
 
@@ -459,10 +477,12 @@ AppDisplay.prototype = {
 
         // we expect this._appCategories.hasOwnProperty(itemInfo.get_id()) to always be true here
         let categories = this._appCategories[itemInfo.get_id()];
-        for (let i = 0; i < categories.length; i++) {
-            let category = categories[i].toLowerCase();
-            if (category.indexOf(search) >= 0)
-                return true;
+        if (categories) {
+            for (let i = 0; i < categories.length; i++) {
+                let category = categories[i].toLowerCase();
+                if (category.indexOf(search) >= 0)
+                    return true;
+            }
         }
        
         return false;
diff --git a/src/shell-app-system.c b/src/shell-app-system.c
index 022d0e7..8829389 100644
--- a/src/shell-app-system.c
+++ b/src/shell-app-system.c
@@ -20,10 +20,12 @@ enum {
 static guint signals[LAST_SIGNAL] = { 0 };
 
 struct _ShellAppSystemPrivate {
-  GMenuTree *tree;
-  GMenuTreeDirectory *trunk;
+  GMenuTree *apps_tree;
+  GMenuTree *settings_tree;
+
+  GSList *cached_app_menus; /* ShellAppMenuEntry */
 
-  GList *cached_menus;
+  GSList *cached_setting_ids; /* utf8 */
 };
 
 static void shell_app_system_finalize (GObject *object);
@@ -81,11 +83,11 @@ shell_app_system_init (ShellAppSystem *self)
                                                    SHELL_TYPE_APP_SYSTEM,
                                                    ShellAppSystemPrivate);
 
-  priv->tree = gmenu_tree_lookup ("applications.menu", GMENU_TREE_FLAGS_NONE);
-
-  priv->trunk = gmenu_tree_get_root_directory (priv->tree);
+  priv->apps_tree = gmenu_tree_lookup ("applications.menu", GMENU_TREE_FLAGS_NONE);
+  priv->settings_tree = gmenu_tree_lookup ("settings.menu", GMENU_TREE_FLAGS_NONE);
 
-  gmenu_tree_add_monitor (priv->tree, on_tree_changed, self);
+  gmenu_tree_add_monitor (priv->apps_tree, on_tree_changed, self);
+  gmenu_tree_add_monitor (priv->settings_tree, on_tree_changed, self);
 
   reread_menus (self);
 }
@@ -96,23 +98,37 @@ shell_app_system_finalize (GObject *object)
   ShellAppSystem *self = SHELL_APP_SYSTEM (object);
   ShellAppSystemPrivate *priv = self->priv;
 
-  gmenu_tree_remove_monitor (priv->tree, on_tree_changed, self);
+  gmenu_tree_remove_monitor (priv->apps_tree, on_tree_changed, self);
+  gmenu_tree_remove_monitor (priv->settings_tree, on_tree_changed, self);
 
-  gmenu_tree_unref (priv->tree);
+  gmenu_tree_unref (priv->apps_tree);
+  gmenu_tree_unref (priv->settings_tree);
+
+  g_slist_foreach (priv->cached_app_menus, (GFunc)shell_app_menu_entry_free, NULL);
+  g_slist_free (priv->cached_app_menus);
+  priv->cached_app_menus = NULL;
+
+  g_slist_foreach (priv->cached_setting_ids, (GFunc)g_free, NULL);
+  g_slist_free (priv->cached_setting_ids);
+  priv->cached_setting_ids = NULL;
 
   G_OBJECT_CLASS (shell_app_system_parent_class)->finalize(object);
 }
 
 static void
-reread_menus (ShellAppSystem *self)
+reread_directories (ShellAppSystem *self, GSList **cache, GMenuTree *tree)
 {
-  GSList *entries = gmenu_tree_directory_get_contents (self->priv->trunk);
-  GSList *iter;
   ShellAppSystemPrivate *priv = self->priv;
+  GMenuTreeDirectory *trunk;
+  GSList *entries;
+  GSList *iter;
 
-  g_list_foreach (self->priv->cached_menus, (GFunc)shell_app_menu_entry_free, NULL);
-  g_list_free (self->priv->cached_menus);
-  self->priv->cached_menus = NULL;
+  trunk = gmenu_tree_get_root_directory (tree);
+  entries = gmenu_tree_directory_get_contents (trunk);
+
+  g_slist_foreach (*cache, (GFunc)shell_app_menu_entry_free, NULL);
+  g_slist_free (*cache);
+  *cache = NULL;
 
   for (iter = entries; iter; iter = iter->next)
     {
@@ -124,12 +140,11 @@ reread_menus (ShellAppSystem *self)
             {
               GMenuTreeDirectory *dir = iter->data;
               ShellAppMenuEntry *shell_entry = g_new0 (ShellAppMenuEntry, 1);
-
               shell_entry->name = g_strdup (gmenu_tree_directory_get_name (dir));
               shell_entry->id = g_strdup (gmenu_tree_directory_get_menu_id (dir));
               shell_entry->icon = g_strdup (gmenu_tree_directory_get_icon (dir));
 
-              priv->cached_menus = g_list_prepend (priv->cached_menus, shell_entry);
+              *cache = g_slist_prepend (*cache, shell_entry);
 
               gmenu_tree_item_unref (dir);
             }
@@ -138,37 +153,15 @@ reread_menus (ShellAppSystem *self)
             break;
         }
     }
-  priv->cached_menus = g_list_reverse (priv->cached_menus);
+  *cache = g_slist_reverse (*cache);
 
   g_slist_free (entries);
+  gmenu_tree_item_unref (trunk);
 }
 
-static void
-on_tree_changed (GMenuTree *monitor, gpointer user_data)
-{
-  ShellAppSystem *self = SHELL_APP_SYSTEM (user_data);
-
-  g_signal_emit (self, signals[CHANGED], 0);
-
-  reread_menus (self);
-}
-
-GType
-shell_app_menu_entry_get_type (void)
-{
-  static GType gtype = G_TYPE_INVALID;
-  if (gtype == G_TYPE_INVALID)
-    {
-      gtype = g_boxed_type_register_static ("ShellAppMenuEntry",
-          shell_app_menu_entry_copy,
-          shell_app_menu_entry_free);
-    }
-  return gtype;
-}
-
-static GList *
+static GSList *
 gather_entries_recurse (ShellAppSystem     *monitor,
-                        GList              *ids,
+                        GSList             *ids,
                         GMenuTreeDirectory *root)
 {
   GSList *contents;
@@ -185,7 +178,7 @@ gather_entries_recurse (ShellAppSystem     *monitor,
             {
               GMenuTreeEntry *entry = (GMenuTreeEntry *)item;
               const char *id = gmenu_tree_entry_get_desktop_file_id (entry);
-              ids = g_list_prepend (ids, g_strdup (id));
+              ids = g_slist_prepend (ids, g_strdup (id));
             }
             break;
           case GMENU_TREE_ITEM_DIRECTORY:
@@ -205,12 +198,63 @@ gather_entries_recurse (ShellAppSystem     *monitor,
   return ids;
 }
 
+static void
+reread_entries (ShellAppSystem     *self,
+                GSList            **cache,
+                GMenuTree          *tree)
+{
+  GMenuTreeDirectory *trunk;
+
+  trunk = gmenu_tree_get_root_directory (tree);
+
+  g_slist_foreach (*cache, (GFunc)g_free, NULL);
+  g_slist_free (*cache);
+  *cache = NULL;
+
+  *cache = gather_entries_recurse (self, *cache, trunk);
+
+  gmenu_tree_item_unref (trunk);
+}
+
+static void
+reread_menus (ShellAppSystem *self)
+{
+  reread_directories (self, &(self->priv->cached_app_menus), self->priv->apps_tree);
+  reread_entries (self, &(self->priv->cached_setting_ids), self->priv->settings_tree);
+}
+
+static void
+on_tree_changed (GMenuTree *monitor, gpointer user_data)
+{
+  ShellAppSystem *self = SHELL_APP_SYSTEM (user_data);
+
+  g_signal_emit (self, signals[CHANGED], 0);
+
+  reread_menus (self);
+}
+
+GType
+shell_app_menu_entry_get_type (void)
+{
+  static GType gtype = G_TYPE_INVALID;
+  if (gtype == G_TYPE_INVALID)
+    {
+      gtype = g_boxed_type_register_static ("ShellAppMenuEntry",
+          shell_app_menu_entry_copy,
+          shell_app_menu_entry_free);
+    }
+  return gtype;
+}
+
 /**
  * shell_app_system_get_applications_for_menu:
  *
+ * Traverses a toplevel menu, and returns all items under it.  Nested items
+ * are flattened.
+ *
  * Return value: (transfer full) (element-type utf8): List of desktop file ids
  */
-GList *
+GSList *
 shell_app_system_get_applications_for_menu (ShellAppSystem *monitor,
                                             const char *menu)
 {
@@ -218,7 +262,7 @@ shell_app_system_get_applications_for_menu (ShellAppSystem *monitor,
   GMenuTreeDirectory *menu_entry;
 
   path = g_strdup_printf ("/%s", menu);
-  menu_entry = gmenu_tree_get_directory_from_path (monitor->priv->tree, path);
+  menu_entry = gmenu_tree_get_directory_from_path (monitor->priv->apps_tree, path);
   g_free (path);
   g_assert (menu_entry != NULL);
 
@@ -228,10 +272,25 @@ shell_app_system_get_applications_for_menu (ShellAppSystem *monitor,
 /**
  * shell_app_system_get_menus:
  *
+ * Returns a list of toplevel menu names, like "Accessories", "Programming", etc.
+ *
  * Return value: (transfer none) (element-type AppMenuEntry): List of toplevel menus
  */
-GList *
+GSList *
 shell_app_system_get_menus (ShellAppSystem *monitor)
 {
-  return monitor->priv->cached_menus;
+  return monitor->priv->cached_app_menus;
+}
+
+/**
+ * shell_app_system_get_all_settings:
+ *
+ * Returns a list of all desktop file ids under "settings.menu".
+ *
+ * Return value: (transfer full) (element-type utf8): List of desktop file ids
+ */
+GSList *
+shell_app_system_get_all_settings (ShellAppSystem *monitor)
+{
+  return monitor->priv->cached_setting_ids;
 }
diff --git a/src/shell-app-system.h b/src/shell-app-system.h
index 090643f..cbd2d2e 100644
--- a/src/shell-app-system.h
+++ b/src/shell-app-system.h
@@ -31,7 +31,7 @@ struct _ShellAppSystemClass
 GType shell_app_system_get_type (void) G_GNUC_CONST;
 ShellAppSystem* shell_app_system_new(void);
 
-GList *shell_app_system_get_applications_for_menu (ShellAppSystem *monitor, const char *menu);
+GSList *shell_app_system_get_applications_for_menu (ShellAppSystem *system, const char *menu);
 
 typedef struct _ShellAppMenuEntry ShellAppMenuEntry;
 
@@ -43,6 +43,8 @@ struct _ShellAppMenuEntry {
 
 GType shell_app_menu_entry_get_type (void);
 
-GList *shell_app_system_get_menus (ShellAppSystem *monitor);
+GSList *shell_app_system_get_menus (ShellAppSystem *system);
+
+GSList *shell_app_system_get_all_settings (ShellAppSystem *system);
 
 #endif /* __SHELL_APP_SYSTEM_H__ */



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