From 7f558ce894934bd347140f5edd6419bf7d115c26 Mon Sep 17 00:00:00 2001 From: "D.B" Date: Fri, 7 Oct 2016 07:10:06 +0200 Subject: [PATCH 1/3] wrap container in direction (if possible) Introduces container wrapping - if there is no other viable move, the selection wraps on the first container where such action is possible. --- sway/layout.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/sway/layout.c b/sway/layout.c index 6012af661..f10e21bda 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -1084,13 +1084,17 @@ swayc_t *get_swayc_in_direction_under(swayc_t *container, enum movement_directio return container->fullscreen; } + swayc_t *wrap_candidate = NULL; while (true) { // Test if we can even make a difference here bool can_move = false; int diff = 0; if (parent->type == C_ROOT) { - sway_log(L_DEBUG, "Moving between outputs"); swayc_t *output = swayc_adjacent_output(container, dir, &abs_pos, true); + if (!output || output == container) { + return wrap_candidate; + } + sway_log(L_DEBUG, "Moving between outputs"); return get_swayc_in_output_direction(output, dir); } else { if (dir == MOVE_LEFT || dir == MOVE_RIGHT) { @@ -1108,8 +1112,18 @@ swayc_t *get_swayc_in_direction_under(swayc_t *container, enum movement_directio if (can_move) { int desired = index_child(container) + diff; - if (container->is_floating || desired < 0 || desired >= parent->children->length) { + if (container->is_floating) { can_move = false; + } else if (desired < 0 || desired >= parent->children->length) { + can_move = false; + int len = parent->children->length; + if (!wrap_candidate && len > 1) { + if (desired < 0) { + wrap_candidate = parent->children->items[len-1]; + } else { + wrap_candidate = parent->children->items[0]; + } + } } else { return parent->children->items[desired]; } @@ -1118,8 +1132,8 @@ swayc_t *get_swayc_in_direction_under(swayc_t *container, enum movement_directio container = parent; parent = parent->parent; if (!parent || container == limit) { - // Nothing we can do - return NULL; + // wrapping is the last chance + return wrap_candidate; } } } From d3f5ac8cbbdde88e5822c1d9dd20ce9cbde8cbbe Mon Sep 17 00:00:00 2001 From: "D.B" Date: Fri, 7 Oct 2016 07:32:57 +0200 Subject: [PATCH 2/3] add force_focus_wrapping option --- include/sway/commands.h | 1 + include/sway/config.h | 1 + sway/commands.c | 1 + sway/commands/force_focus_wrapping.c | 12 ++++++++++++ sway/layout.c | 3 +++ 5 files changed, 18 insertions(+) create mode 100644 sway/commands/force_focus_wrapping.c diff --git a/include/sway/commands.h b/include/sway/commands.h index f646c4126..fe67c58c5 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -106,6 +106,7 @@ sway_cmd cmd_focus; sway_cmd cmd_focus_follows_mouse; sway_cmd cmd_font; sway_cmd cmd_for_window; +sway_cmd cmd_force_focus_wrapping; sway_cmd cmd_fullscreen; sway_cmd cmd_gaps; sway_cmd cmd_hide_edge_borders; diff --git a/include/sway/config.h b/include/sway/config.h index 56deaf01f..b29fe6c54 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -211,6 +211,7 @@ struct sway_config { // Flags bool focus_follows_mouse; bool mouse_warping; + bool force_focus_wrapping; bool active; bool failed; bool reloading; diff --git a/sway/commands.c b/sway/commands.c index 317122cd2..d93f6591f 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -171,6 +171,7 @@ static struct cmd_handler handlers[] = { { "focus", cmd_focus }, { "focus_follows_mouse", cmd_focus_follows_mouse }, { "font", cmd_font }, + { "force_focus_wrapping", cmd_force_focus_wrapping }, { "for_window", cmd_for_window }, { "fullscreen", cmd_fullscreen }, { "gaps", cmd_gaps }, diff --git a/sway/commands/force_focus_wrapping.c b/sway/commands/force_focus_wrapping.c new file mode 100644 index 000000000..23019cd37 --- /dev/null +++ b/sway/commands/force_focus_wrapping.c @@ -0,0 +1,12 @@ +#include +#include "sway/commands.h" + +struct cmd_results *cmd_force_focus_wrapping(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "force_focus_wrapping", EXPECTED_EQUAL_TO, 1))) { + return error; + } + + config->force_focus_wrapping = !strcasecmp(argv[0], "yes"); + return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} diff --git a/sway/layout.c b/sway/layout.c index f10e21bda..a7206e9a5 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -1123,6 +1123,9 @@ swayc_t *get_swayc_in_direction_under(swayc_t *container, enum movement_directio } else { wrap_candidate = parent->children->items[0]; } + if (config->force_focus_wrapping) { + return wrap_candidate; + } } } else { return parent->children->items[desired]; From 379b1a0378292ff1c470276f1caad59f36c7fc66 Mon Sep 17 00:00:00 2001 From: "D.B" Date: Fri, 7 Oct 2016 07:42:51 +0200 Subject: [PATCH 3/3] add focus changing between floating containers It will also wrap if needed. --- sway/layout.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sway/layout.c b/sway/layout.c index a7206e9a5..3629df248 100644 --- a/sway/layout.c +++ b/sway/layout.c @@ -1113,7 +1113,17 @@ swayc_t *get_swayc_in_direction_under(swayc_t *container, enum movement_directio if (can_move) { int desired = index_child(container) + diff; if (container->is_floating) { - can_move = false; + if (desired < 0) { + wrap_candidate = parent->floating->items[parent->floating->length-1]; + } else if (desired >= parent->floating->length){ + wrap_candidate = parent->floating->items[0]; + } else { + wrap_candidate = parent->floating->items[desired]; + } + if (wrap_candidate) { + wlc_view_bring_to_front(wrap_candidate->handle); + } + return wrap_candidate; } else if (desired < 0 || desired >= parent->children->length) { can_move = false; int len = parent->children->length;