smooth_window_close 0.2.0
smooth_window_close: ^0.2.0 copied to clipboard
Hide Flutter Windows apps before graceful asynchronous shutdown.
smooth_window_close #
Responsive, graceful shutdown for Flutter Windows applications.
Flutter desktop apps often intercept native close events to save state, close databases, stop sockets, or destroy tray resources. Awaiting that work while the Flutter window remains visible can leave a frozen final frame on screen.
smooth_window_close hides the Windows window first, performs asynchronous
state saving and cleanup, then allows and destroys the window. It uses
window_manager; no custom native
runner changes are required.
Installation #
Published dependency:
dependencies:
smooth_window_close: ^0.2.0
Local sibling package:
dependencies:
smooth_window_close:
path: ../smooth_window_close
Basic usage #
runApp(
SmoothWindowCloseScope(
onSaveState: saveWindowState,
onCleanup: shutdownServices,
onError: (error, stackTrace) {
logger.warning('Shutdown failed', error, stackTrace);
},
child: MaterialApp(home: HomePage()),
),
);
The scope initializes and disposes its closer automatically. Keep
windowManager.ensureInitialized() in main() before runApp().
Close-to-tray #
No tray package is required. Supply application state through a callback:
SmoothWindowCloseScope(
shouldCloseToTray: () => settings.closeToTray,
onSaveState: saveWindowBounds,
onCleanup: () async {
await closeChildWindows();
await destroyTray();
},
child: MaterialApp(home: HomePage()),
);
A normal X or Alt+F4 request hides the window, saves state, and returns when
shouldCloseToTray is true. Your tray integration remains responsible for
showing the window again.
Explicit Exit #
Use exit() for File → Exit, tray Exit, or a Quit button:
await SmoothWindowCloseScope.of(context).exit();
exit() always terminates, even when close-to-tray is enabled.
Use handleCloseRequest() only when manually forwarding a normal close
request. Native X and Alt+F4 events are already handled after initialize().
Operation order #
Windows exit:
hide → save state → cleanup → setPreventClose(false) → destroy
Windows close-to-tray:
hide → save state → return
The reentrancy guard is set before the first asynchronous operation. Repeated
close events cannot run cleanup concurrently. Callback failures are reported
through onError; remaining shutdown steps continue so a failed cleanup does
not leave an invisible process running indefinitely.
Keep callbacks limited to work that genuinely must finish before process exit.