diff --git a/include/commands.h b/include/commands.h index 273f32a8..94200741 100644 --- a/include/commands.h +++ b/include/commands.h @@ -61,6 +61,12 @@ void cmd_move_con_to_workspace(I3_CMD, char *which); */ void cmd_move_con_to_workspace_name(I3_CMD, char *name); +/** + * Implementation of 'move [window|container] [to] workspace number '. + * + */ +void cmd_move_con_to_workspace_number(I3_CMD, char *which); + /** * Implementation of 'resize grow|shrink [ px] [or ppt]'. * diff --git a/parser-specs/commands.spec b/parser-specs/commands.spec index 9ea1c55e..aab5529d 100644 --- a/parser-specs/commands.spec +++ b/parser-specs/commands.spec @@ -217,9 +217,15 @@ state MOVE_WORKSPACE: -> MOVE_WORKSPACE_TO_OUTPUT workspace = 'next', 'prev', 'next_on_output', 'prev_on_output' -> call cmd_move_con_to_workspace($workspace) + 'number' + -> MOVE_WORKSPACE_NUMBER workspace = string -> call cmd_move_con_to_workspace_name($workspace) +state MOVE_WORKSPACE_NUMBER: + number = string + -> call cmd_move_con_to_workspace_number($number) + state MOVE_TO_OUTPUT: output = string -> call cmd_move_con_to_output($output) diff --git a/src/commands.c b/src/commands.c index 6c36c256..1eff7390 100644 --- a/src/commands.c +++ b/src/commands.c @@ -391,6 +391,58 @@ void cmd_move_con_to_workspace_name(I3_CMD, char *name) { cmd_output->json_output = sstrdup("{\"success\": true}"); } +/* + * Implementation of 'move [window|container] [to] workspace number '. + * + */ +void cmd_move_con_to_workspace_number(I3_CMD, char *which) { + owindow *current; + + /* Error out early to not create a non-existing workspace (in + * workspace_get()) if we are not actually able to move anything. */ + if (match_is_empty(current_match) && focused->type == CT_WORKSPACE) { + cmd_output->json_output = sstrdup("{\"sucess\": false}"); + return; + } + + LOG("should move window to workspace with number %d\n", which); + /* get the workspace */ + Con *output, *workspace; + + char *endptr = NULL; + long parsed_num = strtol(which, &endptr, 10); + if (parsed_num == LONG_MIN || + parsed_num == LONG_MAX || + parsed_num < 0 || + *endptr != '\0') { + LOG("Could not parse \"%s\" as a number.\n", which); + cmd_output->json_output = sstrdup("{\"success\": false, " + "\"error\": \"Could not parse number\"}"); + return; + } + + TAILQ_FOREACH(output, &(croot->nodes_head), nodes) + GREP_FIRST(workspace, output_get_content(output), + child->num == parsed_num); + + if (!workspace) { + cmd_output->json_output = sstrdup("{\"success\": false, " + "\"error\": \"No such workspace\"}"); + return; + } + + HANDLE_EMPTY_MATCH; + + TAILQ_FOREACH(current, &owindows, owindows) { + DLOG("matching: %p / %s\n", current->con, current->con->name); + con_move_to_workspace(current->con, workspace, true, false); + } + + cmd_output->needs_tree_render = true; + // XXX: default reply for now, make this a better reply + cmd_output->json_output = sstrdup("{\"success\": true}"); +} + static void cmd_resize_floating(I3_CMD, char *way, char *direction, Con *floating_con, int px) { LOG("floating resize\n"); if (strcmp(direction, "up") == 0) { diff --git a/testcases/t/132-move-workspace.t b/testcases/t/132-move-workspace.t index a7c5544b..3f00428c 100644 --- a/testcases/t/132-move-workspace.t +++ b/testcases/t/132-move-workspace.t @@ -46,6 +46,26 @@ move_workspace_test('move to workspace'); move_workspace_test('move window to workspace'); move_workspace_test('move container to workspace'); +################################################################################ +# Check that 'move to workspace number ' works to move a window to +# named workspaces which start with . +################################################################################ + +cmd 'workspace 13: meh'; +cmd 'open'; +ok(@{get_ws_content('13: meh')} == 1, 'one container on 13: meh'); + +ok(!workspace_exists('13'), 'workspace 13 does not exist yet'); + +cmd 'workspace 12'; +cmd 'open'; + +cmd 'move to workspace number 13'; +ok(@{get_ws_content('13: meh')} == 2, 'two containers on 13: meh'); +ok(@{get_ws_content('12')} == 0, 'no container on 12 anymore'); + +ok(!workspace_exists('13'), 'workspace 13 does still not exist'); + ################################################################### # check if 'move workspace next' and 'move workspace prev' work ###################################################################