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/<size>/apps/<app_id>.png and /usr/share/pixmaps/
for a matching icon based on the xdg_toplevel app_id.
This commit is contained in:
lkn 2026-06-21 19:24:59 +02:00
parent bc0446aa7a
commit 9f32dc4eef
1 changed files with 45 additions and 2 deletions

View File

@ -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)
{