Restore window placement on startup

This commit is contained in:
wgh19
2024-05-22 12:49:58 +08:00
parent 471b319891
commit de26cba0fa
4 changed files with 100 additions and 15 deletions

View File

@@ -12,7 +12,9 @@ import "package:pixes/foundation/log.dart";
import "package:pixes/network/app_dio.dart"; import "package:pixes/network/app_dio.dart";
import "package:pixes/pages/main_page.dart"; import "package:pixes/pages/main_page.dart";
import "package:pixes/utils/app_links.dart"; import "package:pixes/utils/app_links.dart";
import "package:pixes/utils/loop.dart";
import "package:pixes/utils/translation.dart"; import "package:pixes/utils/translation.dart";
import "package:pixes/utils/window.dart";
import "package:window_manager/window_manager.dart"; import "package:window_manager/window_manager.dart";
void main() async { void main() async {
@@ -33,10 +35,13 @@ void main() async {
windowButtonVisibility: false, windowButtonVisibility: false,
); );
await windowManager.setMinimumSize(const Size(500, 600)); await windowManager.setMinimumSize(const Size(500, 600));
var placement = await WindowPlacement.loadFromFile();
await placement.applyToWindow();
await windowManager.show(); await windowManager.show();
await windowManager.setSkipTaskbar(false); Loop.register(WindowPlacement.loop);
}); });
} }
Loop.start();
runApp(const MyApp()); runApp(const MyApp());
} }

View File

@@ -20,6 +20,7 @@ import "package:pixes/pages/login_page.dart";
import "package:pixes/pages/search_page.dart"; import "package:pixes/pages/search_page.dart";
import "package:pixes/pages/settings_page.dart"; import "package:pixes/pages/settings_page.dart";
import "package:pixes/pages/user_info_page.dart"; import "package:pixes/pages/user_info_page.dart";
import "package:pixes/utils/loop.dart";
import "package:pixes/utils/mouse_listener.dart"; import "package:pixes/utils/mouse_listener.dart";
import "package:pixes/utils/translation.dart"; import "package:pixes/utils/translation.dart";
import "package:window_manager/window_manager.dart"; import "package:window_manager/window_manager.dart";
@@ -327,28 +328,22 @@ class _BackButtonState extends State<_BackButton> {
@override @override
void initState() { void initState() {
enabled = navigatorKey.currentState?.canPop() == true; enabled = navigatorKey.currentState?.canPop() == true;
loop(); Loop.register(loop);
super.initState(); super.initState();
} }
void loop() { void loop() {
timer = Timer.periodic(const Duration(milliseconds: 100), (timer) { bool enabled = navigatorKey.currentState?.canPop() == true;
if (!mounted) { if (enabled != this.enabled) {
timer.cancel(); setState(() {
} else { this.enabled = enabled;
bool enabled = navigatorKey.currentState?.canPop() == true; });
if (enabled != this.enabled) { }
setState(() {
this.enabled = enabled;
});
}
}
});
} }
@override @override
void dispose() { void dispose() {
timer?.cancel(); Loop.remove(loop);
super.dispose(); super.dispose();
} }

21
lib/utils/loop.dart Normal file
View File

@@ -0,0 +1,21 @@
import 'dart:async';
class Loop {
static final List<void Function()> _callbacks = [];
static void start() {
Timer.periodic(const Duration(milliseconds: 100), (timer) {
for(var func in _callbacks) {
func.call();
}
});
}
static void register(void Function() func) {
_callbacks.add(func);
}
static void remove(void Function() func) {
_callbacks.remove(func);
}
}

64
lib/utils/window.dart Normal file
View File

@@ -0,0 +1,64 @@
import 'dart:convert';
import 'dart:ui';
import 'dart:io';
import 'package:pixes/foundation/app.dart';
import 'package:window_manager/window_manager.dart';
class WindowPlacement {
final Rect rect;
final bool isMaximized;
const WindowPlacement(this.rect, this.isMaximized);
Future<void> applyToWindow() async {
await windowManager.setBounds(rect);
if (isMaximized) {
await windowManager.maximize();
}
}
Future<void> writeToFile() async {
var file = File("${App.dataPath}/window_placement");
await file.writeAsString(jsonEncode({
'width': rect.width,
'height': rect.height,
'x': rect.topLeft.dx,
'y': rect.topLeft.dy,
'isMaximized': isMaximized
}));
}
static Future<WindowPlacement> loadFromFile() async {
var file = File("${App.dataPath}/window_placement");
if (!file.existsSync()) {
return defaultPlacement;
}
var json = jsonDecode(await file.readAsString());
var rect =
Rect.fromLTWH(json['x'], json['y'], json['width'], json['height']);
return WindowPlacement(rect, json['isMaximized']);
}
static Future<WindowPlacement> get current async {
var rect = await windowManager.getBounds();
var isMaximized = await windowManager.isMaximized();
return WindowPlacement(rect, isMaximized);
}
static const defaultPlacement =
WindowPlacement(Rect.fromLTWH(10, 10, 900, 600), false);
static WindowPlacement cache = defaultPlacement;
static void loop() async {
var placement = await WindowPlacement.current;
if (placement.rect != cache.rect ||
placement.isMaximized != cache.isMaximized) {
cache = placement;
await placement.writeToFile();
}
}
}