Merge pull request #3062 from Kingtous/master

fix: --connect command on macOS & window closing issues
This commit is contained in:
RustDesk 2023-02-03 20:50:45 +08:00 committed by GitHub
commit a9b5739221
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 83 additions and 37 deletions

View File

@ -3,14 +3,11 @@ import 'dart:convert';
import 'dart:ffi' hide Size; import 'dart:ffi' hide Size;
import 'dart:io'; import 'dart:io';
import 'dart:math'; import 'dart:math';
import 'dart:typed_data';
import 'package:back_button_interceptor/back_button_interceptor.dart'; import 'package:back_button_interceptor/back_button_interceptor.dart';
import 'package:desktop_multi_window/desktop_multi_window.dart'; import 'package:desktop_multi_window/desktop_multi_window.dart';
import 'package:ffi/ffi.dart'; import 'package:ffi/ffi.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter_hbb/utils/platform_channel.dart';
import 'package:win32/win32.dart' as win32;
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -19,14 +16,17 @@ import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart';
import 'package:flutter_hbb/main.dart'; import 'package:flutter_hbb/main.dart';
import 'package:flutter_hbb/models/peer_model.dart'; import 'package:flutter_hbb/models/peer_model.dart';
import 'package:flutter_hbb/utils/multi_window_manager.dart'; import 'package:flutter_hbb/utils/multi_window_manager.dart';
import 'package:flutter_hbb/utils/platform_channel.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:uni_links/uni_links.dart'; import 'package:uni_links/uni_links.dart';
import 'package:uni_links_desktop/uni_links_desktop.dart'; import 'package:uni_links_desktop/uni_links_desktop.dart';
import 'package:window_manager/window_manager.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:window_size/window_size.dart' as window_size;
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'package:win32/win32.dart' as win32;
import 'package:window_manager/window_manager.dart';
import 'package:window_size/window_size.dart' as window_size;
import '../consts.dart';
import 'common/widgets/overlay.dart'; import 'common/widgets/overlay.dart';
import 'mobile/pages/file_manager_page.dart'; import 'mobile/pages/file_manager_page.dart';
import 'mobile/pages/remote_page.dart'; import 'mobile/pages/remote_page.dart';
@ -34,8 +34,6 @@ import 'models/input_model.dart';
import 'models/model.dart'; import 'models/model.dart';
import 'models/platform_model.dart'; import 'models/platform_model.dart';
import '../consts.dart';
final globalKey = GlobalKey<NavigatorState>(); final globalKey = GlobalKey<NavigatorState>();
final navigationBarKey = GlobalKey(); final navigationBarKey = GlobalKey();
@ -1274,10 +1272,12 @@ Future<bool> restoreWindowPosition(WindowType type, {int? windowId}) async {
/// [Availability] /// [Availability]
/// initUniLinks should only be used on macos/windows. /// initUniLinks should only be used on macos/windows.
/// we use dbus for linux currently. /// we use dbus for linux currently.
Future<void> initUniLinks() async { Future<bool> initUniLinks() async {
if (!Platform.isWindows && !Platform.isMacOS) { if (Platform.isLinux) {
return; return false;
} }
// Register uni links for Windows. The required info of url scheme is already
// declared in `Info.plist` for macOS.
if (Platform.isWindows) { if (Platform.isWindows) {
registerProtocol('rustdesk'); registerProtocol('rustdesk');
} }
@ -1285,11 +1285,12 @@ Future<void> initUniLinks() async {
try { try {
final initialLink = await getInitialLink(); final initialLink = await getInitialLink();
if (initialLink == null) { if (initialLink == null) {
return; return false;
} }
parseRustdeskUri(initialLink); return parseRustdeskUri(initialLink);
} catch (err) { } catch (err) {
debugPrintStack(label: "$err"); debugPrintStack(label: "$err");
return false;
} }
} }
@ -1310,11 +1311,13 @@ StreamSubscription? listenUniLinks() {
return sub; return sub;
} }
/// Returns true if we successfully handle the startup arguments. /// Handle command line arguments
///
/// * Returns true if we successfully handle the startup arguments.
bool checkArguments() { bool checkArguments() {
// bootArgs:[--connect, 362587269, --switch_uuid, e3d531cc-5dce-41e0-bd06-5d4a2b1eec05] // bootArgs:[--connect, 362587269, --switch_uuid, e3d531cc-5dce-41e0-bd06-5d4a2b1eec05]
// check connect args // check connect args
final connectIndex = kBootArgs.indexOf("--connect"); var connectIndex = kBootArgs.indexOf("--connect");
if (connectIndex == -1) { if (connectIndex == -1) {
return false; return false;
} }
@ -1368,7 +1371,7 @@ bool callUniLinksUriHandler(Uri uri) {
Future.delayed(Duration.zero, () { Future.delayed(Duration.zero, () {
rustDeskWinManager.newRemoteDesktop(peerId, switch_uuid: switch_uuid); rustDeskWinManager.newRemoteDesktop(peerId, switch_uuid: switch_uuid);
}); });
return false; return true;
} }
return false; return false;
} }
@ -1508,8 +1511,12 @@ Future<void> onActiveWindowChanged() async {
} catch (err) { } catch (err) {
debugPrintStack(label: "$err"); debugPrintStack(label: "$err");
} finally { } finally {
debugPrint("Start closing RustDesk...");
await windowManager.setPreventClose(false); await windowManager.setPreventClose(false);
await windowManager.close(); await windowManager.close();
if (Platform.isMacOS) {
RdPlatformChannel.instance.terminate();
}
} }
} }
} }

View File

@ -1,9 +1,10 @@
import 'package:flutter/material.dart';
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_hbb/common.dart'; import 'package:flutter_hbb/common.dart';
const double kDesktopRemoteTabBarHeight = 28.0; const double kDesktopRemoteTabBarHeight = 28.0;
const int kMainWindowId = 0;
const String kPeerPlatformWindows = "Windows"; const String kPeerPlatformWindows = "Windows";
const String kPeerPlatformLinux = "Linux"; const String kPeerPlatformLinux = "Linux";

View File

@ -1,23 +1,23 @@
import 'dart:io';
import 'dart:async'; import 'dart:async';
import 'dart:io';
import 'dart:math'; import 'dart:math';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:bot_toast/bot_toast.dart';
import 'package:desktop_multi_window/desktop_multi_window.dart'; import 'package:desktop_multi_window/desktop_multi_window.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart' hide TabBarTheme; import 'package:flutter/material.dart' hide TabBarTheme;
import 'package:flutter_hbb/common.dart'; import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/common/shared_state.dart';
import 'package:flutter_hbb/consts.dart'; import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/main.dart'; import 'package:flutter_hbb/main.dart';
import 'package:flutter_hbb/common/shared_state.dart';
import 'package:flutter_hbb/models/platform_model.dart'; import 'package:flutter_hbb/models/platform_model.dart';
import 'package:flutter_hbb/models/state_model.dart'; import 'package:flutter_hbb/models/state_model.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:get/get_rx/src/rx_workers/utils/debouncer.dart'; import 'package:get/get_rx/src/rx_workers/utils/debouncer.dart';
import 'package:scroll_pos/scroll_pos.dart'; import 'package:scroll_pos/scroll_pos.dart';
import 'package:window_manager/window_manager.dart'; import 'package:window_manager/window_manager.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:bot_toast/bot_toast.dart';
import '../../utils/multi_window_manager.dart'; import '../../utils/multi_window_manager.dart';
@ -527,7 +527,9 @@ class WindowActionPanelState extends State<WindowActionPanel>
void onWindowClose() async { void onWindowClose() async {
// hide window on close // hide window on close
if (widget.isMainWindow) { if (widget.isMainWindow) {
await rustDeskWinManager.unregisterActiveWindow(0); if (rustDeskWinManager.getActiveWindows().contains(kMainWindowId)) {
await rustDeskWinManager.unregisterActiveWindow(kMainWindowId);
}
// `hide` must be placed after unregisterActiveWindow, because once all windows are hidden, // `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. // flutter closes the application on macOS. We should ensure the post-run logic has ran successfully.
// e.g.: saving window position. // e.g.: saving window position.

View File

@ -1,22 +1,22 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:bot_toast/bot_toast.dart';
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';
import 'package:flutter_hbb/models/state_model.dart';
import 'package:flutter_hbb/desktop/pages/desktop_tab_page.dart'; import 'package:flutter_hbb/desktop/pages/desktop_tab_page.dart';
import 'package:flutter_hbb/desktop/pages/server_page.dart';
import 'package:flutter_hbb/desktop/pages/install_page.dart'; import 'package:flutter_hbb/desktop/pages/install_page.dart';
import 'package:flutter_hbb/desktop/pages/server_page.dart';
import 'package:flutter_hbb/desktop/screen/desktop_file_transfer_screen.dart'; import 'package:flutter_hbb/desktop/screen/desktop_file_transfer_screen.dart';
import 'package:flutter_hbb/desktop/screen/desktop_port_forward_screen.dart'; import 'package:flutter_hbb/desktop/screen/desktop_port_forward_screen.dart';
import 'package:flutter_hbb/desktop/screen/desktop_remote_screen.dart'; import 'package:flutter_hbb/desktop/screen/desktop_remote_screen.dart';
import 'package:flutter_hbb/desktop/widgets/refresh_wrapper.dart'; import 'package:flutter_hbb/desktop/widgets/refresh_wrapper.dart';
import 'package:flutter_hbb/models/state_model.dart';
import 'package:flutter_hbb/utils/multi_window_manager.dart'; import 'package:flutter_hbb/utils/multi_window_manager.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:window_manager/window_manager.dart'; import 'package:window_manager/window_manager.dart';
import 'package:bot_toast/bot_toast.dart';
// import 'package:window_manager/window_manager.dart'; // import 'package:window_manager/window_manager.dart';
@ -114,7 +114,6 @@ Future<void> initEnv(String appType) async {
void runMainApp(bool startService) async { void runMainApp(bool startService) async {
// register uni links // register uni links
initUniLinks();
await initEnv(kAppTypeMain); await initEnv(kAppTypeMain);
// trigger connection status updater // trigger connection status updater
await bind.mainCheckConnectStatus(); await bind.mainCheckConnectStatus();
@ -130,7 +129,11 @@ void runMainApp(bool startService) async {
// Restore the location of the main window before window hide or show. // Restore the location of the main window before window hide or show.
await restoreWindowPosition(WindowType.Main); await restoreWindowPosition(WindowType.Main);
// Check the startup argument, if we successfully handle the argument, we keep the main window hidden. // Check the startup argument, if we successfully handle the argument, we keep the main window hidden.
if (checkArguments()) { final handledByUniLinks = await initUniLinks();
final handledByCli = checkArguments();
debugPrint(
"handled by uni links: $handledByUniLinks, handled by cli: $handledByCli");
if (handledByUniLinks || handledByCli) {
windowManager.hide(); windowManager.hide();
} else { } else {
windowManager.show(); windowManager.show();
@ -139,8 +142,8 @@ void runMainApp(bool startService) async {
rustDeskWinManager.registerActiveWindow(kWindowMainId); rustDeskWinManager.registerActiveWindow(kWindowMainId);
} }
windowManager.setOpacity(1); windowManager.setOpacity(1);
windowManager.setTitle(getWindowName());
}); });
windowManager.setTitle(getWindowName());
} }
void runMobileApp() async { void runMobileApp() async {

View File

@ -160,6 +160,24 @@ class RustDeskMultiWindowManager {
return null; return null;
} }
void clearWindowType(WindowType type) {
switch (type) {
case WindowType.Main:
return;
case WindowType.RemoteDesktop:
_remoteDesktopWindowId = null;
break;
case WindowType.FileTransfer:
_fileTransferWindowId = null;
break;
case WindowType.PortForward:
_portForwardWindowId = null;
break;
case WindowType.Unknown:
break;
}
}
void setMethodHandler( void setMethodHandler(
Future<dynamic> Function(MethodCall call, int fromWindowId)? handler) { Future<dynamic> Function(MethodCall call, int fromWindowId)? handler) {
DesktopMultiWindow.setMethodHandler(handler); DesktopMultiWindow.setMethodHandler(handler);
@ -186,8 +204,11 @@ class RustDeskMultiWindowManager {
} }
await WindowController.fromWindowId(wId).setPreventClose(false); await WindowController.fromWindowId(wId).setPreventClose(false);
await WindowController.fromWindowId(wId).close(); await WindowController.fromWindowId(wId).close();
} on Error { } catch (e) {
debugPrint("$e");
return; return;
} finally {
clearWindowType(type);
} }
} }
} }

View File

@ -31,4 +31,10 @@ class RdPlatformChannel {
return _osxMethodChannel return _osxMethodChannel
.invokeMethod("setWindowTheme", {"themeName": theme.name}); .invokeMethod("setWindowTheme", {"themeName": theme.name});
} }
/// Terminate .app manually.
Future<void> terminate() {
assert(Platform.isMacOS);
return _osxMethodChannel.invokeMethod("terminate");
}
} }

View File

@ -3,21 +3,22 @@ import FlutterMacOS
@NSApplicationMain @NSApplicationMain
class AppDelegate: FlutterAppDelegate { class AppDelegate: FlutterAppDelegate {
var lauched = false; var launched = false;
override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
dummy_method_to_enforce_bundling() dummy_method_to_enforce_bundling()
return true // https://github.com/leanflutter/window_manager/issues/214
return false
} }
override func applicationShouldOpenUntitledFile(_ sender: NSApplication) -> Bool { override func applicationShouldOpenUntitledFile(_ sender: NSApplication) -> Bool {
if (lauched) { if (launched) {
handle_applicationShouldOpenUntitledFile(); handle_applicationShouldOpenUntitledFile();
} }
return true return true
} }
override func applicationDidFinishLaunching(_ aNotification: Notification) { override func applicationDidFinishLaunching(_ aNotification: Notification) {
lauched = true; launched = true;
NSApplication.shared.activate(ignoringOtherApps: true); NSApplication.shared.activate(ignoringOtherApps: true);
} }
} }

View File

@ -23,8 +23,10 @@
<dict> <dict>
<key>CFBundleTypeRole</key> <key>CFBundleTypeRole</key>
<string>Editor</string> <string>Editor</string>
<key>CFBundleURLName</key> <key>CFBundleURLIconFile</key>
<string></string> <string></string>
<key>CFBundleURLName</key>
<string>com.carriez.rustdesk</string>
<key>CFBundleURLSchemes</key> <key>CFBundleURLSchemes</key>
<array> <array>
<string>rustdesk</string> <string>rustdesk</string>
@ -35,13 +37,13 @@
<string>$(FLUTTER_BUILD_NUMBER)</string> <string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string> <string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>LSUIElement</key>
<string>1</string>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>$(PRODUCT_COPYRIGHT)</string> <string>$(PRODUCT_COPYRIGHT)</string>
<key>NSMainNibFile</key> <key>NSMainNibFile</key>
<string>MainMenu</string> <string>MainMenu</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>
<string>NSApplication</string> <string>NSApplication</string>
<key>LSUIElement</key>
<string>1</string>
</dict> </dict>
</plist> </plist>

View File

@ -78,6 +78,9 @@ class MainFlutterWindow: NSWindow {
self.setWindowInterfaceMode(window: window,themeName: themeName ?? "light") self.setWindowInterfaceMode(window: window,themeName: themeName ?? "light")
result(nil) result(nil)
break; break;
case "terminate":
NSApplication.shared.terminate(self)
result(nil)
default: default:
result(FlutterMethodNotImplemented) result(FlutterMethodNotImplemented)
} }