From 9f32dc4eefc8b062cd43085e41719c94a2578d68 Mon Sep 17 00:00:00 2001 From: lkn Date: Sun, 21 Jun 2026 19:24:59 +0200 Subject: [PATCH] icon: look up freedesktop icon theme for native Wayland clients Native Wayland clients have no _NET_WM_ICON or WM hints icon. Before falling back to the default icon, search the hicolor icon theme at /usr/share/icons/hicolor//apps/.png and /usr/share/pixmaps/ for a matching icon based on the xdg_toplevel app_id. --- src/icon.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/src/icon.c b/src/icon.c index f1d35ef..b210cfb 100644 --- a/src/icon.c +++ b/src/icon.c @@ -63,6 +63,7 @@ static void get_rimage_icon_from_icon_win(WIcon *icon); static void get_rimage_icon_from_user_icon(WIcon *icon); static void get_rimage_icon_from_default_icon(WIcon *icon); static void get_rimage_icon_from_x11(WIcon *icon); +static void get_rimage_icon_from_freedesktop(WIcon *icon); static void icon_update_pixmap(WIcon *icon, RImage *image); static void unset_icon_image(WIcon *icon); @@ -652,8 +653,10 @@ void wIconUpdate(WIcon *icon) if (!icon->file_image) get_rimage_icon_from_user_icon(icon); } else { - /* Get the WMNativePixmap from the user */ - get_rimage_icon_from_user_icon(icon); + /* Try freedesktop icon theme, then fall back to user/default */ + get_rimage_icon_from_freedesktop(icon); + if (!icon->file_image) + get_rimage_icon_from_user_icon(icon); } update_icon_pixmap(icon); @@ -718,6 +721,46 @@ static void get_rimage_icon_from_default_icon(WIcon *icon) icon->file_image = RRetainImage(scr->def_icon_rimage); } +static void get_rimage_icon_from_freedesktop(WIcon *icon) +{ + WWindow *wwin = icon->owner; + if (!wwin || !wwin->wm_instance) + return; + + WScreen *scr = icon->core->screen_ptr; + const char *app_id = wwin->wm_instance; + const char *sizes[] = { "48x48", "64x64", "128x128", "256x256", "32x32", "24x24", NULL }; + char path[512]; + RImage *image = NULL; + + for (int i = 0; sizes[i]; i++) { + snprintf(path, sizeof(path), "/usr/share/icons/hicolor/%s/apps/%s.png", sizes[i], app_id); + if (access(path, R_OK) == 0) { + image = RLoadImage(scr->rcontext, path, 0); + if (image) + break; + } + } + + if (!image) { + /* Try pixmaps directory as fallback */ + snprintf(path, sizeof(path), "/usr/share/pixmaps/%s.png", app_id); + if (access(path, R_OK) == 0) + image = RLoadImage(scr->rcontext, path, 0); + } + + if (image) { + unset_icon_image(icon); + int s = wPreferences.icon_size - 4; + if (image->width != s || image->height != s) { + RImage *scaled = RScaleImage(image, s, s); + RReleaseImage(image); + image = scaled; + } + icon->file_image = image; + } +} + /* Get the RImage from the WIcon of the WWindow */ static void get_rimage_icon_from_icon_win(WIcon *icon) {