diff --git a/include/config.h b/include/config.h index e6fc9f28..b97acb57 100644 --- a/include/config.h +++ b/include/config.h @@ -21,6 +21,7 @@ struct sway_variable { * A key binding and an associated command. */ struct sway_binding { + int order; list_t *keys; uint32_t modifiers; char *command; diff --git a/sway/commands.c b/sway/commands.c index 4af9186a..3d882a7b 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -167,6 +167,8 @@ static struct cmd_results *checkarg(int argc, const char *name, enum expected_ar return error; } +int binding_order = 0; + static struct cmd_results *cmd_bindsym(int argc, char **argv) { struct cmd_results *error = NULL; if ((error = checkarg(argc, "bindsym", EXPECTED_MORE_THAN, 1))) { @@ -215,6 +217,7 @@ static struct cmd_results *cmd_bindsym(int argc, char **argv) { free_sway_binding(dup); list_del(mode->bindings, i); } + binding->order = binding_order++; list_add(mode->bindings, binding); list_sort(mode->bindings, sway_binding_cmp); diff --git a/sway/workspace.c b/sway/workspace.c index 761a5f4e..f7523b79 100644 --- a/sway/workspace.c +++ b/sway/workspace.c @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include #include @@ -31,6 +33,8 @@ char *workspace_next_name(void) { // if none are found/available then default to a number struct sway_mode *mode = config->current_mode; + int order = INT_MAX; + char *target = NULL; for (i = 0; i < mode->bindings->length; ++i) { struct sway_binding *binding = mode->bindings->items[i]; char *cmdlist = strdup(binding->command); @@ -45,35 +49,40 @@ char *workspace_next_name(void) { if (strcmp("workspace", cmd) == 0 && name) { sway_log(L_DEBUG, "Got valid workspace command for target: '%s'", name); - char* target = strdup(name); - while (*target == ' ' || *target == '\t') - target++; + char *_target = strdup(name); + while (isspace(*_target)) + _target++; // Make sure that the command references an actual workspace // not a command about workspaces - if (strcmp(target, "next") == 0 || - strcmp(target, "prev") == 0 || - strcmp(target, "next_on_output") == 0 || - strcmp(target, "prev_on_output") == 0 || - strcmp(target, "number") == 0 || - strcmp(target, "back_and_forth") == 0 || - strcmp(target, "current") == 0) + if (strcmp(_target, "next") == 0 || + strcmp(_target, "prev") == 0 || + strcmp(_target, "next_on_output") == 0 || + strcmp(_target, "prev_on_output") == 0 || + strcmp(_target, "number") == 0 || + strcmp(_target, "back_and_forth") == 0 || + strcmp(_target, "current") == 0) { - free(target); + free(_target); continue; } // Make sure that the workspace doesn't already exist - if (workspace_by_name(target)) { - free(target); + if (workspace_by_name(_target)) { + free(_target); continue; } - free(dup); - sway_log(L_DEBUG, "Workspace: Found free name %s", target); - return target; + if (binding->order < order) { + order = binding->order; + target = _target; + sway_log(L_DEBUG, "Workspace: Found free name %s", _target); + } } free(dup); } + if (target != NULL) { + return target; + } // As a fall back, get the current number of active workspaces // and return that + 1 for the next workspace's name int ws_num = root_container.children->length;