mirror of
https://github.com/rustdesk/rustdesk.git
synced 2025-05-12 19:06:13 +02:00
refact, separate remote window
Signed-off-by: dignow <linlong1265@gmail.com>
This commit is contained in:
parent
72c198a1e9
commit
f495bf105f
12 changed files with 297 additions and 233 deletions
|
@ -5,6 +5,7 @@ import 'package:desktop_multi_window/desktop_multi_window.dart';
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_hbb/consts.dart';
|
||||
import 'package:flutter_hbb/common.dart';
|
||||
|
||||
/// must keep the order
|
||||
|
@ -35,146 +36,159 @@ class RustDeskMultiWindowManager {
|
|||
|
||||
static final instance = RustDeskMultiWindowManager._();
|
||||
|
||||
final List<int> _activeWindows = List.empty(growable: true);
|
||||
final Set<int> _inactiveWindows = {};
|
||||
final Set<int> _activeWindows = {};
|
||||
final List<AsyncCallback> _windowActiveCallbacks = List.empty(growable: true);
|
||||
int? _remoteDesktopWindowId;
|
||||
int? _fileTransferWindowId;
|
||||
int? _portForwardWindowId;
|
||||
final Map<int, Set<String>> _remoteDesktopWindows = {};
|
||||
final Map<int, Set<String>> _fileTransferWindows = {};
|
||||
final Map<int, Set<String>> _portForwardWindows = {};
|
||||
|
||||
Future<dynamic> newRemoteDesktop(
|
||||
String remoteId, {
|
||||
Future<dynamic> newSession(
|
||||
WindowType type,
|
||||
String methodName,
|
||||
String remoteId,
|
||||
Map<int, Set<String>> windows, {
|
||||
String? password,
|
||||
String? switch_uuid,
|
||||
bool? forceRelay,
|
||||
String? switchUuid,
|
||||
bool? isRDP,
|
||||
}) async {
|
||||
var params = {
|
||||
"type": WindowType.RemoteDesktop.index,
|
||||
"type": type.index,
|
||||
"id": remoteId,
|
||||
"password": password,
|
||||
"forceRelay": forceRelay
|
||||
};
|
||||
if (switch_uuid != null) {
|
||||
params['switch_uuid'] = switch_uuid;
|
||||
if (switchUuid != null) {
|
||||
params['switch_uuid'] = switchUuid;
|
||||
}
|
||||
if (isRDP != null) {
|
||||
params['isRDP'] = isRDP;
|
||||
}
|
||||
final msg = jsonEncode(params);
|
||||
|
||||
try {
|
||||
final ids = await DesktopMultiWindow.getAllSubWindowIds();
|
||||
if (!ids.contains(_remoteDesktopWindowId)) {
|
||||
_remoteDesktopWindowId = null;
|
||||
}
|
||||
} on Error {
|
||||
_remoteDesktopWindowId = null;
|
||||
}
|
||||
if (_remoteDesktopWindowId == null) {
|
||||
final remoteDesktopController =
|
||||
await DesktopMultiWindow.createWindow(msg);
|
||||
remoteDesktopController
|
||||
newSessionWindow() async {
|
||||
final windowController = await DesktopMultiWindow.createWindow(msg);
|
||||
windowController
|
||||
..setFrame(const Offset(0, 0) & const Size(1280, 720))
|
||||
..center()
|
||||
..setTitle(getWindowNameWithId(remoteId,
|
||||
overrideType: WindowType.RemoteDesktop));
|
||||
..setTitle(getWindowNameWithId(
|
||||
remoteId,
|
||||
overrideType: type,
|
||||
));
|
||||
if (Platform.isMacOS) {
|
||||
Future.microtask(() => remoteDesktopController.show());
|
||||
Future.microtask(() => windowController.show());
|
||||
}
|
||||
registerActiveWindow(remoteDesktopController.windowId);
|
||||
_remoteDesktopWindowId = remoteDesktopController.windowId;
|
||||
} else {
|
||||
return call(WindowType.RemoteDesktop, "new_remote_desktop", msg);
|
||||
registerActiveWindow(windowController.windowId);
|
||||
windows[windowController.windowId] = {remoteId};
|
||||
}
|
||||
|
||||
// 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());
|
||||
// }
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (kCloseMultiWindowByHide && _inactiveWindows.isNotEmpty) {
|
||||
final windowId = _inactiveWindows.first;
|
||||
final invokeRes =
|
||||
await DesktopMultiWindow.invokeMethod(windowId, methodName, msg);
|
||||
final windowController = WindowController.fromWindowId(windowId);
|
||||
windowController.show();
|
||||
registerActiveWindow(windowController.windowId);
|
||||
windows[windowController.windowId] = {remoteId};
|
||||
return invokeRes;
|
||||
} else {
|
||||
await newSessionWindow();
|
||||
}
|
||||
} else {
|
||||
if (windows.isEmpty) {
|
||||
await newSessionWindow();
|
||||
} else {
|
||||
return call(type, methodName, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<dynamic> newRemoteDesktop(
|
||||
String remoteId, {
|
||||
String? password,
|
||||
String? switchUuid,
|
||||
bool? forceRelay,
|
||||
}) async {
|
||||
return await newSession(
|
||||
WindowType.RemoteDesktop,
|
||||
'new_remote_desktop',
|
||||
remoteId,
|
||||
_remoteDesktopWindows,
|
||||
password: password,
|
||||
forceRelay: forceRelay,
|
||||
switchUuid: switchUuid,
|
||||
);
|
||||
}
|
||||
|
||||
Future<dynamic> newFileTransfer(String remoteId,
|
||||
{String? password, bool? forceRelay}) async {
|
||||
var msg = jsonEncode({
|
||||
"type": WindowType.FileTransfer.index,
|
||||
"id": remoteId,
|
||||
"password": password,
|
||||
"forceRelay": forceRelay,
|
||||
});
|
||||
|
||||
try {
|
||||
final ids = await DesktopMultiWindow.getAllSubWindowIds();
|
||||
if (!ids.contains(_fileTransferWindowId)) {
|
||||
_fileTransferWindowId = null;
|
||||
}
|
||||
} on Error {
|
||||
_fileTransferWindowId = null;
|
||||
}
|
||||
if (_fileTransferWindowId == null) {
|
||||
final fileTransferController = await DesktopMultiWindow.createWindow(msg);
|
||||
fileTransferController
|
||||
..setFrame(const Offset(0, 0) & const Size(1280, 720))
|
||||
..center()
|
||||
..setTitle(getWindowNameWithId(remoteId,
|
||||
overrideType: WindowType.FileTransfer));
|
||||
if (Platform.isMacOS) {
|
||||
Future.microtask(() => fileTransferController.show());
|
||||
}
|
||||
registerActiveWindow(fileTransferController.windowId);
|
||||
_fileTransferWindowId = fileTransferController.windowId;
|
||||
} else {
|
||||
return call(WindowType.FileTransfer, "new_file_transfer", msg);
|
||||
}
|
||||
return await newSession(
|
||||
WindowType.FileTransfer,
|
||||
'new_file_transfer',
|
||||
remoteId,
|
||||
_fileTransferWindows,
|
||||
password: password,
|
||||
forceRelay: forceRelay,
|
||||
);
|
||||
}
|
||||
|
||||
Future<dynamic> newPortForward(String remoteId, bool isRDP,
|
||||
{String? password, bool? forceRelay}) async {
|
||||
final msg = jsonEncode({
|
||||
"type": WindowType.PortForward.index,
|
||||
"id": remoteId,
|
||||
"isRDP": isRDP,
|
||||
"password": password,
|
||||
"forceRelay": forceRelay,
|
||||
});
|
||||
|
||||
try {
|
||||
final ids = await DesktopMultiWindow.getAllSubWindowIds();
|
||||
if (!ids.contains(_portForwardWindowId)) {
|
||||
_portForwardWindowId = null;
|
||||
}
|
||||
} on Error {
|
||||
_portForwardWindowId = null;
|
||||
}
|
||||
if (_portForwardWindowId == null) {
|
||||
final portForwardController = await DesktopMultiWindow.createWindow(msg);
|
||||
portForwardController
|
||||
..setFrame(const Offset(0, 0) & const Size(1280, 720))
|
||||
..center()
|
||||
..setTitle(getWindowNameWithId(remoteId,
|
||||
overrideType: WindowType.PortForward));
|
||||
if (Platform.isMacOS) {
|
||||
Future.microtask(() => portForwardController.show());
|
||||
}
|
||||
registerActiveWindow(portForwardController.windowId);
|
||||
_portForwardWindowId = portForwardController.windowId;
|
||||
} else {
|
||||
return call(WindowType.PortForward, "new_port_forward", msg);
|
||||
}
|
||||
return await newSession(
|
||||
WindowType.PortForward,
|
||||
'new_port_forward',
|
||||
remoteId,
|
||||
_portForwardWindows,
|
||||
password: password,
|
||||
forceRelay: forceRelay,
|
||||
isRDP: isRDP,
|
||||
);
|
||||
}
|
||||
|
||||
Future<dynamic> call(WindowType type, String methodName, dynamic args) async {
|
||||
int? windowId = findWindowByType(type);
|
||||
if (windowId == null) {
|
||||
final wnds = _findWindowsByType(type);
|
||||
if (wnds.isEmpty) {
|
||||
return;
|
||||
}
|
||||
return await DesktopMultiWindow.invokeMethod(windowId, methodName, args);
|
||||
return await DesktopMultiWindow.invokeMethod(
|
||||
wnds.keys.toList()[0], methodName, args);
|
||||
}
|
||||
|
||||
int? findWindowByType(WindowType type) {
|
||||
Map<int, Set<String>> _findWindowsByType(WindowType type) {
|
||||
switch (type) {
|
||||
case WindowType.Main:
|
||||
return 0;
|
||||
return {
|
||||
0: {''}
|
||||
};
|
||||
case WindowType.RemoteDesktop:
|
||||
return _remoteDesktopWindowId;
|
||||
return _remoteDesktopWindows;
|
||||
case WindowType.FileTransfer:
|
||||
return _fileTransferWindowId;
|
||||
return _fileTransferWindows;
|
||||
case WindowType.PortForward:
|
||||
return _portForwardWindowId;
|
||||
return _portForwardWindows;
|
||||
case WindowType.Unknown:
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
return {};
|
||||
}
|
||||
|
||||
void clearWindowType(WindowType type) {
|
||||
|
@ -182,13 +196,13 @@ class RustDeskMultiWindowManager {
|
|||
case WindowType.Main:
|
||||
return;
|
||||
case WindowType.RemoteDesktop:
|
||||
_remoteDesktopWindowId = null;
|
||||
_remoteDesktopWindows.clear();
|
||||
break;
|
||||
case WindowType.FileTransfer:
|
||||
_fileTransferWindowId = null;
|
||||
_fileTransferWindows.clear();
|
||||
break;
|
||||
case WindowType.PortForward:
|
||||
_portForwardWindowId = null;
|
||||
_portForwardWindows.clear();
|
||||
break;
|
||||
case WindowType.Unknown:
|
||||
break;
|
||||
|
@ -209,27 +223,37 @@ class RustDeskMultiWindowManager {
|
|||
// skip main window, use window manager instead
|
||||
return;
|
||||
}
|
||||
int? wId = findWindowByType(type);
|
||||
if (wId != null) {
|
||||
|
||||
List<int> windows = [];
|
||||
try {
|
||||
windows = await DesktopMultiWindow.getAllSubWindowIds();
|
||||
} catch (e) {
|
||||
debugPrint('Failed to getAllSubWindowIds of $type, $e');
|
||||
return;
|
||||
}
|
||||
|
||||
if (windows.isEmpty) {
|
||||
return;
|
||||
}
|
||||
for (final wId in windows) {
|
||||
debugPrint("closing multi window: ${type.toString()}");
|
||||
await saveWindowPosition(type, windowId: wId);
|
||||
try {
|
||||
final ids = await DesktopMultiWindow.getAllSubWindowIds();
|
||||
if (!ids.contains(wId)) {
|
||||
// no such window already
|
||||
return;
|
||||
}
|
||||
// final ids = await DesktopMultiWindow.getAllSubWindowIds();
|
||||
// if (!ids.contains(wId)) {
|
||||
// // no such window already
|
||||
// return;
|
||||
// }
|
||||
await WindowController.fromWindowId(wId).setPreventClose(false);
|
||||
await WindowController.fromWindowId(wId).close();
|
||||
// unregister the sub window in the main window.
|
||||
unregisterActiveWindow(wId);
|
||||
_activeWindows.remove(wId);
|
||||
} catch (e) {
|
||||
debugPrint("$e");
|
||||
return;
|
||||
} finally {
|
||||
clearWindowType(type);
|
||||
}
|
||||
}
|
||||
await _notifyActiveWindow();
|
||||
clearWindowType(type);
|
||||
}
|
||||
|
||||
Future<List<int>> getAllSubWindowIds() async {
|
||||
|
@ -245,7 +269,7 @@ class RustDeskMultiWindowManager {
|
|||
}
|
||||
}
|
||||
|
||||
List<int> getActiveWindows() {
|
||||
Set<int> getActiveWindows() {
|
||||
return _activeWindows;
|
||||
}
|
||||
|
||||
|
@ -256,14 +280,19 @@ class RustDeskMultiWindowManager {
|
|||
}
|
||||
|
||||
Future<void> registerActiveWindow(int windowId) async {
|
||||
if (_activeWindows.contains(windowId)) {
|
||||
// ignore
|
||||
} else {
|
||||
_activeWindows.add(windowId);
|
||||
}
|
||||
_activeWindows.add(windowId);
|
||||
_inactiveWindows.remove(windowId);
|
||||
await _notifyActiveWindow();
|
||||
}
|
||||
|
||||
Future<void> destroyWindow(int windowId) async {
|
||||
await WindowController.fromWindowId(windowId).setPreventClose(false);
|
||||
await WindowController.fromWindowId(windowId).close();
|
||||
_remoteDesktopWindows.remove(windowId);
|
||||
_fileTransferWindows.remove(windowId);
|
||||
_portForwardWindows.remove(windowId);
|
||||
}
|
||||
|
||||
/// Remove active window which has [`windowId`]
|
||||
///
|
||||
/// [Availability]
|
||||
|
@ -271,10 +300,9 @@ class RustDeskMultiWindowManager {
|
|||
/// For other windows, please post a unregister(hide) event to main window handler:
|
||||
/// `rustDeskWinManager.call(WindowType.Main, kWindowEventHide, {"id": windowId!});`
|
||||
Future<void> unregisterActiveWindow(int windowId) async {
|
||||
if (!_activeWindows.contains(windowId)) {
|
||||
// ignore
|
||||
} else {
|
||||
_activeWindows.remove(windowId);
|
||||
_activeWindows.remove(windowId);
|
||||
if (windowId != kMainWindowId) {
|
||||
_inactiveWindows.add(windowId);
|
||||
}
|
||||
await _notifyActiveWindow();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue