Commit 9e8937bb4297
tarball2 files changed+37-12
@@ -94,18 +94,38 @@ impl State {
9494
});9595
}9696
97
- /// Called on commits, starts the spawn of a window that now has a buffer.97
+ /// Called on commits, starts the spawn of a window that now has a buffer98
+ /// and unmaps one that lost it.9899
pub fn on_buffer(&mut self, surface: &WlSurface) {99
- if !self.wm.any_settling() {100
+ let Some(id) = self.window_id(surface) else {100101
return;101
- }102
+ };102103
let has_buffer =103104
with_renderer_surface_state(surface, |s| s.buffer_size().is_some()).unwrap_or(false);104
- if has_buffer && let Some(id) = self.window_id(surface) {105
+ let Some(w) = self.wm.get_mut(id) else {106
+ return;107
+ };108
+ if !has_buffer {109
+ if std::mem::take(&mut w.drawn) && w.window.toplevel().is_some() {110
+ self.hide_window(id);111
+ }112
+ return;113
+ }114
+ w.drawn = true;115
+ if w.settling() {105116
self.first_buffer(id);106117
}107118
}108119
120
+ /// Takes a toplevel that dropped its buffer, as clients do to hide to a121
+ /// tray, out of the layout. Smithay has reset its role, so its next commit122
+ /// maps it afresh with a new initial configure.123
+ fn hide_window(&mut self, id: WindowId) {124
+ if let Some(window) = self.remove_window(id) {125
+ self.wm.unmapped.push(window);126
+ }127
+ }128
+109129
fn first_buffer(&mut self, id: WindowId) {110130
let Some(w) = self.wm.get_mut(id) else {111131
return;@@ -265,13 +285,15 @@ impl State {
265285
}266286
}267287
268
- pub fn remove_window(&mut self, id: WindowId) {269
- if let Some(state) = self.wm.remove(id) {288
+ pub fn remove_window(&mut self, id: WindowId) -> Option<Window> {289
+ let state = self.wm.remove(id);290
+ if let Some(state) = &state {270291
self.wm.space.unmap_elem(&state.window);271292
self.leave_ghost(id, &state.window);272293
}273294
self.wm.layout.remove_window(id);274295
self.apply_layout();296
+ state.map(|s| s.window)275297
}276298
277299
/// Keeps a visible tiled window's last frame shrinking to its seed while@@ -55,6 +55,8 @@ pub struct WindowState {
5555
pub placed: Option<(Kind, Rect, OutputId)>,5656
/// Held on its seed until its first buffer lands.5757
pub awaiting_buffer: bool,58
+ /// Has shown a buffer, so one committed without is an unmap.59
+ pub drawn: bool,5860
/// Configured without a size until its first buffer shows the one it5961
/// picked.6062
pub natural_size: bool,@@ -72,6 +74,12 @@ pub struct WindowState {
7274
pub title: String,7375
}7476
77
+impl WindowState {78
+ pub fn settling(&self) -> bool {79
+ self.awaiting_buffer || self.natural_size || self.reclassify80
+ }81
+}82
+7583
/// The id clients see for a window, stable for its lifetime.7684
pub fn key(id: WindowId) -> u64 {7785
slotmap::Key::data(&id).as_ffi()@@ -119,6 +127,7 @@ impl Wm {
119127
window,120128
placed: None,121129
awaiting_buffer: true,130
+ drawn: false,122131
natural_size: false,123132
natural_after: None,124133
reclassify: false,@@ -198,12 +207,6 @@ impl Wm {
198207
self.last_frames199208
.retain(|id, _| ghosts.iter().any(|g| g.id == *id));200209
}201
-202
- pub fn any_settling(&self) -> bool {203
- self.windows204
- .values()205
- .any(|w| w.awaiting_buffer || w.natural_size || w.reclassify)206
- }207210
}208211
209212
#[derive(Clone, Copy, Debug, PartialEq, Eq)]