diff options
| author | srdusr <[email protected]> | 2025-05-27 23:55:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2025-05-27 23:55:00 +0200 |
| commit | d0103908bd1c316bdebaa48e13aae332cffdeabf (patch) | |
| tree | 6b095fad936c36a51d0392d806b0d3634a36070a /docs/TODO.md | |
| parent | 65e1e7476101c56f44f843c9b9160730331dfbd1 (diff) | |
| download | srdwm-d0103908bd1c316bdebaa48e13aae332cffdeabf.tar.gz srdwm-d0103908bd1c316bdebaa48e13aae332cffdeabf.zip | |
Document the investigation of aegis's focus-staleness report
Traced the whole write/read path for srd clients' focused field going
stale after a zwlr_foreign_toplevel_handle_v1.activate-driven change --
ruled out several plausible causes (a caching/staleness bug at the IPC
layer, a same-cycle dispatch-order race in the nested backend) without
finding the actual mismatch. No live repro was run: this machine has
neither pywayland nor wlrctl, and building a minimal wayland-client
test binary to call activate directly is real, separate scope. Written
up as a lead for whoever picks this back up, not a fix.
Diffstat (limited to 'docs/TODO.md')
| -rw-r--r-- | docs/TODO.md | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/docs/TODO.md b/docs/TODO.md index eec8845..32cde59 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -35,6 +35,14 @@ Found building aegis's dock primitive against the real protocol (confirmed other Not yet root-caused on this side: `foreign_toplevel.rs`'s `Activate` handler calls the same `focus_window(state, id)` every other focus path uses (mouse click, keybinding), and `crates/platform/src/ipc.rs`'s `"clients"` request handler calls `client_snapshot(wm)` fresh on every query (no caching) which reads `wm.focused_id()` directly - both look correct in isolation from a first read, so the actual disagreement is somewhere less obvious (worth checking whether `WindowManager::focus_window` itself has a guard that no-ops for this case, or whether the winit/nested backend specifically has its own focus-sync gap the udev backend doesn't - the peer's repro was on nested `srdwm --wayland` specifically). Not blocking aegis (protocol-level behavior is correct, which is what actually matters for a dock), but a real gap for any other tooling reading `srd clients` to know what's focused. +Follow-up investigation (2026-08-25, code-reading only, no live repro run - this session had no minimal Wayland test client set up to actually call `zwlr_foreign_toplevel_handle_v1.activate` and verify, `pywayland`/`wlrctl` both absent from this machine): traced the whole write/read path and everything reads the *same* `wm.focused` through the *same* accessor, so a plain staleness/caching bug looks unlikely from the source alone. +- `crate::input::focus_window` (the free function every path - Activate, click, keybinding - calls) sets `wm.focused` via `WindowManager::focus_window` *first*, then calls `set_keyboard_focus`, which calls `foreign_toplevel::update_activated`, which calls `send_state` for both the old and new window - and `send_state_to` reads `wm.focused_id()` fresh at that point, already past the write. This is consistent with the peer's own observation that the protocol feedback is correct; it does not by itself explain `srd clients` disagreeing moments later, since `client_snapshot` reads the identical field the identical way. +- `IpcServer::poll` takes `&Rc<RefCell<WindowManager>>` by reference on every call (`ipc.poll(&self.wm)`/`ipc.poll(&self.state.wm)`), not a stored/cloned handle, so there is no separate stale copy at the IPC layer either. +- `WindowManager::focus_window`'s entire body (including the `self.focused = Some(id)` write) is gated on `self.windows.get(&id)` resolving to `Some` - a real, if unconfirmed, way for the write to silently no-op if `data.window` (the `WindowId` a `zwlr_foreign_toplevel_handle_v1` was originally bound to) ever stops matching a currently-mapped window. Not verified either way against the peer's actual repro (two plain alacritty windows, no XWayland reparenting in play) - worth a temporary diagnostic log on this specific `if let` the next time this reproduces live, to confirm the branch is even being taken. +- `nested_platform.rs`'s own event-loop ordering processes Wayland protocol dispatch (`display.dispatch_clients`, which is where `Activate` actually runs) *before* `ipc.poll` within one `poll_events` call, so a same-cycle ordering race between the two doesn't look likely either - consistent with the peer's own "ruled out as a race, still stale seconds later." + +None of this pins down an actual mismatch - it narrows out several plausible causes without finding the real one. Next step is the live repro this investigation didn't have set up: a minimal `wayland-client`-based test binary (this workspace already depends on smithay, which pulls in `wayland-client` transitively) that maps two toplevels, calls `activate` via `zwlr_foreign_toplevel_manager_v1`, and polls `srd clients` immediately after - or reproducing directly against aegis's own dock if it's available to test against interactively. + ## Real bug, root-caused and fixed: a straight vertical border line poked out of every decorated window's own rounded corners, on both the udev and winit backends (2026-08-24) Reported live, insistently, over several rounds: "the vertical border lines are protruding out" / "it's drawing onto windows." Every earlier check this session (raw pixel sampling, visual crops, multiple apps, multiple radii up to a deliberately oversized `30` live test) had been looking at the top/bottom border strip's own curve in isolation and finding it genuinely correct - which was true, but beside the point: the actual defect was a *second*, separate element bleeding through the *first* one's own correctly-cut transparent region. |