[gnome-shell] appDisplay: Use the desktop file index for app searching



commit ba602c17d4eddb4b415ab3ff81295fc2365e45ac
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Sat Nov 2 20:13:42 2013 -0400

    appDisplay: Use the desktop file index for app searching
    
    Rather than scanning all apps for searching, use Ryan's new desktop
    file index and the glib support APIs for app searching instead of our
    own system.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=711631

 js/ui/appDisplay.js     |   17 +++++-
 src/shell-app-private.h |    5 --
 src/shell-app-system.c  |  140 ----------------------------------------
 src/shell-app-system.h  |    6 --
 src/shell-app-usage.c   |   18 +++---
 src/shell-app-usage.h   |    4 +-
 src/shell-app.c         |  162 -----------------------------------------------
 src/shell-util.c        |   92 ---------------------------
 src/shell-util.h        |    4 -
 9 files changed, 26 insertions(+), 422 deletions(-)
---
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index c683cc2..4785c99 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -889,11 +889,24 @@ const AppSearchProvider = new Lang.Class({
     },
 
     getInitialResultSet: function(terms, callback, cancellable) {
-        callback(this._appSys.initial_search(terms));
+        let query = terms.join(' ');
+        let groups = Gio.DesktopAppInfo.search(query);
+        let usage = Shell.AppUsage.get_default();
+        let results = [];
+        groups.forEach(function(group) {
+            group = group.filter(function(appID) {
+                let app = Gio.DesktopAppInfo.new(appID);
+                return app && app.should_show();
+            });
+            results = results.concat(group.sort(function(a, b) {
+                return usage.compare('', a, b);
+            }));
+        });
+        callback(results);
     },
 
     getSubsearchResultSet: function(previousResults, terms, callback, cancellable) {
-        callback(this._appSys.subsearch(previousResults, terms));
+        this.getInitialResultSet(terms, callback, cancellable);
     },
 
     activateResult: function(result) {
diff --git a/src/shell-app-private.h b/src/shell-app-private.h
index 407e75f..020abd4 100644
--- a/src/shell-app-private.h
+++ b/src/shell-app-private.h
@@ -22,11 +22,6 @@ void _shell_app_add_window (ShellApp *app, MetaWindow *window);
 
 void _shell_app_remove_window (ShellApp *app, MetaWindow *window);
 
-void _shell_app_do_match (ShellApp         *app,
-                          GSList           *terms,
-                          GSList          **prefix_results,
-                          GSList          **substring_results);
-
 G_END_DECLS
 
 #endif /* __SHELL_APP_PRIVATE_H__ */
diff --git a/src/shell-app-system.c b/src/shell-app-system.c
index feca09c..3a31709 100644
--- a/src/shell-app-system.c
+++ b/src/shell-app-system.c
@@ -348,143 +348,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)
-{
-  GSList *matches = NULL;
-  GSList *l;
-
-  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);
-
-  for (l = substring_matches; l != NULL; l = l->next)
-    matches = g_slist_prepend (matches, (char *) shell_app_get_id (SHELL_APP (l->data)));
-  for (l = prefix_matches; l != NULL; l = l->next)
-    matches = g_slist_prepend (matches, (char *) shell_app_get_id (SHELL_APP (l->data)));
-
-  return g_slist_reverse (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 utf8): List of applications
- */
-GSList *
-shell_app_system_initial_search (ShellAppSystem  *self,
-                                 GSList          *terms)
-{
-  return search_tree (self, terms, self->priv->id_to_app);
-}
-
-/**
- * shell_app_system_subsearch:
- * @system: A #ShellAppSystem
- * @previous_results: (element-type utf8): 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 that returned strings are only valid until
- * a return to the main loop.
- *
- * Returns: (transfer container) (element-type utf8): 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 = shell_app_system_lookup_app (system, 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);
-}
-
diff --git a/src/shell-app-system.h b/src/shell-app-system.h
index 6f93449..c0c501a 100644
--- a/src/shell-app-system.h
+++ b/src/shell-app-system.h
@@ -49,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__ */
diff --git a/src/shell-app-usage.c b/src/shell-app-usage.c
index 31e7f85..c733ce4 100644
--- a/src/shell-app-usage.c
+++ b/src/shell-app-usage.c
@@ -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;
diff --git a/src/shell-app-usage.h b/src/shell-app-usage.h
index 4016b58..4afdbb3 100644
--- a/src/shell-app-usage.h
+++ b/src/shell-app-usage.h
@@ -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
 
diff --git a/src/shell-app.c b/src/shell-app.c
index 6904b6b..487268d 100644
--- a/src/shell-app.c
+++ b/src/shell-app.c
@@ -81,12 +81,7 @@ struct _ShellApp
   ShellAppRunningState *running_state;
 
   char *window_id_string;
-
-  char *casefolded_name;
-  char *casefolded_generic_name;
   char *name_collation_key;
-  char *casefolded_exec;
-  char **casefolded_keywords;
 };
 
 enum {
@@ -1360,49 +1355,6 @@ trim_exec_line (const char *str)
   return g_strndup (start, end - start);
 }
 
-static void
-shell_app_init_search_data (ShellApp *app)
-{
-  const char *name;
-  const char *generic_name;
-  const char *exec;
-  const char * const *keywords;
-  char *normalized_exec;
-
-  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 (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 (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 (app->info);
-
-  if (keywords)
-    {
-      int i;
-
-      app->casefolded_keywords = g_new0 (char*, g_strv_length ((char **)keywords) + 1);
-
-      i = 0;
-      while (keywords[i])
-        {
-          app->casefolded_keywords[i] = shell_util_normalize_casefold_and_unaccent (keywords[i]);
-          ++i;
-        }
-      app->casefolded_keywords[i] = NULL;
-    }
-  else
-    app->casefolded_keywords = NULL;
-}
-
 /**
  * shell_app_compare_by_name:
  * @app: One app
@@ -1419,116 +1371,6 @@ shell_app_compare_by_name (ShellApp *app, ShellApp *other)
   return strcmp (app->name_collation_key, other->name_collation_key);
 }
 
-static ShellAppSearchMatch
-_shell_app_match_search_terms (ShellApp  *app,
-                               GSList    *terms)
-{
-  GSList *iter;
-  ShellAppSearchMatch match;
-
-  if (G_UNLIKELY (!app->casefolded_name))
-    shell_app_init_search_data (app);
-
-  match = MATCH_NONE;
-  for (iter = terms; iter; iter = iter->next)
-    {
-      ShellAppSearchMatch current_match;
-      const char *term = iter->data;
-      const char *p;
-
-      current_match = MATCH_NONE;
-
-      p = strstr (app->casefolded_name, term);
-      if (p != NULL)
-        {
-          if (p == app->casefolded_name || *(p - 1) == ' ')
-            current_match = MATCH_PREFIX;
-          else
-            current_match = MATCH_SUBSTRING;
-        }
-
-      if (app->casefolded_generic_name)
-        {
-          p = strstr (app->casefolded_generic_name, term);
-          if (p != NULL)
-            {
-              if (p == app->casefolded_generic_name || *(p - 1) == ' ')
-                current_match = MATCH_PREFIX;
-              else if (current_match < MATCH_PREFIX)
-                current_match = MATCH_SUBSTRING;
-            }
-        }
-
-      if (app->casefolded_exec)
-        {
-          p = strstr (app->casefolded_exec, term);
-          if (p != NULL)
-            {
-              if (p == app->casefolded_exec || *(p - 1) == '-')
-                current_match = MATCH_PREFIX;
-              else if (current_match < MATCH_PREFIX)
-                current_match = MATCH_SUBSTRING;
-            }
-        }
-
-      if (app->casefolded_keywords)
-        {
-          int i = 0;
-          while (app->casefolded_keywords[i] && current_match < MATCH_PREFIX)
-            {
-              p = strstr (app->casefolded_keywords[i], term);
-              if (p != NULL)
-                {
-                  if (p == app->casefolded_keywords[i])
-                    current_match = MATCH_PREFIX;
-                  else
-                    current_match = MATCH_SUBSTRING;
-                }
-              ++i;
-            }
-        }
-
-      if (current_match == MATCH_NONE)
-        return current_match;
-
-      if (current_match > match)
-        match = current_match;
-    }
-  return match;
-}
-
-void
-_shell_app_do_match (ShellApp         *app,
-                     GSList           *terms,
-                     GSList          **prefix_results,
-                     GSList          **substring_results)
-{
-  ShellAppSearchMatch match;
-
-  g_assert (app != NULL);
-
-  /* Skip window-backed apps */ 
-  if (app->info == NULL)
-    return;
-  /* Skip not-visible apps */ 
-  if (!g_app_info_should_show (G_APP_INFO (app->info)))
-    return;
-
-  match = _shell_app_match_search_terms (app, terms);
-  switch (match)
-    {
-      case MATCH_NONE:
-        break;
-      case MATCH_PREFIX:
-        *prefix_results = g_slist_prepend (*prefix_results, app);
-        break;
-      case MATCH_SUBSTRING:
-        *substring_results = g_slist_prepend (*substring_results, app);
-        break;
-    }
-}
-
-
 static void
 shell_app_init (ShellApp *self)
 {
@@ -1561,11 +1403,7 @@ shell_app_finalize (GObject *object)
 
   g_free (app->window_id_string);
 
-  g_free (app->casefolded_name);
-  g_free (app->casefolded_generic_name);
   g_free (app->name_collation_key);
-  g_free (app->casefolded_exec);
-  g_strfreev (app->casefolded_keywords);
 
   G_OBJECT_CLASS(shell_app_parent_class)->finalize (object);
 }
diff --git a/src/shell-util.c b/src/shell-util.c
index 92fc3da..bbbb86f 100644
--- a/src/shell-util.c
+++ b/src/shell-util.c
@@ -111,98 +111,6 @@ shell_util_get_transformed_allocation (ClutterActor    *actor,
   box->y2 = y_max;
 }
 
-char *
-shell_util_normalize_and_casefold (const char *str)
-{
-  char *normalized, *result;
-
-  if (str == NULL)
-    return NULL;
-
-  /* NOTE: 'ALL' is equivalent to 'NFKD'. If this is ever updated, please
-   * update the unaccenting mechanism as well. */
-  normalized = g_utf8_normalize (str, -1, G_NORMALIZE_ALL);
-  result = g_utf8_casefold (normalized, -1);
-  g_free (normalized);
-  return result;
-}
-
-/* Combining diacritical mark?
- *  Basic range: [0x0300,0x036F]
- *  Supplement:  [0x1DC0,0x1DFF]
- *  For Symbols: [0x20D0,0x20FF]
- *  Half marks:  [0xFE20,0xFE2F]
- */
-#define IS_CDM_UCS4(c) (((c) >= 0x0300 && (c) <= 0x036F)  || \
-                        ((c) >= 0x1DC0 && (c) <= 0x1DFF)  || \
-                        ((c) >= 0x20D0 && (c) <= 0x20FF)  || \
-                        ((c) >= 0xFE20 && (c) <= 0xFE2F))
-
-/* Copied from tracker/src/libtracker-fts/tracker-parser-glib.c under the GPL
- * Originally written by Aleksander Morgado <aleksander gnu org>
- */
-char *
-shell_util_normalize_casefold_and_unaccent (const char *str)
-{
-  char *tmp;
-  gsize i = 0, j = 0, ilen;
-
-  if (str == NULL)
-    return NULL;
-
-  /* Get the NFKD-normalized and casefolded string */
-  tmp = shell_util_normalize_and_casefold (str);
-  ilen = strlen (tmp);
-
-  while (i < ilen)
-    {
-      gunichar unichar;
-      gchar *next_utf8;
-      gint utf8_len;
-
-      /* Get next character of the word as UCS4 */
-      unichar = g_utf8_get_char_validated (&tmp[i], -1);
-
-      /* Invalid UTF-8 character or end of original string. */
-      if (unichar == (gunichar) -1 ||
-          unichar == (gunichar) -2)
-        {
-          break;
-        }
-
-      /* Find next UTF-8 character */
-      next_utf8 = g_utf8_next_char (&tmp[i]);
-      utf8_len = next_utf8 - &tmp[i];
-
-      if (IS_CDM_UCS4 ((guint32) unichar))
-        {
-          /* If the given unichar is a combining diacritical mark,
-           * just update the original index, not the output one */
-          i += utf8_len;
-          continue;
-        }
-
-      /* If already found a previous combining
-       * diacritical mark, indexes are different so
-       * need to copy characters. As output and input
-       * buffers may overlap, need to use memmove
-       * instead of memcpy */
-      if (i != j)
-        {
-          memmove (&tmp[j], &tmp[i], utf8_len);
-        }
-
-      /* Update both indexes */
-      i += utf8_len;
-      j += utf8_len;
-    }
-
-  /* Force proper string end */
-  tmp[j] = '\0';
-
-  return tmp;
-}
-
 /**
  * shell_util_format_date:
  * @format: a strftime-style string format, as parsed by
diff --git a/src/shell-util.h b/src/shell-util.h
index 95271d0..fdaec56 100644
--- a/src/shell-util.h
+++ b/src/shell-util.h
@@ -19,10 +19,6 @@ void     shell_util_get_transformed_allocation (ClutterActor     *actor,
 
 int      shell_util_get_week_start             (void);
 
-char    *shell_util_normalize_and_casefold     (const char       *str);
-
-char    *shell_util_normalize_casefold_and_unaccent (const char  *str);
-
 char    *shell_util_format_date                (const char       *format,
                                                 gint64            time_ms);
 


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