power_state_monitor

Flutter plugin that delivers Windows power management events (suspend and resume) straight into your app. It wraps a lightweight native listener around WM_POWERBROADCAST, then exposes events as a Dart broadcast stream so your UI and services can react in real time. The package is intentionally Windows-only for now—other platforms ship only as blank stubs so the example can compile everywhere, and there are currently no plans to extend this package beyond Windows.

  • Observe when the machine enters sleep or hibernate.
  • Distinguish between user-triggered and automatic resume events.
  • Keep your app state in sync by refreshing data or re-establishing connections after wake.

Platform support

Platform Status Notes
Windows ✅ Implemented Uses a hidden Win32 window to forward WM_POWERBROADCAST events
macOS 🟡 Planned Would require listening to system power notifications on macOS
Linux ⛔ Not planned Ships as a stub so the example compiles
Android ⛔ Not planned Ships as a stub so the example compiles
iOS ⛔ Not planned Ships as a stub so the example compiles
Web ⛔ Not planned Ships as a stub so the example compiles

The plugin silently refuses to initialize on unsupported targets, so you can keep a single code path. Use PowerStateMonitor.instance.isPlatformSupported to guard features when needed.

Installation

  1. Add the dependency in your pubspec.yaml:
dependencies:
  power_state_monitor: ^0.1.2
  1. Run flutter pub get.

  2. Target Windows (64-bit). No additional configuration is required. Launching the example on other platforms is fine, but power events will not be emitted.

Quick start

Call initialize() early (for example in main() or your root widget's initState) and listen to the broadcast stream:

import 'package:flutter/material.dart';
import 'package:power_state_monitor/power_state_monitor.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  final initialized = await PowerStateMonitor.instance.initialize();
  if (!initialized) {
    debugPrint('PowerStateMonitor: unsupported platform');
  }

  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    PowerStateMonitor.instance.onPowerStateChanged.listen((event) {
      debugPrint('Power state changed: ${event.name}');
      if (event == PowerStateEvent.resumeAutomatic ||
          event == PowerStateEvent.resumeSuspend) {
        _refreshData();
      }
    });
  }

  void _refreshData() {
    // Your resume handling logic.
  }

  @override
  void dispose() {
    PowerStateMonitor.instance.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) => const Placeholder();
}

Event reference

Event Native source Typical use
PowerStateEvent.suspend PBT_APMSUSPEND Save app state, pause background work
PowerStateEvent.resumeSuspend PBT_APMRESUMESUSPEND User woke the PC: refresh data, reconnect sockets
PowerStateEvent.resumeAutomatic PBT_APMRESUMEAUTOMATIC System woke automatically: defer UI updates until user interaction

Under the hood the plugin registers a hidden window and forwards notifications through a MethodChannel. The Dart side keeps a broadcast StreamController, so you can attach multiple listeners safely.

Testing & debugging

  • Use PowerStateMonitor.instance.debugPlatformOverride in widget tests to mock a supported OS.
  • On Windows, trigger sleep/resume manually or use the psshutdown utility (psshutdown -d -t 0) to automate testing.
  • Remember to call dispose() when your app shuts down or when you hot-reload during development to avoid duplicate listeners.

Example app

A minimal example is available under example/. Launch it on Windows and put your device to sleep to see events show up in real time. The demo UI is fully in English and highlights the suspend/resume history so you can screenshot it or extend it for your own debugging tools.

Roadmap ideas

  • macOS implementation powered by Darwin power notification APIs.
  • Optional callbacks for battery and AC change notifications.
  • Integrations with background services.

If you need support for another operating system beyond macOS, feel free to open an issue to discuss feasibility or maintain a fork tailored to your use case.

Contributing

Contributions are welcome! Please file an issue or a pull request describing the change. Keep platform-specific code well isolated and cover new Dart logic with tests where possible.

License

This project is distributed under the MIT License. See the LICENSE file for details.