From 773a74e2a90fbe3048017c7c5ef0d0a186fbaedd Mon Sep 17 00:00:00 2001 From: dignow Date: Wed, 2 Aug 2023 20:38:09 +0800 Subject: [PATCH] refact, separate remote window, try active session Signed-off-by: dignow --- flutter/lib/common.dart | 2 +- flutter/lib/consts.dart | 5 ++ .../lib/desktop/pages/desktop_home_page.dart | 2 +- .../desktop/pages/file_manager_tab_page.dart | 4 +- .../desktop/pages/port_forward_tab_page.dart | 4 +- .../lib/desktop/pages/remote_tab_page.dart | 10 +++- .../lib/desktop/widgets/tabbar_widget.dart | 11 ++++- flutter/lib/main.dart | 2 +- flutter/lib/models/chat_model.dart | 4 +- flutter/lib/models/model.dart | 2 +- flutter/lib/models/server_model.dart | 4 +- flutter/lib/utils/multi_window_manager.dart | 46 ++++++++----------- 12 files changed, 54 insertions(+), 42 deletions(-) diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 522f93c6f..ee7806a14 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -543,7 +543,7 @@ closeConnection({String? id}) { } } -void window_on_top(int? id) async { +void windowOnTop(int? id) async { if (!isDesktop) { return; } diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart index 7acd0f04b..e44da0854 100644 --- a/flutter/lib/consts.dart +++ b/flutter/lib/consts.dart @@ -32,6 +32,11 @@ const String kWindowEventHide = "hide"; const String kWindowEventShow = "show"; const String kWindowConnect = "connect"; +const String kWindowEventNewRemoteDesktop = "new_remote_desktop"; +const String kWindowEventNewFileTransfer = "new_file_transfer"; +const String kWindowEventNewPortForward = "new_port_forward"; +const String kWindowEventActiveSession = "active_session"; + const String kOptionSeparateRemoteWindow = "enable-separate-remote-window"; const String kUniLinksPrefix = "rustdesk://"; diff --git a/flutter/lib/desktop/pages/desktop_home_page.dart b/flutter/lib/desktop/pages/desktop_home_page.dart index 2318a5b81..6b7fe7140 100644 --- a/flutter/lib/desktop/pages/desktop_home_page.dart +++ b/flutter/lib/desktop/pages/desktop_home_page.dart @@ -527,7 +527,7 @@ class _DesktopHomePageState extends State debugPrint( "[Main] call ${call.method} with args ${call.arguments} from window $fromWindowId"); if (call.method == kWindowMainWindowOnTop) { - window_on_top(null); + windowOnTop(null); } else if (call.method == kWindowGetWindowInfo) { final screen = (await window_size.getWindowInfo()).screen; if (screen == null) { diff --git a/flutter/lib/desktop/pages/file_manager_tab_page.dart b/flutter/lib/desktop/pages/file_manager_tab_page.dart index c011fe48d..1412ba059 100644 --- a/flutter/lib/desktop/pages/file_manager_tab_page.dart +++ b/flutter/lib/desktop/pages/file_manager_tab_page.dart @@ -60,10 +60,10 @@ class _FileManagerTabPageState extends State { print( "[FileTransfer] call ${call.method} with args ${call.arguments} from window $fromWindowId to ${windowId()}"); // for simplify, just replace connectionId - if (call.method == "new_file_transfer") { + if (call.method == kWindowEventNewFileTransfer) { final args = jsonDecode(call.arguments); final id = args['id']; - window_on_top(windowId()); + windowOnTop(windowId()); tabController.add(TabInfo( key: id, label: id, diff --git a/flutter/lib/desktop/pages/port_forward_tab_page.dart b/flutter/lib/desktop/pages/port_forward_tab_page.dart index df824e431..621f393e0 100644 --- a/flutter/lib/desktop/pages/port_forward_tab_page.dart +++ b/flutter/lib/desktop/pages/port_forward_tab_page.dart @@ -60,11 +60,11 @@ class _PortForwardTabPageState extends State { debugPrint( "[Port Forward] call ${call.method} with args ${call.arguments} from window $fromWindowId"); // for simplify, just replace connectionId - if (call.method == "new_port_forward") { + if (call.method == kWindowEventNewPortForward) { final args = jsonDecode(call.arguments); final id = args['id']; final isRDP = args['isRDP']; - window_on_top(windowId()); + windowOnTop(windowId()); if (tabController.state.value.tabs.indexWhere((e) => e.key == id) >= 0) { debugPrint("port forward $id exists"); diff --git a/flutter/lib/desktop/pages/remote_tab_page.dart b/flutter/lib/desktop/pages/remote_tab_page.dart index 2e553e724..296b7ec08 100644 --- a/flutter/lib/desktop/pages/remote_tab_page.dart +++ b/flutter/lib/desktop/pages/remote_tab_page.dart @@ -95,11 +95,11 @@ class _ConnectionTabPageState extends State { "[Remote Page] call ${call.method} with args ${call.arguments} from window $fromWindowId"); // for simplify, just replace connectionId - if (call.method == "new_remote_desktop") { + if (call.method == kWindowEventNewRemoteDesktop) { final args = jsonDecode(call.arguments); final id = args['id']; final switchUuid = args['switch_uuid']; - window_on_top(windowId()); + windowOnTop(windowId()); ConnectionTypeState.init(id); _toolbarState.setShow( bind.mainGetUserDefaultOption(key: 'collapse_toolbar') != 'Y'); @@ -125,6 +125,12 @@ class _ConnectionTabPageState extends State { tabController.clear(); } else if (call.method == kWindowActionRebuild) { reloadCurrentWindow(); + } else if (call.method == kWindowEventActiveSession) { + final jumpOk = tabController.jumpToByKey(call.arguments); + if (jumpOk) { + windowOnTop(windowId()); + } + return jumpOk; } _update_remote_count(); }); diff --git a/flutter/lib/desktop/widgets/tabbar_widget.dart b/flutter/lib/desktop/widgets/tabbar_widget.dart index 1880e75fe..2a7d1452e 100644 --- a/flutter/lib/desktop/widgets/tabbar_widget.dart +++ b/flutter/lib/desktop/widgets/tabbar_widget.dart @@ -147,8 +147,10 @@ class DesktopTabController { /// For addTab, tabPage has not been initialized, set [callOnSelected] to false, /// and call [onSelected] at the end of initState - void jumpTo(int index, {bool callOnSelected = true}) { - if (!isDesktop || index < 0) return; + bool jumpTo(int index, {bool callOnSelected = true}) { + if (!isDesktop || index < 0) { + return false; + } state.update((val) { val!.selected = index; Future.delayed(Duration(milliseconds: 100), (() { @@ -169,8 +171,13 @@ class DesktopTabController { onSelected?.call(key); } } + return true; } + bool jumpToByKey(String key, {bool callOnSelected = true}) => + jumpTo(state.value.tabs.indexWhere((tab) => tab.key == key), + callOnSelected: callOnSelected); + void closeBy(String? key) { if (!isDesktop) return; assert(onRemoved != null); diff --git a/flutter/lib/main.dart b/flutter/lib/main.dart index 4578c2f21..8fcbd4ad0 100644 --- a/flutter/lib/main.dart +++ b/flutter/lib/main.dart @@ -250,7 +250,7 @@ showCmWindow({bool isStartup = false}) async { await windowManager.minimize(); //needed await windowManager.setSizeAlignment( kConnectionManagerWindowSizeClosedChat, Alignment.topRight); - window_on_top(null); + windowOnTop(null); } } } diff --git a/flutter/lib/models/chat_model.dart b/flutter/lib/models/chat_model.dart index fe1de2512..898427351 100644 --- a/flutter/lib/models/chat_model.dart +++ b/flutter/lib/models/chat_model.dart @@ -367,7 +367,7 @@ class ChatModel with ChangeNotifier { // not minisized: add count if (await WindowController.fromWindowId(stateGlobal.windowId) .isMinimized()) { - window_on_top(stateGlobal.windowId); + windowOnTop(stateGlobal.windowId); if (notSelected) { tabController.jumpTo(index); } @@ -386,7 +386,7 @@ class ChatModel with ChangeNotifier { return; } if (isDesktop) { - window_on_top(null); + windowOnTop(null); // disable auto jumpTo other tab when hasFocus, and mark unread message final currentSelectedTab = session.serverModel.tabController.state.value.selectedTabInfo; diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 54965680a..9c20a6a95 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -260,7 +260,7 @@ class FfiModel with ChangeNotifier { }); break; default: - window_on_top(null); + windowOnTop(null); break; } } diff --git a/flutter/lib/models/server_model.dart b/flutter/lib/models/server_model.dart index 6867aa6fe..6e6dd2b82 100644 --- a/flutter/lib/models/server_model.dart +++ b/flutter/lib/models/server_model.dart @@ -473,7 +473,7 @@ class ServerModel with ChangeNotifier { onTap: () {}, page: desktop.buildConnectionCard(client))); Future.delayed(Duration.zero, () async { - if (!hideCm) window_on_top(null); + if (!hideCm) windowOnTop(null); }); // Only do the hidden task when on Desktop. if (client.authorized && isDesktop) { @@ -612,7 +612,7 @@ class ServerModel with ChangeNotifier { if (client.incomingVoiceCall) { // Has incoming phone call, let's set the window on top. Future.delayed(Duration.zero, () { - window_on_top(null); + windowOnTop(null); }); } notifyListeners(); diff --git a/flutter/lib/utils/multi_window_manager.dart b/flutter/lib/utils/multi_window_manager.dart index dfc169193..8b18eb750 100644 --- a/flutter/lib/utils/multi_window_manager.dart +++ b/flutter/lib/utils/multi_window_manager.dart @@ -39,15 +39,15 @@ class RustDeskMultiWindowManager { final Set _inactiveWindows = {}; final Set _activeWindows = {}; final List _windowActiveCallbacks = List.empty(growable: true); - final Map> _remoteDesktopWindows = {}; - final Map> _fileTransferWindows = {}; - final Map> _portForwardWindows = {}; + final List _remoteDesktopWindows = List.empty(growable: true); + final List _fileTransferWindows = List.empty(growable: true); + final List _portForwardWindows = List.empty(growable: true); Future newSession( WindowType type, String methodName, String remoteId, - Map> windows, { + List windows, { String? password, bool? forceRelay, String? switchUuid, @@ -80,27 +80,23 @@ class RustDeskMultiWindowManager { Future.microtask(() => windowController.show()); } registerActiveWindow(windowController.windowId); - windows[windowController.windowId] = {remoteId}; + windows.add(windowController.windowId); } // separate window for file transfer is not supported bool separateWindow = type != WindowType.FileTransfer && mainGetBoolOptionSync(kOptionSeparateRemoteWindow); - if (separateWindow) { - for (final item in windows.entries) { - if (_activeWindows.contains(item.key) && - item.value.contains(remoteId)) { - // already has a window for this remote - final windowController = WindowController.fromWindowId(item.key); - windowController.show(); - // to-do: macos? - // if (Platform.isMacOS) { - // Future.microtask(() => windowController.show()); - // } + if (windows.length > 1 || separateWindow) { + for (final windowId in windows) { + if (await DesktopMultiWindow.invokeMethod( + windowId, kWindowEventActiveSession, remoteId)) { return; } } + } + + if (separateWindow) { if (kCloseMultiWindowByHide && _inactiveWindows.isNotEmpty) { final windowId = _inactiveWindows.first; final invokeRes = @@ -108,7 +104,7 @@ class RustDeskMultiWindowManager { final windowController = WindowController.fromWindowId(windowId); windowController.show(); registerActiveWindow(windowController.windowId); - windows[windowController.windowId] = {remoteId}; + windows.add(windowController.windowId); return invokeRes; } else { await newSessionWindow(); @@ -130,7 +126,7 @@ class RustDeskMultiWindowManager { }) async { return await newSession( WindowType.RemoteDesktop, - 'new_remote_desktop', + kWindowEventNewRemoteDesktop, remoteId, _remoteDesktopWindows, password: password, @@ -143,7 +139,7 @@ class RustDeskMultiWindowManager { {String? password, bool? forceRelay}) async { return await newSession( WindowType.FileTransfer, - 'new_file_transfer', + kWindowEventNewFileTransfer, remoteId, _fileTransferWindows, password: password, @@ -155,7 +151,7 @@ class RustDeskMultiWindowManager { {String? password, bool? forceRelay}) async { return await newSession( WindowType.PortForward, - 'new_port_forward', + kWindowEventNewPortForward, remoteId, _portForwardWindows, password: password, @@ -170,15 +166,13 @@ class RustDeskMultiWindowManager { return; } return await DesktopMultiWindow.invokeMethod( - wnds.keys.toList()[0], methodName, args); + wnds[0], methodName, args); } - Map> _findWindowsByType(WindowType type) { + List _findWindowsByType(WindowType type) { switch (type) { case WindowType.Main: - return { - 0: {''} - }; + return [0]; case WindowType.RemoteDesktop: return _remoteDesktopWindows; case WindowType.FileTransfer: @@ -188,7 +182,7 @@ class RustDeskMultiWindowManager { case WindowType.Unknown: break; } - return {}; + return []; } void clearWindowType(WindowType type) {