From f69576f8a60c1c915462ded055d5a5ce0ff1aec9 Mon Sep 17 00:00:00 2001 From: Jens Peters Date: Mon, 18 Nov 2024 18:59:49 +0100 Subject: [PATCH 1/3] icon-loader: rename to desktop-entry Also rename `struct icon_loader` to `struct sfdo`. --- include/desktop-entry.h | 12 ++++ include/icon-loader.h | 12 ---- include/labwc.h | 2 +- src/{icon-loader.c => desktop-entry.c} | 77 +++++++++++++------------- src/meson.build | 2 +- src/server.c | 10 ++-- src/ssd/ssd-titlebar.c | 4 +- 7 files changed, 60 insertions(+), 59 deletions(-) create mode 100644 include/desktop-entry.h delete mode 100644 include/icon-loader.h rename src/{icon-loader.c => desktop-entry.c} (80%) diff --git a/include/desktop-entry.h b/include/desktop-entry.h new file mode 100644 index 00000000..30db1546 --- /dev/null +++ b/include/desktop-entry.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef LABWC_DESKTOP_ENTRY_H +#define LABWC_DESKTOP_ENTRY_H + +struct server; + +void desktop_entry_init(struct server *server); +void desktop_entry_finish(struct server *server); +struct lab_data_buffer *desktop_entry_icon_lookup(struct server *server, + const char *app_id, int size, float scale); + +#endif /* LABWC_DESKTOP_ENTRY_H */ diff --git a/include/icon-loader.h b/include/icon-loader.h deleted file mode 100644 index 846d20a2..00000000 --- a/include/icon-loader.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef LABWC_ICON_LOADER_H -#define LABWC_ICON_LOADER_H - -struct server; - -void icon_loader_init(struct server *server); -void icon_loader_finish(struct server *server); -struct lab_data_buffer *icon_loader_lookup(struct server *server, - const char *app_id, int size, float scale); - -#endif /* LABWC_ICON_LOADER_H */ diff --git a/include/labwc.h b/include/labwc.h index b9095ae1..b02868a6 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -379,7 +379,7 @@ struct server { struct menu *menu_current; struct wl_list menus; - struct icon_loader *icon_loader; + struct sfdo *sfdo; pid_t primary_client_pid; }; diff --git a/src/icon-loader.c b/src/desktop-entry.c similarity index 80% rename from src/icon-loader.c rename to src/desktop-entry.c index d31ae07e..d51451ed 100644 --- a/src/icon-loader.c +++ b/src/desktop-entry.c @@ -9,7 +9,7 @@ #include "common/mem.h" #include "common/string-helpers.h" #include "config.h" -#include "icon-loader.h" +#include "desktop-entry.h" #include "img/img-png.h" #include "img/img-xpm.h" @@ -19,7 +19,7 @@ #include "labwc.h" -struct icon_loader { +struct sfdo { struct sfdo_desktop_ctx *desktop_ctx; struct sfdo_icon_ctx *icon_ctx; struct sfdo_desktop_db *desktop_db; @@ -40,20 +40,20 @@ log_handler(enum sfdo_log_level level, const char *fmt, va_list args, void *tag) } void -icon_loader_init(struct server *server) +desktop_entry_init(struct server *server) { - struct icon_loader *loader = znew(*loader); + struct sfdo *sfdo = znew(*sfdo); struct sfdo_basedir_ctx *basedir_ctx = sfdo_basedir_ctx_create(); if (!basedir_ctx) { goto err_basedir_ctx; } - loader->desktop_ctx = sfdo_desktop_ctx_create(basedir_ctx); - if (!loader->desktop_ctx) { + sfdo->desktop_ctx = sfdo_desktop_ctx_create(basedir_ctx); + if (!sfdo->desktop_ctx) { goto err_desktop_ctx; } - loader->icon_ctx = sfdo_icon_ctx_create(basedir_ctx); - if (!loader->icon_ctx) { + sfdo->icon_ctx = sfdo_icon_ctx_create(basedir_ctx); + if (!sfdo->icon_ctx) { goto err_icon_ctx; } @@ -61,12 +61,12 @@ icon_loader_init(struct server *server) enum sfdo_log_level level = (enum sfdo_log_level)wlr_log_get_verbosity(); sfdo_desktop_ctx_set_log_handler( - loader->desktop_ctx, level, log_handler, "sfdo-desktop"); + sfdo->desktop_ctx, level, log_handler, "sfdo-desktop"); sfdo_icon_ctx_set_log_handler( - loader->icon_ctx, level, log_handler, "sfdo-icon"); + sfdo->icon_ctx, level, log_handler, "sfdo-icon"); - loader->desktop_db = sfdo_desktop_db_load(loader->desktop_ctx, NULL); - if (!loader->desktop_db) { + sfdo->desktop_db = sfdo_desktop_db_load(sfdo->desktop_ctx, NULL); + if (!sfdo->desktop_db) { goto err_desktop_db; } @@ -84,45 +84,46 @@ icon_loader_init(struct server *server) | SFDO_ICON_THEME_LOAD_OPTION_ALLOW_MISSING | SFDO_ICON_THEME_LOAD_OPTION_RELAXED; - loader->icon_theme = sfdo_icon_theme_load(loader->icon_ctx, + sfdo->icon_theme = sfdo_icon_theme_load( + sfdo->icon_ctx, rc.icon_theme_name, load_options); - if (!loader->icon_theme) { + if (!sfdo->icon_theme) { goto err_icon_theme; } /* basedir_ctx is not referenced by other objects */ sfdo_basedir_ctx_destroy(basedir_ctx); - server->icon_loader = loader; + server->sfdo = sfdo; return; err_icon_theme: - sfdo_desktop_db_destroy(loader->desktop_db); + sfdo_desktop_db_destroy(sfdo->desktop_db); err_desktop_db: - sfdo_icon_ctx_destroy(loader->icon_ctx); + sfdo_icon_ctx_destroy(sfdo->icon_ctx); err_icon_ctx: - sfdo_desktop_ctx_destroy(loader->desktop_ctx); + sfdo_desktop_ctx_destroy(sfdo->desktop_ctx); err_desktop_ctx: sfdo_basedir_ctx_destroy(basedir_ctx); err_basedir_ctx: - free(loader); + free(sfdo); wlr_log(WLR_ERROR, "Failed to initialize icon loader"); } void -icon_loader_finish(struct server *server) +desktop_entry_finish(struct server *server) { - struct icon_loader *loader = server->icon_loader; - if (!loader) { + struct sfdo *sfdo = server->sfdo; + if (!sfdo) { return; } - sfdo_icon_theme_destroy(loader->icon_theme); - sfdo_desktop_db_destroy(loader->desktop_db); - sfdo_icon_ctx_destroy(loader->icon_ctx); - sfdo_desktop_ctx_destroy(loader->desktop_ctx); - free(loader); - server->icon_loader = NULL; + 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); + free(sfdo); + server->sfdo = NULL; } struct icon_ctx { @@ -153,7 +154,7 @@ length_without_extension(const char *name) */ static int process_rel_name(struct icon_ctx *ctx, const char *icon_name, - struct icon_loader *loader, int size, int scale) + struct sfdo *sfdo, int size, int scale) { int ret = 0; int lookup_options = SFDO_ICON_THEME_LOOKUP_OPTIONS_DEFAULT; @@ -168,7 +169,7 @@ process_rel_name(struct icon_ctx *ctx, const char *icon_name, */ size_t name_len = length_without_extension(icon_name); struct sfdo_icon_file *icon_file = sfdo_icon_theme_lookup( - loader->icon_theme, icon_name, name_len, size, scale, + sfdo->icon_theme, icon_name, name_len, size, scale, lookup_options); if (!icon_file || icon_file == SFDO_ICON_FILE_INVALID) { ret = -1; @@ -255,19 +256,19 @@ get_db_entry_by_id_fuzzy(struct sfdo_desktop_db *db, const char *app_id) } struct lab_data_buffer * -icon_loader_lookup(struct server *server, const char *app_id, int size, +desktop_entry_icon_lookup(struct server *server, const char *app_id, int size, float scale) { - struct icon_loader *loader = server->icon_loader; - if (!loader) { + struct sfdo *sfdo = server->sfdo; + if (!sfdo) { return NULL; } const char *icon_name = NULL; struct sfdo_desktop_entry *entry = sfdo_desktop_db_get_entry_by_id( - loader->desktop_db, app_id, SFDO_NT); + sfdo->desktop_db, app_id, SFDO_NT); if (!entry) { - entry = get_db_entry_by_id_fuzzy(loader->desktop_db, app_id); + entry = get_db_entry_by_id_fuzzy(sfdo->desktop_db, app_id); } if (entry) { icon_name = sfdo_desktop_entry_get_icon(entry, NULL); @@ -284,15 +285,15 @@ icon_loader_lookup(struct server *server, const char *app_id, int size, int ret; if (!icon_name) { /* fall back to app id */ - ret = process_rel_name(&ctx, app_id, loader, lookup_size, lookup_scale); + ret = process_rel_name(&ctx, app_id, sfdo, lookup_size, lookup_scale); } else if (icon_name[0] == '/') { ret = process_abs_name(&ctx, icon_name); } else { /* this should be the case for most icons */ - ret = process_rel_name(&ctx, icon_name, loader, lookup_size, lookup_scale); + ret = process_rel_name(&ctx, icon_name, sfdo, lookup_size, lookup_scale); /* Icon defined in .desktop file could not be loaded, retry with app_id */ if (ret < 0) { - ret = process_rel_name(&ctx, app_id, loader, lookup_size, lookup_scale); + ret = process_rel_name(&ctx, app_id, sfdo, lookup_size, lookup_scale); } } if (ret < 0) { diff --git a/src/meson.build b/src/meson.build index 497bc33f..40cf0f69 100644 --- a/src/meson.build +++ b/src/meson.build @@ -45,7 +45,7 @@ endif if have_libsfdo labwc_sources += files( - 'icon-loader.c', + 'desktop-entry.c', ) endif diff --git a/src/server.c b/src/server.c index 697caa5b..b2077330 100644 --- a/src/server.c +++ b/src/server.c @@ -30,7 +30,7 @@ #include "config/session.h" #include "decorations.h" #if HAVE_LIBSFDO -#include "icon-loader.h" +#include "desktop-entry.h" #endif #include "idle.h" #include "labwc.h" @@ -66,8 +66,8 @@ reload_config_and_theme(struct server *server) theme_init(server->theme, server, rc.theme_name); #if HAVE_LIBSFDO - icon_loader_finish(server); - icon_loader_init(server); + desktop_entry_finish(server); + desktop_entry_init(server); #endif struct view *view; @@ -585,7 +585,7 @@ server_init(struct server *server) layers_init(server); #if HAVE_LIBSFDO - icon_loader_init(server); + desktop_entry_init(server); #endif #if HAVE_XWAYLAND @@ -629,7 +629,7 @@ server_finish(struct server *server) xwayland_server_finish(server); #endif #if HAVE_LIBSFDO - icon_loader_finish(server); + desktop_entry_finish(server); #endif if (sighup_source) { wl_event_source_remove(sighup_source); diff --git a/src/ssd/ssd-titlebar.c b/src/ssd/ssd-titlebar.c index 373dd1c4..3f194603 100644 --- a/src/ssd/ssd-titlebar.c +++ b/src/ssd/ssd-titlebar.c @@ -10,7 +10,7 @@ #include "common/scene-helpers.h" #include "common/string-helpers.h" #if HAVE_LIBSFDO -#include "icon-loader.h" +#include "desktop-entry.h" #endif #include "labwc.h" #include "node.h" @@ -610,7 +610,7 @@ ssd_update_window_icon(struct ssd *ssd) */ float icon_scale = output_max_scale(ssd->view->server); - struct lab_data_buffer *icon_buffer = icon_loader_lookup( + struct lab_data_buffer *icon_buffer = desktop_entry_icon_lookup( ssd->view->server, app_id, icon_size, icon_scale); if (!icon_buffer) { wlr_log(WLR_DEBUG, "icon could not be loaded for %s", app_id); From 57aee700f731262e771ae33c4128aa1385878143 Mon Sep 17 00:00:00 2001 From: Jens Peters Date: Mon, 18 Nov 2024 19:03:39 +0100 Subject: [PATCH 2/3] sfdo: add sfdo_desktop_entry_name_lookup() --- include/desktop-entry.h | 11 +++++++++++ src/desktop-entry.c | 40 +++++++++++++++++++++++++++++++++++----- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/include/desktop-entry.h b/include/desktop-entry.h index 30db1546..42b47081 100644 --- a/include/desktop-entry.h +++ b/include/desktop-entry.h @@ -6,7 +6,18 @@ struct server; void desktop_entry_init(struct server *server); void desktop_entry_finish(struct server *server); + struct lab_data_buffer *desktop_entry_icon_lookup(struct server *server, const char *app_id, int size, float scale); +/** + * desktop_entry_name_lookup() - return the application name + * from the sfdo desktop entry database based on app_id + * + * The lifetime of the returned value is the same as that + * of sfdo_desktop_db (from `struct sfdo.desktop_db`) + */ +const char *desktop_entry_name_lookup(struct server *server, + const char *app_id); + #endif /* LABWC_DESKTOP_ENTRY_H */ diff --git a/src/desktop-entry.c b/src/desktop-entry.c index d51451ed..404bc989 100644 --- a/src/desktop-entry.c +++ b/src/desktop-entry.c @@ -255,6 +255,18 @@ get_db_entry_by_id_fuzzy(struct sfdo_desktop_db *db, const char *app_id) return NULL; } +static struct sfdo_desktop_entry * +get_desktop_entry(struct sfdo *sfdo, const char *app_id) +{ + struct sfdo_desktop_entry *entry = sfdo_desktop_db_get_entry_by_id( + sfdo->desktop_db, app_id, SFDO_NT); + if (!entry) { + entry = get_db_entry_by_id_fuzzy(sfdo->desktop_db, app_id); + } + + return entry; +} + struct lab_data_buffer * desktop_entry_icon_lookup(struct server *server, const char *app_id, int size, float scale) @@ -265,11 +277,7 @@ desktop_entry_icon_lookup(struct server *server, const char *app_id, int size, } const char *icon_name = NULL; - struct sfdo_desktop_entry *entry = sfdo_desktop_db_get_entry_by_id( - sfdo->desktop_db, app_id, SFDO_NT); - if (!entry) { - entry = get_db_entry_by_id_fuzzy(sfdo->desktop_db, app_id); - } + struct sfdo_desktop_entry *entry = get_desktop_entry(sfdo, app_id); if (entry) { icon_name = sfdo_desktop_entry_get_icon(entry, NULL); } @@ -321,3 +329,25 @@ desktop_entry_icon_lookup(struct server *server, const char *app_id, int size, free(ctx.path); return icon_buffer; } + +const char * +desktop_entry_name_lookup(struct server *server, const char *app_id) +{ + struct sfdo *sfdo = server->sfdo; + if (!sfdo) { + return NULL; + } + + struct sfdo_desktop_entry *entry = get_desktop_entry(sfdo, app_id); + if (!entry) { + return NULL; + } + + size_t len; + const char *name = sfdo_desktop_entry_get_name(entry, &len); + if (!len) { + return NULL; + } + + return name; +} From 7b5c76d573d51b2a690e4ca2e078dbf3138a95e1 Mon Sep 17 00:00:00 2001 From: Jens Peters Date: Mon, 18 Nov 2024 21:38:43 +0100 Subject: [PATCH 3/3] osd: add desktop entry name option Looks desktop entry name up from libsfdo. --- docs/labwc-config.5.scd | 5 +++++ include/osd.h | 1 + src/osd-field.c | 27 +++++++++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 9d469dde..5925a007 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -270,6 +270,9 @@ this is for compatibility with Openbox. - *trimmed_identifier* Show trimmed identifier. Trimming removes the first two nodes of 'org.' strings. + - *desktop_entry_name* Show application name from freedesktop.org desktop + entry/file. Falls back to trimmed identifier (trimmed_identifier). + - *title* Show window title if different to app_id - *workspace* Show workspace name @@ -289,6 +292,8 @@ this is for compatibility with Openbox. - 's' - state of window (short form), values [M|m|F] (1 space) - 'I' - wm-class/app-id - 'i' - wm-class/app-id trimmed, remove "org." if available + - 'n' - desktop entry/file application name, falls back to + wm-class/app-id trimmed - 'W' - workspace name - 'w' - workspace name (if more than 1 ws configured) - 'O' - output name diff --git a/include/osd.h b/include/osd.h index 4fa0fa3b..478bcc30 100644 --- a/include/osd.h +++ b/include/osd.h @@ -12,6 +12,7 @@ enum window_switcher_field_content { LAB_FIELD_TYPE_SHORT, LAB_FIELD_IDENTIFIER, LAB_FIELD_TRIMMED_IDENTIFIER, + LAB_FIELD_DESKTOP_ENTRY_NAME, LAB_FIELD_TITLE, LAB_FIELD_TITLE_SHORT, LAB_FIELD_WORKSPACE, diff --git a/src/osd-field.c b/src/osd-field.c index b97418b2..926f908f 100644 --- a/src/osd-field.c +++ b/src/osd-field.c @@ -7,6 +7,9 @@ #include "view.h" #include "workspaces.h" #include "labwc.h" +#if HAVE_LIBSFDO +#include "desktop-entry.h" +#endif #include "osd.h" /* includes '%', terminating 's' and NULL byte, 8 is enough for %-9999s */ @@ -44,6 +47,20 @@ get_app_id_or_class(struct view *view, bool trim) return identifier; } +static const char * +get_desktop_name(struct view *view) +{ +#if HAVE_LIBSFDO + const char *app_id = view_get_string_prop(view, "app_id"); + const char *name = desktop_entry_name_lookup(view->server, app_id); + if (name) { + return name; + } +#endif + + return get_app_id_or_class(view, /* trim */ true); +} + static const char * get_type(struct view *view, bool short_form) { @@ -164,6 +181,13 @@ field_set_identifier_trimmed(struct buf *buf, struct view *view, const char *for buf_add(buf, get_app_id_or_class(view, /*trim*/ true)); } +static void +field_set_desktop_entry_name(struct buf *buf, struct view *view, const char *format) +{ + /* custom type conversion-specifier: n */ + buf_add(buf, get_desktop_name(view)); +} + static void field_set_title(struct buf *buf, struct view *view, const char *format) { @@ -263,6 +287,7 @@ static const struct field_converter field_converter[LAB_FIELD_COUNT] = { [LAB_FIELD_WIN_STATE] = { 's', field_set_win_state }, [LAB_FIELD_IDENTIFIER] = { 'I', field_set_identifier }, [LAB_FIELD_TRIMMED_IDENTIFIER] = { 'i', field_set_identifier_trimmed }, + [LAB_FIELD_DESKTOP_ENTRY_NAME] = { 'n', field_set_desktop_entry_name}, [LAB_FIELD_WORKSPACE] = { 'W', field_set_workspace }, [LAB_FIELD_WORKSPACE_SHORT] = { 'w', field_set_workspace_short }, [LAB_FIELD_OUTPUT] = { 'O', field_set_output }, @@ -296,6 +321,8 @@ osd_field_arg_from_xml_node(struct window_switcher_field *field, field->content = LAB_FIELD_IDENTIFIER; } else if (!strcmp(content, "trimmed_identifier")) { field->content = LAB_FIELD_TRIMMED_IDENTIFIER; + } else if (!strcmp(content, "desktop_entry_name")) { + field->content = LAB_FIELD_DESKTOP_ENTRY_NAME; } else if (!strcmp(content, "title")) { /* Keep old defaults */ field->content = LAB_FIELD_TITLE_SHORT;