From c5dfe70ab124b84d9867a835d909c20da1d9c143 Mon Sep 17 00:00:00 2001 From: Calvin Kosmatka Date: Mon, 10 Apr 2017 23:52:23 -0500 Subject: [PATCH 1/9] started ipc approach to bar hiding - builds fine, but bar won't show up right now --- include/swaybar/config.h | 1 + swaybar/config.c | 1 + swaybar/ipc.c | 35 ++++++++++++++++++++++++++++++++--- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/include/swaybar/config.h b/include/swaybar/config.h index 04b12cd4b..527361ed4 100644 --- a/include/swaybar/config.h +++ b/include/swaybar/config.h @@ -26,6 +26,7 @@ struct 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/config.c b/swaybar/config.c index 1d8020223..5b81c2e31 100644 --- a/swaybar/config.c +++ b/swaybar/config.c @@ -37,6 +37,7 @@ struct config *init_config() { config->position = DESKTOP_SHELL_PANEL_POSITION_BOTTOM; config->font = strdup("monospace 10"); config->mode = NULL; + config->hidden_state = NULL; config->sep_symbol = NULL; config->strip_workspace_numbers = false; config->binding_mode_indicator = true; diff --git a/swaybar/ipc.c b/swaybar/ipc.c index b08eeea89..0366a9f13 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c @@ -7,6 +7,7 @@ #include "ipc-client.h" #include "list.h" #include "log.h" +#include "util.h" void ipc_send_workspace_command(const char *workspace_name) { uint32_t size = strlen("workspace \"\"") + strlen(workspace_name) + 1; @@ -19,13 +20,13 @@ void ipc_send_workspace_command(const char *workspace_name) { static void ipc_parse_config(struct config *config, const char *payload) { json_object *bar_config = json_tokener_parse(payload); - json_object *tray_output, *mode, *hidden_bar, *position, *status_command; + json_object *tray_output, *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 *markup; json_object_object_get_ex(bar_config, "tray_output", &tray_output); 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); @@ -323,7 +324,9 @@ void ipc_bar_init(struct bar *bar, const char *bar_id) { free(res); json_object_put(outputs); - const char *subscribe_json = "[ \"workspace\", \"mode\" ]"; + const char *subscribe_json = strcmp(bar->config->mode, "hide") == 0 ? + "[ \"workspace\", \"mode\", \"modifier\" ]" + : "[ \"workspace\", \"mode\" ]"; len = strlen(subscribe_json); res = ipc_single_command(bar->ipc_event_socketfd, IPC_SUBSCRIBE, subscribe_json, &len); free(res); @@ -364,6 +367,32 @@ bool handle_ipc_event(struct bar *bar) { json_object_put(result); break; } + case IPC_EVENT_MODIFIER: { + if (strcmp(bar->config->mode, "hide") == 0) { + json_object *result = json_tokener_parse(resp->payload); + if (!result) { + free_ipc_response(resp); + sway_log(L_ERROR, "failed to parse payload as json"); + return false; + } + json_object *json_change; + if (json_object_object_get_ex(result, "change", &json_change)) { + const char *change = json_object_get_string(json_change); + + if (strcmp(change, "pressed") == 0) { + bar->config->hidden_state = "show"; + } else { //must be "released" + bar->config->hidden_state = "hide"; + } + + } else { + sway_log(L_ERROR, "failed to parse response"); + } + + json_object_put(result); + break; + } + } default: free_ipc_response(resp); return false; From 39735013b4b48911f04aa8487c2a08fa24674aa4 Mon Sep 17 00:00:00 2001 From: Calvin Kosmatka Date: Wed, 12 Apr 2017 02:36:03 -0500 Subject: [PATCH 2/9] Adds hide mode functionality to swaybar --- include/sway/config.h | 12 ++++- include/swaybar/config.h | 1 + sway/commands.c | 1 + sway/commands/bar/mode.c | 20 ++++---- sway/commands/ipc.c | 1 + sway/config.c | 6 ++- sway/ipc-json.c | 7 ++- sway/ipc-server.c | 3 +- swaybar/config.c | 1 + swaybar/ipc.c | 66 ++++++++++++++---------- swaybar/render.c | 108 +++++++++++++++++++++------------------ 11 files changed, 133 insertions(+), 93 deletions(-) diff --git a/include/sway/config.h b/include/sway/config.h index 2de904344..408a21003 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -110,12 +110,19 @@ struct bar_config { * Always visible in dock mode. Visible only when modifier key is held in hide mode. * Never visible in invisible mode. */ - char *mode; + char *display_mode; /** * One of "show" or "hide". * * In "show" mode, it will always be shown on top of the active workspace. */ + char *mode; + /** + * Current keybinding mode + * + * Names should probably be reworked at some point, but I'm keeping it for now + * Don't think this does anything at the moment + */ char *hidden_state; /** * Id name used to identify the bar through IPC. @@ -225,9 +232,10 @@ enum ipc_feature { IPC_FEATURE_EVENT_WINDOW = 2048, IPC_FEATURE_EVENT_BINDING = 4096, IPC_FEATURE_EVENT_INPUT = 8192, + IPC_FEATURE_EVENT_MODIFIER = 16384, IPC_FEATURE_ALL_COMMANDS = 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, - IPC_FEATURE_ALL_EVENTS = 256 | 512 | 1024 | 2048 | 4096 | 8192, + IPC_FEATURE_ALL_EVENTS = 256 | 512 | 1024 | 2048 | 4096 | 8192 | 16384, IPC_FEATURE_ALL = IPC_FEATURE_ALL_COMMANDS | IPC_FEATURE_ALL_EVENTS, }; diff --git a/include/swaybar/config.h b/include/swaybar/config.h index 527361ed4..fd3e11cc2 100644 --- a/include/swaybar/config.h +++ b/include/swaybar/config.h @@ -26,6 +26,7 @@ struct config { char *font; char *sep_symbol; char *mode; + char *display_mode; char *hidden_state; bool strip_workspace_numbers; bool binding_mode_indicator; diff --git a/sway/commands.c b/sway/commands.c index 17c7d7176..02f6a6961 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -321,6 +321,7 @@ static struct cmd_handler ipc_event_handlers[] = { { "binding", cmd_ipc_event_cmd }, { "input", cmd_ipc_event_cmd }, { "mode", cmd_ipc_event_cmd }, + { "modifier", cmd_ipc_event_cmd }, { "output", cmd_ipc_event_cmd }, { "window", cmd_ipc_event_cmd }, { "workspace", cmd_ipc_event_cmd }, diff --git a/sway/commands/bar/mode.c b/sway/commands/bar/mode.c index 36816b939..9ba9a1487 100644 --- a/sway/commands/bar/mode.c +++ b/sway/commands/bar/mode.c @@ -7,31 +7,31 @@ #include "log.h" static struct cmd_results *bar_set_mode(struct bar_config *bar, const char *mode) { - char *old_mode = bar->mode; + char *old_mode = bar->display_mode; if (strcasecmp("toggle", mode) == 0 && !config->reading) { - if (strcasecmp("dock", bar->mode) == 0) { - bar->mode = strdup("hide"); - } else if (strcasecmp("hide", bar->mode) == 0) { - bar->mode = strdup("dock"); + if (strcasecmp("dock", bar->display_mode) == 0) { + bar->display_mode = strdup("hide"); + } else if (strcasecmp("hide", bar->display_mode) == 0) { + bar->display_mode = strdup("dock"); } } else if (strcasecmp("dock", mode) == 0) { - bar->mode = strdup("dock"); + bar->display_mode = strdup("dock"); } else if (strcasecmp("hide", mode) == 0) { - bar->mode = strdup("hide"); + bar->display_mode = strdup("hide"); } else if (strcasecmp("invisible", mode) == 0) { - bar->mode = strdup("invisible"); + bar->display_mode = strdup("invisible"); } else { return cmd_results_new(CMD_INVALID, "mode", "Invalid value %s", mode); } - if (strcmp(old_mode, bar->mode) != 0) { + if (strcmp(old_mode, bar->display_mode) != 0) { if (!config->reading) { ipc_event_barconfig_update(bar); // active bar modifiers might have changed. update_active_bar_modifiers(); } - sway_log(L_DEBUG, "Setting mode: '%s' for bar: %s", bar->mode, bar->id); + sway_log(L_DEBUG, "Setting mode: '%s' for bar: %s", bar->display_mode, bar->id); } // free old mode diff --git a/sway/commands/ipc.c b/sway/commands/ipc.c index 8a7b849f9..6dcee3658 100644 --- a/sway/commands/ipc.c +++ b/sway/commands/ipc.c @@ -130,6 +130,7 @@ struct cmd_results *cmd_ipc_event_cmd(int argc, char **argv) { { "window", IPC_FEATURE_EVENT_WINDOW }, { "binding", IPC_FEATURE_EVENT_BINDING }, { "input", IPC_FEATURE_EVENT_INPUT }, + { "modifier", IPC_FEATURE_EVENT_MODIFIER } }; uint32_t type = 0; diff --git a/sway/config.c b/sway/config.c index c8432a2a0..9744facd3 100644 --- a/sway/config.c +++ b/sway/config.c @@ -67,6 +67,7 @@ static void free_bar(struct bar_config *bar) { if (!bar) { return; } + free(bar->display_mode); free(bar->mode); free(bar->hidden_state); free(bar->status_command); @@ -408,7 +409,7 @@ void update_active_bar_modifiers() { int i; for (i = 0; i < config->bars->length; ++i) { bar = config->bars->items[i]; - if (strcmp(bar->mode, "hide") == 0 && strcmp(bar->hidden_state, "hide") == 0) { + if (strcmp(bar->display_mode, "hide") == 0 && strcmp(bar->hidden_state, "hide") == 0) { if (list_seq_find(config->active_bar_modifiers, compare_modifiers, &bar->modifier) < 0) { list_add(config->active_bar_modifiers, &bar->modifier); } @@ -1334,8 +1335,9 @@ struct bar_config *default_bar_config(void) { if (!bar) { return NULL; } - if (!(bar->mode = strdup("dock"))) goto cleanup; + if (!(bar->display_mode = strdup("dock"))) goto cleanup; if (!(bar->hidden_state = strdup("hide"))) goto cleanup; + bar->mode = NULL; bar->modifier = WLC_BIT_MOD_LOGO; bar->outputs = NULL; bar->position = DESKTOP_SHELL_PANEL_POSITION_BOTTOM; diff --git a/sway/ipc-json.c b/sway/ipc-json.c index 6bd5204c7..20b82b784 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c @@ -288,7 +288,12 @@ json_object *ipc_json_describe_bar_config(struct bar_config *bar) { json_object *json = json_object_new_object(); json_object_object_add(json, "id", json_object_new_string(bar->id)); json_object_object_add(json, "tray_output", NULL); - json_object_object_add(json, "mode", json_object_new_string(bar->mode)); + json_object_object_add(json, "mode", json_object_new_string(bar->display_mode)); + if (!bar->mode) { + json_object_object_add(json, "binding_mode", json_object_new_string("default")); + } else { + json_object_object_add(json, "binding_mode", json_object_new_string(bar->mode)); + } json_object_object_add(json, "hidden_state", json_object_new_string(bar->hidden_state)); json_object_object_add(json, "modifier", json_object_new_string(get_modifier_name_by_mask(bar->modifier))); switch (bar->position) { diff --git a/sway/ipc-server.c b/sway/ipc-server.c index 6554098be..7b5b39e11 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c @@ -651,7 +651,8 @@ void ipc_send_event(const char *json_string, enum ipc_command_type event) { { IPC_EVENT_MODE, IPC_FEATURE_EVENT_MODE }, { IPC_EVENT_WINDOW, IPC_FEATURE_EVENT_WINDOW }, { IPC_EVENT_BINDING, IPC_FEATURE_EVENT_BINDING }, - { IPC_EVENT_INPUT, IPC_FEATURE_EVENT_INPUT } + { IPC_EVENT_INPUT, IPC_FEATURE_EVENT_INPUT }, + { IPC_EVENT_MODIFIER, IPC_FEATURE_EVENT_MODIFIER} }; uint32_t security_mask = 0; diff --git a/swaybar/config.c b/swaybar/config.c index 5b81c2e31..ee7486715 100644 --- a/swaybar/config.c +++ b/swaybar/config.c @@ -37,6 +37,7 @@ struct config *init_config() { config->position = DESKTOP_SHELL_PANEL_POSITION_BOTTOM; config->font = strdup("monospace 10"); config->mode = NULL; + config->display_mode = NULL; config->hidden_state = NULL; config->sep_symbol = NULL; config->strip_workspace_numbers = false; diff --git a/swaybar/ipc.c b/swaybar/ipc.c index 0366a9f13..65b684a48 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c @@ -20,12 +20,14 @@ void ipc_send_workspace_command(const char *workspace_name) { static void ipc_parse_config(struct config *config, const char *payload) { json_object *bar_config = json_tokener_parse(payload); - json_object *tray_output, *mode, *hidden_state, *position, *status_command; + json_object *tray_output, *display_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 *markup; json_object_object_get_ex(bar_config, "tray_output", &tray_output); - json_object_object_get_ex(bar_config, "mode", &mode); + // "mode" as in the bar's display mode and "mode" as in binding mode + // should be distinguished more carefully + json_object_object_get_ex(bar_config, "mode", &display_mode); 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); @@ -45,6 +47,16 @@ static void ipc_parse_config(struct config *config, const char *payload) { free(config->status_command); config->status_command = strdup(json_object_get_string(status_command)); } + + if (display_mode) { + free(config->display_mode); + config->display_mode = strdup(json_object_get_string(display_mode)); + } + + if (hidden_state) { + free(config->hidden_state); + config->hidden_state = strdup(json_object_get_string(hidden_state)); + } if (position) { config->position = parse_position(json_object_get_string(position)); @@ -323,10 +335,12 @@ void ipc_bar_init(struct bar *bar, const char *bar_id) { } free(res); json_object_put(outputs); - - const char *subscribe_json = strcmp(bar->config->mode, "hide") == 0 ? + // Will need to be redone for display mode toggling compatibility + // Will require setting bar->config->hidden_state to "show" as default + const char *subscribe_json = strcmp(bar->config->display_mode, "hide") == 0 ? "[ \"workspace\", \"mode\", \"modifier\" ]" : "[ \"workspace\", \"mode\" ]"; + sway_log(L_ERROR, subscribe_json); len = strlen(subscribe_json); res = ipc_single_command(bar->ipc_event_socketfd, IPC_SUBSCRIBE, subscribe_json, &len); free(res); @@ -368,30 +382,28 @@ bool handle_ipc_event(struct bar *bar) { break; } case IPC_EVENT_MODIFIER: { - if (strcmp(bar->config->mode, "hide") == 0) { - json_object *result = json_tokener_parse(resp->payload); - if (!result) { - free_ipc_response(resp); - sway_log(L_ERROR, "failed to parse payload as json"); - return false; - } - json_object *json_change; - if (json_object_object_get_ex(result, "change", &json_change)) { - const char *change = json_object_get_string(json_change); - - if (strcmp(change, "pressed") == 0) { - bar->config->hidden_state = "show"; - } else { //must be "released" - bar->config->hidden_state = "hide"; - } - - } else { - sway_log(L_ERROR, "failed to parse response"); - } - - json_object_put(result); - break; + json_object *result = json_tokener_parse(resp->payload); + if (!result) { + free_ipc_response(resp); + sway_log(L_ERROR, "failed to parse payload as json"); + return false; } + json_object *json_change; + if (json_object_object_get_ex(result, "change", &json_change)) { + const char *change = json_object_get_string(json_change); + free(bar->config->hidden_state); + if (strcmp(change, "pressed") == 0) { + bar->config->hidden_state = strdup("show"); + } else { //must be "released" + bar->config->hidden_state = strdup("hide"); + } + + } else { + sway_log(L_ERROR, "failed to parse response"); + } + + json_object_put(result); + break; } default: free_ipc_response(resp); diff --git a/swaybar/render.c b/swaybar/render.c index 2eae997fc..f40fb9dce 100644 --- a/swaybar/render.c +++ b/swaybar/render.c @@ -286,59 +286,67 @@ void render(struct output *output, struct config *config, struct status_line *li cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR); cairo_paint(cairo); cairo_restore(cairo); - - cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); - - // Background - if (is_focused) { - cairo_set_source_u32(cairo, config->colors.focused_background); - } else { - cairo_set_source_u32(cairo, config->colors.background); - } - cairo_paint(cairo); - - // Command output - if (is_focused) { - cairo_set_source_u32(cairo, config->colors.focused_statusline); - } else { - cairo_set_source_u32(cairo, config->colors.statusline); - } - - int width, height; - - if (line->protocol == TEXT) { - get_text_size(window->cairo, window->font, &width, &height, - window->scale, config->pango_markup, "%s", line->text_line); - cairo_move_to(cairo, (window->width * window->scale) - - margin - width, margin); - pango_printf(window->cairo, window->font, window->scale, - config->pango_markup, "%s", line->text_line); - } else if (line->protocol == I3BAR && line->block_line) { - double pos = (window->width * window->scale) - 0.5; - bool edge = true; - for (i = line->block_line->length - 1; i >= 0; --i) { - struct status_block *block = line->block_line->items[i]; - if (block->full_text && block->full_text[0]) { - render_block(window, config, block, &pos, edge, is_focused); - edge = false; + // Could also be done by always rendering then conditionally clearing and drawing alpha + // That may be preferable down the line + if (!strcmp(config->display_mode, "hide") == 0 || strcmp(config->hidden_state, "show") == 0) { + + cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); + + // Background + if (is_focused) { + cairo_set_source_u32(cairo, config->colors.focused_background); + } else { + cairo_set_source_u32(cairo, config->colors.background); + } + cairo_paint(cairo); + + // Command output + if (is_focused) { + cairo_set_source_u32(cairo, config->colors.focused_statusline); + } else { + cairo_set_source_u32(cairo, config->colors.statusline); + } + + int width, height; + + if (line->protocol == TEXT) { + get_text_size(window->cairo, window->font, &width, &height, + window->scale, config->pango_markup, "%s", line->text_line); + cairo_move_to(cairo, (window->width * window->scale) + - margin - width, margin); + pango_printf(window->cairo, window->font, window->scale, + config->pango_markup, "%s", line->text_line); + } else if (line->protocol == I3BAR && line->block_line) { + double pos = (window->width * window->scale) - 0.5; + bool edge = true; + for (i = line->block_line->length - 1; i >= 0; --i) { + struct status_block *block = line->block_line->items[i]; + if (block->full_text && block->full_text[0]) { + render_block(window, config, block, &pos, edge, is_focused); + edge = false; + } } } - } - - cairo_set_line_width(cairo, 1.0); - double x = 0.5; - - // Workspaces - if (config->workspace_buttons) { - for (i = 0; i < output->workspaces->length; ++i) { - struct workspace *ws = output->workspaces->items[i]; - render_workspace_button(window, config, ws, &x); + + cairo_set_line_width(cairo, 1.0); + double x = 0.5; + + // Workspaces + if (config->workspace_buttons) { + for (i = 0; i < output->workspaces->length; ++i) { + struct workspace *ws = output->workspaces->items[i]; + render_workspace_button(window, config, ws, &x); + } } - } - - // binding mode indicator - if (config->mode && config->binding_mode_indicator) { - render_binding_mode_indicator(window, config, x); + + // binding mode indicator + if (config->mode && config->binding_mode_indicator) { + render_binding_mode_indicator(window, config, x); + } + } else { + cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); + cairo_set_source_u32(cairo, 0x00000000); + cairo_paint(cairo); } } From 7c3dd9ecfbc613c937034fc39bcf506ee4d1c002 Mon Sep 17 00:00:00 2001 From: Calvin Kosmatka Date: Wed, 12 Apr 2017 02:52:11 -0500 Subject: [PATCH 3/9] Update to security to allow swaybar to recieve modifier events --- security.d/00-defaults.in | 1 + 1 file changed, 1 insertion(+) diff --git a/security.d/00-defaults.in b/security.d/00-defaults.in index 05098dea0..e9bdbb3d1 100644 --- a/security.d/00-defaults.in +++ b/security.d/00-defaults.in @@ -33,6 +33,7 @@ ipc __PREFIX__/bin/swaybar { events { workspace enabled mode enabled + modifier enabled } } From 3172023df851b77dfc3e6f6b6d984cb5e203592b Mon Sep 17 00:00:00 2001 From: Calvin Kosmatka Date: Wed, 12 Apr 2017 03:30:01 -0500 Subject: [PATCH 4/9] fix parentheses --- swaybar/render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swaybar/render.c b/swaybar/render.c index f40fb9dce..d62829032 100644 --- a/swaybar/render.c +++ b/swaybar/render.c @@ -288,7 +288,7 @@ void render(struct output *output, struct config *config, struct status_line *li cairo_restore(cairo); // Could also be done by always rendering then conditionally clearing and drawing alpha // That may be preferable down the line - if (!strcmp(config->display_mode, "hide") == 0 || strcmp(config->hidden_state, "show") == 0) { + if ((!strcmp(config->display_mode, "hide")) == 0 || strcmp(config->hidden_state, "show") == 0) { cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); From 79e76387918911938cc59150960fbe28ed2f66d3 Mon Sep 17 00:00:00 2001 From: Calvin Kosmatka Date: Wed, 12 Apr 2017 08:24:59 -0500 Subject: [PATCH 5/9] removed logging statement --- swaybar/ipc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/swaybar/ipc.c b/swaybar/ipc.c index 65b684a48..fc4ef5c7e 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c @@ -340,7 +340,6 @@ void ipc_bar_init(struct bar *bar, const char *bar_id) { const char *subscribe_json = strcmp(bar->config->display_mode, "hide") == 0 ? "[ \"workspace\", \"mode\", \"modifier\" ]" : "[ \"workspace\", \"mode\" ]"; - sway_log(L_ERROR, subscribe_json); len = strlen(subscribe_json); res = ipc_single_command(bar->ipc_event_socketfd, IPC_SUBSCRIBE, subscribe_json, &len); free(res); From b23fd02fb612f0b2e63dd1cb5ffd738079bf7190 Mon Sep 17 00:00:00 2001 From: Calvin Kosmatka Date: Sun, 16 Apr 2017 19:58:44 -0500 Subject: [PATCH 6/9] removed binding mode state variable from bar config --- include/sway/config.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/include/sway/config.h b/include/sway/config.h index 408a21003..98fb738c1 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -116,13 +116,6 @@ struct bar_config { * * In "show" mode, it will always be shown on top of the active workspace. */ - char *mode; - /** - * Current keybinding mode - * - * Names should probably be reworked at some point, but I'm keeping it for now - * Don't think this does anything at the moment - */ char *hidden_state; /** * Id name used to identify the bar through IPC. From 0dc55dda6abe5ae6a3233ec19c5785d3ab07a124 Mon Sep 17 00:00:00 2001 From: Calvin Kosmatka Date: Sun, 16 Apr 2017 23:34:27 -0500 Subject: [PATCH 7/9] remove binding mode from sway side. switch from strings to enums on swaybar side --- include/swaybar/config.h | 25 +++++++++++++++++++++++-- sway/config.c | 2 -- sway/ipc-json.c | 5 ----- swaybar/config.c | 26 ++++++++++++++++++++++++-- swaybar/ipc.c | 25 +++++++++++++------------ swaybar/render.c | 2 +- 6 files changed, 61 insertions(+), 24 deletions(-) diff --git a/include/swaybar/config.h b/include/swaybar/config.h index fd3e11cc2..e2653c37c 100644 --- a/include/swaybar/config.h +++ b/include/swaybar/config.h @@ -16,6 +16,17 @@ struct box_colors { uint32_t text; }; +enum display_mode_types { + MODE_HIDE, + MODE_DOCK, + MODE_INVISIBLE +}; + +enum hidden_states { + BAR_HIDDEN, + BAR_SHOW +}; + /** * Swaybar config. */ @@ -26,8 +37,8 @@ struct config { char *font; char *sep_symbol; char *mode; - char *display_mode; - char *hidden_state; + enum display_mode_types display_mode; + enum hidden_states hidden_state; bool strip_workspace_numbers; bool binding_mode_indicator; bool wrap_scroll; @@ -64,6 +75,16 @@ uint32_t parse_position(const char *position); */ char *parse_font(const char *font); +/** + * Parse display mode dock|hide|invisible. + */ +enum display_mode_types parse_display_mode(const char *display_mode); + +/** + * Parse hidden state show|hide. + */ +enum hidden_states parse_hidden_state(const char *hidden_state); + /** * Initialize default sway config. */ diff --git a/sway/config.c b/sway/config.c index 9744facd3..ca94b074e 100644 --- a/sway/config.c +++ b/sway/config.c @@ -68,7 +68,6 @@ static void free_bar(struct bar_config *bar) { return; } free(bar->display_mode); - free(bar->mode); free(bar->hidden_state); free(bar->status_command); free(bar->font); @@ -1337,7 +1336,6 @@ struct bar_config *default_bar_config(void) { } if (!(bar->display_mode = strdup("dock"))) goto cleanup; if (!(bar->hidden_state = strdup("hide"))) goto cleanup; - bar->mode = NULL; bar->modifier = WLC_BIT_MOD_LOGO; bar->outputs = NULL; bar->position = DESKTOP_SHELL_PANEL_POSITION_BOTTOM; diff --git a/sway/ipc-json.c b/sway/ipc-json.c index a9a1453b3..57a296bb3 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c @@ -352,11 +352,6 @@ json_object *ipc_json_describe_bar_config(struct bar_config *bar) { json_object_object_add(json, "id", json_object_new_string(bar->id)); json_object_object_add(json, "tray_output", NULL); json_object_object_add(json, "mode", json_object_new_string(bar->display_mode)); - if (!bar->mode) { - json_object_object_add(json, "binding_mode", json_object_new_string("default")); - } else { - json_object_object_add(json, "binding_mode", json_object_new_string(bar->mode)); - } json_object_object_add(json, "hidden_state", json_object_new_string(bar->hidden_state)); json_object_object_add(json, "modifier", json_object_new_string(get_modifier_name_by_mask(bar->modifier))); switch (bar->position) { diff --git a/swaybar/config.c b/swaybar/config.c index ee7486715..38704a4ea 100644 --- a/swaybar/config.c +++ b/swaybar/config.c @@ -30,6 +30,28 @@ char *parse_font(const char *font) { return new_font; } +enum display_mode_types parse_display_mode(const char *display_mode) { + if (strcmp("hide", display_mode) == 0) { + return MODE_HIDE; + } else if (strcmp("dock", display_mode) == 0) { + return MODE_DOCK; + } else if (strcmp("invisible", display_mode) == 0) { + return MODE_INVISIBLE; + } else { + return MODE_DOCK; + } +} + +enum hidden_states parse_hidden_state(const char *hidden_state) { + if (strcmp("show", hidden_state) == 0) { + return BAR_SHOW; + } else if (strcmp("hide", hidden_state) == 0) { + return BAR_HIDDEN; + } else { + return BAR_SHOW; + } +} + struct config *init_config() { struct config *config = calloc(1, sizeof(struct config)); config->status_command = NULL; @@ -37,8 +59,8 @@ struct config *init_config() { config->position = DESKTOP_SHELL_PANEL_POSITION_BOTTOM; config->font = strdup("monospace 10"); config->mode = NULL; - config->display_mode = NULL; - config->hidden_state = NULL; + config->display_mode = MODE_DOCK; + config->hidden_state = BAR_SHOW; config->sep_symbol = NULL; config->strip_workspace_numbers = false; config->binding_mode_indicator = true; diff --git a/swaybar/ipc.c b/swaybar/ipc.c index fc4ef5c7e..2a1fe219d 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c @@ -49,13 +49,11 @@ static void ipc_parse_config(struct config *config, const char *payload) { } if (display_mode) { - free(config->display_mode); - config->display_mode = strdup(json_object_get_string(display_mode)); + config->display_mode = parse_display_mode(strdup(json_object_get_string(display_mode))); } if (hidden_state) { - free(config->hidden_state); - config->hidden_state = strdup(json_object_get_string(hidden_state)); + config->hidden_state = parse_hidden_state(strdup(json_object_get_string(hidden_state))); } if (position) { @@ -337,11 +335,15 @@ void ipc_bar_init(struct bar *bar, const char *bar_id) { json_object_put(outputs); // Will need to be redone for display mode toggling compatibility // Will require setting bar->config->hidden_state to "show" as default - const char *subscribe_json = strcmp(bar->config->display_mode, "hide") == 0 ? - "[ \"workspace\", \"mode\", \"modifier\" ]" - : "[ \"workspace\", \"mode\" ]"; - len = strlen(subscribe_json); - res = ipc_single_command(bar->ipc_event_socketfd, IPC_SUBSCRIBE, subscribe_json, &len); + json_object *subscribe_json = json_object_new_array(); + json_object_array_add(subscribe_json, json_object_new_string("workspace")); + json_object_array_add(subscribe_json, json_object_new_string("mode")); + if (bar->config->display_mode == MODE_HIDE) { + json_object_array_add(subscribe_json, json_object_new_string("modifier")); + } + const char *subscribe_json_string = json_object_to_json_string(subscribe_json); + len = strlen(subscribe_json_string); + res = ipc_single_command(bar->ipc_event_socketfd, IPC_SUBSCRIBE, subscribe_json_string, &len); free(res); ipc_update_workspaces(bar); @@ -390,11 +392,10 @@ bool handle_ipc_event(struct bar *bar) { json_object *json_change; if (json_object_object_get_ex(result, "change", &json_change)) { const char *change = json_object_get_string(json_change); - free(bar->config->hidden_state); if (strcmp(change, "pressed") == 0) { - bar->config->hidden_state = strdup("show"); + bar->config->hidden_state = BAR_SHOW; } else { //must be "released" - bar->config->hidden_state = strdup("hide"); + bar->config->hidden_state = BAR_HIDDEN; } } else { diff --git a/swaybar/render.c b/swaybar/render.c index d62829032..d0b30221b 100644 --- a/swaybar/render.c +++ b/swaybar/render.c @@ -288,7 +288,7 @@ void render(struct output *output, struct config *config, struct status_line *li cairo_restore(cairo); // Could also be done by always rendering then conditionally clearing and drawing alpha // That may be preferable down the line - if ((!strcmp(config->display_mode, "hide")) == 0 || strcmp(config->hidden_state, "show") == 0) { + if ((!config->display_mode == MODE_HIDE) || config->hidden_state == BAR_SHOW) { cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); From b7fe2a95ca097ce40394e136105f08b68b0c0dde Mon Sep 17 00:00:00 2001 From: Calvin Kosmatka Date: Sun, 16 Apr 2017 23:41:27 -0500 Subject: [PATCH 8/9] fix parentheses --- swaybar/render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swaybar/render.c b/swaybar/render.c index d0b30221b..a46826b2b 100644 --- a/swaybar/render.c +++ b/swaybar/render.c @@ -288,7 +288,7 @@ void render(struct output *output, struct config *config, struct status_line *li cairo_restore(cairo); // Could also be done by always rendering then conditionally clearing and drawing alpha // That may be preferable down the line - if ((!config->display_mode == MODE_HIDE) || config->hidden_state == BAR_SHOW) { + if (!(config->display_mode == MODE_HIDE) || config->hidden_state == BAR_SHOW) { cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); From aea0d45c9d3f5c2457fafddc80bb96618dca4244 Mon Sep 17 00:00:00 2001 From: Calvin Kosmatka Date: Mon, 17 Apr 2017 10:33:35 -0500 Subject: [PATCH 9/9] progress on panel protocol --- include/sway/extensions.h | 3 + protocols/desktop-shell.xml | 26 +++++++++ sway/extensions.c | 32 ++++++++++- sway/layout.c | 28 ++++----- swaybar/bar.c | 9 +++ swaybar/ipc.c | 53 +++++++++++------- swaybar/render.c | 109 +++++++++++++++++------------------- 7 files changed, 168 insertions(+), 92 deletions(-) diff --git a/include/sway/extensions.h b/include/sway/extensions.h index f6b0c00ec..e1fbbb9f6 100644 --- a/include/sway/extensions.h +++ b/include/sway/extensions.h @@ -27,6 +27,9 @@ struct panel_config { struct wl_client *client; // wlc handle for this panel's surface, not set until panel is created wlc_handle handle; + + enum desktop_shell_hide_modes hide_mode; + enum desktop_shell_hide_state hide; }; struct desktop_shell_state { diff --git a/protocols/desktop-shell.xml b/protocols/desktop-shell.xml index 581f0c5d3..1b2f8b30d 100644 --- a/protocols/desktop-shell.xml +++ b/protocols/desktop-shell.xml @@ -116,6 +116,32 @@ + + + + + + + + + + + + + + Tell the shell whether or not panel is in hide mode + i.e. whether to allocate a fixed amount of space + for the panel (hide mode false) or not (hide mode true) + + + + + + + Tell the shell whether or not panel is currently hidden + + + diff --git a/sway/extensions.c b/sway/extensions.c index 96957dbff..89afb8484 100644 --- a/sway/extensions.c +++ b/sway/extensions.c @@ -133,6 +133,34 @@ static void set_panel(struct wl_client *client, struct wl_resource *resource, wlc_output_schedule_render(config->output); } +static void set_panel_hide_mode(struct wl_client *client, struct wl_resource *resource, + uint32_t mode) { + struct panel_config *config = find_or_create_panel_config(resource); + config->hide_mode = mode; + if (mode == 0) { + wlc_view_set_mask(wlc_handle_from_wl_surface_resource(config->wl_surface_res), false); + } else { + wlc_view_set_mask(wlc_handle_from_wl_surface_resource(config->wl_surface_res), true); + } + arrange_windows(&root_container, -1, -1); + wlc_output_schedule_render(config->output); +} + +static void set_panel_hide(struct wl_client *client, struct wl_resource *resource, + uint32_t hide) { + sway_log(L_ERROR, "Attempting to find panel %p", resource); + struct panel_config *config = find_or_create_panel_config(resource); + config->hide = hide; + if (hide == 0) { + sway_log(L_ERROR, "Hiding panel %p", resource); + wlc_view_set_mask(wlc_handle_from_wl_surface_resource(config->wl_surface_res), false); + } else if (hide == 1) { + sway_log(L_ERROR, "Showing panel %p", resource); + wlc_view_set_mask(wlc_handle_from_wl_surface_resource(config->wl_surface_res), true); + } + wlc_output_schedule_render(config->output); +} + static void desktop_set_lock_surface(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface) { sway_log(L_ERROR, "desktop_set_lock_surface is not currently supported"); } @@ -169,7 +197,9 @@ static struct desktop_shell_interface desktop_shell_implementation = { .unlock = desktop_unlock, .set_grab_surface = set_grab_surface, .desktop_ready = desktop_ready, - .set_panel_position = set_panel_position + .set_panel_position = set_panel_position, + .set_panel_hide_mode = set_panel_hide_mode, + .set_panel_hide = set_panel_hide }; static void desktop_shell_bind(struct wl_client *client, void *data, diff --git a/sway/layout.c b/sway/layout.c index 69291dafd..f61402afd 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -1006,19 +1006,21 @@ static void arrange_windows_r(swayc_t *container, double width, double height) { if (config->output == output->handle) { struct wlc_size size = *wlc_surface_get_size(config->surface); sway_log(L_DEBUG, "-> Found panel for this workspace: %ux%u, position: %u", size.w, size.h, config->panel_position); - switch (config->panel_position) { - case DESKTOP_SHELL_PANEL_POSITION_TOP: - y += size.h; height -= size.h; - break; - case DESKTOP_SHELL_PANEL_POSITION_BOTTOM: - height -= size.h; - break; - case DESKTOP_SHELL_PANEL_POSITION_LEFT: - x += size.w; width -= size.w; - break; - case DESKTOP_SHELL_PANEL_POSITION_RIGHT: - width -= size.w; - break; + if (config->hide_mode == DESKTOP_SHELL_HIDE_MODES_SHOW) { + switch (config->panel_position) { + case DESKTOP_SHELL_PANEL_POSITION_TOP: + y += size.h; height -= size.h; + break; + case DESKTOP_SHELL_PANEL_POSITION_BOTTOM: + height -= size.h; + break; + case DESKTOP_SHELL_PANEL_POSITION_LEFT: + x += size.w; width -= size.w; + break; + case DESKTOP_SHELL_PANEL_POSITION_RIGHT: + width -= size.w; + break; + } } } } diff --git a/swaybar/bar.c b/swaybar/bar.c index abde1cc94..98572ffaf 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -163,6 +163,15 @@ void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id) { output->output, bar_output->window->surface); desktop_shell_set_panel_position(bar_output->registry->desktop_shell, bar->config->position); + switch (bar->config->display_mode) { + case MODE_HIDE: + case MODE_INVISIBLE: + desktop_shell_set_panel_hide_mode(bar_output->registry->desktop_shell, DESKTOP_SHELL_HIDE_MODES_HIDE); + break; + case MODE_DOCK: + desktop_shell_set_panel_hide_mode(bar_output->registry->desktop_shell, DESKTOP_SHELL_HIDE_MODES_SHOW); + break; + } window_make_shell(bar_output->window); diff --git a/swaybar/ipc.c b/swaybar/ipc.c index 2a1fe219d..34a9abe99 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c @@ -383,27 +383,42 @@ bool handle_ipc_event(struct bar *bar) { break; } case IPC_EVENT_MODIFIER: { - json_object *result = json_tokener_parse(resp->payload); - if (!result) { - free_ipc_response(resp); - sway_log(L_ERROR, "failed to parse payload as json"); - return false; - } - json_object *json_change; - if (json_object_object_get_ex(result, "change", &json_change)) { - const char *change = json_object_get_string(json_change); - if (strcmp(change, "pressed") == 0) { - bar->config->hidden_state = BAR_SHOW; - } else { //must be "released" - bar->config->hidden_state = BAR_HIDDEN; + if (bar->config->display_mode == MODE_HIDE) { + json_object *result = json_tokener_parse(resp->payload); + if (!result) { + free_ipc_response(resp); + sway_log(L_ERROR, "failed to parse payload as json"); + return false; } - - } else { - sway_log(L_ERROR, "failed to parse response"); + json_object *json_change; + if (json_object_object_get_ex(result, "change", &json_change)) { + const char *change = json_object_get_string(json_change); + if (strcmp(change, "pressed") == 0) { + bar->config->hidden_state = BAR_SHOW; + sway_log(L_ERROR, "Showing bar on %d outputs", bar->outputs->length); + int i; + for (i = 0; i < bar->outputs->length; ++i) { + struct output *bar_output = bar->outputs->items[i]; + sway_log(L_ERROR, "showing bar on input %d, with registry %p", i, bar_output->registry); + desktop_shell_set_panel_hide(bar_output->registry->desktop_shell, DESKTOP_SHELL_HIDE_STATE_SHOW); + } + } else { //must be "released" + bar->config->hidden_state = BAR_HIDDEN; + sway_log(L_ERROR, "Hiding bar"); + int i; + for (i = 0; i < bar->outputs->length; ++i) { + struct output *bar_output = bar->outputs->items[i]; + desktop_shell_set_panel_hide(bar_output->registry->desktop_shell, DESKTOP_SHELL_HIDE_STATE_HIDE); + } + } + + } else { + sway_log(L_ERROR, "failed to parse response"); + } + + json_object_put(result); + break; } - - json_object_put(result); - break; } default: free_ipc_response(resp); diff --git a/swaybar/render.c b/swaybar/render.c index a46826b2b..2b53aa453 100644 --- a/swaybar/render.c +++ b/swaybar/render.c @@ -286,67 +286,58 @@ void render(struct output *output, struct config *config, struct status_line *li cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR); cairo_paint(cairo); cairo_restore(cairo); - // Could also be done by always rendering then conditionally clearing and drawing alpha - // That may be preferable down the line - if (!(config->display_mode == MODE_HIDE) || config->hidden_state == BAR_SHOW) { + cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); - cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); - - // Background - if (is_focused) { - cairo_set_source_u32(cairo, config->colors.focused_background); - } else { - cairo_set_source_u32(cairo, config->colors.background); - } - cairo_paint(cairo); - - // Command output - if (is_focused) { - cairo_set_source_u32(cairo, config->colors.focused_statusline); - } else { - cairo_set_source_u32(cairo, config->colors.statusline); - } - - int width, height; - - if (line->protocol == TEXT) { - get_text_size(window->cairo, window->font, &width, &height, - window->scale, config->pango_markup, "%s", line->text_line); - cairo_move_to(cairo, (window->width * window->scale) - - margin - width, margin); - pango_printf(window->cairo, window->font, window->scale, - config->pango_markup, "%s", line->text_line); - } else if (line->protocol == I3BAR && line->block_line) { - double pos = (window->width * window->scale) - 0.5; - bool edge = true; - for (i = line->block_line->length - 1; i >= 0; --i) { - struct status_block *block = line->block_line->items[i]; - if (block->full_text && block->full_text[0]) { - render_block(window, config, block, &pos, edge, is_focused); - edge = false; - } - } - } - - cairo_set_line_width(cairo, 1.0); - double x = 0.5; - - // Workspaces - if (config->workspace_buttons) { - for (i = 0; i < output->workspaces->length; ++i) { - struct workspace *ws = output->workspaces->items[i]; - render_workspace_button(window, config, ws, &x); - } - } - - // binding mode indicator - if (config->mode && config->binding_mode_indicator) { - render_binding_mode_indicator(window, config, x); - } + // Background + if (is_focused) { + cairo_set_source_u32(cairo, config->colors.focused_background); } else { - cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); - cairo_set_source_u32(cairo, 0x00000000); - cairo_paint(cairo); + cairo_set_source_u32(cairo, config->colors.background); + } + cairo_paint(cairo); + + // Command output + if (is_focused) { + cairo_set_source_u32(cairo, config->colors.focused_statusline); + } else { + cairo_set_source_u32(cairo, config->colors.statusline); + } + + int width, height; + + if (line->protocol == TEXT) { + get_text_size(window->cairo, window->font, &width, &height, + window->scale, config->pango_markup, "%s", line->text_line); + cairo_move_to(cairo, (window->width * window->scale) + - margin - width, margin); + pango_printf(window->cairo, window->font, window->scale, + config->pango_markup, "%s", line->text_line); + } else if (line->protocol == I3BAR && line->block_line) { + double pos = (window->width * window->scale) - 0.5; + bool edge = true; + for (i = line->block_line->length - 1; i >= 0; --i) { + struct status_block *block = line->block_line->items[i]; + if (block->full_text && block->full_text[0]) { + render_block(window, config, block, &pos, edge, is_focused); + edge = false; + } + } + } + + cairo_set_line_width(cairo, 1.0); + double x = 0.5; + + // Workspaces + if (config->workspace_buttons) { + for (i = 0; i < output->workspaces->length; ++i) { + struct workspace *ws = output->workspaces->items[i]; + render_workspace_button(window, config, ws, &x); + } + } + + // binding mode indicator + if (config->mode && config->binding_mode_indicator) { + render_binding_mode_indicator(window, config, x); } }