mirror of
https://github.com/swaywm/sway.git
synced 2026-04-17 06:46:32 -04:00
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. Rebased from origin/master.
This commit is contained in:
parent
b5dfcd96bc
commit
2dc1a41e6d
4 changed files with 593 additions and 553 deletions
|
|
@ -1,14 +1,18 @@
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sfdo-basedir.h>
|
#include <sfdo-basedir.h>
|
||||||
#include <sfdo-desktop.h>
|
#include <sfdo-desktop.h>
|
||||||
#include <sfdo-icon.h>
|
#include <sfdo-icon.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "sfdo.h"
|
#include "sfdo.h"
|
||||||
|
|
||||||
// this extends libsfdo's behavior to also handle icons specified as absolute paths
|
<<<<<<< HEAD
|
||||||
char *sfdo_icon_lookup_extended(struct sfdo *sfdo, char *icon_name, int target_size, int scale) {
|
// this extends libsfdo's behavior to also handle icons specified as
|
||||||
|
// absolute paths
|
||||||
|
char *
|
||||||
|
sfdo_icon_lookup_extended(struct sfdo *sfdo, char *icon_name,
|
||||||
|
int target_size, int scale) {
|
||||||
char *icon_path = NULL;
|
char *icon_path = NULL;
|
||||||
if (icon_name[0] == '/') {
|
if (icon_name[0] == '/') {
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
|
@ -17,14 +21,27 @@ char *sfdo_icon_lookup_extended(struct sfdo *sfdo, char *icon_name, int target_s
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int lookup_options = SFDO_ICON_THEME_LOOKUP_OPTIONS_DEFAULT;
|
int lookup_options = SFDO_ICON_THEME_LOOKUP_OPTIONS_DEFAULT;
|
||||||
struct sfdo_icon_file *icon_file = \
|
struct sfdo_icon_file *icon_file =
|
||||||
sfdo_icon_theme_lookup(sfdo->icon_theme, icon_name, SFDO_NT, \
|
sfdo_icon_theme_lookup(sfdo->icon_theme, icon_name, SFDO_NT,
|
||||||
target_size, scale, lookup_options);
|
target_size, scale, lookup_options);
|
||||||
if (icon_file && icon_file != SFDO_ICON_FILE_INVALID) {
|
if (icon_file && icon_file != SFDO_ICON_FILE_INVALID) {
|
||||||
icon_path = strdup(sfdo_icon_file_get_path(icon_file, NULL));
|
icon_path = strdup(sfdo_icon_file_get_path(icon_file, NULL));
|
||||||
}
|
}
|
||||||
sfdo_icon_file_destroy(icon_file);
|
sfdo_icon_file_destroy(icon_file);
|
||||||
}
|
}
|
||||||
|
=======
|
||||||
|
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);
|
||||||
|
>>>>>>> 92e27bd9 (Finds paths to icon files using libsfdo. Libsfdo is currently an)
|
||||||
return icon_path;
|
return icon_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,18 +75,20 @@ struct sfdo *sfdo_create(char *icon_theme) {
|
||||||
goto error_desktop_db;
|
goto error_desktop_db;
|
||||||
}
|
}
|
||||||
|
|
||||||
int load_options = SFDO_ICON_THEME_LOAD_OPTIONS_DEFAULT
|
int load_options = SFDO_ICON_THEME_LOAD_OPTIONS_DEFAULT |
|
||||||
| SFDO_ICON_THEME_LOAD_OPTION_ALLOW_MISSING
|
SFDO_ICON_THEME_LOAD_OPTION_ALLOW_MISSING |
|
||||||
| SFDO_ICON_THEME_LOAD_OPTION_RELAXED;
|
SFDO_ICON_THEME_LOAD_OPTION_RELAXED;
|
||||||
|
|
||||||
sfdo->icon_theme = sfdo_icon_theme_load(sfdo->icon_ctx, icon_theme, load_options);
|
sfdo->icon_theme =
|
||||||
|
sfdo_icon_theme_load(sfdo->icon_ctx, icon_theme, load_options);
|
||||||
if (!sfdo->icon_theme) {
|
if (!sfdo->icon_theme) {
|
||||||
goto error_icon_theme;
|
goto error_icon_theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
sfdo_basedir_ctx_destroy(basedir_ctx);
|
sfdo_basedir_ctx_destroy(basedir_ctx);
|
||||||
|
|
||||||
sway_log(SWAY_INFO, "Successfully setup sfdo with icon theme %s", icon_theme);
|
sway_log(SWAY_INFO, "Successfully setup sfdo with icon theme %s",
|
||||||
|
icon_theme);
|
||||||
return sfdo;
|
return sfdo;
|
||||||
|
|
||||||
error_icon_theme:
|
error_icon_theme:
|
||||||
|
|
|
||||||
|
|
@ -211,9 +211,4 @@ void set_rr_scheduling(void);
|
||||||
|
|
||||||
void handle_new_tearing_hint(struct wl_listener *listener, void *data);
|
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
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -71,12 +71,16 @@
|
||||||
|
|
||||||
#if HAVE_LIBSFDO
|
#if HAVE_LIBSFDO
|
||||||
<<<<<<< HEAD
|
<<<<<<< HEAD
|
||||||
|
<<<<<<< HEAD
|
||||||
#include "sfdo.h"
|
#include "sfdo.h"
|
||||||
=======
|
=======
|
||||||
#include <sfdo-basedir.h>
|
#include <sfdo-basedir.h>
|
||||||
#include <sfdo-desktop.h>
|
#include <sfdo-desktop.h>
|
||||||
#include <sfdo-icon.h>
|
#include <sfdo-icon.h>
|
||||||
>>>>>>> 8b3ea59a (Clean up build scaffolding for libsfdo and add the creation and)
|
>>>>>>> 8b3ea59a (Clean up build scaffolding for libsfdo and add the creation and)
|
||||||
|
=======
|
||||||
|
#include "sfdo.h"
|
||||||
|
>>>>>>> 92e27bd9 (Finds paths to icon files using libsfdo. Libsfdo is currently an)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SWAY_XDG_SHELL_VERSION 5
|
#define SWAY_XDG_SHELL_VERSION 5
|
||||||
|
|
@ -532,25 +536,13 @@ void server_fini(struct sway_server *server) {
|
||||||
wl_list_remove(&server->drm_lease_request.link);
|
wl_list_remove(&server->drm_lease_request.link);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
<<<<<<< HEAD
|
|
||||||
<<<<<<< HEAD wl_list_remove(&server->tearing_control_new_object.link);
|
|
||||||
wl_list_remove(&server->xdg_activation_v1_request_activate.link);
|
|
||||||
wl_list_remove(&server->xdg_activation_v1_new_token.link);
|
|
||||||
wl_list_remove(&server->request_set_cursor_shape.link);
|
|
||||||
input_manager_finish(server->input);
|
|
||||||
=======
|
|
||||||
=======
|
|
||||||
>>>>>>> 8b3ea59a (Clean up build scaffolding for libsfdo and add the creation and)
|
|
||||||
wl_list_remove(&server->tearing_control_new_object.link);
|
wl_list_remove(&server->tearing_control_new_object.link);
|
||||||
wl_list_remove(&server->xdg_activation_v1_request_activate.link);
|
wl_list_remove(&server->xdg_activation_v1_request_activate.link);
|
||||||
wl_list_remove(&server->xdg_activation_v1_new_token.link);
|
wl_list_remove(&server->xdg_activation_v1_new_token.link);
|
||||||
wl_list_remove(&server->request_set_cursor_shape.link);
|
wl_list_remove(&server->request_set_cursor_shape.link);
|
||||||
wl_list_remove(&server->new_foreign_toplevel_capture_request.link);
|
wl_list_remove(&server->new_foreign_toplevel_capture_request.link);
|
||||||
input_manager_finish(server->input);
|
input_manager_finish(server->input);
|
||||||
<<<<<<< HEAD
|
|
||||||
>>>>>>> 170c9c95 (Add support for toplevel capture)
|
|
||||||
=======
|
|
||||||
>>>>>>> 8b3ea59a (Clean up build scaffolding for libsfdo and add the creation and)
|
|
||||||
|
|
||||||
// TODO: free sway-specific resources
|
// TODO: free sway-specific resources
|
||||||
#if WLR_HAS_XWAYLAND
|
#if WLR_HAS_XWAYLAND
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,16 @@
|
||||||
|
#include "swaybar/tray/item.h"
|
||||||
|
#include "cairo_util.h"
|
||||||
|
#include "list.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "stringop.h"
|
||||||
|
#include "swaybar/bar.h"
|
||||||
|
#include "swaybar/config.h"
|
||||||
|
#include "swaybar/image.h"
|
||||||
|
#include "swaybar/input.h"
|
||||||
|
#include "swaybar/tray/host.h"
|
||||||
|
#include "swaybar/tray/icon.h"
|
||||||
|
#include "swaybar/tray/tray.h"
|
||||||
|
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <cairo.h>
|
#include <cairo.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
@ -6,19 +19,6 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "swaybar/bar.h"
|
|
||||||
#include "swaybar/config.h"
|
|
||||||
#include "swaybar/image.h"
|
|
||||||
#include "swaybar/input.h"
|
|
||||||
#include "swaybar/tray/host.h"
|
|
||||||
#include "swaybar/tray/icon.h"
|
|
||||||
#include "swaybar/tray/item.h"
|
|
||||||
#include "swaybar/tray/tray.h"
|
|
||||||
#include "cairo_util.h"
|
|
||||||
#include "list.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "stringop.h"
|
|
||||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
|
||||||
|
|
||||||
#if HAVE_LIBSFDO
|
#if HAVE_LIBSFDO
|
||||||
#include "sfdo.h"
|
#include "sfdo.h"
|
||||||
|
|
@ -27,14 +27,16 @@
|
||||||
// TODO menu
|
// TODO menu
|
||||||
|
|
||||||
static bool sni_ready(struct swaybar_sni *sni) {
|
static bool sni_ready(struct swaybar_sni *sni) {
|
||||||
return sni->status && (sni->status[0] == 'N' ? // NeedsAttention
|
return sni->status &&
|
||||||
sni->attention_icon_name || sni->attention_icon_pixmap :
|
(sni->status[0] == 'N' ? // NeedsAttention
|
||||||
sni->icon_name || sni->icon_pixmap);
|
sni->attention_icon_name || sni->attention_icon_pixmap
|
||||||
|
: sni->icon_name || sni->icon_pixmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_sni_dirty(struct swaybar_sni *sni) {
|
static void set_sni_dirty(struct swaybar_sni *sni) {
|
||||||
if (sni_ready(sni)) {
|
if (sni_ready(sni)) {
|
||||||
sni->target_size = sni->min_size = sni->max_size = 0; // invalidate previous icon
|
sni->target_size = sni->min_size = sni->max_size =
|
||||||
|
0; // invalidate previous icon
|
||||||
set_bar_dirty(sni->tray->bar);
|
set_bar_dirty(sni->tray->bar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -80,7 +82,8 @@ static int read_pixmap(sd_bus_message *msg, struct swaybar_sni *sni,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (height > 0 && width == height) {
|
if (height > 0 && width == height) {
|
||||||
sway_log(SWAY_DEBUG, "%s %s: found icon w:%d h:%d", sni->watcher_id, prop, width, height);
|
sway_log(SWAY_DEBUG, "%s %s: found icon w:%d h:%d", sni->watcher_id, prop,
|
||||||
|
width, height);
|
||||||
struct swaybar_pixmap *pixmap =
|
struct swaybar_pixmap *pixmap =
|
||||||
malloc(sizeof(struct swaybar_pixmap) + npixels);
|
malloc(sizeof(struct swaybar_pixmap) + npixels);
|
||||||
pixmap->size = height;
|
pixmap->size = height;
|
||||||
|
|
@ -92,7 +95,8 @@ static int read_pixmap(sd_bus_message *msg, struct swaybar_sni *sni,
|
||||||
|
|
||||||
list_add(pixmaps, pixmap);
|
list_add(pixmaps, pixmap);
|
||||||
} else {
|
} else {
|
||||||
sway_log(SWAY_DEBUG, "%s %s: discard invalid icon w:%d h:%d", sni->watcher_id, prop, width, height);
|
sway_log(SWAY_DEBUG, "%s %s: discard invalid icon w:%d h:%d",
|
||||||
|
sni->watcher_id, prop, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
sd_bus_message_exit_container(msg);
|
sd_bus_message_exit_container(msg);
|
||||||
|
|
@ -167,8 +171,9 @@ static int get_property_callback(sd_bus_message *msg, void *data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(prop, "Status") == 0 || (sni->status && (sni->status[0] == 'N' ?
|
if (strcmp(prop, "Status") == 0 ||
|
||||||
prop[0] == 'A' : has_prefix(prop, "Icon")))) {
|
(sni->status &&
|
||||||
|
(sni->status[0] == 'N' ? prop[0] == 'A' : has_prefix(prop, "Icon")))) {
|
||||||
set_sni_dirty(sni);
|
set_sni_dirty(sni);
|
||||||
}
|
}
|
||||||
cleanup:
|
cleanup:
|
||||||
|
|
@ -184,9 +189,10 @@ static void sni_get_property_async(struct swaybar_sni *sni, const char *prop,
|
||||||
data->prop = prop;
|
data->prop = prop;
|
||||||
data->type = type;
|
data->type = type;
|
||||||
data->dest = dest;
|
data->dest = dest;
|
||||||
int ret = sd_bus_call_method_async(sni->tray->bus, &data->slot, sni->service,
|
int ret = sd_bus_call_method_async(
|
||||||
sni->path, "org.freedesktop.DBus.Properties", "Get",
|
sni->tray->bus, &data->slot, sni->service, sni->path,
|
||||||
get_property_callback, data, "ss", sni->interface, prop);
|
"org.freedesktop.DBus.Properties", "Get", get_property_callback, data,
|
||||||
|
"ss", sni->interface, prop);
|
||||||
if (ret >= 0) {
|
if (ret >= 0) {
|
||||||
wl_list_insert(&sni->slots, &data->link);
|
wl_list_insert(&sni->slots, &data->link);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -212,7 +218,8 @@ static void sni_get_property_async(struct swaybar_sni *sni, const char *prop,
|
||||||
static int sni_check_msg_sender(struct swaybar_sni *sni, sd_bus_message *msg,
|
static int sni_check_msg_sender(struct swaybar_sni *sni, sd_bus_message *msg,
|
||||||
const char *signal) {
|
const char *signal) {
|
||||||
bool has_well_known_names =
|
bool has_well_known_names =
|
||||||
sd_bus_creds_get_mask(sd_bus_message_get_creds(msg)) & SD_BUS_CREDS_WELL_KNOWN_NAMES;
|
sd_bus_creds_get_mask(sd_bus_message_get_creds(msg)) &
|
||||||
|
SD_BUS_CREDS_WELL_KNOWN_NAMES;
|
||||||
if (sni->service[0] == ':' || has_well_known_names) {
|
if (sni->service[0] == ':' || has_well_known_names) {
|
||||||
sway_log(SWAY_DEBUG, "%s has new %s", sni->watcher_id, signal);
|
sway_log(SWAY_DEBUG, "%s has new %s", sni->watcher_id, signal);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -222,7 +229,8 @@ static int sni_check_msg_sender(struct swaybar_sni *sni, sd_bus_message *msg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_new_icon(sd_bus_message *msg, void *data, sd_bus_error *error) {
|
static int handle_new_icon(sd_bus_message *msg, void *data,
|
||||||
|
sd_bus_error *error) {
|
||||||
struct swaybar_sni *sni = data;
|
struct swaybar_sni *sni = data;
|
||||||
sni_get_property_async(sni, "IconName", "s", &sni->icon_name);
|
sni_get_property_async(sni, "IconName", "s", &sni->icon_name);
|
||||||
sni_get_property_async(sni, "IconPixmap", NULL, &sni->icon_pixmap);
|
sni_get_property_async(sni, "IconPixmap", NULL, &sni->icon_pixmap);
|
||||||
|
|
@ -235,19 +243,23 @@ static int handle_new_icon(sd_bus_message *msg, void *data, sd_bus_error *error)
|
||||||
static int handle_new_attention_icon(sd_bus_message *msg, void *data,
|
static int handle_new_attention_icon(sd_bus_message *msg, void *data,
|
||||||
sd_bus_error *error) {
|
sd_bus_error *error) {
|
||||||
struct swaybar_sni *sni = data;
|
struct swaybar_sni *sni = data;
|
||||||
sni_get_property_async(sni, "AttentionIconName", "s", &sni->attention_icon_name);
|
sni_get_property_async(sni, "AttentionIconName", "s",
|
||||||
sni_get_property_async(sni, "AttentionIconPixmap", NULL, &sni->attention_icon_pixmap);
|
&sni->attention_icon_name);
|
||||||
|
sni_get_property_async(sni, "AttentionIconPixmap", NULL,
|
||||||
|
&sni->attention_icon_pixmap);
|
||||||
return sni_check_msg_sender(sni, msg, "attention icon");
|
return sni_check_msg_sender(sni, msg, "attention icon");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_new_status(sd_bus_message *msg, void *data, sd_bus_error *error) {
|
static int handle_new_status(sd_bus_message *msg, void *data,
|
||||||
|
sd_bus_error *error) {
|
||||||
struct swaybar_sni *sni = data;
|
struct swaybar_sni *sni = data;
|
||||||
int ret = sni_check_msg_sender(sni, msg, "status");
|
int ret = sni_check_msg_sender(sni, msg, "status");
|
||||||
if (ret == 1) {
|
if (ret == 1) {
|
||||||
char *status;
|
char *status;
|
||||||
int r = sd_bus_message_read(msg, "s", &status);
|
int r = sd_bus_message_read(msg, "s", &status);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
sway_log(SWAY_ERROR, "%s new status error: %s", sni->watcher_id, strerror(-ret));
|
sway_log(SWAY_ERROR, "%s new status error: %s", sni->watcher_id,
|
||||||
|
strerror(-ret));
|
||||||
ret = r;
|
ret = r;
|
||||||
} else {
|
} else {
|
||||||
free(sni->status);
|
free(sni->status);
|
||||||
|
|
@ -265,8 +277,9 @@ static int handle_new_status(sd_bus_message *msg, void *data, sd_bus_error *erro
|
||||||
static void sni_match_signal_async(struct swaybar_sni *sni, char *signal,
|
static void sni_match_signal_async(struct swaybar_sni *sni, char *signal,
|
||||||
sd_bus_message_handler_t callback) {
|
sd_bus_message_handler_t callback) {
|
||||||
struct swaybar_sni_slot *slot = calloc(1, sizeof(struct swaybar_sni_slot));
|
struct swaybar_sni_slot *slot = calloc(1, sizeof(struct swaybar_sni_slot));
|
||||||
int ret = sd_bus_match_signal_async(sni->tray->bus, &slot->slot,
|
int ret = sd_bus_match_signal_async(sni->tray->bus, &slot->slot, sni->service,
|
||||||
sni->service, sni->path, sni->interface, signal, callback, NULL, sni);
|
sni->path, sni->interface, signal,
|
||||||
|
callback, NULL, sni);
|
||||||
if (ret >= 0) {
|
if (ret >= 0) {
|
||||||
wl_list_insert(&sni->slots, &slot->link);
|
wl_list_insert(&sni->slots, &slot->link);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -301,8 +314,10 @@ struct swaybar_sni *create_sni(char *id, struct swaybar_tray *tray) {
|
||||||
sni_get_property_async(sni, "Status", "s", &sni->status);
|
sni_get_property_async(sni, "Status", "s", &sni->status);
|
||||||
sni_get_property_async(sni, "IconName", "s", &sni->icon_name);
|
sni_get_property_async(sni, "IconName", "s", &sni->icon_name);
|
||||||
sni_get_property_async(sni, "IconPixmap", NULL, &sni->icon_pixmap);
|
sni_get_property_async(sni, "IconPixmap", NULL, &sni->icon_pixmap);
|
||||||
sni_get_property_async(sni, "AttentionIconName", "s", &sni->attention_icon_name);
|
sni_get_property_async(sni, "AttentionIconName", "s",
|
||||||
sni_get_property_async(sni, "AttentionIconPixmap", NULL, &sni->attention_icon_pixmap);
|
&sni->attention_icon_name);
|
||||||
|
sni_get_property_async(sni, "AttentionIconPixmap", NULL,
|
||||||
|
&sni->attention_icon_pixmap);
|
||||||
sni_get_property_async(sni, "ItemIsMenu", "b", &sni->item_is_menu);
|
sni_get_property_async(sni, "ItemIsMenu", "b", &sni->item_is_menu);
|
||||||
sni_get_property_async(sni, "Menu", "o", &sni->menu);
|
sni_get_property_async(sni, "Menu", "o", &sni->menu);
|
||||||
|
|
||||||
|
|
@ -339,8 +354,8 @@ void destroy_sni(struct swaybar_sni *sni) {
|
||||||
free(sni);
|
free(sni);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_click(struct swaybar_sni *sni, int x, int y,
|
static void handle_click(struct swaybar_sni *sni, int x, int y, uint32_t button,
|
||||||
uint32_t button, int delta) {
|
int delta) {
|
||||||
const char *method = NULL;
|
const char *method = NULL;
|
||||||
struct tray_binding *binding = NULL;
|
struct tray_binding *binding = NULL;
|
||||||
wl_list_for_each(binding, &sni->tray->bar->config->tray_bindings, link) {
|
wl_list_for_each(binding, &sni->tray->bar->config->tray_bindings, link) {
|
||||||
|
|
@ -351,17 +366,9 @@ static void handle_click(struct swaybar_sni *sni, int x, int y,
|
||||||
}
|
}
|
||||||
if (!method) {
|
if (!method) {
|
||||||
static const char *default_bindings[10] = {
|
static const char *default_bindings[10] = {
|
||||||
"nop",
|
"nop", "Activate", "SecondaryActivate", "ContextMenu",
|
||||||
"Activate",
|
"ScrollUp", "ScrollDown", "ScrollLeft", "ScrollRight",
|
||||||
"SecondaryActivate",
|
"nop", "nop"};
|
||||||
"ContextMenu",
|
|
||||||
"ScrollUp",
|
|
||||||
"ScrollDown",
|
|
||||||
"ScrollLeft",
|
|
||||||
"ScrollRight",
|
|
||||||
"nop",
|
|
||||||
"nop"
|
|
||||||
};
|
|
||||||
method = default_bindings[event_to_x11_button(button)];
|
method = default_bindings[event_to_x11_button(button)];
|
||||||
}
|
}
|
||||||
if (strcmp(method, "nop") == 0) {
|
if (strcmp(method, "nop") == 0) {
|
||||||
|
|
@ -377,7 +384,8 @@ static void handle_click(struct swaybar_sni *sni, int x, int y,
|
||||||
int sign = (dir == 'U' || dir == 'L') ? -1 : 1;
|
int sign = (dir == 'U' || dir == 'L') ? -1 : 1;
|
||||||
|
|
||||||
sd_bus_call_method_async(sni->tray->bus, NULL, sni->service, sni->path,
|
sd_bus_call_method_async(sni->tray->bus, NULL, sni->service, sni->path,
|
||||||
sni->interface, "Scroll", NULL, NULL, "is", delta*sign, orientation);
|
sni->interface, "Scroll", NULL, NULL, "is",
|
||||||
|
delta * sign, orientation);
|
||||||
} else {
|
} else {
|
||||||
sd_bus_call_method_async(sni->tray->bus, NULL, sni->service, sni->path,
|
sd_bus_call_method_async(sni->tray->bus, NULL, sni->service, sni->path,
|
||||||
sni->interface, method, NULL, NULL, "ii", x, y);
|
sni->interface, method, NULL, NULL, "ii", x, y);
|
||||||
|
|
@ -389,9 +397,10 @@ static int cmp_sni_id(const void *item, const void *cmp_to) {
|
||||||
return strcmp(sni->watcher_id, cmp_to);
|
return strcmp(sni->watcher_id, cmp_to);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum hotspot_event_handling icon_hotspot_callback(
|
static enum hotspot_event_handling
|
||||||
struct swaybar_output *output, struct swaybar_hotspot *hotspot,
|
icon_hotspot_callback(struct swaybar_output *output,
|
||||||
double x, double y, uint32_t button, bool released, void *data) {
|
struct swaybar_hotspot *hotspot, double x, double y,
|
||||||
|
uint32_t button, bool released, void *data) {
|
||||||
sway_log(SWAY_DEBUG, "Clicked on %s", (char *)data);
|
sway_log(SWAY_DEBUG, "Clicked on %s", (char *)data);
|
||||||
|
|
||||||
struct swaybar_tray *tray = output->bar->tray;
|
struct swaybar_tray *tray = output->bar->tray;
|
||||||
|
|
@ -408,11 +417,14 @@ static enum hotspot_event_handling icon_hotspot_callback(
|
||||||
struct swaybar_config *config = tray->bar->config;
|
struct swaybar_config *config = tray->bar->config;
|
||||||
int global_x = output->output_x + config->gaps.left + x;
|
int global_x = output->output_x + config->gaps.left + x;
|
||||||
bool top_bar = config->position & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
|
bool top_bar = config->position & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
|
||||||
int global_y = output->output_y + (top_bar ? config->gaps.top + y:
|
int global_y = output->output_y + (top_bar ? config->gaps.top + y
|
||||||
(int) output->output_height - config->gaps.bottom - y);
|
: (int)output->output_height -
|
||||||
|
config->gaps.bottom - y);
|
||||||
|
|
||||||
sway_log(SWAY_DEBUG, "Guessing click position at (%d, %d)", global_x, global_y);
|
sway_log(SWAY_DEBUG, "Guessing click position at (%d, %d)", global_x,
|
||||||
handle_click(sni, global_x, global_y, button, 1); // TODO get delta from event
|
global_y);
|
||||||
|
handle_click(sni, global_x, global_y, button,
|
||||||
|
1); // TODO get delta from event
|
||||||
return HOTSPOT_IGNORE;
|
return HOTSPOT_IGNORE;
|
||||||
} else {
|
} else {
|
||||||
sway_log(SWAY_DEBUG, "but it doesn't exist");
|
sway_log(SWAY_DEBUG, "but it doesn't exist");
|
||||||
|
|
@ -421,9 +433,10 @@ static enum hotspot_event_handling icon_hotspot_callback(
|
||||||
return HOTSPOT_PROCESS;
|
return HOTSPOT_PROCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reload_sni(struct swaybar_sni *sni, char *icon_theme, int target_size) {
|
static void reload_sni(struct swaybar_sni *sni, char *icon_theme,
|
||||||
char *icon_name = sni->status[0] == 'N' ?
|
int target_size) {
|
||||||
sni->attention_icon_name : sni->icon_name;
|
char *icon_name =
|
||||||
|
sni->status[0] == 'N' ? sni->attention_icon_name : sni->icon_name;
|
||||||
if (icon_name) {
|
if (icon_name) {
|
||||||
char *icon_path = NULL;
|
char *icon_path = NULL;
|
||||||
#if !HAVE_LIBSFDO
|
#if !HAVE_LIBSFDO
|
||||||
|
|
@ -432,19 +445,37 @@ static void reload_sni(struct swaybar_sni *sni, char *icon_theme, int target_siz
|
||||||
if (sni->icon_theme_path) {
|
if (sni->icon_theme_path) {
|
||||||
list_add(icon_search_paths, sni->icon_theme_path);
|
list_add(icon_search_paths, sni->icon_theme_path);
|
||||||
}
|
}
|
||||||
icon_path = find_icon(sni->tray->themes, icon_search_paths,
|
icon_path =
|
||||||
icon_name, target_size, icon_theme,
|
find_icon(sni->tray->themes, icon_search_paths, icon_name, target_size,
|
||||||
&sni->min_size, &sni->max_size);
|
icon_theme, &sni->min_size, &sni->max_size);
|
||||||
#else
|
#else
|
||||||
// TODO: at some point we will need to make this scaling-aware
|
// TODO: at some point we will need to make this scaling-aware
|
||||||
int scale = 1;
|
int scale = 1;
|
||||||
struct sfdo *sfdo = sni->tray->bar->config->sfdo;
|
struct sfdo *sfdo = sni->tray->bar->config->sfdo;
|
||||||
if (sfdo) {
|
if (sfdo) {
|
||||||
icon_path = sfdo_icon_lookup_extended(sfdo, icon_name, target_size, scale);
|
icon_path =
|
||||||
|
sfdo_icon_lookup_extended(sfdo, icon_name, target_size, scale);
|
||||||
if (!icon_path) {
|
if (!icon_path) {
|
||||||
sway_log(SWAY_DEBUG, "sfdo: icon %s invalid or not found in theme %s at size %d", \
|
sway_log(SWAY_DEBUG,
|
||||||
|
"sfdo: icon %s invalid or not found in theme %s at size %d",
|
||||||
icon_name, icon_theme, target_size);
|
icon_name, icon_theme, target_size);
|
||||||
}
|
}
|
||||||
|
=======
|
||||||
|
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
|
#endif
|
||||||
#if !HAVE_LIBSFDO
|
#if !HAVE_LIBSFDO
|
||||||
|
|
@ -456,18 +487,18 @@ static void reload_sni(struct swaybar_sni *sni, char *icon_theme, int target_siz
|
||||||
free(icon_path);
|
free(icon_path);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// the :( icon won't be drawn for a missing icon and whichever old icon was
|
// the :( icon won't be drawn for a missing icon and whichever old icon
|
||||||
// loaded will persist if this is not done. one might not have noticed this
|
// was loaded will persist if this is not done. one might not have noticed
|
||||||
// for tray items that have only one icon loaded only once, successfully or
|
// this for tray items that have only one icon loaded only once,
|
||||||
// unsuccessfully. items with multiple icons, such as fcitx5 or other input
|
// successfully or unsuccessfully. items with multiple icons, such as
|
||||||
// method frameworks make the problem apparent
|
// fcitx5 or other input method frameworks make the problem apparent
|
||||||
free(sni->icon);
|
free(sni->icon);
|
||||||
sni->icon = NULL;
|
sni->icon = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
list_t *pixmaps = sni->status[0] == 'N' ?
|
list_t *pixmaps =
|
||||||
sni->attention_icon_pixmap : sni->icon_pixmap;
|
sni->status[0] == 'N' ? sni->attention_icon_pixmap : sni->icon_pixmap;
|
||||||
if (pixmaps) {
|
if (pixmaps) {
|
||||||
struct swaybar_pixmap *pixmap = NULL;
|
struct swaybar_pixmap *pixmap = NULL;
|
||||||
int min_error = INT_MAX;
|
int min_error = INT_MAX;
|
||||||
|
|
@ -480,8 +511,8 @@ static void reload_sni(struct swaybar_sni *sni, char *icon_theme, int target_siz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cairo_surface_destroy(sni->icon);
|
cairo_surface_destroy(sni->icon);
|
||||||
sni->icon = cairo_image_surface_create_for_data(pixmap->pixels,
|
sni->icon = cairo_image_surface_create_for_data(
|
||||||
CAIRO_FORMAT_ARGB32, pixmap->size, pixmap->size,
|
pixmap->pixels, CAIRO_FORMAT_ARGB32, pixmap->size, pixmap->size,
|
||||||
cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, pixmap->size));
|
cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, pixmap->size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -509,12 +540,14 @@ uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x,
|
||||||
cairo_surface_t *icon;
|
cairo_surface_t *icon;
|
||||||
if (sni->icon) {
|
if (sni->icon) {
|
||||||
int actual_size = cairo_image_surface_get_height(sni->icon);
|
int actual_size = cairo_image_surface_get_height(sni->icon);
|
||||||
icon_size = actual_size < target_size ?
|
icon_size = actual_size < target_size
|
||||||
actual_size*(target_size/actual_size) : target_size;
|
? actual_size * (target_size / actual_size)
|
||||||
|
: target_size;
|
||||||
icon = cairo_image_surface_scale(sni->icon, icon_size, icon_size);
|
icon = cairo_image_surface_scale(sni->icon, icon_size, icon_size);
|
||||||
} else { // draw a :(
|
} else { // draw a :(
|
||||||
icon_size = target_size * 0.8;
|
icon_size = target_size * 0.8;
|
||||||
icon = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, icon_size, icon_size);
|
icon =
|
||||||
|
cairo_image_surface_create(CAIRO_FORMAT_ARGB32, icon_size, icon_size);
|
||||||
cairo_t *cairo_icon = cairo_create(icon);
|
cairo_t *cairo_icon = cairo_create(icon);
|
||||||
cairo_set_source_u32(cairo_icon, 0xFF0000FF);
|
cairo_set_source_u32(cairo_icon, 0xFF0000FF);
|
||||||
cairo_translate(cairo_icon, icon_size / 2, icon_size / 2);
|
cairo_translate(cairo_icon, icon_size / 2, icon_size / 2);
|
||||||
|
|
@ -546,7 +579,8 @@ uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x,
|
||||||
cairo_pattern_t *icon_pattern = cairo_pattern_create_for_surface(icon);
|
cairo_pattern_t *icon_pattern = cairo_pattern_create_for_surface(icon);
|
||||||
// TODO: check cairo_pattern_status for "ENOMEM"
|
// TODO: check cairo_pattern_status for "ENOMEM"
|
||||||
cairo_matrix_init_scale(&scale_matrix, output->scale, output->scale);
|
cairo_matrix_init_scale(&scale_matrix, output->scale, output->scale);
|
||||||
cairo_matrix_translate(&scale_matrix, -(*x + descaled_padding), -(icon_y + descaled_padding));
|
cairo_matrix_translate(&scale_matrix, -(*x + descaled_padding),
|
||||||
|
-(icon_y + descaled_padding));
|
||||||
cairo_pattern_set_matrix(icon_pattern, &scale_matrix);
|
cairo_pattern_set_matrix(icon_pattern, &scale_matrix);
|
||||||
cairo_set_source(cairo, icon_pattern);
|
cairo_set_source(cairo, icon_pattern);
|
||||||
cairo_rectangle(cairo, *x, icon_y, size, size);
|
cairo_rectangle(cairo, *x, icon_y, size, size);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue