diff options
Diffstat (limited to 'swaybar/bar.c')
-rw-r--r-- | swaybar/bar.c | 161 |
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 | ||
75 | static 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 | |||
69 | static void layer_surface_configure(void *data, | 85 | static 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 | ||
79 | static void layer_surface_closed(void *_output, | 95 | static 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 | ||
286 | static void output_geometry(void *data, struct wl_output *output, int32_t x, | 302 | static 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 | |||
320 | static 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 | |||
333 | static 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 | ||
292 | static void output_mode(void *data, struct wl_output *output, uint32_t flags, | 340 | static 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 | ||
297 | static void output_done(void *data, struct wl_output *output) { | 345 | static 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 | ||
301 | static void output_scale(void *data, struct wl_output *wl_output, | 350 | static 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 | ||
310 | struct wl_output_listener output_listener = { | 356 | struct wl_output_listener output_listener = { |
@@ -326,7 +372,22 @@ static void xdg_output_handle_logical_size(void *data, | |||
326 | 372 | ||
327 | static void xdg_output_handle_done(void *data, | 373 | static 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 | ||
332 | static void xdg_output_handle_name(void *data, | 393 | static 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 | ||
352 | static bool bar_uses_output(struct swaybar *bar, const char *name) { | 413 | static 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 | ||
365 | static void handle_global(void *data, struct wl_registry *registry, | 424 | static 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 | ||
416 | static void render_all_frames(struct swaybar *bar) { | 478 | static 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 | ||
423 | void bar_setup(struct swaybar *bar, | 485 | bool 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 | ||
498 | static void display_in(int fd, short mask, void *data) { | 538 | static void display_in(int fd, short mask, void *data) { |
@@ -506,7 +546,7 @@ static void display_in(int fd, short mask, void *data) { | |||
506 | static void ipc_in(int fd, short mask, void *data) { | 546 | static 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 | ||