srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2025-10-07 22:20:00 +0200
committersrdusr <[email protected]>2025-10-07 22:20:00 +0200
commit9f07715b469a481849ee35ffa33d6dab34356c7d (patch)
tree7080f57115b9ea3ccab43e458c34aa2acec74501 /docs
parent4eb36873d4ca4b0faf0e54dbeab8f5f6450dd704 (diff)
downloadsrdwm-9f07715b469a481849ee35ffa33d6dab34356c7d.tar.gz
srdwm-9f07715b469a481849ee35ffa33d6dab34356c7d.zip
Fix intermittent cursor ghosting when crossing between monitors
Live report: the real cursor sometimes leaves a brief ghost behind right after moving between monitors. The bare-metal render loop already forces a full repaint (ages = [0, 0]) on a workspace switch or any window move/ resize/open/close/restack, both added earlier for the same underlying gap: the damage tracker's own element diffing doesn't always catch a vacated region on its own. Neither reset noticed the pointer leaving one monitor for another - no window moved, no workspace changed - so that head's own vacated cursor-sized region was left entirely to the tracker's diffing, intermittently. Adds UdevState::last_cursor_head, compared each frame the same way the other two resets are; only the head the pointer just left gets forced back to ages = [0, 0] (the newly-entered head draws a genuinely new element there and diffs correctly on its own).
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 a4c8d14..1392761 100644
--- a/docs/TODO.md
+++ b/docs/TODO.md
@@ -13,6 +13,16 @@ that has the full story. Keep this list current as items close or open;
update the source doc's own entry too, don't let this drift into a
second stale copy the way `PANEL_SUPPORT_TODO.md` did.
+## Real bug, root-caused and fixed: the cursor itself leaves a "ghost" briefly when crossing between monitors (2026-08-27)
+
+Reported live, separately from the secondary-cursor ghost above (same word, different bug - this one is the user's own single, real cursor): "sometimes I recognize ghosting cursor when moving between monitors."
+
+`render_udev_frame` already has two defensive resets that force a head's `ages` back to `[0, 0]` (a full repaint, bypassing damage-diffing) on a workspace switch and on any window move/resize/open/close/restack - both added previously for the exact same underlying shape of bug: `OutputDamageTracker`'s own element-level diffing "evidently doesn't always catch a vacated region on its own" (see `layout_signature`'s own doc comment, added for a window that left a stale titlebar fragment behind after un-maximizing). Neither reset covers the pointer crossing from one monitor to another: no window moved and the workspace didn't change, so the head being *left* just silently drops its cursor element from `custom_elements` one frame to the next, with nothing forcing that head to notice and repaint over it. Intermittent for the same reason the window case was: it depends on whatever else that head's own diffing already had queued that frame.
+
+Fixed with the same pattern already established for the other two cases: new `UdevState::last_cursor_head` (`Option<usize>`, the head index the pointer was actually drawn on last frame, found the same way `cursor::render_elements` itself bounds-checks). Compared each frame in `render_udev_frame`; when it changes, only the *old* head gets `ages = [0, 0]` forced - the newly-entered head draws a genuinely new element there this frame regardless, which the existing diffing already handles correctly on its own, so resetting it too would just be wasted work every time the mouse crosses a boundary.
+
+Full workspace build/test/clippy clean. Not yet live-verified - needs a restart and a real cross-monitor mouse move to confirm, same as everything else in this session.
+
## Real bug, root-caused and fixed: an uncontrollable "ghost" secondary cursor, on by default (2026-08-27)
Reported live: "I see two cursors on screen and I can't even control the other one/shouldn't really auto show. It's more of like if I use two inputs at same time or for agents to use one without interrupting me." Multi-cursor Phase 1 (`UdevState::secondary_cursors`) drew one extra cursor sprite per physical libinput pointer device that had ever reported a position, unconditionally, with no way to turn it off and no way to know which physical device it belonged to.