From 977d56169596db8b29ce50e3776f3235f31a3195 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Fri, 4 Oct 2024 17:31:58 -0400 Subject: [PATCH] icon-loader: fix a few more missing icons By: - stripping extensions from relative icon filenames (for example, gdmap.desktop has "Icon=gdmap_icon.png") - using the WM_CLASS "instance" rather than "class" string, which is usually the same but lowercase --- src/icon-loader.c | 26 +++++++++++++++++++++++++- src/xwayland.c | 12 ++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/icon-loader.c b/src/icon-loader.c index a9444fe4..60f82029 100644 --- a/src/icon-loader.c +++ b/src/icon-loader.c @@ -113,6 +113,23 @@ struct icon_ctx { enum sfdo_icon_file_format format; }; +/* + * Return the length of a filename minus any known extension + */ +static size_t +length_without_extension(const char *name) +{ + size_t len = strlen(name); + if (len >= 4 && name[len - 4] == '.') { + const char *ext = &name[len - 3]; + if (!strcmp(ext, "png") || !strcmp(ext, "svg") + || !strcmp(ext, "xpm")) { + len -= 4; + } + } + return len; +} + /* * Return 0 on success and -1 on error * The calling function is responsible for free()ing ctx->path @@ -126,8 +143,15 @@ process_rel_name(struct icon_ctx *ctx, const char *icon_name, #if !HAVE_RSVG lookup_options |= SFDO_ICON_THEME_LOOKUP_OPTION_NO_SVG; #endif + + /* + * Relative icon names are not supposed to include an extension, + * but some .desktop files include one anyway. libsfdo does not + * allow this in lookups, so strip the extension first. + */ + size_t name_len = length_without_extension(icon_name); struct sfdo_icon_file *icon_file = sfdo_icon_theme_lookup( - loader->icon_theme, icon_name, SFDO_NT, size, scale, + loader->icon_theme, icon_name, name_len, size, scale, lookup_options); if (!icon_file || icon_file == SFDO_ICON_FILE_INVALID) { ret = -1; diff --git a/src/xwayland.c b/src/xwayland.c index c7f0568b..af3bb871 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -489,9 +489,17 @@ xwayland_view_get_string_prop(struct view *view, const char *prop) if (!strcmp(prop, "class")) { return xwayland_surface->class; } - /* We give 'class' for wlr_foreign_toplevel_handle_v1_set_app_id() */ + /* + * Use the WM_CLASS 'instance' (1st string) for the app_id. Per + * ICCCM, this is usually "the trailing part of the name used to + * invoke the program (argv[0] stripped of any directory names)". + * + * In most cases, the 'class' (2nd string) is the same as the + * 'instance' except for being capitalized. We want lowercase + * here since we use the app_id for icon lookups. + */ if (!strcmp(prop, "app_id")) { - return xwayland_surface->class; + return xwayland_surface->instance; } return ""; } -- 2.52.0