summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar wil <william.barsse@gmail.com>2016-12-22 18:46:00 +0100
committerLibravatar wil <william.barsse@gmail.com>2016-12-29 20:31:30 +0100
commit0ff9fe9a7a18a5130b7c5e979ba980409f91b5f1 (patch)
tree08d523251534f637582f168b87223d9e536724db
parent[fix] Handle auto layout resize with multiple slave groups (diff)
downloadsway-0ff9fe9a7a18a5130b7c5e979ba980409f91b5f1.tar.gz
sway-0ff9fe9a7a18a5130b7c5e979ba980409f91b5f1.tar.zst
sway-0ff9fe9a7a18a5130b7c5e979ba980409f91b5f1.zip
introduce next/prev as a direction for focus/move commands.
-rw-r--r--include/sway/focus.h5
-rw-r--r--sway/commands/focus.c4
-rw-r--r--sway/commands/layout.c3
-rw-r--r--sway/commands/move.c6
-rw-r--r--sway/layout.c65
-rw-r--r--sway/sway.5.txt6
6 files changed, 75 insertions, 14 deletions
diff --git a/include/sway/focus.h b/include/sway/focus.h
index b532edc2..30c9e108 100644
--- a/include/sway/focus.h
+++ b/include/sway/focus.h
@@ -6,7 +6,9 @@ enum movement_direction {
6 MOVE_UP, 6 MOVE_UP,
7 MOVE_DOWN, 7 MOVE_DOWN,
8 MOVE_PARENT, 8 MOVE_PARENT,
9 MOVE_CHILD 9 MOVE_CHILD,
10 MOVE_NEXT,
11 MOVE_PREV
10}; 12};
11 13
12#include "container.h" 14#include "container.h"
@@ -40,4 +42,3 @@ extern bool suspend_workspace_cleanup;
40bool move_focus(enum movement_direction direction); 42bool move_focus(enum movement_direction direction);
41 43
42#endif 44#endif
43
diff --git a/sway/commands/focus.c b/sway/commands/focus.c
index 8442305f..0be442ca 100644
--- a/sway/commands/focus.c
+++ b/sway/commands/focus.c
@@ -46,6 +46,10 @@ struct cmd_results *cmd_focus(int argc, char **argv) {
46 move_focus(MOVE_PARENT); 46 move_focus(MOVE_PARENT);
47 } else if (strcasecmp(argv[0], "child") == 0) { 47 } else if (strcasecmp(argv[0], "child") == 0) {
48 move_focus(MOVE_CHILD); 48 move_focus(MOVE_CHILD);
49 } else if (strcasecmp(argv[0], "next") == 0) {
50 move_focus(MOVE_NEXT);
51 } else if (strcasecmp(argv[0], "prev") == 0) {
52 move_focus(MOVE_PREV);
49 } else if (strcasecmp(argv[0], "mode_toggle") == 0) { 53 } else if (strcasecmp(argv[0], "mode_toggle") == 0) {
50 int i; 54 int i;
51 swayc_t *workspace = swayc_active_workspace(); 55 swayc_t *workspace = swayc_active_workspace();
diff --git a/sway/commands/layout.c b/sway/commands/layout.c
index 5e2e8efd..9e468c21 100644
--- a/sway/commands/layout.c
+++ b/sway/commands/layout.c
@@ -49,7 +49,8 @@ struct cmd_results *cmd_layout(int argc, char **argv) {
49 } else if (strcasecmp(argv[0], "splitv") == 0) { 49 } else if (strcasecmp(argv[0], "splitv") == 0) {
50 swayc_change_layout(parent, L_VERT); 50 swayc_change_layout(parent, L_VERT);
51 } else if (strcasecmp(argv[0], "toggle") == 0 && argc == 2 && strcasecmp(argv[1], "split") == 0) { 51 } else if (strcasecmp(argv[0], "toggle") == 0 && argc == 2 && strcasecmp(argv[1], "split") == 0) {
52 if (parent->layout == L_HORIZ && (parent->workspace_layout == L_NONE || parent->workspace_layout == L_HORIZ)) { 52 if (parent->layout == L_HORIZ && (parent->workspace_layout == L_NONE ||
53 parent->workspace_layout == L_HORIZ)) {
53 swayc_change_layout(parent, L_VERT); 54 swayc_change_layout(parent, L_VERT);
54 } else { 55 } else {
55 swayc_change_layout(parent, L_HORIZ); 56 swayc_change_layout(parent, L_HORIZ);
diff --git a/sway/commands/move.c b/sway/commands/move.c
index 4819d9ef..4f6bc76f 100644
--- a/sway/commands/move.c
+++ b/sway/commands/move.c
@@ -13,7 +13,7 @@ struct cmd_results *cmd_move(int argc, char **argv) {
13 if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) { 13 if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) {
14 return error; 14 return error;
15 } 15 }
16 const char* expected_syntax = "Expected 'move <left|right|up|down>' or " 16 const char* expected_syntax = "Expected 'move <left|right|up|down|next|prev>' or "
17 "'move <container|window> to workspace <name>' or " 17 "'move <container|window> to workspace <name>' or "
18 "'move <container|window|workspace> to output <name|direction>' or " 18 "'move <container|window|workspace> to output <name|direction>' or "
19 "'move position mouse'"; 19 "'move position mouse'";
@@ -27,6 +27,10 @@ struct cmd_results *cmd_move(int argc, char **argv) {
27 move_container(view, MOVE_UP); 27 move_container(view, MOVE_UP);
28 } else if (strcasecmp(argv[0], "down") == 0) { 28 } else if (strcasecmp(argv[0], "down") == 0) {
29 move_container(view, MOVE_DOWN); 29 move_container(view, MOVE_DOWN);
30 } else if (strcasecmp(argv[0], "next") == 0) {
31 move_container(view, MOVE_NEXT);
32 } else if (strcasecmp(argv[0], "prev") == 0) {
33 move_container(view, MOVE_PREV);
30 } else if (strcasecmp(argv[0], "container") == 0 || strcasecmp(argv[0], "window") == 0) { 34 } else if (strcasecmp(argv[0], "container") == 0 || strcasecmp(argv[0], "window") == 0) {
31 // "move container ... 35 // "move container ...
32 if ((error = checkarg(argc, "move container/window", EXPECTED_AT_LEAST, 4))) { 36 if ((error = checkarg(argc, "move container/window", EXPECTED_AT_LEAST, 4))) {
diff --git a/sway/layout.c b/sway/layout.c
index 0428ecf9..a8ad7ed5 100644
--- a/sway/layout.c
+++ b/sway/layout.c
@@ -251,7 +251,7 @@ void swap_geometry(swayc_t *a, swayc_t *b) {
251} 251}
252 252
253void move_container(swayc_t *container, enum movement_direction dir) { 253void move_container(swayc_t *container, enum movement_direction dir) {
254 enum swayc_layouts layout; 254 enum swayc_layouts layout = L_NONE;
255 if (container->is_floating 255 if (container->is_floating
256 || (container->type != C_VIEW && container->type != C_CONTAINER)) { 256 || (container->type != C_VIEW && container->type != C_CONTAINER)) {
257 return; 257 return;
@@ -260,7 +260,7 @@ void move_container(swayc_t *container, enum movement_direction dir) {
260 layout = L_VERT; 260 layout = L_VERT;
261 } else if (dir == MOVE_LEFT || dir == MOVE_RIGHT) { 261 } else if (dir == MOVE_LEFT || dir == MOVE_RIGHT) {
262 layout = L_HORIZ; 262 layout = L_HORIZ;
263 } else { 263 } else if (! (dir == MOVE_NEXT || dir == MOVE_PREV)) {
264 return; 264 return;
265 } 265 }
266 swayc_t *parent = container->parent; 266 swayc_t *parent = container->parent;
@@ -284,18 +284,51 @@ void move_container(swayc_t *container, enum movement_direction dir) {
284 container,parent,child); 284 container,parent,child);
285 if (parent->layout == layout 285 if (parent->layout == layout
286 || (parent->layout == L_TABBED && layout == L_HORIZ) 286 || (parent->layout == L_TABBED && layout == L_HORIZ)
287 || (parent->layout == L_STACKED && layout == L_VERT)) { 287 || (parent->layout == L_STACKED && layout == L_VERT)
288 || is_auto_layout(parent->layout)) {
288 int diff; 289 int diff;
289 // If it has ascended (parent has moved up), no container is removed 290 // If it has ascended (parent has moved up), no container is removed
290 // so insert it at index, or index+1. 291 // so insert it at index, or index+1.
291 // if it has not, the moved container is removed, so it needs to be 292 // if it has not, the moved container is removed, so it needs to be
292 // inserted at index-1, or index+1 293 // inserted at index-1, or index+1
293 if (ascended) { 294 if (ascended) {
294 diff = dir == MOVE_LEFT || dir == MOVE_UP ? 0 : 1; 295 diff = dir == MOVE_LEFT || dir == MOVE_UP || dir == MOVE_PREV ? 0 : 1;
295 } else { 296 } else {
296 diff = dir == MOVE_LEFT || dir == MOVE_UP ? -1 : 1; 297 diff = dir == MOVE_LEFT || dir == MOVE_UP || dir == MOVE_PREV ? -1 : 1;
298 }
299 int idx = index_child(child);
300 int desired = idx + diff;
301 if (dir == MOVE_NEXT || dir == MOVE_PREV) {
302 // Next/Prev always wrap.
303 if (desired < 0) {
304 desired += parent->children->length;
305 } else if (desired >= parent->children->length) {
306 desired = 0;
307 }
308 // if move command makes container change from master to slave
309 // (or the contrary), reset its geometry an the one of the replaced item.
310 if (parent->nb_master &&
311 (uint_fast32_t) parent->children->length > parent->nb_master) {
312 swayc_t *swap_geom = NULL;
313 // if child is being promoted/demoted, it will swap geometry
314 // with the sibling being demoted/promoted.
315 if ((dir == MOVE_NEXT && desired == 0)
316 || (dir == MOVE_PREV && (uint_fast32_t) desired == parent->nb_master - 1)) {
317 swap_geom = parent->children->items[parent->nb_master - 1];
318 } else if ((dir == MOVE_NEXT && (uint_fast32_t) desired == parent->nb_master)
319 || (dir == MOVE_PREV && desired == parent->children->length - 1)) {
320 swap_geom = parent->children->items[parent->nb_master];
321 }
322 if (swap_geom) {
323 double h = child->height;
324 double w = child->width;
325 child->width = swap_geom->width;
326 child->height = swap_geom->height;
327 swap_geom->width = w;
328 swap_geom->height = h;
329 }
330 }
297 } 331 }
298 int desired = index_child(child) + diff;
299 // when it has ascended, legal insertion position is 0:len 332 // when it has ascended, legal insertion position is 0:len
300 // when it has not, legal insertion position is 0:len-1 333 // when it has not, legal insertion position is 0:len-1
301 if (desired >= 0 && desired - ascended < parent->children->length) { 334 if (desired >= 0 && desired - ascended < parent->children->length) {
@@ -308,7 +341,8 @@ void move_container(swayc_t *container, enum movement_direction dir) {
308 // insert it next to focused container 341 // insert it next to focused container
309 if (parent->layout == layout 342 if (parent->layout == layout
310 || (parent->layout == L_TABBED && layout == L_HORIZ) 343 || (parent->layout == L_TABBED && layout == L_HORIZ)
311 || (parent->layout == L_STACKED && layout == L_VERT)) { 344 || (parent->layout == L_STACKED && layout == L_VERT)
345 || is_auto_layout(parent->layout)) {
312 desired = (diff < 0) * parent->children->length; 346 desired = (diff < 0) * parent->children->length;
313 } else { 347 } else {
314 desired = index_child(child->focused) + 1; 348 desired = index_child(child->focused) + 1;
@@ -325,7 +359,7 @@ void move_container(swayc_t *container, enum movement_direction dir) {
325 } 359 }
326 } 360 }
327 // Change parent layout if we need to 361 // Change parent layout if we need to
328 if (parent->children->length == 1 && parent->layout != layout) { 362 if (parent->children->length == 1 && parent->layout != layout && layout != L_NONE) {
329 /* swayc_change_layout(parent, layout); */ 363 /* swayc_change_layout(parent, layout); */
330 parent->layout = layout; 364 parent->layout = layout;
331 continue; 365 continue;
@@ -1310,6 +1344,21 @@ swayc_t *get_swayc_in_direction_under(swayc_t *container, enum movement_directio
1310 return parent; 1344 return parent;
1311 } 1345 }
1312 } 1346 }
1347
1348 if (dir == MOVE_PREV || dir == MOVE_NEXT) {
1349 int focused_idx = index_child(container);
1350 if (focused_idx == -1) {
1351 return NULL;
1352 } else {
1353 int desired = (focused_idx + (dir == MOVE_NEXT ? 1 : -1)) %
1354 parent->children->length;
1355 if (desired < 0) {
1356 desired += parent->children->length;
1357 }
1358 return parent->children->items[desired];
1359 }
1360 }
1361
1313 // If moving to an adjacent output we need a starting position (since this 1362 // If moving to an adjacent output we need a starting position (since this
1314 // output might border to multiple outputs). 1363 // output might border to multiple outputs).
1315 struct wlc_point abs_pos; 1364 struct wlc_point abs_pos;
diff --git a/sway/sway.5.txt b/sway/sway.5.txt
index 2fa5f32e..8f8302f0 100644
--- a/sway/sway.5.txt
+++ b/sway/sway.5.txt
@@ -92,8 +92,10 @@ They are expected to be used with **bindsym** or at runtime through **swaymsg**(
92 focused container. <n> can be a positive or negative integer. These commands 92 focused container. <n> can be a positive or negative integer. These commands
93 only have an effect if the focused container uses one of the "auto" layouts. 93 only have an effect if the focused container uses one of the "auto" layouts.
94 94
95**move** <left|right|up|down>:: 95**move** <left|right|up|down|next|prev>::
96 Moves the focused container _left_, _right_, _up_, or _down_. 96 Moves the focused container _left_, _right_, _up_, or _down_. Moving
97 to _prev_ or _next_ swaps the container with its sibling in the same
98 container.
97 99
98**move** <container|window> to workspace <name>:: 100**move** <container|window> to workspace <name>::
99 Moves the focused container to the workspace identified by _name_. 101 Moves the focused container to the workspace identified by _name_.