Skip to content

feat(gpu): add a relative pointer option for virtio-GPU VMs - #181

Merged
Benehiko merged 4 commits into
mainfrom
feat/pointer-device
Sep 6, 2026
Merged

Benehiko merged 4 commits into
mainfrom
feat/pointer-device

Conversation

@Benehiko

@Benehiko Benehiko commented Sep 6, 2026

Copy link
Copy Markdown
Owner

Problem

On a virtio-GPU gaming VM, games that lock the pointer for mouse-look (Elden Ring under Proton here) get keyboard input and a visible cursor but the camera never moves. vee attaches virtio-tablet-pci, an absolute pointer. KWin (and other Wayland compositors) deliver absolute motion with a zero relative delta, and a pointer-locked client reads relative deltas only.

Change

gpu.pointer: tablet | mouse (default tablet, unchanged behaviour).

  • mouse attaches virtio-mouse-pci: the QEMU window grabs the cursor on click and forwards deltas; Ctrl+Alt+G releases the grab.
  • vee create --pointer mouse, pointer on the MCP create tool, and vee config <vm> --pointer mouse for existing VMs (applies on next start; QEMU cannot swap input devices live).
  • Refused outside --gpu-mode=virtio, like the GL knobs; unknown device names refused up front.
  • Docs: gaming-arch flags table + a "Pointer device" section; vm-yaml gpu table.

Verification

  • Unit tests: device selection, value validation, override plumbing/rejection.
  • venus-test VM: vee config venus-test --pointer mouse, restart, guest shows QEMU Virtio Mouse; Elden Ring in a loaded world, 12 relative-x events via QMP input-send-event turned the camera (frame diff 77% in the play region, compass heading changed). Same input on the tablet device did nothing.
  • make lint, go test ./... pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_011c6BRY7R2svSu26ugUstV6

Benehiko and others added 3 commits September 6, 2026 12:30
The virtio-GPU path attaches a virtio-tablet, an absolute pointer. That is
right for a desktop — the host cursor maps onto the guest with no grab —
but Wayland compositors deliver absolute motion with a zero relative delta,
and a game that locks the pointer for mouse-look reads relative deltas only,
so the camera never moves. Observed with Elden Ring under Proton on a
gaming-arch VM: keyboard fine, mouse cursor visible, no look.

Add gpu.pointer (tablet | mouse). "mouse" attaches virtio-mouse-pci, a
relative pointer: the QEMU window grabs the cursor on click and forwards
deltas, Ctrl+Alt+G releases. Exposed as --pointer on create, as pointer on
the MCP create tool, and as `vee config <vm> --pointer` for existing VMs;
QEMU cannot swap input devices live, so that applies on the next start.
Like the GL knobs it is refused outside --gpu-mode=virtio, and an unknown
device name is refused up front.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011c6BRY7R2svSu26ugUstV6
GTK3 cannot lock or warp the cursor on a Wayland host, so QEMU's GTK mouse
grab never captures motion and a virtio-mouse receives no deltas — the
relative pointer worked from QMP but not from a real mouse. QEMU's SDL2
display implements relative mouse mode with native pointer lock on both
Wayland and X11, so pointer=mouse now selects -display sdl on Linux. The
QEMU child gets SDL_VIDEODRIVER=wayland when the session is Wayland and the
user has not set a driver, so SDL does not fall back to X11 via Xwayland.
macOS keeps cocoa.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011c6BRY7R2svSu26ugUstV6
With a virtio-mouse attached, the Linux guest's psmouse driver still probes
QEMU's VMware backdoor port, finds vmmouse, and binds it to the PS/2 port.
QEMU's vmmouse is an absolute pointer, and once the guest activates it QEMU
makes it the current mouse ("info mice": "* vmmouse (absolute)"), so host
motion from the SDL window arrives as absolute coordinates again — zero
relative delta in kwin, no mouse-look — while QMP-injected relative events
still reached the virtio-mouse and looked fine.

Boot pointer=mouse VMs with -machine ...,vmport=off on x86 boards so there
is no vmmouse to bind. Left alone when the machine type already pins a
vmport= value, and never added off x86. Verified live: switching QEMU's
current mouse back to the virtio-mouse restored mouse-look immediately.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011c6BRY7R2svSu26ugUstV6
@Benehiko
Benehiko force-pushed the feat/pointer-device branch from 4b50aff to a9ea80d Compare September 6, 2026 10:32
Games lock the pointer for mouse-look and read relative deltas, which the
absolute tablet never produces on a Wayland guest, so a gaming VM created
with the default pointer starts with a camera that cannot turn. Make the
gaming-arch template's virtio configuration ask for pointer=mouse (relative
virtio-mouse, SDL window, vmport off); --pointer tablet on create restores
the desktop-style pointer. Every other template keeps tablet.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011c6BRY7R2svSu26ugUstV6
@Benehiko
Benehiko merged commit df20e95 into main Sep 6, 2026
4 checks passed
@Benehiko
Benehiko deleted the feat/pointer-device branch September 6, 2026 10:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant