flutter_inactive_timer 3.0.0
flutter_inactive_timer: ^3.0.0 copied to clipboard
Detect user inactivity on Windows and macOS desktop apps: configurable timeout, percentage or fixed-lead-time warnings, and a live countdown for auto-logout and session timeouts.
3.0.0 #
Breaking #
-
The Notification's timing is now a
NotificationTriggerpassed asnotification:, replacing thenotificationPerinteger. It is a sealed type with two kinds:NotifyAtPercent(int percent)— fire atpercent% of the timeout (the oldnotificationPerbehavior).NotifyBefore(Duration before)— fire a fixed lead time before the timeout, independent of its length (new).
notificationis optional;null(the default) means no Notification, only the timeout fires — replacing the oldnotificationPer: 0. See ADR-0002. -
timeoutDurationis now aDurationinstead of anintnumber of seconds, so the whole API speaks one time type.Migration:
// 2.x FlutterInactiveTimer(timeoutDuration: 60, notificationPer: 50, ...); // 3.0.0 FlutterInactiveTimer( timeoutDuration: Duration(seconds: 60), notification: NotifyAtPercent(50), ..., );
Features #
NotifyBefore(Duration)schedules the Notification a fixed lead time before the timeout (e.g.NotifyBefore(Duration(seconds: 120))on a 5-minute timeout fires at 3 minutes).beforemust be>= 0and shorter than the timeout (asserted in debug); a value>=the timeout safely clamps to firing at monitoring start.Future<Duration> remaining()returns the time left before timeout, for driving a live countdown (e.g. a "logs out in 04:59" label). It reads the current idle duration, so the countdown resets on user activity — and stays correct inrequireExplicitContinuelock, where a naivetimeout - idlewould not. ReturnsDuration.zerowhen not monitoring. It is a pull API: drive it from your own periodic ticker; the timer keeps none of its own. See ADR-0003.
2.0.0 #
Breaking #
- The native method channel now exposes a single
getIdleDuration()method (milliseconds since the last user input) in place of the previousgetSystemTickCount()+getLastInputTime()pair. This removes a Windows bug where the two calls used different clock widths (64-bitGetTickCount64vs 32-bitGetLastInputInfo), producing incorrect inactivity after ~49.7 days of uptime. See ADR-0001. CustomFlutterInactiveTimerPlatformimplementations must now implementgetIdleDuration().
Features #
- Added
FlutterInactiveTimer.dispose()for deterministic teardown: it cancels the active timer and releases the instance so it (and its callbacks) can be garbage collected. UnlikestopMonitoring()(a resumable pause), a disposed timer cannot be restarted. Call it from your widget'sState.dispose.
Internal #
- Extracted the scheduling and notification logic into a pure, side-effect-free
InactivityPolicy(with a sealedInactivityDecision), making the timing rules unit-testable without mocking timers or the platform channel.FlutterInactiveTimeris now a thin shell over it. FlutterInactiveTimergained optionalplatformandclockconstructor parameters for dependency injection in tests; production defaults are unchanged.- Hardened the scheduling loop with a generation guard so an in-flight check that is superseded by
stopMonitoring/startMonitoring/continueSession/disposecannot arm a stale timer. Guarantees at most one live timer under overlapping calls (regression-tested).
1.2.0 #
Behavior fix (breaking) #
notificationPernow consistently means "percent of timeout elapsed", matching the documented behavior. The scheduler previously interpreted it as "percent remaining", so notifications fired at the wrong time (e.g.timeoutDuration=60, notificationPer=10fired at 54s instead of 6s) and triggered a 1ms busy-loop wheneverper > 50. Callers that relied on the old reversed meaning will see firing times change — adjust yournotificationPeraccordingly.
Features #
- Added optional
onActivecallback. Fires when the user becomes active again after a notification has been delivered — both on detected user input (whenrequireExplicitContinueis false) and oncontinueSession()calls. Existing constructors remain source-compatible (the parameter is optional).
Improvements #
- Post-notification scheduling now polls at a 500ms cap when
requireExplicitContinueis false, bounding the latency between user return andonActivefiring. Previously the next check could be scheduled up totimeoutDuration × (100 - per)%away, which made UI recovery feel broken on longer timeouts. requireExplicitContinue=truecontinues to schedule a single check at timeout (input is ignored in that mode, so polling buys nothing).
Tests #
- Rewrote the test suite with
fake_asyncfor real behavioral verification of timer scheduling, notification timing, user-activity reset, explicit continue,onActivetriggers, and the 500ms polling cap.
Example #
MultiModeDemonow usesonActiveto restore the status label when the user returns, instead of leaving it stuck at "Almost inactive!".
1.1.4 #
- Fix: ensure stopMonitoring() fully stops during async inactivity checks
1.1.3 #
- update license
1.1.2 #
- update license
1.1.1 #
- update macos target version
1.1.0 #
macOS Support Added #
- Added native macOS implementation using IOKit HIDIdleTime
- Now fully supports both Windows and macOS platforms
- Updated platform configuration in pubspec.yaml
- Added example code for macOS
1.0.0 #
Initial Release #
- Added support for detecting user inactivity in Windows desktop applications
- Implemented customizable timeout duration for inactivity detection
- Added notification threshold feature to alert users before timeout occurs
- Included callback functions for handling inactivity detection and notifications
- Implemented option to require explicit user confirmation to continue session after notification
- Added ability to start and stop inactivity monitoring
- Added continueSession method to explicitly reset timer when required