diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 208c7f7c8..672adca75 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -614,6 +614,7 @@ class OverlayDialogManager { int _tagCount = 0; OverlayEntry? _mobileActionsOverlayEntry; + RxBool mobileActionsOverlayVisible = false.obs; void setOverlayState(OverlayKeyState overlayKeyState) { _overlayKeyState = overlayKeyState; @@ -780,12 +781,14 @@ class OverlayDialogManager { }); overlayState.insert(overlay); _mobileActionsOverlayEntry = overlay; + mobileActionsOverlayVisible.value = true; } void hideMobileActionsOverlay() { if (_mobileActionsOverlayEntry != null) { _mobileActionsOverlayEntry!.remove(); _mobileActionsOverlayEntry = null; + mobileActionsOverlayVisible.value = false; return; } } diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index 7e6e8ff86..f265f1895 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -279,7 +279,10 @@ class _RemotePageState extends State _ffi.ffiModel.pi.isSet.isTrue && _ffi.ffiModel.waitForFirstImage.isTrue ? emptyOverlay() - : Offstage(), + : () { + _ffi.ffiModel.tryShowAndroidActionsOverlay(); + return Offstage(); + }(), // Use Overlay to enable rebuild every time on menu button click. _ffi.ffiModel.pi.isSet.isTrue ? Overlay(initialEntries: [ diff --git a/flutter/lib/desktop/widgets/remote_toolbar.dart b/flutter/lib/desktop/widgets/remote_toolbar.dart index 9d6dec496..b59ae3736 100644 --- a/flutter/lib/desktop/widgets/remote_toolbar.dart +++ b/flutter/lib/desktop/widgets/remote_toolbar.dart @@ -101,6 +101,9 @@ class ToolbarState { class _ToolbarTheme { static const Color blueColor = MyTheme.button; static const Color hoverBlueColor = MyTheme.accent; + static Color inactiveColor = Colors.grey[800]!; + static Color hoverInactiveColor = Colors.grey[850]!; + static const Color redColor = Colors.redAccent; static const Color hoverRedColor = Colors.red; // kMinInteractiveDimension @@ -543,9 +546,9 @@ class _PinMenu extends StatelessWidget { assetName: state.pin ? "assets/pinned.svg" : "assets/unpinned.svg", tooltip: state.pin ? 'Unpin Toolbar' : 'Pin Toolbar', onPressed: state.switchPin, - color: state.pin ? _ToolbarTheme.blueColor : Colors.grey[800]!, + color: state.pin ? _ToolbarTheme.blueColor : _ToolbarTheme.inactiveColor, hoverColor: - state.pin ? _ToolbarTheme.hoverBlueColor : Colors.grey[850]!, + state.pin ? _ToolbarTheme.hoverBlueColor : _ToolbarTheme.hoverInactiveColor, ), ); } @@ -558,13 +561,15 @@ class _MobileActionMenu extends StatelessWidget { @override Widget build(BuildContext context) { if (!ffi.ffiModel.isPeerAndroid) return Offstage(); - return _IconMenuButton( + return Obx(()=>_IconMenuButton( assetName: 'assets/actions_mobile.svg', tooltip: 'Mobile Actions', onPressed: () => ffi.dialogManager.toggleMobileActionsOverlay(ffi: ffi), - color: _ToolbarTheme.blueColor, - hoverColor: _ToolbarTheme.hoverBlueColor, - ); + color: ffi.dialogManager.mobileActionsOverlayVisible.isTrue + ? _ToolbarTheme.blueColor : _ToolbarTheme.inactiveColor, + hoverColor: ffi.dialogManager.mobileActionsOverlayVisible.isTrue + ? _ToolbarTheme.hoverBlueColor : _ToolbarTheme.hoverInactiveColor, + )); } } diff --git a/flutter/lib/mobile/pages/remote_page.dart b/flutter/lib/mobile/pages/remote_page.dart index ff650d3c9..519e228f8 100644 --- a/flutter/lib/mobile/pages/remote_page.dart +++ b/flutter/lib/mobile/pages/remote_page.dart @@ -266,7 +266,10 @@ class _RemotePageState extends State { gFFI.ffiModel.pi.isSet.isTrue && gFFI.ffiModel.waitForFirstImage.isTrue ? emptyOverlay() - : Offstage(), + : () { + gFFI.ffiModel.tryShowAndroidActionsOverlay(); + return Offstage(); + }(), _bottomWidget(), gFFI.ffiModel.pi.isSet.isFalse ? emptyOverlay() : Offstage(), ], diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 95b5094df..a1f22242e 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -554,23 +554,13 @@ class FfiModel with ChangeNotifier { } final connType = parent.target?.connType; - if (isPeerAndroid) { _touchMode = true; - if (connType == ConnType.defaultConn && - parent.target != null && - parent.target!.ffiModel.permissions['keyboard'] != false) { - Timer( - const Duration(milliseconds: 100), - () => parent.target!.dialogManager - .showMobileActionsOverlay(ffi: parent.target!)); - } } else { _touchMode = await bind.sessionGetOption( sessionId: sessionId, arg: 'touch-mode') != ''; } - if (connType == ConnType.fileTransfer) { parent.target?.fileModel.onReady(); } else if (connType == ConnType.defaultConn) { @@ -616,6 +606,19 @@ class FfiModel with ChangeNotifier { notifyListeners(); } + tryShowAndroidActionsOverlay({int delayMSecs = 10}) { + if (isPeerAndroid) { + if (parent.target?.connType == ConnType.defaultConn && + parent.target != null && + parent.target!.ffiModel.permissions['keyboard'] != false) { + Timer( + Duration(milliseconds: delayMSecs), + () => parent.target!.dialogManager + .showMobileActionsOverlay(ffi: parent.target!)); + } + } + } + handleResolutions(String id, dynamic resolutions) { try { final List dynamicArray = jsonDecode(resolutions as String);