restoreWindowPosition for sub window and add restore maximize

This commit is contained in:
csf 2022-10-14 19:48:41 +09:00
parent cf73c04cb3
commit c01b9d5d7d
6 changed files with 89 additions and 42 deletions

View File

@ -38,7 +38,6 @@ var isWeb = false;
var isWebDesktop = false; var isWebDesktop = false;
var version = ""; var version = "";
int androidVersion = 0; int androidVersion = 0;
const windowPrefix = "wm_";
DesktopType? desktopType; DesktopType? desktopType;
typedef F = String Function(String); typedef F = String Function(String);
@ -957,16 +956,18 @@ class LastWindowPosition {
double? height; double? height;
double? offsetWidth; double? offsetWidth;
double? offsetHeight; double? offsetHeight;
bool? isMaximized;
LastWindowPosition( LastWindowPosition(this.width, this.height, this.offsetWidth,
this.width, this.height, this.offsetWidth, this.offsetHeight); this.offsetHeight, this.isMaximized);
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
return <String, dynamic>{ return <String, dynamic>{
"width": width, "width": width,
"height": height, "height": height,
"offsetWidth": offsetWidth, "offsetWidth": offsetWidth,
"offsetHeight": offsetHeight "offsetHeight": offsetHeight,
"isMaximized": isMaximized,
}; };
} }
@ -981,8 +982,8 @@ class LastWindowPosition {
} }
try { try {
final m = jsonDecode(content); final m = jsonDecode(content);
return LastWindowPosition( return LastWindowPosition(m["width"], m["height"], m["offsetWidth"],
m["width"], m["height"], m["offsetWidth"], m["offsetHeight"]); m["offsetHeight"], m["isMaximized"]);
} catch (e) { } catch (e) {
debugPrint(e.toString()); debugPrint(e.toString());
return null; return null;
@ -999,22 +1000,29 @@ Future<void> saveWindowPosition(WindowType type, {int? windowId}) async {
} }
switch (type) { switch (type) {
case WindowType.Main: case WindowType.Main:
List resp = await Future.wait( final position = await windowManager.getPosition();
[windowManager.getPosition(), windowManager.getSize()]); final sz = await windowManager.getSize();
Offset position = resp[0]; final isMaximized = await windowManager.isMaximized();
Size sz = resp[1]; final pos = LastWindowPosition(
final pos = sz.width, sz.height, position.dx, position.dy, isMaximized);
LastWindowPosition(sz.width, sz.height, position.dx, position.dy);
await Get.find<SharedPreferences>() await Get.find<SharedPreferences>()
.setString(windowPrefix + type.name, pos.toString()); .setString(kWindowPrefix + type.name, pos.toString());
break; break;
default: 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<SharedPreferences>()
.setString(kWindowPrefix + type.name, pos.toString());
break; break;
} }
} }
_adjustRestoreMainWindowSize(double? width, double? height) async { Future<Size> _adjustRestoreMainWindowSize(double? width, double? height) async {
const double minWidth = 600; const double minWidth = 600;
const double minHeight = 100; const double minHeight = 100;
double maxWidth = (((isDesktop || isWebDesktop) double maxWidth = (((isDesktop || isWebDesktop)
@ -1055,10 +1063,12 @@ _adjustRestoreMainWindowSize(double? width, double? height) async {
if (restoreHeight > maxHeight) { if (restoreHeight > maxHeight) {
restoreWidth = maxHeight; restoreWidth = maxHeight;
} }
await windowManager.setSize(Size(restoreWidth, restoreHeight)); return Size(restoreWidth, restoreHeight);
} }
_adjustRestoreMainWindowOffset(double? left, double? top) async { /// return null means center
Future<Offset?> _adjustRestoreMainWindowOffset(
double? left, double? top) async {
if (left == null || top == null) { if (left == null || top == null) {
await windowManager.center(); await windowManager.center();
} else { } else {
@ -1090,24 +1100,24 @@ _adjustRestoreMainWindowOffset(double? left, double? top) async {
windowLeft > frameRight || windowLeft > frameRight ||
windowTop < frameTop || windowTop < frameTop ||
windowTop > frameBottom) { windowTop > frameBottom) {
await windowManager.center(); return null;
} else { } 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 /// Note that windowId must be provided if it's subwindow
Future<bool> restoreWindowPosition(WindowType type, {int? windowId}) async { Future<bool> restoreWindowPosition(WindowType type, {int? windowId}) async {
if (type != WindowType.Main && windowId == null) { if (type != WindowType.Main && windowId == null) {
debugPrint( debugPrint(
"Error: windowId cannot be null when saving positions for sub window"); "Error: windowId cannot be null when saving positions for sub window");
} }
switch (type) { final pos =
case WindowType.Main: Get.find<SharedPreferences>().getString(kWindowPrefix + type.name);
var pos =
Get.find<SharedPreferences>().getString(windowPrefix + type.name);
if (pos == null) { if (pos == null) {
debugPrint("no window position saved, ignore restore"); debugPrint("no window position saved, ignore restore");
return false; return false;
@ -1118,12 +1128,40 @@ Future<bool> restoreWindowPosition(WindowType type, {int? windowId}) async {
return false; return false;
} }
switch (type) {
case WindowType.Main:
if (lpos.isMaximized == true) {
await windowManager.maximize();
} else {
final size =
await _adjustRestoreMainWindowSize(lpos.width, lpos.height); await _adjustRestoreMainWindowSize(lpos.width, lpos.height);
await _adjustRestoreMainWindowOffset(lpos.offsetWidth, lpos.offsetHeight); final offset = await _adjustRestoreMainWindowOffset(
lpos.offsetWidth, lpos.offsetHeight);
await windowManager.setSize(size);
if (offset == null) {
await windowManager.center();
} else {
await windowManager.setPosition(offset);
}
}
return true; return true;
default: 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; break;
} }
return false; return false;

View File

@ -15,6 +15,8 @@ const String kActionNewConnection = "connection/new/";
const String kTabLabelHomePage = "Home"; const String kTabLabelHomePage = "Home";
const String kTabLabelSettingPage = "Settings"; const String kTabLabelSettingPage = "Settings";
const String kWindowPrefix = "wm_";
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;

View File

@ -387,10 +387,8 @@ class WindowActionPanelState extends State<WindowActionPanel>
DesktopMultiWindow.addListener(this); DesktopMultiWindow.addListener(this);
windowManager.addListener(this); windowManager.addListener(this);
// TODO init window can't detect isMaximized
if (widget.mainTab) { if (widget.mainTab) {
windowManager.isMaximized().then((maximized) { windowManager.isMaximized().then((maximized) {
debugPrint("init main maximized: $maximized");
if (isMaximized != maximized) { if (isMaximized != maximized) {
WidgetsBinding.instance.addPostFrameCallback( WidgetsBinding.instance.addPostFrameCallback(
(_) => setState(() => isMaximized = maximized)); (_) => setState(() => isMaximized = maximized));
@ -399,7 +397,6 @@ class WindowActionPanelState extends State<WindowActionPanel>
} else { } else {
final wc = WindowController.fromWindowId(windowId!); final wc = WindowController.fromWindowId(windowId!);
wc.isMaximized().then((maximized) { wc.isMaximized().then((maximized) {
debugPrint("init sun maximized: $maximized");
if (isMaximized != maximized) { if (isMaximized != maximized) {
WidgetsBinding.instance.addPostFrameCallback( WidgetsBinding.instance.addPostFrameCallback(
(_) => setState(() => isMaximized = maximized)); (_) => setState(() => isMaximized = maximized));
@ -433,6 +430,12 @@ class WindowActionPanelState extends State<WindowActionPanel>
super.onWindowUnmaximize(); super.onWindowUnmaximize();
} }
@override
void onWindowClose() {
debugPrint("onWindowClose : is Main : ${widget.mainTab}");
super.onWindowClose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Row( return Row(

View File

@ -45,7 +45,6 @@ Future<void> main(List<String> args) async {
int type = argument['type'] ?? -1; int type = argument['type'] ?? -1;
argument['windowId'] = windowId; argument['windowId'] = windowId;
WindowType wType = type.windowType; WindowType wType = type.windowType;
restoreWindowPosition(wType, windowId: windowId);
switch (wType) { switch (wType) {
case WindowType.RemoteDesktop: case WindowType.RemoteDesktop:
desktopType = DesktopType.remote; desktopType = DesktopType.remote;
@ -118,6 +117,7 @@ void runMobileApp() async {
void runRemoteScreen(Map<String, dynamic> argument) async { void runRemoteScreen(Map<String, dynamic> argument) async {
await initEnv(kAppTypeDesktopRemote); await initEnv(kAppTypeDesktopRemote);
await restoreWindowPosition(WindowType.RemoteDesktop, windowId: windowId);
runApp(GetMaterialApp( runApp(GetMaterialApp(
navigatorKey: globalKey, navigatorKey: globalKey,
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
@ -143,6 +143,7 @@ void runRemoteScreen(Map<String, dynamic> argument) async {
void runFileTransferScreen(Map<String, dynamic> argument) async { void runFileTransferScreen(Map<String, dynamic> argument) async {
await initEnv(kAppTypeDesktopFileTransfer); await initEnv(kAppTypeDesktopFileTransfer);
await restoreWindowPosition(WindowType.FileTransfer, windowId: windowId);
runApp( runApp(
GetMaterialApp( GetMaterialApp(
navigatorKey: globalKey, navigatorKey: globalKey,
@ -168,6 +169,7 @@ void runFileTransferScreen(Map<String, dynamic> argument) async {
void runPortForwardScreen(Map<String, dynamic> argument) async { void runPortForwardScreen(Map<String, dynamic> argument) async {
await initEnv(kAppTypeDesktopPortForward); await initEnv(kAppTypeDesktopPortForward);
await restoreWindowPosition(WindowType.PortForward, windowId: windowId);
runApp( runApp(
GetMaterialApp( GetMaterialApp(
navigatorKey: globalKey, navigatorKey: globalKey,

View File

@ -3,6 +3,7 @@ import 'dart:convert';
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/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_hbb/common.dart';
/// must keep the order /// must keep the order
enum WindowType { Main, RemoteDesktop, FileTransfer, PortForward, Unknown } enum WindowType { Main, RemoteDesktop, FileTransfer, PortForward, Unknown }
@ -153,6 +154,7 @@ class RustDeskMultiWindowManager {
int? wId = findWindowByType(type); int? wId = findWindowByType(type);
if (wId != null) { if (wId != null) {
debugPrint("closing multi window: ${type.toString()}"); debugPrint("closing multi window: ${type.toString()}");
saveWindowPosition(type, windowId: wId);
try { try {
final ids = await DesktopMultiWindow.getAllSubWindowIds(); final ids = await DesktopMultiWindow.getAllSubWindowIds();
if (!ids.contains(wId)) { if (!ids.contains(wId)) {

View File

@ -243,8 +243,8 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
path: "." path: "."
ref: c09d65018f402dd0d6073149fe6705185101a270 ref: f25487b8aacfcc9d22b86a84e97eda1a5c07ccaf
resolved-ref: c09d65018f402dd0d6073149fe6705185101a270 resolved-ref: f25487b8aacfcc9d22b86a84e97eda1a5c07ccaf
url: "https://github.com/Kingtous/rustdesk_desktop_multi_window" url: "https://github.com/Kingtous/rustdesk_desktop_multi_window"
source: git source: git
version: "0.1.0" version: "0.1.0"