commands: complete workspace implementation

Allow optional --no-auto-back-and-forth flag, as well as refactoring some logic
This commit is contained in:
Ian Fan 2018-08-05 00:05:48 +01:00
parent 356063b6c0
commit 85ae121caa
4 changed files with 59 additions and 46 deletions

View file

@ -1,6 +1,7 @@
#ifndef _SWAY_WORKSPACE_H #ifndef _SWAY_WORKSPACE_H
#define _SWAY_WORKSPACE_H #define _SWAY_WORKSPACE_H
#include <stdbool.h>
#include "sway/tree/container.h" #include "sway/tree/container.h"
struct sway_view; struct sway_view;
@ -17,7 +18,8 @@ extern char *prev_workspace_name;
char *workspace_next_name(const char *output_name); char *workspace_next_name(const char *output_name);
bool workspace_switch(struct sway_container *workspace); bool workspace_switch(struct sway_container *workspace,
bool no_auto_back_and_forth);
struct sway_container *workspace_by_number(const char* name); struct sway_container *workspace_by_number(const char* name);

View file

@ -17,17 +17,6 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
int output_location = -1; 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) { for (int i = 0; i < argc; ++i) {
if (strcasecmp(argv[i], "output") == 0) { if (strcasecmp(argv[i], "output") == 0) {
output_location = i; output_location = i;
@ -57,39 +46,42 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
if (config->reading || !config->active) { if (config->reading || !config->active) {
return cmd_results_new(CMD_DEFER, "workspace", NULL); 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; struct sway_container *ws = NULL;
if (strcasecmp(argv[0], "number") == 0) { 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]))) { if (!(ws = workspace_by_number(argv[1]))) {
char *name = join_args(argv + 1, argc - 1); char *name = join_args(argv + 1, argc - 1);
ws = workspace_create(NULL, name); ws = workspace_create(NULL, name);
free(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 { } else {
char *name = join_args(argv, argc); char *name = join_args(argv, argc);
if (!(ws = workspace_by_name(name))) { if (!(ws = workspace_by_name(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); ws = workspace_create(NULL, name);
} }
}
free(name); free(name);
} }
workspace_switch(ws); workspace_switch(ws, no_auto_back_and_forth);
} }
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);
} }

View file

@ -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 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. 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 Switches to the specified workspace. The string "number" is optional and is
used to sort workspaces. 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 *workspace* prev\_on\_output|next\_on\_output
Switches to the next workspace on the current output. Switches to the next workspace on the current output.
*workspace* back_and_forth
Switches to the previously focused workspace.
*workspace* <name> output <output> *workspace* <name> output <output>
Specifies that workspace _name_ should be shown on the specified _output_. Specifies that workspace _name_ should be shown on the specified _output_.

View file

@ -250,20 +250,35 @@ struct sway_container *workspace_by_name(const char *name) {
current_workspace = container_parent(focus, C_WORKSPACE); current_workspace = container_parent(focus, C_WORKSPACE);
current_output = container_parent(focus, C_OUTPUT); current_output = container_parent(focus, C_OUTPUT);
} }
if (strcmp(name, "prev") == 0) {
return workspace_prev(current_workspace); char *name_cpy = strdup(name);
} else if (strcmp(name, "prev_on_output") == 0) { char *first_word = strtok(name_cpy, " ");
return workspace_output_prev(current_output); if (first_word == NULL) {
} else if (strcmp(name, "next") == 0) { first_word = name_cpy;
return workspace_next(current_workspace); }
} else if (strcmp(name, "next_on_output") == 0) {
return workspace_output_next(current_output); struct sway_container *ws = NULL;
} else if (strcmp(name, "current") == 0) { if (strcmp(first_word, "prev") == 0) {
return current_workspace; 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 { } else {
return container_find(&root_container, _workspace_by_name, ws = container_find(&root_container, _workspace_by_name,
(void *)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); 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) { if (!workspace) {
return false; return false;
} }
@ -379,7 +395,7 @@ bool workspace_switch(struct sway_container *workspace) {
active_ws = container_parent(focus, C_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 && active_ws == workspace
&& prev_workspace_name) { && prev_workspace_name) {
struct sway_container *new_ws = workspace_by_name(prev_workspace_name); struct sway_container *new_ws = workspace_by_name(prev_workspace_name);