Commit 1a10e81ae5c1
tarball2 files changed+50-0
@@ -87,12 +87,47 @@ impl GroupPlan {
8787
}8888
8989
/// Plans the transition from `from` to `to`. Both slices index the same windows.90
+/// Windows with no area at either end, like hidden ones held at their seed,91
+/// jump straight to `to`. Planning them would let an invisible point inside92
+/// a visible window join its group, or block every strategy and pinch.9093
pub fn plan(from: &[Rect], to: &[Rect], cfg: &Config) -> Plan {9194
assert_eq!(9295
from.len(),9396
to.len(),9497
"layouts must describe the same windows"9598
);99
+ let empty = |r: &Rect| r.w <= cfg.eps || r.h <= cfg.eps;100
+ let live: Vec<usize> = (0..from.len())101
+ .filter(|&i| !(empty(&from[i]) && empty(&to[i])))102
+ .collect();103
+ if live.len() == from.len() {104
+ return plan_live(from, to, cfg);105
+ }106
+ let pick = |rects: &[Rect]| live.iter().map(|&i| rects[i]).collect::<Vec<_>>();107
+ let inner = plan_live(&pick(from), &pick(to), cfg);108
+ let keyframes = inner109
+ .keyframes110
+ .iter()111
+ .map(|key| {112
+ let mut frame = to.to_vec();113
+ for (k, &i) in live.iter().enumerate() {114
+ frame[i] = key[k];115
+ }116
+ frame117
+ })118
+ .collect();119
+ let groups = inner120
+ .groups121
+ .into_iter()122
+ .map(|g| Group {123
+ members: g.members.iter().map(|&k| live[k]).collect(),124
+ ..g125
+ })126
+ .collect();127
+ Plan { keyframes, groups }128
+}129
+130
+fn plan_live(from: &[Rect], to: &[Rect], cfg: &Config) -> Plan {96131
let mut groups = Vec::new();97132
let mut plans = Vec::new();98133
for members in motion_groups(from, to, cfg) {@@ -251,3 +251,18 @@ proptest! {
251251
prop_assert_eq!(&second.keyframes[0], &mid);252252
}253253
}254
+255
+/// A hidden window is a zero-size seed. One sitting inside a visible window256
+/// used to join its group and make every strategy fail, so the plan pinched.257
+#[test]258
+fn hidden_seeds_stay_out_of_the_plan() {259
+ let c = cfg(Style::Orthogonal);260
+ let a = cols(region(), 2);261
+ let seed = |r: Rect| Rect::new(r.center_x(), r.center_y(), 0.0, 0.0);262
+ let from = vec![a[0], a[1], seed(a[0])];263
+ let to = vec![a[1], a[0], seed(a[1])];264
+ let p = plan(&from, &to, &c);265
+ assert_clean(&p, &c);266
+ assert!(p.groups.iter().all(|g| !g.members.contains(&2)));267
+ assert!(p.keyframes.iter().all(|k| k[2] == to[2]));268
+}