Skip to content

Support Steam Link virtual controllers in the Mac launcher - #874

Closed
thehobbit85 wants to merge 2 commits into
LNPANDY:mainfrom
thehobbit85:codex/issue-797-steam-link
Closed

thehobbit85 wants to merge 2 commits into
LNPANDY:mainfrom
thehobbit85:codex/issue-797-steam-link

Conversation

@thehobbit85

Copy link
Copy Markdown
Contributor

Fix or feature

  • Fix
  • Feature

What and why

Addresses the launcher-side gap in #797. Draft pending the reporter's Steam Link test. This does not claim an end-to-end fix or close the issue.

The reporter adds NX2Apple to Steam as a non-Steam game and streams from a Mac to an iPhone with a PS5 controller. Local input works, but remote input does not. The issue was closed immediately before another comment describing the failure, with no linked fixing commit. It has been reopened.

The Mac launcher previously enumerated only Apple's GameController devices. Steam can instead expose a virtual Xbox 360 HID device. This PR adds a narrow, non-exclusive IOKit reader for virtual 045e:028e devices named GamePad-N, with the known contiguous 15-button Mac Xbox layout and absolute X/Y axes. Physical controllers, GC synthetic devices, unknown layouts and devices claimed by GameController are excluded. No dependency or driver is installed.

Accepted devices use the existing navigation, button-edge, capture and repeat handling. They appear in the existing controller inventory with Xbox prompts, unknown battery and no Identify capability. Focus loss and disconnect cancel repeats and queued input. Desktop, console and onboarding views share one active input route, including ordinary GC controllers.

Settings > Copy diagnostics now includes GC device count, HID manager result, accepted/skipped candidates, open failures and input-value counts. It does not record button histories, serial numbers or environment variables.

Findings and remaining boundary

  • SDL's macOS HID reader recognizes the GamePad-N virtual Xbox identity. The Mac Xbox mapping supplies the proposed button and axis interpretation. Applying that layout to the reporter's device is an inference awaiting their test. Unknown descriptor shapes are reported instead of guessed.
  • Games are separate applications with their own engine controller reader. This PR only changes the launcher. A successful menu test does not establish successful gameplay.
  • The pinned engine skips raw HID when GameController claims the device. This PR also leaves GC-claimed devices on that existing API to avoid duplicate input. If diagnostics show GC claiming the virtual device but no usable input arrives, engine/controller API work may still be necessary.
  • The engine's generic HID fallback uses a different default button map, so detection alone would not establish correct in-game buttons. Gameplay mapping must be tested separately.
  • Add Steam Controller 2026 support and per-game mappings #731 concerns physical Steam Controller hardware, not this virtual Steam Link transport. Changing launch environment alone would not explain absent input in the already-running launcher.
  • Launcher player assignment is not a new cross-process player-order bridge. No engine files, patches, process injection or gameplay configuration are changed.

Checked

  • swift build && swift test: 1,232 tests executed, 32 optional/environment-dependent skips, zero failures on Apple silicon, macOS 26.6.
  • python3 -m unittest discover -s frontend-qt/tests: 353 tests executed, 44 environment-dependent skips, zero failures.
  • 12 focused input/diagnostic regressions cover identity exclusions, button/axis mapping, malformed values, press deduplication, capture IDs, focus loss, disconnect, view transitions, real GC-profile callback routing, inventory removal and diagnostic output.
  • Negative controls: the empty decoder failed 9 assertions, removing the Steam event hookup failed the integration test, and retaining stale GC state across a held-button view switch failed its regression. Each passes with the corresponding fix restored.
  • Opt-in native capture test passed and generated 24 state images (Home and Controllers, before/after, six languages). Normal CI skips this capture unless requested.
  • Required pre-push checks run with the project's hooks enabled, including engine sync from the pinned revision. git diff --check passes.

Not checked: an actual Steam Link session, the reporter's HID descriptor, remote gameplay, physical reconnects, rumble or multiplayer player ordering. No game files were needed or used. The reporter's separate launcher/game test is required before marking this ready.

Screenshots

Controlled native SwiftUI fixtures in all six languages. These show the existing console Home and Controllers views before recognition (no GC controller) and after accepting one Steam virtual controller. They are illustrative state captures, not screenshots of a successful Steam Link session. There are no layout or translated-string changes.

English
View Before After
Home Before home en After home en
Controllers Before controllers en After controllers en
Chinese
View Before After
Home Before home zh After home zh
Controllers Before controllers zh After controllers zh
German
View Before After
Home Before home de After home de
Controllers Before controllers de After controllers de
French
View Before After
Home Before home fr After home fr
Controllers Before controllers fr After controllers fr
Italian
View Before After
Home Before home it After home it
Controllers Before controllers it After controllers it
Swedish
View Before After
Home Before home sv After home sv
Controllers Before controllers sv After controllers sv

Scope

  • No engine file is added or changed.
  • No engine or game-profile change requiring a parallel upstream PR.
  • Before/after state captures are attached above.
  • No keys, game files or data extracted from a game in the change or attachments.

@thehobbit85 thehobbit85 added bug Something isn't working full-build Build the Mac app on this pull request for hands-on review labels Nov 7, 2026
@github-actions github-actions Bot added the launcher The NX2Apple launcher app label Nov 7, 2026
@thehobbit85

Copy link
Copy Markdown
Contributor Author

@SupermanX2006 could you test this PR through your existing iPhone Steam Link → Mac M2 Max setup, with the PS5 controller connected to the iPhone?

The draft adds a launcher-side reader for Steam's virtual controller and diagnostic information. I have validated it with synthetic input, but I cannot confirm your remote session from here. The games use a separate controller reader, so we need these results separately:

  1. Use this PR's app build. Once the Mac app build finishes, download its NX2Apple-macOS-arm64 artifact. Point your non-Steam shortcut at that app, ensuring Steam is not launching your old installed copy. From a repository checkout, tools/try-pr 874 is another way to open the artifact.
  2. Launcher over Steam Link: can the D-pad and left stick move selection, Cross/A activate, Circle/B go back, and shoulders change pages? Does the controller appear in the Controllers sheet? Please check desktop and console mode. Release a held direction, disconnect/reconnect once, and check there are no continuing or doubled presses.
  3. Game over Steam Link: launch one of your existing built games from this launcher. Separately report whether the controller is detected, both sticks and face buttons work, and button directions/layout are correct. Please name the game and its NX2Apple/engine version. No new game build is needed just to distinguish the launcher from the existing game input path.
  4. Copy diagnostics: while the Steam Link session is connected, press a few buttons and move the left stick, then use Settings > Copy diagnostics and paste the result here. The new Launcher controllers section reports whether a matching virtual device was found, claimed by GameController, opened through HID, and delivered input values. Review the report before posting. Please do not attach keys, game files or extracted game data.
  5. If launcher navigation works but the game does not, please also try adding that same built game app directly to Steam as a non-Steam game and report whether remote input then works. This helps distinguish the game process's Steam association from its controller reader.

If both launcher and gameplay work with correct mapping, a fix within NX2Apple may be sufficient. If the launcher works but gameplay still fails, or diagnostics show a virtual device claimed by GameController without usable input, we will use that evidence to determine the engine changes needed. This PR deliberately does not change the engine or claim that #731 fixed Steam Link.

@thehobbit85 thehobbit85 mentioned this pull request Nov 7, 2026
1 task done
@v0lumehi

v0lumehi commented Nov 7, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the work, @thehobbit85. We changed how the team works, so this pull request is now handled like any other outside contribution. A change to how the launcher works or looks starts as an issue, and a maintainer has to agree to the idea before the pull request is reviewed. Please open an issue for it. Until then I leave this pull request open without a milestone. Please also keep at most three pull requests open at the same time, so each one can be reviewed properly.

@thehobbit85

Copy link
Copy Markdown
Contributor Author

The existing report and investigation are #797, currently in v1.3.2. Your earlier comment distinguishes Steam Link’s virtual controller from the physical Steam Controller and places the report in the controller milestone. The proposed launcher-side reader is linked there. This PR remains a draft pending both maintainer agreement on that approach and the reporter’s separate launcher/game test. I have not opened a duplicate report or treated the synthetic tests as an end-to-end fix.

@v0lumehi

v0lumehi commented Nov 10, 2026 •

Copy link
Copy Markdown
Collaborator

Thank you @thehobbit85. Your change is part of #1097, the launcher UI overhaul, with you as co-author. Closing this one in favor of it. Please have a look there if something of yours is missing or changed.

@v0lumehi v0lumehi closed this Nov 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working full-build Build the Mac app on this pull request for hands-on review launcher The NX2Apple launcher app

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants