srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/wayland/src/winit
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/src/winit
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/src/winit')
-rw-r--r--crates/wayland/src/winit/capture.rs27
-rw-r--r--crates/wayland/src/winit/connect.rs1
2 files changed, 28 insertions, 0 deletions
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(),