Summary
Steam (and Lutris) apps that Vibepollo successfully tracks never end their session when the game exits, as long as the game ran for more than 15 seconds. The stream stays up on the client until the user quits from Moonlight.
Cause
In proc_t::running(), when the tracked process tree disappears, the poll block clears _steam_tracking_associated and _steam_tracking_active, but execution stays inside the if (_steam_tracking_active) block. With the 15 second launch deadline already passed, it falls into the "remained untrackable" warning, sets placebo = true and returns _app_id. From then on the placebo branch keeps the app "running" indefinitely.
Games that exit inside the 15 second window take the intended path, which is why short tests look fine.
Host log from Dota 2 (appid 570) on 2.0.0. The warning appears at the moment the game is quit in-game:
10:10:28.152 Info: Executing: [cmd /c start "" steam://rungameid/570] ...
10:10:31.477 Info: Steam app 570 associated with 1 tracked process(es).
10:11:03.689 Warning: Steam app 570 process tree remained untrackable after the 15 second launch window; retaining detached streaming behavior.Changes
- Extract the per-poll decision into
next_tracking_action()(keep_alive,tracked_tree_exited,give_up_detached) insteam_process_tracker. - On
tracked_tree_exited, log the exit with the tracker reason and go straight to the cleanup path, skipping theplacebo,wait_all, launcherrunning()andauto_detachchecks. Without that skip, a game that exits within 5 seconds of launch would still be turned into a placebo app by the auto-detach branch. - The "remained untrackable" warning is now only logged when the tree was never associated.
No new settings; this restores the intended automatic behaviour.
Testing
- New unit tests in
tests/test_steam_process_tracker.cppfor every branch ofnext_tracking_action(), plus a tracker-level test thatfinish()stops reporting association once the tracked PID disappears. AllSteamProcessTrackerandSteamBigPicturetests pass. - Built the Windows installer from this branch and installed it on a Windows 11 host (RTX 4080), streaming to a Moonlight client on macOS. Launched Dota 2 from the synced Steam entry, played for about a minute, then quit in-game. The session ended on its own and the client returned to the app list:
11:05:59.796 Info: Executing: [cmd /c start "" steam://rungameid/570] ...
11:06:02.873 Info: Steam app 570 associated with 1 tracked process(es).
11:07:11.192 Info: Steam app 570 tracked process tree exited (new processes had no install-directory or compatibility-runtime evidence); ending session.
11:07:11.192 Info: [running] Tracked game process tree exited; calling terminate() for app 'Dota 2' (id=1288542858)
11:07:14.524 Info: Session ended
Thanks for the review. Both points are addressed:
canaryand rebased onto it (no conflicts; canary doesn't touch these files)._steam_tracked_tree_exit_pendingmember instead of a local. It's only cleared byterminate()or a new launch, so if the lifecycle gate is held (or teardown is in flight elsewhere), the retry poll still goes straight to cleanup and can't fall intoauto_detach/placebo.next_post_tracking_action()helper next tonext_tracking_action(), with tests covering a pending exit followed by a retry 1s after launch withauto_detachon (gives cleanup), plus the unchanged non-pending behaviour.