diff --git a/src/workspaces/officerdev/src/apps/Desktop/DesktopView.tsx b/src/workspaces/officerdev/src/apps/Desktop/DesktopView.tsx index bcc6e906..91eea6ea 100644 --- a/src/workspaces/officerdev/src/apps/Desktop/DesktopView.tsx +++ b/src/workspaces/officerdev/src/apps/Desktop/DesktopView.tsx @@ -27,6 +27,7 @@ const buildWsUrl = () => { type RFBInstance = { resizeSession: boolean; scaleViewport: boolean; + showDotCursor: boolean; focusOnClick: boolean; disconnect: () => void; sendCredentials: (creds: { password: string }) => void; @@ -148,6 +149,13 @@ export const DesktopView = ({ className, style }: DesktopViewProps) => { rfb.resizeSession = true; rfb.scaleViewport = false; rfb.focusOnClick = true; + // noVNC hides the browser's own cursor over the canvas and draws the REMOTE cursor in its place. + // Until the server sends a cursor shape its image is RFB.cursors.none — so nothing is drawn, the + // real cursor is hidden, and the pointer becomes invisible. Pointer coordinates are unaffected + // (measured: x 5..1108, y 11..714 against a 1109x715 session — a perfect 1:1 map), which is why + // this looked like a desync when it was only ever a visibility problem: the clicks were landing + // correctly all along. A dot is better than nothing when the server has not supplied a shape. + rfb.showDotCursor = true; rfbRef.current = rfb; rfb.addEventListener('connect', () => {