refact, separate remote window, try active session
Signed-off-by: dignow <linlong1265@gmail.com>
This commit is contained in:
parent
f495bf105f
commit
773a74e2a9
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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://";
|
||||||
|
@ -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) {
|
||||||
|
@ -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,
|
||||||
|
@ -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");
|
||||||
|
@ -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();
|
||||||
});
|
});
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -260,7 +260,7 @@ class FfiModel with ChangeNotifier {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
window_on_top(null);
|
windowOnTop(null);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user