summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sway/commands.c1
-rw-r--r--sway/layout.c59
2 files changed, 34 insertions, 26 deletions
diff --git a/sway/commands.c b/sway/commands.c
index de98b624..8a790384 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -366,7 +366,6 @@ static bool cmd_move(struct sway_config *config, int argc, char **argv) {
366 return false; 366 return false;
367 } 367 }
368 368
369 // TODO handle case of workspace, something similar to _do_split
370 if (view->type != C_CONTAINER && view->type != C_VIEW) { 369 if (view->type != C_CONTAINER && view->type != C_VIEW) {
371 return false; 370 return false;
372 } 371 }
diff --git a/sway/layout.c b/sway/layout.c
index 103ede52..b558e704 100644
--- a/sway/layout.c
+++ b/sway/layout.c
@@ -195,7 +195,6 @@ void swap_geometry(swayc_t *a, swayc_t *b) {
195// TODO fix workspace movement, as in 195// TODO fix workspace movement, as in
196// [a][b][c] => |move b| => [aa][cc] 196// [a][b][c] => |move b| => [aa][cc]
197// [a][b][c] => |down | => [bbbbbb] 197// [a][b][c] => |down | => [bbbbbb]
198//
199void move_container(swayc_t *container, enum movement_direction dir) { 198void move_container(swayc_t *container, enum movement_direction dir) {
200 enum swayc_layouts layout; 199 enum swayc_layouts layout;
201 if (container->is_floating) { 200 if (container->is_floating) {
@@ -210,37 +209,37 @@ void move_container(swayc_t *container, enum movement_direction dir) {
210 } 209 }
211 swayc_t *parent = container->parent; 210 swayc_t *parent = container->parent;
212 swayc_t *child = container; 211 swayc_t *child = container;
212 bool ascended = false;
213 while (true) { 213 while (true) {
214 sway_log(L_DEBUG, "container:%p, parent:%p, child %p,", 214 sway_log(L_DEBUG, "container:%p, parent:%p, child %p,",
215 container,parent,child); 215 container,parent,child);
216 if (parent->layout == layout) { 216 if (parent->layout == layout) {
217 int diff; 217 int diff;
218 // When child == container the container is removed, 218 // If it has ascended (parent has moved up), no container is removed
219 // so when inserting it back in, it needs to be -1, or 1 219 // so insert it at index, or index+1.
220 // inserts at 1-1 or 1+1 220 // if it has not, the moved container is removed, so it needs to be
221 // 0 1 2 3 => 0 1 2 => 0 1 2 3 or 0 1 2 3 221 // inserted at index-1, or index+1
222 // |0|1|2| => |0|2| => |1|0|2| or |0|2|1| 222 if (ascended) {
223 // When child != container, no container is removed
224 // inserts at 1+0 or 1+1
225 // 0 1 2 3 => 0 1 2 3 4 or 0 1 2 3 4
226 // |0|1|2| => |0|n|1|2| or |0|1|n|2|
227 if (child == container) {
228 diff = dir == MOVE_LEFT || dir == MOVE_UP ? -1 : 1;
229 } else {
230 diff = dir == MOVE_LEFT || dir == MOVE_UP ? 0 : 1; 223 diff = dir == MOVE_LEFT || dir == MOVE_UP ? 0 : 1;
224 } else {
225 diff = dir == MOVE_LEFT || dir == MOVE_UP ? -1 : 1;
231 } 226 }
232 int desired = index_child(child) + diff; 227 int desired = index_child(child) + diff;
233 // Legal position 228 // when it has ascended, legal insertion position is 0:len
234 // when child == container, desired must be less then parent, 229 // when it has not, legal insertion position is 0:len-1
235 // when child != container, desired can be equal to parent length 230 if (desired >= 0 && desired - ascended < parent->children->length) {
236 if (desired >= 0 && desired - (child != container) < parent->children->length) { 231 if (!ascended) {
237 // Case where we descend into a container
238 if (child == container) {
239 child = parent->children->items[desired]; 232 child = parent->children->items[desired];
240 // Move container Into child container. 233 // Move container into sibling container
241 if (child->type == C_CONTAINER) { 234 if (child->type == C_CONTAINER) {
242 parent = child; 235 parent = child;
243 desired = index_child(child->focused); 236 // Insert it in first/last if matching layout,otherwise
237 // inesrt it next to focused container
238 if (parent->layout == layout) {
239 desired = (diff < 0) * parent->children->length;
240 } else {
241 desired = index_child(child->focused);
242 }
244 //reset geometry 243 //reset geometry
245 container->width = container->height = 0; 244 container->width = container->height = 0;
246 } 245 }
@@ -252,12 +251,22 @@ void move_container(swayc_t *container, enum movement_direction dir) {
252 break; 251 break;
253 } 252 }
254 } 253 }
254 // Change parent layout if we need to
255 if (parent->children->length == 1 && parent->layout != layout) {
256 parent->layout = layout;
257 continue;
258 }
259 if (parent->type == C_WORKSPACE) {
260 // We simply cannot move any further.
261 if (parent->layout == layout) {
262 break;
263 }
264 // Create container around workspace to insert child into
265 parent = new_container(parent, layout);
266 }
267 ascended = true;
255 child = parent; 268 child = parent;
256 parent = child->parent; 269 parent = child->parent;
257 if (!parent || child->type == C_WORKSPACE) {
258 sway_log(L_DEBUG, "Failed to move container");
259 return;
260 }
261 } 270 }
262 // Dirty hack to fix a certain case 271 // Dirty hack to fix a certain case
263 arrange_windows(parent, -1, -1); 272 arrange_windows(parent, -1, -1);