From 199e1ef041ceae55e66f64239c32d9e80b96bdef Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Fri, 4 Oct 2024 13:42:23 -0400 Subject: [PATCH] icon-loader: also match desktop entries by executable path It's relatively common for X11 applications to set WM_CLASS to the name of the executable, which may not be the same as the name of the .desktop file (for example, "gimp-2.10" vs. gimp.desktop). We can still match these applications by looking at the Exec key. This currently makes use of an internal libsfdo header since the needed API doesn't exist yet. I have submitted a merge request upstream: https://gitlab.freedesktop.org/vyivel/libsfdo/-/merge_requests/5 --- src/icon-loader.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/icon-loader.c b/src/icon-loader.c index 83d91c50..838c4e07 100644 --- a/src/icon-loader.c +++ b/src/icon-loader.c @@ -5,6 +5,12 @@ #include #include #include +/* + * FIXME: remove when this is merged: + * https://gitlab.freedesktop.org/vyivel/libsfdo/-/merge_requests/5 + */ +#include + #include "common/mem.h" #include "common/string-helpers.h" #include "config.h" @@ -25,6 +31,20 @@ struct icon_loader { struct sfdo_icon_theme *icon_theme; }; +/* + * FIXME: remove when this is merged: + * https://gitlab.freedesktop.org/vyivel/libsfdo/-/merge_requests/5 + */ +static const char * +desktop_entry_get_exec_name(struct sfdo_desktop_entry *entry) +{ + struct sfdo_desktop_exec *exec = sfdo_desktop_entry_get_exec(entry); + if (!exec || exec->n_literals < 1) { + return NULL; + } + return exec->literals[0]; +} + void icon_loader_init(struct server *server) { @@ -152,14 +172,24 @@ get_db_entry_by_id_fuzzy(struct sfdo_desktop_db *db, const char *app_id) for (size_t i = 0; i < n_entries; i++) { struct sfdo_desktop_entry *entry = entries[i]; + + /* Try portion of desktop ID after last '.' */ const char *desktop_id = sfdo_desktop_entry_get_id(entry, NULL); - /* Get portion of desktop ID after last '.' */ const char *dot = strrchr(desktop_id, '.'); const char *desktop_id_base = dot ? (dot + 1) : desktop_id; - if (!strcasecmp(app_id, desktop_id_base)) { return entry; } + + /* Try basename of executable (e.g. "gimp-2.10") */ + const char *exec_name = desktop_entry_get_exec_name(entry); + if (exec_name) { + const char *slash = strrchr(exec_name, '/'); + const char *exec_base = slash ? (slash + 1) : exec_name; + if (!strcasecmp(app_id, exec_base)) { + return entry; + } + } } return NULL;