Keep fullscreen apps active in background on macOS >= 15 - #226
Conversation
Since macOS 15, runningboardd suspends Catalyst apps as soon as their scene becomes invisible (window on another Space, minimized, hidden), freezing PlayCover games completely. Games also pause themselves because the engine receives the standard background lifecycle events. This commit does the following on macOS >= 15: 1. Plays an inaudible audio loop (AVAudioEngine, .playback + .mixWithOthers, output volume 0). Like on iOS, an app that is actively playing audio is exempt from suspension. Requires UIBackgroundModes: [audio] in the app's Info.plist. 2. Hides the background transition from the game: drops the willResignActive/didEnterBackground notifications and neuters the corresponding app/scene delegate callbacks, so engines such as Unity never pause their player loop. Because the shutdown sequence replays exactly these suppressed events (quitWhenClose does so explicitly, Cmd+Q via the system), all quit paths are hooked through NSApplication.terminate to stand down the suppression and the audio exemption first, so games can still save their state and exit cleanly. Verified with Genshin Impact, Honkai: Star Rail and ZZZ on macOS 27 Beta: the game keeps running at full speed while its window is swiped away, and quits cleanly via both the close button and Cmd+Q. Fixes PlayCover/PlayCover#1568 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@Brawl345 @JoseMoreville Thanks a lot for this fix, and maintainers' reviewing. I applied this patch, and tested with local dogfooding build, works fine with MacOS 26.5.2 Tahoe and Arknights (PlayCover with MAA to be specific) Is there a merge plan, or anything still blocking? (except failed lint CI, haha) |
| DiscordIPC.shared.initialize() | ||
|
|
||
| // runningboardd only freezes invisible scenes since macOS 15. | ||
| if ProcessInfo.processInfo.isOperatingSystemAtLeast( |
There was a problem hiding this comment.
It would be better to use iOS version check if #available(...) rather than the macOS since it is technically running under iOS guise. It should be the same as they parallel releases.
There was a problem hiding this comment.
Fixed, iOS 18 should be the correct one since it released at the same time. I think you meant that, right?
|
I believe the main blocker at the moment is the CI haha |
|
CI should get through now, haven't tested the changes though since I no longer have macOS 27 installed |
|
|
||
| var cmdPressed: Bool = false | ||
| var cursorHideLevel = 0 | ||
| fileprivate var modifierFlag: UInt = 0 |
There was a problem hiding this comment.
No need for the fileprivate modifier since that is the default for any variable, same for the ones in extension AKPlugin.
Disclamer: This was
vibesloppedmade with Claue Fable 5 (before it was taken down luckily!), I just steered and verified it.This fixes the "apps are paused in background when fullscreen and I swipe away" that was introduced in macOS 15 for Catalyst apps. It blocks certain calls and "plays" a silent audio-loop since apps that play audio are kept alive (for music players on iOS).
Few things to note:
didEnterBackgroundNotificationetc are blocked because games will pause themselves, too (in addition to the hard block introduced by macOS 15)Fixes PlayCover/PlayCover#1568