mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-09-14 00:11:01 +03:00
fix(cursor): align the remote cursor with scrollbar offsets
This commit is contained in:
@@ -1401,22 +1401,20 @@ class CursorPaint extends StatelessWidget {
|
||||
final imageOffset = _softwareImageOffset(c);
|
||||
double cx = imageOffset?.dx ?? c.x;
|
||||
double cy = imageOffset?.dy ?? c.y;
|
||||
if (c.viewStyle.style == kRemoteViewStyleOriginal &&
|
||||
c.scrollStyle == ScrollStyle.scrollbar) {
|
||||
if (c.imageOverflow.isTrue && c.scrollStyle == ScrollStyle.scrollbar) {
|
||||
final rect = c.parent.target!.ffiModel.rect;
|
||||
if (rect == null) {
|
||||
// unreachable!
|
||||
debugPrint('unreachable! The displays rect is null.');
|
||||
return Container();
|
||||
}
|
||||
if (cx < 0) {
|
||||
final imageWidth = rect.width * c.scale;
|
||||
cx = -imageWidth * c.scrollX;
|
||||
}
|
||||
if (cy < 0) {
|
||||
final imageHeight = rect.height * c.scale;
|
||||
cy = -imageHeight * c.scrollY;
|
||||
}
|
||||
// Pan offsets can be stale after leaving the image; scrollbars do not use them.
|
||||
final imageWidth = rect.width * c.scale;
|
||||
final imageHeight = rect.height * c.scale;
|
||||
cx = (c.size.width > imageWidth ? (c.size.width - imageWidth) / 2 : 0) -
|
||||
imageWidth * c.scrollX;
|
||||
cy = (c.size.height > imageHeight ? (c.size.height - imageHeight) / 2 : 0) -
|
||||
imageHeight * c.scrollY;
|
||||
}
|
||||
|
||||
final image = m.image ?? preDefaultCursor.image;
|
||||
|
||||
@@ -45,6 +45,8 @@ class _Peer extends Fake implements FfiModel {
|
||||
final pi = PeerInfo();
|
||||
@override
|
||||
bool get isPeerLinux => false;
|
||||
@override
|
||||
Rect get rect => Offset.zero & _viewport;
|
||||
}
|
||||
|
||||
class _FFI extends Fake implements FFI {
|
||||
@@ -82,11 +84,26 @@ class _CanvasModel extends ChangeNotifier implements CanvasModel {
|
||||
final double scale;
|
||||
@override
|
||||
ScrollStyle get scrollStyle => ScrollStyle.scrollauto;
|
||||
@override
|
||||
Size get size => _viewport;
|
||||
|
||||
@override
|
||||
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
|
||||
}
|
||||
|
||||
class _ScrollbarCanvasModel extends _CanvasModel {
|
||||
_ScrollbarCanvasModel(String style) : super(style, 2, true) {
|
||||
imageOverflow.value = true;
|
||||
}
|
||||
|
||||
@override
|
||||
ScrollStyle get scrollStyle => ScrollStyle.scrollbar;
|
||||
@override
|
||||
double get scrollX => 0.1;
|
||||
@override
|
||||
double get scrollY => 0.2;
|
||||
}
|
||||
|
||||
class _Canvas extends Fake implements Canvas {
|
||||
double factor = 1;
|
||||
Offset? position;
|
||||
@@ -161,4 +178,31 @@ void main() {
|
||||
expect(position.dy, closeTo(target.dy, 1e-9));
|
||||
});
|
||||
}
|
||||
for (final style in [kRemoteViewStyleOriginal, kRemoteViewStyleCustom]) {
|
||||
testWidgets('$style painted cursor follows scrollbar position',
|
||||
(tester) async {
|
||||
final image = (await tester.runAsync(
|
||||
() => createTestImage(width: 48, height: 64)))!;
|
||||
addTearDown(image.dispose);
|
||||
await tester.pumpWidget(MediaQuery(
|
||||
data: const MediaQueryData(devicePixelRatio: 2),
|
||||
child: MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider<CursorModel>(
|
||||
create: (_) => _CursorModel(image)),
|
||||
ChangeNotifierProvider<CanvasModel>(
|
||||
create: (_) => _ScrollbarCanvasModel(style)),
|
||||
],
|
||||
child: CursorPaint(id: 'cursor-test', zoomCursor: true.obs),
|
||||
),
|
||||
));
|
||||
final painter = tester
|
||||
.widget<CustomPaint>(find.byType(CustomPaint))
|
||||
.painter! as ImagePainter;
|
||||
final target = _remotePosition * 2 -
|
||||
Offset(_viewport.width * 2 * 0.1, _viewport.height * 2 * 0.2);
|
||||
expect(
|
||||
(Offset(painter.x, painter.y) + _hotspot) * painter.scale, target);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user