diff options
| author | srdusr <[email protected]> | 2025-12-03 22:52:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2025-12-03 22:52:00 +0200 |
| commit | 393f886eb9e275c3b7a9e3ef396092ba71297dfb (patch) | |
| tree | e84786279ff2216b1fa54c9fdad6ad57d8f73118 /crates | |
| parent | 96aff79ae2df2ade1a29a68c1a8108d258596bc3 (diff) | |
| download | srdwm-393f886eb9e275c3b7a9e3ef396092ba71297dfb.tar.gz srdwm-393f886eb9e275c3b7a9e3ef396092ba71297dfb.zip | |
Stop giving tiled windows a shadow that lands on their neighbour
Diagnosed by a peer session (dotfiles-1a): SHADOW_SIZE is 24px, and a
tiling layout with a small gap_inner (as little as 1px live) leaves the
shadow nowhere to fall except onto the adjacent tile, darkening it by up
to SHADOW_MAX_ALPHA (~35%) on whichever side is unfocused. Not a content
tint or an opacity rule - verified against the actual rasteriser and the
live rule set before accepting the diagnosis.
A drop shadow separates a window from what's behind it; tiled windows are
coplanar and adjacent by construction, with nothing behind them to
separate from. redraw_decoration_buffer's shadow gate now requires
w.floating in addition to the existing !maximized/!fullscreen checks.
DecorationSignature gained a floating field so toggling floating on its
own invalidates the decoration cache instead of waiting for an unrelated
field to force a rebuild.
Live-verified in a nested compositor: two tiled windows show a clean
shared edge with no gradient bleeding across; floating a window still
detaches it from the tile group with its shadow intact; shadows still
toggle globally both ways.
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/wayland/src/state/lifecycle.rs | 16 | ||||
| -rw-r--r-- | crates/wayland/src/state/mod.rs | 9 |
2 files changed, 24 insertions, 1 deletions
diff --git a/crates/wayland/src/state/lifecycle.rs b/crates/wayland/src/state/lifecycle.rs index 1afa738..112c64e 100644 --- a/crates/wayland/src/state/lifecycle.rs +++ b/crates/wayland/src/state/lifecycle.rs @@ -157,6 +157,7 @@ impl CompState { maximized: w.maximized, fullscreen: w.fullscreen, shadows_enabled: self.wm.borrow().shadows_enabled, + floating: w.floating, hovered_button, title_centered: theme.title_centered, buttons_left: theme.buttons_left, @@ -250,8 +251,21 @@ impl CompState { // as a shadow the window doesn't visually need. Matches the // Hyprland/GNOME convention `MISSING.md` measures this compositor // against. + // + // No shadow for a TILED window either - a real, reported bug, not + // a style choice made up front: a drop shadow exists to separate a + // window from whatever is visually *behind* it, but tiled windows + // are coplanar and adjacent by construction, with nothing behind + // them to separate from. `SHADOW_SIZE` pixels of shadow with only + // `gap_inner` pixels of real gap to fall into (as little as 1px) + // has nowhere to land except on the neighbouring tile, darkening + // it by up to `SHADOW_MAX_ALPHA` - reported live as "some windows + // are dark tinted." Floating windows keep their shadow: they + // genuinely do sit above other windows, which is exactly where a + // shadow does its job, and it's also the one case `visible_border_ + // fragments`' own occluder clipping already handles correctly. let shadows_enabled = self.wm.borrow().shadows_enabled; - if shadows_enabled && !w.maximized && !w.fullscreen { + if shadows_enabled && w.floating && !w.maximized && !w.fullscreen { // A decorated window's corners are *always* rounded (the // titlebar/border strips round to `corner_radius` regardless of // this setting - see their own call sites); an undecorated diff --git a/crates/wayland/src/state/mod.rs b/crates/wayland/src/state/mod.rs index f39edcc..e07dc1d 100644 --- a/crates/wayland/src/state/mod.rs +++ b/crates/wayland/src/state/mod.rs @@ -114,6 +114,15 @@ pub(crate) struct DecorationSignature { pub(crate) maximized: bool, pub(crate) fullscreen: bool, pub(crate) shadows_enabled: bool, + /// A tiled window gets no shadow at all (see `redraw_decoration_ + /// buffer`'s own gate) - included here for the same "one signature, + /// every real input" reason as `maximized`/`fullscreen` just above: + /// toggling floating on its own (`srd.window.toggle_floating()`, + /// switching layouts) changes nothing else this signature already + /// tracks, so without this the cache would keep serving whichever + /// shadow state happened to be cached until some unrelated field + /// (a resize, a focus change) forced a rebuild anyway. + pub(crate) floating: bool, /// Which of *this* window's own titlebar buttons (if any) is currently /// hovered, and the glyph-reveal animation's current progress (0..=255) /// - see `CompState::hovered_titlebar_button`'s own doc comment. |