diff --git a/lib/main.dart b/lib/main.dart index 394fbde..3f5bad3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -12,7 +12,9 @@ import "package:pixes/foundation/log.dart"; import "package:pixes/network/app_dio.dart"; import "package:pixes/pages/main_page.dart"; import "package:pixes/utils/app_links.dart"; +import "package:pixes/utils/loop.dart"; import "package:pixes/utils/translation.dart"; +import "package:pixes/utils/window.dart"; import "package:window_manager/window_manager.dart"; void main() async { @@ -33,10 +35,13 @@ void main() async { windowButtonVisibility: false, ); await windowManager.setMinimumSize(const Size(500, 600)); + var placement = await WindowPlacement.loadFromFile(); + await placement.applyToWindow(); await windowManager.show(); - await windowManager.setSkipTaskbar(false); + Loop.register(WindowPlacement.loop); }); } + Loop.start(); runApp(const MyApp()); } diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 6f97af0..d2c5150 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -20,6 +20,7 @@ import "package:pixes/pages/login_page.dart"; import "package:pixes/pages/search_page.dart"; import "package:pixes/pages/settings_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/translation.dart"; import "package:window_manager/window_manager.dart"; @@ -327,28 +328,22 @@ class _BackButtonState extends State<_BackButton> { @override void initState() { enabled = navigatorKey.currentState?.canPop() == true; - loop(); + Loop.register(loop); super.initState(); } void loop() { - timer = Timer.periodic(const Duration(milliseconds: 100), (timer) { - if (!mounted) { - timer.cancel(); - } else { - bool enabled = navigatorKey.currentState?.canPop() == true; - if (enabled != this.enabled) { - setState(() { - this.enabled = enabled; - }); - } - } - }); + bool enabled = navigatorKey.currentState?.canPop() == true; + if (enabled != this.enabled) { + setState(() { + this.enabled = enabled; + }); + } } @override void dispose() { - timer?.cancel(); + Loop.remove(loop); super.dispose(); } diff --git a/lib/utils/loop.dart b/lib/utils/loop.dart new file mode 100644 index 0000000..1bc60e0 --- /dev/null +++ b/lib/utils/loop.dart @@ -0,0 +1,21 @@ +import 'dart:async'; + +class Loop { + static final List _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); + } +} \ No newline at end of file diff --git a/lib/utils/window.dart b/lib/utils/window.dart new file mode 100644 index 0000000..1235f96 --- /dev/null +++ b/lib/utils/window.dart @@ -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 applyToWindow() async { + await windowManager.setBounds(rect); + + if (isMaximized) { + await windowManager.maximize(); + } + } + + Future 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 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 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(); + } + } +}