summaryrefslogtreecommitdiffstats
path: root/swaybar/bar.c
diff options
context:
space:
mode:
Diffstat (limited to 'swaybar/bar.c')
-rw-r--r--swaybar/bar.c161
1 files changed, 101 insertions, 60 deletions
diff --git a/swaybar/bar.c b/swaybar/bar.c
index 3ae730f7..388c24c4 100644
--- a/swaybar/bar.c
+++ b/swaybar/bar.c
@@ -16,12 +16,13 @@
16#else 16#else
17#include <linux/input-event-codes.h> 17#include <linux/input-event-codes.h>
18#endif 18#endif
19#include "swaybar/render.h" 19#include "swaybar/bar.h"
20#include "swaybar/config.h" 20#include "swaybar/config.h"
21#include "swaybar/event_loop.h" 21#include "swaybar/event_loop.h"
22#include "swaybar/status_line.h" 22#include "swaybar/i3bar.h"
23#include "swaybar/bar.h"
24#include "swaybar/ipc.h" 23#include "swaybar/ipc.h"
24#include "swaybar/status_line.h"
25#include "swaybar/render.h"
25#include "ipc-client.h" 26#include "ipc-client.h"
26#include "list.h" 27#include "list.h"
27#include "log.h" 28#include "log.h"
@@ -48,8 +49,13 @@ static void swaybar_output_free(struct swaybar_output *output) {
48 return; 49 return;
49 } 50 }
50 wlr_log(WLR_DEBUG, "Removing output %s", output->name); 51 wlr_log(WLR_DEBUG, "Removing output %s", output->name);
51 zwlr_layer_surface_v1_destroy(output->layer_surface); 52 if (output->layer_surface != NULL) {
52 wl_surface_destroy(output->surface); 53 zwlr_layer_surface_v1_destroy(output->layer_surface);
54 }
55 if (output->surface != NULL) {
56 wl_surface_destroy(output->surface);
57 }
58 zxdg_output_v1_destroy(output->xdg_output);
53 wl_output_destroy(output->output); 59 wl_output_destroy(output->output);
54 destroy_buffer(&output->buffers[0]); 60 destroy_buffer(&output->buffers[0]);
55 destroy_buffer(&output->buffers[1]); 61 destroy_buffer(&output->buffers[1]);
@@ -66,6 +72,16 @@ static void swaybar_output_free(struct swaybar_output *output) {
66 free(output); 72 free(output);
67} 73}
68 74
75static void set_output_dirty(struct swaybar_output *output) {
76 if (output->frame_scheduled) {
77 output->dirty = true;
78 return;
79 }
80 if (output->surface) {
81 render_frame(output);
82 }
83}
84
69static void layer_surface_configure(void *data, 85static void layer_surface_configure(void *data,
70 struct zwlr_layer_surface_v1 *surface, 86 struct zwlr_layer_surface_v1 *surface,
71 uint32_t serial, uint32_t width, uint32_t height) { 87 uint32_t serial, uint32_t width, uint32_t height) {
@@ -73,7 +89,7 @@ static void layer_surface_configure(void *data,
73 output->width = width; 89 output->width = width;
74 output->height = height; 90 output->height = height;
75 zwlr_layer_surface_v1_ack_configure(surface, serial); 91 zwlr_layer_surface_v1_ack_configure(surface, serial);
76 render_frame(output->bar, output); 92 set_output_dirty(output);
77} 93}
78 94
79static void layer_surface_closed(void *_output, 95static void layer_surface_closed(void *_output,
@@ -283,28 +299,58 @@ const struct wl_seat_listener seat_listener = {
283 .name = seat_handle_name, 299 .name = seat_handle_name,
284}; 300};
285 301
286static void output_geometry(void *data, struct wl_output *output, int32_t x, 302static void add_layer_surface(struct swaybar_output *output) {
303 if (output->surface != NULL) {
304 return;
305 }
306 struct swaybar *bar = output->bar;
307
308 output->surface = wl_compositor_create_surface(bar->compositor);
309 assert(output->surface);
310 output->layer_surface = zwlr_layer_shell_v1_get_layer_surface(
311 bar->layer_shell, output->surface, output->output,
312 ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "panel");
313 assert(output->layer_surface);
314 zwlr_layer_surface_v1_add_listener(output->layer_surface,
315 &layer_surface_listener, output);
316 zwlr_layer_surface_v1_set_anchor(output->layer_surface,
317 bar->config->position);
318}
319
320static bool bar_uses_output(struct swaybar *bar, const char *name) {
321 if (bar->config->all_outputs) {
322 return true;
323 }
324 struct config_output *coutput;
325 wl_list_for_each(coutput, &bar->config->outputs, link) {
326 if (strcmp(coutput->name, name) == 0) {
327 return true;
328 }
329 }
330 return false;
331}
332
333static void output_geometry(void *data, struct wl_output *wl_output, int32_t x,
287 int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, 334 int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel,
288 const char *make, const char *model, int32_t transform) { 335 const char *make, const char *model, int32_t transform) {
289 // Who cares 336 struct swaybar_output *output = data;
337 output->subpixel = subpixel;
290} 338}
291 339
292static void output_mode(void *data, struct wl_output *output, uint32_t flags, 340static void output_mode(void *data, struct wl_output *wl_output, uint32_t flags,
293 int32_t width, int32_t height, int32_t refresh) { 341 int32_t width, int32_t height, int32_t refresh) {
294 // Who cares 342 // Who cares
295} 343}
296 344
297static void output_done(void *data, struct wl_output *output) { 345static void output_done(void *data, struct wl_output *wl_output) {
298 // Who cares 346 struct swaybar_output *output = data;
347 set_output_dirty(output);
299} 348}
300 349
301static void output_scale(void *data, struct wl_output *wl_output, 350static void output_scale(void *data, struct wl_output *wl_output,
302 int32_t factor) { 351 int32_t factor) {
303 struct swaybar_output *output = data; 352 struct swaybar_output *output = data;
304 output->scale = factor; 353 output->scale = factor;
305 if (output->surface) {
306 render_frame(output->bar, output);
307 }
308} 354}
309 355
310struct wl_output_listener output_listener = { 356struct wl_output_listener output_listener = {
@@ -326,7 +372,22 @@ static void xdg_output_handle_logical_size(void *data,
326 372
327static void xdg_output_handle_done(void *data, 373static void xdg_output_handle_done(void *data,
328 struct zxdg_output_v1 *xdg_output) { 374 struct zxdg_output_v1 *xdg_output) {
329 // Who cares 375 struct swaybar_output *output = data;
376 struct swaybar *bar = output->bar;
377
378 assert(output->name != NULL);
379 if (!bar_uses_output(bar, output->name)) {
380 swaybar_output_free(output);
381 return;
382 }
383
384 if (wl_list_empty(&output->link)) {
385 wl_list_remove(&output->link);
386 wl_list_insert(&bar->outputs, &output->link);
387
388 add_layer_surface(output);
389 set_output_dirty(output);
390 }
330} 391}
331 392
332static void xdg_output_handle_name(void *data, 393static void xdg_output_handle_name(void *data,
@@ -349,17 +410,15 @@ struct zxdg_output_v1_listener xdg_output_listener = {
349 .description = xdg_output_handle_description, 410 .description = xdg_output_handle_description,
350}; 411};
351 412
352static bool bar_uses_output(struct swaybar *bar, const char *name) { 413static void add_xdg_output(struct swaybar_output *output) {
353 if (bar->config->all_outputs) { 414 if (output->xdg_output != NULL) {
354 return true; 415 return;
355 }
356 struct config_output *coutput;
357 wl_list_for_each(coutput, &bar->config->outputs, link) {
358 if (strcmp(coutput->name, name) == 0) {
359 return true;
360 }
361 } 416 }
362 return false; 417 assert(output->bar->xdg_output_manager != NULL);
418 output->xdg_output = zxdg_output_manager_v1_get_xdg_output(
419 output->bar->xdg_output_manager, output->output);
420 zxdg_output_v1_add_listener(output->xdg_output, &xdg_output_listener,
421 output);
363} 422}
364 423
365static void handle_global(void *data, struct wl_registry *registry, 424static void handle_global(void *data, struct wl_registry *registry,
@@ -386,7 +445,10 @@ static void handle_global(void *data, struct wl_registry *registry,
386 output->wl_name = name; 445 output->wl_name = name;
387 wl_list_init(&output->workspaces); 446 wl_list_init(&output->workspaces);
388 wl_list_init(&output->hotspots); 447 wl_list_init(&output->hotspots);
389 wl_list_insert(&bar->outputs, &output->link); 448 wl_list_init(&output->link);
449 if (bar->xdg_output_manager != NULL) {
450 add_xdg_output(output);
451 }
390 } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { 452 } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
391 bar->layer_shell = wl_registry_bind( 453 bar->layer_shell = wl_registry_bind(
392 registry, name, &zwlr_layer_shell_v1_interface, 1); 454 registry, name, &zwlr_layer_shell_v1_interface, 1);
@@ -413,21 +475,23 @@ static const struct wl_registry_listener registry_listener = {
413 .global_remove = handle_global_remove, 475 .global_remove = handle_global_remove,
414}; 476};
415 477
416static void render_all_frames(struct swaybar *bar) { 478static void set_bar_dirty(struct swaybar *bar) {
417 struct swaybar_output *output; 479 struct swaybar_output *output;
418 wl_list_for_each(output, &bar->outputs, link) { 480 wl_list_for_each(output, &bar->outputs, link) {
419 render_frame(bar, output); 481 set_output_dirty(output);
420 } 482 }
421} 483}
422 484
423void bar_setup(struct swaybar *bar, 485bool bar_setup(struct swaybar *bar,
424 const char *socket_path, const char *bar_id) { 486 const char *socket_path, const char *bar_id) {
425 bar_init(bar); 487 bar_init(bar);
426 init_event_loop(); 488 init_event_loop();
427 489
428 bar->ipc_socketfd = ipc_open_socket(socket_path); 490 bar->ipc_socketfd = ipc_open_socket(socket_path);
429 bar->ipc_event_socketfd = ipc_open_socket(socket_path); 491 bar->ipc_event_socketfd = ipc_open_socket(socket_path);
430 ipc_initialize(bar, bar_id); 492 if (!ipc_initialize(bar, bar_id)) {
493 return false;
494 }
431 if (bar->config->status_command) { 495 if (bar->config->status_command) {
432 bar->status = status_line_init(bar->config->status_command); 496 bar->status = status_line_init(bar->config->status_command);
433 } 497 }
@@ -443,23 +507,10 @@ void bar_setup(struct swaybar *bar,
443 507
444 struct swaybar_output *output; 508 struct swaybar_output *output;
445 wl_list_for_each(output, &bar->outputs, link) { 509 wl_list_for_each(output, &bar->outputs, link) {
446 output->xdg_output = zxdg_output_manager_v1_get_xdg_output( 510 add_xdg_output(output);
447 bar->xdg_output_manager, output->output);
448 zxdg_output_v1_add_listener(output->xdg_output, &xdg_output_listener,
449 output);
450 } 511 }
451 wl_display_roundtrip(bar->display); 512 wl_display_roundtrip(bar->display);
452 513
453 struct swaybar_output *output_tmp;
454 wl_list_for_each_safe(output, output_tmp, &bar->outputs, link) {
455 if (!bar_uses_output(bar, output->name)) {
456 zxdg_output_v1_destroy(output->xdg_output);
457 wl_output_destroy(output->output);
458 wl_list_remove(&output->link);
459 free(output);
460 }
461 }
462
463 struct swaybar_pointer *pointer = &bar->pointer; 514 struct swaybar_pointer *pointer = &bar->pointer;
464 515
465 int max_scale = 1; 516 int max_scale = 1;
@@ -479,20 +530,9 @@ void bar_setup(struct swaybar *bar,
479 pointer->cursor_surface = wl_compositor_create_surface(bar->compositor); 530 pointer->cursor_surface = wl_compositor_create_surface(bar->compositor);
480 assert(pointer->cursor_surface); 531 assert(pointer->cursor_surface);
481 532
482 wl_list_for_each(output, &bar->outputs, link) {
483 output->surface = wl_compositor_create_surface(bar->compositor);
484 assert(output->surface);
485 output->layer_surface = zwlr_layer_shell_v1_get_layer_surface(
486 bar->layer_shell, output->surface, output->output,
487 ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "panel");
488 assert(output->layer_surface);
489 zwlr_layer_surface_v1_add_listener(output->layer_surface,
490 &layer_surface_listener, output);
491 zwlr_layer_surface_v1_set_anchor(output->layer_surface,
492 bar->config->position);
493 }
494 ipc_get_workspaces(bar); 533 ipc_get_workspaces(bar);
495 render_all_frames(bar); 534 set_bar_dirty(bar);
535 return true;
496} 536}
497 537
498static void display_in(int fd, short mask, void *data) { 538static void display_in(int fd, short mask, void *data) {
@@ -506,7 +546,7 @@ static void display_in(int fd, short mask, void *data) {
506static void ipc_in(int fd, short mask, void *data) { 546static void ipc_in(int fd, short mask, void *data) {
507 struct swaybar *bar = data; 547 struct swaybar *bar = data;
508 if (handle_ipc_readable(bar)) { 548 if (handle_ipc_readable(bar)) {
509 render_all_frames(bar); 549 set_bar_dirty(bar);
510 } 550 }
511} 551}
512 552
@@ -514,10 +554,10 @@ static void status_in(int fd, short mask, void *data) {
514 struct swaybar *bar = data; 554 struct swaybar *bar = data;
515 if (mask & (POLLHUP | POLLERR)) { 555 if (mask & (POLLHUP | POLLERR)) {
516 status_error(bar->status, "[error reading from status command]"); 556 status_error(bar->status, "[error reading from status command]");
517 render_all_frames(bar); 557 set_bar_dirty(bar);
518 remove_event(fd); 558 remove_event(fd);
519 } else if (status_handle_readable(bar->status)) { 559 } else if (status_handle_readable(bar->status)) {
520 render_all_frames(bar); 560 set_bar_dirty(bar);
521 } 561 }
522} 562}
523 563
@@ -529,6 +569,7 @@ void bar_run(struct swaybar *bar) {
529 } 569 }
530 while (1) { 570 while (1) {
531 event_loop_poll(); 571 event_loop_poll();
572 wl_display_flush(bar->display);
532 } 573 }
533} 574}
534 575