Finds paths to icon files using libsfdo. Libsfdo is currently an

optional compile time dependency. This means the former code paths are
all retained and new ones are wrapped in #if HAVE_LIBSFDO. Behavior
should be identical now between the two code paths. Later commits will
add the handling of icons specified as absolute paths which both former
swaybar code and libsfdo have thus far avoided.
This commit is contained in:
myrslint 2025-04-29 17:37:58 +00:00
parent 3a21b8c6f1
commit aeeb99c5a3
14 changed files with 220 additions and 93 deletions

View file

@ -8,6 +8,7 @@ lib_sway_common = static_library(
'loop.c',
'list.c',
'pango.c',
'sfdo.c',
'stringop.c',
'util.c'
),

95
common/sfdo.c Normal file
View file

@ -0,0 +1,95 @@
#include <stdlib.h>
#include <sfdo-basedir.h>
#include <sfdo-desktop.h>
#include <sfdo-icon.h>
#include "log.h"
#include "sfdo.h"
char *sfdo_icon_lookup_extended(struct sfdo *sfdo, char *icon_name, int target_size, int scale) {
int lookup_options = SFDO_ICON_THEME_LOOKUP_OPTIONS_DEFAULT;
struct sfdo_icon_file *icon_file = \
sfdo_icon_theme_lookup(sfdo->icon_theme, icon_name, SFDO_NT, \
target_size, scale, lookup_options);
char *icon_path = NULL;
if (icon_file && icon_file != SFDO_ICON_FILE_INVALID) {
icon_path = strdup(sfdo_icon_file_get_path(icon_file, NULL));
}
sfdo_icon_file_destroy(icon_file);
return icon_path;
}
struct sfdo *sfdo_create(char *icon_theme) {
if (!icon_theme) {
goto error_null;
}
struct sfdo *sfdo = calloc(1, sizeof(struct sfdo));
if (!sfdo) {
goto error_calloc;
}
struct sfdo_basedir_ctx *basedir_ctx = sfdo_basedir_ctx_create();
if (!basedir_ctx) {
goto error_basedir_ctx;
}
sfdo->desktop_ctx = sfdo_desktop_ctx_create(basedir_ctx);
if (!sfdo->desktop_ctx) {
goto error_desktop_ctx;
}
sfdo->icon_ctx = sfdo_icon_ctx_create(basedir_ctx);
if (!sfdo->icon_ctx) {
goto error_icon_ctx;
}
sfdo->desktop_db = sfdo_desktop_db_load(sfdo->desktop_ctx, NULL);
if (!sfdo->desktop_db) {
goto error_desktop_db;
}
int load_options = SFDO_ICON_THEME_LOAD_OPTIONS_DEFAULT
| SFDO_ICON_THEME_LOAD_OPTION_ALLOW_MISSING
| SFDO_ICON_THEME_LOAD_OPTION_RELAXED;
sfdo->icon_theme = sfdo_icon_theme_load(sfdo->icon_ctx, icon_theme, load_options);
if (!sfdo->icon_theme) {
goto error_icon_theme;
}
sfdo_basedir_ctx_destroy(basedir_ctx);
sway_log(SWAY_INFO, "Successfully setup sfdo with icon theme %s", icon_theme);
return sfdo;
error_icon_theme:
sfdo_desktop_db_destroy(sfdo->desktop_db);
error_desktop_db:
sfdo_icon_ctx_destroy(sfdo->icon_ctx);
error_icon_ctx:
sfdo_desktop_ctx_destroy(sfdo->desktop_ctx);
error_desktop_ctx:
sfdo_basedir_ctx_destroy(basedir_ctx);
error_basedir_ctx:
free(sfdo);
error_calloc:
error_null:
// it's safe to call with null
sway_log(SWAY_ERROR, "Failed to setup sfdo with icon theme %s", icon_theme);
return NULL;
}
void sfdo_destroy(struct sfdo *sfdo) {
if (!sfdo) {
sway_log(SWAY_DEBUG, "Null sfdo passed in");
return;
}
sfdo_desktop_ctx_destroy(sfdo->desktop_ctx);
sfdo_icon_ctx_destroy(sfdo->icon_ctx);
sfdo_desktop_db_destroy(sfdo->desktop_db);
sfdo_icon_theme_destroy(sfdo->icon_theme);
free(sfdo);
sway_log(SWAY_DEBUG, "Successfully destroyed sfdo");
}

19
include/sfdo.h Normal file
View file

@ -0,0 +1,19 @@
#ifndef _SWAY_SFDO_H
#define _SWAY_SFDO_H
#include <sfdo-desktop.h>
#include <sfdo-icon.h>
#include <sfdo-basedir.h>
struct sfdo {
struct sfdo_desktop_ctx *desktop_ctx;
struct sfdo_icon_ctx *icon_ctx;
struct sfdo_desktop_db *desktop_db;
struct sfdo_icon_theme *icon_theme;
};
char *sfdo_icon_lookup_extended(struct sfdo *sfdo, char *icon_name, int target_size, int scale);
struct sfdo *sfdo_create(char *icon_theme);
void sfdo_destroy(struct sfdo *sfdo);
#endif

View file

@ -399,8 +399,11 @@ struct bar_config {
char *binding_mode_text;
} colors;
#if HAVE_TRAY
#if HAVE_TRAY || HAVE_LIBSFDO
char *icon_theme;
#endif
#if HAVE_TRAY
struct wl_list tray_bindings; // struct tray_binding::link
list_t *tray_outputs; // char *
int tray_padding;

View file

@ -8,11 +8,11 @@
#if WLR_HAS_XWAYLAND
#include "sway/xwayland.h"
#endif
#if HAVE_LIBSFDO
#include <sfdo-desktop.h>
#include <sfdo-icon.h>
#include <sfdo-basedir.h>
#include "sfdo.h"
#endif
struct sway_transaction;
struct sway_session_lock {
@ -28,15 +28,6 @@ struct sway_session_lock {
struct wl_listener destroy;
};
#if HAVE_LIBSFDO
struct sfdo {
struct sfdo_desktop_ctx *desktop_ctx;
struct sfdo_icon_ctx *icon_ctx;
struct sfdo_desktop_db *desktop_db;
struct sfdo_icon_theme *icon_theme;
};
#endif
struct sway_server {
struct wl_display *wl_display;
struct wl_event_loop *wl_event_loop;
@ -209,9 +200,4 @@ void set_rr_scheduling(void);
void handle_new_tearing_hint(struct wl_listener *listener, void *data);
#if HAVE_LIBSFDO
struct sfdo *sfdo_create(char *theme);
void sfdo_destroy(struct sfdo *sfdo);
#endif
#endif

View file

@ -16,6 +16,10 @@ struct swaybar_tray;
struct swaybar_workspace;
struct loop;
#if HAVE_LIBSFDO
struct sfdo;
#endif
struct swaybar {
char *id;
char *mode;
@ -50,6 +54,10 @@ struct swaybar {
struct swaybar_tray *tray;
#endif
#if HAVE_LIBSFDO
struct sfdo *sfdo;
#endif
bool running;
};

View file

@ -8,6 +8,10 @@
#include "util.h"
#include <pango/pangocairo.h>
#if HAVE_LIBSFDO
#include "sfdo.h"
#endif
struct box_colors {
uint32_t border;
uint32_t background;
@ -68,13 +72,20 @@ struct swaybar_config {
struct box_colors binding_mode;
} colors;
#if HAVE_TRAY
#if HAVE_TRAY || HAVE_LIBSFDO
char *icon_theme;
#endif
#if HAVE_TRAY
struct wl_list tray_bindings; // struct tray_binding::link
bool tray_hidden;
list_t *tray_outputs; // char *
int tray_padding;
#endif
#if HAVE_LIBSFDO
struct sfdo *sfdo;
#endif
};
#if HAVE_TRAY

View file

@ -70,6 +70,14 @@ void free_bar_config(struct bar_config *bar) {
free(bar->colors.binding_mode_border);
free(bar->colors.binding_mode_bg);
free(bar->colors.binding_mode_text);
// this is to cover the case where tray support is not compiled in
// but we have libsfdo support which implies at least a default
// icon_theme string was allocated
#if HAVE_LIBSFDO && !HAVE_TRAY
free(bar->icone_theme);
#endif
#if HAVE_TRAY
list_free_items_and_destroy(bar->tray_outputs);
free(bar->icon_theme);
@ -170,6 +178,13 @@ struct bar_config *default_bar_config(void) {
bar->colors.binding_mode_bg = NULL;
bar->colors.binding_mode_text = NULL;
// we need some default when we initialize sfdo
#if HAVE_LIBSFDO
if (!(bar->icon_theme = strdup("Hicolor"))) {
goto cleanup;
}
#endif
#if HAVE_TRAY
bar->tray_padding = 2;
wl_list_init(&bar->tray_bindings);

View file

@ -71,9 +71,7 @@
#endif
#if HAVE_LIBSFDO
#include <sfdo-basedir.h>
#include <sfdo-desktop.h>
#include <sfdo-icon.h>
#include "sfdo.h"
#endif
#define SWAY_XDG_SHELL_VERSION 5
@ -570,73 +568,3 @@ void server_run(struct sway_server *server) {
server->socket);
wl_display_run(server->wl_display);
}
#if HAVE_LIBSFDO
struct sfdo *sfdo_create(char *theme) {
struct sfdo *sfdo = calloc(1, sizeof(struct sfdo));
if (!sfdo) {
goto error_calloc;
}
struct sfdo_basedir_ctx *basedir_ctx = sfdo_basedir_ctx_create();
if (!basedir_ctx) {
goto error_basedir_ctx;
}
sfdo->desktop_ctx = sfdo_desktop_ctx_create(basedir_ctx);
if (!sfdo->desktop_ctx) {
goto error_desktop_ctx;
}
sfdo->icon_ctx = sfdo_icon_ctx_create(basedir_ctx);
if (!sfdo->icon_ctx) {
goto error_icon_ctx;
}
sfdo->desktop_db = sfdo_desktop_db_load(sfdo->desktop_ctx, NULL);
if (!sfdo->desktop_db) {
goto error_desktop_db;
}
int load_options = SFDO_ICON_THEME_LOAD_OPTIONS_DEFAULT
| SFDO_ICON_THEME_LOAD_OPTION_ALLOW_MISSING
| SFDO_ICON_THEME_LOAD_OPTION_RELAXED;
sfdo->icon_theme = sfdo_icon_theme_load(sfdo->icon_ctx, theme, load_options);
if (!sfdo->icon_theme) {
goto error_icon_theme;
}
sfdo_basedir_ctx_destroy(basedir_ctx);
sway_log(SWAY_DEBUG, "Successfully setup sfdo");
return sfdo;
error_icon_theme:
sfdo_desktop_db_destroy(sfdo->desktop_db);
error_desktop_db:
sfdo_icon_ctx_destroy(sfdo->icon_ctx);
error_icon_ctx:
sfdo_desktop_ctx_destroy(sfdo->desktop_ctx);
error_desktop_ctx:
sfdo_basedir_ctx_destroy(basedir_ctx);
error_basedir_ctx:
free(sfdo);
error_calloc:
sway_log(SWAY_ERROR, "Failed to setup sfdo");
return NULL;
}
void sfdo_destroy(struct sfdo *sfdo) {
if (!sfdo) {
sway_log(SWAY_DEBUG, "Null sfdo passed in");
return;
}
sfdo_icon_theme_destroy(sfdo->icon_theme);
sfdo_desktop_db_destroy(sfdo->desktop_db);
sfdo_icon_ctx_destroy(sfdo->icon_ctx);
sfdo_desktop_ctx_destroy(sfdo->desktop_ctx);
sway_log(SWAY_DEBUG, "Successfully destroyed sfdo");
}
#endif

View file

@ -537,6 +537,9 @@ static void free_seats(struct wl_list *list) {
void bar_teardown(struct swaybar *bar) {
#if HAVE_TRAY
destroy_tray(bar->tray);
#endif
#if HAVE_LIBSFDO
sfdo_destroy(bar->config->sfdo);
#endif
free_outputs(&bar->outputs);
free_outputs(&bar->unused_outputs);

View file

@ -7,6 +7,10 @@
#include "list.h"
#include "log.h"
#if HAVE_LIBSFDO
#include "sfdo.h"
#endif
uint32_t parse_position(const char *position) {
uint32_t horiz = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
@ -131,5 +135,15 @@ void free_config(struct swaybar_config *config) {
free(config->icon_theme);
#endif
#if HAVE_LIBSFDO && !HAVE_TRAY
free(config->icon_theme);
#endif
#if HAVE_LIBSFDO
sfdo_destroy(config->sfdo);
sway_log(SWAY_DEBUG, "Destroyed swaybar sfdo");
#endif
free(config);
}

View file

@ -18,6 +18,10 @@
#include "stringop.h"
#include "util.h"
#if HAVE_LIBSFDO
#include "sfdo.h"
#endif
void ipc_send_workspace_command(struct swaybar *bar, const char *ws) {
uint32_t size = strlen("workspace \"\"") + strlen(ws);
for (size_t i = 0; i < strlen(ws); ++i) {
@ -330,6 +334,10 @@ static bool ipc_parse_config(
if ((json_object_object_get_ex(bar_config, "icon_theme", &icon_theme))) {
config->icon_theme = strdup(json_object_get_string(icon_theme));
#if HAVE_LIBSFDO
sfdo_destroy(config->sfdo);
config->sfdo = sfdo_create(config->icon_theme);
#endif
}
#endif

View file

@ -21,6 +21,15 @@ if have_tray
swaybar_deps += sdbus
endif
if have_libsfdo
swaybar_deps += [
sfdo_basedir,
sfdo_desktop,
sfdo_desktop_file,
sfdo_icon
]
endif
executable(
'swaybar', [
'bar.c',

View file

@ -1,6 +1,8 @@
#include <arpa/inet.h>
#include <cairo.h>
#include <limits.h>
#include <sfdo-common.h>
#include <sfdo-icon.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
@ -18,6 +20,10 @@
#include "stringop.h"
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
#if HAVE_LIBSFDO
#include "sfdo.h"
#endif
// TODO menu
static bool sni_ready(struct swaybar_sni *sni) {
@ -420,15 +426,36 @@ static void reload_sni(struct swaybar_sni *sni, char *icon_theme,
char *icon_name = sni->status[0] == 'N' ?
sni->attention_icon_name : sni->icon_name;
if (icon_name) {
char *icon_path = NULL;
#if !HAVE_LIBSFDO
list_t *icon_search_paths = create_list();
list_cat(icon_search_paths, sni->tray->basedirs);
if (sni->icon_theme_path) {
list_add(icon_search_paths, sni->icon_theme_path);
}
char *icon_path = find_icon(sni->tray->themes, icon_search_paths,
icon_path = find_icon(sni->tray->themes, icon_search_paths,
icon_name, target_size, icon_theme,
&sni->min_size, &sni->max_size);
#else
struct sfdo *sfdo = sni->tray->bar->config->sfdo;
if (sfdo) {
int lookup_options = SFDO_ICON_THEME_LOOKUP_OPTIONS_DEFAULT;
int scale = 1;
struct sfdo_icon_file *icon_file = \
sfdo_icon_theme_lookup(sfdo->icon_theme, icon_name, SFDO_NT, \
target_size, scale, lookup_options);
if (!icon_file || icon_file == SFDO_ICON_FILE_INVALID) {
sway_log(SWAY_ERROR, "sfdo: icon %s invalid or not found in theme %s at size %d", \
icon_name, icon_theme, target_size);
} else {
icon_path = strdup(sfdo_icon_file_get_path(icon_file, NULL));
}
sfdo_icon_file_destroy(icon_file);
}
#endif
#if !HAVE_LIBSFDO
list_free(icon_search_paths);
#endif
if (icon_path) {
cairo_surface_destroy(sni->icon);
sni->icon = load_image(icon_path);