chore: use nyx caches for steamdeck

This commit is contained in:
Bogdan Buduroiu 2026-09-14 11:43:15 +08:00
commit c87213d3c4
Signed by: bogdan
GPG key ID: F71EF75A4C09A095
7 changed files with 220 additions and 108 deletions

View file

@ -4,7 +4,36 @@ Noctalia 5.0.1 replaces Waybar, Walker/Elephant, Mako, swaylock/hyprlock,
swayidle/hypridle, swaybg/hyprpaper, meeting guard, and `theme-switch`.
Their modules, launcher/locker/wallpaper flake inputs, Walker cache, and
Waybar-specific passwordless WireGuard polling rules are removed.
Hyprland remains a compositor for the portable profiles; Framework uses Niri.
Framework, Phantom and Steam Deck use Niri. The live ISO still uses Hyprland.
## Portable profiles
Phantom inherits the Framework applications, plugins and shared Niri bindings.
`desktop.niri.portable` omits Framework's output placement and workspace pins,
letting Niri discover the connected displays. Brightness commands use the focused
display. The source `home/programs/wayland/niri.kdl` remains unchanged.
Its tmpfs root and selective encrypted persistence remain in place; Noctalia
runtime settings, clipboard history and generated themes are ephemeral. See
`hosts/phantom/README.md` for the dedicated WireGuard peer provisioning requirement.
Steam Deck uses the same shell and bindings with a smaller application selection.
Obsidian and Mullvad Browser launch shortcuts/autostarts are omitted. Ghostty,
Firefox, Yazi, Newsboat, screenshots and recording are available. The Deck does
not import Framework's account integrations or plugins. Noctalia's idle suspend
is disabled there so the media server stays reachable; locking and screen-off
remain enabled. Desktop login still locks immediately, so ensure the `deck`
account has a usable password before switching from Gaming Mode.
Jovian's “Switch to Desktop” now selects `niri`. In Noctalia's launcher, choose
“Return to Gaming Mode” to invoke Jovian's `steamosctl switch-to-game-mode`.
Steam Deck now uses Nyx's vendored Jovian, with nixpkgs and Home Manager following
Nyx's pins independently of Framework's unstable packages. The current gaming
stack selects `7.2.4-valve1`; its Valve kernel patches remain enabled. Update
the `nyx` input deliberately to advance the gaming stack together. Nyx's cache
supplies the checked kernel and 64-bit graphics outputs; 32-bit Valve graphics
may still need compiling on the build machine. Validate the session
round trip, panel orientation, touch input, X11 games and suspend/resume on the
actual Deck before making it the boot default.
`home/programs/wayland/noctalia.nix` is imported by the shared Wayland profile.
`noctalia-templates.nix` adds community templates to the Framework-derived

178
flake.lock generated
View file

@ -390,6 +390,20 @@
"type": "github"
}
},
"flake-schemas": {
"locked": {
"lastModified": 1780327564,
"narHash": "sha256-HiRPtA0spK+Dkgbhz/1zW9glXxNVB+L4Rj2VYmdawb8=",
"rev": "6cc9bd98891b1fc6bb2b8cb3277df8bc72799ca6",
"revCount": 149,
"type": "tarball",
"url": "https://api.flakehub.com/f/pinned/DeterminateSystems/flake-schemas/0.5.0/019e83cf-9af3-78b1-ac5b-70e68ad1efe1/source.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://flakehub.com/f/DeterminateSystems/flake-schemas/%3D0.5.0.tar.gz"
}
},
"flake-utils": {
"inputs": {
"systems": "systems_3"
@ -565,26 +579,6 @@
"type": "github"
}
},
"home-manager-unstable": {
"inputs": {
"nixpkgs": [
"nixpkgs-unstable"
]
},
"locked": {
"lastModified": 1788651960,
"narHash": "sha256-v9wJd32eZ2bvhBzVOd7TIjLQd011P7nwOhjKtWlci5I=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "2c0350c759688177331b8f5242311fae8877bdb3",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"home-manager_2": {
"inputs": {
"nixpkgs": [
@ -627,6 +621,27 @@
"type": "github"
}
},
"home-manager_4": {
"inputs": {
"nixpkgs": [
"nyx",
"nixpkgs"
]
},
"locked": {
"lastModified": 1789230132,
"narHash": "sha256-u7aiV01Iu11NGOjXbxoCCrew6n0vo/LnULqOvZa+Agc=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "17bf375751d457efa3897c7c3d68106616b1d469",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"hyprcursor": {
"inputs": {
"hyprlang": [
@ -986,25 +1001,6 @@
"type": "github"
}
},
"jovian-nixos": {
"inputs": {
"nix-github-actions": "nix-github-actions",
"nixpkgs": "nixpkgs_5"
},
"locked": {
"lastModified": 1787899316,
"narHash": "sha256-1y0aG4j8ZzUWiUlnAdnC6VZxkqbp7UDuFE222f3u/MQ=",
"owner": "Jovian-Experiments",
"repo": "Jovian-NixOS",
"rev": "9ffc5dc5af266c2e44066f22e5496274cf93a1a6",
"type": "github"
},
"original": {
"owner": "Jovian-Experiments",
"repo": "Jovian-NixOS",
"type": "github"
}
},
"mcp-servers-nix": {
"inputs": {
"nixpkgs": [
@ -1065,28 +1061,6 @@
"type": "github"
}
},
"nix-github-actions": {
"inputs": {
"nixpkgs": [
"jovian-nixos",
"nixpkgs"
]
},
"locked": {
"lastModified": 1729697500,
"narHash": "sha256-VFTWrbzDlZyFHHb1AlKRiD/qqCJIripXKiCSFS8fAOY=",
"owner": "zhaofengli",
"repo": "nix-github-actions",
"rev": "e418aeb728b6aa5ca8c5c71974e7159c2df1d8cf",
"type": "github"
},
"original": {
"owner": "zhaofengli",
"ref": "matrix-name",
"repo": "nix-github-actions",
"type": "github"
}
},
"nix-minecraft": {
"inputs": {
"flake-compat": "flake-compat_3",
@ -1160,7 +1134,7 @@
},
"nixos-hardware": {
"inputs": {
"nixpkgs": "nixpkgs_6"
"nixpkgs": "nixpkgs_5"
},
"locked": {
"lastModified": 1788335262,
@ -1274,22 +1248,6 @@
}
},
"nixpkgs_5": {
"locked": {
"lastModified": 1787498568,
"narHash": "sha256-9i/VTdusq/+NM/tz+J1Re+ojkMB8MBf0QshnYfzHz30=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "56c02bc00adcf003215cc4bd996d6efaf4cff188",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_6": {
"locked": {
"lastModified": 1767892417,
"narHash": "sha256-8bW3q88CEg2u4hSP66Vf4lpbLonHz7hqDNBMcCY7E9U=",
@ -1302,7 +1260,7 @@
"url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
}
},
"nixpkgs_7": {
"nixpkgs_6": {
"locked": {
"lastModified": 1788921488,
"narHash": "sha256-8+xWRxEkD6l217cIUdRxfeUGS9lQX0hVtUuNVsBaDzk=",
@ -1318,7 +1276,7 @@
"type": "github"
}
},
"nixpkgs_8": {
"nixpkgs_7": {
"locked": {
"lastModified": 1788614874,
"narHash": "sha256-PRK1fSEiAcO29DkUoOlsVLGYRK3h1YKVr+qQJB0VcYQ=",
@ -1331,6 +1289,22 @@
"url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.zst"
}
},
"nixpkgs_8": {
"locked": {
"lastModified": 1789149629,
"narHash": "sha256-H6GwaZzZf+4npqv0tph94w9tZddSjFjmQrVsW0z78uk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "eaad089433ca2bb662274377d33df3d0e51ef28b",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_9": {
"locked": {
"lastModified": 1710272261,
@ -1349,7 +1323,7 @@
},
"noctalia": {
"inputs": {
"nixpkgs": "nixpkgs_8"
"nixpkgs": "nixpkgs_7"
},
"locked": {
"lastModified": 1789006712,
@ -1462,6 +1436,27 @@
},
"parent": []
},
"nyx": {
"inputs": {
"flake-schemas": "flake-schemas",
"home-manager": "home-manager_4",
"nixpkgs": "nixpkgs_8"
},
"locked": {
"lastModified": 1789331472,
"narHash": "sha256-RBd2QyJCjg5z+x7J+SlaihMYeVSULi//t5IofGFfRP0=",
"owner": "chaotic-cx",
"repo": "nyx",
"rev": "be105ca0649b88a9a2d63cfa877c459239fb5ad8",
"type": "github"
},
"original": {
"owner": "chaotic-cx",
"ref": "nyxpkgs-unstable",
"repo": "nyx",
"type": "github"
}
},
"openapi-tui": {
"inputs": {
"fenix": "fenix",
@ -1563,21 +1558,28 @@
"helix": "helix",
"hermes-agent": "hermes-agent",
"home-manager": "home-manager_2",
"home-manager-unstable": "home-manager-unstable",
"home-manager-steamdeck": [
"nyx",
"home-manager"
],
"hyprland": "hyprland",
"hyprland-contrib": "hyprland-contrib",
"impermanence": "impermanence",
"jovian-nixos": "jovian-nixos",
"mcp-servers-nix": "mcp-servers-nix",
"nix-minecraft": "nix-minecraft",
"nix4nvchad": "nix4nvchad",
"nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs_7",
"nixpkgs": "nixpkgs_6",
"nixpkgs-steamdeck": [
"nyx",
"nixpkgs"
],
"nixpkgs-unstable": "nixpkgs-unstable",
"noctalia": "noctalia",
"noctalia-templates": "noctalia-templates",
"nur": "nur",
"nvchad-config": "nvchad-config",
"nyx": "nyx",
"openapi-tui": "openapi-tui",
"secrets": "secrets",
"sops-nix": "sops-nix",
@ -1667,11 +1669,11 @@
},
"secrets": {
"locked": {
"lastModified": 1789277992,
"narHash": "sha256-LybxC9vVNX4Vr3pQoWQoxvYRvkkK84Iub7jcuj/aHm0=",
"lastModified": 1789360733,
"narHash": "sha256-POhH8KvdDRbnWICVF6Y++DMFjKJt4qVPvv34CYhU00U=",
"ref": "refs/heads/main",
"rev": "87a665f14091d32e86b2045c06ee7cefed151cd3",
"revCount": 22,
"rev": "fd9a0696954d8c5929503671e1b05c3e6d43c79d",
"revCount": 23,
"type": "git",
"url": "ssh://forgejo@git.oolongtechnologies.io/bogdan/secrets.git"
},

View file

@ -47,11 +47,11 @@
inputs.nixpkgs.follows = "nixpkgs";
};
# Home Manager for Steam Deck (follows unstable for Jovian-NixOS compatibility)
home-manager-unstable = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs-unstable";
};
# Steam Deck has an independent, jointly updated gaming stack.
# Preserve Nyx's pins so its binary cache can supply Jovian packages.
nyx.url = "github:chaotic-cx/nyx/nyxpkgs-unstable";
nixpkgs-steamdeck.follows = "nyx/nixpkgs";
home-manager-steamdeck.follows = "nyx/home-manager";
# Hyprland
@ -72,9 +72,7 @@
# upstream's lock, and following ours would force a full local rebuild
hermes-agent.url = "github:NousResearch/hermes-agent";
# Steam Deck support via Jovian-NixOS
# Note: Don't override nixpkgs to ensure cache hits for pre-built binaries
jovian-nixos.url = "github:Jovian-Experiments/Jovian-NixOS";
# Jovian is vendored by Nyx; hosts/default.nix selects that matching module.
mcp-servers-nix = {
url = "github:natsukium/mcp-servers-nix";

View file

@ -1,4 +1,4 @@
{ config, pkgs, inputs, ... }:
{ config, lib, pkgs, inputs, ... }:
{
imports = [
@ -10,8 +10,40 @@
# by the openrct2 coding-agent fork, whose in-game terminal launches `claude`.
../../terminal/programs/claude
./media.nix
../../programs/wayland
../../programs/wayland/niri.nix
../../terminal/emulators/ghostty.nix
../../services/media/playerctl.nix
];
desktop.niri = {
portable = true;
omittedApplications = [ "obsidian" "mullvad-browser" ];
# Niri reads the kernel's panel orientation; keep the small display at 1x.
extraConfig = ''
output "eDP-1" {
scale 1
}
'';
};
programs.firefox.enable = true;
programs.firefox.configPath = ".mozilla/firefox";
programs.yazi.enable = true;
programs.newsboat.enable = true;
gtk.enable = true;
home.pointerCursor = {
enable = true;
name = "BreezeX-RosePine-Linux";
package = pkgs.rose-pine-cursor;
size = 24;
gtk.enable = true;
};
# Desktop inactivity must not suspend the stationary media server.
programs.noctalia.settings.idle.behavior.suspend.enabled = lib.mkForce false;
# Gaming Mode also starts graphical-session.target. Only start the desktop
# shell when Niri has imported its socket into the user manager environment.
systemd.user.services.noctalia.Unit.ConditionEnvironment = "NIRI_SOCKET";
home = {
username = "deck";
homeDirectory = "/home/deck";
@ -29,7 +61,7 @@
nixpkgs.config.allowUnfree = true;
# keepassxc.nix sets `programs.keepassxc.autostart = true`, which (on
# home-manager-unstable, used by this host) asserts xdg.autostart must be on.
# Nyx's Home Manager, used by this host) asserts xdg.autostart must be on.
# Framework13's stable HM lacks that assertion, so this is only needed here.
xdg.autostart.enable = true;
}

View file

@ -1,6 +1,22 @@
{ inputs, pkgs, ... }:
{ config, inputs, lib, pkgs, ... }:
let
cfg = config.desktop.niri;
baseConfig = builtins.readFile ./niri.kdl;
# Preserve the hand-written shared config; portable hosts omit only the
# Framework output section, output pins and panel-specific brightness target.
beforeOutputs = builtins.head (lib.splitString "// ----- outputs (framework13)" baseConfig);
afterOutputs = builtins.elemAt (lib.splitString "// ----- layout" baseConfig) 1;
portableConfig = lib.concatStringsSep "\n" (builtins.filter
(line: !(lib.hasInfix "open-on-output " line))
(lib.splitString "\n" (beforeOutputs + "// ----- layout" + afterOutputs)));
configText = lib.concatStringsSep "\n" (builtins.filter
(line: !(builtins.any (command: lib.hasInfix ("spawn \"" + command + "\"") line
|| line == "spawn-at-startup \"${command}\"") cfg.omittedApplications))
(lib.splitString "\n" (if cfg.portable then lib.replaceStrings
[ "\"brightness-up\" \"eDP-1\"" "\"brightness-down\" \"eDP-1\"" ]
[ "\"brightness-up\"" "\"brightness-down\"" ] portableConfig else baseConfig)));
source = pkgs.writeText "niri-config.kdl" (configText + "\n" + cfg.extraConfig);
noctalia = inputs.noctalia.packages.${pkgs.stdenv.hostPlatform.system}.default;
# Validate first login without colors and both generated theme modes.
# Only config.kdl is installed: Noctalia owns the writable color include.
@ -10,7 +26,7 @@ let
mkdir -p $out
export GSETTINGS_BACKEND=memory
export NOCTALIA_CONFIG_HOME="$TMPDIR" NOCTALIA_STATE_HOME="$TMPDIR"
cp ${./niri.kdl} $out/config.kdl
cp ${source} $out/config.kdl
niri validate -c $out/config.kdl
for mode in dark light; do
noctalia theme ${../../wallpapers/taipei-toner-4k-negative.png} \
@ -20,5 +36,18 @@ let
done
'';
in {
xdg.configFile."niri/config.kdl".source = "${configDir}/config.kdl";
options.desktop.niri = {
portable = lib.mkEnableOption "automatic output placement without Framework monitor pins";
omittedApplications = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "Applications whose shared launch bindings and autostarts are omitted.";
};
extraConfig = lib.mkOption {
type = lib.types.lines;
default = "";
description = "Host-specific Niri configuration appended to the shared layout.";
};
};
config.xdg.configFile."niri/config.kdl".source = "${configDir}/config.kdl";
}

View file

@ -10,6 +10,15 @@
inherit (import mod) laptop steamdeck iso phantom;
specialArgs = { inherit inputs self;};
# Shared modules may select unstable applications. Scope those selections
# to the Deck's pin without changing Framework or Phantom's package set.
deckSpecialArgs = {
inherit self;
inputs = inputs // {
nixpkgs-unstable = inputs.nixpkgs-steamdeck;
jovian-nixos = inputs.nyx.vendored.jovian;
};
};
in {
framework13 = nixosSystem {
inherit specialArgs;
@ -48,18 +57,18 @@
];
};
# Steam Deck with Jovian-NixOS (requires nixpkgs-unstable)
steamdeck = inputs.nixpkgs-unstable.lib.nixosSystem {
inherit specialArgs;
# Nyx's vendored Jovian and its matching nixpkgs/Home Manager pins.
steamdeck = inputs.nixpkgs-steamdeck.lib.nixosSystem {
specialArgs = deckSpecialArgs;
modules = steamdeck
++ [
./steamdeck
# Jovian-NixOS for Steam Deck support
inputs.jovian-nixos.nixosModules.default
inputs.nyx.vendored.jovian.nixosModules.default
inputs.nyx.nixosModules.default
# Home Manager (unstable, follows nixpkgs-unstable for Jovian compatibility)
inputs.home-manager-unstable.nixosModules.home-manager
inputs.home-manager-steamdeck.nixosModules.home-manager
# Secrets management
inputs.sops-nix.nixosModules.sops
@ -70,7 +79,7 @@
{
home-manager = {
users.deck.imports = homeImports."deck@steamdeck";
extraSpecialArgs = specialArgs;
extraSpecialArgs = deckSpecialArgs;
backupFileExtension = ".hm-backup";
sharedModules = [
inputs.sops-nix.homeManagerModules.sops

View file

@ -8,6 +8,9 @@ in
./hardware-configuration.nix
./transmission.nix
./kodi.nix
../../system/programs/niri
../../system/programs/fonts.nix
../../system/services/brightnessctl.nix
];
# Steam Deck hardware support via Jovian-NixOS
@ -30,16 +33,19 @@ in
autoStart = true;
user = mainUser;
# Switch to Plasma desktop when using "Switch to Desktop" in Gaming Mode
desktopSession = "plasma";
# Jovian owns the session switch in both directions.
desktopSession = "niri";
};
steamos.useSteamOSConfig = true;
};
# Plasma Desktop for "Switch to Desktop" functionality
services.desktopManager.plasma6.enable = true;
# Keep Nyx's vendored Jovian kernel, including its Valve patches.
# enableKernelPatches selects linuxPackages_jovian, including Deck drivers.
jovian.devices.steamdeck.enableKernelPatches = true;
services.upower.enable = true;
programs.dconf.enable = true;
# System configuration
networking.hostName = "steamdeck";
@ -122,6 +128,13 @@ in
# Packages
environment.systemPackages = with pkgs; [
(makeDesktopItem {
name = "return-to-gaming-mode";
desktopName = "Return to Gaming Mode";
exec = "${pkgs.steamos-manager}/bin/steamosctl switch-to-game-mode";
icon = "steam";
categories = [ "Game" ];
})
vim
git
htop