summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sway/tree/workspace.h4
-rw-r--r--sway/commands/workspace.c54
-rw-r--r--sway/sway.5.scd5
-rw-r--r--sway/tree/workspace.c42
4 files changed, 59 insertions, 46 deletions
diff --git a/include/sway/tree/workspace.h b/include/sway/tree/workspace.h
index 3337f2c8..239cbbdb 100644
--- a/include/sway/tree/workspace.h
+++ b/include/sway/tree/workspace.h
@@ -1,6 +1,7 @@
1#ifndef _SWAY_WORKSPACE_H 1#ifndef _SWAY_WORKSPACE_H
2#define _SWAY_WORKSPACE_H 2#define _SWAY_WORKSPACE_H
3 3
4#include <stdbool.h>
4#include "sway/tree/container.h" 5#include "sway/tree/container.h"
5 6
6struct sway_view; 7struct sway_view;
@@ -17,7 +18,8 @@ extern char *prev_workspace_name;
17 18
18char *workspace_next_name(const char *output_name); 19char *workspace_next_name(const char *output_name);
19 20
20bool workspace_switch(struct sway_container *workspace); 21bool workspace_switch(struct sway_container *workspace,
22 bool no_auto_back_and_forth);
21 23
22struct sway_container *workspace_by_number(const char* name); 24struct sway_container *workspace_by_number(const char* name);
23 25
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) {
17 17
18 int output_location = -1; 18 int output_location = -1;
19 19
20 struct sway_container *current_container = config->handler_context.current_container;
21 struct sway_container *old_workspace = NULL, *old_output = NULL;
22 if (current_container) {
23 if (current_container->type == C_WORKSPACE) {
24 old_workspace = current_container;
25 } else {
26 old_workspace = container_parent(current_container, C_WORKSPACE);
27 }
28 old_output = container_parent(current_container, C_OUTPUT);
29 }
30
31 for (int i = 0; i < argc; ++i) { 20 for (int i = 0; i < argc; ++i) {
32 if (strcasecmp(argv[i], "output") == 0) { 21 if (strcasecmp(argv[i], "output") == 0) {
33 output_location = i; 22 output_location = i;
@@ -57,39 +46,42 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
57 if (config->reading || !config->active) { 46 if (config->reading || !config->active) {
58 return cmd_results_new(CMD_DEFER, "workspace", NULL); 47 return cmd_results_new(CMD_DEFER, "workspace", NULL);
59 } 48 }
49
50 bool no_auto_back_and_forth = false;
51 while (strcasecmp(argv[0], "--no-auto-back-and-forth") == 0) {
52 no_auto_back_and_forth = true;
53 if ((error = checkarg(--argc, "workspace", EXPECTED_AT_LEAST, 1))) {
54 return error;
55 }
56 ++argv;
57 }
58
59
60 struct sway_container *ws = NULL; 60 struct sway_container *ws = NULL;
61 if (strcasecmp(argv[0], "number") == 0) { 61 if (strcasecmp(argv[0], "number") == 0) {
62 if (argc < 2) {
63 cmd_results_new(CMD_INVALID, "workspace",
64 "Expected workspace number");
65 }
62 if (!(ws = workspace_by_number(argv[1]))) { 66 if (!(ws = workspace_by_number(argv[1]))) {
63 char *name = join_args(argv + 1, argc - 1); 67 char *name = join_args(argv + 1, argc - 1);
64 ws = workspace_create(NULL, name); 68 ws = workspace_create(NULL, name);
65 free(name); 69 free(name);
66 } 70 }
67 } else if (strcasecmp(argv[0], "next") == 0) {
68 ws = workspace_next(old_workspace);
69 } else if (strcasecmp(argv[0], "prev") == 0) {
70 ws = workspace_prev(old_workspace);
71 } else if (strcasecmp(argv[0], "next_on_output") == 0) {
72 ws = workspace_output_next(old_output);
73 } else if (strcasecmp(argv[0], "prev_on_output") == 0) {
74 ws = workspace_output_prev(old_output);
75 } else if (strcasecmp(argv[0], "back_and_forth") == 0) {
76 // if auto_back_and_forth is enabled, workspace_switch will swap
77 // the workspaces. If we created prev_workspace here, workspace_switch
78 // would put us back on original workspace.
79 if (config->auto_back_and_forth) {
80 ws = old_workspace;
81 } else if (prev_workspace_name
82 && !(ws = workspace_by_name(prev_workspace_name))) {
83 ws = workspace_create(NULL, prev_workspace_name);
84 }
85 } else { 71 } else {
86 char *name = join_args(argv, argc); 72 char *name = join_args(argv, argc);
87 if (!(ws = workspace_by_name(name))) { 73 if (!(ws = workspace_by_name(name))) {
88 ws = workspace_create(NULL, name); 74 if (strcasecmp(argv[0], "back_and_forth") == 0) {
75 if (prev_workspace_name) {
76 ws = workspace_create(NULL, prev_workspace_name);
77 }
78 } else {
79 ws = workspace_create(NULL, name);
80 }
89 } 81 }
90 free(name); 82 free(name);
91 } 83 }
92 workspace_switch(ws); 84 workspace_switch(ws, no_auto_back_and_forth);
93 } 85 }
94 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 86 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
95} 87}
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.
526 state. Using _allow_ or _deny_ controls the window's ability to set itself 526 state. Using _allow_ or _deny_ controls the window's ability to set itself
527 as urgent. By default, windows are allowed to set their own urgency. 527 as urgent. By default, windows are allowed to set their own urgency.
528 528
529*workspace* [number] <name> 529*workspace* [--no-auto-back-and-forth] [number] <name>
530 Switches to the specified workspace. The string "number" is optional and is 530 Switches to the specified workspace. The string "number" is optional and is
531 used to sort workspaces. 531 used to sort workspaces.
532 532
@@ -537,6 +537,9 @@ config after the others, or it will be matched instead of the others.
537*workspace* prev\_on\_output|next\_on\_output 537*workspace* prev\_on\_output|next\_on\_output
538 Switches to the next workspace on the current output. 538 Switches to the next workspace on the current output.
539 539
540*workspace* back_and_forth
541 Switches to the previously focused workspace.
542
540*workspace* <name> output <output> 543*workspace* <name> output <output>
541 Specifies that workspace _name_ should be shown on the specified _output_. 544 Specifies that workspace _name_ should be shown on the specified _output_.
542 545
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) {
250 current_workspace = container_parent(focus, C_WORKSPACE); 250 current_workspace = container_parent(focus, C_WORKSPACE);
251 current_output = container_parent(focus, C_OUTPUT); 251 current_output = container_parent(focus, C_OUTPUT);
252 } 252 }
253 if (strcmp(name, "prev") == 0) { 253
254 return workspace_prev(current_workspace); 254 char *name_cpy = strdup(name);
255 } else if (strcmp(name, "prev_on_output") == 0) { 255 char *first_word = strtok(name_cpy, " ");
256 return workspace_output_prev(current_output); 256 if (first_word == NULL) {
257 } else if (strcmp(name, "next") == 0) { 257 first_word = name_cpy;
258 return workspace_next(current_workspace); 258 }
259 } else if (strcmp(name, "next_on_output") == 0) { 259
260 return workspace_output_next(current_output); 260 struct sway_container *ws = NULL;
261 } else if (strcmp(name, "current") == 0) { 261 if (strcmp(first_word, "prev") == 0) {
262 return current_workspace; 262 ws = workspace_prev(current_workspace);
263 } else if (strcmp(first_word, "prev_on_output") == 0) {
264 ws = workspace_output_prev(current_output);
265 } else if (strcmp(first_word, "next") == 0) {
266 ws = workspace_next(current_workspace);
267 } else if (strcmp(first_word, "next_on_output") == 0) {
268 ws = workspace_output_next(current_output);
269 } else if (strcmp(first_word, "current") == 0) {
270 ws = current_workspace;
271 } else if (strcasecmp(first_word, "back_and_forth") == 0) {
272 if (prev_workspace_name) {
273 ws = container_find(&root_container, _workspace_by_name,
274 (void *)prev_workspace_name);
275 }
263 } else { 276 } else {
264 return container_find(&root_container, _workspace_by_name, 277 ws = container_find(&root_container, _workspace_by_name,
265 (void *)name); 278 (void *)name);
266 } 279 }
280 free(name_cpy);
281 return ws;
267} 282}
268 283
269/** 284/**
@@ -364,7 +379,8 @@ struct sway_container *workspace_prev(struct sway_container *current) {
364 return workspace_prev_next_impl(current, false); 379 return workspace_prev_next_impl(current, false);
365} 380}
366 381
367bool workspace_switch(struct sway_container *workspace) { 382bool workspace_switch(struct sway_container *workspace,
383 bool no_auto_back_and_forth) {
368 if (!workspace) { 384 if (!workspace) {
369 return false; 385 return false;
370 } 386 }
@@ -379,7 +395,7 @@ bool workspace_switch(struct sway_container *workspace) {
379 active_ws = container_parent(focus, C_WORKSPACE); 395 active_ws = container_parent(focus, C_WORKSPACE);
380 } 396 }
381 397
382 if (config->auto_back_and_forth 398 if (!no_auto_back_and_forth && config->auto_back_and_forth
383 && active_ws == workspace 399 && active_ws == workspace
384 && prev_workspace_name) { 400 && prev_workspace_name) {
385 struct sway_container *new_ws = workspace_by_name(prev_workspace_name); 401 struct sway_container *new_ws = workspace_by_name(prev_workspace_name);