diff options
author | Ian Fan <ianfan0@gmail.com> | 2018-08-05 00:05:48 +0100 |
---|---|---|
committer | Ian Fan <ianfan0@gmail.com> | 2018-08-06 14:17:58 +0100 |
commit | 85ae121caad02265b95ecea66fa864607575eb31 (patch) | |
tree | b4d8dab619005e0b2f34068fd908b9153164a74f | |
parent | commands: fix layout implementation (also better name for previous split layout) (diff) | |
download | sway-85ae121caad02265b95ecea66fa864607575eb31.tar.gz sway-85ae121caad02265b95ecea66fa864607575eb31.tar.zst sway-85ae121caad02265b95ecea66fa864607575eb31.zip |
commands: complete workspace implementation
Allow optional --no-auto-back-and-forth flag, as well as refactoring some logic
-rw-r--r-- | include/sway/tree/workspace.h | 4 | ||||
-rw-r--r-- | sway/commands/workspace.c | 54 | ||||
-rw-r--r-- | sway/sway.5.scd | 5 | ||||
-rw-r--r-- | sway/tree/workspace.c | 42 |
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 | ||
6 | struct sway_view; | 7 | struct sway_view; |
@@ -17,7 +18,8 @@ extern char *prev_workspace_name; | |||
17 | 18 | ||
18 | char *workspace_next_name(const char *output_name); | 19 | char *workspace_next_name(const char *output_name); |
19 | 20 | ||
20 | bool workspace_switch(struct sway_container *workspace); | 21 | bool workspace_switch(struct sway_container *workspace, |
22 | bool no_auto_back_and_forth); | ||
21 | 23 | ||
22 | struct sway_container *workspace_by_number(const char* name); | 24 | struct 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 | ||
367 | bool workspace_switch(struct sway_container *workspace) { | 382 | bool 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); |