Commit e8128033f056
tarball2 files changed+24-4
@@ -394,10 +394,14 @@ impl State {
394394
}395395
396396
let mut mapped = Vec::new();397
- for (id, rect, kind, _) in shown {397
+ for (id, rect, kind, o) in shown {398398
let free = kind == Kind::Floating && self.wm.get(id).is_some_and(|s| s.natural_size);399
+ let scale = self400
+ .backend401
+ .output(o)402
+ .map_or(1.0, |o| o.current_scale().fractional_scale());399403
if let Some(window) = self.wm.window(id).cloned()400
- && (free || configure(&window, rect, kind, self.wm.layout.maximized(id)))404
+ && (free || configure(&window, rect, kind, self.wm.layout.maximized(id), scale))401405
{402406
let loc = (rect.x.round() as i32, rect.y.round() as i32);403407
self.wm.space.map_element(window, loc, false);@@ -222,7 +222,7 @@ pub enum Kind {
222222
223223
/// Sets a window's pending size and states. Returns false for windows224224
/// squeezed to a line by an expanded sibling, which are not shown.225
-pub fn configure(window: &Window, rect: Rect, kind: Kind, maximized: bool) -> bool {225
+pub fn configure(window: &Window, rect: Rect, kind: Kind, maximized: bool, scale: f64) -> bool {226226
let (x, y) = (rect.x.round(), rect.y.round());227227
let w = (rect.right().round() - x) as i32;228228
let h = (rect.bottom().round() - y) as i32;@@ -240,8 +240,12 @@ pub fn configure(window: &Window, rect: Rect, kind: Kind, maximized: bool) -> bo
240240
);241241
}242242
if let Some(t) = window.toplevel() {243
+ let size = (244
+ logical_extent(rect.x, rect.right(), scale),245
+ logical_extent(rect.y, rect.bottom(), scale),246
+ );243247
t.with_pending_state(|s| {244
- s.size = Some((w, h).into());248
+ s.size = Some(size.into());245249
set_states(s, kind, maximized);246250
});247251
if t.is_initial_configure_sent() {@@ -251,6 +255,18 @@ pub fn configure(window: &Window, rect: Rect, kind: Kind, maximized: bool) -> bo
251255
true252256
}253257
258
+/// The logical length to ask a client for between `start` and `end`. Its259
+/// buffer is round(length * scale) pixels, so a length that rounds to the260
+/// span's physical pixels keeps the window from being cropped or stretched.261
+fn logical_extent(start: f64, end: f64, scale: f64) -> i32 {262
+ let physical = (end * scale).round() - (start * scale).round();263
+ let guess = (physical / scale).round() as i32;264
+ [guess, guess - 1, guess + 1]265
+ .into_iter()266
+ .find(|&c| c >= 1 && (f64::from(c) * scale).round() == physical)267
+ .unwrap_or((end.round() - start.round()) as i32)268
+}269
+254270
/// Lets a floating toplevel pick its own size, returning the serial of the255271
/// configure that says so. None if it was sent nothing.256272
pub fn configure_free(t: &ToplevelSurface) -> Option<Serial> {