diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 8d047dd0d..4ea494fc5 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -1418,7 +1418,7 @@ bool isRunningInPortableMode() { } /// Window status callback -void onActiveWindowChanged() async { +Future onActiveWindowChanged() async { print( "[MultiWindowHandler] active window changed: ${rustDeskWinManager.getActiveWindows()}"); if (rustDeskWinManager.getActiveWindows().isEmpty) { diff --git a/flutter/lib/desktop/pages/desktop_home_page.dart b/flutter/lib/desktop/pages/desktop_home_page.dart index 43ffbd1e3..fd9814cc2 100644 --- a/flutter/lib/desktop/pages/desktop_home_page.dart +++ b/flutter/lib/desktop/pages/desktop_home_page.dart @@ -513,9 +513,9 @@ class _DesktopHomePageState extends State } else if (call.method == kWindowActionRebuild) { reloadCurrentWindow(); } else if (call.method == kWindowEventShow) { - rustDeskWinManager.registerActiveWindow(call.arguments["id"]); + await rustDeskWinManager.registerActiveWindow(call.arguments["id"]); } else if (call.method == kWindowEventHide) { - rustDeskWinManager.unregisterActiveWindow(call.arguments["id"]); + await rustDeskWinManager.unregisterActiveWindow(call.arguments["id"]); } else if (call.method == kWindowConnect) { await connectMainDesktop( call.arguments['id'], diff --git a/flutter/lib/desktop/widgets/tabbar_widget.dart b/flutter/lib/desktop/widgets/tabbar_widget.dart index f6a5da819..91ce6cce6 100644 --- a/flutter/lib/desktop/widgets/tabbar_widget.dart +++ b/flutter/lib/desktop/widgets/tabbar_widget.dart @@ -527,13 +527,19 @@ class WindowActionPanelState extends State void onWindowClose() async { // hide window on close if (widget.isMainWindow) { + await rustDeskWinManager.unregisterActiveWindow(0); + // `hide` must be placed after unregisterActiveWindow, because once all windows are hidden, + // flutter closes the application on macOS. We should ensure the post-run logic has ran successfully. + // e.g.: saving window position. await windowManager.hide(); - rustDeskWinManager.unregisterActiveWindow(0); } else { - widget.onClose?.call(); + // it's safe to hide the subwindow await WindowController.fromWindowId(windowId!).hide(); - rustDeskWinManager - .call(WindowType.Main, kWindowEventHide, {"id": windowId!}); + await Future.wait([ + rustDeskWinManager + .call(WindowType.Main, kWindowEventHide, {"id": windowId!}), + widget.onClose?.call() ?? Future.microtask(() => null) + ]); } super.onWindowClose(); } diff --git a/flutter/lib/main.dart b/flutter/lib/main.dart index 6d09ef139..6fd205a22 100644 --- a/flutter/lib/main.dart +++ b/flutter/lib/main.dart @@ -196,6 +196,8 @@ void runMultiWindow( // no such appType exit(0); } + // show window from hidden status + WindowController.fromWindowId(windowId!).show(); } void runConnectionManagerScreen(bool hide) async { diff --git a/flutter/lib/utils/multi_window_manager.dart b/flutter/lib/utils/multi_window_manager.dart index de6750a3f..cf6d78cd2 100644 --- a/flutter/lib/utils/multi_window_manager.dart +++ b/flutter/lib/utils/multi_window_manager.dart @@ -1,6 +1,7 @@ import 'dart:convert'; 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/common.dart'; @@ -34,7 +35,7 @@ class RustDeskMultiWindowManager { static final instance = RustDeskMultiWindowManager._(); final List _activeWindows = List.empty(growable: true); - final List _windowActiveCallbacks = List.empty(growable: true); + final List _windowActiveCallbacks = List.empty(growable: true); int? _remoteDesktopWindowId; int? _fileTransferWindowId; int? _portForwardWindowId; @@ -191,19 +192,19 @@ class RustDeskMultiWindowManager { return _activeWindows; } - void _notifyActiveWindow() { + Future _notifyActiveWindow() async { for (final callback in _windowActiveCallbacks) { - callback.call(); + await callback.call(); } } - void registerActiveWindow(int windowId) { + Future registerActiveWindow(int windowId) async { if (_activeWindows.contains(windowId)) { // ignore } else { _activeWindows.add(windowId); } - _notifyActiveWindow(); + await _notifyActiveWindow(); } /// Remove active window which has [`windowId`] @@ -212,20 +213,20 @@ class RustDeskMultiWindowManager { /// This function should only be called from main window. /// For other windows, please post a unregister(hide) event to main window handler: /// `rustDeskWinManager.call(WindowType.Main, kWindowEventHide, {"id": windowId!});` - void unregisterActiveWindow(int windowId) { + Future unregisterActiveWindow(int windowId) async { if (!_activeWindows.contains(windowId)) { // ignore } else { _activeWindows.remove(windowId); } - _notifyActiveWindow(); + await _notifyActiveWindow(); } - void registerActiveWindowListener(VoidCallback callback) { + void registerActiveWindowListener(AsyncCallback callback) { _windowActiveCallbacks.add(callback); } - void unregisterActiveWindowListener(VoidCallback callback) { + void unregisterActiveWindowListener(AsyncCallback callback) { _windowActiveCallbacks.remove(callback); } } diff --git a/flutter/macos/Runner/MainFlutterWindow.swift b/flutter/macos/Runner/MainFlutterWindow.swift index 1d16763ee..540cd9ab9 100644 --- a/flutter/macos/Runner/MainFlutterWindow.swift +++ b/flutter/macos/Runner/MainFlutterWindow.swift @@ -49,7 +49,8 @@ class MainFlutterWindow: NSWindow { super.awakeFromNib() } -// override func bitsdojo_window_configure() -> UInt { -// return BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP -// } + override public func order(_ place: NSWindow.OrderingMode, relativeTo otherWin: Int) { + super.order(place, relativeTo: otherWin) + hiddenWindowAtLaunch() + } } diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index a87727f7b..4826f6198 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -63,7 +63,7 @@ dependencies: desktop_multi_window: git: url: https://github.com/Kingtous/rustdesk_desktop_multi_window - ref: 82f9eab81cb2c7bfb938def7a1b399a6279bbc75 + ref: e6d30bde98bd0f4ff50a130e5b1068138307bd03 freezed_annotation: ^2.0.3 flutter_custom_cursor: ^0.0.2 window_size: