Skip to content

FEX: Linux Steam as an experimental Steam client (MetalSharp Wine 7.0-pre1) - #778

Open
aaf2tbz wants to merge 1 commit into
mainfrom
linux-steam-client
Open

aaf2tbz wants to merge 1 commit into
mainfrom
linux-steam-client

Conversation

@aaf2tbz

@aaf2tbz aaf2tbz commented Nov 13, 2026

Copy link
Copy Markdown
Collaborator

Adds Linux Steam, Valve's arm64 client in a small Linux VM shipped inside MetalSharp Wine 7.0-pre1 (metalsharp/MetalSharp-Wine#22), as an experimental Steam client on the FEX build. The regular build is unchanged in behaviour.

What it does

  • Setting: "Steam client: Windows / Linux (experimental)" under Launchers (steamClient config key, default windows). It only shows when the installed MetalSharp Wine carries share/steamvm/metalsharp-steam. Switching stops the running client first.
  • Start Steam (Linux mode): the first time, runs metalsharp-steam install in the background, with progress shown as "Setting up Linux Steam: ". Then it starts the VM and Steam and opens the Linux Steam window. Stop Steam shuts the VM down cleanly. Running and installed state come from status --json, cached for 2 s.
  • Shared prefix: games run in ~/.metalsharp/prefix-steam (METALSHARP_GAME_PREFIX) as the Mac user, so saves, settings and the already prepared prefix are shared with Windows Steam games. No per-game prefix is created.
  • Play (Linux mode): writes launch.env, launch-exe and launch-args as today, then a launch intent naming the per-game backend (Mullion, DXVK, VKD3D-Proton or OpenGL), then sends steam://run/<id> to Linux Steam. MetalSharp's backend choice wins for that launch; a Play from inside Steam uses Steam's tool.
  • Library: prefix-steam/drive_c/SteamLibrary/steamapps is scanned everywhere, so games installed by Linux Steam show up and launch.
  • No prefix update at Play:
    • After the Wine app is swapped (update migration, or the startup refresh), wineboot -u -r runs once in prefix-steam.
    • The startup refresh no longer replaces an installed MetalSharp Wine with an older carried one.
  • Process control:
    • Quitting MetalSharp, the updater and the migration stop the VM with metalsharp-steam stop.
    • krunkit, gvproxy, metalsharp-vmd and LinuxSteam.app are excluded from the kill lists.
  • Pins: the arm64 runtime pins move to v7.0-pre1; x86_64 stays on 6.0.

Tests

  • make -C app/src-c test, regular and FEX: pass, 0 warnings. That includes the new linux_steam_test (stand-in metalsharp-steam) and the updater stop test.
  • cargo test: 128 passed.
  • node --test app/tests/*.cjs: 13 passed.

Status: needs end-to-end testing before merge

  • Done:
    • Signed FEX test DMG built around the 7.0-pre1 runtime.
    • The real update.sh installed it over a signed 1.1.0, with every updater stage passing.
  • Not yet verified:
    • Migration did not swap the runtime. The test build and the installed app were both 1.1.0, so the post-update migration found nothing to migrate and did not swap Wine. A real update has a higher version and goes through app_update; that path and the startup swap still need checking.
    • Start Steam / Play / Stop with the real VM from inside MetalSharp.
    • That a Play triggers no prefix update.
    • Quit with the VM running.
  • Open questions:
    • Stop Steam in Linux mode also ends games in prefix-steam, as in Windows mode.
    • Direct-launch titles get no Steam client in Linux mode.
    • Play can wait up to 90 s for Linux Steam to start.
    • The test-only METALSHARP_LINUX_STEAM_COMMAND override is read by the shipped backend.

…-pre1)

Settings' new Steam client choice (steamClient, "windows" by default) can run
Valve's Linux Steam client, which MetalSharp-Wine.app 7.0-pre1 carries as
share/steamvm/metalsharp-steam, in place of Windows Steam. Its games run on the
Mac in MetalSharp Wine in the Steam prefix. FEX build only; the regular build
never takes this path.

- Backend (linux_steam.c): Start Steam runs the one-time setup as a background
  job (logs/linux-steam-setup.log, its "==> " stage in /steam/status), then
  start and show. Stop and running state follow metalsharp-steam stop and
  status --json (cached for 2 s). /steam/install is refused in Linux mode.
- Play: launch.env, launch-exe and launch-args are written as before. The game's
  lane goes to the bridge daemon as run/linux-steam/launch-intent/<appid>
  (mullion, dxvk, vkd3d or wine), and the steam://run link goes to Linux Steam,
  which is started first if needed (up to 90 s). Direct launches no longer
  start Windows Steam in Linux mode.
- Library: prefix-steam/drive_c/SteamLibrary/steamapps is scanned wherever the
  Steam roots are.
- Quit, the updater and the post-update migration stop the virtual machine
  with metalsharp-steam stop (60 s bound). krunkit, gvproxy, metalsharp-vmd and
  LinuxSteam are left out of every path-based Wine kill list.
- After a Wine app swap (update migration, startup refresh), the Steam prefix
  gets wineboot -u -r and wineserver -w, so the first Play does not wait for
  Wine's own prefix update. This runs only for a FEX-ready prefix with no
  wineserver. The startup refresh keeps an installed MetalSharp-Wine.app
  whose version is newer than the carried one.
- Pins: MetalSharp Wine 7.0-pre1 for the arm64 runtime download and the FEX
  release job. The x86_64 runtime stays at 6.0.
- Tests: linux_steam_test (a stand-in metalsharp-steam), the updater stop test,
  migration stubs, Rust tests for the stop and kill-list exclusion, and the node
  source-contract test linux-steam-client.cjs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant