Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
fix: every normal window casts the DE shadow, not just cce/ssd ones
The remaining "shadows aren't appearing properly" on claude-desktop:
after the ghost bugs were fixed there was simply NO shadow left — the
compositor gated want_shadow on ssd || cce-*, and claude (frameless
Electron) reserves CSD shadow margins in its buffer but leaves them
fully transparent, so it sat flat and hard-edged next to shadowed cce
siblings. want_shadow now keys on !status && !fullscreen only, giving
non-cce clients (claude, keepassxc, foot) the same scenefx drop shadow.
Verified in the nested harness: foot casts a soft down-right shadow
over the grid gaps.
Co-Authored-By: Claude Fable 5 <[email protected]>
src/server/window.rs | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/src/server/window.rs b/src/server/window.rs
index 582bcdb..d81dcda 100644
--- a/src/server/window.rs
+++ b/src/server/window.rs
@@ -1949,7 +1949,11 @@ impl Window {
// (cf. the window_background rect, which scales it the same way).
(radius as f64 * self.scale) as i32,
);
- let want_shadow = !is_status && (self.wm_requested.ssd || is_cce_app) && !self.is_fullscreen();
+ // Every normal window casts the DE shadow. CSD apps don't draw
+ // their own here (frameless Electron reserves shadow margins but
+ // leaves them transparent), so without this, non-cce windows sat
+ // flat and shadowless next to shadowed cce siblings.
+ let want_shadow = !is_status && !self.is_fullscreen();
self.update_shadow(width, height, radius, want_shadow);
ffi::river_scene_node_set_opacity(self.tree as *mut ffi::wlr_scene_node, requested.opacity);
@@ -2326,7 +2330,11 @@ impl Window {
height,
(radius as f64 * self.scale) as i32,
);
- let want_shadow = !is_status && (self.wm_requested.ssd || is_cce_app) && !self.is_fullscreen();
+ // Every normal window casts the DE shadow. CSD apps don't draw
+ // their own here (frameless Electron reserves shadow margins but
+ // leaves them transparent), so without this, non-cce windows sat
+ // flat and shadowless next to shadowed cce siblings.
+ let want_shadow = !is_status && !self.is_fullscreen();
self.update_shadow(width, height, radius, want_shadow);
} else {
// Tearing the blur down: radius is irrelevant, the nodes are destroyed.