Commit 54559daf11c3
tarball3 files changed+57-22
@@ -524,7 +524,7 @@ impl Layout {
524524
let Some(o) = self.windows.get(w).and_then(|w| w.output) else {525525
return false;526526
};527
- self.outputs[o].tree.maximized(w)527
+ self.outputs[o].tree.maximized(w, self.vis_on(o))528528
}529529
530530
pub fn resize(&mut self, axis: Axis, delta: f64) -> bool {@@ -546,7 +546,10 @@ impl Layout {
546546
ExpandScope::Container => (1, 1),547547
ExpandScope::All => (0, usize::MAX),548548
};549
- self.outputs[o].tree.toggle_expand(w, skip, count)549
+ let mut tree = std::mem::take(&mut self.outputs[o].tree);550
+ let expanded = tree.toggle_expand(w, skip, count, self.vis_on(o));551
+ self.outputs[o].tree = tree;552
+ expanded550553
}551554
552555
pub fn flip(&mut self, o: OutputId) {@@ -294,3 +294,21 @@ fn merging_steps_out_of_a_stack_before_joining_another() {
294294
assert_eq!(rect(a).w, AREA.w);295295
assert!(rect(a).bottom() <= rect(b).y && rect(b).y == rect(c).y);296296
}297
+298
+/// A window alone on screen in a container of hidden ones expands among the299
+/// windows it is shown beside, not inside the container nobody can see.300
+#[test]301
+fn expand_skips_containers_of_hidden_windows() {302
+ let (a, b, c) = (1, 2, 3);303
+ let mut t: Tree<u32> = Tree::default();304
+ t.insert_row(a);305
+ t.insert_after(b, a);306
+ t.insert_after(c, b);307
+ assert!(t.merge_window(a, Dir::Right, |_| true));308
+ let shown = |w: u32| w != a;309
+ assert!(t.toggle_expand(b, 0, 1, shown));310
+ assert!(t.maximized(b, shown));311
+ let all = t.arrange(AREA, 0.0, shown);312
+ let rect = |w| all.iter().find(|p| p.0 == w).unwrap().1;313
+ assert_eq!(rect(b).w, AREA.w);314
+}@@ -217,20 +217,31 @@ impl<W: Copy + Eq + Hash> Tree<W> {
217217
}218218
219219
/// Whether every container above `w` is expanded towards it.220
- pub fn maximized(&self, w: W) -> bool {220
+ pub fn maximized(&self, w: W, vis: impl Fn(W) -> bool) -> bool {221
+ let path = self.shown_path(w, &vis);222
+ !path.is_empty() && path.iter().all(|&(p, c)| self.expanded(p) == Some(c))223
+ }224
+225
+ /// `w`'s ancestry as (container, child) pairs, leaving out containers226
+ /// where the child has no visible sibling. Those look like nothing on227
+ /// screen, so expanding there would do nothing the user could see.228
+ fn shown_path(&self, w: W, vis: &impl Fn(W) -> bool) -> Vec<(NodeId, NodeId)> {221229
let Some(&leaf) = self.leaves.get(&w) else {222
- return false;230
+ return Vec::new();223231
};232
+ let mut path = Vec::new();224233
let mut cur = leaf;225
- let mut any = false;226234
while let Some(p) = self.nodes[cur].parent {227
- if self.expanded(p) != Some(cur) {228
- return false;235
+ let shared = self236
+ .children(p)237
+ .iter()238
+ .any(|c| c.node != cur && self.visible(c.node, vis));239
+ if shared {240
+ path.push((p, cur));229241
}230
- any = true;231242
cur = p;232243
}233
- any244
+ path234245
}235246
236247
/// Transposes the whole tree.@@ -243,19 +254,22 @@ impl<W: Copy + Eq + Hash> Tree<W> {
243254
}244255
}245256
246
- /// Toggles expansion for `count` levels of `w`'s ancestry, starting247
- /// `skip` levels up. Level 0 expands the window inside its container.248
- pub fn toggle_expand(&mut self, w: W, skip: usize, count: usize) -> bool {249
- let Some(&leaf) = self.leaves.get(&w) else {250
- return false;251
- };252
- let mut path = Vec::new();253
- let mut cur = leaf;254
- while let Some(p) = self.nodes[cur].parent {255
- path.push((p, cur));256
- cur = p;257
- }258
- let path: Vec<_> = path.into_iter().skip(skip).take(count).collect();257
+ /// Toggles expansion for `count` levels of `w`'s visible ancestry,258
+ /// starting `skip` levels up. Level 0 expands the window inside the259
+ /// nearest container where it has a visible sibling.260
+ pub fn toggle_expand(261
+ &mut self,262
+ w: W,263
+ skip: usize,264
+ count: usize,265
+ vis: impl Fn(W) -> bool,266
+ ) -> bool {267
+ let path: Vec<_> = self268
+ .shown_path(w, &vis)269
+ .into_iter()270
+ .skip(skip)271
+ .take(count)272
+ .collect();259273
if path.is_empty() {260274
return false;261275
}