diff --git a/include/sway/tree/workspace.h b/include/sway/tree/workspace.h index 7abfbff1..41b59796 100644 --- a/include/sway/tree/workspace.h +++ b/include/sway/tree/workspace.h @@ -67,11 +67,13 @@ struct sway_workspace *workspace_by_number(const char* name); struct sway_workspace *workspace_by_name(const char*); -struct sway_workspace *workspace_output_next(struct sway_workspace *current); +struct sway_workspace *workspace_output_next( + struct sway_workspace *current, bool create); struct sway_workspace *workspace_next(struct sway_workspace *current); -struct sway_workspace *workspace_output_prev(struct sway_workspace *current); +struct sway_workspace *workspace_output_prev( + struct sway_workspace *current, bool create); struct sway_workspace *workspace_prev(struct sway_workspace *current); diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c index 65a3f407..5fde8129 100644 --- a/sway/commands/workspace.c +++ b/sway/commands/workspace.c @@ -181,7 +181,9 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { ++argv; } - + bool create = argc > 1 && strcasecmp(argv[1], "--create") == 0; + struct sway_seat *seat = config->handler_context.seat; + struct sway_workspace *current = seat_get_focused_workspace(seat); struct sway_workspace *ws = NULL; if (strcasecmp(argv[0], "number") == 0) { if (argc < 2) { @@ -199,12 +201,13 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { } } else if (strcasecmp(argv[0], "next") == 0 || strcasecmp(argv[0], "prev") == 0 || - strcasecmp(argv[0], "next_on_output") == 0 || - strcasecmp(argv[0], "prev_on_output") == 0 || strcasecmp(argv[0], "current") == 0) { ws = workspace_by_name(argv[0]); + } else if (strcasecmp(argv[0], "next_on_output") == 0) { + ws = workspace_output_next(current, create); + } else if (strcasecmp(argv[0], "prev_on_output") == 0) { + ws = workspace_output_prev(current, create); } else if (strcasecmp(argv[0], "back_and_forth") == 0) { - struct sway_seat *seat = config->handler_context.seat; if (!seat->prev_workspace_name) { return cmd_results_new(CMD_INVALID, "There is no previous workspace"); @@ -220,7 +223,7 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { free(name); } workspace_switch(ws, no_auto_back_and_forth); - seat_consider_warp_to_focus(config->handler_context.seat); + seat_consider_warp_to_focus(seat); } return cmd_results_new(CMD_SUCCESS, NULL); } diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index cda6caf7..68f1de50 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -230,8 +230,10 @@ static void workspace_name_from_binding(const struct sway_binding * binding, // 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 || + strncmp(_target, "next_on_output", + strlen("next_on_output")) == 0 || + strncmp(_target, "prev_on_output", + strlen("next_on_output")) == 0 || strcmp(_target, "number") == 0 || strcmp(_target, "back_and_forth") == 0 || strcmp(_target, "current") == 0) { @@ -372,11 +374,11 @@ struct sway_workspace *workspace_by_name(const char *name) { if (strcmp(name, "prev") == 0) { return workspace_prev(current); } else if (strcmp(name, "prev_on_output") == 0) { - return workspace_output_prev(current); + return workspace_output_prev(current, false); } else if (strcmp(name, "next") == 0) { return workspace_next(current); } else if (strcmp(name, "next_on_output") == 0) { - return workspace_output_next(current); + return workspace_output_next(current, false); } else if (strcmp(name, "current") == 0) { return current; } else if (strcasecmp(name, "back_and_forth") == 0) { @@ -397,11 +399,18 @@ struct sway_workspace *workspace_by_name(const char *name) { * otherwise the next one is returned. */ static struct sway_workspace *workspace_output_prev_next_impl( - struct sway_output *output, int dir) { + struct sway_output *output, int dir, bool create) { struct sway_seat *seat = input_manager_current_seat(); struct sway_workspace *workspace = seat_get_focused_workspace(seat); int index = list_find(output->workspaces, workspace); + if (!workspace_is_empty(workspace) && create && + (index + dir < 0 || index + dir == output->workspaces->length)) { + struct sway_output *output = workspace->output; + char *next = workspace_next_name(output->wlr_output->name); + workspace_create(output, next); + free(next); + } size_t new_index = wrap(index + dir, output->workspaces->length); return output->workspaces->items[new_index]; } @@ -432,16 +441,18 @@ static struct sway_workspace *workspace_prev_next_impl( } } -struct sway_workspace *workspace_output_next(struct sway_workspace *current) { - return workspace_output_prev_next_impl(current->output, 1); +struct sway_workspace *workspace_output_next( + struct sway_workspace *current, bool create) { + return workspace_output_prev_next_impl(current->output, 1, create); } struct sway_workspace *workspace_next(struct sway_workspace *current) { return workspace_prev_next_impl(current, 1); } -struct sway_workspace *workspace_output_prev(struct sway_workspace *current) { - return workspace_output_prev_next_impl(current->output, -1); +struct sway_workspace *workspace_output_prev( + struct sway_workspace *current, bool create) { + return workspace_output_prev_next_impl(current->output, -1, create); } struct sway_workspace *workspace_prev(struct sway_workspace *current) {