Summary
Two small changes to the remote-session control path in nvhttp.cpp / remote_session.cpp:
-
Remote Input relaunch from the same client is now an idempotent retry.
remote_session::dispatchalready allowscontrol_e::monitorwhen the caller itself owns the monitor role (the comment notes Moonlight retries slow launches and cached tiles).control_e::inputhad no equivalent, so a client whose Remote Input stream dropped, and which still owns the input role until cleanup, got a 409 from its own stale ownership when reconnecting. Input now allowsowner.role == input, matching monitor. Cross-role conflicts (monitor→input, input→monitor) are still rejected. -
Log why a remote session control is rejected. The 409 path ("Remote session action conflicts with this client's current session state") previously logged nothing, so it was hard to tell which state caused it. It now logs a warning with the control, caller UUID, game running/owner, owner role, and retained/ready flags.
Context
Seen with a Steam Deck client (Nonary's moonlight-qt VRR fork, PyroWave) over Wi-Fi: after a dropped stream, the Deck's next remote control action returned 409 and the host kept deferring virtual display cleanup because the stale session still counted as active.
Testing
- Built on Windows (MSYS2 UCRT64, Release, WebRTC off) and ran the build on the host. Normal streaming, disconnect, and reconnect from the Deck worked.
- Added a unit case in
tests/unit/test_remote_session.cppfor same-client input relaunch. I have not built or run the unit test suite locally. - I did not reproduce the exact Remote Input 409 after the change, so fix 1 is based on reading the dispatch rules rather than a confirmed before/after repro. Marking as draft for that reason; happy to adjust if the stale-owner case should be handled differently (for example, by releasing the old input session instead of replacing ownership).
Not included
While testing I also hit a 503 ("composed display topology did not apply") when Windows rejected a 2560x1600 virtual display next to two physical monitors (ERROR_INVALID_PARAMETER / "failed to move device to new origin"). That is separate and not addressed here.
🤖 Generated with Claude Code
Activity
2This pull request is a draft
Merging is unavailable until it is marked ready for review.
Thanks for documenting the reconnect scenario. Development integration targets
canary; could you update this original PR's base tocanary, update the branch, and resolve the conflicts? The added dispatch test covers the allow decision but not the ownership replacement or cleanup path. Please add and run coverage for a stale same-client input owner reconnecting, and verify that active ownership and cross-role conflicts still behave correctly without leaving duplicate or stale sessions. The PR notes that the new unit test has not yet been run.