Implement focus_wrapping workspace

I had a dilemma about the behaviour here:
1. Prohibit focus leaving the workspace in any case unless if
get_tree_next's initial argument is a workspace. This is what this
commit does (also i3-cycle).
2. Leave the workspace if no warp is possible (eg workspace with single
container or `focus right` with `V[a b c*]`).

Fixes #2180
This commit is contained in:
Orestis Floros
2018-09-15 11:36:48 +03:00
committed by Orestis Floros
parent bbc4c99c72
commit 24a58d2952
6 changed files with 118 additions and 7 deletions

View File

@@ -497,6 +497,13 @@ static Con *get_tree_next(Con *con, direction_t direction) {
const orientation_t orientation = orientation_from_direction(direction);
Con *first_wrap = NULL;
if (con->type == CT_WORKSPACE) {
/* Special case for FOCUS_WRAPPING_WORKSPACE: allow the focus to leave
* the workspace only when a workspace is selected. */
goto handle_workspace;
}
while (con->type != CT_WORKSPACE) {
if (con->fullscreen_mode == CF_OUTPUT) {
/* We've reached a fullscreen container. Directional focus should
@@ -542,6 +549,7 @@ static Con *get_tree_next(Con *con, direction_t direction) {
switch (config.focus_wrapping) {
case FOCUS_WRAPPING_OFF:
break;
case FOCUS_WRAPPING_WORKSPACE:
case FOCUS_WRAPPING_ON:
if (!first_wrap && con_fullscreen_permits_focusing(wrap)) {
first_wrap = wrap;
@@ -561,6 +569,11 @@ static Con *get_tree_next(Con *con, direction_t direction) {
}
assert(con->type == CT_WORKSPACE);
if (config.focus_wrapping == FOCUS_WRAPPING_WORKSPACE) {
return first_wrap;
}
handle_workspace:;
Con *workspace = get_tree_next_workspace(con, direction);
return workspace ? workspace : first_wrap;
}