From c01b9d5d7d846ab8b5d99daa24ad8b1524060411 Mon Sep 17 00:00:00 2001 From: csf Date: Fri, 14 Oct 2022 19:48:41 +0900 Subject: [PATCH] restoreWindowPosition for sub window and add restore maximize --- flutter/lib/common.dart | 110 ++++++++++++------ flutter/lib/consts.dart | 2 + .../lib/desktop/widgets/tabbar_widget.dart | 9 +- flutter/lib/main.dart | 4 +- flutter/lib/utils/multi_window_manager.dart | 2 + flutter/pubspec.lock | 4 +- 6 files changed, 89 insertions(+), 42 deletions(-) diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 890feac6b..6e32ad09c 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -38,7 +38,6 @@ var isWeb = false; var isWebDesktop = false; var version = ""; int androidVersion = 0; -const windowPrefix = "wm_"; DesktopType? desktopType; typedef F = String Function(String); @@ -957,16 +956,18 @@ class LastWindowPosition { double? height; double? offsetWidth; double? offsetHeight; + bool? isMaximized; - LastWindowPosition( - this.width, this.height, this.offsetWidth, this.offsetHeight); + LastWindowPosition(this.width, this.height, this.offsetWidth, + this.offsetHeight, this.isMaximized); Map toJson() { return { "width": width, "height": height, "offsetWidth": offsetWidth, - "offsetHeight": offsetHeight + "offsetHeight": offsetHeight, + "isMaximized": isMaximized, }; } @@ -981,8 +982,8 @@ class LastWindowPosition { } try { final m = jsonDecode(content); - return LastWindowPosition( - m["width"], m["height"], m["offsetWidth"], m["offsetHeight"]); + return LastWindowPosition(m["width"], m["height"], m["offsetWidth"], + m["offsetHeight"], m["isMaximized"]); } catch (e) { debugPrint(e.toString()); return null; @@ -999,22 +1000,29 @@ Future saveWindowPosition(WindowType type, {int? windowId}) async { } switch (type) { case WindowType.Main: - List resp = await Future.wait( - [windowManager.getPosition(), windowManager.getSize()]); - Offset position = resp[0]; - Size sz = resp[1]; - final pos = - LastWindowPosition(sz.width, sz.height, position.dx, position.dy); + final position = await windowManager.getPosition(); + final sz = await windowManager.getSize(); + final isMaximized = await windowManager.isMaximized(); + final pos = LastWindowPosition( + sz.width, sz.height, position.dx, position.dy, isMaximized); await Get.find() - .setString(windowPrefix + type.name, pos.toString()); + .setString(kWindowPrefix + type.name, pos.toString()); break; default: - // TODO: implement window + final wc = WindowController.fromWindowId(windowId!); + final frame = await wc.getFrame(); + final position = frame.topLeft; + final sz = frame.size; + final isMaximized = await wc.isMaximized(); + final pos = LastWindowPosition( + sz.width, sz.height, position.dx, position.dy, isMaximized); + await Get.find() + .setString(kWindowPrefix + type.name, pos.toString()); break; } } -_adjustRestoreMainWindowSize(double? width, double? height) async { +Future _adjustRestoreMainWindowSize(double? width, double? height) async { const double minWidth = 600; const double minHeight = 100; double maxWidth = (((isDesktop || isWebDesktop) @@ -1055,10 +1063,12 @@ _adjustRestoreMainWindowSize(double? width, double? height) async { if (restoreHeight > maxHeight) { restoreWidth = maxHeight; } - await windowManager.setSize(Size(restoreWidth, restoreHeight)); + return Size(restoreWidth, restoreHeight); } -_adjustRestoreMainWindowOffset(double? left, double? top) async { +/// return null means center +Future _adjustRestoreMainWindowOffset( + double? left, double? top) async { if (left == null || top == null) { await windowManager.center(); } else { @@ -1090,40 +1100,68 @@ _adjustRestoreMainWindowOffset(double? left, double? top) async { windowLeft > frameRight || windowTop < frameTop || windowTop > frameBottom) { - await windowManager.center(); + return null; } else { - await windowManager.setPosition(Offset(windowLeft, windowTop)); + return Offset(windowLeft, windowTop); } } + return null; } -/// Save window position and size on exit +/// Restore window position and size on start /// Note that windowId must be provided if it's subwindow Future restoreWindowPosition(WindowType type, {int? windowId}) async { if (type != WindowType.Main && windowId == null) { debugPrint( "Error: windowId cannot be null when saving positions for sub window"); } + final pos = + Get.find().getString(kWindowPrefix + type.name); + + if (pos == null) { + debugPrint("no window position saved, ignore restore"); + return false; + } + var lpos = LastWindowPosition.loadFromString(pos); + if (lpos == null) { + debugPrint("window position saved, but cannot be parsed"); + return false; + } + switch (type) { case WindowType.Main: - var pos = - Get.find().getString(windowPrefix + type.name); - if (pos == null) { - debugPrint("no window position saved, ignore restore"); - return false; + if (lpos.isMaximized == true) { + await windowManager.maximize(); + } else { + final size = + await _adjustRestoreMainWindowSize(lpos.width, lpos.height); + final offset = await _adjustRestoreMainWindowOffset( + lpos.offsetWidth, lpos.offsetHeight); + await windowManager.setSize(size); + if (offset == null) { + await windowManager.center(); + } else { + await windowManager.setPosition(offset); + } } - var lpos = LastWindowPosition.loadFromString(pos); - if (lpos == null) { - debugPrint("window position saved, but cannot be parsed"); - return false; - } - - await _adjustRestoreMainWindowSize(lpos.width, lpos.height); - await _adjustRestoreMainWindowOffset(lpos.offsetWidth, lpos.offsetHeight); - return true; default: - // TODO: implement subwindow + final wc = WindowController.fromWindowId(windowId!); + if (lpos.isMaximized == true) { + await wc.maximize(); + } else { + final size = + await _adjustRestoreMainWindowSize(lpos.width, lpos.height); + final offset = await _adjustRestoreMainWindowOffset( + lpos.offsetWidth, lpos.offsetHeight); + if (offset == null) { + await wc.center(); + } else { + final frame = + Rect.fromLTWH(offset.dx, offset.dy, size.width, size.height); + await wc.setFrame(frame); + } + } break; } return false; @@ -1150,7 +1188,7 @@ void checkArguments() { } /// Parse `rustdesk://` unilinks -/// +/// /// [Functions] /// 1. New Connection: rustdesk://connection/new/your_peer_id void parseRustdeskUri(String uriPath) { diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart index 056cc000c..f43c20cc6 100644 --- a/flutter/lib/consts.dart +++ b/flutter/lib/consts.dart @@ -15,6 +15,8 @@ const String kActionNewConnection = "connection/new/"; const String kTabLabelHomePage = "Home"; const String kTabLabelSettingPage = "Settings"; +const String kWindowPrefix = "wm_"; + const Color kColorWarn = Color.fromARGB(255, 245, 133, 59); const int kMobileDefaultDisplayWidth = 720; diff --git a/flutter/lib/desktop/widgets/tabbar_widget.dart b/flutter/lib/desktop/widgets/tabbar_widget.dart index d92af9447..b11ded495 100644 --- a/flutter/lib/desktop/widgets/tabbar_widget.dart +++ b/flutter/lib/desktop/widgets/tabbar_widget.dart @@ -387,10 +387,8 @@ class WindowActionPanelState extends State DesktopMultiWindow.addListener(this); windowManager.addListener(this); - // TODO init window can't detect isMaximized if (widget.mainTab) { windowManager.isMaximized().then((maximized) { - debugPrint("init main maximized: $maximized"); if (isMaximized != maximized) { WidgetsBinding.instance.addPostFrameCallback( (_) => setState(() => isMaximized = maximized)); @@ -399,7 +397,6 @@ class WindowActionPanelState extends State } else { final wc = WindowController.fromWindowId(windowId!); wc.isMaximized().then((maximized) { - debugPrint("init sun maximized: $maximized"); if (isMaximized != maximized) { WidgetsBinding.instance.addPostFrameCallback( (_) => setState(() => isMaximized = maximized)); @@ -433,6 +430,12 @@ class WindowActionPanelState extends State super.onWindowUnmaximize(); } + @override + void onWindowClose() { + debugPrint("onWindowClose : is Main : ${widget.mainTab}"); + super.onWindowClose(); + } + @override Widget build(BuildContext context) { return Row( diff --git a/flutter/lib/main.dart b/flutter/lib/main.dart index 43f4b9c24..835606eb1 100644 --- a/flutter/lib/main.dart +++ b/flutter/lib/main.dart @@ -45,7 +45,6 @@ Future main(List args) async { int type = argument['type'] ?? -1; argument['windowId'] = windowId; WindowType wType = type.windowType; - restoreWindowPosition(wType, windowId: windowId); switch (wType) { case WindowType.RemoteDesktop: desktopType = DesktopType.remote; @@ -118,6 +117,7 @@ void runMobileApp() async { void runRemoteScreen(Map argument) async { await initEnv(kAppTypeDesktopRemote); + await restoreWindowPosition(WindowType.RemoteDesktop, windowId: windowId); runApp(GetMaterialApp( navigatorKey: globalKey, debugShowCheckedModeBanner: false, @@ -143,6 +143,7 @@ void runRemoteScreen(Map argument) async { void runFileTransferScreen(Map argument) async { await initEnv(kAppTypeDesktopFileTransfer); + await restoreWindowPosition(WindowType.FileTransfer, windowId: windowId); runApp( GetMaterialApp( navigatorKey: globalKey, @@ -168,6 +169,7 @@ void runFileTransferScreen(Map argument) async { void runPortForwardScreen(Map argument) async { await initEnv(kAppTypeDesktopPortForward); + await restoreWindowPosition(WindowType.PortForward, windowId: windowId); runApp( GetMaterialApp( navigatorKey: globalKey, diff --git a/flutter/lib/utils/multi_window_manager.dart b/flutter/lib/utils/multi_window_manager.dart index 97d5a5e23..8fd71540d 100644 --- a/flutter/lib/utils/multi_window_manager.dart +++ b/flutter/lib/utils/multi_window_manager.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'package:desktop_multi_window/desktop_multi_window.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_hbb/common.dart'; /// must keep the order enum WindowType { Main, RemoteDesktop, FileTransfer, PortForward, Unknown } @@ -153,6 +154,7 @@ class RustDeskMultiWindowManager { int? wId = findWindowByType(type); if (wId != null) { debugPrint("closing multi window: ${type.toString()}"); + saveWindowPosition(type, windowId: wId); try { final ids = await DesktopMultiWindow.getAllSubWindowIds(); if (!ids.contains(wId)) { diff --git a/flutter/pubspec.lock b/flutter/pubspec.lock index d5f46f2f6..4b78bab93 100644 --- a/flutter/pubspec.lock +++ b/flutter/pubspec.lock @@ -243,8 +243,8 @@ packages: dependency: "direct main" description: path: "." - ref: c09d65018f402dd0d6073149fe6705185101a270 - resolved-ref: c09d65018f402dd0d6073149fe6705185101a270 + ref: f25487b8aacfcc9d22b86a84e97eda1a5c07ccaf + resolved-ref: f25487b8aacfcc9d22b86a84e97eda1a5c07ccaf url: "https://github.com/Kingtous/rustdesk_desktop_multi_window" source: git version: "0.1.0"