Commit b2274115d1c6
tarball4 files changed+40-0
@@ -57,6 +57,8 @@ pub enum Command {
5757
axis: Axis,5858
delta: f64,5959
},60
+ /// Shares the focused window's block equally among its children.61
+ BalanceBlock,6062
Expand {6163
scope: ExpandScope,6264
},@@ -166,6 +168,7 @@ impl Command {
166168
"flip" => none(Command::Flip)?,167169
"maximize" => none(Command::Maximize)?,168170
"invert-move" => none(Command::InvertMove)?,171
+ "balance-block" => none(Command::BalanceBlock)?,169172
"float" => none(Command::Float)?,170173
"fullscreen" => none(Command::Fullscreen)?,171174
"sticky" => none(Command::Sticky)?,@@ -687,6 +687,16 @@ impl Layout {
687687
done688688
}689689
690
+ pub fn balance(&mut self) -> bool {691
+ let Some((w, o)) = self.focused_tiled() else {692
+ return false;693
+ };694
+ let mut tree = std::mem::take(&mut self.outputs[o].tree);695
+ let done = tree.balance(w, self.vis_on(o));696
+ self.outputs[o].tree = tree;697
+ done698
+ }699
+690700
/// Whether `w` is tiled with a visible window across the split on side `dir`.691701
pub fn has_split(&self, w: WindowId, dir: Dir) -> bool {692702
let Some(o) = self.windows.get(w).and_then(|w| w.output) else {@@ -483,6 +483,30 @@ impl<W: Copy + Eq + Hash> Tree<W> {
483483
false484484
}485485
486
+ /// Gives every visible child of the nearest container where `w` has a487
+ /// visible sibling an equal share along that container's axis.488
+ pub fn balance(&mut self, w: W, vis: impl Fn(W) -> bool) -> bool {489
+ let Some(&(p, _)) = self.shown_path(w, &vis).first() else {490
+ return false;491
+ };492
+ let Some(axis) = self.axis(p) else {493
+ return false;494
+ };495
+ let shown: Vec<(NodeId, f64)> = self496
+ .children(p)497
+ .iter()498
+ .filter(|&&c| self.visible(c, &vis))499
+ .map(|&c| (c, self.extent(c, axis, &vis)))500
+ .collect();501
+ let mean = shown.iter().map(|s| s.1).sum::<f64>() / shown.len() as f64;502
+ for (c, e) in shown {503
+ if e > 0.0 {504
+ self.scale(c, axis, mean / e);505
+ }506
+ }507
+ true508
+ }509
+486510
/// The lane a window's split on side `dir` lives in, as the child holding487511
/// the window, its parent and the index of the visible sibling across488512
/// the split.@@ -96,6 +96,9 @@ impl State {
9696
Command::Resize { axis, delta } => {9797
self.wm.layout.resize(axis, delta);9898
}99
+ Command::BalanceBlock => {100
+ self.wm.layout.balance();101
+ }99102
Command::Expand { scope } => {100103
self.wm.layout.expand(match scope {101104
monolith_ipc::ExpandScope::Window => ExpandScope::Window,