Repository navigation
Conversation
clintcan
left a comment
There was a problem hiding this comment.
Thanks! I tested this live on a Mac mini (macOS 26.5, mirroring a 1080p monitor) over RDP.
Colour and orientation: works. The wait cursor's colours are right now, and the cursor points the right way (the SkyLight path; the NSCursor fallback wasn't exercised). I also checked the layout against the encoder: it still sends RGBAPointer.data unchanged at our current pin. On the e258f6a0 bump, the AND mask built from alpha pairs rows by index, so this layout should work there too (not tested on the bump).
Hiding: doesn't fire. The pointer stayed on screen on the client while typing in TextEdit and during full-screen YouTube. I ran a small read-only probe in the GUI session to see why:
CGCursorIsVisibleand SkyLight'sSLCursorIsVisibleboth answer from the calling process's point of view. It flipped between 0 and 1 while the pointer was visible and moving, and a plain command-line process reads 0 with the cursor on screen. So it can't tell whether the cursor is hidden.- When a video hides the pointer, the global cursor becomes a 1×1 image with every pixel transparent.
SLSGetGlobalCursorDatareturned that six times during the video steps, and a real cursor again as soon as the mouse moved.macrdpalready reads this image. - Typing gives no signal I could find. The cursor image and
SLSCurrentCursorSeedstayed the same through 30 s of typing, and SkyLight exports no getter for the obscured state (onlySLSObscureCursor/SLSDisableCursorObscure).
Could you:
- Drop
cursor_visible()and theCGCursorIsVisibledeclaration. - In
poll_shape, sendDisplayUpdate::HidePointerwhen the cursor image is fully transparent (every alpha 0) instead of sending it as a bitmap. That covers the video case on every client, including ones that ignore a 32 bpp pointer with an empty AND mask. - Drop "typing in a text field" from the docs line and the module comment, since that case isn't detectable.
The colour fix is good to go once that's in. If you'd rather keep this PR to colour only and do the hiding separately, that's fine too.
…acOS Coloured cursors (the wait cursor, colour pickers) showed red and blue swapped in every client. A 32 bpp TS_POINTERATTRIBUTE XOR mask is B,G,R,A with the bottom row first, and the encoder writes RGBAPointer data to the wire verbatim, but macrdp sent R,G,B,A. Keep the cursor as straight RGBA, top row first, through scaling and encode it to the spec layout in one place. SkyLight's buffer is top-down (row 0 holds the arrow's tip), so the old row flip was what kept it upright on the wire; SkyLight cursors keep their orientation and the NSCursor fallback, already top-down, is no longer upside down. macrdp only ever sent bitmaps, so a client kept drawing the last shape while an app hid the cursor (full-screen video). WindowServer's cursor is then a fully transparent image, so send the hidden system pointer for it instead of a transparent bitmap, which covers clients that ignore a 32 bpp pointer with an empty AND mask. macOS obscuring the cursor while typing leaves no signal to read, so that case is not handled.
5167d9e to
03bc180
Compare
It answers from the calling process's point of view and cannot tell whether the cursor is hidden (found in upstream review of clintcan#219); a hidden cursor is already caught as a fully transparent image.
Coloured cursors (wait cursor, colour pickers) showed red and blue swapped. The 32 bpp pointer XOR mask is B,G,R,A with the bottom row first, and the encoder sends
RGBAPointer.dataunchanged, so macrdp now converts to that layout in one place. SkyLight cursors keep their orientation, and the NSCursor fallback is no longer upside down.Clients also kept drawing the last cursor shape while an app hid it (full-screen video). WindowServer's cursor is then a fully transparent image, so macrdp now sends the hidden pointer for it instead of a transparent bitmap. Typing-obscured cursors leave no readable signal, so that case is not handled.
Tests: new unit tests for the mask layout, the SkyLight pixel conversion and the transparent-cursor check;
cargo fmt --check,cargo test --locked --target aarch64-apple-darwinand clippy pass. Not yet checked against a live client; worth a look at the wait cursor and hiding during full-screen video in mstsc or FreeRDP.