From the first headset tests (docs/gaze-first.md, "Test results"):
- SteamVR gives the treadmill path only to a device that hints it when
it's added, so the driver hints a role that's no hand from Activate
(a hand still only while shown). With it, our device held the
dashboard laser with no hand role. The helper doesn't release the
pointer for having no hand role when POINTER_ROLE is treadmill.
- The helper's global action sets can't mute the compositor (SteamVR
reports them inactive while the laser mouse has focus), but selecting
pointer/bindings/vrcompositor_frame_controller_gazefirst.json (the
stock binding without its trigger and bumper laser entries) through
vrserver's /input/selectconfig.action does.
- input/vrws.py follows devices that connect later.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/gaze-first.md is the plan agreed on 2026-09-30: with gaze on and no
game, the gaze drives the 3D pointer everywhere, either trigger clicks
where you look (tap, precision by hand movement, hold to drag), and the
controllers keep everything but their lasers.
For its four tests:
- The driver takes "role treadmill", and its compositor bindings repeat
the right hand's under /user/treadmill. They're additive, so nothing
changes while the device is a hand. POINTER_ROLE accepts treadmill.
- pointer/probe/lasertest follows who has the dashboard laser and the
controllers' roles, and with --snapback takes the laser back.
- input/vrws.py reads vrserver's web socket with the standard library
(the host's Python has no websockets module) and prints component
changes and update rates. Checked: it connects, and lists the
controllers' bumper, thumbstick axes, and Steam button, and the
headset's /proximity, which flickers off for 0.3-0.5 s while worn.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two new actions for mouse buttons, controller buttons, and key
combinations: gaze_precision (hold: the pointer stops where you look and
the button's device steers it, a controller by where it points at
POINTER_PRECISION_GAIN, the mouse by its moves; release: click there) and
gaze_drag (the same with a real press at once, dragging until the
release). The relay sends "precision|gazedrag <source> 1|0" to the
helper, which runs them through the same holds as pinches and grips.
- Key combinations on any keyboard ("key_bindings" in the rules, e.g.
Ctrl+Alt+G for gaze on/off): the last key isn't typed.
- POINTER_GAZE_MOUSE: in gaze mode the left button is a precision button
(the default, as before) or clicks right away (direct).
- In gaze mode a moving controller no longer takes the pointer away.
- POINTER_ROLE (right, left, stylus): the driver takes a "role" command,
so the pointer can stay off the hand holding the precision controller,
which would otherwise take the role back. Needs the rebuilt driver.
- Input Settings: the actions on the Controllers and Buttons pages; on the
Gaze page the mouse choice, the role, the precision sliders, and key
combinations (captured from any keyboard).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Several KDE Plasma screens floating in SteamVR, each a real monitor of any
resolution and shape, shown by our own compositor (ft-screens), with a
layout, wrist pinning, and visibility modes; a Bluetooth mouse that drives
all of SteamVR as a room-anchored 3D pointer (input relay, ft-pointer
helper, ft_pointer SteamVR driver); two settings apps; and Bluetooth LE
fixes. Installs on the headset with ./install.sh.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>