srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/x11/src/platform/mod.rs
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2025-11-10 09:31:00 +0200
committersrdusr <[email protected]>2025-11-10 09:31:00 +0200
commitf988203a7c22d945383efa9609f5c8a09a9506d2 (patch)
treea88281daee61cf148362e7b83132a86a5ae43444 /crates/x11/src/platform/mod.rs
parentea78f94027ecd2c690904a6d7729e9e3cc190a20 (diff)
downloadsrdwm-f988203a7c22d945383efa9609f5c8a09a9506d2.tar.gz
srdwm-f988203a7c22d945383efa9609f5c8a09a9506d2.zip
Fix a maximized X11 window overhanging the screen by its own border
Reported by the aegis-fc peer session testing srdwm's own layer-shell strut handling: a maximized X11 client sat 4-8px past the right and bottom screen edges whenever its border was nonzero. set_border_width sets the frame's native X11 border-width attribute, which the X server draws outside a window's own declared width/height on all four sides - unlike every other backend's own border in this compositor (rendered as ordinary pixels inside the allocated geometry rect). apply_geometry configured the frame at geometry's own x/y/width/ height verbatim, so a nonzero native border pushed the frame's true visible footprint 2*border_width past every edge of what geometry actually promised. Fixed by shifting the configured origin inward and the configured size down by border_width on both axes (frame_geometry_for, pulled out as a pure function so it's unit-tested without a real X11 connection) - the visible footprint, native border included, now lands exactly on geometry. border_width == 0 reduces to the prior behavior exactly.
Diffstat (limited to 'crates/x11/src/platform/mod.rs')
-rw-r--r--crates/x11/src/platform/mod.rs23
1 files changed, 23 insertions, 0 deletions
diff --git a/crates/x11/src/platform/mod.rs b/crates/x11/src/platform/mod.rs
index e22b3f7..0f097df 100644
--- a/crates/x11/src/platform/mod.rs
+++ b/crates/x11/src/platform/mod.rs
@@ -149,6 +149,29 @@ fn rgb_to_pixel((r, g, b): (u8, u8, u8)) -> u32 {
((r as u32) << 16) | ((g as u32) << 8) | (b as u32)
}
+/// The actual arithmetic behind `Platform::apply_geometry`'s frame
+/// placement - pulled out so it's testable without a real X11
+/// connection, the same reasoning `modmask_for_keycode_in_mod_slots`
+/// above already gets.
+///
+/// X11's native `border_width` window attribute is drawn OUTSIDE a
+/// window's own declared width/height, on all four sides, by the X
+/// server itself - unlike every other backend's own border (rendered as
+/// ordinary pixels *inside* the allocated geometry rect, Wayland's
+/// `decoration.rs`, concretely). `geometry` is the true, already-decided
+/// on-screen rect (`Window::maximize_geometry`'s own doc comment); this
+/// shifts the *configured* origin inward and the *configured* size down
+/// by `border_width` on both axes so the window's real, visible footprint
+/// (native border included) still lands exactly on `geometry`, instead of
+/// spilling `border_width` pixels past every edge of it. Returns
+/// `(frame_x, frame_y, frame_width, frame_height)` - the caller applies
+/// `band` (the titlebar reservation) on top of `frame_height` separately,
+/// same as before this existed.
+fn frame_geometry_for(geometry: Rect, border_width: u32) -> (i32, i32, u32, u32) {
+ let bw = border_width as i32;
+ (geometry.x + bw, geometry.y + bw, geometry.width.saturating_sub(2 * border_width), geometry.height.saturating_sub(2 * border_width))
+}
+
pub struct X11Platform {
conn: RustConnection,
root: XWindow,