diff options
| author | srdusr <[email protected]> | 2024-06-20 16:08:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2024-06-20 16:08:00 +0200 |
| commit | ab0916391532031376817ed4ab6ab234428559a2 (patch) | |
| tree | 169e7799fbb6dd5d225b01ed645b1fa5cbf179de /crates/core/src/manager.rs | |
| parent | 20cdd47b39f09aa19317d9d29fef6511b98c1233 (diff) | |
| download | srdwm-ab0916391532031376817ed4ab6ab234428559a2.tar.gz srdwm-ab0916391532031376817ed4ab6ab234428559a2.zip | |
Add drop shadows and shrink the resize grab margin that was eating content clicks
Two independent daily-driving gaps closed in one pass, both from MISSING.md
and live user feedback:
Drop shadows (general.shadows, default true). Reuses the exact "bitmap
drawn outside geometry, cached like the border" technique border_strips/
render_border_top already established - decoration::shadow_bitmap rasterizes
a linear alpha falloff (Chebyshev/square-ring distance, not a true blur --
no blur primitive exists without a GPU shader, and the udev backend's
PixmanRenderer is software-only) from SHADOW_MAX_ALPHA (90/255, deliberately
subtle) at the window's own edge down to fully transparent SHADOW_SIZE (12px)
out. Cached in CompState::shadow_buffers, rebuilt at the same trigger points
as border_top_decorations (redraw_decoration_buffer), for the identical
damage-tracking reason: a fresh Id every frame means OutputDamageTracker
never finds a previous-frame match. No shadow for a maximized or fullscreen
window, matching the Hyprland/GNOME convention MISSING.md measures against.
Resize grab margin: 10px -> 6px (general.resize_margin, now configurable,
same call-site-count-preserving change as threading a new parameter through
one indirection point: ResizeEdge::hit_test's only production caller is
WindowManager::hit_test, so this didn't need touching every backend despite
hit_test being shared verbatim across X11/Wayland/Windows/macOS). Reported
live: ordinary clicks near any window edge - a link near a browser's edge,
a button near a panel's edge - regularly registered as a resize-edge grab
instead of reaching the client, not just an occasional near-miss, because
the 10px band was measured inward from the client's own content rect. 6px
stays comfortably grabbable while giving content back most of its edge.
Verified: cargo build --workspace (all 9 crates including the windows/macos
stub backends), cargo clippy --workspace (0 new warnings), cargo test across
core/wayland/config/x11 (188 tests, 0 failed). Shadow rendering verified at
the render-element level live in a nested session (correct geometry, alpha,
buffer contents) - grim/screencopy itself turned out to route through
winit.rs's separate capture_offscreen path, which only ever drew
`decorations` (titlebars), never borders or shadows, so screenshots taken
this way have never shown either; a real gap, not fixed in this pass.
Diffstat (limited to 'crates/core/src/manager.rs')
| -rw-r--r-- | crates/core/src/manager.rs | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/crates/core/src/manager.rs b/crates/core/src/manager.rs index 8696508..2c92ac1 100644 --- a/crates/core/src/manager.rs +++ b/crates/core/src/manager.rs @@ -4,7 +4,7 @@ use crate::monitor::{Monitor, MonitorId}; use crate::placement::{PlacementConfig, SmartPlacement, MIN_WINDOW_HEIGHT, MIN_WINDOW_WIDTH}; use crate::rules::WindowRule; use crate::theme::ThemeConfig; -use crate::window::{ResizeEdge, TitlebarHit, Window, WindowId}; +use crate::window::{ResizeEdge, TitlebarHit, Window, WindowId, RESIZE_MARGIN}; use crate::workspace::{Workspace, WorkspaceId}; use std::collections::HashMap; @@ -61,6 +61,15 @@ pub struct WindowManager { pub animations_enabled: bool, /// Tween duration in milliseconds, read from `general.animation_duration`. pub animation_duration_ms: u32, + /// Whether windows get a drop shadow. Read from `general.shadows`. A + /// maximized or fullscreen window never gets one regardless of this -- + /// see the Wayland backend's shadow render call site - so this only + /// ever turns it off entirely, not on for those. + pub shadows_enabled: bool, + /// Width, in pixels, of the resize grab band along a window's edges, + /// read from `general.resize_margin`. See [`crate::window::RESIZE_MARGIN`]'s + /// doc comment for the default and why it's what it is. + pub resize_margin: i32, /// Default decoration colours and border width, read from `theme.colors.*`/ /// `theme.decorations.*`. See `ThemeConfig`'s own doc comment. pub theme: ThemeConfig, @@ -103,6 +112,8 @@ impl WindowManager { placement: PlacementConfig::default(), animations_enabled: true, animation_duration_ms: 200, + shadows_enabled: true, + resize_margin: RESIZE_MARGIN, theme: ThemeConfig::default(), drag: None, resize: None, @@ -759,7 +770,7 @@ impl WindowManager { if w.minimized { continue; } - if let Some(hit) = ResizeEdge::hit_test(w.geometry, x, y, w.decorated, w.border_width) { + if let Some(hit) = ResizeEdge::hit_test(w.geometry, x, y, w.decorated, w.border_width, self.resize_margin) { return Some((w.id, hit)); } } |