fix(flutter): shrink the unzoomed remote cursor by DPR on macOS and Linux

With "Zoom cursor" off in Adaptive or Custom view, the remote cursor
bitmap was registered at scale 1.0. NSCursor and GdkCursor treat the
bitmap size as logical pixels, so on a HiDPI controller the cursor was
drawn DPR times larger than in Original view (which already passes
1/DPR) and than on Windows (whose cursor path is in physical pixels).
A HiDPI remote such as KDE Wayland sends a 48-64 px bitmap, which then
showed up 3-4x too big on a Retina Mac.

Scale the bitmap by 1/DPR in that case, and scale the Flutter-painted
cursor used while the peer moves the mouse the same way so its size
does not jump. The new branch is an identity at DPR 1 and the Windows
paths are untouched.

Fixes https://github.com/rustdesk/rustdesk/discussions/15363

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K8HSHTEHo27mDcJXVyVfSP
This commit is contained in:
rustdesk
2026-09-10 14:08:42 +08:00
parent 5cfe136fb0
commit 7194743a30

View File

@@ -1117,6 +1117,12 @@ class _ImagePaintState extends State<ImagePaint> {
} else {
if (zoomCursor.value || isViewOriginal()) {
cursorScale = s;
} else {
// NSCursor and GdkCursor treat the bitmap size as logical
// pixels, so an unzoomed cursor must be shrunk by the DPR to
// keep 1 remote px == 1 physical px, the size Original view
// already renders it at.
cursorScale = 1.0 / c.devicePixelRatio;
}
}
return cursorScale;
@@ -1412,6 +1418,12 @@ class CursorPaint extends StatelessWidget {
x = m.x - hotx + cx / c.scale;
y = m.y - hoty + cy / c.scale;
scale = c.scale;
} else if (!isWindows) {
// Keep the painted cursor the same physical size as the native one
// built by getCursorScale() above.
scale = 1.0 / c.devicePixelRatio;
x = (m.x * c.scale + cx) / scale - hotx;
y = (m.y * c.scale + cy) / scale - hoty;
}
return CustomPaint(