Adds hide mode functionality to swaybar

This commit is contained in:
Calvin Kosmatka 2017-04-12 02:36:03 -05:00
parent c5dfe70ab1
commit 39735013b4
11 changed files with 133 additions and 93 deletions

View file

@ -110,12 +110,19 @@ struct bar_config {
* Always visible in dock mode. Visible only when modifier key is held in hide mode. * Always visible in dock mode. Visible only when modifier key is held in hide mode.
* Never visible in invisible mode. * Never visible in invisible mode.
*/ */
char *mode; char *display_mode;
/** /**
* One of "show" or "hide". * One of "show" or "hide".
* *
* In "show" mode, it will always be shown on top of the active workspace. * 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; char *hidden_state;
/** /**
* Id name used to identify the bar through IPC. * Id name used to identify the bar through IPC.
@ -225,9 +232,10 @@ enum ipc_feature {
IPC_FEATURE_EVENT_WINDOW = 2048, IPC_FEATURE_EVENT_WINDOW = 2048,
IPC_FEATURE_EVENT_BINDING = 4096, IPC_FEATURE_EVENT_BINDING = 4096,
IPC_FEATURE_EVENT_INPUT = 8192, 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_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, IPC_FEATURE_ALL = IPC_FEATURE_ALL_COMMANDS | IPC_FEATURE_ALL_EVENTS,
}; };

View file

@ -26,6 +26,7 @@ struct config {
char *font; char *font;
char *sep_symbol; char *sep_symbol;
char *mode; char *mode;
char *display_mode;
char *hidden_state; char *hidden_state;
bool strip_workspace_numbers; bool strip_workspace_numbers;
bool binding_mode_indicator; bool binding_mode_indicator;

View file

@ -321,6 +321,7 @@ static struct cmd_handler ipc_event_handlers[] = {
{ "binding", cmd_ipc_event_cmd }, { "binding", cmd_ipc_event_cmd },
{ "input", cmd_ipc_event_cmd }, { "input", cmd_ipc_event_cmd },
{ "mode", cmd_ipc_event_cmd }, { "mode", cmd_ipc_event_cmd },
{ "modifier", cmd_ipc_event_cmd },
{ "output", cmd_ipc_event_cmd }, { "output", cmd_ipc_event_cmd },
{ "window", cmd_ipc_event_cmd }, { "window", cmd_ipc_event_cmd },
{ "workspace", cmd_ipc_event_cmd }, { "workspace", cmd_ipc_event_cmd },

View file

@ -7,31 +7,31 @@
#include "log.h" #include "log.h"
static struct cmd_results *bar_set_mode(struct bar_config *bar, const char *mode) { 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("toggle", mode) == 0 && !config->reading) {
if (strcasecmp("dock", bar->mode) == 0) { if (strcasecmp("dock", bar->display_mode) == 0) {
bar->mode = strdup("hide"); bar->display_mode = strdup("hide");
} else if (strcasecmp("hide", bar->mode) == 0) { } else if (strcasecmp("hide", bar->display_mode) == 0) {
bar->mode = strdup("dock"); bar->display_mode = strdup("dock");
} }
} else if (strcasecmp("dock", mode) == 0) { } else if (strcasecmp("dock", mode) == 0) {
bar->mode = strdup("dock"); bar->display_mode = strdup("dock");
} else if (strcasecmp("hide", mode) == 0) { } else if (strcasecmp("hide", mode) == 0) {
bar->mode = strdup("hide"); bar->display_mode = strdup("hide");
} else if (strcasecmp("invisible", mode) == 0) { } else if (strcasecmp("invisible", mode) == 0) {
bar->mode = strdup("invisible"); bar->display_mode = strdup("invisible");
} else { } else {
return cmd_results_new(CMD_INVALID, "mode", "Invalid value %s", mode); 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) { if (!config->reading) {
ipc_event_barconfig_update(bar); ipc_event_barconfig_update(bar);
// active bar modifiers might have changed. // active bar modifiers might have changed.
update_active_bar_modifiers(); 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 // free old mode

View file

@ -130,6 +130,7 @@ struct cmd_results *cmd_ipc_event_cmd(int argc, char **argv) {
{ "window", IPC_FEATURE_EVENT_WINDOW }, { "window", IPC_FEATURE_EVENT_WINDOW },
{ "binding", IPC_FEATURE_EVENT_BINDING }, { "binding", IPC_FEATURE_EVENT_BINDING },
{ "input", IPC_FEATURE_EVENT_INPUT }, { "input", IPC_FEATURE_EVENT_INPUT },
{ "modifier", IPC_FEATURE_EVENT_MODIFIER }
}; };
uint32_t type = 0; uint32_t type = 0;

View file

@ -67,6 +67,7 @@ static void free_bar(struct bar_config *bar) {
if (!bar) { if (!bar) {
return; return;
} }
free(bar->display_mode);
free(bar->mode); free(bar->mode);
free(bar->hidden_state); free(bar->hidden_state);
free(bar->status_command); free(bar->status_command);
@ -408,7 +409,7 @@ void update_active_bar_modifiers() {
int i; int i;
for (i = 0; i < config->bars->length; ++i) { for (i = 0; i < config->bars->length; ++i) {
bar = config->bars->items[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) { if (list_seq_find(config->active_bar_modifiers, compare_modifiers, &bar->modifier) < 0) {
list_add(config->active_bar_modifiers, &bar->modifier); list_add(config->active_bar_modifiers, &bar->modifier);
} }
@ -1334,8 +1335,9 @@ struct bar_config *default_bar_config(void) {
if (!bar) { if (!bar) {
return NULL; 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; if (!(bar->hidden_state = strdup("hide"))) goto cleanup;
bar->mode = NULL;
bar->modifier = WLC_BIT_MOD_LOGO; bar->modifier = WLC_BIT_MOD_LOGO;
bar->outputs = NULL; bar->outputs = NULL;
bar->position = DESKTOP_SHELL_PANEL_POSITION_BOTTOM; bar->position = DESKTOP_SHELL_PANEL_POSITION_BOTTOM;

View file

@ -288,7 +288,12 @@ json_object *ipc_json_describe_bar_config(struct bar_config *bar) {
json_object *json = json_object_new_object(); json_object *json = json_object_new_object();
json_object_object_add(json, "id", json_object_new_string(bar->id)); 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, "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, "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))); json_object_object_add(json, "modifier", json_object_new_string(get_modifier_name_by_mask(bar->modifier)));
switch (bar->position) { switch (bar->position) {

View file

@ -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_MODE, IPC_FEATURE_EVENT_MODE },
{ IPC_EVENT_WINDOW, IPC_FEATURE_EVENT_WINDOW }, { IPC_EVENT_WINDOW, IPC_FEATURE_EVENT_WINDOW },
{ IPC_EVENT_BINDING, IPC_FEATURE_EVENT_BINDING }, { 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; uint32_t security_mask = 0;

View file

@ -37,6 +37,7 @@ struct config *init_config() {
config->position = DESKTOP_SHELL_PANEL_POSITION_BOTTOM; config->position = DESKTOP_SHELL_PANEL_POSITION_BOTTOM;
config->font = strdup("monospace 10"); config->font = strdup("monospace 10");
config->mode = NULL; config->mode = NULL;
config->display_mode = NULL;
config->hidden_state = NULL; config->hidden_state = NULL;
config->sep_symbol = NULL; config->sep_symbol = NULL;
config->strip_workspace_numbers = false; config->strip_workspace_numbers = false;

View file

@ -20,12 +20,14 @@ void ipc_send_workspace_command(const char *workspace_name) {
static void ipc_parse_config(struct config *config, const char *payload) { static void ipc_parse_config(struct config *config, const char *payload) {
json_object *bar_config = json_tokener_parse(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 *font, *bar_height, *wrap_scroll, *workspace_buttons, *strip_workspace_numbers;
json_object *binding_mode_indicator, *verbose, *colors, *sep_symbol, *outputs; json_object *binding_mode_indicator, *verbose, *colors, *sep_symbol, *outputs;
json_object *markup; json_object *markup;
json_object_object_get_ex(bar_config, "tray_output", &tray_output); 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, "hidden_state", &hidden_state);
json_object_object_get_ex(bar_config, "position", &position); 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, "status_command", &status_command);
@ -45,6 +47,16 @@ static void ipc_parse_config(struct config *config, const char *payload) {
free(config->status_command); free(config->status_command);
config->status_command = strdup(json_object_get_string(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) { if (position) {
config->position = parse_position(json_object_get_string(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); free(res);
json_object_put(outputs); json_object_put(outputs);
// Will need to be redone for display mode toggling compatibility
const char *subscribe_json = strcmp(bar->config->mode, "hide") == 0 ? // 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\", \"modifier\" ]"
: "[ \"workspace\", \"mode\" ]"; : "[ \"workspace\", \"mode\" ]";
sway_log(L_ERROR, subscribe_json);
len = strlen(subscribe_json); len = strlen(subscribe_json);
res = ipc_single_command(bar->ipc_event_socketfd, IPC_SUBSCRIBE, subscribe_json, &len); res = ipc_single_command(bar->ipc_event_socketfd, IPC_SUBSCRIBE, subscribe_json, &len);
free(res); free(res);
@ -368,30 +382,28 @@ bool handle_ipc_event(struct bar *bar) {
break; break;
} }
case IPC_EVENT_MODIFIER: { case IPC_EVENT_MODIFIER: {
if (strcmp(bar->config->mode, "hide") == 0) { json_object *result = json_tokener_parse(resp->payload);
json_object *result = json_tokener_parse(resp->payload); if (!result) {
if (!result) { free_ipc_response(resp);
free_ipc_response(resp); sway_log(L_ERROR, "failed to parse payload as json");
sway_log(L_ERROR, "failed to parse payload as json"); return false;
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 *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: default:
free_ipc_response(resp); free_ipc_response(resp);

View file

@ -286,59 +286,67 @@ void render(struct output *output, struct config *config, struct status_line *li
cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR); cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR);
cairo_paint(cairo); cairo_paint(cairo);
cairo_restore(cairo); cairo_restore(cairo);
// Could also be done by always rendering then conditionally clearing and drawing alpha
cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); // That may be preferable down the line
if (!strcmp(config->display_mode, "hide") == 0 || strcmp(config->hidden_state, "show") == 0) {
// Background
if (is_focused) { cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
cairo_set_source_u32(cairo, config->colors.focused_background);
} else { // Background
cairo_set_source_u32(cairo, config->colors.background); if (is_focused) {
} cairo_set_source_u32(cairo, config->colors.focused_background);
cairo_paint(cairo); } else {
cairo_set_source_u32(cairo, config->colors.background);
// Command output }
if (is_focused) { cairo_paint(cairo);
cairo_set_source_u32(cairo, config->colors.focused_statusline);
} else { // Command output
cairo_set_source_u32(cairo, config->colors.statusline); if (is_focused) {
} cairo_set_source_u32(cairo, config->colors.focused_statusline);
} else {
int width, height; cairo_set_source_u32(cairo, config->colors.statusline);
}
if (line->protocol == TEXT) {
get_text_size(window->cairo, window->font, &width, &height, int width, height;
window->scale, config->pango_markup, "%s", line->text_line);
cairo_move_to(cairo, (window->width * window->scale) if (line->protocol == TEXT) {
- margin - width, margin); get_text_size(window->cairo, window->font, &width, &height,
pango_printf(window->cairo, window->font, window->scale, window->scale, config->pango_markup, "%s", line->text_line);
config->pango_markup, "%s", line->text_line); cairo_move_to(cairo, (window->width * window->scale)
} else if (line->protocol == I3BAR && line->block_line) { - margin - width, margin);
double pos = (window->width * window->scale) - 0.5; pango_printf(window->cairo, window->font, window->scale,
bool edge = true; config->pango_markup, "%s", line->text_line);
for (i = line->block_line->length - 1; i >= 0; --i) { } else if (line->protocol == I3BAR && line->block_line) {
struct status_block *block = line->block_line->items[i]; double pos = (window->width * window->scale) - 0.5;
if (block->full_text && block->full_text[0]) { bool edge = true;
render_block(window, config, block, &pos, edge, is_focused); for (i = line->block_line->length - 1; i >= 0; --i) {
edge = false; 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);
cairo_set_line_width(cairo, 1.0); double x = 0.5;
double x = 0.5;
// Workspaces
// Workspaces if (config->workspace_buttons) {
if (config->workspace_buttons) { for (i = 0; i < output->workspaces->length; ++i) {
for (i = 0; i < output->workspaces->length; ++i) { struct workspace *ws = output->workspaces->items[i];
struct workspace *ws = output->workspaces->items[i]; render_workspace_button(window, config, ws, &x);
render_workspace_button(window, config, ws, &x); }
} }
}
// binding mode indicator
// binding mode indicator if (config->mode && config->binding_mode_indicator) {
if (config->mode && config->binding_mode_indicator) { render_binding_mode_indicator(window, config, x);
render_binding_mode_indicator(window, config, x); }
} else {
cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
cairo_set_source_u32(cairo, 0x00000000);
cairo_paint(cairo);
} }
} }