Commit 9c0e9500c151
tarball2 files changed+47-6
@@ -351,3 +351,28 @@ fn stacking_in_and_out_does_not_drift() {
351351
assert_eq!(t.arrange(AREA, 0.0, |_| true), once, "stepping out {out:?}");352352
}353353
}354
+355
+/// Hidden windows in the rows around a window must not soak up its weight356
+/// as it passes through their lanes, or it shrinks on every round trip.357
+#[test]358
+fn moving_past_hidden_windows_does_not_drift() {359
+ let (a, b, h, h2) = (1, 2, 3, 4);360
+ let mut t: Tree<u32> = Tree::default();361
+ t.insert_row(h);362
+ t.insert_row(a);363
+ t.insert_after(h2, a);364
+ t.insert_after(b, h2);365
+ let vis = |w: u32| w != h && w != h2;366
+ let once = t.arrange(AREA, 0.0, |_| true);367
+ for _ in 0..4 {368
+ for d in [Dir::Up, Dir::Up, Dir::Down] {369
+ assert!(t.move_window(b, d, vis));370
+ }371
+ t.check();372
+ }373
+ let after = t.arrange(AREA, 0.0, |_| true);374
+ for ((w, r), (v, s)) in once.iter().zip(&after) {375
+ assert_eq!(w, v);376
+ assert!((r.y - s.y).abs() < 1e-6 && (r.h - s.h).abs() < 1e-6, "{w}: {r:?} became {s:?}");377
+ }378
+}@@ -434,8 +434,7 @@ impl<W: Copy + Eq + Hash> Tree<W> {
434434
if let Some(j) = self.next_shown(p, i, dir, vis) {435435
let sib = self.children(p)[j].node;436436
if enter && self.axis(sib).is_some() {437
- let end = self.children(sib).len();438
- self.relocate(n, sib, end);437
+ self.join_lane(n, p, j);439438
} else {440439
let children = self.children_mut(p);441440
children[i].node = sib;@@ -517,9 +516,23 @@ impl<W: Copy + Eq + Hash> Tree<W> {
517516
c518517
};519518
let end = self.children(lane).len();520
- let from_p = self.position(n).filter(|&(old, _)| old == p);521
- let weight = from_p.map(|(_, i)| self.children(p)[i].weight);522
- self.relocate(n, lane, end);519
+ let (old, i) = self.position(n).expect("n is below p");520
+ let weight = if old == p {521
+ Some(self.children(p)[i].weight)522
+ } else if self.position(old).is_some_and(|(q, _)| q == p) {523
+ self.release_share(n)524
+ } else {525
+ None526
+ };527
+ let inner = match weight {528
+ Some(weight) => {529
+ let k = self.position(lane).expect("lanes sit in p").1;530
+ let total: f64 = self.children(lane).iter().map(|c| c.weight).sum();531
+ total * weight / self.children(p)[k].weight532
+ }533
+ None => self.mean_weight(lane),534
+ };535
+ self.relocate_weighted(n, lane, end, inner);523536
if let Some(weight) = weight524537
&& self.nodes.contains_key(lane)525538
&& let Some((q, k)) = self.position(lane)@@ -557,8 +570,11 @@ impl<W: Copy + Eq + Hash> Tree<W> {
557570
}558571
559572
fn relocate(&mut self, n: NodeId, p: NodeId, at: usize) {573
+ self.relocate_weighted(n, p, at, self.mean_weight(p));574
+ }575
+576
+ fn relocate_weighted(&mut self, n: NodeId, p: NodeId, at: usize, weight: f64) {560577
let (old, i) = self.position(n).expect("relocated nodes have a parent");561
- let weight = self.mean_weight(p);562578
let at = if old == p && i < at { at - 1 } else { at };563579
self.unlink(old, i);564580
self.attach(p, at, n, weight);