6.6 KiB
steam-frame-nix
Home Manager modules for the
Valve Steam Frame (SteamOS, aarch64-linux, standalone home-manager). They
work around quirks of the Frame's two graphical sessions,
enable hardware video decoding in Jellyfin, and extend Steam's and SteamVR's
UIs at runtime.
Everything is declarative: files are links into the Nix store, UI patches
live in memory. The few things written elsewhere are
listed and removed by steam-frame-nix-cleanup.
Features
All options live under steamFrame.*; the portal fix and clipboard sync are
on by default, everything else is opt-in. Full reference:
docs/options.md.
Session and desktop:
- Portal fix (
session.portalFix): apps in the Steam session can open links. - Clipboard sync
(
clipboardSync): one clipboard for the Steam session and the nested desktop. - Session settings
(
session.*): outer bus and user services, for launchers and the other modules.
Keyboard:
- Keyboard layout (
keyboard.layout,keyboard.variant): XKB layout for the Steam session. - Extra keys (
keyboard.vr.extraKeys): Esc/Ctrl/Alt, arrows, Delete, real chords and AltGr/non-ASCII characters on the VR keyboard. - Swipe and suggestions
(
keyboard.vr): swipe typing, corrections, completions, Backspace drag.
VR "+" menu:
- Launcher menu (
launcherMenu.*): sorted, Desktop pinned, closes on launch, no double launches, grid of tiles, all programs without Developer Mode. - Hidden apps
(
launcherMenu.hiddenApps) and icon fallbacks (launcherMenu.iconFallbacks, on) for Konsole and KDE System Settings.
SteamVR dashboard (needs the SteamVR debugger, turned on automatically):
- Dashboard windows
(
dashboard.windows): larger max scale and push-back distance. - Steam close button
(
dashboard.steamCloseButton): an X that hides the Steam window. - Window curvature
(
dashboard.windowCurvature): adjustable curvature per window. - Window control bar
(
dashboard.frameControls): move controls between bar and three-dot menu.
Apps:
- Firefox (
firefox): launcher for the Flatpak with a VR fullscreen fix, optional AV1 off, a separate desktop profile. - Jellyfin (
jellyfin.hardwareDecoding): hardware video decoding in the Jellyfin Desktop Flatpak.
Writing your own patches of Steam's UI: docs/ui-patches.md (also: checking signatures after a Steam update).
Install
On the Frame (or a Steam Deck), in a terminal (Konsole in desktop mode or the nested desktop):
curl -fsSL https://steam-frame-nix.lhns.de | bash -s -- install
The short link redirects to
install.sh
on main. sudo needs a password: run passwd first if you never set one.
It installs Nix (unless it already works), creates ~/nix-config from the
template (or uses ~/.config/home-manager, or
--flake <dir-or-flakeref>) and runs home-manager switch; conflicting
dotfiles are renamed to *.hm-backup-<time>. Details:
set up by install.sh.
Re-running it just switches again.
curl -fsSL https://steam-frame-nix.lhns.de | bash -s -- status # Nix, generation, services
curl -fsSL https://steam-frame-nix.lhns.de | bash -s -- uninstall # --keep-nix keeps Nix
Manual setup (Nix with flakes and standalone home-manager):
nix flake init -t github:lhns/steam-frame-nix creates a commented
flake.nix and home.nix (template/). Or add the input to
your own flake:
inputs.steam-frame-nix = {
url = "github:lhns/steam-frame-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
# homeManagerConfiguration { modules = [ steam-frame-nix.homeManagerModules.default ./home.nix ]; … }
default imports all modules; single ones:
homeManagerModules.{session,portal,keyboard-layout,steam-keyboard-patch,vr-keyboard,hidden-apps,steam-ui-patches,launcher-menu,steamvr-debugger,cleanup,dashboard-windows,steam-close-button,window-curvature,frame-controls,clipboard-sync,firefox,jellyfin}
(each imports cleanup).
Usage
In ~/nix-config/home.nix (the template's example, uncommented):
steamFrame = {
keyboard.layout = "de";
keyboard.vr.extraKeys.enable = true; # Esc/Ctrl/Alt/arrows in VR
keyboard.vr.enable = true; # swipe, suggestions, Backspace drag
launcherMenu = {
sort = true;
pinDesktop = "bottom";
closeOnLaunch = true;
launchDebounceSeconds = 10;
grid = { enable = true; columns = 4; maxRows = 4; };
showAllApps = true;
# Listed in the "+" menu only with showAllApps or Developer Mode:
hiddenApps = [ "lxterminal" "cmake-gui" "firewall-config" "renderdoc" ];
};
dashboard = {
windows.maxScale = 4.0;
windows.distance.world.max = 10.0;
windows.distance.theater.max = 12.0;
steamCloseButton.enable = true;
windowCurvature.enable = true;
frameControls.enable = true;
};
firefox.enable = true;
firefox.disableAv1 = true;
jellyfin.hardwareDecoding.enable = true;
};
Then switch from a terminal in the nested desktop (so clipboard-sync restarts with the desktop's environment):
home-manager switch # manual setup: --flake <dir>#<user>
Rollback and uninstall
Run <store path>/activate of a generation from home-manager generations.
After rolling back to a generation without steam-frame-nix (or older than
2026-09-29), remove what the newer one wrote outside the store:
curl -fsSL https://steam-frame-nix.lhns.de | bash -s -- cleanup --all
# or: nix run github:lhns/steam-frame-nix#cleanup -- --all
install.sh uninstall (above) reverts the UI patches, runs cleanup --all,
home-manager uninstall and removes Nix; your configuration, backups, app
data and Flatpaks stay. To drop steam-frame-nix from a configuration you
keep, run steam-frame-nix-cleanup --all first, then remove it and switch.
Details: rollback,
uninstall.