aboutsummaryrefslogtreecommitdiffstats
path: root/swaybar
diff options
context:
space:
mode:
authorLibravatar Ian Fan <ianfan0@gmail.com>2018-12-07 12:37:33 +0000
committerLibravatar Ian Fan <ianfan0@gmail.com>2018-12-31 20:40:18 +0000
commitfa2c5282c1d09eced82a9c15a4ee26e7b00a37c4 (patch)
treeec9e36055d21478466d663e2dc1796658ab273ca /swaybar
parentswaybar: implement tray config (diff)
downloadsway-fa2c5282c1d09eced82a9c15a4ee26e7b00a37c4.tar.gz
sway-fa2c5282c1d09eced82a9c15a4ee26e7b00a37c4.tar.zst
sway-fa2c5282c1d09eced82a9c15a4ee26e7b00a37c4.zip
swaybar: implement tray rendering
Diffstat (limited to 'swaybar')
-rw-r--r--swaybar/tray/item.c84
-rw-r--r--swaybar/tray/tray.c25
2 files changed, 108 insertions, 1 deletions
diff --git a/swaybar/tray/item.c b/swaybar/tray/item.c
index 561a3425..019e8ed0 100644
--- a/swaybar/tray/item.c
+++ b/swaybar/tray/item.c
@@ -1,14 +1,27 @@
1#define _POSIX_C_SOURCE 200809L 1#define _POSIX_C_SOURCE 200809L
2#include <cairo.h>
3#include <stdbool.h>
2#include <stdlib.h> 4#include <stdlib.h>
3#include <string.h> 5#include <string.h>
6#include "swaybar/bar.h"
7#include "swaybar/config.h"
4#include "swaybar/tray/host.h" 8#include "swaybar/tray/host.h"
9#include "swaybar/tray/icon.h"
5#include "swaybar/tray/item.h" 10#include "swaybar/tray/item.h"
6#include "swaybar/tray/tray.h" 11#include "swaybar/tray/tray.h"
12#include "background-image.h"
13#include "cairo.h"
7#include "list.h" 14#include "list.h"
8#include "log.h" 15#include "log.h"
9 16
10// TODO menu 17// TODO menu
11 18
19static bool sni_ready(struct swaybar_sni *sni) {
20 return sni->status && (sni->status[0] == 'N' ?
21 sni->attention_icon_name || sni->attention_icon_pixmap :
22 sni->icon_name || sni->icon_pixmap);
23}
24
12static int read_pixmap(sd_bus_message *msg, struct swaybar_sni *sni, 25static int read_pixmap(sd_bus_message *msg, struct swaybar_sni *sni,
13 const char *prop, list_t **dest) { 26 const char *prop, list_t **dest) {
14 int ret = sd_bus_message_enter_container(msg, 'a', "(iiay)"); 27 int ret = sd_bus_message_enter_container(msg, 'a', "(iiay)");
@@ -234,3 +247,74 @@ void destroy_sni(struct swaybar_sni *sni) {
234 free(sni->menu); 247 free(sni->menu);
235 free(sni); 248 free(sni);
236} 249}
250
251uint32_t render_sni(cairo_t *cairo, struct swaybar_output *output, double *x,
252 struct swaybar_sni *sni) {
253 uint32_t height = output->height * output->scale;
254 int padding = output->bar->config->tray_padding;
255 int ideal_size = height - 2*padding;
256 if ((ideal_size < sni->min_size || ideal_size > sni->max_size) && sni_ready(sni)) {
257 bool icon_found = false;
258 char *icon_name = sni->status[0] == 'N' ?
259 sni->attention_icon_name : sni->icon_name;
260 if (icon_name) {
261 char *icon_path = find_icon(sni->tray->themes, sni->tray->basedirs,
262 icon_name, ideal_size, output->bar->config->icon_theme,
263 &sni->min_size, &sni->max_size);
264 if (icon_path) {
265 cairo_surface_destroy(sni->icon);
266 sni->icon = load_background_image(icon_path);
267 free(icon_path);
268 icon_found = true;
269 }
270 }
271 if (!icon_found) {
272 list_t *pixmaps = sni->status[0] == 'N' ?
273 sni->attention_icon_pixmap : sni->icon_pixmap;
274 if (pixmaps) {
275 int idx = -1;
276 unsigned smallest_error = -1; // UINT_MAX
277 for (int i = 0; i < pixmaps->length; ++i) {
278 struct swaybar_pixmap *pixmap = pixmaps->items[i];
279 unsigned error = (ideal_size - pixmap->size) *
280 (ideal_size < pixmap->size ? -1 : 1);
281 if (error < smallest_error) {
282 smallest_error = error;
283 idx = i;
284 }
285 }
286 struct swaybar_pixmap *pixmap = pixmaps->items[idx];
287 cairo_surface_destroy(sni->icon);
288 sni->icon = cairo_image_surface_create_for_data(pixmap->pixels,
289 CAIRO_FORMAT_ARGB32, pixmap->size, pixmap->size,
290 cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, pixmap->size));
291 }
292 }
293 }
294
295 if (!sni->icon) {
296 // TODO fallback
297 return 0;
298 }
299
300 cairo_surface_t *icon;
301 int actual_size = cairo_image_surface_get_height(sni->icon);
302 int icon_size = actual_size < ideal_size ?
303 actual_size * (ideal_size / actual_size) : ideal_size;
304 icon = cairo_image_surface_scale(sni->icon, icon_size, icon_size);
305
306 int padded_size = icon_size + 2*padding;
307 *x -= padded_size;
308 int y = floor((height - padded_size) / 2.0);
309
310 cairo_operator_t op = cairo_get_operator(cairo);
311 cairo_set_operator(cairo, CAIRO_OPERATOR_OVER);
312 cairo_set_source_surface(cairo, icon, *x + padding, y + padding);
313 cairo_rectangle(cairo, *x, y, padded_size, padded_size);
314 cairo_fill(cairo);
315 cairo_set_operator(cairo, op);
316
317 cairo_surface_destroy(icon);
318
319 return output->height;
320}
diff --git a/swaybar/tray/tray.c b/swaybar/tray/tray.c
index 4ef28a78..f186ed86 100644
--- a/swaybar/tray/tray.c
+++ b/swaybar/tray/tray.c
@@ -2,6 +2,7 @@
2#include <stdint.h> 2#include <stdint.h>
3#include <stdlib.h> 3#include <stdlib.h>
4#include <string.h> 4#include <string.h>
5#include "swaybar/config.h"
5#include "swaybar/bar.h" 6#include "swaybar/bar.h"
6#include "swaybar/tray/icon.h" 7#include "swaybar/tray/icon.h"
7#include "swaybar/tray/host.h" 8#include "swaybar/tray/host.h"
@@ -70,6 +71,28 @@ void tray_in(int fd, short mask, void *data) {
70 } 71 }
71} 72}
72 73
74static int cmp_output(const void *item, const void *cmp_to) {
75 return strcmp(item, cmp_to);
76}
77
73uint32_t render_tray(cairo_t *cairo, struct swaybar_output *output, double *x) { 78uint32_t render_tray(cairo_t *cairo, struct swaybar_output *output, double *x) {
74 return 0; // placeholder 79 struct swaybar_config *config = output->bar->config;
80 if (config->tray_outputs) {
81 if (list_seq_find(config->tray_outputs, cmp_output, output->name) == -1) {
82 return 0;
83 }
84 } // else display on all
85
86 if ((int) output->height*output->scale <= 2*config->tray_padding) {
87 return 2*config->tray_padding + 1;
88 }
89
90 uint32_t max_height = 0;
91 struct swaybar_tray *tray = output->bar->tray;
92 for (int i = 0; i < tray->items->length; ++i) {
93 uint32_t h = render_sni(cairo, output, x, tray->items->items[i]);
94 max_height = h > max_height ? h : max_height;
95 }
96
97 return max_height;
75} 98}