diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index eb070a676..52f474fbd 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -286,30 +286,35 @@ class ImagePaint extends StatelessWidget { child: child)); if (c.scrollStyle == ScrollStyle.scrollbar) { + final imageWidth = c.getDisplayWidth() * s; + final imageHeight = c.getDisplayHeight() * s; final imageWidget = SizedBox( - width: c.getDisplayWidth() * s, - height: c.getDisplayHeight() * s, + width: imageWidth, + height: imageHeight, child: CustomPaint( painter: ImagePainter(image: m.image, x: 0, y: 0, scale: s), )); - return Center( - child: NotificationListener( - onNotification: (notification) { - final percentX = _horizontal.position.extentBefore / - (_horizontal.position.extentBefore + - _horizontal.position.extentInside + - _horizontal.position.extentAfter); - final percentY = _vertical.position.extentBefore / - (_vertical.position.extentBefore + - _vertical.position.extentInside + - _vertical.position.extentAfter); - c.setScrollPercent(percentX, percentY); - return false; - }, - child: mouseRegion( - child: _buildCrossScrollbar(_buildListener(imageWidget))), - ), + return NotificationListener( + onNotification: (notification) { + final percentX = _horizontal.hasClients + ? _horizontal.position.extentBefore / + (_horizontal.position.extentBefore + + _horizontal.position.extentInside + + _horizontal.position.extentAfter) + : 0.0; + final percentY = _vertical.hasClients + ? _vertical.position.extentBefore / + (_vertical.position.extentBefore + + _vertical.position.extentInside + + _vertical.position.extentAfter) + : 0.0; + c.setScrollPercent(percentX, percentY); + return false; + }, + child: mouseRegion( + child: _buildCrossScrollbar(context, _buildListener(imageWidget), + Size(imageWidth, imageHeight))), ); } else { final imageWidget = SizedBox( @@ -342,44 +347,96 @@ class ImagePaint extends StatelessWidget { } } - Widget _buildCrossScrollbar(Widget child) { + Widget _buildCrossScrollbarFromLayout( + BuildContext context, Widget child, Size layoutSize, Size size) { final scrollConfig = CustomMouseWheelScrollConfig( scrollDuration: kDefaultScrollDuration, scrollCurve: Curves.linearToEaseOut, mouseWheelTurnsThrottleTimeMs: kDefaultMouseWheelThrottleDuration.inMilliseconds, scrollAmountMultiplier: kDefaultScrollAmountMultiplier); - return Obx(() => ImprovedScrolling( + var widget = child; + if (layoutSize.width < size.width) { + widget = ScrollConfiguration( + behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false), + child: SingleChildScrollView( + controller: _horizontal, + scrollDirection: Axis.horizontal, + physics: cursorOverImage.isTrue + ? const NeverScrollableScrollPhysics() + : null, + child: widget, + ), + ); + } else { + widget = Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [widget], + ); + } + if (layoutSize.height < size.height) { + widget = ScrollConfiguration( + behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false), + child: SingleChildScrollView( + controller: _vertical, + physics: cursorOverImage.isTrue + ? const NeverScrollableScrollPhysics() + : null, + child: widget, + ), + ); + } else { + widget = Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [widget], + ); + } + if (layoutSize.width < size.width) { + widget = ImprovedScrolling( + scrollController: _horizontal, + enableCustomMouseWheelScrolling: cursorOverImage.isFalse, + customMouseWheelScrollConfig: scrollConfig, + child: RawScrollbar( + thumbColor: Colors.grey, + controller: _horizontal, + thumbVisibility: false, + trackVisibility: false, + notificationPredicate: (notification) => notification.depth == 1, + child: widget, + ), + ); + } + if (layoutSize.height < size.height) { + widget = ImprovedScrolling( scrollController: _vertical, enableCustomMouseWheelScrolling: cursorOverImage.isFalse, customMouseWheelScrollConfig: scrollConfig, - child: ImprovedScrolling( - scrollController: _horizontal, - enableCustomMouseWheelScrolling: cursorOverImage.isFalse, - customMouseWheelScrollConfig: scrollConfig, - child: Scrollbar( - controller: _vertical, - thumbVisibility: false, - trackVisibility: false, - child: Scrollbar( - controller: _horizontal, - thumbVisibility: false, - trackVisibility: false, - notificationPredicate: (notif) => notif.depth == 1, - child: SingleChildScrollView( - controller: _vertical, - physics: cursorOverImage.isTrue - ? const NeverScrollableScrollPhysics() - : null, - child: SingleChildScrollView( - controller: _horizontal, - scrollDirection: Axis.horizontal, - physics: cursorOverImage.isTrue - ? const NeverScrollableScrollPhysics() - : null, - child: child, - ), - )))))); + child: RawScrollbar( + thumbColor: Colors.grey, + controller: _vertical, + thumbVisibility: false, + trackVisibility: false, + child: widget, + ), + ); + } + + return widget; + } + + Widget _buildCrossScrollbar(BuildContext context, Widget child, Size size) { + var layoutSize = MediaQuery.of(context).size; + layoutSize = Size( + layoutSize.width - kWindowBorderWidth * 2, + layoutSize.height - + kWindowBorderWidth * 2 - + kDesktopRemoteTabBarHeight); + bool overflow = + layoutSize.width < size.width || layoutSize.height < size.height; + return overflow + ? Obx(() => + _buildCrossScrollbarFromLayout(context, child, layoutSize, size)) + : _buildCrossScrollbarFromLayout(context, child, layoutSize, size); } Widget _buildListener(Widget child) { diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index 1865dfec0..fc62df908 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -73,7 +73,7 @@ dependencies: flutter_custom_cursor: git: url: https://github.com/Kingtous/rustdesk_flutter_custom_cursor - ref: 527821d676017387be024dffd61898ff79b14c41 + ref: 4a950fd3a5a228bf5381070a4c803919d5787c07 get: ^4.6.5 visibility_detector: ^0.3.3 contextmenu: ^3.0.0