Files
DeeJanuz--frametop/docs/desktop-mouse.md
T

105 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Independent desktop mouse
`input/ft-mousectl desktop --save` selects normal desktop input: the physical
mouse moves across the nested KDE monitors, clicks and scrolls through KDE's
Wayland seat, and displays KDE's own cursor. No mouse event becomes a virtual
controller event. Physical controllers remain available to SteamVR and games.
While a routed mouse is connected, controller events on desktop app panels are ignored;
floating app panels, the separate grab bars and placement controls still work under the existing
controller policy. SteamVR dashboard controls are unaffected.
Native CLI commands (no additional project tooling required):
```sh
input/ft-mousectl status
input/ft-mousectl desktop --save
input/ft-mousectl center 2
input/ft-mousectl position 2 960 540
input/ft-mousectl layout
input/ft-mousectl spatial --save
```
Numbers follow KDE's WL-0, WL-1 output order, starting at 1. Positions are local
logical pixels; `layout` reads actual output geometry and scale from the running
private KDE session. Geometry follows FrameTop layout changes too. A drag keeps
the Wayland implicit grab on its initial output until all buttons are released,
while the cursor can cross onto another monitor.
The relay gathers motion and wheels until the mouse's SYN_REPORT. High resolution
wheel reports use 1/120-notch units and replace accompanying ordinary reports;
they are delivered immediately without the spatial pointer's pulse timer. The
main and thumb wheels are independent. Standard mouse button codes are passed
through, including back/forward; spatial mouse button mappings do not apply.
`DESKTOP_MOUSE_SPEED` in `~/.config/frametop.conf` sets logical pixels per motion
count, default 1, range .05–10. This initial implementation uses constant speed,
not KDE's libinput acceleration settings, because FrameTop's relay owns the
physical device outside the nested session.
The cursor overlay only displays KDE's cursor; it has no input method, laser
claim, or interactive overlay flag. Cursor shape, hotspot and buffer scale come
from KDE. GPU cursor buffers use the same zero-copy DMA-BUF import as the monitor
textures. Common 32-bit shared-memory cursor formats are converted to RGBA.
Controller fallback: `DESKTOP_CONTROLLER_FALLBACK=1` (default) allows controller
laser input into desktop apps when no grabbed physical mouse is routed by the
relay. Idle mice do not trigger fallback. The relay reports presence every
second; absence must persist for one second, so disconnect detection normally
takes about one to two seconds. Keyboard routing still follows desktop clicks.
The virtual spatial mouse/gaze pointer stays off; controller policy stays
`dashboard`, preserving SteamVR's existing pointer-mode behavior.
Reconnect or native mouse motion returns ownership to the native seat and
releases controller-held buttons before clearing its focus. A held native mouse
button prevents fallback until released. An unknown presence or a heartbeat
older than three seconds blocks automatic controller desktop input. Set
`DESKTOP_CONTROLLER_FALLBACK=0` to retain strict separation even without a mouse;
reload the relay at an appropriate pause after changing this preference.
`input/ft-mousectl status` includes `controllerFallback` with presence, freshness,
configured enablement and actual desktop controller ownership. Older running
compositors report this field unavailable until explicitly reloaded.
Both paths support images up to 512×512 and buffer scale 8. FrameTop retains the
image from the first surface commit, because KDE can commit it before selecting
the active cursor and wlroots releases current.buffer after commit callbacks.
An unsupported buffer is reported by cursorReady=false with cursorError
and hides the old cursor image. Rendering in VR still needs a wearer check for
visibility, stereo depth, monitor edges and cursor shape changes.
The private desktop and apps launched from it use KDE's `kcminputrc` cursor
preferences (24px Breeze by default). Steam's VR environment exports
`XCURSOR_SIZE=256` and `XCURSOR_THEME=steam`; inheriting these makes app cursors
huge and can make their appearance change across monitors. A live KDE
CursorChanged notification updates KDE, but already running apps may retain
the old environment until reopened. Do not resize the VR overlay to mask an
app's incorrectly configured cursor size.
The updated compositor, pointer helper and relay must all be loaded before
activation. `status` is read-only and shows readiness, actual/desired mode,
held buttons and delivery counters. Saving happens only after an acknowledged
mode change. Switching refuses while buttons/keys on a pointer device are held.
An absent compositor does not prevent explicit spatial recovery. Restarting the
desktop requires the user's approval; use `desktops.sh restart` so background
work is preserved, and restore the current app windows afterwards.
If the compositor is lost, native mouse messages are not redirected into VR.
The input helpers need reloading when upgrading this feature. A standalone
helper/compositor restart may require `input/ft-mousectl desktop` again; inspect
all three components in `status` rather than inferring success from motion alone.
Offline verification (or run `scripts/test-desktop-input.sh`):
```sh
python3 -m unittest discover -s input -p 'test_*.py'
scripts/frame.sh -C screens 'gcc -std=c11 -Wall -Wextra -Werror tests/desktop-mouse-test.c -lm -o build/desktop-mouse-test && build/desktop-mouse-test'
scripts/frame.sh -C screens 'gcc -std=c11 -Wall -Wextra -Werror $(pkg-config --cflags libdrm) tests/desktop-cursor-test.c -o build/desktop-cursor-test && build/desktop-cursor-test'
scripts/frame.sh -C screens 'gcc -std=c11 -Wall -Wextra -Werror tests/cursor-cache-test.c $(pkg-config --cflags --libs wlroots-0.20 wayland-server wayland-client libdrm pixman-1) -o build/cursor-cache-test && build/cursor-cache-test'
```
The direct seat and cursor path follow the [Wayland pointer protocol](https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_pointer).
The default remains `MOUSE_MODE=spatial`. Native mode is explicitly selected
with `input/ft-mousectl desktop --save`; no driver bindings or SteamVR defaults
are changed by installation. The new native mode suppresses virtual gaze, hand
gesture and gaze-click input while selected. Switch back to spatial mode to
use those features. Ordinary VR keyboard events remain available.