aboutsummaryrefslogtreecommitdiffstats
path: root/swaybar/tray/item.c
diff options
context:
space:
mode:
Diffstat (limited to 'swaybar/tray/item.c')
-rw-r--r--swaybar/tray/item.c54
1 files changed, 40 insertions, 14 deletions
diff --git a/swaybar/tray/item.c b/swaybar/tray/item.c
index a5660f62..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,13 +6,13 @@
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" 15#include "cairo_util.h"
16#include "cairo.h"
17#include "list.h" 16#include "list.h"
18#include "log.h" 17#include "log.h"
19#include "wlr-layer-shell-unstable-v1-client-protocol.h" 18#include "wlr-layer-shell-unstable-v1-client-protocol.h"
@@ -118,8 +117,13 @@ static int get_property_callback(sd_bus_message *msg, void *data,
118 117
119 int ret; 118 int ret;
120 if (sd_bus_message_is_method_error(msg, NULL)) { 119 if (sd_bus_message_is_method_error(msg, NULL)) {
121 sway_log(SWAY_ERROR, "%s %s: %s", sni->watcher_id, prop, 120 const sd_bus_error *err = sd_bus_message_get_error(msg);
122 sd_bus_message_get_error(msg)->message); 121 sway_log_importance_t log_lv = SWAY_ERROR;
122 if ((!strcmp(prop, "IconThemePath")) &&
123 (!strcmp(err->name, SD_BUS_ERROR_UNKNOWN_PROPERTY))) {
124 log_lv = SWAY_DEBUG;
125 }
126 sway_log(log_lv, "%s %s: %s", sni->watcher_id, prop, err->message);
123 ret = sd_bus_message_get_errno(msg); 127 ret = sd_bus_message_get_errno(msg);
124 goto cleanup; 128 goto cleanup;
125 } 129 }
@@ -380,13 +384,18 @@ static int cmp_sni_id(const void *item, const void *cmp_to) {
380 384
381static enum hotspot_event_handling icon_hotspot_callback( 385static enum hotspot_event_handling icon_hotspot_callback(
382 struct swaybar_output *output, struct swaybar_hotspot *hotspot, 386 struct swaybar_output *output, struct swaybar_hotspot *hotspot,
383 double x, double y, uint32_t button, void *data) { 387 double x, double y, uint32_t button, bool released, void *data) {
384 sway_log(SWAY_DEBUG, "Clicked on %s", (char *)data); 388 sway_log(SWAY_DEBUG, "Clicked on %s", (char *)data);
385 389
386 struct swaybar_tray *tray = output->bar->tray; 390 struct swaybar_tray *tray = output->bar->tray;
387 int idx = list_seq_find(tray->items, cmp_sni_id, data); 391 int idx = list_seq_find(tray->items, cmp_sni_id, data);
388 392
389 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 }
390 struct swaybar_sni *sni = tray->items->items[idx]; 399 struct swaybar_sni *sni = tray->items->items[idx];
391 // guess global position since wayland doesn't expose it 400 // guess global position since wayland doesn't expose it
392 struct swaybar_config *config = tray->bar->config; 401 struct swaybar_config *config = tray->bar->config;
@@ -421,7 +430,7 @@ static void reload_sni(struct swaybar_sni *sni, char *icon_theme,
421 list_free(icon_search_paths); 430 list_free(icon_search_paths);
422 if (icon_path) { 431 if (icon_path) {
423 cairo_surface_destroy(sni->icon); 432 cairo_surface_destroy(sni->icon);
424 sni->icon = load_background_image(icon_path); 433 sni->icon = load_image(icon_path);
425 free(icon_path); 434 free(icon_path);
426 return; 435 return;
427 } 436 }
@@ -461,6 +470,11 @@ uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x,
461 sni->target_size = target_size; 470 sni->target_size = target_size;
462 } 471 }
463 472
473 // Passive
474 if (sni->status && sni->status[0] == 'P') {
475 return 0;
476 }
477
464 int icon_size; 478 int icon_size;
465 cairo_surface_t *icon; 479 cairo_surface_t *icon;
466 if (sni->icon) { 480 if (sni->icon) {
@@ -488,24 +502,36 @@ uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x,
488 cairo_destroy(cairo_icon); 502 cairo_destroy(cairo_icon);
489 } 503 }
490 504
491 int padded_size = icon_size + 2*padding; 505 double descaled_padding = (double)padding / output->scale;
492 *x -= padded_size; 506 double descaled_icon_size = (double)icon_size / output->scale;
493 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);
494 511
495 cairo_operator_t op = cairo_get_operator(cairo); 512 cairo_operator_t op = cairo_get_operator(cairo);
496 cairo_set_operator(cairo, CAIRO_OPERATOR_OVER); 513 cairo_set_operator(cairo, CAIRO_OPERATOR_OVER);
497 cairo_set_source_surface(cairo, icon, *x + padding, y + padding); 514
498 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);
499 cairo_fill(cairo); 523 cairo_fill(cairo);
524
500 cairo_set_operator(cairo, op); 525 cairo_set_operator(cairo, op);
501 526
527 cairo_pattern_destroy(icon_pattern);
502 cairo_surface_destroy(icon); 528 cairo_surface_destroy(icon);
503 529
504 struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); 530 struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot));
505 hotspot->x = *x; 531 hotspot->x = *x;
506 hotspot->y = 0; 532 hotspot->y = 0;
507 hotspot->width = height; 533 hotspot->width = size;
508 hotspot->height = height; 534 hotspot->height = output->height;
509 hotspot->callback = icon_hotspot_callback; 535 hotspot->callback = icon_hotspot_callback;
510 hotspot->destroy = free; 536 hotspot->destroy = free;
511 hotspot->data = strdup(sni->watcher_id); 537 hotspot->data = strdup(sni->watcher_id);