mirror of
https://github.com/labwc/labwc.git
synced 2025-10-29 05:40:24 -04:00
Merge pull request #2360 from jp7677/sfdo-app-name
feat: add libsfdo desktop entry name as OSD element
This commit is contained in:
commit
cfc92f43db
10 changed files with 137 additions and 62 deletions
|
|
@ -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
|
||||
|
|
|
|||
23
include/desktop-entry.h
Normal file
23
include/desktop-entry.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* 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);
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -254,21 +255,29 @@ 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 *
|
||||
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);
|
||||
if (!entry) {
|
||||
entry = get_db_entry_by_id_fuzzy(loader->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);
|
||||
}
|
||||
|
|
@ -284,15 +293,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) {
|
||||
|
|
@ -320,3 +329,25 @@ icon_loader_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;
|
||||
}
|
||||
|
|
@ -45,7 +45,7 @@ endif
|
|||
|
||||
if have_libsfdo
|
||||
labwc_sources += files(
|
||||
'icon-loader.c',
|
||||
'desktop-entry.c',
|
||||
)
|
||||
endif
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
10
src/server.c
10
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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue