feat: working_dir handler field, per-process concurrency, per-instance audio sinks#16
Merged
Merged
Conversation
Launcher-shim games run the real binary from a subdir but need cwd at a higher level — e.g. native Frozenbyte titles: the game binary is in _enchanted_edition_/bin/ while its data root (and goldberg's GseAppPath) is _enchanted_edition_, and the game's own config-GUI launcher can't be driven by gamepad-only together seats. Add an optional `working_dir` handler field (relative to the mounted game root) that overrides the cwd derivation in build_cmds. Unset = today's behavior (the exec's parent dir). Generic — replaces per-game wrapper scripts for the whole launcher-shim class: exec: _enchanted_edition_/bin/trine1_linux_32bit working_dir: _enchanted_edition_ env: "LD_LIBRARY_PATH=lib/lib32"
…dow ownership
splitux could only run ONE session per host: every launch keyed its scratch by
instance index (tmp/game-0, work-0, <backend>-overlay-0), so a 2nd concurrent
launch collided on the fuse-overlayfs mounts ("mount failed"); teardown unmounted
ALL tmp/game-* globally; the startup unit-sweep stopped other live sessions; and
the niri WM grabbed EVERY gamescope window (stacking all sessions into one column
+ cross-repositioning that crashed games).
Each `splitux launch` is its own process with one active launch, so namespace all
per-launch state by a per-process launch id:
- paths: set_launch_ns() / launch_tmp_dir() = tmp/<launch_id>; scratch (game-N,
work-N, <backend>-overlay-N, game-patches) now lives under it. overlays.rs,
build_cmds.rs and backend overlay all route through it (mount + cwd agree).
- teardown: fuse_overlayfs_unmount_gamedirs() is launch-scoped (only this
launch's tmp/<ns>, then removes it) — concurrent sessions untouched. session.rs
end-of-launch cleanup uses it instead of the blanket clear_tmp().
- startup: sweep_orphan_units() skips units whose owner pid is still alive (other
live sessions); reap_orphan_launch_scratch() removes only DEAD-pid tmp/<ns>.
- WM: niri get_gamescope_windows() filters to windows whose pid cgroup carries
THIS launch's namespace (splitux-<ns>), so each session manages only its own
gamescope window. Falls back to all when unscoped.
Validated: 3 native couch games launched concurrently — distinct namespaces, 6
seats, each WM "Found 1 window" + mapped, no mount collision.
…eanup Per-instance capture/mute virtual sinks for both PulseAudio and PipeWire, with orphan-sink reaping that recovers from dead launches without disturbing live concurrent sessions. Threads per-instance audio and namespaced scratch through launch (scope/build_cmds/execute), bwrap base, and together so multiple sessions run isolated side by side.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Foundation of the split PR stack (#12 → #13 → #14 → #15 are based on this branch). Three commits:
working_dir— override the game process cwd for launcher-shim titles whose real binary lives in a subdir but must run with cwd higher up (e.g. native Frozenbyte titles).tmp/<launch_ns>) + per-launch window ownership so two concurrentsplituxprocesses don't collide on scratch dirs or grab each other's gamescope windows.Merge this first; the four
split/*PRs then stack on top in order.