From ca972a1bc661aaf43ee9f27b7cab6de763c75939 Mon Sep 17 00:00:00 2001 From: KLXY <36424064+KLXYinc@users.noreply.github.com> Date: Wed, 22 Apr 2026 00:22:38 +0300 Subject: [PATCH] fix(mobile): refactor remote page toolbar to prevent canvas render flicker --- flutter/lib/mobile/pages/remote_page.dart | 64 +++++++++++++---------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/flutter/lib/mobile/pages/remote_page.dart b/flutter/lib/mobile/pages/remote_page.dart index 9102d163c..bc8c1c78f 100644 --- a/flutter/lib/mobile/pages/remote_page.dart +++ b/flutter/lib/mobile/pages/remote_page.dart @@ -342,11 +342,15 @@ class _RemotePageState extends State with WidgetsBindingObserver { }); } - Widget _bottomWidget() => _showGestureHelp - ? getGestureHelp() - : (_showBar && gFFI.ffiModel.pi.displays.isNotEmpty - ? getBottomAppBar() - : Offstage()); + Widget _bottomWidget() => AnimatedSize( + duration: const Duration(milliseconds: 200), + curve: Curves.easeOutCubic, + child: _showGestureHelp + ? getGestureHelp() + : (_showBar && gFFI.ffiModel.pi.displays.isNotEmpty + ? getBottomAppBar() + : const SizedBox(width: double.infinity, height: 0)), + ); @override Widget build(BuildContext context) { @@ -360,6 +364,7 @@ class _RemotePageState extends State with WidgetsBindingObserver { return false; }, child: Scaffold( + extendBody: true, // workaround for https://github.com/rustdesk/rustdesk/issues/3131 floatingActionButtonLocation: keyboardIsVisible ? FABLocation(FloatingActionButtonLocation.endFloat, 0, -35) @@ -389,24 +394,11 @@ class _RemotePageState extends State with WidgetsBindingObserver { } }); }), - bottomNavigationBar: Obx(() => Stack( - alignment: Alignment.bottomCenter, - children: [ - gFFI.ffiModel.pi.isSet.isTrue && - gFFI.ffiModel.waitForFirstImage.isTrue - ? emptyOverlay(MyTheme.canvasColor) - : () { - gFFI.ffiModel.tryShowAndroidActionsOverlay(); - return Offstage(); - }(), - _bottomWidget(), - gFFI.ffiModel.pi.isSet.isFalse - ? emptyOverlay(MyTheme.canvasColor) - : Offstage(), - ], - )), body: Obx( - () => getRawPointerAndKeyBody(Overlay( + () => Stack( + alignment: Alignment.bottomCenter, + children: [ + getRawPointerAndKeyBody(Overlay( initialEntries: [ OverlayEntry(builder: (context) { return Container( @@ -439,7 +431,20 @@ class _RemotePageState extends State with WidgetsBindingObserver { }) ], )), - )), + gFFI.ffiModel.pi.isSet.isTrue && + gFFI.ffiModel.waitForFirstImage.isTrue + ? emptyOverlay(MyTheme.canvasColor) + : () { + gFFI.ffiModel.tryShowAndroidActionsOverlay(); + return Offstage(); + }(), + _bottomWidget(), + gFFI.ffiModel.pi.isSet.isFalse + ? emptyOverlay(MyTheme.canvasColor) + : Offstage(), + ], + ), + )), ); } @@ -464,7 +469,9 @@ class _RemotePageState extends State with WidgetsBindingObserver { return BottomAppBar( elevation: 10, color: MyTheme.accent, - child: Row( + child: Padding( + padding: const EdgeInsets.only(bottom: 5.0, left: 16.0, right: 16.0), + child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -555,6 +562,7 @@ class _RemotePageState extends State with WidgetsBindingObserver { )), ], ), + ), ); } @@ -789,8 +797,10 @@ class _RemotePageState extends State with WidgetsBindingObserver { /// aka changeTouchMode BottomAppBar getGestureHelp() { return BottomAppBar( - child: SingleChildScrollView( - controller: ScrollController(), + child: Padding( + padding: const EdgeInsets.only(bottom: 5.0, left: 16.0, right: 16.0), + child: SingleChildScrollView( + controller: ScrollController(), padding: EdgeInsets.symmetric(vertical: 10), child: GestureHelp( touchMode: gFFI.ffiModel.touchMode, @@ -801,7 +811,7 @@ class _RemotePageState extends State with WidgetsBindingObserver { }, virtualMouseMode: gFFI.ffiModel.virtualMouseMode, inputModel: gFFI.inputModel, - ))); + )))); } // * Currently mobile does not enable map mode