From 9e586254a786cdb91216f9c839ab7fe60b1fa1f1 Mon Sep 17 00:00:00 2001 From: Xmarmalade <16839488+Xmarmalade@users.noreply.github.com> Date: Tue, 13 Aug 2024 16:21:46 +0800 Subject: [PATCH] perf: Improve window dimensions handling and screen bounds check --- lib/provider/persistence_provider.dart | 27 ++++-- lib/provider/window_dimensions_provider.dart | 88 +++++++++++++------- 2 files changed, 77 insertions(+), 38 deletions(-) diff --git a/lib/provider/persistence_provider.dart b/lib/provider/persistence_provider.dart index 417ab86..bf4cbd1 100644 --- a/lib/provider/persistence_provider.dart +++ b/lib/provider/persistence_provider.dart @@ -98,18 +98,33 @@ class PersistenceService { await _prefs.setDouble(_windowWidth, width); } - WindowDimensions getWindowLastDimensions() { + WindowDimensions? getWindowLastDimensions() { Size? size; Offset? position; final offsetX = _prefs.getDouble(_windowOffsetX); final offsetY = _prefs.getDouble(_windowOffsetY); final width = _prefs.getDouble(_windowWidth); final height = _prefs.getDouble(_windowHeight); - if (width != null && height != null) size = Size(width, height); - if (offsetX != null && offsetY != null) position = Offset(offsetX, offsetY); - final dimensions = {"size": size, "position": position}; - return dimensions; + if (width != null && height != null) { + size = Size(width, height); + } + + if (offsetX != null && offsetY != null) { + if (offsetX < -2048 || offsetY < -2048) { + position = const Offset(0, 0); + } + position = Offset(offsetX, offsetY); + } + + if (size == null || position == null) { + return null; + } + + return WindowDimensions( + position: position, + size: size, + ); } Future setSaveWindowPlacement(bool savePlacement) async { @@ -157,7 +172,7 @@ class PersistenceService { } List getRcloneArgs() { - return _prefs.getStringList(_rcloneArgs) ?? ['rcd','--rc-web-gui']; + return _prefs.getStringList(_rcloneArgs) ?? ['rcd', '--rc-web-gui']; } Future setAutoStartRclone(bool value) async { diff --git a/lib/provider/window_dimensions_provider.dart b/lib/provider/window_dimensions_provider.dart index bcde799..cbbe46e 100644 --- a/lib/provider/window_dimensions_provider.dart +++ b/lib/provider/window_dimensions_provider.dart @@ -4,15 +4,22 @@ import 'package:alisthelper/provider/persistence_provider.dart'; import 'package:screen_retriever/screen_retriever.dart'; import 'package:window_manager/window_manager.dart'; -// Records are a better alternative, but they are currently experimental -typedef WindowDimensions = Map; +class WindowDimensions { + final Offset position; + final Size size; + + WindowDimensions({ + required this.position, + required this.size, + }); +} final windowDimensionProvider = Provider((ref) { - return WindowDimensionsController(ref.watch(persistenceProvider)); + return WindowDimensionsController(ref.read(persistenceProvider)); }); -const Size _minimalSize = Size(400, 600); -const Size _defaultSize = Size(1000, 600); +const Size _minimalSize = Size(400, 500); +const Size _defaultSize = Size(900, 600); class WindowDimensionsController { final PersistenceService _service; @@ -22,50 +29,67 @@ class WindowDimensionsController { /// Sets window position & size according to saved settings. Future initDimensionsConfiguration() async { await WindowManager.instance.setMinimumSize(_minimalSize); - final primaryDisplay = await ScreenRetriever.instance.getPrimaryDisplay(); - final hasEnoughWidth = (primaryDisplay.visibleSize ?? primaryDisplay.size).width >= 1200; // load saved Window placement and preferences final useSavedPlacement = _service.getSaveWindowPlacement(); final persistedDimensions = _service.getWindowLastDimensions(); - // if [savePlacement is false], both values will be [set to null] - final Size? persistedSize = useSavedPlacement ? persistedDimensions["size"] as Size? : null; - final Offset? persistedOffset = useSavedPlacement ? persistedDimensions["position"] as Offset? : null; - - // settings applied accordingly if [save option is enabled] and if [persisted values exist] - await WindowManager.instance.setSize(persistedSize ?? (hasEnoughWidth ? _defaultSize : _minimalSize)); - - if (persistedOffset == null) { - await WindowManager.instance.center(); + if (useSavedPlacement && + persistedDimensions != null && + await isInScreenBounds( + persistedDimensions.position, persistedDimensions.size)) { + await WindowManager.instance.setSize(persistedDimensions.size); + await WindowManager.instance.setPosition(persistedDimensions.position); } else { - await WindowManager.instance.setPosition(persistedOffset); + final primaryDisplay = await ScreenRetriever.instance.getPrimaryDisplay(); + final hasEnoughWidthForDefaultSize = + primaryDisplay.digestedSize.width >= 1200; + await WindowManager.instance + .setSize(hasEnoughWidthForDefaultSize ? _defaultSize : _minimalSize); + await WindowManager.instance.center(); } } + Future isInScreenBounds(Offset windowPosition, + [Size? windowSize]) async { + final displays = await ScreenRetriever.instance.getAllDisplays(); + final sumWidth = displays.fold(0.0, + (previousValue, element) => previousValue + element.digestedSize.width); + final maxHeight = displays.fold( + 0.0, + (previousValue, element) => previousValue > element.digestedSize.height + ? previousValue + : element.digestedSize.height, + ); + return windowPosition.dx + (windowSize?.width ?? 0) < sumWidth && + windowPosition.dy + (windowSize?.height ?? 0) < maxHeight; + } + Future storeDimensions({ required Offset windowOffset, required Size windowSize, }) async { - await Future.wait([ - _service.setWindowOffsetX(windowOffset.dx), - _service.setWindowOffsetY(windowOffset.dy), - _service.setWindowHeight(windowSize.height), - _service.setWindowWidth(windowSize.width), - ]); + if (await isInScreenBounds(windowOffset)) { + await _service.setWindowOffsetX(windowOffset.dx); + await _service.setWindowOffsetY(windowOffset.dy); + await _service.setWindowHeight(windowSize.height); + await _service.setWindowWidth(windowSize.width); + } } Future storePosition({required Offset windowOffset}) async { - await Future.wait([ - _service.setWindowOffsetX(windowOffset.dx), - _service.setWindowOffsetY(windowOffset.dy), - ]); + if (await isInScreenBounds(windowOffset)) { + await _service.setWindowOffsetX(windowOffset.dx); + await _service.setWindowOffsetY(windowOffset.dy); + } } Future storeSize({required Size windowSize}) async { - await Future.wait([ - _service.setWindowHeight(windowSize.height), - _service.setWindowWidth(windowSize.width), - ]); + await _service.setWindowHeight(windowSize.height); + await _service.setWindowWidth(windowSize.width); } -} \ No newline at end of file +} + +extension on Display { + Size get digestedSize => visibleSize ?? size; +}