Commit 60f00dd4f2be
tarball4 files changed+68-3
@@ -5,3 +5,4 @@
55
# It is recommended to check this file in to source control so that66
# everyone who runs the test benefits from these saved cases.77
cc feaaec708a35beac0ab9749dd260c423ed4177da099bd85a2041f38172334f65 # shrinks to ops = [Add(0, false), Add(0, false), Add(0, false), View(1), Scratch(0), Add(0, false), Add(0, false), Add(0, false), Summon, Summon, Flip, Add(1, false), Move(Left), Add(0, false), Add(0, false), Focus(114), Flip, Move(Left), Focus(0), Add(0, false), View(0), View(0), View(0), Add(0, false), Expand(0)]8
+cc 796d3b6a182db230a58f8fcf320dde6b4ffd5ff3128b07a4f4c75737b25d9e88 # shrinks to ops = [Add(0, false), Focus(0), Add(0, false), Focus(30), View(3), Focus(0), Add(3, false), Move(Up), Add(0, false), Move(Left), Add(0, false), View(0), Add(0, false), Block(Right), Add(0, false), Move(Right), Add(0, false), View(3), Flip, Add(3, false), Expand(0), View(0), Move(Right)]@@ -186,3 +186,24 @@ fn hidden_windows_keep_their_slots() {
186186
t.check();187187
assert_eq!(rect(&t, e).w, AREA.w, "E is demoted to a row of its own");188188
}189
+190
+/// Moving out of a row toward a lane of hidden windows joins that lane, so191
+/// they share it when shown again instead of a new lane opening between.192
+#[test]193
+fn moving_toward_a_hidden_lane_joins_it() {194
+ let (a, b, c, d, e) = (1, 2, 3, 4, 5);195
+ let mut t: Tree<u32> = Tree::default();196
+ t.insert_row(a);197
+ t.insert_after(b, a);198
+ t.insert_after(c, b);199
+ t.insert_row(d);200
+ t.insert_after(e, c);201
+ let tag_two = |w: u32| w != a && w != d;202
+ assert!(t.move_window(e, Dir::Down, tag_two));203
+ t.check();204
+ let all = t.arrange(AREA, 0.0, |_| true);205
+ let rect = |w| all.iter().find(|p| p.0 == w).unwrap().1;206
+ assert_eq!(rect(e).y, rect(d).y);207
+ assert!(rect(d).x < rect(e).x);208
+ assert!(rect(a).y < rect(d).y);209
+}@@ -339,9 +339,16 @@ impl<W: Copy + Eq + Hash> Tree<W> {
339339
let mut cur = n;340340
while let Some((p, i)) = self.position(cur) {341341
if self.axis(p) == Some(dir.axis()) {342
+ let hidden_lane = self343
+ .adjacent(p, i, dir)344
+ .filter(|&j| enter && !self.visible(self.children(p)[j].node, vis));342345
if cur != n {343
- let at = if dir.forward() { i + 1 } else { i };344
- self.relocate(n, p, at);346
+ if let Some(j) = hidden_lane {347
+ self.join_lane(n, p, j);348
+ } else {349
+ let at = if dir.forward() { i + 1 } else { i };350
+ self.relocate(n, p, at);351
+ }345352
return true;346353
}347354
if let Some(j) = self.next_shown(p, i, dir, vis) {@@ -356,6 +363,10 @@ impl<W: Copy + Eq + Hash> Tree<W> {
356363
}357364
return true;358365
}366
+ if let Some(j) = hidden_lane {367
+ self.join_lane(n, p, j);368
+ return true;369
+ }359370
}360371
cur = p;361372
}@@ -397,6 +408,38 @@ impl<W: Copy + Eq + Hash> Tree<W> {
397408
}398409
}399410
411
+ fn adjacent(&self, p: NodeId, i: usize, dir: Dir) -> Option<usize> {412
+ let j = if dir.forward() {413
+ i + 1414
+ } else {415
+ i.checked_sub(1)?416
+ };417
+ (j < self.children(p).len()).then_some(j)418
+ }419
+420
+ /// Moves `n` to the end of the lane at `p`'s child `j`, which holds only421
+ /// hidden windows, so it shares that lane when they come back instead of422
+ /// opening a new one beside it. A lone window becomes a lane of its own.423
+ fn join_lane(&mut self, n: NodeId, p: NodeId, j: usize) {424
+ let lane = self.children(p)[j].node;425
+ let lane = if self.axis(lane).is_some() {426
+ lane427
+ } else {428
+ let c = self.new_container(self.axis(p).expect("p is a container").other());429
+ self.children_mut(p)[j].node = c;430
+ self.nodes[c].parent = Some(p);431
+ if let Kind::Container { expanded, .. } = &mut self.nodes[p].kind432
+ && *expanded == Some(lane)433
+ {434
+ *expanded = Some(c);435
+ }436
+ self.attach(c, 0, lane, 1.0);437
+ c438
+ };439
+ let end = self.children(lane).len();440
+ self.relocate(n, lane, end);441
+ }442
+400443
fn relocate(&mut self, n: NodeId, p: NodeId, at: usize) {401444
let (old, i) = self.position(n).expect("relocated nodes have a parent");402445
let weight = self.mean_weight(p);@@ -92,7 +92,7 @@ Running log of settled decisions and open questions. Research backing lives in `
9292
- Floating to tiled and fullscreen use a direct glide above the tiled layer. Expand is a tiled operation planned normally, siblings squeezed to zero-size lines.9393
- One layout tree per output, tags filter it. Hidden windows keep their slots, visible moves swap visible slots only, containers collapse by the normal one-child rule counting hidden children, and a hidden only child is demoted into the grandparent. This replaces per-tag layouts and the row-stacking merge rule, row stacking is just the default arrangement.9494
- Lanes span only the band of the involved windows, never the whole output.95
-- Hidden-slot rules confirmed.95
+- Hidden-slot rules confirmed. A window moving toward a lane that holds only hidden windows joins that lane rather than opening a new one beside it.9696
- Input hit-tests against final layout geometry, never animated geometry.9797
- smithay is pinned by git rev. The repo uses jj.