diff --git a/include/layout.h b/include/layout.h index 62e4c2025..b77310314 100644 --- a/include/layout.h +++ b/include/layout.h @@ -24,6 +24,10 @@ int index_child(const swayc_t *child); // parent must be of type C_WORKSPACE or C_CONTAINER void add_child(swayc_t *parent, swayc_t *child); +// Adds child to parent at index, if parent has no focus, it is set to child +// parent must be of type C_WORKSPACE or C_CONTAINER +void insert_child(swayc_t *parent, swayc_t *child, int index); + // Adds child as floating window to ws, if there is no focus it is set to child. // ws must be of type C_WORKSPACE void add_floating(swayc_t *ws, swayc_t *child); diff --git a/include/workspace.h b/include/workspace.h index b916f715c..c69ccdbbd 100644 --- a/include/workspace.h +++ b/include/workspace.h @@ -10,6 +10,7 @@ extern char *prev_workspace_name; char *workspace_next_name(void); swayc_t *workspace_create(const char*); swayc_t *workspace_by_name(const char*); +swayc_t *workspace_by_number(const char*); bool workspace_switch(swayc_t*); swayc_t *workspace_output_next(); swayc_t *workspace_next(); diff --git a/sway/commands.c b/sway/commands.c index b40cdb6a1..24d56052e 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -649,12 +649,15 @@ static struct cmd_results *cmd_move(int argc, char **argv) { } const char *ws_name = argv[3]; - if (argc == 5) { + swayc_t *ws; + if (argc == 5 && strcasecmp(ws_name, "number") == 0) { // move "container to workspace number x" ws_name = argv[4]; + ws = workspace_by_number(ws_name); + } else { + ws = workspace_by_name(ws_name); } - swayc_t *ws = workspace_by_name(ws_name); if (ws == NULL) { ws = workspace_create(ws_name); } @@ -1435,13 +1438,17 @@ static struct cmd_results *cmd_workspace(int argc, char **argv) { if ((error = checkarg(argc, "workspace", EXPECTED_AT_LEAST, 1))) { return error; } - if (argc == 1) { + if (argc == 1 || (argc == 2 && strcasecmp(argv[0], "number") == 0) ) { if (config->reading || !config->active) { return cmd_results_new(CMD_DEFER, "workspace", NULL); } // Handle workspace next/prev swayc_t *ws = NULL; - if (strcasecmp(argv[0], "next") == 0) { + if (argc == 2) { + if (!(ws=workspace_by_number(argv[1]))) { + ws = workspace_create(argv[1]); + } + }else if (strcasecmp(argv[0], "next") == 0) { ws = workspace_next(); } else if (strcasecmp(argv[0], "prev") == 0) { ws = workspace_prev(); diff --git a/sway/container.c b/sway/container.c index 8165bbad6..36056ff7e 100644 --- a/sway/container.c +++ b/sway/container.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -168,7 +169,24 @@ swayc_t *new_workspace(swayc_t *output, const char *name) { workspace->visible = false; workspace->floating = create_list(); - add_child(output, workspace); + if (isdigit(workspace->name[0])) { + // find position for numbered workspace + // order: ascending numbers, insert before same number + // numbers before unnumbered + int num = strtol(workspace->name, NULL, 10); + int i; + for (i = 0; i < output->children->length; ++i) { + char *name = ((swayc_t *)output->children->items[i])->name; + if (!isdigit(name[0]) || num <= strtol(name, NULL, 10)) { + break; + } + } + insert_child(output, workspace, i); + + } else { + // append new unnumbered to the end + add_child(output, workspace); + } return workspace; } diff --git a/sway/workspace.c b/sway/workspace.c index 5e6ea799e..761a5f4e8 100644 --- a/sway/workspace.c +++ b/sway/workspace.c @@ -17,6 +17,11 @@ #include "ipc.h" char *prev_workspace_name = NULL; +struct workspace_by_number_data { + int len; + const char *cset; + const char *name; +}; char *workspace_next_name(void) { sway_log(L_DEBUG, "Workspace: Generating new name"); @@ -133,6 +138,23 @@ swayc_t *workspace_by_name(const char* name) { } } +static bool _workspace_by_number(swayc_t *view, void *data) { + if (view->type != C_WORKSPACE) { + return false; + } + struct workspace_by_number_data *wbnd = data; + int a = strspn(view->name, wbnd->cset); + return a == wbnd->len && strncmp(view->name, wbnd->name, a) == 0; +} +swayc_t *workspace_by_number(const char* name) { + struct workspace_by_number_data wbnd = {0, "1234567890", name}; + wbnd.len = strspn(name, wbnd.cset); + if (wbnd.len <= 0) { + return NULL; + } + return swayc_by_test(&root_container, _workspace_by_number, (void *) &wbnd); +} + /** * Get the previous or next workspace on the specified output. * Wraps around at the end and beginning.