diff --git a/sidecar/session.ts b/sidecar/session.ts index 94032a0..a6ad7e9 100644 --- a/sidecar/session.ts +++ b/sidecar/session.ts @@ -318,7 +318,15 @@ async function startInner(log: (line: string) => void): Promise { // -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', );