Compare commits
	
		
			15 Commits
		
	
	
		
			3.37.91
			...
			wip/deskto
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 45797a977b | ||
|   | 884b94233e | ||
|   | 74d3e3139f | ||
|   | 77b5385cc3 | ||
|   | d749d646be | ||
|   | fa8224d7b5 | ||
|   | f687197ccc | ||
|   | 28a6aefb6c | ||
|   | 96c2a90e11 | ||
|   | 63cf46e49b | ||
|   | 200a9ef1af | ||
|   | 6050ca6e0c | ||
|   | 8bd7db9227 | ||
|   | 982feb85c1 | ||
|   | f165cc23c0 | 
| @@ -70,7 +70,6 @@ POLKIT_MIN_VERSION=0.100 | ||||
| STARTUP_NOTIFICATION_MIN_VERSION=0.11 | ||||
| GCR_MIN_VERSION=3.7.5 | ||||
| GNOME_DESKTOP_REQUIRED_VERSION=3.7.90 | ||||
| GNOME_MENUS_REQUIRED_VERSION=3.5.3 | ||||
| NETWORKMANAGER_MIN_VERSION=0.9.8 | ||||
| PULSE_MIN_VERS=2.0 | ||||
|  | ||||
| @@ -80,7 +79,6 @@ SHARED_PCS="gio-unix-2.0 >= $GIO_MIN_VERSION | ||||
|             gtk+-3.0 >= $GTK_MIN_VERSION | ||||
|             atk-bridge-2.0 | ||||
|             gjs-internals-1.0 >= $GJS_MIN_VERSION | ||||
|             libgnome-menu-3.0 >= $GNOME_MENUS_REQUIRED_VERSION | ||||
|             $recorder_modules | ||||
|             gdk-x11-3.0 libsoup-2.4 | ||||
|             xtst | ||||
|   | ||||
| @@ -55,13 +55,13 @@ function _loadCategory(dir, view) { | ||||
|     while ((nextType = iter.next()) != GMenu.TreeItemType.INVALID) { | ||||
|         if (nextType == GMenu.TreeItemType.ENTRY) { | ||||
|             let entry = iter.get_entry(); | ||||
|             let app = appSystem.lookup_app_by_tree_entry(entry); | ||||
|             if (!entry.get_app_info().get_nodisplay()) | ||||
|             let appInfo = entry.get_app_info(); | ||||
|             let app = appSystem.lookup_app(entry.get_desktop_file_id()); | ||||
|             if (appInfo.should_show()) | ||||
|                 view.addApp(app); | ||||
|         } else if (nextType == GMenu.TreeItemType.DIRECTORY) { | ||||
|             let itemDir = iter.get_directory(); | ||||
|             if (!itemDir.get_is_nodisplay()) | ||||
|                 _loadCategory(itemDir, view); | ||||
|             _loadCategory(itemDir, view); | ||||
|         } | ||||
|     } | ||||
| }; | ||||
| @@ -691,8 +691,7 @@ const AppDisplay = new Lang.Class({ | ||||
|     Name: 'AppDisplay', | ||||
|  | ||||
|     _init: function() { | ||||
|         this._appSystem = Shell.AppSystem.get_default(); | ||||
|         this._appSystem.connect('installed-changed', Lang.bind(this, function() { | ||||
|         Shell.AppSystem.get_default().connect('installed-changed', Lang.bind(this, function() { | ||||
|             Main.queueDeferredWork(this._allAppsWorkId); | ||||
|         })); | ||||
|         Main.overview.connect('showing', Lang.bind(this, function() { | ||||
| @@ -808,7 +807,8 @@ const AppDisplay = new Lang.Class({ | ||||
|  | ||||
|         view.removeAll(); | ||||
|  | ||||
|         let tree = this._appSystem.get_tree(); | ||||
|         let tree = new GMenu.Tree({ menu_basename: "applications.menu" }); | ||||
|         tree.load_sync(); | ||||
|         let root = tree.get_root_directory(); | ||||
|  | ||||
|         let iter = root.iter(); | ||||
| @@ -817,8 +817,6 @@ const AppDisplay = new Lang.Class({ | ||||
|         while ((nextType = iter.next()) != GMenu.TreeItemType.INVALID) { | ||||
|             if (nextType == GMenu.TreeItemType.DIRECTORY) { | ||||
|                 let dir = iter.get_directory(); | ||||
|                 if (dir.get_is_nodisplay()) | ||||
|                     continue; | ||||
|  | ||||
|                 if (folderCategories.indexOf(dir.get_menu_id()) != -1) | ||||
|                     view.addFolder(dir); | ||||
| @@ -866,8 +864,8 @@ const AppSearchProvider = new Lang.Class({ | ||||
|     getResultMetas: function(apps, callback) { | ||||
|         let metas = []; | ||||
|         for (let i = 0; i < apps.length; i++) { | ||||
|             let app = apps[i]; | ||||
|             metas.push({ 'id': app, | ||||
|             let app = this._appSys.lookup_app(apps[i]); | ||||
|             metas.push({ 'id': app.get_id(), | ||||
|                          'name': app.get_name(), | ||||
|                          'createIcon': function(size) { | ||||
|                              return app.create_icon_texture(size); | ||||
| @@ -877,15 +875,23 @@ const AppSearchProvider = new Lang.Class({ | ||||
|         callback(metas); | ||||
|     }, | ||||
|  | ||||
|     _compareResults: function(a, b) { | ||||
|         let usage = Shell.AppUsage.get_default(); | ||||
|         return usage.compare('', a, b); | ||||
|     }, | ||||
|  | ||||
|     getInitialResultSet: function(terms) { | ||||
|         this.searchSystem.setResults(this, this._appSys.initial_search(terms)); | ||||
|         let query = terms.join(' '); | ||||
|         let results = Gio.DesktopAppInfo.search(query, Lang.bind(this, this._compareResults), MAX_COLUMNS); | ||||
|         this.searchSystem.setResults(this, results); | ||||
|     }, | ||||
|  | ||||
|     getSubsearchResultSet: function(previousResults, terms) { | ||||
|         this.searchSystem.setResults(this, this._appSys.subsearch(previousResults, terms)); | ||||
|         this.getInitialResultSet(terms); | ||||
|     }, | ||||
|  | ||||
|     activateResult: function(app) { | ||||
|     activateResult: function(result) { | ||||
|         let app = this._appSys.lookup_app(result); | ||||
|         let event = Clutter.get_current_event(); | ||||
|         let modifiers = event ? event.get_state() : 0; | ||||
|         let openNewWindow = modifiers & Clutter.ModifierType.CONTROL_MASK; | ||||
| @@ -905,7 +911,7 @@ const AppSearchProvider = new Lang.Class({ | ||||
|     }, | ||||
|  | ||||
|     createResultObject: function (resultMeta, terms) { | ||||
|         let app = resultMeta['id']; | ||||
|         let app = this._appSys.lookup_app(resultMeta['id']); | ||||
|         return new AppIcon(app); | ||||
|     } | ||||
| }); | ||||
|   | ||||
| @@ -12,9 +12,9 @@ G_BEGIN_DECLS | ||||
|  | ||||
| ShellApp* _shell_app_new_for_window (MetaWindow *window); | ||||
|  | ||||
| ShellApp* _shell_app_new (GMenuTreeEntry *entry); | ||||
| ShellApp* _shell_app_new (GDesktopAppInfo *info); | ||||
|  | ||||
| void _shell_app_set_entry (ShellApp *app, GMenuTreeEntry *entry); | ||||
| void _shell_app_set_app_info (ShellApp *app, GDesktopAppInfo *info); | ||||
|  | ||||
| void _shell_app_handle_startup_sequence (ShellApp *app, SnStartupSequence *sequence); | ||||
|  | ||||
|   | ||||
| @@ -38,18 +38,12 @@ enum { | ||||
| static guint signals[LAST_SIGNAL] = { 0 }; | ||||
|  | ||||
| struct _ShellAppSystemPrivate { | ||||
|   GMenuTree *apps_tree; | ||||
|  | ||||
|   GHashTable *running_apps; | ||||
|   GHashTable *visible_id_to_app; | ||||
|   GHashTable *id_to_app; | ||||
|   GHashTable *startup_wm_class_to_app; | ||||
|  | ||||
|   GSList *known_vendor_prefixes; | ||||
|   GHashTable *startup_wm_class_to_id; | ||||
| }; | ||||
|  | ||||
| static void shell_app_system_finalize (GObject *object); | ||||
| static void on_apps_tree_changed_cb (GMenuTree *tree, gpointer user_data); | ||||
|  | ||||
| G_DEFINE_TYPE(ShellAppSystem, shell_app_system, G_TYPE_OBJECT); | ||||
|  | ||||
| @@ -77,10 +71,45 @@ static void shell_app_system_class_init(ShellAppSystemClass *klass) | ||||
|   g_type_class_add_private (gobject_class, sizeof (ShellAppSystemPrivate)); | ||||
| } | ||||
|  | ||||
| static void | ||||
| scan_startup_wm_class_to_id (ShellAppSystem *self) | ||||
| { | ||||
|   ShellAppSystemPrivate *priv = self->priv; | ||||
|   GList *apps, *l; | ||||
|  | ||||
|   g_hash_table_remove_all (priv->startup_wm_class_to_id); | ||||
|  | ||||
|   apps = g_app_info_get_all (); | ||||
|   for (l = apps; l != NULL; l = l->next) | ||||
|     { | ||||
|       GAppInfo *info = l->data; | ||||
|       const char *startup_wm_class, *id; | ||||
|  | ||||
|       id = g_app_info_get_id (info); | ||||
|       startup_wm_class = g_desktop_app_info_get_startup_wm_class (G_DESKTOP_APP_INFO (info)); | ||||
|       if (startup_wm_class != NULL) | ||||
|         g_hash_table_insert (priv->startup_wm_class_to_id, (char *) startup_wm_class, (char *) id); | ||||
|     } | ||||
|  | ||||
|   g_list_free_full (apps, g_object_unref); | ||||
| } | ||||
|  | ||||
| static void | ||||
| installed_changed (GAppInfoMonitor *monitor, | ||||
|                    gpointer         user_data) | ||||
| { | ||||
|   ShellAppSystem *self = user_data; | ||||
|  | ||||
|   scan_startup_wm_class_to_id (self); | ||||
|  | ||||
|   g_signal_emit (self, signals[INSTALLED_CHANGED], 0, NULL); | ||||
| } | ||||
|  | ||||
| static void | ||||
| shell_app_system_init (ShellAppSystem *self) | ||||
| { | ||||
|   ShellAppSystemPrivate *priv; | ||||
|   GAppInfoMonitor *monitor; | ||||
|  | ||||
|   self->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (self, | ||||
|                                                    SHELL_TYPE_APP_SYSTEM, | ||||
| @@ -91,19 +120,11 @@ shell_app_system_init (ShellAppSystem *self) | ||||
|                                            NULL, | ||||
|                                            (GDestroyNotify)g_object_unref); | ||||
|  | ||||
|   /* All the objects in this hash table are owned by id_to_app */ | ||||
|   priv->visible_id_to_app = g_hash_table_new (g_str_hash, g_str_equal); | ||||
|   priv->startup_wm_class_to_id = g_hash_table_new (g_str_hash, g_str_equal); | ||||
|  | ||||
|   priv->startup_wm_class_to_app = g_hash_table_new_full (g_str_hash, g_str_equal, | ||||
|                                                          NULL, | ||||
|                                                          (GDestroyNotify)g_object_unref); | ||||
|  | ||||
|   /* We want to track NoDisplay apps, so we add INCLUDE_NODISPLAY. We'll | ||||
|    * filter NoDisplay apps out when showing them to the user. */ | ||||
|   priv->apps_tree = gmenu_tree_new ("applications.menu", GMENU_TREE_FLAGS_INCLUDE_NODISPLAY); | ||||
|   g_signal_connect (priv->apps_tree, "changed", G_CALLBACK (on_apps_tree_changed_cb), self); | ||||
|  | ||||
|   on_apps_tree_changed_cb (priv->apps_tree, self); | ||||
|   monitor = g_app_info_monitor_get (); | ||||
|   g_signal_connect (monitor, "changed", G_CALLBACK (installed_changed), self); | ||||
|   installed_changed (monitor, self); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -112,313 +133,13 @@ shell_app_system_finalize (GObject *object) | ||||
|   ShellAppSystem *self = SHELL_APP_SYSTEM (object); | ||||
|   ShellAppSystemPrivate *priv = self->priv; | ||||
|  | ||||
|   g_object_unref (priv->apps_tree); | ||||
|  | ||||
|   g_hash_table_destroy (priv->running_apps); | ||||
|   g_hash_table_destroy (priv->id_to_app); | ||||
|   g_hash_table_destroy (priv->visible_id_to_app); | ||||
|   g_hash_table_destroy (priv->startup_wm_class_to_app); | ||||
|  | ||||
|   g_slist_free_full (priv->known_vendor_prefixes, g_free); | ||||
|   priv->known_vendor_prefixes = NULL; | ||||
|   g_hash_table_destroy (priv->startup_wm_class_to_id); | ||||
|  | ||||
|   G_OBJECT_CLASS (shell_app_system_parent_class)->finalize (object); | ||||
| } | ||||
|  | ||||
| static char * | ||||
| get_prefix_for_entry (GMenuTreeEntry *entry) | ||||
| { | ||||
|   char *prefix = NULL, *file_prefix = NULL; | ||||
|   const char *id; | ||||
|   GFile *file; | ||||
|   char *name; | ||||
|   int i = 0; | ||||
|  | ||||
|   id = gmenu_tree_entry_get_desktop_file_id (entry); | ||||
|   file = g_file_new_for_path (gmenu_tree_entry_get_desktop_file_path (entry)); | ||||
|   name = g_file_get_basename (file); | ||||
|  | ||||
|   if (!name) | ||||
|     { | ||||
|       g_object_unref (file); | ||||
|       return NULL; | ||||
|     } | ||||
|   for (i = 0; vendor_prefixes[i]; i++) | ||||
|     { | ||||
|       if (g_str_has_prefix (name, vendor_prefixes[i])) | ||||
|         { | ||||
|           file_prefix = g_strdup (vendor_prefixes[i]); | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   while (strcmp (name, id) != 0) | ||||
|     { | ||||
|       char *t; | ||||
|       char *pname; | ||||
|       GFile *parent = g_file_get_parent (file); | ||||
|  | ||||
|       if (!parent) | ||||
|         { | ||||
|           g_warn_if_reached (); | ||||
|           break; | ||||
|         } | ||||
|  | ||||
|       pname = g_file_get_basename (parent); | ||||
|       if (!pname) | ||||
|         { | ||||
|           g_object_unref (parent); | ||||
|           break; | ||||
|         } | ||||
|       if (!g_strstr_len (id, -1, pname)) | ||||
|         { | ||||
|           /* handle <LegacyDir prefix="..."> */ | ||||
|           char *t; | ||||
|           size_t name_len = strlen (name); | ||||
|           size_t id_len = strlen (id); | ||||
|           char *t_id = g_strdup (id); | ||||
|  | ||||
|           t_id[id_len - name_len] = '\0'; | ||||
|           t = g_strdup(t_id); | ||||
|           g_free (prefix); | ||||
|           g_free (t_id); | ||||
|           g_free (name); | ||||
|           name = g_strdup (id); | ||||
|           prefix = t; | ||||
|  | ||||
|           g_object_unref (file); | ||||
|           file = parent; | ||||
|           g_free (pname); | ||||
|           g_free (file_prefix); | ||||
|           file_prefix = NULL; | ||||
|           break; | ||||
|         } | ||||
|  | ||||
|       t = g_strconcat (pname, "-", name, NULL); | ||||
|       g_free (name); | ||||
|       name = t; | ||||
|  | ||||
|       t = g_strconcat (pname, "-", prefix, NULL); | ||||
|       g_free (prefix); | ||||
|       prefix = t; | ||||
|  | ||||
|       g_object_unref (file); | ||||
|       file = parent; | ||||
|       g_free (pname); | ||||
|     } | ||||
|  | ||||
|   if (file) | ||||
|     g_object_unref (file); | ||||
|  | ||||
|   if (strcmp (name, id) == 0) | ||||
|     { | ||||
|       g_free (name); | ||||
|       if (file_prefix && !prefix) | ||||
|         return file_prefix; | ||||
|       if (file_prefix) | ||||
|         { | ||||
|           char *t = g_strconcat (prefix, "-", file_prefix, NULL); | ||||
|           g_free (prefix); | ||||
|           g_free (file_prefix); | ||||
|           prefix = t; | ||||
|         } | ||||
|       return prefix; | ||||
|     } | ||||
|  | ||||
|   g_free (name); | ||||
|   g_free (prefix); | ||||
|   g_free (file_prefix); | ||||
|   g_return_val_if_reached (NULL); | ||||
| } | ||||
|  | ||||
| static void | ||||
| get_flattened_entries_recurse (GMenuTreeDirectory *dir, | ||||
|                                GHashTable         *entry_set) | ||||
| { | ||||
|   GMenuTreeIter *iter = gmenu_tree_directory_iter (dir); | ||||
|   GMenuTreeItemType next_type; | ||||
|  | ||||
|   while ((next_type = gmenu_tree_iter_next (iter)) != GMENU_TREE_ITEM_INVALID) | ||||
|     { | ||||
|       gpointer item = NULL; | ||||
|  | ||||
|       switch (next_type) | ||||
|         { | ||||
|         case GMENU_TREE_ITEM_ENTRY: | ||||
|           { | ||||
|             GMenuTreeEntry *entry; | ||||
|             item = entry = gmenu_tree_iter_get_entry (iter); | ||||
|             /* Key is owned by entry */ | ||||
|             g_hash_table_replace (entry_set, | ||||
|                                   (char*)gmenu_tree_entry_get_desktop_file_id (entry), | ||||
|                                   gmenu_tree_item_ref (entry)); | ||||
|           } | ||||
|           break; | ||||
|         case GMENU_TREE_ITEM_DIRECTORY: | ||||
|           { | ||||
|             item = gmenu_tree_iter_get_directory (iter); | ||||
|             get_flattened_entries_recurse ((GMenuTreeDirectory*)item, entry_set); | ||||
|           } | ||||
|           break; | ||||
|         default: | ||||
|           break; | ||||
|         } | ||||
|       if (item != NULL) | ||||
|         gmenu_tree_item_unref (item); | ||||
|     } | ||||
|  | ||||
|   gmenu_tree_iter_unref (iter); | ||||
| } | ||||
|  | ||||
| static GHashTable * | ||||
| get_flattened_entries_from_tree (GMenuTree *tree) | ||||
| { | ||||
|   GHashTable *table; | ||||
|   GMenuTreeDirectory *root; | ||||
|  | ||||
|   table = g_hash_table_new_full (g_str_hash, g_str_equal, | ||||
|                                  (GDestroyNotify) NULL, | ||||
|                                  (GDestroyNotify) gmenu_tree_item_unref); | ||||
|  | ||||
|   root = gmenu_tree_get_root_directory (tree); | ||||
|    | ||||
|   if (root != NULL) | ||||
|     get_flattened_entries_recurse (root, table); | ||||
|  | ||||
|   gmenu_tree_item_unref (root); | ||||
|    | ||||
|   return table; | ||||
| } | ||||
|  | ||||
| static void | ||||
| on_apps_tree_changed_cb (GMenuTree *tree, | ||||
|                          gpointer   user_data) | ||||
| { | ||||
|   ShellAppSystem *self = SHELL_APP_SYSTEM (user_data); | ||||
|   GError *error = NULL; | ||||
|   GHashTable *new_apps; | ||||
|   GHashTableIter iter; | ||||
|   gpointer key, value; | ||||
|  | ||||
|   g_assert (tree == self->priv->apps_tree); | ||||
|  | ||||
|   g_hash_table_remove_all (self->priv->visible_id_to_app); | ||||
|   g_slist_free_full (self->priv->known_vendor_prefixes, g_free); | ||||
|   self->priv->known_vendor_prefixes = NULL; | ||||
|  | ||||
|   if (!gmenu_tree_load_sync (self->priv->apps_tree, &error)) | ||||
|     { | ||||
|       if (error) | ||||
|         { | ||||
|           g_warning ("Failed to load apps: %s", error->message); | ||||
|           g_error_free (error); | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           g_warning ("Failed to load apps"); | ||||
|         } | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   new_apps = get_flattened_entries_from_tree (self->priv->apps_tree); | ||||
|   g_hash_table_iter_init (&iter, new_apps); | ||||
|   while (g_hash_table_iter_next (&iter, &key, &value)) | ||||
|     { | ||||
|       const char *id = key; | ||||
|       GMenuTreeEntry *entry = value; | ||||
|       GMenuTreeEntry *old_entry; | ||||
|       char *prefix; | ||||
|       ShellApp *app; | ||||
|       GDesktopAppInfo *info; | ||||
|       const char *startup_wm_class; | ||||
|  | ||||
|       prefix = get_prefix_for_entry (entry); | ||||
|  | ||||
|       if (prefix != NULL | ||||
|           && !g_slist_find_custom (self->priv->known_vendor_prefixes, prefix, | ||||
|                                    (GCompareFunc)g_strcmp0)) | ||||
|         self->priv->known_vendor_prefixes = g_slist_append (self->priv->known_vendor_prefixes, | ||||
|                                                             prefix); | ||||
|       else | ||||
|         g_free (prefix); | ||||
|  | ||||
|       app = g_hash_table_lookup (self->priv->id_to_app, id); | ||||
|       if (app != NULL) | ||||
|         { | ||||
|           /* We hold a reference to the original entry temporarily, | ||||
|            * because otherwise the hash table would be referencing | ||||
|            * potentially free'd memory until we replace it below with | ||||
|            * the new data. | ||||
|            */ | ||||
|           old_entry = shell_app_get_tree_entry (app); | ||||
|           gmenu_tree_item_ref (old_entry); | ||||
|           _shell_app_set_entry (app, entry); | ||||
|           g_object_ref (app);  /* Extra ref, removed in _replace below */ | ||||
|         } | ||||
|       else | ||||
|         { | ||||
|           old_entry = NULL; | ||||
|           app = _shell_app_new (entry); | ||||
|         } | ||||
|       /* Note that "id" is owned by app->entry.  Since we're always | ||||
|        * setting a new entry, even if the app already exists in the | ||||
|        * hash table we need to replace the key so that the new id | ||||
|        * string is pointed to. | ||||
|        */ | ||||
|       g_hash_table_replace (self->priv->id_to_app, (char*)id, app); | ||||
|       if (!gmenu_tree_entry_get_is_nodisplay_recurse (entry)) | ||||
|         g_hash_table_replace (self->priv->visible_id_to_app, (char*)id, app); | ||||
|  | ||||
|       if (old_entry) | ||||
|         { | ||||
|           GDesktopAppInfo *old_info; | ||||
|           const gchar *old_startup_wm_class; | ||||
|  | ||||
|           old_info = gmenu_tree_entry_get_app_info (old_entry); | ||||
|           old_startup_wm_class = g_desktop_app_info_get_startup_wm_class (old_info); | ||||
|  | ||||
|           if (old_startup_wm_class) | ||||
|             g_hash_table_remove (self->priv->startup_wm_class_to_app, old_startup_wm_class); | ||||
|         } | ||||
|  | ||||
|       info = gmenu_tree_entry_get_app_info (entry); | ||||
|       startup_wm_class = g_desktop_app_info_get_startup_wm_class (info); | ||||
|       if (startup_wm_class) | ||||
|         g_hash_table_replace (self->priv->startup_wm_class_to_app, | ||||
|                               (char*)startup_wm_class, g_object_ref (app)); | ||||
|  | ||||
|       if (old_entry) | ||||
|         gmenu_tree_item_unref (old_entry); | ||||
|     } | ||||
|   /* Now iterate over the apps again; we need to unreference any apps | ||||
|    * which have been removed.  The JS code may still be holding a | ||||
|    * reference; that's fine. | ||||
|    */ | ||||
|   g_hash_table_iter_init (&iter, self->priv->id_to_app); | ||||
|   while (g_hash_table_iter_next (&iter, &key, &value)) | ||||
|     { | ||||
|       const char *id = key; | ||||
|        | ||||
|       if (!g_hash_table_lookup (new_apps, id)) | ||||
|         g_hash_table_iter_remove (&iter); | ||||
|     } | ||||
|  | ||||
|   g_hash_table_destroy (new_apps); | ||||
|  | ||||
|   g_signal_emit (self, signals[INSTALLED_CHANGED], 0); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * shell_app_system_get_tree: | ||||
|  * | ||||
|  * Return Value: (transfer none): The #GMenuTree for apps | ||||
|  */ | ||||
| GMenuTree * | ||||
| shell_app_system_get_tree (ShellAppSystem *self) | ||||
| { | ||||
|   return self->priv->apps_tree; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * shell_app_system_get_default: | ||||
|  * | ||||
| @@ -446,61 +167,20 @@ ShellApp * | ||||
| shell_app_system_lookup_app (ShellAppSystem   *self, | ||||
|                              const char       *id) | ||||
| { | ||||
|   return g_hash_table_lookup (self->priv->id_to_app, id); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * shell_app_system_lookup_app_by_tree_entry: | ||||
|  * @system: a #ShellAppSystem | ||||
|  * @entry: a #GMenuTreeEntry | ||||
|  * | ||||
|  * Find a #ShellApp corresponding to a #GMenuTreeEntry. | ||||
|  * | ||||
|  * Return value: (transfer none): The #ShellApp for @entry, or %NULL if none | ||||
|  */ | ||||
| ShellApp * | ||||
| shell_app_system_lookup_app_by_tree_entry (ShellAppSystem  *self, | ||||
|                                            GMenuTreeEntry  *entry) | ||||
| { | ||||
|   /* If we looked up directly in ->entry_to_app, we'd lose the | ||||
|    * override of running apps.  Thus, indirect through the id. | ||||
|    */ | ||||
|   return shell_app_system_lookup_app (self, gmenu_tree_entry_get_desktop_file_id (entry)); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * shell_app_system_lookup_app_for_path: | ||||
|  * @system: a #ShellAppSystem | ||||
|  * @desktop_path: (type utf8): UTF-8 encoded absolute file name | ||||
|  * | ||||
|  * Find or create a #ShellApp corresponding to a given absolute file | ||||
|  * name which must be in the standard paths (XDG_DATA_DIRS).  For | ||||
|  * files outside the datadirs, this function returns %NULL. | ||||
|  * | ||||
|  * Return value: (transfer none): The #ShellApp for id, or %NULL if none | ||||
|  */ | ||||
| ShellApp * | ||||
| shell_app_system_lookup_app_for_path (ShellAppSystem   *system, | ||||
|                                       const char       *desktop_path) | ||||
| { | ||||
|   const char *basename; | ||||
|   const char *app_path; | ||||
|   ShellAppSystemPrivate *priv = self->priv; | ||||
|   ShellApp *app; | ||||
|   GDesktopAppInfo *info; | ||||
|  | ||||
|   basename = g_strrstr (desktop_path, "/"); | ||||
|   if (basename) | ||||
|     basename += 1; | ||||
|   else | ||||
|     basename = desktop_path; | ||||
|   app = g_hash_table_lookup (priv->id_to_app, id); | ||||
|   if (app) | ||||
|     return app; | ||||
|  | ||||
|   app = shell_app_system_lookup_app (system, basename); | ||||
|   if (!app) | ||||
|     return NULL; | ||||
|  | ||||
|   app_path = g_desktop_app_info_get_filename (shell_app_get_app_info (app)); | ||||
|   if (strcmp (desktop_path, app_path) != 0) | ||||
|   info = g_desktop_app_info_new (id); | ||||
|   if (!info) | ||||
|     return NULL; | ||||
|  | ||||
|   app = _shell_app_new (info); | ||||
|   g_hash_table_insert (priv->id_to_app, (char *) id, app); | ||||
|   return app; | ||||
| } | ||||
|  | ||||
| @@ -520,15 +200,15 @@ shell_app_system_lookup_heuristic_basename (ShellAppSystem *system, | ||||
|                                             const char     *name) | ||||
| { | ||||
|   ShellApp *result; | ||||
|   GSList *prefix; | ||||
|   const char *const *prefix; | ||||
|  | ||||
|   result = shell_app_system_lookup_app (system, name); | ||||
|   if (result != NULL) | ||||
|     return result; | ||||
|  | ||||
|   for (prefix = system->priv->known_vendor_prefixes; prefix; prefix = g_slist_next (prefix)) | ||||
|   for (prefix = vendor_prefixes; *prefix != NULL; prefix++) | ||||
|     { | ||||
|       char *tmpid = g_strconcat ((char*)prefix->data, name, NULL); | ||||
|       char *tmpid = g_strconcat (*prefix, name, NULL); | ||||
|       result = shell_app_system_lookup_app (system, tmpid); | ||||
|       g_free (tmpid); | ||||
|       if (result != NULL) | ||||
| @@ -603,10 +283,16 @@ ShellApp * | ||||
| shell_app_system_lookup_startup_wmclass (ShellAppSystem *system, | ||||
|                                          const char     *wmclass) | ||||
| { | ||||
|   const char *id; | ||||
|  | ||||
|   if (wmclass == NULL) | ||||
|     return NULL; | ||||
|  | ||||
|   return g_hash_table_lookup (system->priv->startup_wm_class_to_app, wmclass); | ||||
|   id = g_hash_table_lookup (system->priv->startup_wm_class_to_id, wmclass); | ||||
|   if (id == NULL) | ||||
|     return NULL; | ||||
|  | ||||
|   return shell_app_system_lookup_app (system, id); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -661,136 +347,3 @@ shell_app_system_get_running (ShellAppSystem *self) | ||||
|  | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
|  | ||||
| static gint | ||||
| compare_apps_by_usage (gconstpointer a, | ||||
|                        gconstpointer b, | ||||
|                        gpointer      data) | ||||
| { | ||||
|   ShellAppUsage *usage = shell_app_usage_get_default (); | ||||
|  | ||||
|   ShellApp *app_a = (ShellApp*)a; | ||||
|   ShellApp *app_b = (ShellApp*)b; | ||||
|  | ||||
|   return shell_app_usage_compare (usage, "", app_a, app_b); | ||||
| } | ||||
|  | ||||
| static GSList * | ||||
| sort_and_concat_results (ShellAppSystem *system, | ||||
|                          GSList         *prefix_matches, | ||||
|                          GSList         *substring_matches) | ||||
| { | ||||
|   prefix_matches = g_slist_sort_with_data (prefix_matches, | ||||
|                                            compare_apps_by_usage, | ||||
|                                            system); | ||||
|   substring_matches = g_slist_sort_with_data (substring_matches, | ||||
|                                               compare_apps_by_usage, | ||||
|                                               system); | ||||
|   return g_slist_concat (prefix_matches, substring_matches); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * normalize_terms: | ||||
|  * @terms: (element-type utf8): Input search terms | ||||
|  * | ||||
|  * Returns: (element-type utf8) (transfer full): Unicode-normalized and lowercased terms | ||||
|  */ | ||||
| static GSList * | ||||
| normalize_terms (GSList *terms) | ||||
| { | ||||
|   GSList *normalized_terms = NULL; | ||||
|   GSList *iter; | ||||
|   for (iter = terms; iter; iter = iter->next) | ||||
|     { | ||||
|       const char *term = iter->data; | ||||
|       normalized_terms = g_slist_prepend (normalized_terms, | ||||
|                                           shell_util_normalize_casefold_and_unaccent (term)); | ||||
|     } | ||||
|   return normalized_terms; | ||||
| } | ||||
|  | ||||
| static GSList * | ||||
| search_tree (ShellAppSystem *self, | ||||
|              GSList         *terms, | ||||
|              GHashTable     *apps) | ||||
| { | ||||
|   GSList *prefix_results = NULL; | ||||
|   GSList *substring_results = NULL; | ||||
|   GSList *normalized_terms; | ||||
|   GHashTableIter iter; | ||||
|   gpointer key, value; | ||||
|  | ||||
|   normalized_terms = normalize_terms (terms); | ||||
|  | ||||
|   g_hash_table_iter_init (&iter, apps); | ||||
|   while (g_hash_table_iter_next (&iter, &key, &value)) | ||||
|     { | ||||
|       ShellApp *app = value; | ||||
|       _shell_app_do_match (app, normalized_terms, | ||||
|                            &prefix_results, | ||||
|                            &substring_results); | ||||
|     } | ||||
|   g_slist_free_full (normalized_terms, g_free); | ||||
|  | ||||
|   return sort_and_concat_results (self, prefix_results, substring_results); | ||||
|  | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * shell_app_system_initial_search: | ||||
|  * @system: A #ShellAppSystem | ||||
|  * @terms: (element-type utf8): List of terms, logical AND | ||||
|  * | ||||
|  * Search through applications for the given search terms. | ||||
|  * | ||||
|  * Returns: (transfer container) (element-type ShellApp): List of applications | ||||
|  */ | ||||
| GSList * | ||||
| shell_app_system_initial_search (ShellAppSystem  *self, | ||||
|                                  GSList          *terms) | ||||
| { | ||||
|   return search_tree (self, terms, self->priv->visible_id_to_app); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * shell_app_system_subsearch: | ||||
|  * @system: A #ShellAppSystem | ||||
|  * @previous_results: (element-type ShellApp): List of previous results | ||||
|  * @terms: (element-type utf8): List of terms, logical AND | ||||
|  * | ||||
|  * Search through a previous result set; for more information, see | ||||
|  * js/ui/search.js.  Note the value of @prefs must be | ||||
|  * the same as passed to shell_app_system_initial_search().  Note that returned | ||||
|  * strings are only valid until a return to the main loop. | ||||
|  * | ||||
|  * Returns: (transfer container) (element-type ShellApp): List of application identifiers | ||||
|  */ | ||||
| GSList * | ||||
| shell_app_system_subsearch (ShellAppSystem   *system, | ||||
|                             GSList           *previous_results, | ||||
|                             GSList           *terms) | ||||
| { | ||||
|   GSList *iter; | ||||
|   GSList *prefix_results = NULL; | ||||
|   GSList *substring_results = NULL; | ||||
|   GSList *normalized_terms = normalize_terms (terms); | ||||
|  | ||||
|   previous_results = g_slist_reverse (previous_results); | ||||
|  | ||||
|   for (iter = previous_results; iter; iter = iter->next) | ||||
|     { | ||||
|       ShellApp *app = iter->data; | ||||
|        | ||||
|       _shell_app_do_match (app, normalized_terms, | ||||
|                            &prefix_results, | ||||
|                            &substring_results); | ||||
|     } | ||||
|   g_slist_free_full (normalized_terms, g_free); | ||||
|  | ||||
|   /* Note that a shorter term might have matched as a prefix, but | ||||
|      when extended only as a substring, so we have to redo the | ||||
|      sort rather than reusing the existing ordering */ | ||||
|   return sort_and_concat_results (system, prefix_results, substring_results); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -5,8 +5,6 @@ | ||||
| #include <gio/gio.h> | ||||
| #include <clutter/clutter.h> | ||||
| #include <meta/window.h> | ||||
| #define GMENU_I_KNOW_THIS_IS_UNSTABLE | ||||
| #include <gmenu-tree.h> | ||||
|  | ||||
| #include "shell-app.h" | ||||
|  | ||||
| @@ -39,14 +37,8 @@ struct _ShellAppSystemClass | ||||
| GType           shell_app_system_get_type    (void) G_GNUC_CONST; | ||||
| ShellAppSystem *shell_app_system_get_default (void); | ||||
|  | ||||
| GMenuTree      *shell_app_system_get_tree                     (ShellAppSystem *system); | ||||
|  | ||||
| ShellApp       *shell_app_system_lookup_app                   (ShellAppSystem  *system, | ||||
|                                                                const char      *id); | ||||
| ShellApp       *shell_app_system_lookup_app_by_tree_entry     (ShellAppSystem  *system, | ||||
|                                                                GMenuTreeEntry  *entry); | ||||
| ShellApp       *shell_app_system_lookup_app_for_path          (ShellAppSystem  *system, | ||||
|                                                                const char      *desktop_path); | ||||
| ShellApp       *shell_app_system_lookup_heuristic_basename    (ShellAppSystem  *system, | ||||
|                                                                const char      *id); | ||||
|  | ||||
| @@ -57,10 +49,4 @@ ShellApp       *shell_app_system_lookup_desktop_wmclass       (ShellAppSystem *s | ||||
|  | ||||
| GSList         *shell_app_system_get_running               (ShellAppSystem  *self); | ||||
|  | ||||
| GSList         *shell_app_system_initial_search            (ShellAppSystem  *system, | ||||
|                                                             GSList          *terms); | ||||
| GSList         *shell_app_system_subsearch                 (ShellAppSystem  *system, | ||||
|                                                             GSList          *previous_results, | ||||
|                                                             GSList          *terms); | ||||
|  | ||||
| #endif /* __SHELL_APP_SYSTEM_H__ */ | ||||
|   | ||||
| @@ -527,19 +527,19 @@ shell_app_usage_get_most_used (ShellAppUsage   *self, | ||||
|  * shell_app_usage_compare: | ||||
|  * @self: the usage instance to request | ||||
|  * @context: Activity identifier | ||||
|  * @app_a: First app | ||||
|  * @app_b: Second app | ||||
|  * @id_a: ID of first app | ||||
|  * @id_b: ID of second app | ||||
|  * | ||||
|  * Compare @app_a and @app_b based on frequency of use. | ||||
|  * Compare @id_a and @id_b based on frequency of use. | ||||
|  * | ||||
|  * Returns: -1 if @app_a ranks higher than @app_b, 1 if @app_b ranks higher | ||||
|  *          than @app_a, and 0 if both rank equally. | ||||
|  * Returns: -1 if @id_a ranks higher than @id_b, 1 if @id_b ranks higher | ||||
|  *          than @id_a, and 0 if both rank equally. | ||||
|  */ | ||||
| int | ||||
| shell_app_usage_compare (ShellAppUsage *self, | ||||
|                          const char    *context, | ||||
|                          ShellApp      *app_a, | ||||
|                          ShellApp      *app_b) | ||||
|                          const char    *id_a, | ||||
|                          const char    *id_b) | ||||
| { | ||||
|   GHashTable *usages; | ||||
|   UsageData *usage_a, *usage_b; | ||||
| @@ -548,8 +548,8 @@ shell_app_usage_compare (ShellAppUsage *self, | ||||
|   if (usages == NULL) | ||||
|     return 0; | ||||
|  | ||||
|   usage_a = g_hash_table_lookup (usages, shell_app_get_id (app_a)); | ||||
|   usage_b = g_hash_table_lookup (usages, shell_app_get_id (app_b)); | ||||
|   usage_a = g_hash_table_lookup (usages, id_a); | ||||
|   usage_b = g_hash_table_lookup (usages, id_b); | ||||
|  | ||||
|   if (usage_a == NULL && usage_b == NULL) | ||||
|     return 0; | ||||
|   | ||||
| @@ -31,8 +31,8 @@ GSList *shell_app_usage_get_most_used (ShellAppUsage *usage, | ||||
|                                        const char    *context); | ||||
| int shell_app_usage_compare (ShellAppUsage *self, | ||||
|                              const char    *context, | ||||
|                              ShellApp      *app_a, | ||||
|                              ShellApp      *app_b); | ||||
|                              const char    *id_a, | ||||
|                              const char    *id_b); | ||||
|  | ||||
| G_END_DECLS | ||||
|  | ||||
|   | ||||
| @@ -53,7 +53,7 @@ typedef struct { | ||||
|  * SECTION:shell-app | ||||
|  * @short_description: Object representing an application | ||||
|  * | ||||
|  * This object wraps a #GMenuTreeEntry, providing methods and signals | ||||
|  * This object wraps a #GDesktopAppInfo, providing methods and signals | ||||
|  * primarily useful for running applications. | ||||
|  */ | ||||
| struct _ShellApp | ||||
| @@ -64,7 +64,7 @@ struct _ShellApp | ||||
|  | ||||
|   ShellAppState state; | ||||
|  | ||||
|   GMenuTreeEntry *entry; /* If NULL, this app is backed by one or more | ||||
|   GDesktopAppInfo *info; /* If NULL, this app is backed by one or more | ||||
|                           * MetaWindow.  For purposes of app title | ||||
|                           * etc., we use the first window added, | ||||
|                           * because it's most likely to be what we | ||||
| @@ -137,15 +137,15 @@ shell_app_get_property (GObject    *gobject, | ||||
| const char * | ||||
| shell_app_get_id (ShellApp *app) | ||||
| { | ||||
|   if (app->entry) | ||||
|     return gmenu_tree_entry_get_desktop_file_id (app->entry); | ||||
|   if (app->info) | ||||
|     return g_app_info_get_id (G_APP_INFO (app->info)); | ||||
|   return app->window_id_string; | ||||
| } | ||||
|  | ||||
| static MetaWindow * | ||||
| window_backed_app_get_window (ShellApp     *app) | ||||
| { | ||||
|   g_assert (app->entry == NULL); | ||||
|   g_assert (app->info == NULL); | ||||
|   g_assert (app->running_state); | ||||
|   g_assert (app->running_state->windows); | ||||
|   return app->running_state->windows->data; | ||||
| @@ -194,10 +194,10 @@ shell_app_create_icon_texture (ShellApp   *app, | ||||
|  | ||||
|   ret = NULL; | ||||
|  | ||||
|   if (app->entry == NULL) | ||||
|   if (app->info == NULL) | ||||
|     return window_backed_app_get_icon (app, size); | ||||
|  | ||||
|   icon = g_app_info_get_icon (G_APP_INFO (gmenu_tree_entry_get_app_info (app->entry))); | ||||
|   icon = g_app_info_get_icon (G_APP_INFO (app->info)); | ||||
|   if (icon != NULL) | ||||
|     ret = st_texture_cache_load_gicon (st_texture_cache_get_default (), NULL, icon, size); | ||||
|  | ||||
| @@ -245,7 +245,7 @@ shell_app_create_faded_icon_cpu (StTextureCache *cache, | ||||
|  | ||||
|   info = NULL; | ||||
|  | ||||
|   icon = g_app_info_get_icon (G_APP_INFO (gmenu_tree_entry_get_app_info (app->entry))); | ||||
|   icon = g_app_info_get_icon (G_APP_INFO (app->info)); | ||||
|   if (icon != NULL) | ||||
|     { | ||||
|       info = gtk_icon_theme_lookup_by_gicon (gtk_icon_theme_get_default (), | ||||
| @@ -347,7 +347,7 @@ shell_app_get_faded_icon (ShellApp *app, int size, ClutterTextDirection directio | ||||
|    * property tracking bits, and this helps us visually distinguish | ||||
|    * app-tracked from not. | ||||
|    */ | ||||
|   if (!app->entry) | ||||
|   if (!app->info) | ||||
|     return window_backed_app_get_icon (app, size); | ||||
|  | ||||
|   /* Use icon: prefix so that we get evicted from the cache on | ||||
| @@ -384,8 +384,8 @@ shell_app_get_faded_icon (ShellApp *app, int size, ClutterTextDirection directio | ||||
| const char * | ||||
| shell_app_get_name (ShellApp *app) | ||||
| { | ||||
|   if (app->entry) | ||||
|     return g_app_info_get_name (G_APP_INFO (gmenu_tree_entry_get_app_info (app->entry))); | ||||
|   if (app->info) | ||||
|     return g_app_info_get_name (G_APP_INFO (app->info)); | ||||
|   else | ||||
|     { | ||||
|       MetaWindow *window = window_backed_app_get_window (app); | ||||
| @@ -401,8 +401,8 @@ shell_app_get_name (ShellApp *app) | ||||
| const char * | ||||
| shell_app_get_description (ShellApp *app) | ||||
| { | ||||
|   if (app->entry) | ||||
|     return g_app_info_get_description (G_APP_INFO (gmenu_tree_entry_get_app_info (app->entry))); | ||||
|   if (app->info) | ||||
|     return g_app_info_get_description (G_APP_INFO (app->info)); | ||||
|   else | ||||
|     return NULL; | ||||
| } | ||||
| @@ -417,7 +417,7 @@ shell_app_get_description (ShellApp *app) | ||||
| gboolean | ||||
| shell_app_is_window_backed (ShellApp *app) | ||||
| { | ||||
|   return app->entry == NULL; | ||||
|   return app->info == NULL; | ||||
| } | ||||
|  | ||||
| typedef struct { | ||||
| @@ -670,7 +670,7 @@ void | ||||
| shell_app_open_new_window (ShellApp      *app, | ||||
|                            int            workspace) | ||||
| { | ||||
|   g_return_if_fail (app->entry != NULL); | ||||
|   g_return_if_fail (app->info != NULL); | ||||
|  | ||||
|   /* Here we just always launch the application again, even if we know | ||||
|    * it was already running.  For most applications this | ||||
| @@ -865,25 +865,24 @@ _shell_app_new_for_window (MetaWindow      *window) | ||||
| } | ||||
|  | ||||
| ShellApp * | ||||
| _shell_app_new (GMenuTreeEntry *info) | ||||
| _shell_app_new (GDesktopAppInfo *info) | ||||
| { | ||||
|   ShellApp *app; | ||||
|  | ||||
|   app = g_object_new (SHELL_TYPE_APP, NULL); | ||||
|  | ||||
|   _shell_app_set_entry (app, info); | ||||
|   _shell_app_set_app_info (app, info); | ||||
|  | ||||
|   return app; | ||||
| } | ||||
|  | ||||
| void | ||||
| _shell_app_set_entry (ShellApp       *app, | ||||
|                       GMenuTreeEntry *entry) | ||||
| _shell_app_set_app_info (ShellApp        *app, | ||||
|                          GDesktopAppInfo *info) | ||||
| { | ||||
|   if (app->entry != NULL) | ||||
|     gmenu_tree_item_unref (app->entry); | ||||
|   app->entry = gmenu_tree_item_ref (entry); | ||||
|    | ||||
|   g_clear_object (&app->info); | ||||
|   app->info = g_object_ref (info); | ||||
|  | ||||
|   if (app->name_collation_key != NULL) | ||||
|     g_free (app->name_collation_key); | ||||
|   app->name_collation_key = g_utf8_collate_key (shell_app_get_name (app), -1); | ||||
| @@ -1188,7 +1187,6 @@ shell_app_launch (ShellApp     *app, | ||||
|                   char        **startup_id, | ||||
|                   GError      **error) | ||||
| { | ||||
|   GDesktopAppInfo *gapp; | ||||
|   GdkAppLaunchContext *context; | ||||
|   gboolean ret; | ||||
|   ShellGlobal *global; | ||||
| @@ -1198,7 +1196,7 @@ shell_app_launch (ShellApp     *app, | ||||
|   if (startup_id) | ||||
|     *startup_id = NULL; | ||||
|  | ||||
|   if (app->entry == NULL) | ||||
|   if (app->info == NULL) | ||||
|     { | ||||
|       MetaWindow *window = window_backed_app_get_window (app); | ||||
|       /* We can't pass URIs into a window; shouldn't hit this | ||||
| @@ -1224,8 +1222,7 @@ shell_app_launch (ShellApp     *app, | ||||
|   gdk_app_launch_context_set_timestamp (context, timestamp); | ||||
|   gdk_app_launch_context_set_desktop (context, workspace); | ||||
|  | ||||
|   gapp = gmenu_tree_entry_get_app_info (app->entry); | ||||
|   ret = g_desktop_app_info_launch_uris_as_manager (gapp, uris, | ||||
|   ret = g_desktop_app_info_launch_uris_as_manager (app->info, uris, | ||||
|                                                    G_APP_LAUNCH_CONTEXT (context), | ||||
|                                                    G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, | ||||
|                                                    NULL, NULL, | ||||
| @@ -1245,21 +1242,7 @@ shell_app_launch (ShellApp     *app, | ||||
| GDesktopAppInfo * | ||||
| shell_app_get_app_info (ShellApp *app) | ||||
| { | ||||
|   if (app->entry) | ||||
|     return gmenu_tree_entry_get_app_info (app->entry); | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * shell_app_get_tree_entry: | ||||
|  * @app: a #ShellApp | ||||
|  * | ||||
|  * Returns: (transfer none): The #GMenuTreeEntry for this app, or %NULL if backed by a window | ||||
|  */ | ||||
| GMenuTreeEntry * | ||||
| shell_app_get_tree_entry (ShellApp *app) | ||||
| { | ||||
|   return app->entry; | ||||
|   return app->info; | ||||
| } | ||||
|  | ||||
| static void | ||||
| @@ -1374,24 +1357,22 @@ shell_app_init_search_data (ShellApp *app) | ||||
|   const char *exec; | ||||
|   const char * const *keywords; | ||||
|   char *normalized_exec; | ||||
|   GDesktopAppInfo *appinfo; | ||||
|  | ||||
|   appinfo = gmenu_tree_entry_get_app_info (app->entry); | ||||
|   name = g_app_info_get_name (G_APP_INFO (appinfo)); | ||||
|   name = g_app_info_get_name (G_APP_INFO (app->info)); | ||||
|   app->casefolded_name = shell_util_normalize_casefold_and_unaccent (name); | ||||
|  | ||||
|   generic_name = g_desktop_app_info_get_generic_name (appinfo); | ||||
|   generic_name = g_desktop_app_info_get_generic_name (app->info); | ||||
|   if (generic_name) | ||||
|     app->casefolded_generic_name = shell_util_normalize_casefold_and_unaccent (generic_name); | ||||
|   else | ||||
|     app->casefolded_generic_name = NULL; | ||||
|  | ||||
|   exec = g_app_info_get_executable (G_APP_INFO (appinfo)); | ||||
|   exec = g_app_info_get_executable (G_APP_INFO (app->info)); | ||||
|   normalized_exec = shell_util_normalize_casefold_and_unaccent (exec); | ||||
|   app->casefolded_exec = trim_exec_line (normalized_exec); | ||||
|   g_free (normalized_exec); | ||||
|  | ||||
|   keywords = g_desktop_app_info_get_keywords (appinfo); | ||||
|   keywords = g_desktop_app_info_get_keywords (app->info); | ||||
|  | ||||
|   if (keywords) | ||||
|     { | ||||
| @@ -1512,16 +1493,14 @@ _shell_app_do_match (ShellApp         *app, | ||||
|                      GSList          **substring_results) | ||||
| { | ||||
|   ShellAppSearchMatch match; | ||||
|   GAppInfo *appinfo; | ||||
|  | ||||
|   g_assert (app != NULL); | ||||
|  | ||||
|   /* Skip window-backed apps */  | ||||
|   appinfo = (GAppInfo*)shell_app_get_app_info (app); | ||||
|   if (appinfo == NULL) | ||||
|   if (app->info == NULL) | ||||
|     return; | ||||
|   /* Skip not-visible apps */  | ||||
|   if (!g_app_info_should_show (appinfo)) | ||||
|   if (!g_app_info_should_show (G_APP_INFO (app->info))) | ||||
|     return; | ||||
|  | ||||
|   match = _shell_app_match_search_terms (app, terms); | ||||
| @@ -1550,11 +1529,7 @@ shell_app_dispose (GObject *object) | ||||
| { | ||||
|   ShellApp *app = SHELL_APP (object); | ||||
|  | ||||
|   if (app->entry) | ||||
|     { | ||||
|       gmenu_tree_item_unref (app->entry); | ||||
|       app->entry = NULL; | ||||
|     } | ||||
|   g_clear_object (&app->info); | ||||
|  | ||||
|   if (app->running_state) | ||||
|     { | ||||
|   | ||||
| @@ -4,9 +4,8 @@ | ||||
|  | ||||
| #include <clutter/clutter.h> | ||||
| #include <gio/gio.h> | ||||
| #include <gio/gdesktopappinfo.h> | ||||
| #include <meta/window.h> | ||||
| #define GMENU_I_KNOW_THIS_IS_UNSTABLE | ||||
| #include <gmenu-tree.h> | ||||
|  | ||||
| G_BEGIN_DECLS | ||||
|  | ||||
| @@ -39,7 +38,6 @@ GType shell_app_get_type (void) G_GNUC_CONST; | ||||
|  | ||||
| const char *shell_app_get_id (ShellApp *app); | ||||
|  | ||||
| GMenuTreeEntry *shell_app_get_tree_entry (ShellApp *app); | ||||
| GDesktopAppInfo *shell_app_get_app_info (ShellApp *app); | ||||
|  | ||||
| ClutterActor *shell_app_create_icon_texture (ShellApp *app, int size); | ||||
|   | ||||
| @@ -844,6 +844,7 @@ ShellApp * | ||||
| shell_startup_sequence_get_app (ShellStartupSequence *sequence) | ||||
| { | ||||
|   const char *appid; | ||||
|   char *basename; | ||||
|   ShellAppSystem *appsys; | ||||
|   ShellApp *app; | ||||
|  | ||||
| @@ -851,8 +852,10 @@ shell_startup_sequence_get_app (ShellStartupSequence *sequence) | ||||
|   if (!appid) | ||||
|     return NULL; | ||||
|  | ||||
|   basename = g_path_get_basename (appid); | ||||
|   appsys = shell_app_system_get_default (); | ||||
|   app = shell_app_system_lookup_app_for_path (appsys, appid); | ||||
|   app = shell_app_system_lookup_app (appsys, basename); | ||||
|   g_free (basename); | ||||
|   return app; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user