srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/TODO.md10
1 files changed, 10 insertions, 0 deletions
diff --git a/docs/TODO.md b/docs/TODO.md
index c212993..2cace23 100644
--- a/docs/TODO.md
+++ b/docs/TODO.md
@@ -1,5 +1,15 @@
# TODO / planned features - master checklist
+## Root cause found and fixed: tiled windows tinted dark along a shared edge (2026-08-28)
+
+Reported live as "some windows are dark tinted" (via a peer session, `dotfiles-1a`, who diagnosed the actual cause and handed over a concrete fix rather than a symptom). Root cause verified by reading the rasteriser before touching anything: `shadow_bitmap` never tints a window's own interior, and no rule sets `opacity` on the affected windows - the tint was never a content property. It was a shadow-versus-gap-size mismatch. `SHADOW_SIZE` is 24px; `gap_inner` on this session's live config is 1px. `redraw_decoration_buffer`'s shadow gate (`crates/wayland/src/state/lifecycle.rs`) only excluded a maximized or fullscreen window, so every *tiled* window got the same 24px shadow too - with only 1px of real gap for it to fall into, it landed almost entirely on the neighbouring tile instead, darkening it by up to `SHADOW_MAX_ALPHA` (~35%). The focused window is raised above its neighbours, so this showed up as the *unfocused* side of a shared tile edge reading tinted.
+
+Fixed by gating the shadow on `w.floating` as well: a drop shadow exists to separate a window from whatever is genuinely *behind* it, and tiled windows are coplanar and adjacent by construction - there's nothing behind them to separate from. Floating windows keep their shadow unchanged (`SHADOW_SIZE`/`SHADOW_MAX_ALPHA` untouched, no new config key) - they do sit above other windows, which is exactly where a shadow does its job, and it's also the one case `visible_border_fragments`'s own occluder clipping already handles correctly. `DecorationSignature` gained a `floating` field alongside `maximized`/`fullscreen` - without it, toggling floating on its own (`srd.window.toggle_floating()`, a layout switch) changes nothing else the signature already tracks, so the shadow cache would have kept serving whichever state it last computed until some unrelated field forced a rebuild anyway.
+
+Live-verified in a nested compositor, not just read: two tiled Alacritty windows with `gap_inner`/`gap_outer` at 8px each (this test's own config value; the live report was against 1px, an even more visible case of the same bug) showed a clean shared edge with no gradient bleeding across, confirmed via `grim` screenshot. Floating a window (`{"cmd":"toggle_floating"}`) correctly detached it from the tiling group and left the remaining tiled window filling the tile area alone, confirming the gate change didn't disturb ordinary floating behaviour; `{"cmd":"set","key":"shadows",...}` still toggles the global setting both ways. Full workspace build/test/clippy clean (152 wayland tests, unchanged in count - no new pure function to isolate here, the gate is a one-line boolean condition already covered by this same live test).
+
+**Your running srdwm is stale as of this fix.** A peer session found `/proc/<pid>/exe` on the live process resolves to `/home/srdusr/.local/share/cargo/bin/srdwm (deleted)` - it was started 04:23 today, before every rebuild since (lock screen, window-sizing fix, and now this one). None of today's work is live in your actual session. Not restarted here, per this file's own standing rule never to touch the live session without being asked - restart whenever you're ready to pick any of it up.
+
## Root cause found and fixed: every new window forced to the same guessed size, never its own (2026-08-28)
Asked directly why windows "spawn small and as a square" and not centred, on top of the already-fixed "don't remember placement" bug. Read the actual code path rather than guessing, and found the real cause: `new_managed_window` hardcodes a brand-new toplevel's `Window::geometry` to `800x632` (800x600 plus the titlebar band) *before* the client has said anything about its own size, `WindowManager::add_window` feeds that same guessed number into `SmartPlacement` as if it were real, and - the actual bug - `sync_geometry` then forces that guessed size onto the client's very first `xdg_toplevel::configure` via `state.size = Some(size.into())`, unconditionally, on every single new window. Per the xdg-shell protocol, `size: None` on that first configure is the standard way every mainstream compositor (Mutter, KWin, Hyprland, sway, niri) lets a client pick its own natural size; this compositor never did, so every app - a tiny dialog and a browser alike - was flattened onto the exact same placeholder rectangle regardless of what it would have chosen for itself. That is why windows read as "the same size, small, square" rather than each app looking like itself.