fixes #776
this implements both the "move container to workspace back_and_forth" command and movements to the same workspace when auto_back_and_forth is set. it includes documentation and test suite additions by michael. it also simplifies the workspace_show_by_name function (making use of workspace_get accepting NULL pointers).
This commit is contained in:
parent
a01bac13fe
commit
e15e37f922
|
@ -1395,7 +1395,8 @@ RandR output.
|
||||||
|
|
||||||
[[back_and_forth]]
|
[[back_and_forth]]
|
||||||
To switch back to the previously focused workspace, use +workspace
|
To switch back to the previously focused workspace, use +workspace
|
||||||
back_and_forth+.
|
back_and_forth+; likewise, you can move containers to the previously focused
|
||||||
|
workspace using +move container to workspace back_and_forth+.
|
||||||
|
|
||||||
*Syntax*:
|
*Syntax*:
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
@ -1421,6 +1422,7 @@ bindsym mod+Shift+2 move container to workspace 2
|
||||||
|
|
||||||
# switch between the current and the previously focused one
|
# switch between the current and the previously focused one
|
||||||
bindsym mod+b workspace back_and_forth
|
bindsym mod+b workspace back_and_forth
|
||||||
|
bindsym mod+Shift+b move container to workspace back_and_forth
|
||||||
|
|
||||||
# move the whole workspace to the next output
|
# move the whole workspace to the next output
|
||||||
bindsym mod+x move workspace to output right
|
bindsym mod+x move workspace to output right
|
||||||
|
|
|
@ -55,6 +55,12 @@ void cmd_criteria_add(I3_CMD, char *ctype, char *cvalue);
|
||||||
*/
|
*/
|
||||||
void cmd_move_con_to_workspace(I3_CMD, char *which);
|
void cmd_move_con_to_workspace(I3_CMD, char *which);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of 'move [window|container] [to] workspace back_and_forth'.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void cmd_move_con_to_workspace_back_and_forth(I3_CMD);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of 'move [window|container] [to] workspace <name>'.
|
* Implementation of 'move [window|container] [to] workspace <name>'.
|
||||||
*
|
*
|
||||||
|
|
|
@ -95,6 +95,12 @@ Con* workspace_prev_on_output(void);
|
||||||
*/
|
*/
|
||||||
void workspace_back_and_forth(void);
|
void workspace_back_and_forth(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the previously focused workspace con, or NULL if unavailable.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Con *workspace_back_and_forth_get(void);
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -243,6 +243,8 @@ state MOVE_WORKSPACE:
|
||||||
-> MOVE_WORKSPACE_TO_OUTPUT
|
-> MOVE_WORKSPACE_TO_OUTPUT
|
||||||
workspace = 'next', 'prev', 'next_on_output', 'prev_on_output', 'current'
|
workspace = 'next', 'prev', 'next_on_output', 'prev_on_output', 'current'
|
||||||
-> call cmd_move_con_to_workspace($workspace)
|
-> call cmd_move_con_to_workspace($workspace)
|
||||||
|
'back_and_forth'
|
||||||
|
-> call cmd_move_con_to_workspace_back_and_forth()
|
||||||
'number'
|
'number'
|
||||||
-> MOVE_WORKSPACE_NUMBER
|
-> MOVE_WORKSPACE_NUMBER
|
||||||
workspace = string
|
workspace = string
|
||||||
|
|
|
@ -99,6 +99,29 @@ static bool maybe_back_and_forth(struct CommandResult *cmd_output, char *name) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the passed workspace unless it is the current one and auto back and
|
||||||
|
* forth is enabled, in which case the back_and_forth workspace is returned.
|
||||||
|
*/
|
||||||
|
static Con *maybe_auto_back_and_forth_workspace(Con *workspace) {
|
||||||
|
Con *current, *baf;
|
||||||
|
|
||||||
|
if (!config.workspace_auto_back_and_forth)
|
||||||
|
return workspace;
|
||||||
|
|
||||||
|
current = con_get_workspace(focused);
|
||||||
|
|
||||||
|
if (current == workspace) {
|
||||||
|
baf = workspace_back_and_forth_get();
|
||||||
|
if (baf != NULL) {
|
||||||
|
DLOG("Substituting workspace with back_and_forth, as it is focused.\n");
|
||||||
|
return baf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return workspace;
|
||||||
|
}
|
||||||
|
|
||||||
// This code is commented out because we might recycle it for popping up error
|
// This code is commented out because we might recycle it for popping up error
|
||||||
// messages on parser errors.
|
// messages on parser errors.
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -400,6 +423,38 @@ void cmd_move_con_to_workspace(I3_CMD, char *which) {
|
||||||
ysuccess(true);
|
ysuccess(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of 'move [window|container] [to] workspace back_and_forth'.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void cmd_move_con_to_workspace_back_and_forth(I3_CMD) {
|
||||||
|
owindow *current;
|
||||||
|
Con *ws;
|
||||||
|
|
||||||
|
ws = workspace_back_and_forth_get();
|
||||||
|
|
||||||
|
if (ws == NULL) {
|
||||||
|
y(map_open);
|
||||||
|
ystr("success");
|
||||||
|
y(bool, false);
|
||||||
|
ystr("error");
|
||||||
|
ystr("No workspace was previously active.");
|
||||||
|
y(map_close);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE_EMPTY_MATCH;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(current, &owindows, owindows) {
|
||||||
|
DLOG("matching: %p / %s\n", current->con, current->con->name);
|
||||||
|
con_move_to_workspace(current->con, ws, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_output->needs_tree_render = true;
|
||||||
|
// XXX: default reply for now, make this a better reply
|
||||||
|
ysuccess(true);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Implementation of 'move [window|container] [to] workspace <name>'.
|
* Implementation of 'move [window|container] [to] workspace <name>'.
|
||||||
*
|
*
|
||||||
|
@ -432,6 +487,8 @@ void cmd_move_con_to_workspace_name(I3_CMD, char *name) {
|
||||||
/* get the workspace */
|
/* get the workspace */
|
||||||
Con *ws = workspace_get(name, NULL);
|
Con *ws = workspace_get(name, NULL);
|
||||||
|
|
||||||
|
ws = maybe_auto_back_and_forth_workspace(ws);
|
||||||
|
|
||||||
HANDLE_EMPTY_MATCH;
|
HANDLE_EMPTY_MATCH;
|
||||||
|
|
||||||
TAILQ_FOREACH(current, &owindows, owindows) {
|
TAILQ_FOREACH(current, &owindows, owindows) {
|
||||||
|
@ -489,6 +546,8 @@ void cmd_move_con_to_workspace_number(I3_CMD, char *which) {
|
||||||
workspace = workspace_get(which, NULL);
|
workspace = workspace_get(which, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
workspace = maybe_auto_back_and_forth_workspace(workspace);
|
||||||
|
|
||||||
HANDLE_EMPTY_MATCH;
|
HANDLE_EMPTY_MATCH;
|
||||||
|
|
||||||
TAILQ_FOREACH(current, &owindows, owindows) {
|
TAILQ_FOREACH(current, &owindows, owindows) {
|
||||||
|
|
|
@ -392,8 +392,7 @@ void workspace_show(Con *workspace) {
|
||||||
*/
|
*/
|
||||||
void workspace_show_by_name(const char *num) {
|
void workspace_show_by_name(const char *num) {
|
||||||
Con *workspace;
|
Con *workspace;
|
||||||
bool changed_num_workspaces;
|
workspace = workspace_get(num, NULL);
|
||||||
workspace = workspace_get(num, &changed_num_workspaces);
|
|
||||||
_workspace_show(workspace);
|
_workspace_show(workspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -664,6 +663,22 @@ void workspace_back_and_forth(void) {
|
||||||
workspace_show_by_name(previous_workspace_name);
|
workspace_show_by_name(previous_workspace_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the previously focused workspace con, or NULL if unavailable.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Con *workspace_back_and_forth_get(void) {
|
||||||
|
if (!previous_workspace_name) {
|
||||||
|
DLOG("no previous workspace name set.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Con *workspace;
|
||||||
|
workspace = workspace_get(previous_workspace_name, NULL);
|
||||||
|
|
||||||
|
return workspace;
|
||||||
|
}
|
||||||
|
|
||||||
static bool get_urgency_flag(Con *con) {
|
static bool get_urgency_flag(Con *con) {
|
||||||
Con *child;
|
Con *child;
|
||||||
TAILQ_FOREACH(child, &(con->nodes_head), nodes)
|
TAILQ_FOREACH(child, &(con->nodes_head), nodes)
|
||||||
|
|
|
@ -47,6 +47,33 @@ ok(get_ws($second_ws)->{focused}, 'second workspace focused');
|
||||||
cmd qq|workspace "$second_ws"|;
|
cmd qq|workspace "$second_ws"|;
|
||||||
ok(get_ws($second_ws)->{focused}, 'second workspace still focused');
|
ok(get_ws($second_ws)->{focused}, 'second workspace still focused');
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# verify that 'move workspace back_and_forth' works as expected
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
cmd qq|workspace "$first_ws"|;
|
||||||
|
my $first_win = open_window;
|
||||||
|
|
||||||
|
cmd qq|workspace "$second_ws"|;
|
||||||
|
my $second_win = open_window;
|
||||||
|
|
||||||
|
is(@{get_ws_content($first_ws)}, 1, 'one container on ws 1 before moving');
|
||||||
|
cmd 'move workspace back_and_forth';
|
||||||
|
is(@{get_ws_content($first_ws)}, 2, 'two containers on ws 1 before moving');
|
||||||
|
|
||||||
|
my $third_win = open_window;
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# verify that moving to the current ws is a no-op without
|
||||||
|
# workspace_auto_back_and_forth.
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
cmd qq|workspace "$first_ws"|;
|
||||||
|
|
||||||
|
is(@{get_ws_content($second_ws)}, 1, 'one container on ws 2 before moving');
|
||||||
|
cmd qq|move workspace "$first_ws"|;
|
||||||
|
is(@{get_ws_content($second_ws)}, 1, 'still one container');
|
||||||
|
|
||||||
exit_gracefully($pid);
|
exit_gracefully($pid);
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
|
@ -72,6 +99,19 @@ ok(get_ws($third_ws)->{focused}, 'third workspace focused');
|
||||||
|
|
||||||
cmd qq|workspace "$third_ws"|;
|
cmd qq|workspace "$third_ws"|;
|
||||||
ok(get_ws($second_ws)->{focused}, 'second workspace focused');
|
ok(get_ws($second_ws)->{focused}, 'second workspace focused');
|
||||||
|
$first_win = open_window;
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# verify that moving to the current ws moves to the previous one with
|
||||||
|
# workspace_auto_back_and_forth.
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
cmd qq|workspace "$first_ws"|;
|
||||||
|
$second_win = open_window;
|
||||||
|
|
||||||
|
is(@{get_ws_content($second_ws)}, 1, 'one container on ws 2 before moving');
|
||||||
|
cmd qq|move workspace "$first_ws"|;
|
||||||
|
is(@{get_ws_content($second_ws)}, 2, 'two containers on ws 2');
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Now see if "workspace number <number>" also works as expected with
|
# Now see if "workspace number <number>" also works as expected with
|
||||||
|
|
Loading…
Reference in New Issue