mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-09-15 08:51:02 +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);
|
final imageOffset = _softwareImageOffset(c);
|
||||||
double cx = imageOffset?.dx ?? c.x;
|
double cx = imageOffset?.dx ?? c.x;
|
||||||
double cy = imageOffset?.dy ?? c.y;
|
double cy = imageOffset?.dy ?? c.y;
|
||||||
if (c.viewStyle.style == kRemoteViewStyleOriginal &&
|
if (c.imageOverflow.isTrue && c.scrollStyle == ScrollStyle.scrollbar) {
|
||||||
c.scrollStyle == ScrollStyle.scrollbar) {
|
|
||||||
final rect = c.parent.target!.ffiModel.rect;
|
final rect = c.parent.target!.ffiModel.rect;
|
||||||
if (rect == null) {
|
if (rect == null) {
|
||||||
// unreachable!
|
// unreachable!
|
||||||
debugPrint('unreachable! The displays rect is null.');
|
debugPrint('unreachable! The displays rect is null.');
|
||||||
return Container();
|
return Container();
|
||||||
}
|
}
|
||||||
if (cx < 0) {
|
// Pan offsets can be stale after leaving the image; scrollbars do not use them.
|
||||||
final imageWidth = rect.width * c.scale;
|
final imageWidth = rect.width * c.scale;
|
||||||
cx = -imageWidth * c.scrollX;
|
final imageHeight = rect.height * c.scale;
|
||||||
}
|
cx = (c.size.width > imageWidth ? (c.size.width - imageWidth) / 2 : 0) -
|
||||||
if (cy < 0) {
|
imageWidth * c.scrollX;
|
||||||
final imageHeight = rect.height * c.scale;
|
cy = (c.size.height > imageHeight ? (c.size.height - imageHeight) / 2 : 0) -
|
||||||
cy = -imageHeight * c.scrollY;
|
imageHeight * c.scrollY;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final image = m.image ?? preDefaultCursor.image;
|
final image = m.image ?? preDefaultCursor.image;
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ class _Peer extends Fake implements FfiModel {
|
|||||||
final pi = PeerInfo();
|
final pi = PeerInfo();
|
||||||
@override
|
@override
|
||||||
bool get isPeerLinux => false;
|
bool get isPeerLinux => false;
|
||||||
|
@override
|
||||||
|
Rect get rect => Offset.zero & _viewport;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _FFI extends Fake implements FFI {
|
class _FFI extends Fake implements FFI {
|
||||||
@@ -82,11 +84,26 @@ class _CanvasModel extends ChangeNotifier implements CanvasModel {
|
|||||||
final double scale;
|
final double scale;
|
||||||
@override
|
@override
|
||||||
ScrollStyle get scrollStyle => ScrollStyle.scrollauto;
|
ScrollStyle get scrollStyle => ScrollStyle.scrollauto;
|
||||||
|
@override
|
||||||
|
Size get size => _viewport;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
|
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 {
|
class _Canvas extends Fake implements Canvas {
|
||||||
double factor = 1;
|
double factor = 1;
|
||||||
Offset? position;
|
Offset? position;
|
||||||
@@ -161,4 +178,31 @@ void main() {
|
|||||||
expect(position.dy, closeTo(target.dy, 1e-9));
|
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