cursor: look a native cursor up by the raster asked for

The key ended in the raster made last. A shape switched away from keeps
no pixels, so its raster stays where it was, and going back to a raster
it was shown at before looked up the wrong key: A at 1.0, A at 0.5, then
B, then A at 1.0 again missed the 32x32 cursor that was still there,
fetched A from the core, and showed B meanwhile. With native cursors
kept for every raster, the key now ends in the raster asked for; with
pixels, that is the raster made, as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EZ49AbZJYfm8NTp5yDPMab
This commit is contained in:
rustdesk
2026-09-24 10:56:27 +08:00
co-authored by Claude Opus 5.5
parent cefb463acd
commit 5414eaf702
2 changed files with 26 additions and 2 deletions
+5 -2
View File
@@ -2930,7 +2930,8 @@ class CursorData {
final targetHeight = (height * scale).ceil();
if ((_rasterWidth != targetWidth || _rasterHeight != targetHeight) &&
!hasPixels) {
// No native cursor at this size yet; buildCursorOfCache asks for the pixels.
// Nothing to make this raster from; buildCursorOfCache asks for the pixels unless its
// native cursor was made before.
data = null;
return scale;
}
@@ -3004,7 +3005,9 @@ class CursorData {
String updateGetKey(double scale) {
scale = _checkUpdateScale(scale);
return '${peerId}_${id}_${_doubleToInt(width * scale)}_${_doubleToInt(height * scale)}_${rasterWidth}_$rasterHeight';
// The raster asked for, not the one made last: a shape without pixels keeps the native
// cursors of every raster it was shown at.
return '${peerId}_${id}_${_doubleToInt(width * scale)}_${_doubleToInt(height * scale)}_${(width * scale).ceil()}_${(height * scale).ceil()}';
}
}
+21
View File
@@ -155,6 +155,27 @@ void main() {
expect(registered.length, 100);
});
test('a raster made before is found again after the shape was switched away from',
() async {
final cursor = ffi.cursorModel;
await _feed(ffi, 'A', size: 32);
buildCursorOfCache(cursor, 1.0, cursor.cache);
await _settle();
final first = registered.single;
buildCursorOfCache(cursor, 0.5, cursor.cache);
await _settle();
await _feed(ffi, 'B');
buildCursorOfCache(cursor, 1.0, cursor.cache);
await _settle();
final count = registered.length;
_select(ffi, 'A'); // its pixels went; its cursors at both rasters stay
expect(_key(buildCursorOfCache(cursor, 1.0, cursor.cache)), first);
await _settle();
expect(ffi.cursor.fetched, isEmpty);
expect(registered.length, count);
});
test('a new raster of a shape without pixels keeps the cursor shown before',
() async {
final cursor = ffi.cursorModel;