Merge pull request #3062 from Kingtous/master
fix: --connect command on macOS & window closing issues
This commit is contained in:
commit
a9b5739221
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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";
|
||||||
|
@ -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.
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user