Commit 5920d2cc09bc
tarball2 files changed+37-7
@@ -68,9 +68,11 @@ impl State {
6868
self.view_if_first(id);6969
let by_rule = rule.tag.is_some() || rule.output.is_some();7070
let natural_size = floating && window.toplevel().is_some();71
+ let reclassify = !floating && rule.floating.is_none() && window.toplevel().is_some();7172
self.wm.insert(id, window, by_rule, app_id, title);7273
if let Some(s) = self.wm.get_mut(id) {7374
s.natural_size = natural_size;75
+ s.reclassify = reclassify;7476
}7577
self.await_first_buffer(id);7678
if self.wm.layout.visible(id) {@@ -107,17 +109,41 @@ impl State {
107109
return;108110
};109111
let natural = std::mem::take(&mut w.natural_size);110
- if natural {111
- let size = w.window.geometry().size;112
- if size.w > 0 && size.h > 0 {113
- self.float_at_natural_size(id, f64::from(size.w), f64::from(size.h));114
- }112
+ let reclassify = std::mem::take(&mut w.reclassify);113
+ let size = w.window.geometry().size;114
+ let sized = natural || (reclassify && self.float_if_hinted(id));115
+ if sized && size.w > 0 && size.h > 0 {116
+ self.float_at_natural_size(id, f64::from(size.w), f64::from(size.h));115117
}116
- if !self.release_hold(id) && natural {118
+ if !self.release_hold(id) && sized {117119
self.apply_layout();118120
}119121
}120122
123
+ /// Floats a tiled window whose size hints, which GTK only sets after its124
+ /// first configure, show it to be a dialog or fixed-size. It is still held125
+ /// on its seed, so it never shows tiled.126
+ fn float_if_hinted(&mut self, id: WindowId) -> bool {127
+ let hinted = self128
+ .wm129
+ .window(id)130
+ .and_then(|w| w.toplevel())131
+ .is_some_and(crate::xdg::floats);132
+ let tiled = self133
+ .wm134
+ .layout135
+ .window(id)136
+ .is_some_and(|w| !w.floating && !w.fullscreen && w.scratchpad.is_none());137
+ if !hinted || !tiled {138
+ return false;139
+ }140
+ self.wm.layout.toggle_floating(id);141
+ if let Some(w) = self.wm.get_mut(id) {142
+ w.placed = None;143
+ }144
+ true145
+ }146
+121147
/// Ends a window's hold on its seed, returning whether that ran the122148
/// layout.123149
fn release_hold(&mut self, id: WindowId) -> bool {@@ -58,6 +58,9 @@ pub struct WindowState {
5858
/// Configured without a size until its first buffer shows the one it5959
/// picked.6060
pub natural_size: bool,61
+ /// Tiled by default, but its size hints are only reliable at its first62
+ /// buffer and may turn it into a float.63
+ pub reclassify: bool,6164
/// A rule sent it somewhere, so activation tokens leave it alone.6265
pub placed_by_rule: bool,6366
pub list_handle: Option<ForeignToplevelHandle>,@@ -114,6 +117,7 @@ impl Wm {
114117
placed: None,115118
awaiting_buffer: true,116119
natural_size: false,120
+ reclassify: false,117121
placed_by_rule,118122
list_handle: None,119123
borders: None,@@ -194,7 +198,7 @@ impl Wm {
194198
pub fn any_settling(&self) -> bool {195199
self.windows196200
.values()197
- .any(|w| w.awaiting_buffer || w.natural_size)201
+ .any(|w| w.awaiting_buffer || w.natural_size || w.reclassify)198202
}199203
}