aboutsummaryrefslogtreecommitdiffstats
path: root/swaybar/tray
diff options
context:
space:
mode:
Diffstat (limited to 'swaybar/tray')
-rw-r--r--swaybar/tray/host.c11
-rw-r--r--swaybar/tray/icon.c27
-rw-r--r--swaybar/tray/item.c43
-rw-r--r--swaybar/tray/tray.c4
-rw-r--r--swaybar/tray/watcher.c12
5 files changed, 47 insertions, 50 deletions
diff --git a/swaybar/tray/host.c b/swaybar/tray/host.c
index ddf2416d..79b54606 100644
--- a/swaybar/tray/host.c
+++ b/swaybar/tray/host.c
@@ -1,4 +1,3 @@
1#define _POSIX_C_SOURCE 200809L
2#include <stdbool.h> 1#include <stdbool.h>
3#include <stdio.h> 2#include <stdio.h>
4#include <stdlib.h> 3#include <stdlib.h>
@@ -10,6 +9,7 @@
10#include "swaybar/tray/tray.h" 9#include "swaybar/tray/tray.h"
11#include "list.h" 10#include "list.h"
12#include "log.h" 11#include "log.h"
12#include "stringop.h"
13 13
14static const char *watcher_path = "/StatusNotifierWatcher"; 14static const char *watcher_path = "/StatusNotifierWatcher";
15 15
@@ -138,12 +138,10 @@ static int handle_new_watcher(sd_bus_message *msg,
138 138
139bool init_host(struct swaybar_host *host, char *protocol, 139bool init_host(struct swaybar_host *host, char *protocol,
140 struct swaybar_tray *tray) { 140 struct swaybar_tray *tray) {
141 size_t len = snprintf(NULL, 0, "org.%s.StatusNotifierWatcher", protocol) + 1; 141 host->watcher_interface = format_str("org.%s.StatusNotifierWatcher", protocol);
142 host->watcher_interface = malloc(len);
143 if (!host->watcher_interface) { 142 if (!host->watcher_interface) {
144 return false; 143 return false;
145 } 144 }
146 snprintf(host->watcher_interface, len, "org.%s.StatusNotifierWatcher", protocol);
147 145
148 sd_bus_slot *reg_slot = NULL, *unreg_slot = NULL, *watcher_slot = NULL; 146 sd_bus_slot *reg_slot = NULL, *unreg_slot = NULL, *watcher_slot = NULL;
149 int ret = sd_bus_match_signal(tray->bus, &reg_slot, host->watcher_interface, 147 int ret = sd_bus_match_signal(tray->bus, &reg_slot, host->watcher_interface,
@@ -173,13 +171,10 @@ bool init_host(struct swaybar_host *host, char *protocol,
173 } 171 }
174 172
175 pid_t pid = getpid(); 173 pid_t pid = getpid();
176 size_t service_len = snprintf(NULL, 0, "org.%s.StatusNotifierHost-%d", 174 host->service = format_str("org.%s.StatusNotifierHost-%d", protocol, pid);
177 protocol, pid) + 1;
178 host->service = malloc(service_len);
179 if (!host->service) { 175 if (!host->service) {
180 goto error; 176 goto error;
181 } 177 }
182 snprintf(host->service, service_len, "org.%s.StatusNotifierHost-%d", protocol, pid);
183 ret = sd_bus_request_name(tray->bus, host->service, 0); 178 ret = sd_bus_request_name(tray->bus, host->service, 0);
184 if (ret < 0) { 179 if (ret < 0) {
185 sway_log(SWAY_DEBUG, "Failed to acquire service name: %s", strerror(-ret)); 180 sway_log(SWAY_DEBUG, "Failed to acquire service name: %s", strerror(-ret));
diff --git a/swaybar/tray/icon.c b/swaybar/tray/icon.c
index c426c3d4..659edd86 100644
--- a/swaybar/tray/icon.c
+++ b/swaybar/tray/icon.c
@@ -1,4 +1,3 @@
1#define _POSIX_C_SOURCE 200809L
2#include <ctype.h> 1#include <ctype.h>
3#include <dirent.h> 2#include <dirent.h>
4#include <stdbool.h> 3#include <stdbool.h>
@@ -40,9 +39,7 @@ static list_t *get_basedirs(void) {
40 data_dirs = strdup(data_dirs); 39 data_dirs = strdup(data_dirs);
41 char *dir = strtok(data_dirs, ":"); 40 char *dir = strtok(data_dirs, ":");
42 do { 41 do {
43 size_t path_len = snprintf(NULL, 0, "%s/icons", dir) + 1; 42 char *path = format_str("%s/icons", dir);
44 char *path = malloc(path_len);
45 snprintf(path, path_len, "%s/icons", dir);
46 list_add(basedirs, path); 43 list_add(basedirs, path);
47 } while ((dir = strtok(NULL, ":"))); 44 } while ((dir = strtok(NULL, ":")));
48 free(data_dirs); 45 free(data_dirs);
@@ -206,13 +203,7 @@ static const char *entry_handler(char *group, char *key, char *value,
206 */ 203 */
207static struct icon_theme *read_theme_file(char *basedir, char *theme_name) { 204static struct icon_theme *read_theme_file(char *basedir, char *theme_name) {
208 // look for index.theme file 205 // look for index.theme file
209 size_t path_len = snprintf(NULL, 0, "%s/%s/index.theme", basedir, 206 char *path = format_str("%s/%s/index.theme", basedir, theme_name);
210 theme_name) + 1;
211 char *path = malloc(path_len);
212 if (!path) {
213 return NULL;
214 }
215 snprintf(path, path_len, "%s/%s/index.theme", basedir, theme_name);
216 FILE *theme_file = fopen(path, "r"); 207 FILE *theme_file = fopen(path, "r");
217 free(path); 208 free(path);
218 if (!theme_file) { 209 if (!theme_file) {
@@ -416,26 +407,20 @@ static char *find_icon_in_subdir(char *name, char *basedir, char *theme,
416#endif 407#endif
417 }; 408 };
418 409
419 size_t path_len = snprintf(NULL, 0, "%s/%s/%s/%s.EXT", basedir, theme,
420 subdir, name) + 1;
421 char *path = malloc(path_len);
422
423 for (size_t i = 0; i < sizeof(extensions) / sizeof(*extensions); ++i) { 410 for (size_t i = 0; i < sizeof(extensions) / sizeof(*extensions); ++i) {
424 snprintf(path, path_len, "%s/%s/%s/%s.%s", basedir, theme, subdir, 411 char *path = format_str("%s/%s/%s/%s.%s",
425 name, extensions[i]); 412 basedir, theme, subdir, name, extensions[i]);
426 if (access(path, R_OK) == 0) { 413 if (access(path, R_OK) == 0) {
427 return path; 414 return path;
428 } 415 }
416 free(path);
429 } 417 }
430 418
431 free(path);
432 return NULL; 419 return NULL;
433} 420}
434 421
435static bool theme_exists_in_basedir(char *theme, char *basedir) { 422static bool theme_exists_in_basedir(char *theme, char *basedir) {
436 size_t path_len = snprintf(NULL, 0, "%s/%s", basedir, theme) + 1; 423 char *path = format_str("%s/%s", basedir, theme);
437 char *path = malloc(path_len);
438 snprintf(path, path_len, "%s/%s", basedir, theme);
439 bool ret = dir_exists(path); 424 bool ret = dir_exists(path);
440 free(path); 425 free(path);
441 return ret; 426 return ret;
diff --git a/swaybar/tray/item.c b/swaybar/tray/item.c
index 19f4beac..ca6c03ad 100644
--- a/swaybar/tray/item.c
+++ b/swaybar/tray/item.c
@@ -1,4 +1,3 @@
1#define _POSIX_C_SOURCE 200809L
2#include <arpa/inet.h> 1#include <arpa/inet.h>
3#include <cairo.h> 2#include <cairo.h>
4#include <limits.h> 3#include <limits.h>
@@ -7,12 +6,12 @@
7#include <string.h> 6#include <string.h>
8#include "swaybar/bar.h" 7#include "swaybar/bar.h"
9#include "swaybar/config.h" 8#include "swaybar/config.h"
9#include "swaybar/image.h"
10#include "swaybar/input.h" 10#include "swaybar/input.h"
11#include "swaybar/tray/host.h" 11#include "swaybar/tray/host.h"
12#include "swaybar/tray/icon.h" 12#include "swaybar/tray/icon.h"
13#include "swaybar/tray/item.h" 13#include "swaybar/tray/item.h"
14#include "swaybar/tray/tray.h" 14#include "swaybar/tray/tray.h"
15#include "background-image.h"
16#include "cairo_util.h" 15#include "cairo_util.h"
17#include "list.h" 16#include "list.h"
18#include "log.h" 17#include "log.h"
@@ -385,13 +384,18 @@ static int cmp_sni_id(const void *item, const void *cmp_to) {
385 384
386static enum hotspot_event_handling icon_hotspot_callback( 385static enum hotspot_event_handling icon_hotspot_callback(
387 struct swaybar_output *output, struct swaybar_hotspot *hotspot, 386 struct swaybar_output *output, struct swaybar_hotspot *hotspot,
388 double x, double y, uint32_t button, void *data) { 387 double x, double y, uint32_t button, bool released, void *data) {
389 sway_log(SWAY_DEBUG, "Clicked on %s", (char *)data); 388 sway_log(SWAY_DEBUG, "Clicked on %s", (char *)data);
390 389
391 struct swaybar_tray *tray = output->bar->tray; 390 struct swaybar_tray *tray = output->bar->tray;
392 int idx = list_seq_find(tray->items, cmp_sni_id, data); 391 int idx = list_seq_find(tray->items, cmp_sni_id, data);
393 392
394 if (idx != -1) { 393 if (idx != -1) {
394 if (released) {
395 // Since we handle the pressed event, also handle the released event
396 // to block it from falling through to a binding in the bar
397 return HOTSPOT_IGNORE;
398 }
395 struct swaybar_sni *sni = tray->items->items[idx]; 399 struct swaybar_sni *sni = tray->items->items[idx];
396 // guess global position since wayland doesn't expose it 400 // guess global position since wayland doesn't expose it
397 struct swaybar_config *config = tray->bar->config; 401 struct swaybar_config *config = tray->bar->config;
@@ -426,7 +430,7 @@ static void reload_sni(struct swaybar_sni *sni, char *icon_theme,
426 list_free(icon_search_paths); 430 list_free(icon_search_paths);
427 if (icon_path) { 431 if (icon_path) {
428 cairo_surface_destroy(sni->icon); 432 cairo_surface_destroy(sni->icon);
429 sni->icon = load_background_image(icon_path); 433 sni->icon = load_image(icon_path);
430 free(icon_path); 434 free(icon_path);
431 return; 435 return;
432 } 436 }
@@ -466,6 +470,11 @@ uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x,
466 sni->target_size = target_size; 470 sni->target_size = target_size;
467 } 471 }
468 472
473 // Passive
474 if (sni->status && sni->status[0] == 'P') {
475 return 0;
476 }
477
469 int icon_size; 478 int icon_size;
470 cairo_surface_t *icon; 479 cairo_surface_t *icon;
471 if (sni->icon) { 480 if (sni->icon) {
@@ -493,24 +502,36 @@ uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x,
493 cairo_destroy(cairo_icon); 502 cairo_destroy(cairo_icon);
494 } 503 }
495 504
496 int padded_size = icon_size + 2*padding; 505 double descaled_padding = (double)padding / output->scale;
497 *x -= padded_size; 506 double descaled_icon_size = (double)icon_size / output->scale;
498 int y = floor((height - padded_size) / 2.0); 507
508 int size = descaled_icon_size + 2 * descaled_padding;
509 *x -= size;
510 int icon_y = floor((output->height - size) / 2.0);
499 511
500 cairo_operator_t op = cairo_get_operator(cairo); 512 cairo_operator_t op = cairo_get_operator(cairo);
501 cairo_set_operator(cairo, CAIRO_OPERATOR_OVER); 513 cairo_set_operator(cairo, CAIRO_OPERATOR_OVER);
502 cairo_set_source_surface(cairo, icon, *x + padding, y + padding); 514
503 cairo_rectangle(cairo, *x, y, padded_size, padded_size); 515 cairo_matrix_t scale_matrix;
516 cairo_pattern_t *icon_pattern = cairo_pattern_create_for_surface(icon);
517 // TODO: check cairo_pattern_status for "ENOMEM"
518 cairo_matrix_init_scale(&scale_matrix, output->scale, output->scale);
519 cairo_matrix_translate(&scale_matrix, -(*x + descaled_padding), -(icon_y + descaled_padding));
520 cairo_pattern_set_matrix(icon_pattern, &scale_matrix);
521 cairo_set_source(cairo, icon_pattern);
522 cairo_rectangle(cairo, *x, icon_y, size, size);
504 cairo_fill(cairo); 523 cairo_fill(cairo);
524
505 cairo_set_operator(cairo, op); 525 cairo_set_operator(cairo, op);
506 526
527 cairo_pattern_destroy(icon_pattern);
507 cairo_surface_destroy(icon); 528 cairo_surface_destroy(icon);
508 529
509 struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); 530 struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot));
510 hotspot->x = *x; 531 hotspot->x = *x;
511 hotspot->y = 0; 532 hotspot->y = 0;
512 hotspot->width = height; 533 hotspot->width = size;
513 hotspot->height = height; 534 hotspot->height = output->height;
514 hotspot->callback = icon_hotspot_callback; 535 hotspot->callback = icon_hotspot_callback;
515 hotspot->destroy = free; 536 hotspot->destroy = free;
516 hotspot->data = strdup(sni->watcher_id); 537 hotspot->data = strdup(sni->watcher_id);
diff --git a/swaybar/tray/tray.c b/swaybar/tray/tray.c
index 5fe6f9c3..b0545f4a 100644
--- a/swaybar/tray/tray.c
+++ b/swaybar/tray/tray.c
@@ -116,8 +116,8 @@ uint32_t render_tray(cairo_t *cairo, struct swaybar_output *output, double *x) {
116 } 116 }
117 } // else display on all 117 } // else display on all
118 118
119 if ((int) output->height*output->scale <= 2*config->tray_padding) { 119 if ((int)(output->height * output->scale) <= 2 * config->tray_padding) {
120 return 2*config->tray_padding + 1; 120 return (2 * config->tray_padding + 1) / output->scale;
121 } 121 }
122 122
123 uint32_t max_height = 0; 123 uint32_t max_height = 0;
diff --git a/swaybar/tray/watcher.c b/swaybar/tray/watcher.c
index 16afc27c..3cfea8d8 100644
--- a/swaybar/tray/watcher.c
+++ b/swaybar/tray/watcher.c
@@ -1,4 +1,3 @@
1#define _POSIX_C_SOURCE 200809L
2#include <stdbool.h> 1#include <stdbool.h>
3#include <stddef.h> 2#include <stddef.h>
4#include <stdio.h> 3#include <stdio.h>
@@ -6,6 +5,7 @@
6#include <string.h> 5#include <string.h>
7#include "list.h" 6#include "list.h"
8#include "log.h" 7#include "log.h"
8#include "stringop.h"
9#include "swaybar/tray/watcher.h" 9#include "swaybar/tray/watcher.h"
10 10
11static const char *obj_path = "/StatusNotifierWatcher"; 11static const char *obj_path = "/StatusNotifierWatcher";
@@ -76,9 +76,7 @@ static int register_sni(sd_bus_message *msg, void *data, sd_bus_error *error) {
76 service = service_or_path; 76 service = service_or_path;
77 path = "/StatusNotifierItem"; 77 path = "/StatusNotifierItem";
78 } 78 }
79 size_t id_len = snprintf(NULL, 0, "%s%s", service, path) + 1; 79 id = format_str("%s%s", service, path);
80 id = malloc(id_len);
81 snprintf(id, id_len, "%s%s", service, path);
82 } 80 }
83 81
84 if (list_seq_find(watcher->items, cmp_id, id) == -1) { 82 if (list_seq_find(watcher->items, cmp_id, id) == -1) {
@@ -107,7 +105,7 @@ static int register_host(sd_bus_message *msg, void *data, sd_bus_error *error) {
107 sway_log(SWAY_DEBUG, "Registering Status Notifier Host '%s'", service); 105 sway_log(SWAY_DEBUG, "Registering Status Notifier Host '%s'", service);
108 list_add(watcher->hosts, strdup(service)); 106 list_add(watcher->hosts, strdup(service));
109 sd_bus_emit_signal(watcher->bus, obj_path, watcher->interface, 107 sd_bus_emit_signal(watcher->bus, obj_path, watcher->interface,
110 "StatusNotifierHostRegistered", "s", service); 108 "StatusNotifierHostRegistered", "");
111 } else { 109 } else {
112 sway_log(SWAY_DEBUG, "Status Notifier Host '%s' already registered", service); 110 sway_log(SWAY_DEBUG, "Status Notifier Host '%s' already registered", service);
113 } 111 }
@@ -159,9 +157,7 @@ struct swaybar_watcher *create_watcher(char *protocol, sd_bus *bus) {
159 return NULL; 157 return NULL;
160 } 158 }
161 159
162 size_t len = snprintf(NULL, 0, "org.%s.StatusNotifierWatcher", protocol) + 1; 160 watcher->interface = format_str("org.%s.StatusNotifierWatcher", protocol);
163 watcher->interface = malloc(len);
164 snprintf(watcher->interface, len, "org.%s.StatusNotifierWatcher", protocol);
165 161
166 sd_bus_slot *signal_slot = NULL, *vtable_slot = NULL; 162 sd_bus_slot *signal_slot = NULL, *vtable_slot = NULL;
167 int ret = sd_bus_add_object_vtable(bus, &vtable_slot, obj_path, 163 int ret = sd_bus_add_object_vtable(bus, &vtable_slot, obj_path,