swaybar/tray: replace icon lookup with libsfdo

Drops the in-tree icon theme parser and lookup logic in favor of
libsfdo-icon, which implements the icon theme spec.

Absolute icon paths are handled in swaybar itself with an access()
probe, since libsfdo intentionally doesn't deal with them. Pixmap
fallback still kicks in if load_image() fails on the absolute path.

KDE's IconThemePath is honored via sfdo_icon_theme_load_from() with
a per-SNI override theme that gets dropped when the property changes.

The min/max size cache per SNI is replaced by re-lookup when the
rendered size changes; libsfdo caches the parsed theme internally
and reads gtk's icon-theme.cache files, so this is cheap.

Theme switching at runtime is preserved via a new
tray_reload_icon_theme() called from parse_bar_config(). The old
code worked here implicitly because all themes were preloaded.

Closes: https://github.com/swaywm/sway/issues/8607
This commit is contained in:
Tim Jochen Kicker 2026-05-05 23:55:55 +02:00
parent c857ca3a97
commit 81c31b0c4d
11 changed files with 175 additions and 597 deletions

View file

@ -1,43 +0,0 @@
#ifndef _SWAYBAR_TRAY_ICON_H
#define _SWAYBAR_TRAY_ICON_H
#include "list.h"
struct icon_theme_subdir {
char *name;
int size;
enum {
THRESHOLD,
SCALABLE,
FIXED
} type;
int max_size;
int min_size;
int threshold;
};
struct icon_theme {
char *name;
char *comment;
list_t *inherits; // char *
list_t *directories; // char *
char *dir;
list_t *subdirs; // struct icon_theme_subdir *
};
void init_themes(list_t **themes, list_t **basedirs);
void finish_themes(list_t *themes, list_t *basedirs);
/*
* Finds an icon of a specified size given a list of themes and base directories.
* If the icon is found, the pointers min_size & max_size are set to minimum &
* maximum size that the icon can be scaled to, respectively.
* Returns: path of icon (which should be freed), or NULL if the icon is not found.
*/
char *find_icon(list_t *themes, list_t *basedirs, char *name, int size,
char *theme, int *min_size, int *max_size);
#endif

View file

@ -28,9 +28,9 @@ struct swaybar_sni {
// icon properties
struct swaybar_tray *tray;
cairo_surface_t *icon;
int min_size;
int max_size;
int icon_size;
int target_size;
struct sfdo_icon_theme *icon_theme_override; // non-NULL if IconThemePath set
// dbus properties
char *watcher_id;

View file

@ -10,6 +10,7 @@
#include <basu/sd-bus.h>
#endif
#include <cairo.h>
#include <sfdo-icon.h>
#include <stdint.h>
#include "swaybar/tray/host.h"
#include "list.h"
@ -30,13 +31,15 @@ struct swaybar_tray {
struct swaybar_watcher *watcher_xdg;
struct swaybar_watcher *watcher_kde;
list_t *basedirs; // char *
list_t *themes; // struct swaybar_theme *
struct sfdo_icon_ctx *icon_ctx;
struct sfdo_icon_theme *icon_theme;
char *icon_theme_name;
};
struct swaybar_tray *create_tray(struct swaybar *bar);
void destroy_tray(struct swaybar_tray *tray);
void tray_in(int fd, short mask, void *data);
void tray_reload_icon_theme(struct swaybar_tray *tray, const char *name);
uint32_t render_tray(cairo_t *cairo, struct swaybar_output *output, double *x);
#endif