diff options
author | wil <william.barsse@gmail.com> | 2016-12-22 18:46:00 +0100 |
---|---|---|
committer | wil <william.barsse@gmail.com> | 2016-12-29 20:31:30 +0100 |
commit | 0ff9fe9a7a18a5130b7c5e979ba980409f91b5f1 (patch) | |
tree | 08d523251534f637582f168b87223d9e536724db /sway | |
parent | [fix] Handle auto layout resize with multiple slave groups (diff) | |
download | sway-0ff9fe9a7a18a5130b7c5e979ba980409f91b5f1.tar.gz sway-0ff9fe9a7a18a5130b7c5e979ba980409f91b5f1.tar.zst sway-0ff9fe9a7a18a5130b7c5e979ba980409f91b5f1.zip |
introduce next/prev as a direction for focus/move commands.
Diffstat (limited to 'sway')
-rw-r--r-- | sway/commands/focus.c | 4 | ||||
-rw-r--r-- | sway/commands/layout.c | 3 | ||||
-rw-r--r-- | sway/commands/move.c | 6 | ||||
-rw-r--r-- | sway/layout.c | 65 | ||||
-rw-r--r-- | sway/sway.5.txt | 6 |
5 files changed, 72 insertions, 12 deletions
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 | ||
253 | void move_container(swayc_t *container, enum movement_direction dir) { | 253 | void 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_. |