diff --git a/lib/app.dart b/lib/app.dart index aa1fa23..5a9b258 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; @@ -21,7 +22,7 @@ class PeyaApp extends ConsumerStatefulWidget { ConsumerState createState() => _PeyaAppState(); } -class _PeyaAppState extends ConsumerState { +class _PeyaAppState extends ConsumerState with WindowListener { static const _bgPanel = Color(0xD60C1824); static const _bgPanelStrong = Color(0xF00F1C2B); static const _line = Color(0x1F88FFE1); @@ -38,6 +39,8 @@ class _PeyaAppState extends ConsumerState { final GlobalKey _scaffoldMessengerKey = GlobalKey(); String? _lastErrorMessage; + bool _desktopCloseHookInitialized = false; + bool _handlingWindowClose = false; @override void initState() { @@ -77,6 +80,9 @@ class _PeyaAppState extends ConsumerState { @override void dispose() { + if (_desktopCloseHookInitialized) { + windowManager.removeListener(this); + } _configSubscription?.close(); _walletSubscription?.close(); super.dispose(); @@ -88,10 +94,8 @@ class _PeyaAppState extends ConsumerState { } _didInit = true; final tray = ref.read(trayServiceProvider); - final windowLifecycle = ref.read(windowLifecycleServiceProvider); - windowLifecycle.onBeforeClose = _handleAppCloseRequest; await tray.init(); - await windowLifecycle.init(); + await _initDesktopCloseHook(); ref.read(syncSchedulerProvider); ref.read(walletConfigSyncProvider); @@ -105,6 +109,39 @@ class _PeyaAppState extends ConsumerState { await _updateTrayMenu(); } + Future _initDesktopCloseHook() async { + if (_desktopCloseHookInitialized || + !(Platform.isLinux || Platform.isWindows)) { + return; + } + await windowManager.ensureInitialized(); + windowManager.addListener(this); + await windowManager.setPreventClose(true); + _desktopCloseHookInitialized = true; + } + + @override + void onWindowClose() { + unawaited(_handleNativeWindowClose()); + } + + Future _handleNativeWindowClose() async { + if (_handlingWindowClose) { + return; + } + _handlingWindowClose = true; + try { + final shouldClose = await _handleAppCloseRequest(); + if (!shouldClose) { + return; + } + await windowManager.setPreventClose(false); + await windowManager.destroy(); + } finally { + _handlingWindowClose = false; + } + } + Future _promptForSavedWalletPassword(WalletInfo wallet) async { await WidgetsBinding.instance.endOfFrame; while (mounted && ref.read(walletControllerProvider).walletInfo == null) {