diff options
Diffstat (limited to 'swaybar')
-rw-r--r-- | swaybar/bar.c | 125 | ||||
-rw-r--r-- | swaybar/config.c | 4 | ||||
-rw-r--r-- | swaybar/event_loop.c | 156 | ||||
-rw-r--r-- | swaybar/ipc.c | 128 | ||||
-rw-r--r-- | swaybar/main.c | 8 | ||||
-rw-r--r-- | swaybar/meson.build | 1 | ||||
-rw-r--r-- | swaybar/render.c | 32 | ||||
-rw-r--r-- | swaybar/status_line.c | 18 |
8 files changed, 231 insertions, 241 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 @@ #endif #include "swaybar/bar.h" #include "swaybar/config.h" -#include "swaybar/event_loop.h" #include "swaybar/i3bar.h" #include "swaybar/ipc.h" #include "swaybar/status_line.h" @@ -26,15 +25,28 @@ #include "ipc-client.h" #include "list.h" #include "log.h" +#include "loop.h" #include "pool-buffer.h" #include "wlr-layer-shell-unstable-v1-client-protocol.h" #include "xdg-output-unstable-v1-client-protocol.h" static void bar_init(struct swaybar *bar) { bar->config = init_config(); + bar->visible = true; wl_list_init(&bar->outputs); } +void free_hotspots(struct wl_list *list) { + struct swaybar_hotspot *hotspot, *tmp; + wl_list_for_each_safe(hotspot, tmp, list, link) { + wl_list_remove(&hotspot->link); + if (hotspot->destroy) { + hotspot->destroy(hotspot->data); + } + free(hotspot); + } +} + void free_workspaces(struct wl_list *list) { struct swaybar_workspace *ws, *tmp; wl_list_for_each_safe(ws, tmp, list, link) { @@ -59,14 +71,8 @@ static void swaybar_output_free(struct swaybar_output *output) { wl_output_destroy(output->output); destroy_buffer(&output->buffers[0]); destroy_buffer(&output->buffers[1]); + free_hotspots(&output->hotspots); free_workspaces(&output->workspaces); - struct swaybar_hotspot *hotspot, *hotspot_tmp; - wl_list_for_each_safe(hotspot, hotspot_tmp, &output->hotspots, link) { - if (hotspot->destroy) { - hotspot->destroy(hotspot->data); - } - free(hotspot); - } wl_list_remove(&output->link); free(output->name); free(output); @@ -75,9 +81,7 @@ static void swaybar_output_free(struct swaybar_output *output) { static void set_output_dirty(struct swaybar_output *output) { if (output->frame_scheduled) { output->dirty = true; - return; - } - if (output->surface) { + } else if (output->surface) { render_frame(output); } } @@ -335,21 +339,68 @@ const struct wl_seat_listener seat_listener = { }; static void add_layer_surface(struct swaybar_output *output) { - if (output->surface != NULL) { + if (output->layer_surface) { return; } struct swaybar *bar = output->bar; - output->surface = wl_compositor_create_surface(bar->compositor); - assert(output->surface); + struct swaybar_config *config = bar->config; + bool hidden = strcmp(config->mode, "hide") == 0; output->layer_surface = zwlr_layer_shell_v1_get_layer_surface( bar->layer_shell, output->surface, output->output, + hidden ? ZWLR_LAYER_SHELL_V1_LAYER_TOP : 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); + + zwlr_layer_surface_v1_set_anchor(output->layer_surface, config->position); + if (hidden) { + zwlr_layer_surface_v1_set_exclusive_zone(output->layer_surface, -1); + } +} + +static void destroy_layer_surface(struct swaybar_output *output) { + if (!output->layer_surface) { + return; + } + zwlr_layer_surface_v1_destroy(output->layer_surface); + wl_surface_attach(output->surface, NULL, 0, 0); // detach buffer + output->layer_surface = NULL; + output->width = 0; + output->frame_scheduled = false; +} + +bool determine_bar_visibility(struct swaybar *bar, bool moving_layer) { + struct swaybar_config *config = bar->config; + bool visible = !(strcmp(config->mode, "invisible") == 0 || + (strcmp(config->mode, config->hidden_state) == 0 // both "hide" + && !bar->visible_by_modifier && !bar->visible_by_urgency)); + + struct swaybar_output *output; + if (visible == bar->visible) { + if (visible && moving_layer) { + // need to destroy layer surface to move to a different layer + wl_list_for_each(output, &bar->outputs, link) { + destroy_layer_surface(output); + add_layer_surface(output); + } + } + } else { + bar->visible = visible; + wl_list_for_each(output, &bar->outputs, link) { + if (visible) { + add_layer_surface(output); + } else { + destroy_layer_surface(output); + } + } + wlr_log(WLR_DEBUG, "Sending %s signal to status command", + visible ? "cont" : "stop"); + kill(bar->status->pid, + visible ? bar->status->cont_signal : bar->status->stop_signal); + } + return visible; } static bool bar_uses_output(struct swaybar *bar, const char *name) { @@ -420,8 +471,11 @@ static void xdg_output_handle_done(void *data, wl_list_remove(&output->link); wl_list_insert(&bar->outputs, &output->link); - add_layer_surface(output); - set_output_dirty(output); + output->surface = wl_compositor_create_surface(bar->compositor); + assert(output->surface); + if (bar->visible) { + add_layer_surface(output); + } } } @@ -517,22 +571,26 @@ static void set_bar_dirty(struct swaybar *bar) { } } -bool bar_setup(struct swaybar *bar, - const char *socket_path, const char *bar_id) { +bool bar_setup(struct swaybar *bar, const char *socket_path) { bar_init(bar); - init_event_loop(); + bar->eventloop = loop_create(); bar->ipc_socketfd = ipc_open_socket(socket_path); bar->ipc_event_socketfd = ipc_open_socket(socket_path); - if (!ipc_initialize(bar, bar_id)) { + if (!ipc_initialize(bar)) { return false; } if (bar->config->status_command) { bar->status = status_line_init(bar->config->status_command); + bar->status->bar = bar; } bar->display = wl_display_connect(NULL); - assert(bar->display); + if (!bar->display) { + sway_abort("Unable to connect to the compositor. " + "If your compositor is running, check or set the " + "WAYLAND_DISPLAY environment variable."); + } struct wl_registry *registry = wl_display_get_registry(bar->display); wl_registry_add_listener(registry, ®istry_listener, bar); @@ -565,8 +623,11 @@ bool bar_setup(struct swaybar *bar, pointer->cursor_surface = wl_compositor_create_surface(bar->compositor); assert(pointer->cursor_surface); - ipc_get_workspaces(bar); - set_bar_dirty(bar); + if (bar->config->workspace_buttons) { + if (ipc_get_workspaces(bar)) { + set_bar_dirty(bar); + } + } return true; } @@ -590,21 +651,23 @@ static void status_in(int fd, short mask, void *data) { if (mask & (POLLHUP | POLLERR)) { status_error(bar->status, "[error reading from status command]"); set_bar_dirty(bar); - remove_event(fd); + loop_remove_fd(bar->eventloop, fd); } else if (status_handle_readable(bar->status)) { set_bar_dirty(bar); } } void bar_run(struct swaybar *bar) { - add_event(wl_display_get_fd(bar->display), POLLIN, display_in, bar); - add_event(bar->ipc_event_socketfd, POLLIN, ipc_in, bar); + loop_add_fd(bar->eventloop, wl_display_get_fd(bar->display), POLLIN, + display_in, bar); + loop_add_fd(bar->eventloop, bar->ipc_event_socketfd, POLLIN, ipc_in, bar); if (bar->status) { - add_event(bar->status->read_fd, POLLIN, status_in, bar); + loop_add_fd(bar->eventloop, bar->status->read_fd, POLLIN, + status_in, bar); } while (1) { wl_display_flush(bar->display); - event_loop_poll(); + loop_poll(bar->eventloop); } } @@ -625,4 +688,6 @@ void bar_teardown(struct swaybar *bar) { if (bar->status) { status_line_free(bar->status); } + free(bar->id); + free(bar->mode); } diff --git a/swaybar/config.c b/swaybar/config.c index 09d40c24..eafb0b69 100644 --- a/swaybar/config.c +++ b/swaybar/config.c @@ -30,7 +30,8 @@ struct swaybar_config *init_config(void) { config->pango_markup = false; config->position = parse_position("bottom"); config->font = strdup("monospace 10"); - config->mode = NULL; + config->mode = strdup("dock"); + config->hidden_state = strdup("hide"); config->sep_symbol = NULL; config->strip_workspace_numbers = false; config->binding_mode_indicator = true; @@ -84,6 +85,7 @@ void free_config(struct swaybar_config *config) { free(config->status_command); free(config->font); free(config->mode); + free(config->hidden_state); free(config->sep_symbol); for (int i = 0; i < config->bindings->length; i++) { struct swaybar_binding *binding = config->bindings->items[i]; diff --git a/swaybar/event_loop.c b/swaybar/event_loop.c deleted file mode 100644 index 686b9962..00000000 --- a/swaybar/event_loop.c +++ /dev/null @@ -1,156 +0,0 @@ -#define _XOPEN_SOURCE 700 -#include <stdlib.h> -#include <stdbool.h> -#include <string.h> -#include <strings.h> -#include <poll.h> -#include <time.h> -#include "swaybar/event_loop.h" -#include "list.h" - -struct event_item { - void (*cb)(int fd, short mask, void *data); - void *data; -}; - -struct timer_item { - timer_t timer; - void (*cb)(timer_t timer, void *data); - void *data; -}; - -static struct { - // The order of each must be kept consistent - struct { /* pollfd array */ - struct pollfd *items; - int capacity; - int length; - } fds; - list_t *items; /* event_item list */ - - // Timer list - list_t *timers; -} event_loop; - -void add_timer(timer_t timer, - void(*cb)(timer_t timer, void *data), - void *data) { - - struct timer_item *item = malloc(sizeof(struct timer_item)); - item->timer = timer; - item->cb = cb; - item->data = data; - - list_add(event_loop.timers, item); -} - -void add_event(int fd, short mask, - void(*cb)(int fd, short mask, void *data), void *data) { - - struct pollfd pollfd = { - fd, - mask, - 0, - }; - - // Resize - if (event_loop.fds.length == event_loop.fds.capacity) { - event_loop.fds.capacity += 10; - event_loop.fds.items = realloc(event_loop.fds.items, - sizeof(struct pollfd) * event_loop.fds.capacity); - } - - event_loop.fds.items[event_loop.fds.length++] = pollfd; - - struct event_item *item = malloc(sizeof(struct event_item)); - item->cb = cb; - item->data = data; - - list_add(event_loop.items, item); - - return; -} - -bool remove_event(int fd) { - /* - * Instead of removing events immediately, we mark them for deletion - * and clean them up later. This is so we can call remove_event inside - * an event callback safely. - */ - for (int i = 0; i < event_loop.fds.length; ++i) { - if (event_loop.fds.items[i].fd == fd) { - event_loop.fds.items[i].fd = -1; - return true; - } - } - return false; -} - -static int timer_item_timer_cmp(const void *_timer_item, const void *_timer) { - const struct timer_item *timer_item = _timer_item; - const timer_t *timer = _timer; - if (timer_item->timer == *timer) { - return 0; - } else { - return -1; - } -} -bool remove_timer(timer_t timer) { - int index = list_seq_find(event_loop.timers, timer_item_timer_cmp, &timer); - if (index != -1) { - free(event_loop.timers->items[index]); - list_del(event_loop.timers, index); - return true; - } - return false; -} - -void event_loop_poll(void) { - poll(event_loop.fds.items, event_loop.fds.length, -1); - - for (int i = 0; i < event_loop.fds.length; ++i) { - struct pollfd pfd = event_loop.fds.items[i]; - struct event_item *item = (struct event_item *)event_loop.items->items[i]; - - // Always send these events - unsigned events = pfd.events | POLLHUP | POLLERR; - - if (pfd.revents & events) { - item->cb(pfd.fd, pfd.revents, item->data); - } - } - - // Cleanup removed events - int end = 0; - int length = event_loop.fds.length; - for (int i = 0; i < length; ++i) { - if (event_loop.fds.items[i].fd == -1) { - free(event_loop.items->items[i]); - list_del(event_loop.items, i); - --event_loop.fds.length; - } else if (end != i) { - event_loop.fds.items[end++] = event_loop.fds.items[i]; - } else { - end = i + 1; - } - } - - // check timers - // not tested, but seems to work - for (int i = 0; i < event_loop.timers->length; ++i) { - struct timer_item *item = event_loop.timers->items[i]; - int overrun = timer_getoverrun(item->timer); - if (overrun && overrun != -1) { - item->cb(item->timer, item->data); - } - } -} - -void init_event_loop(void) { - event_loop.fds.length = 0; - event_loop.fds.capacity = 10; - event_loop.fds.items = malloc( - event_loop.fds.capacity * sizeof(struct pollfd)); - event_loop.items = create_list(); - event_loop.timers = create_list(); -} diff --git a/swaybar/ipc.c b/swaybar/ipc.c index a67814c1..e1b30b52 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c @@ -152,12 +152,12 @@ static bool ipc_parse_config( json_object_put(bar_config); return false; } - json_object *markup, *mode, *hidden_bar, *position, *status_command; + json_object *markup, *mode, *hidden_state, *position, *status_command; json_object *font, *bar_height, *wrap_scroll, *workspace_buttons, *strip_workspace_numbers; json_object *binding_mode_indicator, *verbose, *colors, *sep_symbol, *outputs; json_object *bindings; json_object_object_get_ex(bar_config, "mode", &mode); - json_object_object_get_ex(bar_config, "hidden_bar", &hidden_bar); + json_object_object_get_ex(bar_config, "hidden_state", &hidden_state); json_object_object_get_ex(bar_config, "position", &position); json_object_object_get_ex(bar_config, "status_command", &status_command); json_object_object_get_ex(bar_config, "font", &font); @@ -220,6 +220,14 @@ static bool ipc_parse_config( list_add(config->bindings, binding); } } + if (hidden_state) { + free(config->hidden_state); + config->hidden_state = strdup(json_object_get_string(hidden_state)); + } + if (mode) { + free(config->mode); + config->mode = strdup(json_object_get_string(mode)); + } struct config_output *output, *tmp; wl_list_for_each_safe(output, tmp, &config->outputs, link) { @@ -254,7 +262,7 @@ static bool ipc_parse_config( return true; } -void ipc_get_workspaces(struct swaybar *bar) { +bool ipc_get_workspaces(struct swaybar *bar) { struct swaybar_output *output; wl_list_for_each(output, &bar->outputs, link) { free_workspaces(&output->workspaces); @@ -266,8 +274,10 @@ void ipc_get_workspaces(struct swaybar *bar) { json_object *results = json_tokener_parse(res); if (!results) { free(res); - return; + return false; } + + bar->visible_by_urgency = false; size_t length = json_object_array_length(results); json_object *ws_json; json_object *num, *name, *visible, *focused, *out, *urgent; @@ -294,12 +304,16 @@ void ipc_get_workspaces(struct swaybar *bar) { output->focused = true; } ws->urgent = json_object_get_boolean(urgent); + if (ws->urgent) { + bar->visible_by_urgency = true; + } wl_list_insert(&output->workspaces, &ws->link); } } } json_object_put(results); free(res); + return determine_bar_visibility(bar, false); } static void ipc_get_outputs(struct swaybar *bar) { @@ -345,10 +359,10 @@ void ipc_execute_binding(struct swaybar *bar, struct swaybar_binding *bind) { IPC_COMMAND, bind->command, &len)); } -bool ipc_initialize(struct swaybar *bar, const char *bar_id) { - uint32_t len = strlen(bar_id); +bool ipc_initialize(struct swaybar *bar) { + uint32_t len = strlen(bar->id); char *res = ipc_single_command(bar->ipc_socketfd, - IPC_GET_BAR_CONFIG, bar_id, &len); + IPC_GET_BAR_CONFIG, bar->id, &len); if (!ipc_parse_config(bar->config, res)) { free(res); return false; @@ -356,56 +370,108 @@ bool ipc_initialize(struct swaybar *bar, const char *bar_id) { free(res); ipc_get_outputs(bar); - const char *subscribe = "[ \"workspace\", \"mode\" ]"; - len = strlen(subscribe); + struct swaybar_config *config = bar->config; + char subscribe[128]; // suitably large buffer + len = snprintf(subscribe, 128, + "[ \"barconfig_update\" , \"bar_state_update\" %s %s ]", + config->binding_mode_indicator ? ", \"mode\"" : "", + config->workspace_buttons ? ", \"workspace\"" : ""); free(ipc_single_command(bar->ipc_event_socketfd, IPC_SUBSCRIBE, subscribe, &len)); return true; } +static bool handle_bar_state_update(struct swaybar *bar, json_object *event) { + json_object *json_id; + json_object_object_get_ex(event, "id", &json_id); + const char *id = json_object_get_string(json_id); + if (strcmp(id, bar->id) != 0) { + return false; + } + + json_object *visible_by_modifier; + json_object_object_get_ex(event, "visible_by_modifier", &visible_by_modifier); + bar->visible_by_modifier = json_object_get_boolean(visible_by_modifier); + return determine_bar_visibility(bar, false); +} + +static bool handle_barconfig_update(struct swaybar *bar, + json_object *json_config) { + json_object *json_id; + json_object_object_get_ex(json_config, "id", &json_id); + const char *id = json_object_get_string(json_id); + if (strcmp(id, bar->id) != 0) { + return false; + } + + struct swaybar_config *config = bar->config; + + json_object *json_state; + json_object_object_get_ex(json_config, "hidden_state", &json_state); + const char *new_state = json_object_get_string(json_state); + char *old_state = config->hidden_state; + if (strcmp(new_state, old_state) != 0) { + wlr_log(WLR_DEBUG, "Changing bar hidden state to %s", new_state); + free(old_state); + config->hidden_state = strdup(new_state); + return determine_bar_visibility(bar, false); + } + + free(config->mode); + json_object *json_mode; + json_object_object_get_ex(json_config, "mode", &json_mode); + config->mode = strdup(json_object_get_string(json_mode)); + wlr_log(WLR_DEBUG, "Changing bar mode to %s", config->mode); + + return determine_bar_visibility(bar, true); +} + bool handle_ipc_readable(struct swaybar *bar) { struct ipc_response *resp = ipc_recv_response(bar->ipc_event_socketfd); if (!resp) { return false; } + + json_object *result = json_tokener_parse(resp->payload); + if (!result) { + wlr_log(WLR_ERROR, "failed to parse payload as json"); + free_ipc_response(resp); + return false; + } + + bool bar_is_dirty = true; switch (resp->type) { case IPC_EVENT_WORKSPACE: - ipc_get_workspaces(bar); + bar_is_dirty = ipc_get_workspaces(bar); break; case IPC_EVENT_MODE: { - json_object *result = json_tokener_parse(resp->payload); - if (!result) { - free_ipc_response(resp); - wlr_log(WLR_ERROR, "failed to parse payload as json"); - return false; - } json_object *json_change, *json_pango_markup; if (json_object_object_get_ex(result, "change", &json_change)) { const char *change = json_object_get_string(json_change); - free(bar->config->mode); - if (strcmp(change, "default") == 0) { - bar->config->mode = NULL; - } else { - bar->config->mode = strdup(change); - } + free(bar->mode); + bar->mode = strcmp(change, "default") != 0 ? strdup(change) : NULL; } else { wlr_log(WLR_ERROR, "failed to parse response"); - json_object_put(result); - free_ipc_response(resp); - return false; + bar_is_dirty = false; + break; } if (json_object_object_get_ex(result, "pango_markup", &json_pango_markup)) { - bar->config->mode_pango_markup = json_object_get_boolean( - json_pango_markup); + bar->mode_pango_markup = json_object_get_boolean(json_pango_markup); } - json_object_put(result); break; } + case IPC_EVENT_BARCONFIG_UPDATE: + bar_is_dirty = handle_barconfig_update(bar, result); + break; + case IPC_EVENT_BAR_STATE_UPDATE: + bar_is_dirty = handle_bar_state_update(bar, result); + break; default: - free_ipc_response(resp); - return false; + bar_is_dirty = false; + break; } + json_object_put(result); free_ipc_response(resp); - return true; + return bar_is_dirty; } diff --git a/swaybar/main.c b/swaybar/main.c index db204f4a..2672abef 100644 --- a/swaybar/main.c +++ b/swaybar/main.c @@ -22,7 +22,6 @@ void sway_terminate(int code) { int main(int argc, char **argv) { char *socket_path = NULL; - char *bar_id = NULL; bool debug = false; static struct option long_options[] = { @@ -59,7 +58,7 @@ int main(int argc, char **argv) { socket_path = strdup(optarg); break; case 'b': // Type - bar_id = strdup(optarg); + swaybar.id = strdup(optarg); break; case 'v': fprintf(stdout, "swaybar version " SWAY_VERSION "\n"); @@ -80,7 +79,7 @@ int main(int argc, char **argv) { wlr_log_init(WLR_ERROR, NULL); } - if (!bar_id) { + if (!swaybar.id) { wlr_log(WLR_ERROR, "No bar_id passed. " "Provide --bar_id or let sway start swaybar"); return 1; @@ -96,13 +95,12 @@ int main(int argc, char **argv) { signal(SIGTERM, sig_handler); - if (!bar_setup(&swaybar, socket_path, bar_id)) { + if (!bar_setup(&swaybar, socket_path)) { free(socket_path); return 1; } free(socket_path); - free(bar_id); bar_run(&swaybar); bar_teardown(&swaybar); diff --git a/swaybar/meson.build b/swaybar/meson.build index 7a02a33f..0c116172 100644 --- a/swaybar/meson.build +++ b/swaybar/meson.build @@ -2,7 +2,6 @@ executable( 'swaybar', [ 'bar.c', 'config.c', - 'event_loop.c', 'i3bar.c', 'ipc.c', 'main.c', diff --git a/swaybar/render.c b/swaybar/render.c index dc31a5ea..097eb462 100644 --- a/swaybar/render.c +++ b/swaybar/render.c @@ -296,11 +296,15 @@ static uint32_t render_status_line(cairo_t *cairo, static uint32_t render_binding_mode_indicator(cairo_t *cairo, struct swaybar_output *output, double x) { + const char *mode = output->bar->mode; + if (!mode) { + return 0; + } + struct swaybar_config *config = output->bar->config; - const char *mode = config->mode; int text_width, text_height; get_text_size(cairo, config->font, &text_width, &text_height, NULL, - output->scale, config->mode_pango_markup, + output->scale, output->bar->mode_pango_markup, "%s", mode); int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale; @@ -333,8 +337,8 @@ static uint32_t render_binding_mode_indicator(cairo_t *cairo, double text_y = height / 2.0 - text_height / 2.0; cairo_set_source_u32(cairo, config->colors.binding_mode.text); cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y)); - pango_printf(cairo, config->font, output->scale, config->mode_pango_markup, - "%s", mode); + pango_printf(cairo, config->font, output->scale, + output->bar->mode_pango_markup, "%s", mode); return output->height; } @@ -465,7 +469,7 @@ static uint32_t render_to_cairo(cairo_t *cairo, struct swaybar_output *output) { max_height = h > max_height ? h : max_height; } } - if (config->binding_mode_indicator && config->mode) { + if (config->binding_mode_indicator) { uint32_t h = render_binding_mode_indicator(cairo, output, x); max_height = h > max_height ? h : max_height; } @@ -490,16 +494,12 @@ static const struct wl_callback_listener output_frame_listener = { void render_frame(struct swaybar_output *output) { assert(output->surface != NULL); - - struct swaybar_hotspot *hotspot, *tmp; - wl_list_for_each_safe(hotspot, tmp, &output->hotspots, link) { - if (hotspot->destroy) { - hotspot->destroy(hotspot->data); - } - wl_list_remove(&hotspot->link); - free(hotspot); + if (!output->layer_surface) { + return; } + free_hotspots(&output->hotspots); + cairo_surface_t *recorder = cairo_recording_surface_create( CAIRO_CONTENT_COLOR_ALPHA, NULL); cairo_t *cairo = cairo_create(recorder); @@ -519,10 +519,12 @@ void render_frame(struct swaybar_output *output) { if (config_height >= 0 && height < (uint32_t)config_height) { height = config_height; } - if (height != output->height) { + if (height != output->height || output->width == 0) { // Reconfigure surface zwlr_layer_surface_v1_set_size(output->layer_surface, 0, height); - zwlr_layer_surface_v1_set_exclusive_zone(output->layer_surface, height); + if (strcmp(output->bar->config->mode, "dock") == 0) { + zwlr_layer_surface_v1_set_exclusive_zone(output->layer_surface, height); + } // TODO: this could infinite loop if the compositor assigns us a // different height than what we asked for wl_surface_commit(output->surface); diff --git a/swaybar/status_line.c b/swaybar/status_line.c index ed6dc7c8..65d6c052 100644 --- a/swaybar/status_line.c +++ b/swaybar/status_line.c @@ -7,16 +7,16 @@ #include <stdio.h> #include <unistd.h> #include <wlr/util/log.h> +#include "loop.h" #include "swaybar/bar.h" #include "swaybar/config.h" #include "swaybar/i3bar.h" -#include "swaybar/event_loop.h" #include "swaybar/status_line.h" #include "readline.h" static void status_line_close_fds(struct status_line *status) { if (status->read_fd != -1) { - remove_event(status->read_fd); + loop_remove_fd(status->bar->eventloop, status->read_fd); close(status->read_fd); status->read_fd = -1; } @@ -83,6 +83,17 @@ bool status_handle_readable(struct status_line *status) { return true; } } + + json_object *signal; + if (json_object_object_get_ex(header, "stop_signal", &signal)) { + status->stop_signal = json_object_get_int(signal); + wlr_log(WLR_DEBUG, "Setting stop signal to %d", status->stop_signal); + } + if (json_object_object_get_ex(header, "cont_signal", &signal)) { + status->cont_signal = json_object_get_int(signal); + wlr_log(WLR_DEBUG, "Setting cont signal to %d", status->cont_signal); + } + json_object_put(header); wl_list_init(&status->blocks); @@ -121,6 +132,9 @@ bool status_handle_readable(struct status_line *status) { struct status_line *status_line_init(char *cmd) { struct status_line *status = calloc(1, sizeof(struct status_line)); + status->stop_signal = SIGSTOP; + status->cont_signal = SIGCONT; + status->buffer_size = 8192; status->buffer = malloc(status->buffer_size); |