hide the cursor the server draws — yours is the accurate one

`-nocursor`. The RFB client asks for Raw and CopyRect and nothing else, so
x11vnc has no cursor pseudo-encoding to send a shape through and composites
the pointer into the framebuffer instead. That is a second cursor in the
picture, a round trip behind the real one, and on a bare X server with no
window manager it is the big black X of the root cursor rather than an arrow.

Verified on the live socket by parking the pointer at 100,100 and counting
what is not stage-teal in a 48x48 patch around it: 960 pixels before, 0 after.

Not fixed by teaching the client the cursor encodings — the answer is not to
draw the remote cursor better, it is not to draw it at all.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Officer-Session: de3ed4e6-f88a-429c-94e6-a760336ba83b
This commit is contained in:
2026-08-23 21:19:31 +00:00
co-authored by Claude Opus 5
parent e6cec953e4
commit ad2aa632a5
+9 -1
View File
@@ -318,7 +318,15 @@ async function startInner(log: (line: string) => void): Promise<SessionStatus> {
// -solid: the stage is bigger than the game, so the surround is now something people look at. Teal
// rather than the root's black, which reads as a broken stream rather than a desktop. x11vnc sets it
// itself on a bare display, so this costs no new host binary.
['x11vnc', '-display', display!, '-unixsock', VNC_SOCKET, '-rfbport', '0', '-rfbportv6', '0', '-noipv6', '-solid', STAGE_COLOUR, '-forever', '-shared', '-nopw', '-noxdamage', '-wait', '5', '-defer', '5'],
//
// -nocursor: the browser already draws a cursor over the canvas, and it is the accurate one. The
// client asks for Raw and CopyRect and nothing else — no cursor pseudo-encoding — so x11vnc has
// nowhere to send a cursor SHAPE and composites it into the framebuffer instead. That put a second
// pointer in the picture, lagging the real one by a round trip and, on a bare X server with no
// window manager, drawn as the big black X of the root cursor. Hiding it server-side is the fix;
// adding the pseudo-encoding to the client would be a worse one, since the answer is not to draw
// the remote cursor better but not to draw it at all.
['x11vnc', '-display', display!, '-unixsock', VNC_SOCKET, '-rfbport', '0', '-rfbportv6', '0', '-noipv6', '-solid', STAGE_COLOUR, '-nocursor', '-forever', '-shared', '-nopw', '-noxdamage', '-wait', '5', '-defer', '5'],
{ DISPLAY: display! },
'x11vnc',
);