diff options
Diffstat (limited to 'sway/commands')
-rw-r--r-- | sway/commands/gaps.c | 306 | ||||
-rw-r--r-- | sway/commands/layout.c | 3 | ||||
-rw-r--r-- | sway/commands/workspace.c | 38 |
3 files changed, 193 insertions, 154 deletions
diff --git a/sway/commands/gaps.c b/sway/commands/gaps.c index d676e475..2e0876a9 100644 --- a/sway/commands/gaps.c +++ b/sway/commands/gaps.c @@ -1,4 +1,5 @@ #include <string.h> +#include <strings.h> #include "sway/commands.h" #include "sway/config.h" #include "sway/tree/arrange.h" @@ -13,172 +14,173 @@ enum gaps_op { GAPS_OP_SUBTRACT }; -enum gaps_scope { - GAPS_SCOPE_ALL, - GAPS_SCOPE_WORKSPACE, - GAPS_SCOPE_CURRENT +struct gaps_data { + bool inner; + enum gaps_op operation; + int amount; }; -struct cmd_results *cmd_gaps(int argc, char **argv) { - struct cmd_results *error = checkarg(argc, "gaps", EXPECTED_AT_LEAST, 1); - if (error) { +// gaps edge_gaps on|off|toggle +static struct cmd_results *gaps_edge_gaps(int argc, char **argv) { + struct cmd_results *error; + if ((error = checkarg(argc, "gaps", EXPECTED_AT_LEAST, 2))) { return error; } - if (strcmp(argv[0], "edge_gaps") == 0) { - if ((error = checkarg(argc, "gaps", EXPECTED_AT_LEAST, 2))) { - return error; - } - - if (strcmp(argv[1], "on") == 0) { - config->edge_gaps = true; - } else if (strcmp(argv[1], "off") == 0) { - config->edge_gaps = false; - } else if (strcmp(argv[1], "toggle") == 0) { - if (!config->active) { - return cmd_results_new(CMD_INVALID, "gaps", - "Cannot toggle gaps while not running."); - } - config->edge_gaps = !config->edge_gaps; - } else { + if (strcmp(argv[1], "on") == 0) { + config->edge_gaps = true; + } else if (strcmp(argv[1], "off") == 0) { + config->edge_gaps = false; + } else if (strcmp(argv[1], "toggle") == 0) { + if (!config->active) { return cmd_results_new(CMD_INVALID, "gaps", - "gaps edge_gaps on|off|toggle"); + "Cannot toggle gaps while not running."); } - arrange_root(); + config->edge_gaps = !config->edge_gaps; } else { - int amount_idx = 0; // the current index in argv - enum gaps_op op = GAPS_OP_SET; - enum gaps_scope scope = GAPS_SCOPE_ALL; - bool inner = true; - - if (strcmp(argv[0], "inner") == 0) { - amount_idx++; - inner = true; - } else if (strcmp(argv[0], "outer") == 0) { - amount_idx++; - inner = false; - } + return cmd_results_new(CMD_INVALID, "gaps", + "gaps edge_gaps on|off|toggle"); + } + arrange_root(); + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} - // If one of the long variants of the gaps command is used - // (which starts with inner|outer) check the number of args - if (amount_idx > 0) { // if we've seen inner|outer - if (argc > 2) { // check the longest variant - error = checkarg(argc, "gaps", EXPECTED_EQUAL_TO, 4); - if (error) { - return error; - } - } else { // check the next longest format - error = checkarg(argc, "gaps", EXPECTED_EQUAL_TO, 2); - if (error) { - return error; - } - } - } else { - error = checkarg(argc, "gaps", EXPECTED_EQUAL_TO, 1); - if (error) { - return error; - } - } +// gaps inner|outer <px> +static struct cmd_results *gaps_set_defaults(int argc, char **argv) { + struct cmd_results *error = checkarg(argc, "gaps", EXPECTED_EQUAL_TO, 2); + if (error) { + return error; + } - if (argc == 4) { - // Long format: all|workspace|current. - if (strcmp(argv[amount_idx], "all") == 0) { - amount_idx++; - scope = GAPS_SCOPE_ALL; - } else if (strcmp(argv[amount_idx], "workspace") == 0) { - amount_idx++; - scope = GAPS_SCOPE_WORKSPACE; - } else if (strcmp(argv[amount_idx], "current") == 0) { - amount_idx++; - scope = GAPS_SCOPE_CURRENT; - } - - // Long format: set|plus|minus - if (strcmp(argv[amount_idx], "set") == 0) { - amount_idx++; - op = GAPS_OP_SET; - } else if (strcmp(argv[amount_idx], "plus") == 0) { - amount_idx++; - op = GAPS_OP_ADD; - } else if (strcmp(argv[amount_idx], "minus") == 0) { - amount_idx++; - op = GAPS_OP_SUBTRACT; - } - } + bool inner; + if (strcasecmp(argv[0], "inner") == 0) { + inner = true; + } else if (strcasecmp(argv[0], "outer") == 0) { + inner = false; + } else { + return cmd_results_new(CMD_INVALID, "gaps", + "Expected 'gaps inner|outer <px>'"); + } - char *end; - double val = strtod(argv[amount_idx], &end); - - if (strlen(end) && val == 0.0) { // invalid <amount> - // guess which variant of the command was attempted - if (argc == 1) { - return cmd_results_new(CMD_INVALID, "gaps", "gaps <amount>"); - } - if (argc == 2) { - return cmd_results_new(CMD_INVALID, "gaps", - "gaps inner|outer <amount>"); - } - return cmd_results_new(CMD_INVALID, "gaps", - "gaps inner|outer all|workspace|current set|plus|minus <amount>"); - } + char *end; + int amount = strtol(argv[1], &end, 10); + if (strlen(end) && strcasecmp(end, "px") != 0) { + return cmd_results_new(CMD_INVALID, "gaps", + "Expected 'gaps inner|outer <px>'"); + } + if (amount < 0) { + amount = 0; + } - if (amount_idx == 0) { // gaps <amount> - config->gaps_inner = val; - config->gaps_outer = val; - arrange_root(); - return cmd_results_new(CMD_SUCCESS, NULL, NULL); - } - // Other variants. The middle-length variant (gaps inner|outer <amount>) - // just defaults the scope to "all" and defaults the op to "set". - - double total; - switch (op) { - case GAPS_OP_SUBTRACT: { - total = (inner ? config->gaps_inner : config->gaps_outer) - val; - if (total < 0) { - total = 0; - } - break; - } - case GAPS_OP_ADD: { - total = (inner ? config->gaps_inner : config->gaps_outer) + val; - break; - } - case GAPS_OP_SET: { - total = val; - break; - } - } + if (inner) { + config->gaps_inner = amount; + } else { + config->gaps_outer = amount; + } + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} - if (scope == GAPS_SCOPE_ALL) { - if (inner) { - config->gaps_inner = total; - } else { - config->gaps_outer = total; - } - arrange_root(); - } else { - if (scope == GAPS_SCOPE_WORKSPACE) { - struct sway_workspace *ws = config->handler_context.workspace; - ws->has_gaps = true; - if (inner) { - ws->gaps_inner = total; - } else { - ws->gaps_outer = total; - } - arrange_workspace(ws); - } else { - struct sway_container *c = config->handler_context.container; - c->has_gaps = true; - if (inner) { - c->gaps_inner = total; - } else { - c->gaps_outer = total; - } - arrange_workspace(c->workspace); - } - } +static void configure_gaps(struct sway_workspace *ws, void *_data) { + struct gaps_data *data = _data; + int *prop = data->inner ? &ws->gaps_inner : &ws->gaps_outer; + + switch (data->operation) { + case GAPS_OP_SET: + *prop = data->amount; + break; + case GAPS_OP_ADD: + *prop += data->amount; + break; + case GAPS_OP_SUBTRACT: + *prop -= data->amount; + break; + } + if (*prop < 0) { + *prop = 0; + } + arrange_workspace(ws); +} + +// gaps inner|outer current|all set|plus|minus <px> +static struct cmd_results *gaps_set_runtime(int argc, char **argv) { + struct cmd_results *error = checkarg(argc, "gaps", EXPECTED_EQUAL_TO, 4); + if (error) { + return error; + } + + struct gaps_data data; + + if (strcasecmp(argv[0], "inner") == 0) { + data.inner = true; + } else if (strcasecmp(argv[0], "outer") == 0) { + data.inner = false; + } else { + return cmd_results_new(CMD_INVALID, "gaps", + "Expected 'gaps inner|outer current|all set|plus|minus <px>'"); + } + + bool all; + if (strcasecmp(argv[1], "current") == 0) { + all = false; + } else if (strcasecmp(argv[1], "all") == 0) { + all = true; + } else { + return cmd_results_new(CMD_INVALID, "gaps", + "Expected 'gaps inner|outer current|all set|plus|minus <px>'"); + } + + if (strcasecmp(argv[2], "set") == 0) { + data.operation = GAPS_OP_SET; + } else if (strcasecmp(argv[2], "plus") == 0) { + data.operation = GAPS_OP_ADD; + } else if (strcasecmp(argv[2], "minus") == 0) { + data.operation = GAPS_OP_SUBTRACT; + } else { + return cmd_results_new(CMD_INVALID, "gaps", + "Expected 'gaps inner|outer current|all set|plus|minus <px>'"); + } + + char *end; + data.amount = strtol(argv[3], &end, 10); + if (strlen(end) && strcasecmp(end, "px") != 0) { + return cmd_results_new(CMD_INVALID, "gaps", + "Expected 'gaps inner|outer current|all set|plus|minus <px>'"); + } + + if (all) { + root_for_each_workspace(configure_gaps, &data); + } else { + configure_gaps(config->handler_context.workspace, &data); } return cmd_results_new(CMD_SUCCESS, NULL, NULL); } + +// gaps edge_gaps on|off|toggle +// gaps inner|outer <px> - sets defaults for workspaces +// gaps inner|outer current|all set|plus|minus <px> - runtime only +struct cmd_results *cmd_gaps(int argc, char **argv) { + struct cmd_results *error = checkarg(argc, "gaps", EXPECTED_AT_LEAST, 2); + if (error) { + return error; + } + + if (strcmp(argv[0], "edge_gaps") == 0) { + return gaps_edge_gaps(argc, argv); + } + + if (argc == 2) { + return gaps_set_defaults(argc, argv); + } + if (argc == 4) { + if (config->active) { + return gaps_set_runtime(argc, argv); + } else { + return cmd_results_new(CMD_INVALID, "gaps", + "This syntax can only be used when sway is running"); + } + } + return cmd_results_new(CMD_INVALID, "gaps", + "Expected 'gaps inner|outer <px>' or " + "'gaps inner|outer current|all set|plus|minus <px>'"); +} diff --git a/sway/commands/layout.c b/sway/commands/layout.c index ef3ec1cb..c2ce2e78 100644 --- a/sway/commands/layout.c +++ b/sway/commands/layout.c @@ -138,15 +138,14 @@ struct cmd_results *cmd_layout(int argc, char **argv) { } container->layout = new_layout; container_update_representation(container); - arrange_container(container); } else { if (old_layout != L_TABBED && old_layout != L_STACKED) { workspace->prev_split_layout = old_layout; } workspace->layout = new_layout; workspace_update_representation(workspace); - arrange_workspace(workspace); } + arrange_workspace(workspace); } return cmd_results_new(CMD_SUCCESS, NULL, NULL); diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c index 2ce7872d..63f29641 100644 --- a/sway/commands/workspace.c +++ b/sway/commands/workspace.c @@ -20,6 +20,8 @@ static struct workspace_config *workspace_config_find_or_create(char *ws_name) { return NULL; } wsc->workspace = strdup(ws_name); + wsc->gaps_inner = -1; + wsc->gaps_outer = -1; list_add(config->workspace_configs, wsc); return wsc; } @@ -37,6 +39,7 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { } int output_location = -1; + int gaps_location = -1; for (int i = 0; i < argc; ++i) { if (strcasecmp(argv[i], "output") == 0) { @@ -44,6 +47,12 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { break; } } + for (int i = 0; i < argc; ++i) { + if (strcasecmp(argv[i], "gaps") == 0) { + gaps_location = i; + break; + } + } if (output_location >= 0) { if ((error = checkarg(argc, "workspace", EXPECTED_EQUAL_TO, output_location + 2))) { return error; @@ -57,6 +66,35 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { } free(wsc->output); wsc->output = strdup(argv[output_location + 1]); + } else if (gaps_location >= 0) { + if ((error = checkarg(argc, "workspace", EXPECTED_EQUAL_TO, gaps_location + 3))) { + return error; + } + char *ws_name = join_args(argv, argc - 3); + struct workspace_config *wsc = workspace_config_find_or_create(ws_name); + free(ws_name); + if (!wsc) { + return cmd_results_new(CMD_FAILURE, "workspace gaps", + "Unable to allocate workspace output"); + } + int *prop = NULL; + if (strcasecmp(argv[gaps_location + 1], "inner") == 0) { + prop = &wsc->gaps_inner; + } else if (strcasecmp(argv[gaps_location + 1], "outer") == 0) { + prop = &wsc->gaps_outer; + } else { + return cmd_results_new(CMD_FAILURE, "workspace gaps", + "Expected 'workspace <ws> gaps inner|outer <px>'"); + } + char *end; + int val = strtol(argv[gaps_location + 2], &end, 10); + + if (strlen(end)) { + free(end); + return cmd_results_new(CMD_FAILURE, "workspace gaps", + "Expected 'workspace <ws> gaps inner|outer <px>'"); + } + *prop = val >= 0 ? val : 0; } else { if (config->reading || !config->active) { return cmd_results_new(CMD_DEFER, "workspace", NULL); |