diff --git a/lib/application_exit_control.dart b/lib/application_exit_control.dart index f532f9a..9504e30 100644 --- a/lib/application_exit_control.dart +++ b/lib/application_exit_control.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:window_manager/window_manager.dart'; import 'package:winui_n2n/edge_state.dart'; +import 'package:winui_n2n/globals.dart'; import 'package:winui_n2n/home_page.dart'; import 'package:winui_n2n/shared_pref_singleton.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -32,82 +33,84 @@ class _ApplicationExitControlState extends State { } Future _handleExitRequest() async { - if (SharedPrefSingleton().minimizeOnQuit == null) { - final exitApp = await showDialog( - context: context, - builder: (context) { - bool minimize = false; - return AlertDialog( - title: Text(AppLocalizations.of(context)!.exitAlert), - actions: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - StatefulBuilder(builder: - (BuildContext context, StateSetter setState) { - return Checkbox( - value: minimize, - onChanged: (bool? value) { - SharedPrefSingleton() - .setMinimizeOrNot(value ?? false) - .then( - (_) { - setState( - () { - minimize = value ?? false; - }, - ); - }, - ); + if (!forceExit) { + if (SharedPrefSingleton().minimizeOnQuit == null) { + final exitApp = await showDialog( + context: context, + builder: (context) { + bool minimize = false; + return AlertDialog( + title: Text(AppLocalizations.of(context)!.exitAlert), + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + StatefulBuilder(builder: + (BuildContext context, StateSetter setState) { + return Checkbox( + value: minimize, + onChanged: (bool? value) { + SharedPrefSingleton() + .setMinimizeOrNot(value ?? false) + .then( + (_) { + setState( + () { + minimize = value ?? false; + }, + ); + }, + ); + }, + ); + }), + Text(AppLocalizations.of(context)!.alwaysMinimize), + ], + ), + Row( + children: [ + TextButton( + onPressed: () { + Navigator.pop(context, false); + windowManager.hide(); }, - ); - }), - Text(AppLocalizations.of(context)!.alwaysMinimize), - ], - ), - Row( - children: [ - TextButton( - onPressed: () { - Navigator.pop(context, false); - windowManager.hide(); - }, - child: Text(AppLocalizations.of(context)!.minimize), - ), - TextButton( - onPressed: () { - Navigator.pop(context, true); - }, - child: Text(AppLocalizations.of(context)!.exit), - ), - ], - ), - ], - ), - ], - ); - }, - ); + child: Text(AppLocalizations.of(context)!.minimize), + ), + TextButton( + onPressed: () { + Navigator.pop(context, true); + }, + child: Text(AppLocalizations.of(context)!.exit), + ), + ], + ), + ], + ), + ], + ); + }, + ); - if (exitApp == null || exitApp == false) { + if (exitApp == null || exitApp == false) { + return AppExitResponse.cancel; + } + } + + if (SharedPrefSingleton().minimizeOnQuit == true) { + windowManager.hide(); return AppExitResponse.cancel; } - } - if (SharedPrefSingleton().minimizeOnQuit == true) { - windowManager.hide(); - return AppExitResponse.cancel; - } - - if (EdgeState.instance.isRunning && EdgeState.instance.process != null) { - if (EdgeState.instance.process!.kill()) { - EdgeState.instance.isRunning = false; - EdgeState.instance.process = null; - } else { - // TODO: Handle abnormal close. - return AppExitResponse.cancel; + if (EdgeState.instance.isRunning && EdgeState.instance.process != null) { + if (EdgeState.instance.process!.kill()) { + EdgeState.instance.isRunning = false; + EdgeState.instance.process = null; + } else { + // TODO: Handle abnormal close. + return AppExitResponse.cancel; + } } } diff --git a/lib/globals.dart b/lib/globals.dart index 176fff9..e5e8077 100644 --- a/lib/globals.dart +++ b/lib/globals.dart @@ -2,3 +2,5 @@ import 'package:flutter/material.dart'; final GlobalKey snackbarKey = GlobalKey(); + +bool forceExit = false; diff --git a/lib/home_page.dart b/lib/home_page.dart index 703dd0e..881bfc5 100644 --- a/lib/home_page.dart +++ b/lib/home_page.dart @@ -1,7 +1,11 @@ +import 'dart:ui'; + import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:window_manager/window_manager.dart'; import 'package:winui_n2n/control_page.dart'; import 'package:winui_n2n/about_page.dart'; +import 'package:winui_n2n/globals.dart'; import 'package:winui_n2n/logger_page.dart'; import 'package:winui_n2n/main.dart'; import 'package:winui_n2n/setting_page.dart'; @@ -57,6 +61,14 @@ class _HomePageState extends State with TrayListener { windowManager.show(); }, ), + MenuItem( + key: 'exit_app', + label: AppLocalizations.of(context)!.exit, + onClick: (menuItem) { + forceExit = true; + ServicesBinding.instance.exitApplication(AppExitType.required); + }, + ) ], ); trayManager.setContextMenu(menu);