aboutsummaryrefslogtreecommitdiff
path: root/sway
diff options
context:
space:
mode:
Diffstat (limited to 'sway')
-rw-r--r--sway/commands/workspace.c54
-rw-r--r--sway/sway.5.scd5
-rw-r--r--sway/tree/workspace.c42
3 files changed, 56 insertions, 45 deletions
diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c
index e8b37182..f32ede1e 100644
--- a/sway/commands/workspace.c
+++ b/sway/commands/workspace.c
@@ -17,17 +17,6 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
int output_location = -1;
- struct sway_container *current_container = config->handler_context.current_container;
- struct sway_container *old_workspace = NULL, *old_output = NULL;
- if (current_container) {
- if (current_container->type == C_WORKSPACE) {
- old_workspace = current_container;
- } else {
- old_workspace = container_parent(current_container, C_WORKSPACE);
- }
- old_output = container_parent(current_container, C_OUTPUT);
- }
-
for (int i = 0; i < argc; ++i) {
if (strcasecmp(argv[i], "output") == 0) {
output_location = i;
@@ -57,39 +46,42 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
if (config->reading || !config->active) {
return cmd_results_new(CMD_DEFER, "workspace", NULL);
}
+
+ bool no_auto_back_and_forth = false;
+ while (strcasecmp(argv[0], "--no-auto-back-and-forth") == 0) {
+ no_auto_back_and_forth = true;
+ if ((error = checkarg(--argc, "workspace", EXPECTED_AT_LEAST, 1))) {
+ return error;
+ }
+ ++argv;
+ }
+
+
struct sway_container *ws = NULL;
if (strcasecmp(argv[0], "number") == 0) {
+ if (argc < 2) {
+ cmd_results_new(CMD_INVALID, "workspace",
+ "Expected workspace number");
+ }
if (!(ws = workspace_by_number(argv[1]))) {
char *name = join_args(argv + 1, argc - 1);
ws = workspace_create(NULL, name);
free(name);
}
- } else if (strcasecmp(argv[0], "next") == 0) {
- ws = workspace_next(old_workspace);
- } else if (strcasecmp(argv[0], "prev") == 0) {
- ws = workspace_prev(old_workspace);
- } else if (strcasecmp(argv[0], "next_on_output") == 0) {
- ws = workspace_output_next(old_output);
- } else if (strcasecmp(argv[0], "prev_on_output") == 0) {
- ws = workspace_output_prev(old_output);
- } else if (strcasecmp(argv[0], "back_and_forth") == 0) {
- // if auto_back_and_forth is enabled, workspace_switch will swap
- // the workspaces. If we created prev_workspace here, workspace_switch
- // would put us back on original workspace.
- if (config->auto_back_and_forth) {
- ws = old_workspace;
- } else if (prev_workspace_name
- && !(ws = workspace_by_name(prev_workspace_name))) {
- ws = workspace_create(NULL, prev_workspace_name);
- }
} else {
char *name = join_args(argv, argc);
if (!(ws = workspace_by_name(name))) {
- ws = workspace_create(NULL, name);
+ if (strcasecmp(argv[0], "back_and_forth") == 0) {
+ if (prev_workspace_name) {
+ ws = workspace_create(NULL, prev_workspace_name);
+ }
+ } else {
+ ws = workspace_create(NULL, name);
+ }
}
free(name);
}
- workspace_switch(ws);
+ workspace_switch(ws, no_auto_back_and_forth);
}
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
diff --git a/sway/sway.5.scd b/sway/sway.5.scd
index 8083106b..36ce13df 100644
--- a/sway/sway.5.scd
+++ b/sway/sway.5.scd
@@ -526,7 +526,7 @@ config after the others, or it will be matched instead of the others.
state. Using _allow_ or _deny_ controls the window's ability to set itself
as urgent. By default, windows are allowed to set their own urgency.
-*workspace* [number] <name>
+*workspace* [--no-auto-back-and-forth] [number] <name>
Switches to the specified workspace. The string "number" is optional and is
used to sort workspaces.
@@ -537,6 +537,9 @@ config after the others, or it will be matched instead of the others.
*workspace* prev\_on\_output|next\_on\_output
Switches to the next workspace on the current output.
+*workspace* back_and_forth
+ Switches to the previously focused workspace.
+
*workspace* <name> output <output>
Specifies that workspace _name_ should be shown on the specified _output_.
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
index 250d5ba7..5e20429b 100644
--- a/sway/tree/workspace.c
+++ b/sway/tree/workspace.c
@@ -250,20 +250,35 @@ struct sway_container *workspace_by_name(const char *name) {
current_workspace = container_parent(focus, C_WORKSPACE);
current_output = container_parent(focus, C_OUTPUT);
}
- if (strcmp(name, "prev") == 0) {
- return workspace_prev(current_workspace);
- } else if (strcmp(name, "prev_on_output") == 0) {
- return workspace_output_prev(current_output);
- } else if (strcmp(name, "next") == 0) {
- return workspace_next(current_workspace);
- } else if (strcmp(name, "next_on_output") == 0) {
- return workspace_output_next(current_output);
- } else if (strcmp(name, "current") == 0) {
- return current_workspace;
+
+ char *name_cpy = strdup(name);
+ char *first_word = strtok(name_cpy, " ");
+ if (first_word == NULL) {
+ first_word = name_cpy;
+ }
+
+ struct sway_container *ws = NULL;
+ if (strcmp(first_word, "prev") == 0) {
+ ws = workspace_prev(current_workspace);
+ } else if (strcmp(first_word, "prev_on_output") == 0) {
+ ws = workspace_output_prev(current_output);
+ } else if (strcmp(first_word, "next") == 0) {
+ ws = workspace_next(current_workspace);
+ } else if (strcmp(first_word, "next_on_output") == 0) {
+ ws = workspace_output_next(current_output);
+ } else if (strcmp(first_word, "current") == 0) {
+ ws = current_workspace;
+ } else if (strcasecmp(first_word, "back_and_forth") == 0) {
+ if (prev_workspace_name) {
+ ws = container_find(&root_container, _workspace_by_name,
+ (void *)prev_workspace_name);
+ }
} else {
- return container_find(&root_container, _workspace_by_name,
+ ws = container_find(&root_container, _workspace_by_name,
(void *)name);
}
+ free(name_cpy);
+ return ws;
}
/**
@@ -364,7 +379,8 @@ struct sway_container *workspace_prev(struct sway_container *current) {
return workspace_prev_next_impl(current, false);
}
-bool workspace_switch(struct sway_container *workspace) {
+bool workspace_switch(struct sway_container *workspace,
+ bool no_auto_back_and_forth) {
if (!workspace) {
return false;
}
@@ -379,7 +395,7 @@ bool workspace_switch(struct sway_container *workspace) {
active_ws = container_parent(focus, C_WORKSPACE);
}
- if (config->auto_back_and_forth
+ if (!no_auto_back_and_forth && config->auto_back_and_forth
&& active_ws == workspace
&& prev_workspace_name) {
struct sway_container *new_ws = workspace_by_name(prev_workspace_name);