srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/wayland
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2026-05-15 19:05:00 +0200
committersrdusr <[email protected]>2026-05-15 19:05:00 +0200
commit27daed83230eaefd0f41461cad20bbed7d1ad575 (patch)
treec725244151b2128748e6c6ab07ff0578c6da200c /crates/wayland
parent8174ced0d9d42343b18072c64491ccb06632a75f (diff)
downloadsrdwm-27daed83230eaefd0f41461cad20bbed7d1ad575.tar.gz
srdwm-27daed83230eaefd0f41461cad20bbed7d1ad575.zip
Fix the maximize border on the path that actually runs, and three spawn faults
The maximize border was still drawn because the earlier fix landed on the wrong branch. udev/render.rs has three border blocks: the SRDWM_GPU=1 path at the top and two Pixman ones below. The patch replaced the first match in the file, which is the GPU branch a real DRM session never runs. All four sites across both backends are now gated on !maximized. The verification had failed twice for a separate reason: winit/capture.rs did not draw border strips at all, so a screenshot could never answer "is there a border here" and the control passed for the wrong reason. Border strips are now drawn into that pass as solid fills - corner rounding is not reproduced, so a capture is not pixel-exact at the corners, but presence, position, thickness and colour are. With that closed the test has a real control: unmaximized gives 6 accent pixels at x=800..805, exactly the configured border_width, and maximized gives none at the right edge or along the top row. That proves the winit path; the Pixman path is the same change at two more sites and is not separately confirmed on screen. Windows spawning as squares, partly off-screen, and always on the left were all SmartPlacement::grid. It returned size.min(cell), shrinking every window to its grid cell whatever size it asked for; it scanned cells in reading order and took the first free one, which is the leftmost; and nothing clamped the result, so a window larger than its cell could hang off the edge with its border out of view. The cell now decides only where a window goes, the scan starts from a rotating cell, and both grid and cascade clamp into the usable area. Four tests, one per reported symptom. 525 tests pass, clippy clean.
Diffstat (limited to 'crates/wayland')
-rw-r--r--crates/wayland/src/state/mod.rs6
-rw-r--r--crates/wayland/src/udev/platform.rs1
-rw-r--r--crates/wayland/src/udev/render.rs11
-rw-r--r--crates/wayland/src/winit/capture.rs27
-rw-r--r--crates/wayland/src/winit/connect.rs1
5 files changed, 44 insertions, 2 deletions
diff --git a/crates/wayland/src/state/mod.rs b/crates/wayland/src/state/mod.rs
index fee7af3..5c1b02e 100644
--- a/crates/wayland/src/state/mod.rs
+++ b/crates/wayland/src/state/mod.rs
@@ -589,6 +589,12 @@ pub(crate) struct CompState {
/// one drag is in progress at a time. See
/// `elements::snap_preview_elements`.
pub(crate) snap_preview_buffers: Vec<SolidColorBuffer>,
+ /// Persistent solid-colour buffers for the border strips drawn into the
+ /// winit backend's screencopy pass - same stable-`Id` reasoning as
+ /// `border_side_buffers`. One shared pool rather than one per window:
+ /// a capture pass runs to completion in a single frame, so nothing
+ /// needs to persist per window between windows.
+ pub(crate) capture_border_buffers: Vec<SolidColorBuffer>,
/// Persistent solid-colour buffer backing the whole-output night-light/
/// reading-mode overlay, one per output name - same "reuse the buffer
/// so its `Id` stays stable across frames" reasoning as `border_side_
diff --git a/crates/wayland/src/udev/platform.rs b/crates/wayland/src/udev/platform.rs
index ea2260e..8dad7c3 100644
--- a/crates/wayland/src/udev/platform.rs
+++ b/crates/wayland/src/udev/platform.rs
@@ -268,6 +268,7 @@ impl UdevPlatform {
rounded_content_buffers: HashMap::new(),
border_side_buffers: HashMap::new(),
snap_preview_buffers: Vec::new(),
+ capture_border_buffers: Vec::new(),
color_filter_buffers: HashMap::new(),
last_synced_size: HashMap::new(),
provisional_size: HashSet::new(),
diff --git a/crates/wayland/src/udev/render.rs b/crates/wayland/src/udev/render.rs
index 3bd9a52..9992b2c 100644
--- a/crates/wayland/src/udev/render.rs
+++ b/crates/wayland/src/udev/render.rs
@@ -668,7 +668,14 @@ impl CompState {
// instead, since `custom_elements` composites earlier-
// pushed entries over later ones - exactly backwards
// from what this overlap needs.
- if w.border_width > 0 {
+ // No border on a maximized window - see the matching
+ // gate on the GPU path above. This is the Pixman path,
+ // the one a real DRM session actually runs: the earlier
+ // fix landed only on the GPU branch, so the border kept
+ // being drawn on real hardware and was reported again as
+ // "i still see the border or at least the top border
+ // when maximized".
+ if w.border_width > 0 && !w.maximized {
let strips = decoration::border_strips(frame, w.border_width);
// Strip 0 (top) rounded on its own two corners - see
// `render_border_top`'s own doc comment - so it's a
@@ -773,7 +780,7 @@ impl CompState {
// (unlike the bottom strip) *do* need cropping against
// this same top/bottom-strip overlap, a real bug this
// comment used to claim didn't exist here at all.
- if w.border_width > 0 {
+ if w.border_width > 0 && !w.maximized {
let color = crate::state::effective_border_color(w.border_color, focused == Some(id), self.wm.borrow().theme.border_inactive_dim);
let strips = decoration::border_strips(frame, w.border_width);
// Strip 1 (bottom), the top strip's own mirror --
diff --git a/crates/wayland/src/winit/capture.rs b/crates/wayland/src/winit/capture.rs
index 095b56b..3813559 100644
--- a/crates/wayland/src/winit/capture.rs
+++ b/crates/wayland/src/winit/capture.rs
@@ -96,6 +96,7 @@ impl WaylandPlatform {
// as both on-screen render loops do it.
let monitor_bounds: Vec<srdwm_core::Rect> = self.wm.borrow().monitors().iter().map(|m| m.full_geometry).collect();
let mut occluders: Vec<srdwm_core::Rect> = Vec::new();
+ let focused = self.wm.borrow().focused_id();
for id in self.wm.borrow().visible_windows_front_to_back().map(|w| w.id).collect::<Vec<_>>() {
let Some(w) = self.wm.borrow().window(id).cloned() else { continue };
if let Some(deco) = self.state.decorations.get(&id) {
@@ -158,6 +159,32 @@ impl WaylandPlatform {
}
}
}
+ // Border strips, as plain solid fills.
+ //
+ // The on-screen loop draws the top and bottom strips from
+ // cached bitmaps so their corners round into the titlebar's
+ // curve, and only the sides as fills. This pass approximates
+ // all four with fills: corner rounding is not reproduced, so a
+ // capture is not pixel-exact at the four corners. Everything
+ // that matters for checking a border - whether one is drawn at
+ // all, where, how thick, and in what colour - is faithful.
+ //
+ // Without this a screenshot could not answer "is there a border
+ // here", which is exactly the question a border bug asks. That
+ // gap was documented and then walked into twice: a maximize
+ // border fix was checked against a capture that never draws
+ // borders, and the control silently passed for the wrong
+ // reason both times.
+ if w.border_width > 0 && !w.maximized {
+ let color = crate::state::effective_border_color(w.border_color, focused == Some(id), self.wm.borrow().theme.border_inactive_dim);
+ let frame = self.state.effective_frame(id, w.geometry);
+ for (index, strip) in crate::decoration::border_strips(frame, w.border_width).into_iter().enumerate() {
+ for fragment in crate::elements::visible_border_fragments(strip, &occluders) {
+ let buf = crate::elements::border_fragment_buffer(&mut self.state.capture_border_buffers, index);
+ custom_elements.push(crate::elements::OverlayElement::Solid(crate::elements::border_side_render_element(buf, fragment, color, (0, 0))));
+ }
+ }
+ }
occluders.push(w.geometry);
}
custom_elements.extend(crate::elements::output_layer_elements(renderer, &self.output, |layer| matches!(layer, Layer::Background | Layer::Bottom)));
diff --git a/crates/wayland/src/winit/connect.rs b/crates/wayland/src/winit/connect.rs
index 1648826..aa59d9d 100644
--- a/crates/wayland/src/winit/connect.rs
+++ b/crates/wayland/src/winit/connect.rs
@@ -180,6 +180,7 @@ impl WaylandPlatform {
rounded_content_buffers: HashMap::new(),
border_side_buffers: HashMap::new(),
snap_preview_buffers: Vec::new(),
+ capture_border_buffers: Vec::new(),
color_filter_buffers: HashMap::new(),
last_synced_size: HashMap::new(),
provisional_size: HashSet::new(),