diff options
Diffstat (limited to 'nixos/modules/programs/steam.nix')
-rw-r--r-- | nixos/modules/programs/steam.nix | 111 |
1 files changed, 73 insertions, 38 deletions
diff --git a/nixos/modules/programs/steam.nix b/nixos/modules/programs/steam.nix index 58aa0aa25b082..5138588dbd3e5 100644 --- a/nixos/modules/programs/steam.nix +++ b/nixos/modules/programs/steam.nix @@ -1,17 +1,17 @@ { config, lib, pkgs, ... }: -with lib; - let cfg = config.programs.steam; gamescopeCfg = config.programs.gamescope; + extraCompatPaths = lib.makeSearchPathOutput "steamcompattool" "" cfg.extraCompatPackages; + steam-gamescope = let exports = builtins.attrValues (builtins.mapAttrs (n: v: "export ${n}=${v}") cfg.gamescopeSession.env); in pkgs.writeShellScriptBin "steam-gamescope" '' ${builtins.concatStringsSep "\n" exports} - gamescope --steam ${toString cfg.gamescopeSession.args} -- steam -tenfoot -pipewire-dmabuf + gamescope --steam ${builtins.toString cfg.gamescopeSession.args} -- steam -tenfoot -pipewire-dmabuf ''; gamescopeSessionFile = @@ -24,13 +24,13 @@ let '').overrideAttrs (_: { passthru.providedSessions = [ "steam" ]; }); in { options.programs.steam = { - enable = mkEnableOption "steam"; + enable = lib.mkEnableOption "steam"; - package = mkOption { - type = types.package; + package = lib.mkOption { + type = lib.types.package; default = pkgs.steam; - defaultText = literalExpression "pkgs.steam"; - example = literalExpression '' + defaultText = lib.literalExpression "pkgs.steam"; + example = lib.literalExpression '' pkgs.steam-small.override { extraEnv = { MANGOHUD = true; @@ -44,8 +44,8 @@ in { ''; apply = steam: steam.override (prev: { extraEnv = (lib.optionalAttrs (cfg.extraCompatPackages != [ ]) { - STEAM_EXTRA_COMPAT_TOOLS_PATHS = makeSearchPathOutput "steamcompattool" "" cfg.extraCompatPackages; - }) // (optionalAttrs cfg.extest.enable { + STEAM_EXTRA_COMPAT_TOOLS_PATHS = extraCompatPaths; + }) // (lib.optionalAttrs cfg.extest.enable { LD_PRELOAD = "${pkgs.pkgsi686Linux.extest}/lib/libextest.so"; }) // (prev.extraEnv or {}); extraLibraries = pkgs: let @@ -55,7 +55,8 @@ in { then [ package ] ++ extraPackages else [ package32 ] ++ extraPackages32; in prevLibs ++ additionalLibs; - } // optionalAttrs (cfg.gamescopeSession.enable && gamescopeCfg.capSysNice) + extraPkgs = p: (cfg.extraPackages ++ lib.optionals (prev ? extraPkgs) (prev.extraPkgs p)); + } // lib.optionalAttrs (cfg.gamescopeSession.enable && gamescopeCfg.capSysNice) { buildFHSEnv = pkgs.buildFHSEnv.override { # use the setuid wrapped bubblewrap @@ -71,10 +72,23 @@ in { ''; }; - extraCompatPackages = mkOption { - type = types.listOf types.package; + extraPackages = lib.mkOption { + type = lib.types.listOf lib.types.package; + default = [ ]; + example = lib.literalExpression '' + with pkgs; [ + gamescope + ] + ''; + description = '' + Additional packages to add to the Steam environment. + ''; + }; + + extraCompatPackages = lib.mkOption { + type = lib.types.listOf lib.types.package; default = [ ]; - example = literalExpression '' + example = lib.literalExpression '' with pkgs; [ proton-ge-bin ] @@ -88,46 +102,59 @@ in { ''; }; - remotePlay.openFirewall = mkOption { - type = types.bool; + fontPackages = lib.mkOption { + type = lib.types.listOf lib.types.package; + # `fonts.packages` is a list of paths now, filter out which are not packages + default = builtins.filter lib.types.package.check config.fonts.packages; + defaultText = lib.literalExpression "builtins.filter lib.types.package.check config.fonts.packages"; + example = lib.literalExpression "with pkgs; [ source-han-sans ]"; + description = '' + Font packages to use in Steam. + + Defaults to system fonts, but could be overridden to use other fonts — useful for users who would like to customize CJK fonts used in Steam. According to the [upstream issue](https://github.com/ValveSoftware/steam-for-linux/issues/10422#issuecomment-1944396010), Steam only follows the per-user fontconfig configuration. + ''; + }; + + remotePlay.openFirewall = lib.mkOption { + type = lib.types.bool; default = false; description = '' Open ports in the firewall for Steam Remote Play. ''; }; - dedicatedServer.openFirewall = mkOption { - type = types.bool; + dedicatedServer.openFirewall = lib.mkOption { + type = lib.types.bool; default = false; description = '' Open ports in the firewall for Source Dedicated Server. ''; }; - localNetworkGameTransfers.openFirewall = mkOption { - type = types.bool; + localNetworkGameTransfers.openFirewall = lib.mkOption { + type = lib.types.bool; default = false; description = '' Open ports in the firewall for Steam Local Network Game Transfers. ''; }; - gamescopeSession = mkOption { + gamescopeSession = lib.mkOption { description = "Run a GameScope driven Steam session from your display-manager"; default = {}; - type = types.submodule { + type = lib.types.submodule { options = { - enable = mkEnableOption "GameScope Session"; - args = mkOption { - type = types.listOf types.str; + enable = lib.mkEnableOption "GameScope Session"; + args = lib.mkOption { + type = lib.types.listOf lib.types.str; default = [ ]; description = '' Arguments to be passed to GameScope for the session. ''; }; - env = mkOption { - type = types.attrsOf types.str; + env = lib.mkOption { + type = lib.types.attrsOf lib.types.str; default = { }; description = '' Environmental variables to be passed to GameScope for the session. @@ -137,20 +164,25 @@ in { }; }; - extest.enable = mkEnableOption '' + extest.enable = lib.mkEnableOption '' Load the extest library into Steam, to translate X11 input events to uinput events (e.g. for using Steam Input on Wayland) ''; + + protontricks = { + enable = lib.mkEnableOption "protontricks, a simple wrapper for running Winetricks commands for Proton-enabled games"; + package = lib.mkPackageOption pkgs "protontricks" { }; + }; }; - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { hardware.opengl = { # this fixes the "glXChooseVisual failed" bug, context: https://github.com/NixOS/nixpkgs/issues/47932 enable = true; driSupport = true; driSupport32Bit = true; }; - security.wrappers = mkIf (cfg.gamescopeSession.enable && gamescopeCfg.capSysNice) { + security.wrappers = lib.mkIf (cfg.gamescopeSession.enable && gamescopeCfg.capSysNice) { # needed or steam fails bwrap = { owner = "root"; @@ -160,8 +192,10 @@ in { }; }; - programs.gamescope.enable = mkDefault cfg.gamescopeSession.enable; - services.displayManager.sessionPackages = mkIf cfg.gamescopeSession.enable [ gamescopeSessionFile ]; + programs.steam.extraPackages = cfg.fontPackages; + + programs.gamescope.enable = lib.mkDefault cfg.gamescopeSession.enable; + services.displayManager.sessionPackages = lib.mkIf cfg.gamescopeSession.enable [ gamescopeSessionFile ]; # optionally enable 32bit pulseaudio support if pulseaudio is enabled hardware.pulseaudio.support32Bit = config.hardware.pulseaudio.enable; @@ -171,28 +205,29 @@ in { environment.systemPackages = [ cfg.package cfg.package.run - ] ++ lib.optional cfg.gamescopeSession.enable steam-gamescope; + ] ++ lib.optional cfg.gamescopeSession.enable steam-gamescope + ++ lib.optional cfg.protontricks.enable (cfg.protontricks.package.override { inherit extraCompatPaths; }); networking.firewall = lib.mkMerge [ - (mkIf (cfg.remotePlay.openFirewall || cfg.localNetworkGameTransfers.openFirewall) { + (lib.mkIf (cfg.remotePlay.openFirewall || cfg.localNetworkGameTransfers.openFirewall) { allowedUDPPorts = [ 27036 ]; # Peer discovery }) - (mkIf cfg.remotePlay.openFirewall { + (lib.mkIf cfg.remotePlay.openFirewall { allowedTCPPorts = [ 27036 ]; allowedUDPPortRanges = [ { from = 27031; to = 27035; } ]; }) - (mkIf cfg.dedicatedServer.openFirewall { + (lib.mkIf cfg.dedicatedServer.openFirewall { allowedTCPPorts = [ 27015 ]; # SRCDS Rcon port allowedUDPPorts = [ 27015 ]; # Gameplay traffic }) - (mkIf cfg.localNetworkGameTransfers.openFirewall { + (lib.mkIf cfg.localNetworkGameTransfers.openFirewall { allowedTCPPorts = [ 27040 ]; # Data transfers }) ]; }; - meta.maintainers = teams.steam; + meta.maintainers = lib.teams.steam.members; } |