From 1f90f92f45580adfbe4ce363181331c182f3f341 Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Sun, 30 Sep 2018 23:06:40 +0100 Subject: [PATCH 01/14] commands: fix sending bar mode/hidden_state updates to all bars Previously, if a change was sent to all bars, it would only actually change the first bar it encountered, due to return value handling --- sway/commands/bar/hidden_state.c | 34 ++++++++++++++------------------ sway/commands/bar/mode.c | 34 ++++++++++++++------------------ 2 files changed, 30 insertions(+), 38 deletions(-) diff --git a/sway/commands/bar/hidden_state.c b/sway/commands/bar/hidden_state.c index 502ce2c41..28adf6c7a 100644 --- a/sway/commands/bar/hidden_state.c +++ b/sway/commands/bar/hidden_state.c @@ -32,7 +32,7 @@ static struct cmd_results *bar_set_hidden_state(struct bar_config *bar, } // free old mode free(old_state); - return cmd_results_new(CMD_SUCCESS, NULL, NULL); + return NULL; } struct cmd_results *bar_cmd_hidden_state(int argc, char **argv) { @@ -50,24 +50,20 @@ struct cmd_results *bar_cmd_hidden_state(int argc, char **argv) { const char *state = argv[0]; if (config->reading) { - return bar_set_hidden_state(config->current_bar, state); - } - - const char *id = NULL; - if (argc == 2) { - id = argv[1]; - } - struct bar_config *bar; - for (int i = 0; i < config->bars->length; ++i) { - bar = config->bars->items[i]; - if (id && strcmp(id, bar->id) == 0) { - return bar_set_hidden_state(bar, state); - } - - error = bar_set_hidden_state(bar, state); - if (error) { - return error; + error = bar_set_hidden_state(config->current_bar, state); + } else { + const char *id = argc == 2 ? argv[1] : NULL; + for (int i = 0; i < config->bars->length; ++i) { + struct bar_config *bar = config->bars->items[i]; + if (id) { + if (strcmp(id, bar->id) == 0) { + error = bar_set_hidden_state(bar, state); + break; + } + } else if ((error = bar_set_hidden_state(bar, state))) { + break; + } } } - return cmd_results_new(CMD_SUCCESS, NULL, NULL); + return error ? error : cmd_results_new(CMD_SUCCESS, NULL, NULL); } diff --git a/sway/commands/bar/mode.c b/sway/commands/bar/mode.c index 28e2d77bf..dbdd38970 100644 --- a/sway/commands/bar/mode.c +++ b/sway/commands/bar/mode.c @@ -33,7 +33,7 @@ static struct cmd_results *bar_set_mode(struct bar_config *bar, const char *mode // free old mode free(old_mode); - return cmd_results_new(CMD_SUCCESS, NULL, NULL); + return NULL; } struct cmd_results *bar_cmd_mode(int argc, char **argv) { @@ -51,24 +51,20 @@ struct cmd_results *bar_cmd_mode(int argc, char **argv) { const char *mode = argv[0]; if (config->reading) { - return bar_set_mode(config->current_bar, mode); - } - - const char *id = NULL; - if (argc == 2) { - id = argv[1]; - } - - struct bar_config *bar; - for (int i = 0; i < config->bars->length; ++i) { - bar = config->bars->items[i]; - if (id && strcmp(id, bar->id) == 0) { - return bar_set_mode(bar, mode); - } - error = bar_set_mode(bar, mode); - if (error) { - return error; + error = bar_set_mode(config->current_bar, mode); + } else { + const char *id = argc == 2 ? argv[1] : NULL; + for (int i = 0; i < config->bars->length; ++i) { + struct bar_config *bar = config->bars->items[i]; + if (id) { + if (strcmp(id, bar->id) == 0) { + error = bar_set_mode(bar, mode); + break; + } + } else if ((error = bar_set_mode(bar, mode))) { + break; + } } } - return cmd_results_new(CMD_SUCCESS, NULL, NULL); + return error ? error : cmd_results_new(CMD_SUCCESS, NULL, NULL); } From d0b54e932b59baa71b54d842b249400db74ce79b Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Sun, 30 Sep 2018 15:09:09 +0100 Subject: [PATCH 02/14] swaybar: save id upon startup This adds an id property to the bar, which will be used to filter barconfig_update events --- include/swaybar/bar.h | 4 +++- include/swaybar/ipc.h | 2 +- swaybar/bar.c | 6 +++--- swaybar/ipc.c | 6 +++--- swaybar/main.c | 8 +++----- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/swaybar/bar.h b/include/swaybar/bar.h index de2341118..d29db31e5 100644 --- a/include/swaybar/bar.h +++ b/include/swaybar/bar.h @@ -46,6 +46,8 @@ struct swaybar_hotspot { }; struct swaybar { + char *id; + struct wl_display *display; struct wl_compositor *compositor; struct zwlr_layer_shell_v1 *layer_shell; @@ -96,7 +98,7 @@ struct swaybar_workspace { bool urgent; }; -bool bar_setup(struct swaybar *bar, const char *socket_path, const char *bar_id); +bool bar_setup(struct swaybar *bar, const char *socket_path); void bar_run(struct swaybar *bar); void bar_teardown(struct swaybar *bar); diff --git a/include/swaybar/ipc.h b/include/swaybar/ipc.h index 8731dac2a..51db85b55 100644 --- a/include/swaybar/ipc.h +++ b/include/swaybar/ipc.h @@ -3,7 +3,7 @@ #include #include "swaybar/bar.h" -bool ipc_initialize(struct swaybar *bar, const char *bar_id); +bool ipc_initialize(struct swaybar *bar); bool handle_ipc_readable(struct swaybar *bar); void ipc_get_workspaces(struct swaybar *bar); void ipc_send_workspace_command(struct swaybar *bar, const char *ws); diff --git a/swaybar/bar.c b/swaybar/bar.c index 5b7fea717..f2dab7383 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -517,14 +517,13 @@ 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->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) { @@ -625,4 +624,5 @@ void bar_teardown(struct swaybar *bar) { if (bar->status) { status_line_free(bar->status); } + free(bar->id); } diff --git a/swaybar/ipc.c b/swaybar/ipc.c index a67814c11..84046ab57 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c @@ -345,10 +345,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; diff --git a/swaybar/main.c b/swaybar/main.c index db204f4a8..2672abefc 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); From 18eaf452245d47461070894b4324d2afa47b0b05 Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Sat, 6 Oct 2018 19:02:12 +0100 Subject: [PATCH 03/14] swaybar: annotate wl_list properties in definitions --- include/swaybar/bar.h | 12 ++++++------ include/swaybar/config.h | 2 +- include/swaybar/i3bar.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/swaybar/bar.h b/include/swaybar/bar.h index d29db31e5..3c1a236d1 100644 --- a/include/swaybar/bar.h +++ b/include/swaybar/bar.h @@ -37,7 +37,7 @@ enum hotspot_event_handling { }; struct swaybar_hotspot { - struct wl_list link; + struct wl_list link; // swaybar_output::hotspots int x, y, width, height; enum hotspot_event_handling (*callback)(struct swaybar_output *output, int x, int y, enum x11_button button, void *data); @@ -62,11 +62,11 @@ struct swaybar { int ipc_event_socketfd; int ipc_socketfd; - struct wl_list outputs; + struct wl_list outputs; // swaybar_output::link }; struct swaybar_output { - struct wl_list link; + struct wl_list link; // swaybar::outputs struct swaybar *bar; struct wl_output *output; struct zxdg_output_v1 *xdg_output; @@ -74,8 +74,8 @@ struct swaybar_output { struct zwlr_layer_surface_v1 *layer_surface; uint32_t wl_name; - struct wl_list workspaces; - struct wl_list hotspots; + struct wl_list workspaces; // swaybar_workspace::link + struct wl_list hotspots; // swaybar_hotspot::link char *name; bool focused; @@ -90,7 +90,7 @@ struct swaybar_output { }; struct swaybar_workspace { - struct wl_list link; + struct wl_list link; // swaybar_output::workspaces int num; char *name; bool focused; diff --git a/include/swaybar/config.h b/include/swaybar/config.h index d0336c27d..999484637 100644 --- a/include/swaybar/config.h +++ b/include/swaybar/config.h @@ -13,7 +13,7 @@ struct box_colors { }; struct config_output { - struct wl_list link; + struct wl_list link; // swaybar_config::outputs char *name; size_t index; }; diff --git a/include/swaybar/i3bar.h b/include/swaybar/i3bar.h index 12d9b3174..d4a48e073 100644 --- a/include/swaybar/i3bar.h +++ b/include/swaybar/i3bar.h @@ -5,7 +5,7 @@ #include "status_line.h" struct i3bar_block { - struct wl_list link; + struct wl_list link; // status_link::blocks int ref_count; char *full_text, *short_text, *align; bool urgent; From a67fa8a05d010d488b821a7d6e91db5905f7a123 Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Sun, 30 Sep 2018 15:09:55 +0100 Subject: [PATCH 04/14] swaybar: only subscribe to required events This adds barconfig_update to the list of subscribed events, as well as checking when the other events need to be subscribed to. --- swaybar/ipc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/swaybar/ipc.c b/swaybar/ipc.c index 84046ab57..26b7eca65 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c @@ -356,8 +356,12 @@ bool ipc_initialize(struct swaybar *bar) { 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\" %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; From 19f0bf38640f4da609782442c901366617aa27fa Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Fri, 12 Oct 2018 20:18:04 +0100 Subject: [PATCH 05/14] swaybar: add free_hotspots helper function --- include/swaybar/bar.h | 1 + swaybar/bar.c | 23 +++++++++++++---------- swaybar/render.c | 9 +-------- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/include/swaybar/bar.h b/include/swaybar/bar.h index 3c1a236d1..72e0ca75f 100644 --- a/include/swaybar/bar.h +++ b/include/swaybar/bar.h @@ -102,6 +102,7 @@ bool bar_setup(struct swaybar *bar, const char *socket_path); void bar_run(struct swaybar *bar); void bar_teardown(struct swaybar *bar); +void free_hotspots(struct wl_list *list); void free_workspaces(struct wl_list *list); #endif diff --git a/swaybar/bar.c b/swaybar/bar.c index f2dab7383..e6c5f2f19 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -35,6 +35,17 @@ static void bar_init(struct swaybar *bar) { 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 +70,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 +80,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); } } diff --git a/swaybar/render.c b/swaybar/render.c index dc31a5ea5..2a06a79b1 100644 --- a/swaybar/render.c +++ b/swaybar/render.c @@ -491,14 +491,7 @@ 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); - } + free_hotspots(&output->hotspots); cairo_surface_t *recorder = cairo_recording_surface_create( CAIRO_CONTENT_COLOR_ALPHA, NULL); From a388ffa12776cfad11c13f0bc0b60a5face38a9b Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Fri, 12 Oct 2018 21:17:32 +0100 Subject: [PATCH 06/14] swaybar: only send initial workspace request if workspace buttons are enabled --- swaybar/bar.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/swaybar/bar.c b/swaybar/bar.c index e6c5f2f19..ecf1bf82d 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -567,8 +567,11 @@ bool bar_setup(struct swaybar *bar, const char *socket_path) { 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; } From fed11d1c7b388e999414dd8cec4b8982ba5ce950 Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Fri, 12 Oct 2018 20:23:01 +0100 Subject: [PATCH 07/14] swaybar: move mode & mode_pango_markup to bar struct This distinguishes the binding mode from the distinct config mode, as well as removing mode_pango_markup from the config struct where it should not be present. --- include/swaybar/bar.h | 2 ++ include/swaybar/config.h | 1 - swaybar/bar.c | 1 + swaybar/ipc.c | 11 +++-------- swaybar/render.c | 14 +++++++++----- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/include/swaybar/bar.h b/include/swaybar/bar.h index 72e0ca75f..593f4f6d7 100644 --- a/include/swaybar/bar.h +++ b/include/swaybar/bar.h @@ -47,6 +47,8 @@ struct swaybar_hotspot { struct swaybar { char *id; + char *mode; + bool mode_pango_markup; struct wl_display *display; struct wl_compositor *compositor; diff --git a/include/swaybar/config.h b/include/swaybar/config.h index 999484637..68ee2087e 100644 --- a/include/swaybar/config.h +++ b/include/swaybar/config.h @@ -31,7 +31,6 @@ struct swaybar_config { char *font; char *sep_symbol; char *mode; - bool mode_pango_markup; bool strip_workspace_numbers; bool binding_mode_indicator; bool wrap_scroll; diff --git a/swaybar/bar.c b/swaybar/bar.c index ecf1bf82d..772941360 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -631,4 +631,5 @@ void bar_teardown(struct swaybar *bar) { status_line_free(bar->status); } free(bar->id); + free(bar->mode); } diff --git a/swaybar/ipc.c b/swaybar/ipc.c index 26b7eca65..8568f9572 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c @@ -386,12 +386,8 @@ bool handle_ipc_readable(struct swaybar *bar) { 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); @@ -400,8 +396,7 @@ bool handle_ipc_readable(struct swaybar *bar) { } 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; diff --git a/swaybar/render.c b/swaybar/render.c index 2a06a79b1..d226ba322 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; } From 55ca16f2d83f4d7e14635ac4de3eb67ee2a0787e Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Fri, 12 Oct 2018 20:28:04 +0100 Subject: [PATCH 08/14] swaybar: streamline ipc handling The received json is handled outside of the case statement, which will allow better extensibility. This commit also introduces the variable bar_is_dirty, the return value signifying whether the bar requires rendering. --- swaybar/ipc.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/swaybar/ipc.c b/swaybar/ipc.c index 8568f9572..6013c2deb 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c @@ -372,17 +372,20 @@ bool handle_ipc_readable(struct swaybar *bar) { 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); 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); @@ -390,21 +393,20 @@ bool handle_ipc_readable(struct swaybar *bar) { 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->mode_pango_markup = json_object_get_boolean(json_pango_markup); } - json_object_put(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; } From bcc61e5147fb57a3b4bfb9a2a33065a0cf6da67b Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Fri, 12 Oct 2018 20:32:48 +0100 Subject: [PATCH 09/14] swaybar: handle mode/hidden_state changes As well as adding the hidden_state property to the bar config struct, this commit handles barconfig_update events when the mode or hidden_state changes, and uses a new function determine_bar_visibility to hide or show the bar as required, using, respectively, destroy_layer_surface, which is also newly added, and add_layer_surface, which has been changed to allow dynamically adding the surface. --- include/swaybar/bar.h | 18 ++++++++++++ include/swaybar/config.h | 1 + swaybar/bar.c | 62 +++++++++++++++++++++++++++++++++++----- swaybar/config.c | 4 ++- swaybar/ipc.c | 46 +++++++++++++++++++++++++++-- swaybar/render.c | 7 ++++- 6 files changed, 127 insertions(+), 11 deletions(-) diff --git a/include/swaybar/bar.h b/include/swaybar/bar.h index 593f4f6d7..9ff3fe7bd 100644 --- a/include/swaybar/bar.h +++ b/include/swaybar/bar.h @@ -50,6 +50,11 @@ struct swaybar { char *mode; bool mode_pango_markup; + // only relevant when bar is in "hide" mode + bool visible_by_modifier; + bool visible_by_urgency; + bool visible; + struct wl_display *display; struct wl_compositor *compositor; struct zwlr_layer_shell_v1 *layer_shell; @@ -104,6 +109,19 @@ bool bar_setup(struct swaybar *bar, const char *socket_path); void bar_run(struct swaybar *bar); void bar_teardown(struct swaybar *bar); +/* + * Determines whether the bar should be visible and changes it to be so. + * If the current visibility of the bar is the different to what it should be, + * then it adds or destroys the layer surface as required, + * as well as sending the cont or stop signal to the status command. + * If the current visibility of the bar is already what it should be, + * then this function is a no-op, unless moving_layer is true, which occurs + * when the bar changes from "hide" to "dock" mode or vice versa, and the bar + * needs to be destroyed and re-added in order to change its layer. + * + * Returns true if the bar is now visible, otherwise false. + */ +bool determine_bar_visibility(struct swaybar *bar, bool moving_layer); void free_hotspots(struct wl_list *list); void free_workspaces(struct wl_list *list); diff --git a/include/swaybar/config.h b/include/swaybar/config.h index 68ee2087e..10904bca0 100644 --- a/include/swaybar/config.h +++ b/include/swaybar/config.h @@ -31,6 +31,7 @@ struct swaybar_config { char *font; char *sep_symbol; char *mode; + char *hidden_state; bool strip_workspace_numbers; bool binding_mode_indicator; bool wrap_scroll; diff --git a/swaybar/bar.c b/swaybar/bar.c index 772941360..6894383de 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -32,6 +32,7 @@ static void bar_init(struct swaybar *bar) { bar->config = init_config(); + bar->visible = true; wl_list_init(&bar->outputs); } @@ -338,21 +339,65 @@ 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->height = 0; + 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); + } + } + } + return visible; } static bool bar_uses_output(struct swaybar *bar, const char *name) { @@ -423,8 +468,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); + } } } diff --git a/swaybar/config.c b/swaybar/config.c index 09d40c249..eafb0b691 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/ipc.c b/swaybar/ipc.c index 6013c2deb..56379fdb9 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) { @@ -367,6 +375,37 @@ bool ipc_initialize(struct swaybar *bar) { return true; } +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) { @@ -402,6 +441,9 @@ bool handle_ipc_readable(struct swaybar *bar) { } break; } + case IPC_EVENT_BARCONFIG_UPDATE: + bar_is_dirty = handle_barconfig_update(bar, result); + break; default: bar_is_dirty = false; break; diff --git a/swaybar/render.c b/swaybar/render.c index d226ba322..670630cf7 100644 --- a/swaybar/render.c +++ b/swaybar/render.c @@ -494,6 +494,9 @@ static const struct wl_callback_listener output_frame_listener = { void render_frame(struct swaybar_output *output) { assert(output->surface != NULL); + if (!output->layer_surface) { + return; + } free_hotspots(&output->hotspots); @@ -519,7 +522,9 @@ void render_frame(struct swaybar_output *output) { if (height != output->height) { // 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); From 2f1fd8072673b1824f37759e14f5388d7a87fb5c Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Fri, 12 Oct 2018 21:14:52 +0100 Subject: [PATCH 10/14] swaybar: show hidden bar on key event Since wayland does not currently allow swaybar to create global keybinds, this is handled within sway and sent to the bar using a custom event, so as not to pollute existing events, called bar_state_update. --- include/ipc.h | 3 +++ include/sway/config.h | 1 + include/sway/ipc-server.h | 1 + include/swaybar/config.h | 1 + sway/config/bar.c | 2 ++ sway/input/keyboard.c | 28 ++++++++++++++++++++++------ sway/ipc-server.c | 18 ++++++++++++++++++ swaybar/ipc.c | 19 ++++++++++++++++++- 8 files changed, 66 insertions(+), 7 deletions(-) diff --git a/include/ipc.h b/include/ipc.h index a3f60e193..9063b9337 100644 --- a/include/ipc.h +++ b/include/ipc.h @@ -30,6 +30,9 @@ enum ipc_command_type { IPC_EVENT_BINDING = ((1<<31) | 5), IPC_EVENT_SHUTDOWN = ((1<<31) | 6), IPC_EVENT_TICK = ((1<<31) | 7), + + // sway-specific event types + IPC_EVENT_BAR_STATE_UPDATE = ((1<<31) | 20), }; #endif diff --git a/include/sway/config.h b/include/sway/config.h index f21ecbb11..be5a00b56 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -191,6 +191,7 @@ struct bar_config { * In "show" mode, it will always be shown on top of the active workspace. */ char *hidden_state; + bool visible_by_modifier; // only relevant in "hide" mode /** * Id name used to identify the bar through IPC. * diff --git a/include/sway/ipc-server.h b/include/sway/ipc-server.h index 80180ec4e..3c43f74d2 100644 --- a/include/sway/ipc-server.h +++ b/include/sway/ipc-server.h @@ -15,6 +15,7 @@ void ipc_event_workspace(struct sway_workspace *old, struct sway_workspace *new, const char *change); void ipc_event_window(struct sway_container *window, const char *change); void ipc_event_barconfig_update(struct bar_config *bar); +void ipc_event_bar_state_update(struct bar_config *bar); void ipc_event_mode(const char *mode, bool pango); void ipc_event_shutdown(const char *reason); void ipc_event_binding(struct sway_binding *binding); diff --git a/include/swaybar/config.h b/include/swaybar/config.h index 10904bca0..5d40790aa 100644 --- a/include/swaybar/config.h +++ b/include/swaybar/config.h @@ -32,6 +32,7 @@ struct swaybar_config { char *sep_symbol; char *mode; char *hidden_state; + char *modifier; bool strip_workspace_numbers; bool binding_mode_indicator; bool wrap_scroll; diff --git a/sway/config/bar.c b/sway/config/bar.c index 5726e95b6..8b88642e8 100644 --- a/sway/config/bar.c +++ b/sway/config/bar.c @@ -16,6 +16,7 @@ #include "stringop.h" #include "list.h" #include "log.h" +#include "util.h" static void terminate_swaybar(pid_t pid) { wlr_log(WLR_DEBUG, "Terminating swaybar %d", pid); @@ -101,6 +102,7 @@ struct bar_config *default_bar_config(void) { bar->binding_mode_indicator = true; bar->verbose = false; bar->pid = 0; + bar->modifier = get_modifier_mask_by_name("Mod4"); if (!(bar->mode = strdup("dock"))) { goto cleanup; } diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index fb1fe7b51..2c8b41cd7 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c @@ -9,6 +9,7 @@ #include "sway/input/input-manager.h" #include "sway/input/keyboard.h" #include "sway/input/seat.h" +#include "sway/ipc-server.h" #include "log.h" /** @@ -66,10 +67,10 @@ static void update_shortcut_state(struct sway_shortcut_state *state, bool last_key_was_a_modifier = raw_modifiers != state->last_raw_modifiers; state->last_raw_modifiers = raw_modifiers; - if (last_key_was_a_modifier && state->last_keycode) { - // Last pressed key before this one was a modifier - state_erase_key(state, state->last_keycode); - } + if (last_key_was_a_modifier && state->last_keycode) { + // Last pressed key before this one was a modifier + state_erase_key(state, state->last_keycode); + } if (event->state == WLR_KEY_PRESSED) { // Add current key to set; there may be duplicates @@ -235,7 +236,6 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) { code_modifiers); } - bool handled = false; // Identify active release binding @@ -337,6 +337,19 @@ static int handle_keyboard_repeat(void *data) { return 0; } +static void determine_bar_visibility(uint32_t modifiers) { + for (int i = 0; i < config->bars->length; ++i) { + struct bar_config *bar = config->bars->items[i]; + if (strcmp(bar->mode, bar->hidden_state) == 0) { // both are "hide" + bool should_be_visible = (~modifiers & bar->modifier) == 0; + if (bar->visible_by_modifier != should_be_visible) { + bar->visible_by_modifier = should_be_visible; + ipc_event_bar_state_update(bar); + } + } + } +} + static void handle_keyboard_modifiers(struct wl_listener *listener, void *data) { struct sway_keyboard *keyboard = @@ -346,6 +359,9 @@ static void handle_keyboard_modifiers(struct wl_listener *listener, keyboard->seat_device->input_device->wlr_device; wlr_seat_set_keyboard(wlr_seat, wlr_device); wlr_seat_keyboard_notify_modifiers(wlr_seat, &wlr_device->keyboard->modifiers); + + uint32_t modifiers = wlr_keyboard_get_modifiers(wlr_device->keyboard); + determine_bar_visibility(modifiers); } struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat, @@ -464,7 +480,7 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) { keyboard->keyboard_key.notify = handle_keyboard_key; wl_list_remove(&keyboard->keyboard_modifiers.link); - wl_signal_add( &wlr_device->keyboard->events.modifiers, + wl_signal_add(&wlr_device->keyboard->events.modifiers, &keyboard->keyboard_modifiers); keyboard->keyboard_modifiers.notify = handle_keyboard_modifiers; } diff --git a/sway/ipc-server.c b/sway/ipc-server.c index 2d915502f..63c95503f 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c @@ -349,6 +349,22 @@ void ipc_event_barconfig_update(struct bar_config *bar) { json_object_put(json); } +void ipc_event_bar_state_update(struct bar_config *bar) { + if (!ipc_has_event_listeners(IPC_EVENT_BAR_STATE_UPDATE)) { + return; + } + wlr_log(WLR_DEBUG, "Sending bar_state_update event"); + + json_object *json = json_object_new_object(); + json_object_object_add(json, "id", json_object_new_string(bar->id)); + json_object_object_add(json, "visible_by_modifier", + json_object_new_boolean(bar->visible_by_modifier)); + + const char *json_string = json_object_to_json_string(json); + ipc_send_event(json_string, IPC_EVENT_BAR_STATE_UPDATE); + json_object_put(json); +} + void ipc_event_mode(const char *mode, bool pango) { if (!ipc_has_event_listeners(IPC_EVENT_MODE)) { return; @@ -651,6 +667,8 @@ void ipc_client_handle_command(struct ipc_client *client) { client->subscribed_events |= event_mask(IPC_EVENT_WORKSPACE); } else if (strcmp(event_type, "barconfig_update") == 0) { client->subscribed_events |= event_mask(IPC_EVENT_BARCONFIG_UPDATE); + } else if (strcmp(event_type, "bar_state_update") == 0) { + client->subscribed_events |= event_mask(IPC_EVENT_BAR_STATE_UPDATE); } else if (strcmp(event_type, "mode") == 0) { client->subscribed_events |= event_mask(IPC_EVENT_MODE); } else if (strcmp(event_type, "shutdown") == 0) { diff --git a/swaybar/ipc.c b/swaybar/ipc.c index 56379fdb9..c7fdffae3 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c @@ -367,7 +367,7 @@ bool ipc_initialize(struct swaybar *bar) { struct swaybar_config *config = bar->config; char subscribe[128]; // suitably large buffer len = snprintf(subscribe, 128, - "[ \"barconfig_update\" %s %s ]", + "[ \"barconfig_update\" , \"bar_state_update\" %s %s ]", config->binding_mode_indicator ? ", \"mode\"" : "", config->workspace_buttons ? ", \"workspace\"" : ""); free(ipc_single_command(bar->ipc_event_socketfd, @@ -375,6 +375,20 @@ bool ipc_initialize(struct swaybar *bar) { 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; @@ -444,6 +458,9 @@ bool handle_ipc_readable(struct swaybar *bar) { 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: bar_is_dirty = false; break; From f6f72cb949e2ab46510ba8bea63d1c6ece8a4756 Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Fri, 12 Oct 2018 21:05:43 +0100 Subject: [PATCH 11/14] swaybar: show hidden bar on urgency --- include/swaybar/ipc.h | 2 +- swaybar/ipc.c | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/include/swaybar/ipc.h b/include/swaybar/ipc.h index 51db85b55..d8cd0c761 100644 --- a/include/swaybar/ipc.h +++ b/include/swaybar/ipc.h @@ -5,7 +5,7 @@ bool ipc_initialize(struct swaybar *bar); bool handle_ipc_readable(struct swaybar *bar); -void ipc_get_workspaces(struct swaybar *bar); +bool ipc_get_workspaces(struct swaybar *bar); void ipc_send_workspace_command(struct swaybar *bar, const char *ws); void ipc_execute_binding(struct swaybar *bar, struct swaybar_binding *bind); diff --git a/swaybar/ipc.c b/swaybar/ipc.c index c7fdffae3..e1b30b527 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c @@ -262,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); @@ -274,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; @@ -302,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) { @@ -436,7 +442,7 @@ bool handle_ipc_readable(struct swaybar *bar) { 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 *json_change, *json_pango_markup; From a29ee77411be3f3fe988617d91cc5bed603e3dcb Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Fri, 12 Oct 2018 20:59:45 +0100 Subject: [PATCH 12/14] swaybar: send signal to status when hiding or showing bar --- include/swaybar/status_line.h | 3 +++ swaybar/bar.c | 4 ++++ swaybar/status_line.c | 14 ++++++++++++++ 3 files changed, 21 insertions(+) diff --git a/include/swaybar/status_line.h b/include/swaybar/status_line.h index ca88b0c56..5e7e87712 100644 --- a/include/swaybar/status_line.h +++ b/include/swaybar/status_line.h @@ -22,6 +22,9 @@ struct status_line { const char *text; struct wl_list blocks; // i3bar_block::link + int stop_signal; + int cont_signal; + bool click_events; bool clicked; char *buffer; diff --git a/swaybar/bar.c b/swaybar/bar.c index 6894383de..f636f0c94 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -396,6 +396,10 @@ bool determine_bar_visibility(struct swaybar *bar, bool moving_layer) { 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; } diff --git a/swaybar/status_line.c b/swaybar/status_line.c index ed6dc7c8b..000609cec 100644 --- a/swaybar/status_line.c +++ b/swaybar/status_line.c @@ -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); From 4dba7c084acb6ca1c9d220f8eac918c046c199ad Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Sat, 13 Oct 2018 11:56:56 +0100 Subject: [PATCH 13/14] swaybar: when hiding bar, save old height to be restored upon reshow Previously, when the bar was hidden, the height would be set to 0. This meant that if the bar was empty upon reshow, it would not render since the height was still 0, which made it seem there was a problem. Now, the height is not reset, but the width is, to indicate upon reshow that the layer surface needed reconfiguring. --- swaybar/bar.c | 1 - swaybar/render.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/swaybar/bar.c b/swaybar/bar.c index f636f0c94..9f72c94c7 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -367,7 +367,6 @@ static void destroy_layer_surface(struct swaybar_output *output) { zwlr_layer_surface_v1_destroy(output->layer_surface); wl_surface_attach(output->surface, NULL, 0, 0); // detach buffer output->layer_surface = NULL; - output->height = 0; output->width = 0; output->frame_scheduled = false; } diff --git a/swaybar/render.c b/swaybar/render.c index 670630cf7..097eb4628 100644 --- a/swaybar/render.c +++ b/swaybar/render.c @@ -519,7 +519,7 @@ 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); if (strcmp(output->bar->config->mode, "dock") == 0) { From 85dd36e92b2fb3d4b5fefa36927abf8f35f84c5c Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Sat, 13 Oct 2018 21:44:08 +0100 Subject: [PATCH 14/14] swaybar: add documentation for hide/hidden_state subcommands --- sway/sway-bar.5.scd | 16 ++++++++++++++++ sway/sway.5.scd | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/sway/sway-bar.5.scd b/sway/sway-bar.5.scd index 6729c9ac7..873741c09 100644 --- a/sway/sway-bar.5.scd +++ b/sway/sway-bar.5.scd @@ -65,6 +65,22 @@ Sway allows configuring swaybar in the sway configuration file. is given, when mouse button _n_ has been released). To disable the default behavior for a button, use the command _nop_. +*mode* dock|hide|invisible + Specifies the visibility of the bar. In _dock_ mode, it is permanently + visible at one edge of the screen. In _hide_ mode, it is hidden unless the + modifier key is pressed, though this behaviour depends on the hidden state. + In _invisible_ mode, it is permanently hidden. Default is _dock_. + +*hidden\_state* hide|show + Specifies the behaviour of the bar when it is in _hide_ mode. When the + hidden state is _hide_, then it is normally hidden, and only unhidden by + pressing the modifier key or in case of urgency hints. When the hidden + state is _show_, then it is permanently visible, drawn on top of the + currently visible workspace. Default is _hide_. + +*modifier* |none + Specifies the modifier key that shows a hidden bar. Default is _Mod4_. + ## TRAY Swaybar provides a system tray where third-party applications may place icons. diff --git a/sway/sway.5.scd b/sway/sway.5.scd index 2e1d13a81..67cc1cb14 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd @@ -614,6 +614,18 @@ match any output by using the output name "\*". *workspace\_layout* default|stacking|tabbed Specifies the initial layout for new workspaces. +# BAR CONTROL + +*bar hidden\_state* hide|show|toggle [] + Sets the hidden state of the bar (see *sway-bar*(5)), either individually, + by specifying a bar id, or if none is given, for all bar instances. + _toggle_ switches between _hide_ and _show_. + +*bar mode* dock|hide|invisible|toggle [] + Sets the mode of the bar (see *sway-bar*(5)), either individually, + by specifying a bar id, or if none is given, for all bar instances. + _toggle_ switches between _dock_ and _hide_. + # CRITERIA A criteria is a string in the form of, for example: