srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/wayland/src/state/lifecycle.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/wayland/src/state/lifecycle.rs')
-rw-r--r--crates/wayland/src/state/lifecycle.rs49
1 files changed, 38 insertions, 11 deletions
diff --git a/crates/wayland/src/state/lifecycle.rs b/crates/wayland/src/state/lifecycle.rs
index 112c64e..51297bb 100644
--- a/crates/wayland/src/state/lifecycle.rs
+++ b/crates/wayland/src/state/lifecycle.rs
@@ -145,6 +145,17 @@ impl CompState {
// nothing this function reads has actually changed since the last
// call turns those redundant calls into a cheap signature
// comparison instead of a full re-rasterization.
+ // Whether this window is *actually* occupying a tiled slot right
+ // now - see the shadow gate further down for the full reasoning.
+ // Computed once, here, and reused there rather than recomputed:
+ // it depends on the workspace's own layout name, not just this
+ // window's own `floating` flag, so it has to be part of the
+ // signature too - switching a workspace's layout (`Super+Shift+
+ // t`/`s`) changes this for every window on it without touching
+ // any of their own `floating` fields, and a signature that didn't
+ // track it would keep serving whichever shadow state was cached
+ // before the switch.
+ let currently_tiled = self.wm.borrow().workspace(w.workspace).is_some_and(|ws| ws.layout == "tiling") && !w.floating;
let signature = DecorationSignature {
width: frame.width,
height: frame.height,
@@ -157,7 +168,7 @@ impl CompState {
maximized: w.maximized,
fullscreen: w.fullscreen,
shadows_enabled: self.wm.borrow().shadows_enabled,
- floating: w.floating,
+ currently_tiled,
hovered_button,
title_centered: theme.title_centered,
buttons_left: theme.buttons_left,
@@ -252,20 +263,36 @@ impl CompState {
// 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
+ // No shadow for a window that is *actually being tiled right now*
+ // - 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 a tiled window is coplanar and
+ // adjacent to its neighbours by construction, with nothing behind
+ // it 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.
+ // are dark tinted."
+ //
+ // Gating this on `w.floating` alone (the first version of this
+ // fix) was a real regression, caught live: `arrange_workspace`
+ // only reads `floating` under the `"tiling"` layout, so every
+ // window on this project's own default `"dynamic"` layout starts
+ // - and stays - `floating: false` unless something explicitly
+ // flips it. That first version read `floating: false` as "this
+ // window is tiled, no shadow" regardless of which layout was
+ // actually running, so *every* window under dynamic/floating mode
+ // silently lost its shadow, recoverable only by toggling `Super+S`
+ // (`srd.window.toggle_floating()`) - which then looked like that
+ // key toggles a "tint", not floating, since floating itself does
+ // nothing visible under a layout that never tiles anyone. `Window::
+ // floating` only ever means "opted out of tiling" *within* a
+ // workspace that tiles at all - checking the workspace's own
+ // layout name first is what this needed instead: a window is only
+ // "currently tiled" when both are true. `currently_tiled` itself
+ // was already computed above, alongside the signature.
let shadows_enabled = self.wm.borrow().shadows_enabled;
- if shadows_enabled && w.floating && !w.maximized && !w.fullscreen {
+ if shadows_enabled && !currently_tiled && !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