Refactor tree_next

- Makes `tree_next` not recursive.
- Adds `focus next|prev [sibling]` command. See (1.) and (2.) in
https://github.com/i3/i3/issues/2587#issuecomment-378505551 (Issue also
requests move command, not implemented here).
- Directional focus command now supports command criteria.

Wrapping is not implemented inside a floating container. This was also
true before the refactor so I am not changing it here.
This commit is contained in:
Orestis Floros
2018-09-14 18:34:43 +03:00
committed by Orestis Floros
parent f402f45702
commit bbc4c99c72
9 changed files with 295 additions and 162 deletions

View File

@ -1229,23 +1229,62 @@ void cmd_exec(I3_CMD, const char *nosn, const char *command) {
} while (0)
/*
* Implementation of 'focus left|right|up|down'.
* Implementation of 'focus left|right|up|down|next|prev'.
*
*/
void cmd_focus_direction(I3_CMD, const char *direction) {
switch (parse_direction(direction)) {
case D_LEFT:
tree_next('p', HORIZ);
break;
case D_RIGHT:
tree_next('n', HORIZ);
break;
case D_UP:
tree_next('p', VERT);
break;
case D_DOWN:
tree_next('n', VERT);
break;
void cmd_focus_direction(I3_CMD, const char *direction_str) {
HANDLE_EMPTY_MATCH;
CMD_FOCUS_WARN_CHILDREN;
direction_t direction;
position_t position;
bool auto_direction = true;
if (strcmp(direction_str, "prev") == 0) {
position = BEFORE;
} else if (strcmp(direction_str, "next") == 0) {
position = AFTER;
} else {
auto_direction = false;
direction = parse_direction(direction_str);
}
owindow *current;
TAILQ_FOREACH(current, &owindows, owindows) {
Con *ws = con_get_workspace(current->con);
if (!ws || con_is_internal(ws)) {
continue;
}
if (auto_direction) {
orientation_t o = con_orientation(current->con->parent);
direction = direction_from_orientation_position(o, position);
}
tree_next(current->con, direction);
}
cmd_output->needs_tree_render = true;
// XXX: default reply for now, make this a better reply
ysuccess(true);
}
/*
* Implementation of 'focus next|prev sibling'
*
*/
void cmd_focus_sibling(I3_CMD, const char *direction_str) {
HANDLE_EMPTY_MATCH;
CMD_FOCUS_WARN_CHILDREN;
const position_t direction = (STARTS_WITH(direction_str, "prev")) ? BEFORE : AFTER;
owindow *current;
TAILQ_FOREACH(current, &owindows, owindows) {
Con *ws = con_get_workspace(current->con);
if (!ws || con_is_internal(ws)) {
continue;
}
Con *next = get_tree_next_sibling(current->con, direction);
if (next) {
con_activate(next);
}
}
cmd_output->needs_tree_render = true;