aboutsummaryrefslogtreecommitdiffstats
path: root/swaybar/bar.c
diff options
context:
space:
mode:
Diffstat (limited to 'swaybar/bar.c')
-rw-r--r--swaybar/bar.c125
1 files changed, 95 insertions, 30 deletions
diff --git a/swaybar/bar.c b/swaybar/bar.c
index 5b7fea71..0deba72d 100644
--- a/swaybar/bar.c
+++ b/swaybar/bar.c
@@ -18,7 +18,6 @@
18#endif 18#endif
19#include "swaybar/bar.h" 19#include "swaybar/bar.h"
20#include "swaybar/config.h" 20#include "swaybar/config.h"
21#include "swaybar/event_loop.h"
22#include "swaybar/i3bar.h" 21#include "swaybar/i3bar.h"
23#include "swaybar/ipc.h" 22#include "swaybar/ipc.h"
24#include "swaybar/status_line.h" 23#include "swaybar/status_line.h"
@@ -26,15 +25,28 @@
26#include "ipc-client.h" 25#include "ipc-client.h"
27#include "list.h" 26#include "list.h"
28#include "log.h" 27#include "log.h"
28#include "loop.h"
29#include "pool-buffer.h" 29#include "pool-buffer.h"
30#include "wlr-layer-shell-unstable-v1-client-protocol.h" 30#include "wlr-layer-shell-unstable-v1-client-protocol.h"
31#include "xdg-output-unstable-v1-client-protocol.h" 31#include "xdg-output-unstable-v1-client-protocol.h"
32 32
33static void bar_init(struct swaybar *bar) { 33static void bar_init(struct swaybar *bar) {
34 bar->config = init_config(); 34 bar->config = init_config();
35 bar->visible = true;
35 wl_list_init(&bar->outputs); 36 wl_list_init(&bar->outputs);
36} 37}
37 38
39void free_hotspots(struct wl_list *list) {
40 struct swaybar_hotspot *hotspot, *tmp;
41 wl_list_for_each_safe(hotspot, tmp, list, link) {
42 wl_list_remove(&hotspot->link);
43 if (hotspot->destroy) {
44 hotspot->destroy(hotspot->data);
45 }
46 free(hotspot);
47 }
48}
49
38void free_workspaces(struct wl_list *list) { 50void free_workspaces(struct wl_list *list) {
39 struct swaybar_workspace *ws, *tmp; 51 struct swaybar_workspace *ws, *tmp;
40 wl_list_for_each_safe(ws, tmp, list, link) { 52 wl_list_for_each_safe(ws, tmp, list, link) {
@@ -59,14 +71,8 @@ static void swaybar_output_free(struct swaybar_output *output) {
59 wl_output_destroy(output->output); 71 wl_output_destroy(output->output);
60 destroy_buffer(&output->buffers[0]); 72 destroy_buffer(&output->buffers[0]);
61 destroy_buffer(&output->buffers[1]); 73 destroy_buffer(&output->buffers[1]);
74 free_hotspots(&output->hotspots);
62 free_workspaces(&output->workspaces); 75 free_workspaces(&output->workspaces);
63 struct swaybar_hotspot *hotspot, *hotspot_tmp;
64 wl_list_for_each_safe(hotspot, hotspot_tmp, &output->hotspots, link) {
65 if (hotspot->destroy) {
66 hotspot->destroy(hotspot->data);
67 }
68 free(hotspot);
69 }
70 wl_list_remove(&output->link); 76 wl_list_remove(&output->link);
71 free(output->name); 77 free(output->name);
72 free(output); 78 free(output);
@@ -75,9 +81,7 @@ static void swaybar_output_free(struct swaybar_output *output) {
75static void set_output_dirty(struct swaybar_output *output) { 81static void set_output_dirty(struct swaybar_output *output) {
76 if (output->frame_scheduled) { 82 if (output->frame_scheduled) {
77 output->dirty = true; 83 output->dirty = true;
78 return; 84 } else if (output->surface) {
79 }
80 if (output->surface) {
81 render_frame(output); 85 render_frame(output);
82 } 86 }
83} 87}
@@ -335,21 +339,68 @@ const struct wl_seat_listener seat_listener = {
335}; 339};
336 340
337static void add_layer_surface(struct swaybar_output *output) { 341static void add_layer_surface(struct swaybar_output *output) {
338 if (output->surface != NULL) { 342 if (output->layer_surface) {
339 return; 343 return;
340 } 344 }
341 struct swaybar *bar = output->bar; 345 struct swaybar *bar = output->bar;
342 346
343 output->surface = wl_compositor_create_surface(bar->compositor); 347 struct swaybar_config *config = bar->config;
344 assert(output->surface); 348 bool hidden = strcmp(config->mode, "hide") == 0;
345 output->layer_surface = zwlr_layer_shell_v1_get_layer_surface( 349 output->layer_surface = zwlr_layer_shell_v1_get_layer_surface(
346 bar->layer_shell, output->surface, output->output, 350 bar->layer_shell, output->surface, output->output,
351 hidden ? ZWLR_LAYER_SHELL_V1_LAYER_TOP :
347 ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "panel"); 352 ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "panel");
348 assert(output->layer_surface); 353 assert(output->layer_surface);
349 zwlr_layer_surface_v1_add_listener(output->layer_surface, 354 zwlr_layer_surface_v1_add_listener(output->layer_surface,
350 &layer_surface_listener, output); 355 &layer_surface_listener, output);
351 zwlr_layer_surface_v1_set_anchor(output->layer_surface, 356
352 bar->config->position); 357 zwlr_layer_surface_v1_set_anchor(output->layer_surface, config->position);
358 if (hidden) {
359 zwlr_layer_surface_v1_set_exclusive_zone(output->layer_surface, -1);
360 }
361}
362
363static void destroy_layer_surface(struct swaybar_output *output) {
364 if (!output->layer_surface) {
365 return;
366 }
367 zwlr_layer_surface_v1_destroy(output->layer_surface);
368 wl_surface_attach(output->surface, NULL, 0, 0); // detach buffer
369 output->layer_surface = NULL;
370 output->width = 0;
371 output->frame_scheduled = false;
372}
373
374bool determine_bar_visibility(struct swaybar *bar, bool moving_layer) {
375 struct swaybar_config *config = bar->config;
376 bool visible = !(strcmp(config->mode, "invisible") == 0 ||
377 (strcmp(config->mode, config->hidden_state) == 0 // both "hide"
378 && !bar->visible_by_modifier && !bar->visible_by_urgency));
379
380 struct swaybar_output *output;
381 if (visible == bar->visible) {
382 if (visible && moving_layer) {
383 // need to destroy layer surface to move to a different layer
384 wl_list_for_each(output, &bar->outputs, link) {
385 destroy_layer_surface(output);
386 add_layer_surface(output);
387 }
388 }
389 } else {
390 bar->visible = visible;
391 wl_list_for_each(output, &bar->outputs, link) {
392 if (visible) {
393 add_layer_surface(output);
394 } else {
395 destroy_layer_surface(output);
396 }
397 }
398 wlr_log(WLR_DEBUG, "Sending %s signal to status command",
399 visible ? "cont" : "stop");
400 kill(bar->status->pid,
401 visible ? bar->status->cont_signal : bar->status->stop_signal);
402 }
403 return visible;
353} 404}
354 405
355static bool bar_uses_output(struct swaybar *bar, const char *name) { 406static bool bar_uses_output(struct swaybar *bar, const char *name) {
@@ -420,8 +471,11 @@ static void xdg_output_handle_done(void *data,
420 wl_list_remove(&output->link); 471 wl_list_remove(&output->link);
421 wl_list_insert(&bar->outputs, &output->link); 472 wl_list_insert(&bar->outputs, &output->link);
422 473
423 add_layer_surface(output); 474 output->surface = wl_compositor_create_surface(bar->compositor);
424 set_output_dirty(output); 475 assert(output->surface);
476 if (bar->visible) {
477 add_layer_surface(output);
478 }
425 } 479 }
426} 480}
427 481
@@ -517,22 +571,26 @@ static void set_bar_dirty(struct swaybar *bar) {
517 } 571 }
518} 572}
519 573
520bool bar_setup(struct swaybar *bar, 574bool bar_setup(struct swaybar *bar, const char *socket_path) {
521 const char *socket_path, const char *bar_id) {
522 bar_init(bar); 575 bar_init(bar);
523 init_event_loop(); 576 bar->eventloop = loop_create();
524 577
525 bar->ipc_socketfd = ipc_open_socket(socket_path); 578 bar->ipc_socketfd = ipc_open_socket(socket_path);
526 bar->ipc_event_socketfd = ipc_open_socket(socket_path); 579 bar->ipc_event_socketfd = ipc_open_socket(socket_path);
527 if (!ipc_initialize(bar, bar_id)) { 580 if (!ipc_initialize(bar)) {
528 return false; 581 return false;
529 } 582 }
530 if (bar->config->status_command) { 583 if (bar->config->status_command) {
531 bar->status = status_line_init(bar->config->status_command); 584 bar->status = status_line_init(bar->config->status_command);
585 bar->status->bar = bar;
532 } 586 }
533 587
534 bar->display = wl_display_connect(NULL); 588 bar->display = wl_display_connect(NULL);
535 assert(bar->display); 589 if (!bar->display) {
590 sway_abort("Unable to connect to the compositor. "
591 "If your compositor is running, check or set the "
592 "WAYLAND_DISPLAY environment variable.");
593 }
536 594
537 struct wl_registry *registry = wl_display_get_registry(bar->display); 595 struct wl_registry *registry = wl_display_get_registry(bar->display);
538 wl_registry_add_listener(registry, &registry_listener, bar); 596 wl_registry_add_listener(registry, &registry_listener, bar);
@@ -565,8 +623,11 @@ bool bar_setup(struct swaybar *bar,
565 pointer->cursor_surface = wl_compositor_create_surface(bar->compositor); 623 pointer->cursor_surface = wl_compositor_create_surface(bar->compositor);
566 assert(pointer->cursor_surface); 624 assert(pointer->cursor_surface);
567 625
568 ipc_get_workspaces(bar); 626 if (bar->config->workspace_buttons) {
569 set_bar_dirty(bar); 627 if (ipc_get_workspaces(bar)) {
628 set_bar_dirty(bar);
629 }
630 }
570 return true; 631 return true;
571} 632}
572 633
@@ -590,21 +651,23 @@ static void status_in(int fd, short mask, void *data) {
590 if (mask & (POLLHUP | POLLERR)) { 651 if (mask & (POLLHUP | POLLERR)) {
591 status_error(bar->status, "[error reading from status command]"); 652 status_error(bar->status, "[error reading from status command]");
592 set_bar_dirty(bar); 653 set_bar_dirty(bar);
593 remove_event(fd); 654 loop_remove_fd(bar->eventloop, fd);
594 } else if (status_handle_readable(bar->status)) { 655 } else if (status_handle_readable(bar->status)) {
595 set_bar_dirty(bar); 656 set_bar_dirty(bar);
596 } 657 }
597} 658}
598 659
599void bar_run(struct swaybar *bar) { 660void bar_run(struct swaybar *bar) {
600 add_event(wl_display_get_fd(bar->display), POLLIN, display_in, bar); 661 loop_add_fd(bar->eventloop, wl_display_get_fd(bar->display), POLLIN,
601 add_event(bar->ipc_event_socketfd, POLLIN, ipc_in, bar); 662 display_in, bar);
663 loop_add_fd(bar->eventloop, bar->ipc_event_socketfd, POLLIN, ipc_in, bar);
602 if (bar->status) { 664 if (bar->status) {
603 add_event(bar->status->read_fd, POLLIN, status_in, bar); 665 loop_add_fd(bar->eventloop, bar->status->read_fd, POLLIN,
666 status_in, bar);
604 } 667 }
605 while (1) { 668 while (1) {
606 wl_display_flush(bar->display); 669 wl_display_flush(bar->display);
607 event_loop_poll(); 670 loop_poll(bar->eventloop);
608 } 671 }
609} 672}
610 673
@@ -625,4 +688,6 @@ void bar_teardown(struct swaybar *bar) {
625 if (bar->status) { 688 if (bar->status) {
626 status_line_free(bar->status); 689 status_line_free(bar->status);
627 } 690 }
691 free(bar->id);
692 free(bar->mode);
628} 693}