A Flutter desktop package that persists and restores the window's position and size across app sessions.
Works on:
- Windows.
- Linux.
- macOS (See
⚠️ Note on macOS Startup).
- ✅ Persists window state using shared_preferences.
- ✅ Restores window state on launch via window_manager.
- ✅ Multi-monitor support: Uses screen_retriever to detect out-of-bounds or hidden windows, automatically resetting them to default.
- Initialize
WindowPersistentState.initializeWindowStatebefore runApp. - Wrap your MaterialApp with a
WindowPersistentState.
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Call to restore the window position before showing the app
// and optionally pass custom configurations for the window
await WindowPersistentState.initializeWindowState(
defaultSize: const Size(1280, 720),
minSize: const Size(800, 600),
);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
// Wrap the MaterialApp with the WindowPersistentState widget
return WindowPersistentState(
child: MaterialApp(
title: 'Window Persistent State Example',
home: const MyHomePage(),
),
);
}
}Refer to the example to see the usage of WindowPersistentState.
On macOS, you might notice two visual glitches during startup:
- Black Screen: A brief flash of black background while Flutter initializes the rendering engine.
- Position Jump: The window momentarily appears at the default system position before jumping to its restored coordinates. This happens because
window_managerneeds a few milliseconds to apply the saved position after the window is created.
This is a known behavior in Flutter desktop apps.
To completely hide these artifacts, we recommend implementing a native fade-in effect. By starting the window with alpha: 0 (transparent) and gently animating it to visible after the position has been restored, the user never sees the "jump" or the black screen.
See our MainFlutterWindow.swift example for a smooth, drop-in implementation of this fix.
- Linux: Feedback on Linux support is needed.
- Tests: Unit and Widget tests are currently missing.