summaryrefslogtreecommitdiffstats
path: root/sway/layout.c
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 /sway/layout.c
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.
Diffstat (limited to 'sway/layout.c')
-rw-r--r--sway/layout.c65
1 files changed, 57 insertions, 8 deletions
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;