refact, separate remote window, try active session

Signed-off-by: dignow <linlong1265@gmail.com>
This commit is contained in:
dignow 2023-08-02 20:38:09 +08:00
parent f495bf105f
commit 773a74e2a9
12 changed files with 54 additions and 42 deletions

View File

@ -543,7 +543,7 @@ closeConnection({String? id}) {
} }
} }
void window_on_top(int? id) async { void windowOnTop(int? id) async {
if (!isDesktop) { if (!isDesktop) {
return; return;
} }

View File

@ -32,6 +32,11 @@ const String kWindowEventHide = "hide";
const String kWindowEventShow = "show"; const String kWindowEventShow = "show";
const String kWindowConnect = "connect"; 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 kOptionSeparateRemoteWindow = "enable-separate-remote-window";
const String kUniLinksPrefix = "rustdesk://"; const String kUniLinksPrefix = "rustdesk://";

View File

@ -527,7 +527,7 @@ class _DesktopHomePageState extends State<DesktopHomePage>
debugPrint( debugPrint(
"[Main] call ${call.method} with args ${call.arguments} from window $fromWindowId"); "[Main] call ${call.method} with args ${call.arguments} from window $fromWindowId");
if (call.method == kWindowMainWindowOnTop) { if (call.method == kWindowMainWindowOnTop) {
window_on_top(null); windowOnTop(null);
} else if (call.method == kWindowGetWindowInfo) { } else if (call.method == kWindowGetWindowInfo) {
final screen = (await window_size.getWindowInfo()).screen; final screen = (await window_size.getWindowInfo()).screen;
if (screen == null) { if (screen == null) {

View File

@ -60,10 +60,10 @@ class _FileManagerTabPageState extends State<FileManagerTabPage> {
print( print(
"[FileTransfer] call ${call.method} with args ${call.arguments} from window $fromWindowId to ${windowId()}"); "[FileTransfer] call ${call.method} with args ${call.arguments} from window $fromWindowId to ${windowId()}");
// for simplify, just replace connectionId // for simplify, just replace connectionId
if (call.method == "new_file_transfer") { if (call.method == kWindowEventNewFileTransfer) {
final args = jsonDecode(call.arguments); final args = jsonDecode(call.arguments);
final id = args['id']; final id = args['id'];
window_on_top(windowId()); windowOnTop(windowId());
tabController.add(TabInfo( tabController.add(TabInfo(
key: id, key: id,
label: id, label: id,

View File

@ -60,11 +60,11 @@ class _PortForwardTabPageState extends State<PortForwardTabPage> {
debugPrint( debugPrint(
"[Port Forward] call ${call.method} with args ${call.arguments} from window $fromWindowId"); "[Port Forward] call ${call.method} with args ${call.arguments} from window $fromWindowId");
// for simplify, just replace connectionId // for simplify, just replace connectionId
if (call.method == "new_port_forward") { if (call.method == kWindowEventNewPortForward) {
final args = jsonDecode(call.arguments); final args = jsonDecode(call.arguments);
final id = args['id']; final id = args['id'];
final isRDP = args['isRDP']; final isRDP = args['isRDP'];
window_on_top(windowId()); windowOnTop(windowId());
if (tabController.state.value.tabs.indexWhere((e) => e.key == id) >= if (tabController.state.value.tabs.indexWhere((e) => e.key == id) >=
0) { 0) {
debugPrint("port forward $id exists"); debugPrint("port forward $id exists");

View File

@ -95,11 +95,11 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
"[Remote Page] call ${call.method} with args ${call.arguments} from window $fromWindowId"); "[Remote Page] call ${call.method} with args ${call.arguments} from window $fromWindowId");
// for simplify, just replace connectionId // for simplify, just replace connectionId
if (call.method == "new_remote_desktop") { if (call.method == kWindowEventNewRemoteDesktop) {
final args = jsonDecode(call.arguments); final args = jsonDecode(call.arguments);
final id = args['id']; final id = args['id'];
final switchUuid = args['switch_uuid']; final switchUuid = args['switch_uuid'];
window_on_top(windowId()); windowOnTop(windowId());
ConnectionTypeState.init(id); ConnectionTypeState.init(id);
_toolbarState.setShow( _toolbarState.setShow(
bind.mainGetUserDefaultOption(key: 'collapse_toolbar') != 'Y'); bind.mainGetUserDefaultOption(key: 'collapse_toolbar') != 'Y');
@ -125,6 +125,12 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
tabController.clear(); tabController.clear();
} else if (call.method == kWindowActionRebuild) { } else if (call.method == kWindowActionRebuild) {
reloadCurrentWindow(); reloadCurrentWindow();
} else if (call.method == kWindowEventActiveSession) {
final jumpOk = tabController.jumpToByKey(call.arguments);
if (jumpOk) {
windowOnTop(windowId());
}
return jumpOk;
} }
_update_remote_count(); _update_remote_count();
}); });

View File

@ -147,8 +147,10 @@ class DesktopTabController {
/// For addTab, tabPage has not been initialized, set [callOnSelected] to false, /// For addTab, tabPage has not been initialized, set [callOnSelected] to false,
/// and call [onSelected] at the end of initState /// and call [onSelected] at the end of initState
void jumpTo(int index, {bool callOnSelected = true}) { bool jumpTo(int index, {bool callOnSelected = true}) {
if (!isDesktop || index < 0) return; if (!isDesktop || index < 0) {
return false;
}
state.update((val) { state.update((val) {
val!.selected = index; val!.selected = index;
Future.delayed(Duration(milliseconds: 100), (() { Future.delayed(Duration(milliseconds: 100), (() {
@ -169,8 +171,13 @@ class DesktopTabController {
onSelected?.call(key); 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) { void closeBy(String? key) {
if (!isDesktop) return; if (!isDesktop) return;
assert(onRemoved != null); assert(onRemoved != null);

View File

@ -250,7 +250,7 @@ showCmWindow({bool isStartup = false}) async {
await windowManager.minimize(); //needed await windowManager.minimize(); //needed
await windowManager.setSizeAlignment( await windowManager.setSizeAlignment(
kConnectionManagerWindowSizeClosedChat, Alignment.topRight); kConnectionManagerWindowSizeClosedChat, Alignment.topRight);
window_on_top(null); windowOnTop(null);
} }
} }
} }

View File

@ -367,7 +367,7 @@ class ChatModel with ChangeNotifier {
// not minisized: add count // not minisized: add count
if (await WindowController.fromWindowId(stateGlobal.windowId) if (await WindowController.fromWindowId(stateGlobal.windowId)
.isMinimized()) { .isMinimized()) {
window_on_top(stateGlobal.windowId); windowOnTop(stateGlobal.windowId);
if (notSelected) { if (notSelected) {
tabController.jumpTo(index); tabController.jumpTo(index);
} }
@ -386,7 +386,7 @@ class ChatModel with ChangeNotifier {
return; return;
} }
if (isDesktop) { if (isDesktop) {
window_on_top(null); windowOnTop(null);
// disable auto jumpTo other tab when hasFocus, and mark unread message // disable auto jumpTo other tab when hasFocus, and mark unread message
final currentSelectedTab = final currentSelectedTab =
session.serverModel.tabController.state.value.selectedTabInfo; session.serverModel.tabController.state.value.selectedTabInfo;

View File

@ -260,7 +260,7 @@ class FfiModel with ChangeNotifier {
}); });
break; break;
default: default:
window_on_top(null); windowOnTop(null);
break; break;
} }
} }

View File

@ -473,7 +473,7 @@ class ServerModel with ChangeNotifier {
onTap: () {}, onTap: () {},
page: desktop.buildConnectionCard(client))); page: desktop.buildConnectionCard(client)));
Future.delayed(Duration.zero, () async { Future.delayed(Duration.zero, () async {
if (!hideCm) window_on_top(null); if (!hideCm) windowOnTop(null);
}); });
// Only do the hidden task when on Desktop. // Only do the hidden task when on Desktop.
if (client.authorized && isDesktop) { if (client.authorized && isDesktop) {
@ -612,7 +612,7 @@ class ServerModel with ChangeNotifier {
if (client.incomingVoiceCall) { if (client.incomingVoiceCall) {
// Has incoming phone call, let's set the window on top. // Has incoming phone call, let's set the window on top.
Future.delayed(Duration.zero, () { Future.delayed(Duration.zero, () {
window_on_top(null); windowOnTop(null);
}); });
} }
notifyListeners(); notifyListeners();

View File

@ -39,15 +39,15 @@ class RustDeskMultiWindowManager {
final Set<int> _inactiveWindows = {}; final Set<int> _inactiveWindows = {};
final Set<int> _activeWindows = {}; final Set<int> _activeWindows = {};
final List<AsyncCallback> _windowActiveCallbacks = List.empty(growable: true); final List<AsyncCallback> _windowActiveCallbacks = List.empty(growable: true);
final Map<int, Set<String>> _remoteDesktopWindows = {}; final List<int> _remoteDesktopWindows = List.empty(growable: true);
final Map<int, Set<String>> _fileTransferWindows = {}; final List<int> _fileTransferWindows = List.empty(growable: true);
final Map<int, Set<String>> _portForwardWindows = {}; final List<int> _portForwardWindows = List.empty(growable: true);
Future<dynamic> newSession( Future<dynamic> newSession(
WindowType type, WindowType type,
String methodName, String methodName,
String remoteId, String remoteId,
Map<int, Set<String>> windows, { List<int> windows, {
String? password, String? password,
bool? forceRelay, bool? forceRelay,
String? switchUuid, String? switchUuid,
@ -80,27 +80,23 @@ class RustDeskMultiWindowManager {
Future.microtask(() => windowController.show()); Future.microtask(() => windowController.show());
} }
registerActiveWindow(windowController.windowId); registerActiveWindow(windowController.windowId);
windows[windowController.windowId] = {remoteId}; windows.add(windowController.windowId);
} }
// separate window for file transfer is not supported // separate window for file transfer is not supported
bool separateWindow = type != WindowType.FileTransfer && bool separateWindow = type != WindowType.FileTransfer &&
mainGetBoolOptionSync(kOptionSeparateRemoteWindow); mainGetBoolOptionSync(kOptionSeparateRemoteWindow);
if (separateWindow) { if (windows.length > 1 || separateWindow) {
for (final item in windows.entries) { for (final windowId in windows) {
if (_activeWindows.contains(item.key) && if (await DesktopMultiWindow.invokeMethod(
item.value.contains(remoteId)) { windowId, kWindowEventActiveSession, 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());
// }
return; return;
} }
} }
}
if (separateWindow) {
if (kCloseMultiWindowByHide && _inactiveWindows.isNotEmpty) { if (kCloseMultiWindowByHide && _inactiveWindows.isNotEmpty) {
final windowId = _inactiveWindows.first; final windowId = _inactiveWindows.first;
final invokeRes = final invokeRes =
@ -108,7 +104,7 @@ class RustDeskMultiWindowManager {
final windowController = WindowController.fromWindowId(windowId); final windowController = WindowController.fromWindowId(windowId);
windowController.show(); windowController.show();
registerActiveWindow(windowController.windowId); registerActiveWindow(windowController.windowId);
windows[windowController.windowId] = {remoteId}; windows.add(windowController.windowId);
return invokeRes; return invokeRes;
} else { } else {
await newSessionWindow(); await newSessionWindow();
@ -130,7 +126,7 @@ class RustDeskMultiWindowManager {
}) async { }) async {
return await newSession( return await newSession(
WindowType.RemoteDesktop, WindowType.RemoteDesktop,
'new_remote_desktop', kWindowEventNewRemoteDesktop,
remoteId, remoteId,
_remoteDesktopWindows, _remoteDesktopWindows,
password: password, password: password,
@ -143,7 +139,7 @@ class RustDeskMultiWindowManager {
{String? password, bool? forceRelay}) async { {String? password, bool? forceRelay}) async {
return await newSession( return await newSession(
WindowType.FileTransfer, WindowType.FileTransfer,
'new_file_transfer', kWindowEventNewFileTransfer,
remoteId, remoteId,
_fileTransferWindows, _fileTransferWindows,
password: password, password: password,
@ -155,7 +151,7 @@ class RustDeskMultiWindowManager {
{String? password, bool? forceRelay}) async { {String? password, bool? forceRelay}) async {
return await newSession( return await newSession(
WindowType.PortForward, WindowType.PortForward,
'new_port_forward', kWindowEventNewPortForward,
remoteId, remoteId,
_portForwardWindows, _portForwardWindows,
password: password, password: password,
@ -170,15 +166,13 @@ class RustDeskMultiWindowManager {
return; return;
} }
return await DesktopMultiWindow.invokeMethod( return await DesktopMultiWindow.invokeMethod(
wnds.keys.toList()[0], methodName, args); wnds[0], methodName, args);
} }
Map<int, Set<String>> _findWindowsByType(WindowType type) { List<int> _findWindowsByType(WindowType type) {
switch (type) { switch (type) {
case WindowType.Main: case WindowType.Main:
return { return [0];
0: {''}
};
case WindowType.RemoteDesktop: case WindowType.RemoteDesktop:
return _remoteDesktopWindows; return _remoteDesktopWindows;
case WindowType.FileTransfer: case WindowType.FileTransfer:
@ -188,7 +182,7 @@ class RustDeskMultiWindowManager {
case WindowType.Unknown: case WindowType.Unknown:
break; break;
} }
return {}; return [];
} }
void clearWindowType(WindowType type) { void clearWindowType(WindowType type) {