fix: don't block local launch when remote runs a non-Steam shortcut#1396
fix: don't block local launch when remote runs a non-Steam shortcut#1396ben-pearson wants to merge 1 commit into
Conversation
Tapping Play on a Steam game while a non-Steam shortcut (e.g. Chrome on a Steam Deck) was running on another device showed the "App Running" conflict dialog, but Play Anyway couldn't kick a non-Steam process so the user got stuck. Pre PR utkarshdalal#1306 the local game would launch normally in this scenario. Filter both trigger paths so the dialog only appears when the remote app is in our local DB: - PluviaMain.preLaunchApp: gate the pre-launch dialog on SteamService.getAppInfoOf returning non-null. Non-Steam shortcuts report synthetic IDs that aren't kickable, so let the local launch proceed silently. - SteamService.onPlayingSessionState: same gate, plus pass the resolved remote app name through SteamEvent.PlayingBlocked so the in-game dialog can show it instead of the generic "another game" label. SteamEvent.PlayingBlocked changes from data object to data class carrying remoteAppName: String? (null on LoggedInElsewhere, which doesn't tell us what app caused the kick).
📝 WalkthroughWalkthroughThe PR threads remote app name through the Steam "playing blocked" conflict event pipeline: ChangesRemote App Name in Playing Blocked Event
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| val knownApp = callback.playingAppID | ||
| .takeIf { it != 0 } | ||
| ?.let { getAppInfoOf(it) } | ||
| ?: return |
There was a problem hiding this comment.
getAppInfoOf(it) <- there will be circumstances where it's not 0 and it's not an app that is in our DB (or our DB has not synced for some reason).
Is this function safe to call in that case? What would happen? Could lead to a crash.
Summary
Tapping Play on a Steam game in GameNative while a non-Steam shortcut (e.g. Chrome on a Steam Deck) was running on another signed-in device showed the "App Running" conflict dialog, but tapping Play Anyway couldn't actually kick a non-Steam process — leaving the user stuck. Pre-#1306 the local launch would have proceeded normally in this scenario.
This patch restricts the conflict dialog to cases where the remote app is something we recognise (and could meaningfully kick).
Bonus improvement: the dialog now shows the actual remote game name ("Cyberpunk 2077 is currently running on another device") instead of the generic "another game" label, when we have the app in the local DB.
Root cause
Steam reports session conflicts via two callbacks:
PlayingSessionStateCallback(in-game) andLoggedInElsewhereonLoggedOff(forced kick). Both populate_isPlayingBlockedand emitSteamEvent.PlayingBlockedwhenever Steam says the session is blocked.Non-Steam shortcuts added to a Steam library (Chrome, Discord, etc.) get synthetic high-range app IDs. They pass an
appID != 0check but aren't in our local app DB and can't be kicked viakickPlayingSession— Steam has no game session to stop. The dialog therefore appeared with a generic "another game" label, and Play Anyway no-op'd.The same logic also runs as a pre-launch check in
PluviaMain.preLaunchAppvialocalPersona.gameAppID— synthetic shortcut IDs got through there too.Changes
PluviaMain.preLaunchApp: gate the pre-launch conflict dialog onSteamService.getAppInfoOf(currentPlaying) != null. Unknown apps fall through to a normal local launch.SteamService.onPlayingSessionState: same DB-lookup gate, plus pass the resolved app name through thePlayingBlockedevent so the in-game dialog can display the actual game name.SteamService.onLoggedOffLoggedInElsewherebranch: emitsPlayingBlocked(remoteAppName = null)since that callback doesn't carry remote-app info — the dialog falls back to the existing "another game" label.SteamEvent.PlayingBlocked: changed fromdata objecttodata classcarryingremoteAppName: String?.XServerScreen: stores the resolved name in arememberSaveable, uses it in the dialog message, falls back toR.string.main_app_running_unknown_gamewhen null.+45 / -28across 4 files. No new strings, no new public API, no test changes.Test plan
Demo
Known trade-offs
"another game"fallback string inPluviaMainis now unreachable. Removed.Summary by cubic
Stop blocking local Play when the remote session is a non-Steam shortcut. If a real Steam game is running remotely, the dialog now shows that game’s actual name.
PluviaMain.preLaunchAppandSteamService.onPlayingSessionState.SteamEvent.PlayingBlocked;LoggedInElsewhereemitsremoteAppName = nullso the dialog uses the generic label.XServerScreendisplays the resolved name, saves it across recompositions, and clears it on dismiss.Written for commit 6d56308. Summary will update on new commits.
Summary by CodeRabbit