From 64a183b23d2a0b2e628f641345e33d7ea46c0d07 Mon Sep 17 00:00:00 2001 From: Kevin Hamacher Date: Mon, 14 Dec 2015 11:43:17 +0100 Subject: [PATCH 01/19] Fix dangling pointer on focus swap/describe WS --- sway/focus.c | 6 ++++++ sway/ipc-server.c | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/sway/focus.c b/sway/focus.c index 6911ac00..c60f410c 100644 --- a/sway/focus.c +++ b/sway/focus.c @@ -96,6 +96,7 @@ bool set_focused_container(swayc_t *c) { return false; } swayc_t *active_ws = swayc_active_workspace(); + int active_ws_child_count = active_ws->children->length + active_ws->floating->length; swayc_log(L_DEBUG, c, "Setting focus to %p:%ld", c, c->handle); @@ -118,6 +119,11 @@ bool set_focused_container(swayc_t *c) { p = p->parent; p->is_focused = false; } + // active_ws might have been destroyed by now + // (focus swap away from empty ws = destroy ws) + if (active_ws_child_count == 0) { + active_ws = NULL; + } // get new focused view and set focus to it. p = get_focused_view(c); diff --git a/sway/ipc-server.c b/sway/ipc-server.c index 7c737307..3f02812d 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c @@ -455,7 +455,11 @@ void ipc_get_outputs_callback(swayc_t *container, void *data) { void ipc_event_workspace(swayc_t *old, swayc_t *new) { json_object *obj = json_object_new_object(); json_object_object_add(obj, "change", json_object_new_string("focus")); - json_object_object_add(obj, "old", ipc_json_describe_workspace(old)); + if (old) { + json_object_object_add(obj, "old", ipc_json_describe_workspace(old)); + } else { + json_object_object_add(obj, "old", NULL); + } json_object_object_add(obj, "current", ipc_json_describe_workspace(new)); const char *json_string = json_object_to_json_string(obj); From 74152043f4da7182339f181317960aa6cd01cffa Mon Sep 17 00:00:00 2001 From: Mikkel Oscar Lyderik Date: Mon, 14 Dec 2015 02:39:24 +0100 Subject: [PATCH 02/19] Implement 'bar { }' block parsing --- include/config.h | 3 +++ sway/commands.c | 52 +++++++++++++++++++++++++++++++++++++++++++----- sway/config.c | 29 +++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/include/config.h b/include/config.h index 4019f479..4e62ee68 100644 --- a/include/config.h +++ b/include/config.h @@ -77,6 +77,7 @@ struct bar_config { char *status_command; char *font; int bar_height; + int tray_padding; bool workspace_buttons; bool strip_workspace_numbers; bool binding_mode_indicator; @@ -102,12 +103,14 @@ struct bar_config { struct sway_config { list_t *symbols; list_t *modes; + list_t *bars; list_t *cmd_queue; list_t *workspace_outputs; list_t *output_configs; list_t *criteria; struct sway_mode *current_mode; struct bar_config bar; + struct bar_config *current_bar; uint32_t floating_mod; uint32_t dragging_key; uint32_t resizing_key; diff --git a/sway/commands.c b/sway/commands.c index 74b307e6..d6da1de3 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -32,6 +32,7 @@ struct cmd_handler { sway_cmd *handle; }; +static sway_cmd cmd_bar; static sway_cmd cmd_bindsym; static sway_cmd cmd_debuglog; static sway_cmd cmd_exec; @@ -1099,6 +1100,43 @@ static struct cmd_results *cmd_resize(int argc, char **argv) { return cmd_results_new(CMD_SUCCESS, NULL, NULL); } +static struct cmd_results *cmd_bar(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "bar", EXPECTED_EQUAL_TO, 1))) { + return error; + } + + if (strcmp("{", argv[0]) != 0) { + return cmd_results_new(CMD_INVALID, "bar", + "Expected '{' at start of bar config definition."); + } + + if (!config->reading) { + return cmd_results_new(CMD_FAILURE, "bar", "Can only be used in config file."); + } + + // Create new bar from default bar config + struct bar_config *bar = NULL; + bar = malloc(sizeof*bar); + bar->mode = strdup(config->bar.mode); + bar->hidden_state = strdup(config->bar.hidden_state); + bar->modifier = config->bar.modifier; + bar->position = config->bar.position; + bar->status_command = strdup(config->bar.status_command); + bar->font = strdup(config->bar.font); + bar->bar_height = config->bar.bar_height; + bar->workspace_buttons = config->bar.workspace_buttons; + bar->strip_workspace_numbers = config->bar.strip_workspace_numbers; + bar->binding_mode_indicator = config->bar.binding_mode_indicator; + bar->tray_padding = config->bar.tray_padding; + list_add(config->bars, bar); + + // Set current bar + config->current_bar = bar; + sway_log(L_DEBUG, "Configuring bar"); + return cmd_results_new(CMD_BLOCK_BAR, NULL, NULL); +} + static swayc_t *fetch_view_from_scratchpad() { if (sp_index >= scratchpad->length) { sp_index = 0; @@ -1446,6 +1484,7 @@ static struct cmd_results *cmd_ws_auto_back_and_forth(int argc, char **argv) { /* Keep alphabetized */ static struct cmd_handler handlers[] = { + { "bar", cmd_bar }, { "bindsym", cmd_bindsym }, { "debuglog", cmd_debuglog }, { "default_orientation", cmd_orientation }, @@ -1505,14 +1544,17 @@ static int handler_compare(const void *_a, const void *_b) { } static struct cmd_handler *find_handler(char *line, enum cmd_status block) { - struct cmd_handler *h = handlers; - if (block == CMD_BLOCK_BAR) { - h = bar_handlers; - } struct cmd_handler d = { .command=line }; - struct cmd_handler *res = bsearch(&d, h, + struct cmd_handler *res = NULL; + if (block == CMD_BLOCK_BAR) { + res = bsearch(&d, bar_handlers, + sizeof(bar_handlers) / sizeof(struct cmd_handler), + sizeof(struct cmd_handler), handler_compare); + } else { + res = bsearch(&d, handlers, sizeof(handlers) / sizeof(struct cmd_handler), sizeof(struct cmd_handler), handler_compare); + } return res; } diff --git a/sway/config.c b/sway/config.c index 6c22556f..d5b75adf 100644 --- a/sway/config.c +++ b/sway/config.c @@ -38,6 +38,14 @@ static void free_mode(struct sway_mode *mode) { free(mode); } +static void free_bar(struct bar_config *bar) { + free(bar->mode); + free(bar->hidden_state); + free(bar->status_command); + free(bar->font); + free(bar); +} + void free_output_config(struct output_config *oc) { free(oc->name); free(oc); @@ -61,6 +69,11 @@ static void free_config(struct sway_config *config) { } list_free(config->modes); + for (i = 0; i < config->bars->length; ++i) { + free_bar(config->bars->items[i]); + } + list_free(config->bars); + free_flat_list(config->cmd_queue); for (i = 0; i < config->workspace_outputs->length; ++i) { @@ -88,6 +101,7 @@ static bool file_exists(const char *path) { static void config_defaults(struct sway_config *config) { config->symbols = create_list(); config->modes = create_list(); + config->bars = create_list(); config->workspace_outputs = create_list(); config->criteria = create_list(); config->output_configs = create_list(); @@ -248,11 +262,26 @@ bool read_config(FILE *file, bool is_active) { } break; + case CMD_BLOCK_BAR: + if (block == CMD_BLOCK_END) { + block = CMD_BLOCK_BAR; + } else { + sway_log(L_ERROR, "Invalid block '%s'", line); + } + break; + case CMD_BLOCK_END: switch(block) { case CMD_BLOCK_MODE: sway_log(L_DEBUG, "End of mode block"); config->current_mode = config->modes->items[0]; + block = CMD_BLOCK_END; + break; + + case CMD_BLOCK_BAR: + sway_log(L_DEBUG, "End of bar block"); + config->current_bar = NULL; + block = CMD_BLOCK_END; break; case CMD_BLOCK_END: From b9e8accc51188976cf8ce4710841425b161b9b3f Mon Sep 17 00:00:00 2001 From: Mikkel Oscar Lyderik Date: Sun, 13 Dec 2015 23:33:54 +0100 Subject: [PATCH 03/19] Implement bar option: workspace_buttons --- sway/commands.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/sway/commands.c b/sway/commands.c index d6da1de3..cefad2ef 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -63,6 +63,7 @@ static sway_cmd cmd_splitv; static sway_cmd cmd_sticky; static sway_cmd cmd_workspace; static sway_cmd cmd_ws_auto_back_and_forth; +static sway_cmd bar_cmd_workspace_buttons; swayc_t *sp_view; int sp_index = 0; @@ -1518,6 +1519,27 @@ static struct cmd_handler handlers[] = { { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth }, }; +static struct cmd_results *bar_cmd_workspace_buttons(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "workspace_buttons", EXPECTED_EQUAL_TO, 1))) { + return error; + } + + if (!config->current_bar) { + return cmd_results_new(CMD_FAILURE, "workspace_buttons", "No bar defined."); + } + + if (strcasecmp("yes", argv[0]) == 0) { + config->current_bar->workspace_buttons = true; + } else if (strcasecmp("no", argv[0]) == 0) { + config->current_bar->workspace_buttons = false; + } else { + error = cmd_results_new(CMD_INVALID, "workspace_buttons", "Invalid value %s", argv[0]); + return error; + } + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} + static struct cmd_handler bar_handlers[] = { { "binding_mode_indicator", NULL }, { "bindsym", NULL }, @@ -1534,7 +1556,7 @@ static struct cmd_handler bar_handlers[] = { { "strip_workspace_numbers", NULL }, { "tray_output", NULL }, { "tray_padding", NULL }, - { "workspace_buttons", NULL }, + { "workspace_buttons", bar_cmd_workspace_buttons }, }; static int handler_compare(const void *_a, const void *_b) { From 0a8ec2638338c856adeb3c411d9d01b50eb9ce1e Mon Sep 17 00:00:00 2001 From: Mikkel Oscar Lyderik Date: Mon, 14 Dec 2015 00:00:11 +0100 Subject: [PATCH 04/19] Implement bar option: tray_padding [px] --- sway/commands.c | 28 +++++++++++++++++++++++++++- sway/config.c | 1 + 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/sway/commands.c b/sway/commands.c index cefad2ef..4e9d2796 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -63,6 +63,8 @@ static sway_cmd cmd_splitv; static sway_cmd cmd_sticky; static sway_cmd cmd_workspace; static sway_cmd cmd_ws_auto_back_and_forth; + +static sway_cmd bar_cmd_tray_padding; static sway_cmd bar_cmd_workspace_buttons; swayc_t *sp_view; @@ -1519,6 +1521,30 @@ static struct cmd_handler handlers[] = { { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth }, }; +static struct cmd_results *bar_cmd_tray_padding(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "tray_padding", EXPECTED_AT_LEAST, 1))) { + return error; + } + + if (!config->current_bar) { + return cmd_results_new(CMD_FAILURE, "tray_padding", "No bar defined."); + } + + int padding = atoi(argv[0]); + if (padding < 0) { + return cmd_results_new(CMD_INVALID, "tray_padding", + "Invalid padding value %s, minimum is 0", argv[0]); + } + + if (argc > 1 && strcasecmp("px", argv[1]) != 0) { + return cmd_results_new(CMD_INVALID, "tray_padding", + "Unknown unit %s", argv[1]); + } + config->current_bar->tray_padding = padding; + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} + static struct cmd_results *bar_cmd_workspace_buttons(int argc, char **argv) { struct cmd_results *error = NULL; if ((error = checkarg(argc, "workspace_buttons", EXPECTED_EQUAL_TO, 1))) { @@ -1555,7 +1581,7 @@ static struct cmd_handler bar_handlers[] = { { "status_command", NULL }, { "strip_workspace_numbers", NULL }, { "tray_output", NULL }, - { "tray_padding", NULL }, + { "tray_padding", bar_cmd_tray_padding }, { "workspace_buttons", bar_cmd_workspace_buttons }, }; diff --git a/sway/config.c b/sway/config.c index d5b75adf..bb7ecf9e 100644 --- a/sway/config.c +++ b/sway/config.c @@ -144,6 +144,7 @@ static void config_defaults(struct sway_config *config) { config->bar.workspace_buttons = true; config->bar.strip_workspace_numbers = false; config->bar.binding_mode_indicator = true; + config->bar.tray_padding = 2; } static char *get_config_path(void) { From cb9b157e03911a36136b42f189279053612f7e7c Mon Sep 17 00:00:00 2001 From: Mikkel Oscar Lyderik Date: Mon, 14 Dec 2015 14:52:34 +0100 Subject: [PATCH 05/19] Add tray_output not supported warning --- sway/commands.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sway/commands.c b/sway/commands.c index 4e9d2796..aeb14642 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -64,6 +64,7 @@ static sway_cmd cmd_sticky; static sway_cmd cmd_workspace; static sway_cmd cmd_ws_auto_back_and_forth; +static sway_cmd bar_cmd_tray_output; static sway_cmd bar_cmd_tray_padding; static sway_cmd bar_cmd_workspace_buttons; @@ -1521,6 +1522,11 @@ static struct cmd_handler handlers[] = { { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth }, }; +static struct cmd_results *bar_cmd_tray_output(int argc, char **argv) { + sway_log(L_ERROR, "warning: tray_output is not supported on wayland"); + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} + static struct cmd_results *bar_cmd_tray_padding(int argc, char **argv) { struct cmd_results *error = NULL; if ((error = checkarg(argc, "tray_padding", EXPECTED_AT_LEAST, 1))) { @@ -1580,7 +1586,7 @@ static struct cmd_handler bar_handlers[] = { { "seperator_symbol", NULL }, { "status_command", NULL }, { "strip_workspace_numbers", NULL }, - { "tray_output", NULL }, + { "tray_output", bar_cmd_tray_output }, { "tray_padding", bar_cmd_tray_padding }, { "workspace_buttons", bar_cmd_workspace_buttons }, }; From 4d17aa99194ac8a1511df93a3ec5edf44bcf61e6 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 14 Dec 2015 08:57:00 -0500 Subject: [PATCH 06/19] Revert "Make mouse key used for drag/resize configurable" This reverts commit 22916e9ebc130dbd365e6403730b9e0857977b8e. --- include/config.h | 2 - sway/commands.c | 17 +-------- sway/config.c | 2 - sway/input_state.c | 93 ++++++++++------------------------------------ 4 files changed, 21 insertions(+), 93 deletions(-) diff --git a/include/config.h b/include/config.h index 4e62ee68..04528e27 100644 --- a/include/config.h +++ b/include/config.h @@ -112,8 +112,6 @@ struct sway_config { struct bar_config bar; struct bar_config *current_bar; uint32_t floating_mod; - uint32_t dragging_key; - uint32_t resizing_key; enum swayc_layouts default_orientation; enum swayc_layouts default_layout; diff --git a/sway/commands.c b/sway/commands.c index 4e9d2796..ad43c4d5 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -379,14 +379,14 @@ static struct cmd_results *cmd_floating(int argc, char **argv) { static struct cmd_results *cmd_floating_mod(int argc, char **argv) { struct cmd_results *error = NULL; - if ((error = checkarg(argc, "floating_modifier", EXPECTED_AT_LEAST, 1))) { + if ((error = checkarg(argc, "floating_modifier", EXPECTED_EQUAL_TO, 1))) { return error; } int i, j; list_t *split = split_string(argv[0], "+"); config->floating_mod = 0; - // set modifier keys + // set modifer keys for (i = 0; i < split->length; ++i) { for (j = 0; j < (int)(sizeof(modifiers) / sizeof(struct modifier_key)); ++j) { if (strcasecmp(modifiers[j].name, split->items[i]) == 0) { @@ -399,19 +399,6 @@ static struct cmd_results *cmd_floating_mod(int argc, char **argv) { error = cmd_results_new(CMD_INVALID, "floating_modifier", "Unknown keys %s", argv[0]); return error; } - - if (argc >= 2) { - if (strcasecmp("inverse", argv[1]) == 0) { - config->dragging_key = M_RIGHT_CLICK; - config->resizing_key = M_LEFT_CLICK; - } else if (strcasecmp("normal", argv[1]) == 0) { - config->dragging_key = M_LEFT_CLICK; - config->resizing_key = M_RIGHT_CLICK; - } else { - error = cmd_results_new(CMD_INVALID, "floating_modifier", "Invalid definition %s", argv[1]); - return error; - } - } return cmd_results_new(CMD_SUCCESS, NULL, NULL); } diff --git a/sway/config.c b/sway/config.c index bb7ecf9e..966362cc 100644 --- a/sway/config.c +++ b/sway/config.c @@ -115,8 +115,6 @@ static void config_defaults(struct sway_config *config) { list_add(config->modes, config->current_mode); config->floating_mod = 0; - config->dragging_key = M_LEFT_CLICK; - config->resizing_key = M_RIGHT_CLICK; config->default_layout = L_NONE; config->default_orientation = L_NONE; // Flags diff --git a/sway/input_state.c b/sway/input_state.c index 24678f71..88506c92 100644 --- a/sway/input_state.c +++ b/sway/input_state.c @@ -194,16 +194,8 @@ void center_pointer_on(swayc_t *view) { // Mode set left/right click -static void pointer_mode_set_dragging(void) { - switch (config->dragging_key) { - case M_LEFT_CLICK: - set_initial_view(pointer_state.left.view); - break; - case M_RIGHT_CLICK: - set_initial_view(pointer_state.right.view); - break; - } - +static void pointer_mode_set_left(void) { + set_initial_view(pointer_state.left.view); if (initial.ptr->is_floating) { pointer_state.mode = M_DRAGGING | M_FLOATING; } else { @@ -216,15 +208,8 @@ static void pointer_mode_set_dragging(void) { } } -static void pointer_mode_set_resizing(void) { - switch (config->resizing_key) { - case M_LEFT_CLICK: - set_initial_view(pointer_state.left.view); - break; - case M_RIGHT_CLICK: - set_initial_view(pointer_state.right.view); - break; - } +static void pointer_mode_set_right(void) { + set_initial_view(pointer_state.right.view); // Setup locking information int midway_x = initial.ptr->x + initial.ptr->width/2; int midway_y = initial.ptr->y + initial.ptr->height/2; @@ -248,19 +233,15 @@ void pointer_mode_set(uint32_t button, bool condition) { // switch on drag/resize mode switch (pointer_state.mode & (M_DRAGGING | M_RESIZING)) { case M_DRAGGING: - // end drag mode when 'dragging' click is unpressed - if (config->dragging_key == M_LEFT_CLICK && !pointer_state.left.held) { - pointer_state.mode = 0; - } else if (config->dragging_key == M_RIGHT_CLICK && !pointer_state.right.held) { + // end drag mode when left click is unpressed + if (!pointer_state.left.held) { pointer_state.mode = 0; } break; case M_RESIZING: - // end resize mode when 'resizing' click is unpressed - if (config->resizing_key == M_LEFT_CLICK && !pointer_state.left.held) { - pointer_state.mode = 0; - } else if (config->resizing_key == M_RIGHT_CLICK && !pointer_state.right.held) { + // end resize mode when right click is unpressed + if (!pointer_state.right.held) { pointer_state.mode = 0; } break; @@ -274,27 +255,19 @@ void pointer_mode_set(uint32_t button, bool condition) { // Set mode depending on current button press switch (button) { - // Start left-click mode + // Start dragging mode case M_LEFT_CLICK: // if button release dont do anything if (pointer_state.left.held) { - if (config->dragging_key == M_LEFT_CLICK) { - pointer_mode_set_dragging(); - } else if (config->resizing_key == M_LEFT_CLICK) { - pointer_mode_set_resizing(); - } + pointer_mode_set_left(); } break; - // Start right-click mode + // Start resize mode case M_RIGHT_CLICK: // if button release dont do anyhting if (pointer_state.right.held) { - if (config->dragging_key == M_RIGHT_CLICK) { - pointer_mode_set_dragging(); - } else if (config->resizing_key == M_RIGHT_CLICK) { - pointer_mode_set_resizing(); - } + pointer_mode_set_right(); } break; } @@ -314,17 +287,8 @@ void pointer_mode_update(void) { switch (pointer_state.mode) { case M_FLOATING | M_DRAGGING: // Update position - switch (config->resizing_key) { - case M_LEFT_CLICK: - dx -= pointer_state.left.x; - dy -= pointer_state.left.y; - break; - case M_RIGHT_CLICK: - dx -= pointer_state.right.x; - dy -= pointer_state.right.y; - break; - } - + dx -= pointer_state.left.x; + dy -= pointer_state.left.y; if (initial.x + dx != initial.ptr->x) { initial.ptr->x = initial.x + dx; } @@ -335,19 +299,9 @@ void pointer_mode_update(void) { break; case M_FLOATING | M_RESIZING: - switch (config->resizing_key) { - case M_LEFT_CLICK: - dx -= pointer_state.left.x; - dy -= pointer_state.left.y; - initial.ptr = pointer_state.left.view; - break; - case M_RIGHT_CLICK: - dx -= pointer_state.right.x; - dy -= pointer_state.right.y; - initial.ptr = pointer_state.right.view; - break; - } - + dx -= pointer_state.right.x; + dy -= pointer_state.right.y; + initial.ptr = pointer_state.right.view; if (lock.left) { if (initial.w + dx > min_sane_w) { initial.ptr->width = initial.w + dx; @@ -387,17 +341,8 @@ void pointer_mode_update(void) { break; case M_TILING | M_RESIZING: - switch (config->resizing_key) { - case M_LEFT_CLICK: - dx -= pointer_state.left.x; - dy -= pointer_state.left.y; - break; - case M_RIGHT_CLICK: - dx -= pointer_state.right.x; - dy -= pointer_state.right.y; - break; - } - + dx -= pointer_state.right.x; + dy -= pointer_state.right.y; // resize if we can if (initial.horiz.ptr) { if (lock.left) { From cc08daded412966ba9068ad9ac63c5adea9ef5d4 Mon Sep 17 00:00:00 2001 From: Mikkel Oscar Lyderik Date: Mon, 14 Dec 2015 14:56:28 +0100 Subject: [PATCH 07/19] Implement bar option: strip_workspace_numbers --- sway/commands.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/sway/commands.c b/sway/commands.c index aeb14642..f5593b05 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -64,6 +64,7 @@ static sway_cmd cmd_sticky; static sway_cmd cmd_workspace; static sway_cmd cmd_ws_auto_back_and_forth; +static sway_cmd bar_cmd_strip_workspace_numbers; static sway_cmd bar_cmd_tray_output; static sway_cmd bar_cmd_tray_padding; static sway_cmd bar_cmd_workspace_buttons; @@ -1522,6 +1523,29 @@ static struct cmd_handler handlers[] = { { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth }, }; +static struct cmd_results *bar_cmd_strip_workspace_numbers(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "strip_workspace_numbers", EXPECTED_EQUAL_TO, 1))) { + return error; + } + + if (!config->current_bar) { + return cmd_results_new(CMD_FAILURE, "strip_workspace_numbers", "No bar defined."); + } + + if (strcasecmp("yes", argv[0]) == 0) { + config->current_bar->strip_workspace_numbers = true; + sway_log(L_DEBUG, "Stripping workspace numbers on bar"); + } else if (strcasecmp("no", argv[0]) == 0) { + config->current_bar->strip_workspace_numbers = false; + sway_log(L_DEBUG, "Enabling workspace numbers on bar"); + } else { + error = cmd_results_new(CMD_INVALID, "strip_workspace_numbers", "Invalid value %s", argv[0]); + return error; + } + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} + static struct cmd_results *bar_cmd_tray_output(int argc, char **argv) { sway_log(L_ERROR, "warning: tray_output is not supported on wayland"); return cmd_results_new(CMD_SUCCESS, NULL, NULL); @@ -1585,7 +1609,7 @@ static struct cmd_handler bar_handlers[] = { { "position", NULL }, { "seperator_symbol", NULL }, { "status_command", NULL }, - { "strip_workspace_numbers", NULL }, + { "strip_workspace_numbers", bar_cmd_strip_workspace_numbers }, { "tray_output", bar_cmd_tray_output }, { "tray_padding", bar_cmd_tray_padding }, { "workspace_buttons", bar_cmd_workspace_buttons }, From bd0c58e85a2b6c0e7541e7270e6d7bcca940d7ed Mon Sep 17 00:00:00 2001 From: Mikkel Oscar Lyderik Date: Mon, 14 Dec 2015 15:12:05 +0100 Subject: [PATCH 08/19] Implement bar option: position --- sway/commands.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/sway/commands.c b/sway/commands.c index f5593b05..5372d3e9 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -64,6 +64,7 @@ static sway_cmd cmd_sticky; static sway_cmd cmd_workspace; static sway_cmd cmd_ws_auto_back_and_forth; +static sway_cmd bar_cmd_position; static sway_cmd bar_cmd_strip_workspace_numbers; static sway_cmd bar_cmd_tray_output; static sway_cmd bar_cmd_tray_padding; @@ -1523,6 +1524,33 @@ static struct cmd_handler handlers[] = { { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth }, }; +static struct cmd_results *bar_cmd_position(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "position", EXPECTED_EQUAL_TO, 1))) { + return error; + } + + if (!config->current_bar) { + return cmd_results_new(CMD_FAILURE, "position", "No bar defined."); + } + + if (strcasecmp("top", argv[0]) == 0) { + config->current_bar->position = DESKTOP_SHELL_PANEL_POSITION_TOP; + } else if (strcasecmp("bottom", argv[0]) == 0) { + config->current_bar->position = DESKTOP_SHELL_PANEL_POSITION_BOTTOM; + } else if (strcasecmp("left", argv[0]) == 0) { + config->current_bar->position = DESKTOP_SHELL_PANEL_POSITION_LEFT; + } else if (strcasecmp("right", argv[0]) == 0) { + config->current_bar->position = DESKTOP_SHELL_PANEL_POSITION_RIGHT; + } else { + error = cmd_results_new(CMD_INVALID, "position", "Invalid value %s", argv[0]); + return error; + } + + sway_log(L_DEBUG, "Setting bar position '%s'", argv[0]); + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} + static struct cmd_results *bar_cmd_strip_workspace_numbers(int argc, char **argv) { struct cmd_results *error = NULL; if ((error = checkarg(argc, "strip_workspace_numbers", EXPECTED_EQUAL_TO, 1))) { @@ -1606,7 +1634,7 @@ static struct cmd_handler bar_handlers[] = { { "mode", NULL }, { "modifier", NULL }, { "output", NULL }, - { "position", NULL }, + { "position", bar_cmd_position }, { "seperator_symbol", NULL }, { "status_command", NULL }, { "strip_workspace_numbers", bar_cmd_strip_workspace_numbers }, From b00c106460dfa50959be5fae864d3b10ed4ca1b3 Mon Sep 17 00:00:00 2001 From: Mikkel Oscar Lyderik Date: Mon, 14 Dec 2015 15:24:27 +0100 Subject: [PATCH 09/19] Add more debug logging to bar option parsing --- sway/commands.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sway/commands.c b/sway/commands.c index 5372d3e9..b9cc1a69 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -1600,6 +1600,7 @@ static struct cmd_results *bar_cmd_tray_padding(int argc, char **argv) { "Unknown unit %s", argv[1]); } config->current_bar->tray_padding = padding; + sway_log(L_DEBUG, "Enabling tray padding of %d px", padding); return cmd_results_new(CMD_SUCCESS, NULL, NULL); } @@ -1615,8 +1616,10 @@ static struct cmd_results *bar_cmd_workspace_buttons(int argc, char **argv) { if (strcasecmp("yes", argv[0]) == 0) { config->current_bar->workspace_buttons = true; + sway_log(L_DEBUG, "Enabling workspace buttons on bar"); } else if (strcasecmp("no", argv[0]) == 0) { config->current_bar->workspace_buttons = false; + sway_log(L_DEBUG, "Disabling workspace buttons on bar"); } else { error = cmd_results_new(CMD_INVALID, "workspace_buttons", "Invalid value %s", argv[0]); return error; From 211bc7159973274e70b24c3062c33eef69823e48 Mon Sep 17 00:00:00 2001 From: Mikkel Oscar Lyderik Date: Mon, 14 Dec 2015 16:38:49 +0100 Subject: [PATCH 10/19] Use tabs instead of spaces --- sway/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sway/config.c b/sway/config.c index 966362cc..bd3cf4e6 100644 --- a/sway/config.c +++ b/sway/config.c @@ -151,7 +151,7 @@ static char *get_config_path(void) { "$XDG_CONFIG_HOME/sway/config", "$HOME/.i3/config", "$XDG_CONFIG_HOME/i3/config", - FALLBACK_CONFIG_DIR "/config", + FALLBACK_CONFIG_DIR "/config", "/etc/i3/config", }; From 45b959f601d103c9c308807b55f62f1859556b59 Mon Sep 17 00:00:00 2001 From: Mikkel Oscar Lyderik Date: Mon, 14 Dec 2015 17:07:31 +0100 Subject: [PATCH 11/19] Move numlen(1) to sway/util.c --- include/util.h | 5 +++++ sway/util.c | 10 ++++++++++ swaygrab/main.c | 11 +---------- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/include/util.h b/include/util.h index 8e65e6d6..9cb861dd 100644 --- a/include/util.h +++ b/include/util.h @@ -6,4 +6,9 @@ */ int wrap(int i, int max); +/** + * Count number of digits in int + */ +int numlen(int n); + #endif diff --git a/sway/util.c b/sway/util.c index 9a59ddf9..ed6d033f 100644 --- a/sway/util.c +++ b/sway/util.c @@ -3,3 +3,13 @@ int wrap(int i, int max) { return ((i % max) + max) % max; } + +int numlen(int n) { + if (n >= 1000000) return 7; + if (n >= 100000) return 6; + if (n >= 10000) return 5; + if (n >= 1000) return 4; + if (n >= 100) return 3; + if (n >= 10) return 2; + return 1; +} diff --git a/swaygrab/main.c b/swaygrab/main.c index 681a6da4..2c6cf2dd 100644 --- a/swaygrab/main.c +++ b/swaygrab/main.c @@ -8,21 +8,12 @@ #include #include "log.h" #include "ipc-client.h" +#include "util.h" void sway_terminate(void) { exit(EXIT_FAILURE); } -int numlen(int n) { - if (n >= 1000000) return 7; - if (n >= 100000) return 6; - if (n >= 10000) return 5; - if (n >= 1000) return 4; - if (n >= 100) return 3; - if (n >= 10) return 2; - return 1; -} - void grab_and_apply_magick(const char *file, const char *output, int socketfd, int raw) { uint32_t len = strlen(output); From b65e3482333f28d436a478a9e16157cb8f822cfc Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 14 Dec 2015 11:11:29 -0500 Subject: [PATCH 12/19] Fix crash in bar { } blocks --- sway/commands.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sway/commands.c b/sway/commands.c index b0235dba..604e10aa 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -1782,7 +1782,11 @@ struct cmd_results *config_command(char *exec, enum cmd_status block) { if (argc>1 && (*argv[1] == '\"' || *argv[1] == '\'')) { strip_quotes(argv[1]); } - results = handler->handle(argc-1, argv+1); + if (handler->handle) { + results = handler->handle(argc-1, argv+1); + } else { + results = cmd_results_new(CMD_INVALID, argv[0], "This command is shimmed, but unimplemented"); + } cleanup: free_argv(argc, argv); return results; From 774ffbe0d5eff86710fc8d219871d181f6927c04 Mon Sep 17 00:00:00 2001 From: Streetwalrus Einstein Date: Mon, 14 Dec 2015 18:13:44 +0200 Subject: [PATCH 13/19] Detect proprietary AMD drivers too --- sway/main.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sway/main.c b/sway/main.c index 9a5e351c..382e7ca2 100644 --- a/sway/main.c +++ b/sway/main.c @@ -36,7 +36,7 @@ static void wlc_log_handler(enum wlc_log_type type, const char *str) { } } -void detect_nvidia() { +void detect_proprietary() { FILE *f = fopen("/proc/modules", "r"); if (!f) { return; @@ -48,6 +48,11 @@ void detect_nvidia() { free(line); break; } + if (strstr(line, "fglrx")) { + fprintf(stderr, "\x1B[1;31mWarning: Proprietary AMD drivers do NOT support Wayland. Use radeon.\x1B[0m\n"); + free(line); + break; + } free(line); } fclose(f); @@ -161,7 +166,7 @@ int main(int argc, char **argv) { } setenv("WLC_DIM", "0", 0); wlc_log_set_handler(wlc_log_handler); - detect_nvidia(); + detect_proprietary(); /* Changing code earlier than this point requires detailed review */ /* (That code runs as root on systems without logind, and wlc_init drops to From cf56c41c10b85882d7563c95abe185f450b4ec2b Mon Sep 17 00:00:00 2001 From: Mikkel Oscar Lyderik Date: Mon, 14 Dec 2015 17:16:38 +0100 Subject: [PATCH 14/19] Move sway/util.c to common/util.c --- common/CMakeLists.txt | 1 + {sway => common}/util.c | 0 sway/CMakeLists.txt | 1 - 3 files changed, 1 insertion(+), 1 deletion(-) rename {sway => common}/util.c (100%) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index f7d44ec5..a40f096d 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -2,6 +2,7 @@ add_library(sway-common ipc-client.c list.c log.c + util.c readline.c stringop.c ) diff --git a/sway/util.c b/common/util.c similarity index 100% rename from sway/util.c rename to common/util.c diff --git a/sway/CMakeLists.txt b/sway/CMakeLists.txt index aa553492..894163b8 100644 --- a/sway/CMakeLists.txt +++ b/sway/CMakeLists.txt @@ -21,7 +21,6 @@ add_executable(sway main.c output.c resize.c - util.c workspace.c ) From c6b13163c93f7464ae21fa238fadc238b8ef2936 Mon Sep 17 00:00:00 2001 From: Mikkel Oscar Lyderik Date: Mon, 14 Dec 2015 16:24:01 +0100 Subject: [PATCH 15/19] Add initial support for custom bar-id --- include/config.h | 7 +++++++ sway/commands.c | 14 +++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/include/config.h b/include/config.h index 04528e27..0f3ce550 100644 --- a/include/config.h +++ b/include/config.h @@ -72,6 +72,13 @@ struct bar_config { * In "show" mode, it will always be shown on top of the active workspace. */ char *hidden_state; + /** + * Id name used to identify the bar through IPC. + * + * Defaults to bar-x, where x corresponds to the position of the + * embedding bar block in the config file (bar-0, bar-1, ...). + */ + char *id; uint32_t modifier; enum desktop_shell_panel_position position; char *status_command; diff --git a/sway/commands.c b/sway/commands.c index b0235dba..ea138dfc 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -15,6 +15,7 @@ #include "layout.h" #include "focus.h" #include "log.h" +#include "util.h" #include "workspace.h" #include "commands.h" #include "container.h" @@ -1124,9 +1125,20 @@ static struct cmd_results *cmd_bar(int argc, char **argv) { bar->tray_padding = config->bar.tray_padding; list_add(config->bars, bar); + // set bar id + int i; + for (i = 0; i < config->bars->length; ++i) { + if (bar == config->bars->items[i]) { + const int len = 5 + numlen(i); // "bar-" + i + \0 + bar->id = malloc(len * sizeof(char)); + snprintf(bar->id, len, "bar-%d", i); + break; + } + } + // Set current bar config->current_bar = bar; - sway_log(L_DEBUG, "Configuring bar"); + sway_log(L_DEBUG, "Configuring bar %s", bar->id); return cmd_results_new(CMD_BLOCK_BAR, NULL, NULL); } From 2cedf88273dcec1f79ecb20582c876584db10d36 Mon Sep 17 00:00:00 2001 From: Mikkel Oscar Lyderik Date: Mon, 14 Dec 2015 16:26:59 +0100 Subject: [PATCH 16/19] Add bar id to debug logs --- sway/commands.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sway/commands.c b/sway/commands.c index ea138dfc..ba16260f 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -1546,7 +1546,7 @@ static struct cmd_results *bar_cmd_position(int argc, char **argv) { return error; } - sway_log(L_DEBUG, "Setting bar position '%s'", argv[0]); + sway_log(L_DEBUG, "Setting bar position '%s' for bar: %s", argv[0], config->current_bar->id); return cmd_results_new(CMD_SUCCESS, NULL, NULL); } @@ -1562,10 +1562,10 @@ static struct cmd_results *bar_cmd_strip_workspace_numbers(int argc, char **argv if (strcasecmp("yes", argv[0]) == 0) { config->current_bar->strip_workspace_numbers = true; - sway_log(L_DEBUG, "Stripping workspace numbers on bar"); + sway_log(L_DEBUG, "Stripping workspace numbers on bar: %s", config->current_bar->id); } else if (strcasecmp("no", argv[0]) == 0) { config->current_bar->strip_workspace_numbers = false; - sway_log(L_DEBUG, "Enabling workspace numbers on bar"); + sway_log(L_DEBUG, "Enabling workspace numbers on bar: %s", config->current_bar->id); } else { error = cmd_results_new(CMD_INVALID, "strip_workspace_numbers", "Invalid value %s", argv[0]); return error; @@ -1599,7 +1599,7 @@ static struct cmd_results *bar_cmd_tray_padding(int argc, char **argv) { "Unknown unit %s", argv[1]); } config->current_bar->tray_padding = padding; - sway_log(L_DEBUG, "Enabling tray padding of %d px", padding); + sway_log(L_DEBUG, "Enabling tray padding of %d px on bar: %s", padding, config->current_bar->id); return cmd_results_new(CMD_SUCCESS, NULL, NULL); } @@ -1615,10 +1615,10 @@ static struct cmd_results *bar_cmd_workspace_buttons(int argc, char **argv) { if (strcasecmp("yes", argv[0]) == 0) { config->current_bar->workspace_buttons = true; - sway_log(L_DEBUG, "Enabling workspace buttons on bar"); + sway_log(L_DEBUG, "Enabling workspace buttons on bar: %s", config->current_bar->id); } else if (strcasecmp("no", argv[0]) == 0) { config->current_bar->workspace_buttons = false; - sway_log(L_DEBUG, "Disabling workspace buttons on bar"); + sway_log(L_DEBUG, "Disabling workspace buttons on bar: %s", config->current_bar->id); } else { error = cmd_results_new(CMD_INVALID, "workspace_buttons", "Invalid value %s", argv[0]); return error; From 401333e7c7d61d85836f6bdec926fd860d76c149 Mon Sep 17 00:00:00 2001 From: Mikkel Oscar Lyderik Date: Mon, 14 Dec 2015 18:29:26 +0100 Subject: [PATCH 17/19] Implement bar option: id If the id is defined by another bar it will just use the default id for the bar. Typically `bar-x`. If the id command is used multiple times within a bar block, the last one will 'win'. --- sway/commands.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/sway/commands.c b/sway/commands.c index c565adbb..7eb076c4 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -65,6 +65,7 @@ static sway_cmd cmd_sticky; static sway_cmd cmd_workspace; static sway_cmd cmd_ws_auto_back_and_forth; +static sway_cmd bar_cmd_id; static sway_cmd bar_cmd_position; static sway_cmd bar_cmd_strip_workspace_numbers; static sway_cmd bar_cmd_tray_output; @@ -1523,6 +1524,35 @@ static struct cmd_handler handlers[] = { { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth }, }; +static struct cmd_results *bar_cmd_id(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "id", EXPECTED_EQUAL_TO, 1))) { + return error; + } + + const char *name = argv[0]; + const char *oldname = config->current_bar->id; + + // check if id is used by a previously defined bar + int i; + for (i = 0; i < config->bars->length; ++i) { + struct bar_config *find = config->bars->items[i]; + if (strcmp(name, find->id) == 0 && config->current_bar != find) { + return cmd_results_new(CMD_FAILURE, "id", + "Id '%s' already defined for another bar. Id unchanged (%s).", + name, oldname); + } + } + + sway_log(L_DEBUG, "Renaming bar: '%s' to '%s'", oldname, name); + + // free old bar id + free(config->current_bar->id); + + config->current_bar->id = strdup(name); + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} + static struct cmd_results *bar_cmd_position(int argc, char **argv) { struct cmd_results *error = NULL; if ((error = checkarg(argc, "position", EXPECTED_EQUAL_TO, 1))) { @@ -1632,7 +1662,7 @@ static struct cmd_handler bar_handlers[] = { { "colors", NULL }, { "font", NULL }, { "hidden_state", NULL }, - { "id", NULL }, + { "id", bar_cmd_id }, { "mode", NULL }, { "modifier", NULL }, { "output", NULL }, From d6cd37d87346e4f1b89219a04e790dac1e1dfdfe Mon Sep 17 00:00:00 2001 From: Mikkel Oscar Lyderik Date: Mon, 14 Dec 2015 19:52:25 +0100 Subject: [PATCH 18/19] Implement bar option: hidden_state --- sway/commands.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/sway/commands.c b/sway/commands.c index 7eb076c4..6d40344d 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -65,6 +65,7 @@ static sway_cmd cmd_sticky; static sway_cmd cmd_workspace; static sway_cmd cmd_ws_auto_back_and_forth; +static sway_cmd bar_cmd_hidden_state; static sway_cmd bar_cmd_id; static sway_cmd bar_cmd_position; static sway_cmd bar_cmd_strip_workspace_numbers; @@ -1524,6 +1525,30 @@ static struct cmd_handler handlers[] = { { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth }, }; +static struct cmd_results *bar_cmd_hidden_state(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "hidden_state", EXPECTED_EQUAL_TO, 1))) { + return error; + } + + const char *state = argv[0]; + char *old_state = config->current_bar->hidden_state; + + if (strcasecmp("hide", state) == 0) { + config->current_bar->hidden_state = strdup(state); + } else if(strcmp("show", state) == 0) { + config->current_bar->hidden_state = strdup(state); + } else { + return cmd_results_new(CMD_INVALID, "hidden_state", "Invalid value %s", state); + } + + sway_log(L_DEBUG, "Setting hidden_state: '%s' for bar: %s", state, config->current_bar->id); + + // free old state + free(old_state); + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} + static struct cmd_results *bar_cmd_id(int argc, char **argv) { struct cmd_results *error = NULL; if ((error = checkarg(argc, "id", EXPECTED_EQUAL_TO, 1))) { @@ -1661,7 +1686,7 @@ static struct cmd_handler bar_handlers[] = { { "bindsym", NULL }, { "colors", NULL }, { "font", NULL }, - { "hidden_state", NULL }, + { "hidden_state", bar_cmd_hidden_state }, { "id", bar_cmd_id }, { "mode", NULL }, { "modifier", NULL }, From 0d1eb5553c09e78f6071c75ba53c692be9617406 Mon Sep 17 00:00:00 2001 From: Mikkel Oscar Lyderik Date: Mon, 14 Dec 2015 20:15:58 +0100 Subject: [PATCH 19/19] Implement bar option: mode --- sway/commands.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/sway/commands.c b/sway/commands.c index 6d40344d..a394c69d 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -65,6 +65,7 @@ static sway_cmd cmd_sticky; static sway_cmd cmd_workspace; static sway_cmd cmd_ws_auto_back_and_forth; +static sway_cmd bar_cmd_mode; static sway_cmd bar_cmd_hidden_state; static sway_cmd bar_cmd_id; static sway_cmd bar_cmd_position; @@ -1549,6 +1550,32 @@ static struct cmd_results *bar_cmd_hidden_state(int argc, char **argv) { return cmd_results_new(CMD_SUCCESS, NULL, NULL); } +static struct cmd_results *bar_cmd_mode(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "mode", EXPECTED_EQUAL_TO, 1))) { + return error; + } + + const char *mode = argv[0]; + char *old_mode = config->current_bar->mode; + + if (strcasecmp("dock", mode) == 0) { + config->current_bar->mode = strdup(mode); + } else if(strcmp("hide", mode) == 0) { + config->current_bar->mode = strdup(mode); + } else if(strcmp("invisible", mode) == 0) { + config->current_bar->mode = strdup(mode); + } else { + return cmd_results_new(CMD_INVALID, "mode", "Invalid value %s", mode); + } + + sway_log(L_DEBUG, "Setting mode: '%s' for bar: %s", mode, config->current_bar->id); + + // free old mode + free(old_mode); + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} + static struct cmd_results *bar_cmd_id(int argc, char **argv) { struct cmd_results *error = NULL; if ((error = checkarg(argc, "id", EXPECTED_EQUAL_TO, 1))) { @@ -1688,7 +1715,7 @@ static struct cmd_handler bar_handlers[] = { { "font", NULL }, { "hidden_state", bar_cmd_hidden_state }, { "id", bar_cmd_id }, - { "mode", NULL }, + { "mode", bar_cmd_mode }, { "modifier", NULL }, { "output", NULL }, { "position", bar_cmd_position },