Merge pull request #1550 from Kingtous/master

opt: main window save/restore offset/position
This commit is contained in:
RustDesk 2022-09-16 14:38:52 +08:00 committed by GitHub
commit 723f731a20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 113 additions and 7 deletions

View File

@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'dart:typed_data'; import 'dart:typed_data';
import 'dart:ui';
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';
@ -10,6 +11,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart'; import 'package:flutter_hbb/desktop/widgets/tabbar_widget.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:get/get.dart'; import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:window_manager/window_manager.dart'; import 'package:window_manager/window_manager.dart';
@ -28,6 +30,7 @@ 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);
@ -821,8 +824,6 @@ Future<void> initGlobalFFI() async {
debugPrint("_globalFFI init end"); debugPrint("_globalFFI init end");
// after `put`, can also be globally found by Get.find<FFI>(); // after `put`, can also be globally found by Get.find<FFI>();
Get.put(_globalFFI, permanent: true); Get.put(_globalFFI, permanent: true);
// global shared preference
await Get.putAsync(() => SharedPreferences.getInstance());
} }
String translate(String name) { String translate(String name) {
@ -909,3 +910,100 @@ Widget getPlatformImage(String platform, {double size = 50}) {
} }
return Image.asset('assets/$platform.png', height: size, width: size); return Image.asset('assets/$platform.png', height: size, width: size);
} }
class LastWindowPosition {
double? width;
double? height;
double? offsetWidth;
double? offsetHeight;
LastWindowPosition(
this.width, this.height, this.offsetWidth, this.offsetHeight);
Map<String, dynamic> toJson() {
return <String, dynamic>{
"width": width,
"height": height,
"offsetWidth": offsetWidth,
"offsetHeight": offsetHeight
};
}
@override
String toString() {
return jsonEncode(toJson());
}
static LastWindowPosition? loadFromString(String content) {
if (content.isEmpty) {
return null;
}
try {
final m = jsonDecode(content);
return LastWindowPosition(
m["width"], m["height"], m["offsetWidth"], m["offsetHeight"]);
} catch (e) {
debugPrint(e.toString());
return null;
}
}
}
/// Save window position and size on exit
/// Note that windowId must be provided if it's subwindow
Future<void> saveWindowPosition(WindowType type, {int? windowId}) async {
if (type != WindowType.Main && windowId == null) {
debugPrint(
"Error: windowId cannot be null when saving positions for sub window");
}
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);
await Get.find<SharedPreferences>()
.setString(windowPrefix + type.name, pos.toString());
break;
default:
// TODO: implement window
break;
}
}
/// Save window position and size on exit
/// Note that windowId must be provided if it's subwindow
Future<bool> restoreWindowPosition(WindowType type, {int? windowId}) async {
if (type != WindowType.Main && windowId == null) {
debugPrint(
"Error: windowId cannot be null when saving positions for sub window");
}
switch (type) {
case WindowType.Main:
var pos =
Get.find<SharedPreferences>().getString(windowPrefix + 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;
}
await windowManager.setSize(Size(lpos.width ?? 1280, lpos.height ?? 720));
if (lpos.offsetWidth == null || lpos.offsetHeight == null) {
await windowManager.center();
} else {
await windowManager
.setPosition(Offset(lpos.offsetWidth!, lpos.offsetHeight!));
}
return true;
default:
// TODO: implement subwindow
break;
}
return false;
}

View File

@ -46,7 +46,10 @@ class _DesktopHomePageState extends State<DesktopHomePage>
// close all sub windows // close all sub windows
if (await windowManager.isPreventClose()) { if (await windowManager.isPreventClose()) {
try { try {
await rustDeskWinManager.closeAllSubWindows(); await Future.wait([
saveWindowPosition(WindowType.Main),
rustDeskWinManager.closeAllSubWindows()
]);
} catch (err) { } catch (err) {
debugPrint("$err"); debugPrint("$err");
} finally { } finally {

View File

@ -10,6 +10,7 @@ import 'package:flutter_hbb/desktop/screen/desktop_remote_screen.dart';
import 'package:flutter_hbb/utils/multi_window_manager.dart'; import 'package:flutter_hbb/utils/multi_window_manager.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:window_manager/window_manager.dart'; import 'package:window_manager/window_manager.dart';
// import 'package:window_manager/window_manager.dart'; // import 'package:window_manager/window_manager.dart';
@ -41,6 +42,7 @@ Future<Null> 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;
@ -71,6 +73,8 @@ Future<Null> main(List<String> args) async {
} }
Future<void> initEnv(String appType) async { Future<void> initEnv(String appType) async {
// global shared preference
await Get.putAsync(() => SharedPreferences.getInstance());
await platformFFI.init(appType); await platformFFI.init(appType);
// global FFI, use this **ONLY** for global configuration // global FFI, use this **ONLY** for global configuration
// for convenience, use global FFI on mobile platform // for convenience, use global FFI on mobile platform
@ -93,9 +97,9 @@ void runMainApp(bool startService) async {
} }
runApp(App()); runApp(App());
// set window option // set window option
WindowOptions windowOptions = WindowOptions windowOptions = getHiddenTitleBarWindowOptions();
getHiddenTitleBarWindowOptions(const Size(1280, 720));
windowManager.waitUntilReadyToShow(windowOptions, () async { windowManager.waitUntilReadyToShow(windowOptions, () async {
restoreWindowPosition(WindowType.Main);
await windowManager.show(); await windowManager.show();
await windowManager.focus(); await windowManager.focus();
}); });
@ -166,7 +170,8 @@ void runPortForwardScreen(Map<String, dynamic> argument) async {
void runConnectionManagerScreen() async { void runConnectionManagerScreen() async {
// initialize window // initialize window
WindowOptions windowOptions = getHiddenTitleBarWindowOptions(Size(300, 400)); WindowOptions windowOptions =
getHiddenTitleBarWindowOptions(size: const Size(300, 400));
await Future.wait([ await Future.wait([
initEnv(kAppTypeMain), initEnv(kAppTypeMain),
windowManager.waitUntilReadyToShow(windowOptions, () async { windowManager.waitUntilReadyToShow(windowOptions, () async {
@ -185,7 +190,7 @@ void runConnectionManagerScreen() async {
builder: _keepScaleBuilder())); builder: _keepScaleBuilder()));
} }
WindowOptions getHiddenTitleBarWindowOptions(Size size) { WindowOptions getHiddenTitleBarWindowOptions({Size? size}) {
return WindowOptions( return WindowOptions(
size: size, size: size,
center: true, center: true,