diff options
author | Calvin Lee <cyrus296@gmail.com> | 2017-06-07 21:32:48 -0700 |
---|---|---|
committer | Calvin Lee <cyrus296@gmail.com> | 2017-06-07 21:32:48 -0700 |
commit | 1451ee8fd13dd35227d11e393c80871c70ad90f0 (patch) | |
tree | 74a34de797c46c2734751d77b4dc4ac5694af9a7 /swaybar/tray/tray.c | |
parent | Fix cairo blending on tray icons (diff) | |
download | sway-1451ee8fd13dd35227d11e393c80871c70ad90f0.tar.gz sway-1451ee8fd13dd35227d11e393c80871c70ad90f0.tar.zst sway-1451ee8fd13dd35227d11e393c80871c70ad90f0.zip |
Reorganize Tray Code
Remove tray code from bar.c and render.c
Diffstat (limited to 'swaybar/tray/tray.c')
-rw-r--r-- | swaybar/tray/tray.c | 131 |
1 files changed, 130 insertions, 1 deletions
diff --git a/swaybar/tray/tray.c b/swaybar/tray/tray.c index 9a709fe4..ca8b1341 100644 --- a/swaybar/tray/tray.c +++ b/swaybar/tray/tray.c | |||
@@ -2,12 +2,15 @@ | |||
2 | #include <unistd.h> | 2 | #include <unistd.h> |
3 | #include <stdlib.h> | 3 | #include <stdlib.h> |
4 | #include <string.h> | 4 | #include <string.h> |
5 | #include <sys/wait.h> | ||
5 | #include <dbus/dbus.h> | 6 | #include <dbus/dbus.h> |
6 | #include "swaybar/bar.h" | 7 | #include "swaybar/bar.h" |
7 | #include "swaybar/tray/tray.h" | 8 | #include "swaybar/tray/tray.h" |
8 | #include "swaybar/tray/dbus.h" | 9 | #include "swaybar/tray/dbus.h" |
9 | #include "swaybar/tray/sni.h" | 10 | #include "swaybar/tray/sni.h" |
11 | #include "swaybar/tray/sni_watcher.h" | ||
10 | #include "swaybar/bar.h" | 12 | #include "swaybar/bar.h" |
13 | #include "swaybar/config.h" | ||
11 | #include "list.h" | 14 | #include "list.h" |
12 | #include "log.h" | 15 | #include "log.h" |
13 | 16 | ||
@@ -184,7 +187,7 @@ static DBusHandlerResult signal_handler(DBusConnection *connection, | |||
184 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | 187 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
185 | } | 188 | } |
186 | 189 | ||
187 | int init_tray() { | 190 | static int init_host() { |
188 | tray = (struct tray *)malloc(sizeof(tray)); | 191 | tray = (struct tray *)malloc(sizeof(tray)); |
189 | 192 | ||
190 | tray->items = create_list(); | 193 | tray->items = create_list(); |
@@ -277,3 +280,129 @@ err: | |||
277 | free(name); | 280 | free(name); |
278 | return -1; | 281 | return -1; |
279 | } | 282 | } |
283 | |||
284 | void tray_mouse_event(struct output *output, int x, int y, | ||
285 | uint32_t button, uint32_t state) { | ||
286 | |||
287 | struct window *window = output->window; | ||
288 | uint32_t tray_padding = swaybar.config->tray_padding; | ||
289 | int tray_width = window->width * window->scale; | ||
290 | |||
291 | for (int i = 0; i < output->items->length; ++i) { | ||
292 | struct sni_icon_ref *item = | ||
293 | output->items->items[i]; | ||
294 | int icon_width = cairo_image_surface_get_width(item->icon); | ||
295 | |||
296 | tray_width -= tray_padding; | ||
297 | if (x <= tray_width && x >= tray_width - icon_width) { | ||
298 | if (button == swaybar.config->activate_button) { | ||
299 | sni_activate(item->ref, x, y); | ||
300 | } else if (button == swaybar.config->context_button) { | ||
301 | sni_context_menu(item->ref, x, y); | ||
302 | } else if (button == swaybar.config->secondary_button) { | ||
303 | sni_secondary(item->ref, x, y); | ||
304 | } | ||
305 | break; | ||
306 | } | ||
307 | tray_width -= icon_width; | ||
308 | } | ||
309 | } | ||
310 | |||
311 | uint32_t tray_render(struct output *output, struct config *config) { | ||
312 | struct window *window = output->window; | ||
313 | cairo_t *cairo = window->cairo; | ||
314 | |||
315 | // Tray icons | ||
316 | uint32_t tray_padding = config->tray_padding; | ||
317 | uint32_t tray_width = window->width * window->scale; | ||
318 | const int item_size = (window->height * window->scale) - (2 * tray_padding); | ||
319 | |||
320 | if (item_size < 0) { | ||
321 | // Can't render items if the padding is too large | ||
322 | return tray_width; | ||
323 | } | ||
324 | |||
325 | if (config->tray_output && strcmp(config->tray_output, output->name) != 0) { | ||
326 | return tray_width; | ||
327 | } | ||
328 | |||
329 | for (int i = 0; i < tray->items->length; ++i) { | ||
330 | struct StatusNotifierItem *item = | ||
331 | tray->items->items[i]; | ||
332 | if (!item->image) { | ||
333 | continue; | ||
334 | } | ||
335 | |||
336 | struct sni_icon_ref *render_item = NULL; | ||
337 | int j; | ||
338 | for (j = i; j < output->items->length; ++j) { | ||
339 | struct sni_icon_ref *ref = | ||
340 | output->items->items[j]; | ||
341 | if (ref->ref == item) { | ||
342 | render_item = ref; | ||
343 | break; | ||
344 | } else { | ||
345 | sni_icon_ref_free(ref); | ||
346 | list_del(output->items, j); | ||
347 | } | ||
348 | } | ||
349 | |||
350 | if (!render_item) { | ||
351 | render_item = sni_icon_ref_create(item, item_size); | ||
352 | list_add(output->items, render_item); | ||
353 | } else if (item->dirty) { | ||
354 | // item needs re-render | ||
355 | sni_icon_ref_free(render_item); | ||
356 | output->items->items[j] = render_item = | ||
357 | sni_icon_ref_create(item, item_size); | ||
358 | } | ||
359 | |||
360 | tray_width -= tray_padding; | ||
361 | tray_width -= item_size; | ||
362 | |||
363 | cairo_operator_t op = cairo_get_operator(cairo); | ||
364 | cairo_set_operator(cairo, CAIRO_OPERATOR_OVER); | ||
365 | cairo_set_source_surface(cairo, render_item->icon, tray_width, tray_padding); | ||
366 | cairo_rectangle(cairo, tray_width, tray_padding, item_size, item_size); | ||
367 | cairo_fill(cairo); | ||
368 | cairo_set_operator(cairo, op); | ||
369 | |||
370 | item->dirty = false; | ||
371 | } | ||
372 | |||
373 | |||
374 | if (tray_width != window->width * window->scale) { | ||
375 | tray_width -= tray_padding; | ||
376 | } | ||
377 | |||
378 | return tray_width; | ||
379 | } | ||
380 | |||
381 | void tray_upkeep(struct bar *bar) { | ||
382 | if (!bar->xembed_pid || | ||
383 | (bar->xembed_pid == waitpid(bar->xembed_pid, NULL, WNOHANG))) { | ||
384 | pid_t pid = fork(); | ||
385 | if (pid == 0) { | ||
386 | execlp("xembedsniproxy", "xembedsniproxy", NULL); | ||
387 | _exit(EXIT_FAILURE); | ||
388 | } else { | ||
389 | bar->xembed_pid = pid; | ||
390 | } | ||
391 | } | ||
392 | } | ||
393 | |||
394 | void init_tray(struct bar *bar) { | ||
395 | if (!bar->config->tray_output || strcmp(bar->config->tray_output, "none") != 0) { | ||
396 | /* Connect to the D-Bus */ | ||
397 | dbus_init(); | ||
398 | |||
399 | /* Start the SNI watcher */ | ||
400 | init_sni_watcher(); | ||
401 | |||
402 | /* Start the SNI host */ | ||
403 | init_host(); | ||
404 | |||
405 | /* Start xembedsniproxy */ | ||
406 | tray_upkeep(bar); | ||
407 | } | ||
408 | } | ||