server: adjust minimum and maximum window sizes to account for decorations

Fixes #271
This commit is contained in:
Shawn Wallace 2025-11-27 11:08:40 -05:00
parent ae98f974e0
commit 83e4aab4d5
4 changed files with 31 additions and 6 deletions

View file

@ -145,7 +145,6 @@ impl DecorationsDataSatellite {
pub fn draw_decorations(&mut self, world: &World, width: i32, parent_scale_factor: f32) {
if !self.will_draw_decorations(width) {
println!("not drawing ({} {})", width, self.should_draw);
if self.remove_buffer {
self.surface.attach(None, 0, 0);
self.surface.commit();

View file

@ -499,16 +499,26 @@ pub(super) fn update_surface_viewport(
return;
};
let decorations_height = if data.decoration.satellite.is_some() {
DecorationsDataSatellite::TITLEBAR_HEIGHT
} else {
0
};
if let Some(min) = hints.min_size {
debug!(
"updated min height: {}",
(min.height as f64 / scale_factor.0) as i32 + decorations_height
);
data.toplevel.set_min_size(
(min.width as f64 / scale_factor.0) as i32,
(min.height as f64 / scale_factor.0) as i32,
(min.height as f64 / scale_factor.0) as i32 + decorations_height,
);
}
if let Some(max) = hints.max_size {
data.toplevel.set_max_size(
(max.width as f64 / scale_factor.0) as i32,
(max.height as f64 / scale_factor.0) as i32,
(max.height as f64 / scale_factor.0) as i32 + decorations_height,
);
}
}

View file

@ -854,20 +854,25 @@ impl<S: X11Selection + 'static> InnerServerState<S> {
let mut win = data.get::<&mut WindowData>().unwrap();
if win.attrs.size_hints.is_none() || *win.attrs.size_hints.as_ref().unwrap() != hints {
if win.attrs.size_hints.is_none_or(|h| h != hints) {
debug!("setting {window:?} hints {hints:?}");
let mut query = data.query::<(&SurfaceRole, &SurfaceScaleFactor)>();
if let Some((SurfaceRole::Toplevel(Some(data)), scale_factor)) = query.get() {
let decorations_height = if data.decoration.satellite.is_some() {
DecorationsDataSatellite::TITLEBAR_HEIGHT
} else {
0
};
if let Some(min_size) = &hints.min_size {
data.toplevel.set_min_size(
(min_size.width as f64 / scale_factor.0) as i32,
(min_size.height as f64 / scale_factor.0) as i32,
(min_size.height as f64 / scale_factor.0) as i32 + decorations_height,
);
}
if let Some(max_size) = &hints.max_size {
data.toplevel.set_max_size(
(max_size.width as f64 / scale_factor.0) as i32,
(max_size.height as f64 / scale_factor.0) as i32,
(max_size.height as f64 / scale_factor.0) as i32 + decorations_height,
);
}
}

View file

@ -2288,6 +2288,17 @@ fn toplevel_size_limits_scaled() {
let toplevel = data.toplevel();
assert_eq!(toplevel.min_size, Some(testwl::Vec2 { x: 20, y: 20 }));
assert_eq!(toplevel.max_size, Some(testwl::Vec2 { x: 100, y: 100 }));
// test sizing with decorations
f.testwl
.force_decoration_mode(id, zxdg_toplevel_decoration_v1::Mode::ClientSide);
f.testwl.configure_toplevel(id, 100, 100, vec![]);
f.run();
let data = f.testwl.get_surface_data(id).unwrap();
let toplevel = data.toplevel();
assert_eq!(toplevel.min_size, Some(testwl::Vec2 { x: 20, y: 45 }));
assert_eq!(toplevel.max_size, Some(testwl::Vec2 { x: 100, y: 125 }));
}
#[test]