You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Desktop] Allow applications to continue frame rendering when hidden for real-time games and animation-driven audio #174356
We are building a real-time multiplayer game that uses Rive animations with audio event synchronization. When players perform actions remotely, the game continues running in the background, and animations must maintain their timeline to ensure audio plays at the correct positions. However, when the app window is hidden (e.g., minimized, covered by other windows, or in mission control on macOS), frame rendering stops, causing animations to freeze and audio to not play.
Proposal
Proposed Solution
Add a forceFramesEnabled property to SchedulerBinding that allows developers to explicitly opt-in to continuous frame rendering when the app is hidden. This would be particularly useful for:
Real-time games that continue running in the background
Applications with animation-driven audio (like Rive)
Multiplayer applications where game logic continues server-side
I have already implemented this feature in PR #173862.
Current Workaround
We've implemented a hacky solution by intercepting the AppLifecycleState.hidden state and replacing it with AppLifecycleState.inactive in a custom DesktopWidgetsFlutterBinding:
I've encountered some games that freezes when the window goes inactive or minimized, but yeah there are some that continues to play (maybe with reduced frames).
If we move forward with this flag, I propose a negated name for the property such as pauseFramesWhenHidden, which seems clearer to me.
I talked to @chinmaygarde and he says that the engine doesn't care and will happily continue rendering frames if we tell it to.
So is eliminating the need for the workaround worth the danger of people turning on this flag when they shouldn't?
@tguerin Are you sure you must continue rendering frames in order to play your audio at the right time? Can you explain that in more detail and maybe provide an example if possible?
(you may need to run dart run rive_native:setup --clean --platform macos for it to work). I only added macOS, but it works on Windows as well.
When the app is hidden, you no longer hear the robot’s sound because in Rive the audio is tied directly to the animation timeline. In a real-time game, remote actions don’t stop just because the window is hidden, so the audio must continue to play in sync.
I understand this is a specific use case and mainly relevant on desktop. We could restrict the flag to desktop platforms only. I’m open to any suggestions or adaptations for the PR, but the current workaround is hacky and not a real fix.
I think at least, the logic for Flutter to disable frames when hidden is something "extra" and "smart", therefore it makes perfect sense to allow developers to disable them as long as we document clearly and the developers know what they're doing. My concern is mostly if there are anything better for your project, such as allowing the logic to run without actually rendering them, but I guess you'd be happy to at least have this and we should grant it. @justinmc What do you think?
I am going to add my use case to this: I am using flutter (and flame) for a research project that uses real-time communication and data streams. I often end up with things breaking because while the isolates continue consuming in the background, the main UI stops, and it can get into an inconsistent state (including a countdown timer) which causes all kinds of problems.
It would be awesome to be able to have an option, at least for desktop, to continue rendering when an application loses focus. I understand that is not always desirable, but in some cases it very much is.
This seems better than a global flag like SchedulerBinding.forceFramesEnabled.
However, it would be nice if Flutter's animation system let you force frames using granular app logic. Today, the TickerMode widget lets you configure tickers in the subtree. You can use this to mute animations, for example if the animation is running in a tab that isn't active:
Widgetbuild(BuildContext context) {
returnTickerMode(
enabled:false, // Tickers in the subtree are muted
child: ...,
);
}
Add a new TickerMode.forceFrames property. Something like:
Widgetbuild(BuildContext context) {
// Tickers in the subtree, if any, are enabled and force frames if active.returnTickerMode(
enabled:true,
forceFrames:true,
child: ...,
);
}
This would also likely require deprecating TickerMode.of and TickerMode.getNotifier in favor of new APIs that can return both enabled and forceFrames.
Add a new TickerMode.merged constructor. This creates a TickerMode that overrides ticker mode properties, similar to DefaultTextStyle.merge:
Widgetbuild(BuildContext context) {
// Tickers in the subtree, if any are active, force frames.// Tickers can be muted by a TickerMode higher in the widget tree.returnTickerMode.merge(
forceFrames:true,
child: ...,
);
}
Update SingleTickerProviderStateMixin and TickerProviderStateMixinhere and here.
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.
Activity
tirth-patel-nc commentedon Aug 25, 2025
@tguerin thanks for the report. Marking it as a new proposal.
dkwingsmt commentedon Aug 25, 2025
cc @loic-sharma @justinmc @chinmaygarde
dkwingsmt commentedon Aug 25, 2025
Thank you for the writeup!
I've encountered some games that freezes when the window goes inactive or minimized, but yeah there are some that continues to play (maybe with reduced frames).
If we move forward with this flag, I propose a negated name for the property such as
pauseFramesWhenHidden, which seems clearer to me.Let's wait for a while for more feedbacks.
justinmc commentedon Aug 26, 2025
I talked to @chinmaygarde and he says that the engine doesn't care and will happily continue rendering frames if we tell it to.
So is eliminating the need for the workaround worth the danger of people turning on this flag when they shouldn't?
@tguerin Are you sure you must continue rendering frames in order to play your audio at the right time? Can you explain that in more detail and maybe provide an example if possible?
tguerin commentedon Sep 8, 2025
Here is a sample project: https://github.com/tguerin/rive_sound_sample
(you may need to run
dart run rive_native:setup --clean --platform macosfor it to work). I only added macOS, but it works on Windows as well.When the app is hidden, you no longer hear the robot’s sound because in Rive the audio is tied directly to the animation timeline. In a real-time game, remote actions don’t stop just because the window is hidden, so the audio must continue to play in sync.
I understand this is a specific use case and mainly relevant on desktop. We could restrict the flag to desktop platforms only. I’m open to any suggestions or adaptations for the PR, but the current workaround is hacky and not a real fix.
dkwingsmt commentedon Sep 8, 2025
I think at least, the logic for Flutter to disable frames when hidden is something "extra" and "smart", therefore it makes perfect sense to allow developers to disable them as long as we document clearly and the developers know what they're doing. My concern is mostly if there are anything better for your project, such as allowing the logic to run without actually rendering them, but I guess you'd be happy to at least have this and we should grant it. @justinmc What do you think?
zeyus commentedon Sep 12, 2025
I am going to add my use case to this: I am using flutter (and flame) for a research project that uses real-time communication and data streams. I often end up with things breaking because while the isolates continue consuming in the background, the main UI stops, and it can get into an inconsistent state (including a countdown timer) which causes all kinds of problems.
It would be awesome to be able to have an option, at least for desktop, to continue rendering when an application loses focus. I understand that is not always desirable, but in some cases it very much is.
loic-sharma commentedon Sep 13, 2025
I believe forcing frames globally should already be possible today using
SchedulerBinding.scheduleForcedFrame. Something like:This seems better than a global flag like
SchedulerBinding.forceFramesEnabled.However, it would be nice if Flutter's animation system let you force frames using granular app logic. Today, the
TickerModewidget lets you configure tickers in the subtree. You can use this to mute animations, for example if the animation is running in a tab that isn't active:I would consider:
Add a new
Ticker.forceFramesAPI. Iftrue, this causesTicker.scheduleTickto callSchedulerBinding.scheduleForcedFrameinstead ofSchedulerBinding.scheduleFrame.Add a new
TickerMode.forceFramesproperty. Something like:This would also likely require deprecating
TickerMode.ofandTickerMode.getNotifierin favor of new APIs that can return bothenabledandforceFrames.Add a new
TickerMode.mergedconstructor. This creates aTickerModethat overrides ticker mode properties, similar toDefaultTextStyle.merge:Update
SingleTickerProviderStateMixinandTickerProviderStateMixinhere and here.[Animation] Add granular frame forcing to animations (#173862)
[Animation] Add granular frame forcing to animations (flutter#173862)
github-actions commentedon Nov 26, 2025
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.[Animation] Add granular frame forcing to animations (flutter#173862)
[Animation] Add granular frame forcing to animations (flutter#173862)
[Animation] Add granular frame forcing to animations (#173862)