diff --git a/common/sfdo.c b/common/sfdo.c index e2e685650..732256f33 100644 --- a/common/sfdo.c +++ b/common/sfdo.c @@ -1,104 +1,123 @@ -#include -#include #include #include #include +#include +#include #include "log.h" #include "sfdo.h" -// 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; - if (icon_name[0] == '/') { - struct stat sb; - if (!stat(icon_name, &sb)) { - icon_path = strdup(icon_name); - } - } else { - 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); - 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; -} +<<<<<<< HEAD + // 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; + if (icon_name[0] == '/') { + struct stat sb; + if (!stat(icon_name, &sb)) { + icon_path = strdup(icon_name); + } + } else { + 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); + 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); + } +======= + 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; + } -struct sfdo *sfdo_create(char *icon_theme) { - if (!icon_theme) { - goto error_null; - } + 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 *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; - } + 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->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->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; - } + 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; + 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->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); + sfdo_basedir_ctx_destroy(basedir_ctx); - sway_log(SWAY_INFO, "Successfully setup sfdo with icon theme %s", icon_theme); - return sfdo; + 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; -} + 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; - } + 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"); -} + 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"); + } diff --git a/include/sway/server.h b/include/sway/server.h index ab4caac62..6402206f7 100644 --- a/include/sway/server.h +++ b/include/sway/server.h @@ -211,9 +211,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 diff --git a/sway/server.c b/sway/server.c index 3b77dc88e..71ffcd49f 100644 --- a/sway/server.c +++ b/sway/server.c @@ -71,12 +71,16 @@ #if HAVE_LIBSFDO <<<<<<< HEAD +<<<<<<< HEAD #include "sfdo.h" -======= + ======= #include #include #include ->>>>>>> 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 #define SWAY_XDG_SHELL_VERSION 5 @@ -84,7 +88,7 @@ #define SWAY_FOREIGN_TOPLEVEL_LIST_VERSION 1 #define SWAY_PRESENTATION_VERSION 2 -bool allow_unsupported_gpu = false; + bool allow_unsupported_gpu = false; #if WLR_HAS_DRM_BACKEND static void handle_drm_lease_request(struct wl_listener *listener, void *data) { @@ -532,25 +536,13 @@ void server_fini(struct sway_server *server) { wl_list_remove(&server->drm_lease_request.link); } #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->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); wl_list_remove(&server->new_foreign_toplevel_capture_request.link); 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 #if WLR_HAS_XWAYLAND @@ -580,7 +572,7 @@ void server_fini(struct sway_server *server) { #if HAVE_LIBSFDO sfdo_destroy(server->sfdo); #endif ->>>>>>> 8b3ea59a (Clean up build scaffolding for libsfdo and add the creation and) + >>>>>>> 8b3ea59a (Clean up build scaffolding for libsfdo and add the creation and) } bool server_start(struct sway_server *server) { diff --git a/swaybar/tray/item.c b/swaybar/tray/item.c index e7b8d4231..c657a6dfb 100644 --- a/swaybar/tray/item.c +++ b/swaybar/tray/item.c @@ -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 #include #include @@ -6,19 +19,6 @@ #include #include #include -#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 #include "sfdo.h" @@ -27,172 +27,178 @@ // TODO menu static bool sni_ready(struct swaybar_sni *sni) { - return sni->status && (sni->status[0] == 'N' ? // NeedsAttention - sni->attention_icon_name || sni->attention_icon_pixmap : - sni->icon_name || sni->icon_pixmap); + return sni->status && + (sni->status[0] == 'N' ? // NeedsAttention + sni->attention_icon_name || sni->attention_icon_pixmap + : sni->icon_name || sni->icon_pixmap); } static void set_sni_dirty(struct swaybar_sni *sni) { - if (sni_ready(sni)) { - sni->target_size = sni->min_size = sni->max_size = 0; // invalidate previous icon - set_bar_dirty(sni->tray->bar); - } + if (sni_ready(sni)) { + sni->target_size = sni->min_size = sni->max_size = + 0; // invalidate previous icon + set_bar_dirty(sni->tray->bar); + } } static int read_pixmap(sd_bus_message *msg, struct swaybar_sni *sni, - const char *prop, list_t **dest) { - int ret = sd_bus_message_enter_container(msg, 'a', "(iiay)"); - if (ret < 0) { - sway_log(SWAY_ERROR, "%s %s: %s", sni->watcher_id, prop, strerror(-ret)); - return ret; - } + const char *prop, list_t **dest) { + int ret = sd_bus_message_enter_container(msg, 'a', "(iiay)"); + if (ret < 0) { + sway_log(SWAY_ERROR, "%s %s: %s", sni->watcher_id, prop, strerror(-ret)); + return ret; + } - if (sd_bus_message_at_end(msg, 0)) { - sway_log(SWAY_DEBUG, "%s %s no. of icons = 0", sni->watcher_id, prop); - return ret; - } + if (sd_bus_message_at_end(msg, 0)) { + sway_log(SWAY_DEBUG, "%s %s no. of icons = 0", sni->watcher_id, prop); + return ret; + } - list_t *pixmaps = create_list(); - if (!pixmaps) { - return -12; // -ENOMEM - } + list_t *pixmaps = create_list(); + if (!pixmaps) { + return -12; // -ENOMEM + } - while (!sd_bus_message_at_end(msg, 0)) { - ret = sd_bus_message_enter_container(msg, 'r', "iiay"); - if (ret < 0) { - sway_log(SWAY_ERROR, "%s %s: %s", sni->watcher_id, prop, strerror(-ret)); - goto error; - } + while (!sd_bus_message_at_end(msg, 0)) { + ret = sd_bus_message_enter_container(msg, 'r', "iiay"); + if (ret < 0) { + sway_log(SWAY_ERROR, "%s %s: %s", sni->watcher_id, prop, strerror(-ret)); + goto error; + } - int width, height; - ret = sd_bus_message_read(msg, "ii", &width, &height); - if (ret < 0) { - sway_log(SWAY_ERROR, "%s %s: %s", sni->watcher_id, prop, strerror(-ret)); - goto error; - } + int width, height; + ret = sd_bus_message_read(msg, "ii", &width, &height); + if (ret < 0) { + sway_log(SWAY_ERROR, "%s %s: %s", sni->watcher_id, prop, strerror(-ret)); + goto error; + } - const void *pixels; - size_t npixels; - ret = sd_bus_message_read_array(msg, 'y', &pixels, &npixels); - if (ret < 0) { - sway_log(SWAY_ERROR, "%s %s: %s", sni->watcher_id, prop, strerror(-ret)); - goto error; - } + const void *pixels; + size_t npixels; + ret = sd_bus_message_read_array(msg, 'y', &pixels, &npixels); + if (ret < 0) { + sway_log(SWAY_ERROR, "%s %s: %s", sni->watcher_id, prop, strerror(-ret)); + goto error; + } - if (height > 0 && width == height) { - sway_log(SWAY_DEBUG, "%s %s: found icon w:%d h:%d", sni->watcher_id, prop, width, height); - struct swaybar_pixmap *pixmap = - malloc(sizeof(struct swaybar_pixmap) + npixels); - pixmap->size = height; + if (height > 0 && width == height) { + sway_log(SWAY_DEBUG, "%s %s: found icon w:%d h:%d", sni->watcher_id, prop, + width, height); + struct swaybar_pixmap *pixmap = + malloc(sizeof(struct swaybar_pixmap) + npixels); + pixmap->size = height; - // convert from network byte order to host byte order - for (int i = 0; i < height * width; ++i) { - ((uint32_t *)pixmap->pixels)[i] = ntohl(((uint32_t *)pixels)[i]); - } + // convert from network byte order to host byte order + for (int i = 0; i < height * width; ++i) { + ((uint32_t *)pixmap->pixels)[i] = ntohl(((uint32_t *)pixels)[i]); + } - list_add(pixmaps, pixmap); - } else { - sway_log(SWAY_DEBUG, "%s %s: discard invalid icon w:%d h:%d", sni->watcher_id, prop, width, height); - } + list_add(pixmaps, pixmap); + } else { + 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); + } - if (pixmaps->length < 1) { - sway_log(SWAY_DEBUG, "%s %s no. of icons = 0", sni->watcher_id, prop); - goto error; - } + if (pixmaps->length < 1) { + sway_log(SWAY_DEBUG, "%s %s no. of icons = 0", sni->watcher_id, prop); + goto error; + } - list_free_items_and_destroy(*dest); - *dest = pixmaps; - sway_log(SWAY_DEBUG, "%s %s no. of icons = %d", sni->watcher_id, prop, - pixmaps->length); + list_free_items_and_destroy(*dest); + *dest = pixmaps; + sway_log(SWAY_DEBUG, "%s %s no. of icons = %d", sni->watcher_id, prop, + pixmaps->length); - return ret; + return ret; error: - list_free_items_and_destroy(pixmaps); - return ret; + list_free_items_and_destroy(pixmaps); + return ret; } static int get_property_callback(sd_bus_message *msg, void *data, - sd_bus_error *error) { - struct swaybar_sni_slot *d = data; - struct swaybar_sni *sni = d->sni; - const char *prop = d->prop; - const char *type = d->type; - void *dest = d->dest; + sd_bus_error *error) { + struct swaybar_sni_slot *d = data; + struct swaybar_sni *sni = d->sni; + const char *prop = d->prop; + const char *type = d->type; + void *dest = d->dest; - int ret; - if (sd_bus_message_is_method_error(msg, NULL)) { - const sd_bus_error *err = sd_bus_message_get_error(msg); - sway_log_importance_t log_lv = SWAY_ERROR; - if ((!strcmp(prop, "IconThemePath")) && - (!strcmp(err->name, SD_BUS_ERROR_UNKNOWN_PROPERTY))) { - log_lv = SWAY_DEBUG; - } - sway_log(log_lv, "%s %s: %s", sni->watcher_id, prop, err->message); - ret = sd_bus_message_get_errno(msg); - goto cleanup; - } + int ret; + if (sd_bus_message_is_method_error(msg, NULL)) { + const sd_bus_error *err = sd_bus_message_get_error(msg); + sway_log_importance_t log_lv = SWAY_ERROR; + if ((!strcmp(prop, "IconThemePath")) && + (!strcmp(err->name, SD_BUS_ERROR_UNKNOWN_PROPERTY))) { + log_lv = SWAY_DEBUG; + } + sway_log(log_lv, "%s %s: %s", sni->watcher_id, prop, err->message); + ret = sd_bus_message_get_errno(msg); + goto cleanup; + } - ret = sd_bus_message_enter_container(msg, 'v', type); - if (ret < 0) { - sway_log(SWAY_ERROR, "%s %s: %s", sni->watcher_id, prop, strerror(-ret)); - goto cleanup; - } + ret = sd_bus_message_enter_container(msg, 'v', type); + if (ret < 0) { + sway_log(SWAY_ERROR, "%s %s: %s", sni->watcher_id, prop, strerror(-ret)); + goto cleanup; + } - if (!type) { - ret = read_pixmap(msg, sni, prop, dest); - if (ret < 0) { - goto cleanup; - } - } else { - if (*type == 's' || *type == 'o') { - free(*(char **)dest); - } + if (!type) { + ret = read_pixmap(msg, sni, prop, dest); + if (ret < 0) { + goto cleanup; + } + } else { + if (*type == 's' || *type == 'o') { + free(*(char **)dest); + } - ret = sd_bus_message_read(msg, type, dest); - if (ret < 0) { - sway_log(SWAY_ERROR, "%s %s: %s", sni->watcher_id, prop, strerror(-ret)); - goto cleanup; - } + ret = sd_bus_message_read(msg, type, dest); + if (ret < 0) { + sway_log(SWAY_ERROR, "%s %s: %s", sni->watcher_id, prop, strerror(-ret)); + goto cleanup; + } - if (*type == 's' || *type == 'o') { - char **str = dest; - *str = strdup(*str); - sway_log(SWAY_DEBUG, "%s %s = '%s'", sni->watcher_id, prop, *str); - } else if (*type == 'b') { - sway_log(SWAY_DEBUG, "%s %s = %s", sni->watcher_id, prop, - *(bool *)dest ? "true" : "false"); - } - } + if (*type == 's' || *type == 'o') { + char **str = dest; + *str = strdup(*str); + sway_log(SWAY_DEBUG, "%s %s = '%s'", sni->watcher_id, prop, *str); + } else if (*type == 'b') { + sway_log(SWAY_DEBUG, "%s %s = %s", sni->watcher_id, prop, + *(bool *)dest ? "true" : "false"); + } + } - if (strcmp(prop, "Status") == 0 || (sni->status && (sni->status[0] == 'N' ? - prop[0] == 'A' : has_prefix(prop, "Icon")))) { - set_sni_dirty(sni); - } + if (strcmp(prop, "Status") == 0 || + (sni->status && + (sni->status[0] == 'N' ? prop[0] == 'A' : has_prefix(prop, "Icon")))) { + set_sni_dirty(sni); + } cleanup: - wl_list_remove(&d->link); - free(data); - return ret; + wl_list_remove(&d->link); + free(data); + return ret; } static void sni_get_property_async(struct swaybar_sni *sni, const char *prop, - const char *type, void *dest) { - struct swaybar_sni_slot *data = calloc(1, sizeof(struct swaybar_sni_slot)); - data->sni = sni; - data->prop = prop; - data->type = type; - data->dest = dest; - int ret = sd_bus_call_method_async(sni->tray->bus, &data->slot, sni->service, - sni->path, "org.freedesktop.DBus.Properties", "Get", - get_property_callback, data, "ss", sni->interface, prop); - if (ret >= 0) { - wl_list_insert(&sni->slots, &data->link); - } else { - sway_log(SWAY_ERROR, "%s %s: %s", sni->watcher_id, prop, strerror(-ret)); - free(data); - } + const char *type, void *dest) { + struct swaybar_sni_slot *data = calloc(1, sizeof(struct swaybar_sni_slot)); + data->sni = sni; + data->prop = prop; + data->type = type; + data->dest = dest; + int ret = sd_bus_call_method_async( + sni->tray->bus, &data->slot, sni->service, sni->path, + "org.freedesktop.DBus.Properties", "Get", get_property_callback, data, + "ss", sni->interface, prop); + if (ret >= 0) { + wl_list_insert(&sni->slots, &data->link); + } else { + sway_log(SWAY_ERROR, "%s %s: %s", sni->watcher_id, prop, strerror(-ret)); + free(data); + } } /* @@ -210,362 +216,390 @@ static void sni_get_property_async(struct swaybar_sni *sni, const char *prop, * returns 0, which allows matching to continue. */ static int sni_check_msg_sender(struct swaybar_sni *sni, sd_bus_message *msg, - const char *signal) { - bool has_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) { - sway_log(SWAY_DEBUG, "%s has new %s", sni->watcher_id, signal); - return 1; - } else { - sway_log(SWAY_DEBUG, "%s may have new %s", sni->watcher_id, signal); - return 0; - } + const char *signal) { + bool has_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) { + sway_log(SWAY_DEBUG, "%s has new %s", sni->watcher_id, signal); + return 1; + } else { + sway_log(SWAY_DEBUG, "%s may have new %s", sni->watcher_id, signal); + return 0; + } } -static int handle_new_icon(sd_bus_message *msg, void *data, sd_bus_error *error) { - struct swaybar_sni *sni = data; - sni_get_property_async(sni, "IconName", "s", &sni->icon_name); - sni_get_property_async(sni, "IconPixmap", NULL, &sni->icon_pixmap); - if (!strcmp(sni->interface, "org.kde.StatusNotifierItem")) { - sni_get_property_async(sni, "IconThemePath", "s", &sni->icon_theme_path); - } - return sni_check_msg_sender(sni, msg, "icon"); +static int handle_new_icon(sd_bus_message *msg, void *data, + sd_bus_error *error) { + struct swaybar_sni *sni = data; + sni_get_property_async(sni, "IconName", "s", &sni->icon_name); + sni_get_property_async(sni, "IconPixmap", NULL, &sni->icon_pixmap); + if (!strcmp(sni->interface, "org.kde.StatusNotifierItem")) { + sni_get_property_async(sni, "IconThemePath", "s", &sni->icon_theme_path); + } + return sni_check_msg_sender(sni, msg, "icon"); } static int handle_new_attention_icon(sd_bus_message *msg, void *data, - sd_bus_error *error) { - struct swaybar_sni *sni = data; - sni_get_property_async(sni, "AttentionIconName", "s", &sni->attention_icon_name); - sni_get_property_async(sni, "AttentionIconPixmap", NULL, &sni->attention_icon_pixmap); - return sni_check_msg_sender(sni, msg, "attention icon"); + sd_bus_error *error) { + struct swaybar_sni *sni = data; + sni_get_property_async(sni, "AttentionIconName", "s", + &sni->attention_icon_name); + sni_get_property_async(sni, "AttentionIconPixmap", NULL, + &sni->attention_icon_pixmap); + return sni_check_msg_sender(sni, msg, "attention icon"); } -static int handle_new_status(sd_bus_message *msg, void *data, sd_bus_error *error) { - struct swaybar_sni *sni = data; - int ret = sni_check_msg_sender(sni, msg, "status"); - if (ret == 1) { - char *status; - int r = sd_bus_message_read(msg, "s", &status); - if (r < 0) { - sway_log(SWAY_ERROR, "%s new status error: %s", sni->watcher_id, strerror(-ret)); - ret = r; - } else { - free(sni->status); - sni->status = strdup(status); - sway_log(SWAY_DEBUG, "%s has new status = '%s'", sni->watcher_id, status); - set_sni_dirty(sni); - } - } else { - sni_get_property_async(sni, "Status", "s", &sni->status); - } +static int handle_new_status(sd_bus_message *msg, void *data, + sd_bus_error *error) { + struct swaybar_sni *sni = data; + int ret = sni_check_msg_sender(sni, msg, "status"); + if (ret == 1) { + char *status; + int r = sd_bus_message_read(msg, "s", &status); + if (r < 0) { + sway_log(SWAY_ERROR, "%s new status error: %s", sni->watcher_id, + strerror(-ret)); + ret = r; + } else { + free(sni->status); + sni->status = strdup(status); + sway_log(SWAY_DEBUG, "%s has new status = '%s'", sni->watcher_id, status); + set_sni_dirty(sni); + } + } else { + sni_get_property_async(sni, "Status", "s", &sni->status); + } - return ret; + return ret; } static void sni_match_signal_async(struct swaybar_sni *sni, char *signal, - sd_bus_message_handler_t callback) { - struct swaybar_sni_slot *slot = calloc(1, sizeof(struct swaybar_sni_slot)); - int ret = sd_bus_match_signal_async(sni->tray->bus, &slot->slot, - sni->service, sni->path, sni->interface, signal, callback, NULL, sni); - if (ret >= 0) { - wl_list_insert(&sni->slots, &slot->link); - } else { - sway_log(SWAY_ERROR, "%s failed to subscribe to signal %s: %s", - sni->service, signal, strerror(-ret)); - free(slot); - } + sd_bus_message_handler_t callback) { + struct swaybar_sni_slot *slot = calloc(1, sizeof(struct swaybar_sni_slot)); + int ret = sd_bus_match_signal_async(sni->tray->bus, &slot->slot, sni->service, + sni->path, sni->interface, signal, + callback, NULL, sni); + if (ret >= 0) { + wl_list_insert(&sni->slots, &slot->link); + } else { + sway_log(SWAY_ERROR, "%s failed to subscribe to signal %s: %s", + sni->service, signal, strerror(-ret)); + free(slot); + } } struct swaybar_sni *create_sni(char *id, struct swaybar_tray *tray) { - struct swaybar_sni *sni = calloc(1, sizeof(struct swaybar_sni)); - if (!sni) { - return NULL; - } - sni->tray = tray; - wl_list_init(&sni->slots); - sni->watcher_id = strdup(id); - char *path_ptr = strchr(id, '/'); - if (!path_ptr) { - sni->service = strdup(id); - sni->path = strdup("/StatusNotifierItem"); - sni->interface = "org.freedesktop.StatusNotifierItem"; - } else { - sni->service = strndup(id, path_ptr - id); - sni->path = strdup(path_ptr); - sni->interface = "org.kde.StatusNotifierItem"; - sni_get_property_async(sni, "IconThemePath", "s", &sni->icon_theme_path); - } + struct swaybar_sni *sni = calloc(1, sizeof(struct swaybar_sni)); + if (!sni) { + return NULL; + } + sni->tray = tray; + wl_list_init(&sni->slots); + sni->watcher_id = strdup(id); + char *path_ptr = strchr(id, '/'); + if (!path_ptr) { + sni->service = strdup(id); + sni->path = strdup("/StatusNotifierItem"); + sni->interface = "org.freedesktop.StatusNotifierItem"; + } else { + sni->service = strndup(id, path_ptr - id); + sni->path = strdup(path_ptr); + sni->interface = "org.kde.StatusNotifierItem"; + sni_get_property_async(sni, "IconThemePath", "s", &sni->icon_theme_path); + } - // Ignored: Category, Id, Title, WindowId, OverlayIconName, - // OverlayIconPixmap, AttentionMovieName, ToolTip - sni_get_property_async(sni, "Status", "s", &sni->status); - 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, "AttentionIconName", "s", &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, "Menu", "o", &sni->menu); + // Ignored: Category, Id, Title, WindowId, OverlayIconName, + // OverlayIconPixmap, AttentionMovieName, ToolTip + sni_get_property_async(sni, "Status", "s", &sni->status); + 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, "AttentionIconName", "s", + &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, "Menu", "o", &sni->menu); - sni_match_signal_async(sni, "NewIcon", handle_new_icon); - sni_match_signal_async(sni, "NewAttentionIcon", handle_new_attention_icon); - sni_match_signal_async(sni, "NewStatus", handle_new_status); + sni_match_signal_async(sni, "NewIcon", handle_new_icon); + sni_match_signal_async(sni, "NewAttentionIcon", handle_new_attention_icon); + sni_match_signal_async(sni, "NewStatus", handle_new_status); - return sni; + return sni; } void destroy_sni(struct swaybar_sni *sni) { - if (!sni) { - return; - } + if (!sni) { + return; + } - cairo_surface_destroy(sni->icon); - free(sni->watcher_id); - free(sni->service); - free(sni->path); - free(sni->status); - free(sni->icon_name); - list_free_items_and_destroy(sni->icon_pixmap); - free(sni->attention_icon_name); - list_free_items_and_destroy(sni->attention_icon_pixmap); - free(sni->menu); - free(sni->icon_theme_path); + cairo_surface_destroy(sni->icon); + free(sni->watcher_id); + free(sni->service); + free(sni->path); + free(sni->status); + free(sni->icon_name); + list_free_items_and_destroy(sni->icon_pixmap); + free(sni->attention_icon_name); + list_free_items_and_destroy(sni->attention_icon_pixmap); + free(sni->menu); + free(sni->icon_theme_path); - struct swaybar_sni_slot *slot, *slot_tmp; - wl_list_for_each_safe(slot, slot_tmp, &sni->slots, link) { - sd_bus_slot_unref(slot->slot); - free(slot); - } + struct swaybar_sni_slot *slot, *slot_tmp; + wl_list_for_each_safe(slot, slot_tmp, &sni->slots, link) { + sd_bus_slot_unref(slot->slot); + free(slot); + } - free(sni); + free(sni); } -static void handle_click(struct swaybar_sni *sni, int x, int y, - uint32_t button, int delta) { - const char *method = NULL; - struct tray_binding *binding = NULL; - wl_list_for_each(binding, &sni->tray->bar->config->tray_bindings, link) { - if (binding->button == button) { - method = binding->command; - break; - } - } - if (!method) { - static const char *default_bindings[10] = { - "nop", - "Activate", - "SecondaryActivate", - "ContextMenu", - "ScrollUp", - "ScrollDown", - "ScrollLeft", - "ScrollRight", - "nop", - "nop" - }; - method = default_bindings[event_to_x11_button(button)]; - } - if (strcmp(method, "nop") == 0) { - return; - } - if (sni->item_is_menu && strcmp(method, "Activate") == 0) { - method = "ContextMenu"; - } +static void handle_click(struct swaybar_sni *sni, int x, int y, uint32_t button, + int delta) { + const char *method = NULL; + struct tray_binding *binding = NULL; + wl_list_for_each(binding, &sni->tray->bar->config->tray_bindings, link) { + if (binding->button == button) { + method = binding->command; + break; + } + } + if (!method) { + static const char *default_bindings[10] = { + "nop", "Activate", "SecondaryActivate", "ContextMenu", + "ScrollUp", "ScrollDown", "ScrollLeft", "ScrollRight", + "nop", "nop"}; + method = default_bindings[event_to_x11_button(button)]; + } + if (strcmp(method, "nop") == 0) { + return; + } + if (sni->item_is_menu && strcmp(method, "Activate") == 0) { + method = "ContextMenu"; + } - if (has_prefix(method, "Scroll")) { - char dir = method[strlen("Scroll")]; - char *orientation = (dir == 'U' || dir == 'D') ? "vertical" : "horizontal"; - int sign = (dir == 'U' || dir == 'L') ? -1 : 1; + if (has_prefix(method, "Scroll")) { + char dir = method[strlen("Scroll")]; + char *orientation = (dir == 'U' || dir == 'D') ? "vertical" : "horizontal"; + int sign = (dir == 'U' || dir == 'L') ? -1 : 1; - sd_bus_call_method_async(sni->tray->bus, NULL, sni->service, sni->path, - sni->interface, "Scroll", NULL, NULL, "is", delta*sign, orientation); - } else { - sd_bus_call_method_async(sni->tray->bus, NULL, sni->service, sni->path, - sni->interface, method, NULL, NULL, "ii", x, y); - } + sd_bus_call_method_async(sni->tray->bus, NULL, sni->service, sni->path, + sni->interface, "Scroll", NULL, NULL, "is", + delta * sign, orientation); + } else { + sd_bus_call_method_async(sni->tray->bus, NULL, sni->service, sni->path, + sni->interface, method, NULL, NULL, "ii", x, y); + } } static int cmp_sni_id(const void *item, const void *cmp_to) { - const struct swaybar_sni *sni = item; - return strcmp(sni->watcher_id, cmp_to); + const struct swaybar_sni *sni = item; + return strcmp(sni->watcher_id, cmp_to); } -static enum hotspot_event_handling icon_hotspot_callback( - struct swaybar_output *output, struct swaybar_hotspot *hotspot, - double x, double y, uint32_t button, bool released, void *data) { - sway_log(SWAY_DEBUG, "Clicked on %s", (char *)data); +static enum hotspot_event_handling +icon_hotspot_callback(struct swaybar_output *output, + struct swaybar_hotspot *hotspot, double x, double y, + uint32_t button, bool released, void *data) { + sway_log(SWAY_DEBUG, "Clicked on %s", (char *)data); - struct swaybar_tray *tray = output->bar->tray; - int idx = list_seq_find(tray->items, cmp_sni_id, data); + struct swaybar_tray *tray = output->bar->tray; + int idx = list_seq_find(tray->items, cmp_sni_id, data); - if (idx != -1) { - if (released) { - // Since we handle the pressed event, also handle the released event - // to block it from falling through to a binding in the bar - return HOTSPOT_IGNORE; - } - struct swaybar_sni *sni = tray->items->items[idx]; - // guess global position since wayland doesn't expose it - struct swaybar_config *config = tray->bar->config; - int global_x = output->output_x + config->gaps.left + x; - bool top_bar = config->position & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP; - int global_y = output->output_y + (top_bar ? config->gaps.top + y: - (int) output->output_height - config->gaps.bottom - y); + if (idx != -1) { + if (released) { + // Since we handle the pressed event, also handle the released event + // to block it from falling through to a binding in the bar + return HOTSPOT_IGNORE; + } + struct swaybar_sni *sni = tray->items->items[idx]; + // guess global position since wayland doesn't expose it + struct swaybar_config *config = tray->bar->config; + int global_x = output->output_x + config->gaps.left + x; + bool top_bar = config->position & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP; + int global_y = output->output_y + (top_bar ? config->gaps.top + y + : (int)output->output_height - + config->gaps.bottom - y); - sway_log(SWAY_DEBUG, "Guessing click position at (%d, %d)", global_x, global_y); - handle_click(sni, global_x, global_y, button, 1); // TODO get delta from event - return HOTSPOT_IGNORE; - } else { - sway_log(SWAY_DEBUG, "but it doesn't exist"); - } + sway_log(SWAY_DEBUG, "Guessing click position at (%d, %d)", global_x, + global_y); + handle_click(sni, global_x, global_y, button, + 1); // TODO get delta from event + return HOTSPOT_IGNORE; + } else { + sway_log(SWAY_DEBUG, "but it doesn't exist"); + } - return HOTSPOT_PROCESS; + return HOTSPOT_PROCESS; } -static void reload_sni(struct swaybar_sni *sni, char *icon_theme, int target_size) { - char *icon_name = sni->status[0] == 'N' ? - sni->attention_icon_name : sni->icon_name; - if (icon_name) { - char *icon_path = NULL; +static void reload_sni(struct swaybar_sni *sni, char *icon_theme, + int target_size) { + 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); - } - icon_path = find_icon(sni->tray->themes, icon_search_paths, - icon_name, target_size, icon_theme, - &sni->min_size, &sni->max_size); + 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); + } + icon_path = + find_icon(sni->tray->themes, icon_search_paths, icon_name, target_size, + icon_theme, &sni->min_size, &sni->max_size); #else - // TODO: at some point we will need to make this scaling-aware - int scale = 1; - struct sfdo *sfdo = sni->tray->bar->config->sfdo; - if (sfdo) { - icon_path = sfdo_icon_lookup_extended(sfdo, icon_name, target_size, scale); - if (!icon_path) { - sway_log(SWAY_DEBUG, "sfdo: icon %s invalid or not found in theme %s at size %d", \ - icon_name, icon_theme, target_size); - } - } + // TODO: at some point we will need to make this scaling-aware + int scale = 1; + struct sfdo *sfdo = sni->tray->bar->config->sfdo; + if (sfdo) { + icon_path = + sfdo_icon_lookup_extended(sfdo, icon_name, target_size, scale); + if (!icon_path) { + sway_log(SWAY_DEBUG, + "sfdo: icon %s invalid or not found in theme %s at size %d", + 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 #if !HAVE_LIBSFDO - list_free(icon_search_paths); + list_free(icon_search_paths); #endif - if (icon_path) { - cairo_surface_destroy(sni->icon); - sni->icon = load_image(icon_path, target_size, scale); - free(icon_path); - return; - } else { - // the :( icon won't be drawn for a missing icon and whichever old icon was - // loaded will persist if this is not done. one might not have noticed this - // for tray items that have only one icon loaded only once, successfully or - // unsuccessfully. items with multiple icons, such as fcitx5 or other input - // method frameworks make the problem apparent - free(sni->icon); - sni->icon = NULL; - } - } + if (icon_path) { + cairo_surface_destroy(sni->icon); + sni->icon = load_image(icon_path, target_size, scale); + free(icon_path); + return; + } else { + // the :( icon won't be drawn for a missing icon and whichever old icon + // was loaded will persist if this is not done. one might not have noticed + // this for tray items that have only one icon loaded only once, + // successfully or unsuccessfully. items with multiple icons, such as + // fcitx5 or other input method frameworks make the problem apparent + free(sni->icon); + sni->icon = NULL; + } + } - list_t *pixmaps = sni->status[0] == 'N' ? - sni->attention_icon_pixmap : sni->icon_pixmap; - if (pixmaps) { - struct swaybar_pixmap *pixmap = NULL; - int min_error = INT_MAX; - for (int i = 0; i < pixmaps->length; ++i) { - struct swaybar_pixmap *p = pixmaps->items[i]; - int e = abs(target_size - p->size); - if (e < min_error) { - pixmap = p; - min_error = e; - } - } - cairo_surface_destroy(sni->icon); - sni->icon = cairo_image_surface_create_for_data(pixmap->pixels, - CAIRO_FORMAT_ARGB32, pixmap->size, pixmap->size, - cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, pixmap->size)); - } + list_t *pixmaps = + sni->status[0] == 'N' ? sni->attention_icon_pixmap : sni->icon_pixmap; + if (pixmaps) { + struct swaybar_pixmap *pixmap = NULL; + int min_error = INT_MAX; + for (int i = 0; i < pixmaps->length; ++i) { + struct swaybar_pixmap *p = pixmaps->items[i]; + int e = abs(target_size - p->size); + if (e < min_error) { + pixmap = p; + min_error = e; + } + } + cairo_surface_destroy(sni->icon); + sni->icon = cairo_image_surface_create_for_data( + pixmap->pixels, CAIRO_FORMAT_ARGB32, pixmap->size, pixmap->size, + cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, pixmap->size)); + } } uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x, - struct swaybar_sni *sni) { - uint32_t height = output->height * output->scale; - int padding = output->bar->config->tray_padding; - int target_size = height - 2*padding; - if (target_size != sni->target_size && sni_ready(sni)) { - // check if another icon should be loaded - if (target_size < sni->min_size || target_size > sni->max_size) { - reload_sni(sni, output->bar->config->icon_theme, target_size); - } + struct swaybar_sni *sni) { + uint32_t height = output->height * output->scale; + int padding = output->bar->config->tray_padding; + int target_size = height - 2 * padding; + if (target_size != sni->target_size && sni_ready(sni)) { + // check if another icon should be loaded + if (target_size < sni->min_size || target_size > sni->max_size) { + reload_sni(sni, output->bar->config->icon_theme, target_size); + } - sni->target_size = target_size; - } + sni->target_size = target_size; + } - // Passive - if (sni->status && sni->status[0] == 'P') { - return 0; - } + // Passive + if (sni->status && sni->status[0] == 'P') { + return 0; + } - int icon_size; - cairo_surface_t *icon; - if (sni->icon) { - int actual_size = cairo_image_surface_get_height(sni->icon); - icon_size = actual_size < target_size ? - actual_size*(target_size/actual_size) : target_size; - icon = cairo_image_surface_scale(sni->icon, icon_size, icon_size); - } else { // draw a :( - icon_size = target_size*0.8; - icon = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, icon_size, icon_size); - cairo_t *cairo_icon = cairo_create(icon); - cairo_set_source_u32(cairo_icon, 0xFF0000FF); - cairo_translate(cairo_icon, icon_size/2, icon_size/2); - cairo_scale(cairo_icon, icon_size/2, icon_size/2); - cairo_arc(cairo_icon, 0, 0, 1, 0, 7); - cairo_fill(cairo_icon); - cairo_set_operator(cairo_icon, CAIRO_OPERATOR_CLEAR); - cairo_arc(cairo_icon, 0.35, -0.3, 0.1, 0, 7); - cairo_fill(cairo_icon); - cairo_arc(cairo_icon, -0.35, -0.3, 0.1, 0, 7); - cairo_fill(cairo_icon); - cairo_arc(cairo_icon, 0, 0.75, 0.5, 3.71238898038469, 5.71238898038469); - cairo_set_line_width(cairo_icon, 0.1); - cairo_stroke(cairo_icon); - cairo_destroy(cairo_icon); - } + int icon_size; + cairo_surface_t *icon; + if (sni->icon) { + int actual_size = cairo_image_surface_get_height(sni->icon); + icon_size = actual_size < target_size + ? actual_size * (target_size / actual_size) + : target_size; + icon = cairo_image_surface_scale(sni->icon, icon_size, icon_size); + } else { // draw a :( + icon_size = target_size * 0.8; + icon = + cairo_image_surface_create(CAIRO_FORMAT_ARGB32, icon_size, icon_size); + cairo_t *cairo_icon = cairo_create(icon); + cairo_set_source_u32(cairo_icon, 0xFF0000FF); + cairo_translate(cairo_icon, icon_size / 2, icon_size / 2); + cairo_scale(cairo_icon, icon_size / 2, icon_size / 2); + cairo_arc(cairo_icon, 0, 0, 1, 0, 7); + cairo_fill(cairo_icon); + cairo_set_operator(cairo_icon, CAIRO_OPERATOR_CLEAR); + cairo_arc(cairo_icon, 0.35, -0.3, 0.1, 0, 7); + cairo_fill(cairo_icon); + cairo_arc(cairo_icon, -0.35, -0.3, 0.1, 0, 7); + cairo_fill(cairo_icon); + cairo_arc(cairo_icon, 0, 0.75, 0.5, 3.71238898038469, 5.71238898038469); + cairo_set_line_width(cairo_icon, 0.1); + cairo_stroke(cairo_icon); + cairo_destroy(cairo_icon); + } - double descaled_padding = (double)padding / output->scale; - double descaled_icon_size = (double)icon_size / output->scale; + double descaled_padding = (double)padding / output->scale; + double descaled_icon_size = (double)icon_size / output->scale; - int size = descaled_icon_size + 2 * descaled_padding; - *x -= size; - int icon_y = floor((output->height - size) / 2.0); + int size = descaled_icon_size + 2 * descaled_padding; + *x -= size; + int icon_y = floor((output->height - size) / 2.0); - cairo_operator_t op = cairo_get_operator(cairo); - cairo_set_operator(cairo, CAIRO_OPERATOR_OVER); + cairo_operator_t op = cairo_get_operator(cairo); + cairo_set_operator(cairo, CAIRO_OPERATOR_OVER); - cairo_matrix_t scale_matrix; - cairo_pattern_t *icon_pattern = cairo_pattern_create_for_surface(icon); - // TODO: check cairo_pattern_status for "ENOMEM" - cairo_matrix_init_scale(&scale_matrix, output->scale, output->scale); - cairo_matrix_translate(&scale_matrix, -(*x + descaled_padding), -(icon_y + descaled_padding)); - cairo_pattern_set_matrix(icon_pattern, &scale_matrix); - cairo_set_source(cairo, icon_pattern); - cairo_rectangle(cairo, *x, icon_y, size, size); - cairo_fill(cairo); + cairo_matrix_t scale_matrix; + cairo_pattern_t *icon_pattern = cairo_pattern_create_for_surface(icon); + // TODO: check cairo_pattern_status for "ENOMEM" + cairo_matrix_init_scale(&scale_matrix, output->scale, output->scale); + cairo_matrix_translate(&scale_matrix, -(*x + descaled_padding), + -(icon_y + descaled_padding)); + cairo_pattern_set_matrix(icon_pattern, &scale_matrix); + cairo_set_source(cairo, icon_pattern); + cairo_rectangle(cairo, *x, icon_y, size, size); + cairo_fill(cairo); - cairo_set_operator(cairo, op); + cairo_set_operator(cairo, op); - cairo_pattern_destroy(icon_pattern); - cairo_surface_destroy(icon); + cairo_pattern_destroy(icon_pattern); + cairo_surface_destroy(icon); - struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); - hotspot->x = *x; - hotspot->y = 0; - hotspot->width = size; - hotspot->height = output->height; - hotspot->callback = icon_hotspot_callback; - hotspot->destroy = free; - hotspot->data = strdup(sni->watcher_id); - wl_list_insert(&output->hotspots, &hotspot->link); + struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); + hotspot->x = *x; + hotspot->y = 0; + hotspot->width = size; + hotspot->height = output->height; + hotspot->callback = icon_hotspot_callback; + hotspot->destroy = free; + hotspot->data = strdup(sni->watcher_id); + wl_list_insert(&output->hotspots, &hotspot->link); - return output->height; + return output->height; }