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 @@ #else #include <linux/input-event-codes.h> #endif -#include "swaybar/render.h" +#include "swaybar/bar.h" #include "swaybar/config.h" #include "swaybar/event_loop.h" -#include "swaybar/status_line.h" -#include "swaybar/bar.h" +#include "swaybar/i3bar.h" #include "swaybar/ipc.h" +#include "swaybar/status_line.h" +#include "swaybar/render.h" #include "ipc-client.h" #include "list.h" #include "log.h" @@ -48,8 +49,13 @@ static void swaybar_output_free(struct swaybar_output *output) { return; } wlr_log(WLR_DEBUG, "Removing output %s", output->name); - zwlr_layer_surface_v1_destroy(output->layer_surface); - wl_surface_destroy(output->surface); + if (output->layer_surface != NULL) { + zwlr_layer_surface_v1_destroy(output->layer_surface); + } + if (output->surface != NULL) { + wl_surface_destroy(output->surface); + } + zxdg_output_v1_destroy(output->xdg_output); wl_output_destroy(output->output); destroy_buffer(&output->buffers[0]); destroy_buffer(&output->buffers[1]); @@ -66,6 +72,16 @@ static void swaybar_output_free(struct swaybar_output *output) { free(output); } +static void set_output_dirty(struct swaybar_output *output) { + if (output->frame_scheduled) { + output->dirty = true; + return; + } + if (output->surface) { + render_frame(output); + } +} + static void layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, uint32_t serial, uint32_t width, uint32_t height) { @@ -73,7 +89,7 @@ static void layer_surface_configure(void *data, output->width = width; output->height = height; zwlr_layer_surface_v1_ack_configure(surface, serial); - render_frame(output->bar, output); + set_output_dirty(output); } static void layer_surface_closed(void *_output, @@ -283,28 +299,58 @@ const struct wl_seat_listener seat_listener = { .name = seat_handle_name, }; -static void output_geometry(void *data, struct wl_output *output, int32_t x, +static void add_layer_surface(struct swaybar_output *output) { + if (output->surface != NULL) { + return; + } + struct swaybar *bar = output->bar; + + output->surface = wl_compositor_create_surface(bar->compositor); + assert(output->surface); + output->layer_surface = zwlr_layer_shell_v1_get_layer_surface( + bar->layer_shell, output->surface, output->output, + ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "panel"); + assert(output->layer_surface); + zwlr_layer_surface_v1_add_listener(output->layer_surface, + &layer_surface_listener, output); + zwlr_layer_surface_v1_set_anchor(output->layer_surface, + bar->config->position); +} + +static bool bar_uses_output(struct swaybar *bar, const char *name) { + if (bar->config->all_outputs) { + return true; + } + struct config_output *coutput; + wl_list_for_each(coutput, &bar->config->outputs, link) { + if (strcmp(coutput->name, name) == 0) { + return true; + } + } + return false; +} + +static void output_geometry(void *data, struct wl_output *wl_output, int32_t x, int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, const char *make, const char *model, int32_t transform) { - // Who cares + struct swaybar_output *output = data; + output->subpixel = subpixel; } -static void output_mode(void *data, struct wl_output *output, uint32_t flags, +static void output_mode(void *data, struct wl_output *wl_output, uint32_t flags, int32_t width, int32_t height, int32_t refresh) { // Who cares } -static void output_done(void *data, struct wl_output *output) { - // Who cares +static void output_done(void *data, struct wl_output *wl_output) { + struct swaybar_output *output = data; + set_output_dirty(output); } static void output_scale(void *data, struct wl_output *wl_output, int32_t factor) { struct swaybar_output *output = data; output->scale = factor; - if (output->surface) { - render_frame(output->bar, output); - } } struct wl_output_listener output_listener = { @@ -326,7 +372,22 @@ static void xdg_output_handle_logical_size(void *data, static void xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output) { - // Who cares + struct swaybar_output *output = data; + struct swaybar *bar = output->bar; + + assert(output->name != NULL); + if (!bar_uses_output(bar, output->name)) { + swaybar_output_free(output); + return; + } + + if (wl_list_empty(&output->link)) { + wl_list_remove(&output->link); + wl_list_insert(&bar->outputs, &output->link); + + add_layer_surface(output); + set_output_dirty(output); + } } static void xdg_output_handle_name(void *data, @@ -349,17 +410,15 @@ struct zxdg_output_v1_listener xdg_output_listener = { .description = xdg_output_handle_description, }; -static bool bar_uses_output(struct swaybar *bar, const char *name) { - if (bar->config->all_outputs) { - return true; - } - struct config_output *coutput; - wl_list_for_each(coutput, &bar->config->outputs, link) { - if (strcmp(coutput->name, name) == 0) { - return true; - } +static void add_xdg_output(struct swaybar_output *output) { + if (output->xdg_output != NULL) { + return; } - return false; + assert(output->bar->xdg_output_manager != NULL); + output->xdg_output = zxdg_output_manager_v1_get_xdg_output( + output->bar->xdg_output_manager, output->output); + zxdg_output_v1_add_listener(output->xdg_output, &xdg_output_listener, + output); } static void handle_global(void *data, struct wl_registry *registry, @@ -386,7 +445,10 @@ static void handle_global(void *data, struct wl_registry *registry, output->wl_name = name; wl_list_init(&output->workspaces); wl_list_init(&output->hotspots); - wl_list_insert(&bar->outputs, &output->link); + wl_list_init(&output->link); + if (bar->xdg_output_manager != NULL) { + add_xdg_output(output); + } } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { bar->layer_shell = wl_registry_bind( registry, name, &zwlr_layer_shell_v1_interface, 1); @@ -413,21 +475,23 @@ static const struct wl_registry_listener registry_listener = { .global_remove = handle_global_remove, }; -static void render_all_frames(struct swaybar *bar) { +static void set_bar_dirty(struct swaybar *bar) { struct swaybar_output *output; wl_list_for_each(output, &bar->outputs, link) { - render_frame(bar, output); + set_output_dirty(output); } } -void bar_setup(struct swaybar *bar, +bool bar_setup(struct swaybar *bar, const char *socket_path, const char *bar_id) { bar_init(bar); init_event_loop(); bar->ipc_socketfd = ipc_open_socket(socket_path); bar->ipc_event_socketfd = ipc_open_socket(socket_path); - ipc_initialize(bar, bar_id); + if (!ipc_initialize(bar, bar_id)) { + return false; + } if (bar->config->status_command) { bar->status = status_line_init(bar->config->status_command); } @@ -443,23 +507,10 @@ void bar_setup(struct swaybar *bar, struct swaybar_output *output; wl_list_for_each(output, &bar->outputs, link) { - output->xdg_output = zxdg_output_manager_v1_get_xdg_output( - bar->xdg_output_manager, output->output); - zxdg_output_v1_add_listener(output->xdg_output, &xdg_output_listener, - output); + add_xdg_output(output); } wl_display_roundtrip(bar->display); - struct swaybar_output *output_tmp; - wl_list_for_each_safe(output, output_tmp, &bar->outputs, link) { - if (!bar_uses_output(bar, output->name)) { - zxdg_output_v1_destroy(output->xdg_output); - wl_output_destroy(output->output); - wl_list_remove(&output->link); - free(output); - } - } - struct swaybar_pointer *pointer = &bar->pointer; int max_scale = 1; @@ -479,20 +530,9 @@ void bar_setup(struct swaybar *bar, pointer->cursor_surface = wl_compositor_create_surface(bar->compositor); assert(pointer->cursor_surface); - wl_list_for_each(output, &bar->outputs, link) { - output->surface = wl_compositor_create_surface(bar->compositor); - assert(output->surface); - output->layer_surface = zwlr_layer_shell_v1_get_layer_surface( - bar->layer_shell, output->surface, output->output, - ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "panel"); - assert(output->layer_surface); - zwlr_layer_surface_v1_add_listener(output->layer_surface, - &layer_surface_listener, output); - zwlr_layer_surface_v1_set_anchor(output->layer_surface, - bar->config->position); - } ipc_get_workspaces(bar); - render_all_frames(bar); + set_bar_dirty(bar); + return true; } static void display_in(int fd, short mask, void *data) { @@ -506,7 +546,7 @@ static void display_in(int fd, short mask, void *data) { static void ipc_in(int fd, short mask, void *data) { struct swaybar *bar = data; if (handle_ipc_readable(bar)) { - render_all_frames(bar); + set_bar_dirty(bar); } } @@ -514,10 +554,10 @@ static void status_in(int fd, short mask, void *data) { struct swaybar *bar = data; if (mask & (POLLHUP | POLLERR)) { status_error(bar->status, "[error reading from status command]"); - render_all_frames(bar); + set_bar_dirty(bar); remove_event(fd); } else if (status_handle_readable(bar->status)) { - render_all_frames(bar); + set_bar_dirty(bar); } } @@ -529,6 +569,7 @@ void bar_run(struct swaybar *bar) { } while (1) { event_loop_poll(); + wl_display_flush(bar->display); } } |