srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/core/src/manager
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2025-10-03 22:59:00 +0200
committersrdusr <[email protected]>2025-10-03 22:59:00 +0200
commit4eb36873d4ca4b0faf0e54dbeab8f5f6450dd704 (patch)
tree657c89f7398f98b0305b9cd69889c232608f3027 /crates/core/src/manager
parentd7031dd060ec12e6de334518aa75122c65794047 (diff)
downloadsrdwm-4eb36873d4ca4b0faf0e54dbeab8f5f6450dd704.tar.gz
srdwm-4eb36873d4ca4b0faf0e54dbeab8f5f6450dd704.zip
Make the secondary-cursor sprite opt-in and expire stale entries
Live report: a second cursor appeared uninvited and unusably (frozen, uncontrollable) on screen. Multi-cursor Phase 1 rendered one sprite per physical libinput pointer device that had ever reported a position, with no way to turn it off and no expiry - so a phantom device (a real mouse's side-button/scroll cluster enumerating as its own HID path is a common case) that reports once and never moves again left a frozen ghost sprite with nothing to control or dismiss it. Adds general.multi_cursor (default false, live-settable via `srd set multi_cursor <bool>`) and keys secondary_cursors to (Point, Instant) so both the recording side (udev/session.rs) and the render side (udev/render.rs) drop any entry older than SECONDARY_CURSOR_TIMEOUT (1.5s). The "agent controls a window without interrupting the user" use case this report also raised was never gated on this flag - that's Multi-cursor Phase 2's pinned virtual-pointer delivery, which never shows a visible cursor at all.
Diffstat (limited to 'crates/core/src/manager')
-rw-r--r--crates/core/src/manager/mod.rs21
1 files changed, 21 insertions, 0 deletions
diff --git a/crates/core/src/manager/mod.rs b/crates/core/src/manager/mod.rs
index c82bced..bb22533 100644
--- a/crates/core/src/manager/mod.rs
+++ b/crates/core/src/manager/mod.rs
@@ -232,6 +232,26 @@ pub struct WindowManager {
/// without touching config - `udev::platform::connect` attempts the
/// probe if *either* this or the env var says to.
pub gpu_enabled: bool,
+ /// Read from `general.multi_cursor` - `false` by default. Gates
+ /// whether the udev backend renders one extra cursor sprite per
+ /// *other* physical pointer device that's recently moved (`UdevState::
+ /// secondary_cursors`, "Multi-cursor Phase 1"). Off by default because
+ /// live use found the un-gated version actively confusing rather than
+ /// useful: real hardware routinely reports what is really one mouse
+ /// as more than one distinct libinput device (a side-button/scroll
+ /// cluster on its own HID path, concretely), so an always-on second
+ /// sprite showed up uninvited and, since nothing else ever moved that
+ /// phantom device again, sat frozen on screen with no way to control
+ /// or dismiss it - reported live as exactly that: "I see two cursors
+ /// and can't even control the other one". The two scenarios this
+ /// feature actually exists for are unaffected by this being off:
+ /// genuinely using two input devices at once is now something to
+ /// opt into rather than be surprised by, and "an agent controls a
+ /// window without interrupting me" is Multi-cursor Phase 2's own job
+ /// (`crates/wayland/src/virtual_pointer.rs`'s pinned delivery), which
+ /// never shows a visible cursor at all - it was never blocked on
+ /// this flag to begin with.
+ pub multi_cursor_enabled: bool,
/// Read from `general.phone_mode` - `false` by default. Optional
/// single-app-at-a-time placement policy for a phone-shaped display:
/// see `add_window`'s own use of this (a new window defaults to
@@ -488,6 +508,7 @@ impl WindowManager {
resize_margin: RESIZE_MARGIN,
rounded_corners_enabled: None,
gpu_enabled: false,
+ multi_cursor_enabled: false,
phone_mode: false,
desktop_icons_enabled: true,
desktop_icons_all_monitors: true,