mirror of
https://github.com/rustdesk/rustdesk.git
synced 2024-12-03 11:29:25 +08:00
Merge pull request #1976 from Kingtous/master
opt: add window status management to handle exit logic
This commit is contained in:
commit
ddeaf7fb92
@ -322,10 +322,12 @@ void window_on_top(int? id) {
|
|||||||
windowManager.restore();
|
windowManager.restore();
|
||||||
windowManager.show();
|
windowManager.show();
|
||||||
windowManager.focus();
|
windowManager.focus();
|
||||||
|
rustDeskWinManager.registerActiveWindow(0);
|
||||||
} else {
|
} else {
|
||||||
WindowController.fromWindowId(id)
|
WindowController.fromWindowId(id)
|
||||||
..focus()
|
..focus()
|
||||||
..show();
|
..show();
|
||||||
|
rustDeskWinManager.call(WindowType.Main, kWindowEventShow, {"id": id});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1360,3 +1362,34 @@ Future<void> reloadAllWindows() async {
|
|||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Indicate the flutter app is running in portable mode.
|
||||||
|
///
|
||||||
|
/// [Note]
|
||||||
|
/// Portable build is only avaliable on Windows.
|
||||||
|
bool isRunningInPortableMode() {
|
||||||
|
if (!Platform.isWindows) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return bool.hasEnvironment(kEnvPortableExecutable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Window status callback
|
||||||
|
void onActiveWindowChanged() async {
|
||||||
|
print(
|
||||||
|
"[MultiWindowHandler] active window changed: ${rustDeskWinManager.getActiveWindows()}");
|
||||||
|
if (rustDeskWinManager.getActiveWindows().isEmpty) {
|
||||||
|
// close all sub windows
|
||||||
|
try {
|
||||||
|
await Future.wait([
|
||||||
|
saveWindowPosition(WindowType.Main),
|
||||||
|
rustDeskWinManager.closeAllSubWindows()
|
||||||
|
]);
|
||||||
|
} catch (err) {
|
||||||
|
debugPrint("$err");
|
||||||
|
} finally {
|
||||||
|
await windowManager.setPreventClose(false);
|
||||||
|
await windowManager.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -10,6 +10,8 @@ const String kAppTypeDesktopFileTransfer = "file transfer";
|
|||||||
const String kAppTypeDesktopPortForward = "port forward";
|
const String kAppTypeDesktopPortForward = "port forward";
|
||||||
|
|
||||||
const String kWindowActionRebuild = "rebuild";
|
const String kWindowActionRebuild = "rebuild";
|
||||||
|
const String kWindowEventHide = "hide";
|
||||||
|
const String kWindowEventShow = "show";
|
||||||
|
|
||||||
const String kUniLinksPrefix = "rustdesk://";
|
const String kUniLinksPrefix = "rustdesk://";
|
||||||
const String kActionNewConnection = "connection/new/";
|
const String kActionNewConnection = "connection/new/";
|
||||||
@ -19,6 +21,9 @@ const String kTabLabelSettingPage = "Settings";
|
|||||||
|
|
||||||
const String kWindowPrefix = "wm_";
|
const String kWindowPrefix = "wm_";
|
||||||
|
|
||||||
|
// the executable name of the portable version
|
||||||
|
const String kEnvPortableExecutable = "RUSTDESK_APPNAME";
|
||||||
|
|
||||||
const Color kColorWarn = Color.fromARGB(255, 245, 133, 59);
|
const Color kColorWarn = Color.fromARGB(255, 245, 133, 59);
|
||||||
|
|
||||||
const int kMobileDefaultDisplayWidth = 720;
|
const int kMobileDefaultDisplayWidth = 720;
|
||||||
|
@ -44,20 +44,9 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||||||
@override
|
@override
|
||||||
void onWindowClose() async {
|
void onWindowClose() async {
|
||||||
super.onWindowClose();
|
super.onWindowClose();
|
||||||
// close all sub windows
|
// hide window on close
|
||||||
if (await windowManager.isPreventClose()) {
|
await windowManager.hide();
|
||||||
try {
|
rustDeskWinManager.unregisterActiveWindow(0);
|
||||||
await Future.wait([
|
|
||||||
saveWindowPosition(WindowType.Main),
|
|
||||||
rustDeskWinManager.closeAllSubWindows()
|
|
||||||
]);
|
|
||||||
} catch (err) {
|
|
||||||
debugPrint("$err");
|
|
||||||
} finally {
|
|
||||||
await windowManager.setPreventClose(false);
|
|
||||||
await windowManager.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -437,9 +426,11 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||||||
// initTray();
|
// initTray();
|
||||||
trayManager.addListener(this);
|
trayManager.addListener(this);
|
||||||
windowManager.addListener(this);
|
windowManager.addListener(this);
|
||||||
|
rustDeskWinManager.registerActiveWindowListener(onActiveWindowChanged);
|
||||||
|
rustDeskWinManager.registerActiveWindow(0);
|
||||||
rustDeskWinManager.setMethodHandler((call, fromWindowId) async {
|
rustDeskWinManager.setMethodHandler((call, fromWindowId) async {
|
||||||
debugPrint(
|
debugPrint(
|
||||||
"call ${call.method} with args ${call.arguments} from window $fromWindowId");
|
"[Main] call ${call.method} with args ${call.arguments} from window $fromWindowId");
|
||||||
if (call.method == "main_window_on_top") {
|
if (call.method == "main_window_on_top") {
|
||||||
window_on_top(null);
|
window_on_top(null);
|
||||||
} else if (call.method == "get_window_info") {
|
} else if (call.method == "get_window_info") {
|
||||||
@ -465,6 +456,10 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||||||
}
|
}
|
||||||
} else if (call.method == kWindowActionRebuild) {
|
} else if (call.method == kWindowActionRebuild) {
|
||||||
reloadCurrentWindow();
|
reloadCurrentWindow();
|
||||||
|
} else if (call.method == kWindowEventShow) {
|
||||||
|
rustDeskWinManager.registerActiveWindow(call.arguments["id"]);
|
||||||
|
} else if (call.method == kWindowEventHide) {
|
||||||
|
rustDeskWinManager.unregisterActiveWindow(call.arguments["id"]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Future.delayed(Duration.zero, () {
|
Future.delayed(Duration.zero, () {
|
||||||
@ -475,7 +470,8 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
destoryTray();
|
// destoryTray();
|
||||||
|
rustDeskWinManager.unregisterActiveWindowListener(onActiveWindowChanged);
|
||||||
trayManager.removeListener(this);
|
trayManager.removeListener(this);
|
||||||
windowManager.removeListener(this);
|
windowManager.removeListener(this);
|
||||||
_uniLinksSubscription?.cancel();
|
_uniLinksSubscription?.cancel();
|
||||||
|
@ -97,6 +97,7 @@ class _FileManagerTabPageState extends State<FileManagerTabPage> {
|
|||||||
void onRemoveId(String id) {
|
void onRemoveId(String id) {
|
||||||
if (tabController.state.value.tabs.isEmpty) {
|
if (tabController.state.value.tabs.isEmpty) {
|
||||||
WindowController.fromWindowId(windowId()).hide();
|
WindowController.fromWindowId(windowId()).hide();
|
||||||
|
rustDeskWinManager.call(WindowType.Main, kWindowEventHide, {"id": windowId()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ class _PortForwardTabPageState extends State<PortForwardTabPage> {
|
|||||||
|
|
||||||
rustDeskWinManager.setMethodHandler((call, fromWindowId) async {
|
rustDeskWinManager.setMethodHandler((call, fromWindowId) async {
|
||||||
debugPrint(
|
debugPrint(
|
||||||
"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 == "new_port_forward") {
|
||||||
final args = jsonDecode(call.arguments);
|
final args = jsonDecode(call.arguments);
|
||||||
@ -108,6 +108,7 @@ class _PortForwardTabPageState extends State<PortForwardTabPage> {
|
|||||||
void onRemoveId(String id) {
|
void onRemoveId(String id) {
|
||||||
if (tabController.state.value.tabs.isEmpty) {
|
if (tabController.state.value.tabs.isEmpty) {
|
||||||
WindowController.fromWindowId(windowId()).hide();
|
WindowController.fromWindowId(windowId()).hide();
|
||||||
|
rustDeskWinManager.call(WindowType.Main, kWindowEventHide, {"id": windowId()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
|||||||
|
|
||||||
rustDeskWinManager.setMethodHandler((call, fromWindowId) async {
|
rustDeskWinManager.setMethodHandler((call, fromWindowId) async {
|
||||||
print(
|
print(
|
||||||
"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 == "new_remote_desktop") {
|
||||||
@ -324,6 +324,7 @@ class _ConnectionTabPageState extends State<ConnectionTabPage> {
|
|||||||
void onRemoveId(String id) {
|
void onRemoveId(String id) {
|
||||||
if (tabController.state.value.tabs.isEmpty) {
|
if (tabController.state.value.tabs.isEmpty) {
|
||||||
WindowController.fromWindowId(windowId()).hide();
|
WindowController.fromWindowId(windowId()).hide();
|
||||||
|
rustDeskWinManager.call(WindowType.Main, kWindowEventHide, {"id": windowId()});
|
||||||
}
|
}
|
||||||
ConnectionTypeState.delete(id);
|
ConnectionTypeState.delete(id);
|
||||||
_update_remote_count();
|
_update_remote_count();
|
||||||
|
@ -541,8 +541,11 @@ class WindowActionPanelState extends State<WindowActionPanel>
|
|||||||
Future.delayed(Duration.zero, () async {
|
Future.delayed(Duration.zero, () async {
|
||||||
if (widget.isMainWindow) {
|
if (widget.isMainWindow) {
|
||||||
await windowManager.hide();
|
await windowManager.hide();
|
||||||
|
rustDeskWinManager.unregisterActiveWindow(0);
|
||||||
} else {
|
} else {
|
||||||
await WindowController.fromWindowId(windowId!).hide();
|
await WindowController.fromWindowId(windowId!).hide();
|
||||||
|
rustDeskWinManager.call(
|
||||||
|
WindowType.Main, kWindowEventHide, {"id": windowId!});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -139,11 +140,30 @@ void runMultiWindow(
|
|||||||
String title,
|
String title,
|
||||||
) async {
|
) async {
|
||||||
await initEnv(appType);
|
await initEnv(appType);
|
||||||
|
late Widget widget;
|
||||||
|
switch (appType) {
|
||||||
|
case kAppTypeDesktopRemote:
|
||||||
|
widget = DesktopRemoteScreen(
|
||||||
|
params: argument,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case kAppTypeDesktopFileTransfer:
|
||||||
|
widget = DesktopFileTransferScreen(
|
||||||
|
params: argument,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case kAppTypeDesktopPortForward:
|
||||||
|
widget = DesktopPortForwardScreen(
|
||||||
|
params: argument,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// no such appType
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
_runApp(
|
_runApp(
|
||||||
title,
|
title,
|
||||||
DesktopRemoteScreen(
|
widget,
|
||||||
params: argument,
|
|
||||||
),
|
|
||||||
MyTheme.currentThemeMode(),
|
MyTheme.currentThemeMode(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,8 @@ class RustDeskMultiWindowManager {
|
|||||||
|
|
||||||
static final instance = RustDeskMultiWindowManager._();
|
static final instance = RustDeskMultiWindowManager._();
|
||||||
|
|
||||||
|
final List<int> _activeWindows = List.empty(growable: true);
|
||||||
|
final List<VoidCallback> _windowActiveCallbacks = List.empty(growable: true);
|
||||||
int? _remoteDesktopWindowId;
|
int? _remoteDesktopWindowId;
|
||||||
int? _fileTransferWindowId;
|
int? _fileTransferWindowId;
|
||||||
int? _portForwardWindowId;
|
int? _portForwardWindowId;
|
||||||
@ -57,6 +59,7 @@ class RustDeskMultiWindowManager {
|
|||||||
..center()
|
..center()
|
||||||
..setTitle("rustdesk - remote desktop")
|
..setTitle("rustdesk - remote desktop")
|
||||||
..show();
|
..show();
|
||||||
|
registerActiveWindow(remoteDesktopController.windowId);
|
||||||
_remoteDesktopWindowId = remoteDesktopController.windowId;
|
_remoteDesktopWindowId = remoteDesktopController.windowId;
|
||||||
} else {
|
} else {
|
||||||
return call(WindowType.RemoteDesktop, "new_remote_desktop", msg);
|
return call(WindowType.RemoteDesktop, "new_remote_desktop", msg);
|
||||||
@ -82,6 +85,7 @@ class RustDeskMultiWindowManager {
|
|||||||
..center()
|
..center()
|
||||||
..setTitle("rustdesk - file transfer")
|
..setTitle("rustdesk - file transfer")
|
||||||
..show();
|
..show();
|
||||||
|
registerActiveWindow(fileTransferController.windowId);
|
||||||
_fileTransferWindowId = fileTransferController.windowId;
|
_fileTransferWindowId = fileTransferController.windowId;
|
||||||
} else {
|
} else {
|
||||||
return call(WindowType.FileTransfer, "new_file_transfer", msg);
|
return call(WindowType.FileTransfer, "new_file_transfer", msg);
|
||||||
@ -107,6 +111,7 @@ class RustDeskMultiWindowManager {
|
|||||||
..center()
|
..center()
|
||||||
..setTitle("rustdesk - port forward")
|
..setTitle("rustdesk - port forward")
|
||||||
..show();
|
..show();
|
||||||
|
registerActiveWindow(portForwardController.windowId);
|
||||||
_portForwardWindowId = portForwardController.windowId;
|
_portForwardWindowId = portForwardController.windowId;
|
||||||
} else {
|
} else {
|
||||||
return call(WindowType.PortForward, "new_port_forward", msg);
|
return call(WindowType.PortForward, "new_port_forward", msg);
|
||||||
@ -167,6 +172,56 @@ class RustDeskMultiWindowManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<List<int>> getAllSubWindowIds() async {
|
||||||
|
try {
|
||||||
|
final windows = await DesktopMultiWindow.getAllSubWindowIds();
|
||||||
|
return windows;
|
||||||
|
} catch (err) {
|
||||||
|
if (err is AssertionError) {
|
||||||
|
return [];
|
||||||
|
} else {
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<int> getActiveWindows() {
|
||||||
|
return _activeWindows;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _notifyActiveWindow() {
|
||||||
|
for (final callback in _windowActiveCallbacks) {
|
||||||
|
callback.call();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void registerActiveWindow(int windowId) {
|
||||||
|
if (_activeWindows.contains(windowId)) {
|
||||||
|
// ignore
|
||||||
|
} else {
|
||||||
|
_activeWindows.add(windowId);
|
||||||
|
_notifyActiveWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void unregisterActiveWindow(int windowId) {
|
||||||
|
if (!_activeWindows.contains(windowId)) {
|
||||||
|
// ignore
|
||||||
|
} else {
|
||||||
|
_activeWindows.remove(windowId);
|
||||||
|
_notifyActiveWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void registerActiveWindowListener(VoidCallback callback) {
|
||||||
|
_windowActiveCallbacks.add(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unregisterActiveWindowListener(VoidCallback callback) {
|
||||||
|
_windowActiveCallbacks.remove(callback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final rustDeskWinManager = RustDeskMultiWindowManager.instance;
|
final rustDeskWinManager = RustDeskMultiWindowManager.instance;
|
||||||
|
Loading…
Reference in New Issue
Block a user