atagen

monolith

public
Star0
Watch0

Commit 1db12095f6d7

tarball

atagen <boss@atagen.co>2026-10-19 07:51 UTC

2 files changed+23-10
windows: keep natural size until a buffer exists

The 300 ms first-buffer timeout ran the whole first_buffer path, whose mem::take on WindowState::natural_size discarded the flag while no buffer had shown the client's size. A dialog slower than that stayed at the default float rect forever. The timeout now only releases the spawn hold.
Modified file: crates/monolith/src/windows.rs+19 additions−8 deletions
@@ -85,14 +85,14 @@ impl State {
8585 fn await_first_buffer(&mut self, id: WindowId) {
8686 let timeout = Timer::from_duration(Duration::from_millis(300));
8787 let _ = self.core.handle.insert_source(timeout, move |_, _, state| {
88- state.first_buffer(id);
88+ state.release_hold(id);
8989 TimeoutAction::Drop
9090 });
9191 }
9292
9393 /// Called on commits, starts the spawn of a window that now has a buffer.
9494 pub fn on_buffer(&mut self, surface: &WlSurface) {
95- if !self.wm.any_awaiting() {
95+ if !self.wm.any_settling() {
9696 return;
9797 }
9898 let has_buffer =
@@ -106,20 +106,31 @@ impl State {
106106 let Some(w) = self.wm.get_mut(id) else {
107107 return;
108108 };
109- w.placed_by_rule = false;
110- if std::mem::take(&mut w.natural_size) {
109+ let natural = std::mem::take(&mut w.natural_size);
110+ if natural {
111111 let size = w.window.geometry().size;
112112 if size.w > 0 && size.h > 0 {
113113 self.float_at_natural_size(id, f64::from(size.w), f64::from(size.h));
114114 }
115115 }
116+ if !self.release_hold(id) && natural {
117+ self.apply_layout();
118+ }
119+ }
120+
121+ /// Ends a window's hold on its seed, returning whether that ran the
122+ /// layout.
123+ fn release_hold(&mut self, id: WindowId) -> bool {
116124 let Some(w) = self.wm.get_mut(id) else {
117- return;
125+ return false;
118126 };
119- if std::mem::take(&mut w.awaiting_buffer) {
120- self.wm.anim.spawned(id, now_ns());
121- self.apply_layout();
127+ w.placed_by_rule = false;
128+ if !std::mem::take(&mut w.awaiting_buffer) {
129+ return false;
122130 }
131+ self.wm.anim.spawned(id, now_ns());
132+ self.apply_layout();
133+ true
123134 }
124135
125136 /// Centres a window over its parent, or else its output.
Modified file: crates/monolith/src/wm.rs+4 additions−2 deletions
@@ -191,8 +191,10 @@ impl Wm {
191191 .retain(|id, _| ghosts.iter().any(|g| g.id == *id));
192192 }
193193
194- pub fn any_awaiting(&self) -> bool {
195- self.windows.values().any(|w| w.awaiting_buffer)
194+ pub fn any_settling(&self) -> bool {
195+ self.windows
196+ .values()
197+ .any(|w| w.awaiting_buffer || w.natural_size)
196198 }
197199 }