From 40f567aa2acdc508147cde624cc156c31b3f5bff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nelson=20Ben=C3=ADtez=20Le=C3=B3n?= Date: Mon, 25 Sep 2023 03:29:53 +0100 Subject: [PATCH] GDesktopAppInfo: prioritize match_type over match_category when searching apps Commit 9e2ad88455 improved app search results by allowing to differentiate their match_type: prefix match or substring match; while giving more priority to prefix matches over substring matches, but only when they are in the same match_category[1]. This was a step forward but, as outlined in #3082, still not enough to get most relevant results first to the user, because apparently (and for the specific case of desktop app searching) a prefix match in a lower category is more relevant to the user than a substring match in a higher category. So that's what this commit implements, i.e. it makes sure prefix matches are still preferred over substring matches but this time not only when in the same category but also across different categories. [1] Match category is the Desktop file key where the match happened. They are shown below from top to lesser priority. DESKTOP_KEY_Name DESKTOP_KEY_Exec DESKTOP_KEY_Keywords DESKTOP_KEY_GenericName DESKTOP_KEY_X_GNOME_FullName DESKTOP_KEY_Comment Fixes #3082 --- gio/gdesktopappinfo.c | 15 ++++++++++----- gio/tests/apps.c | 27 +++++++++++++++++++++------ gio/tests/desktop-app-info.c | 7 ++++--- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c index 1f161328a..f724ec9fc 100644 --- a/gio/gdesktopappinfo.c +++ b/gio/gdesktopappinfo.c @@ -458,7 +458,9 @@ const gchar desktop_key_match_category[N_DESKTOP_KEYS] = { typedef enum { /* Lower numbers have higher priority. - * Prefix match should put before substring match. + * Prefix match should put before substring match, independently of + * category relevance, i.e. a prefix match in 'Keyword' category will + * come before a substring match in a more relevant category like 'Name'. */ MATCH_TYPE_PREFIX = 1, MATCH_TYPE_SUBSTRING = 2 @@ -576,7 +578,10 @@ compare_results (gconstpointer a, } else { - if (ra->category == rb->category) + /* We prioritize prefix matches over category relevance e.g. a prefix match in 'Keyword' + * category is better than a substring match in a more relevance category like 'Name'. + */ + if (ra->match_type != rb->match_type) return ra->match_type - rb->match_type; return ra->category - rb->category; @@ -590,10 +595,10 @@ compare_categories (gconstpointer a, const struct search_result *ra = a; const struct search_result *rb = b; - /* Also compare match types so we can put prefix match in a group while - * substring match in another group. + /* We prioritize prefix matches over category relevance e.g. a prefix match in 'Keyword' + * category is better than a substring match in a more relevance category like 'Name'. */ - if (ra->category == rb->category) + if (ra->match_type != rb->match_type) return ra->match_type - rb->match_type; return ra->category - rb->category; diff --git a/gio/tests/apps.c b/gio/tests/apps.c index 4b25b1166..d656b6c92 100644 --- a/gio/tests/apps.c +++ b/gio/tests/apps.c @@ -34,12 +34,27 @@ main (int argc, char **argv) setlocale (LC_ALL, ""); if (argv[1] == NULL || g_str_equal (argv[1], "--help")) - g_print ("Usage:\n apps --help\n apps COMMAND [COMMAND_OPTIONS]\n\nCOMMANDS:\n list\n " - "search [--should-show-only] TEXT_TO_SEARCH\n implementations INTERFACE_NAME\n " - "show-info DESKTOP_FILE\n default-for-type MIME_TYPE\n recommended-for-type MIME_TYPE\n " - "all-for-type MIME_TYPE\n fallback-for-type MIME_TYPE\n should-show DESKTOP_FILE\n " - "monitor\n\nExamples:\n apps search --should-show-only ter\n" - " apps show-info org.gnome.Nautilus.desktop\n apps default-for-type image/png\n\n"); + g_print ("Usage:\n" + " apps --help\n" + " apps COMMAND [COMMAND_OPTIONS]\n" + "\n" + "COMMANDS:\n" + " list\n" + " search [--should-show-only] TEXT_TO_SEARCH\n" + " implementations INTERFACE_NAME\n" + " show-info DESKTOP_FILE\n" + " default-for-type MIME_TYPE\n" + " recommended-for-type MIME_TYPE\n" + " all-for-type MIME_TYPE\n" + " fallback-for-type MIME_TYPE\n" + " should-show DESKTOP_FILE\n" + " monitor\n" + "\n" + "Examples:\n" + " apps search --should-show-only ter\n" + " apps show-info org.gnome.Nautilus.desktop\n" + " apps default-for-type image/png\n" + "\n"); else if (g_str_equal (argv[1], "list")) { GList *all, *i; diff --git a/gio/tests/desktop-app-info.c b/gio/tests/desktop-app-info.c index 594ec945d..6b4580893 100644 --- a/gio/tests/desktop-app-info.c +++ b/gio/tests/desktop-app-info.c @@ -888,11 +888,12 @@ test_search (void) "gedit.desktop\n", TRUE, TRUE, NULL, NULL); /* "con" will match "connect" and "contacts" on name with prefix match in - * first group, then match "Dconf Editor" and "Desktop Icons" with substring - * match in next group. + * first group, then second group is a Keyword prefix match for "configuration" in dconf-editor.desktop + * and third group is a substring match for "Desktop Icons" in Name of nautilus-classic.desktop. */ assert_search ("con", "gnome-contacts.desktop nautilus-connect-server.desktop\n" - "dconf-editor.desktop nautilus-classic.desktop\n", TRUE, TRUE, NULL, NULL); + "dconf-editor.desktop\n" + "nautilus-classic.desktop\n", TRUE, TRUE, NULL, NULL); /* "gnome" will match "eye of gnome" from the user's directory, plus * matching "GNOME Clocks" X-GNOME-FullName. It's only a comment on