at 23.11-pre 4.9 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.programs.steam; 7 gamescopeCfg = config.programs.gamescope; 8 9 steam-gamescope = let 10 exports = builtins.attrValues (builtins.mapAttrs (n: v: "export ${n}=${v}") cfg.gamescopeSession.env); 11 in 12 pkgs.writeShellScriptBin "steam-gamescope" '' 13 ${builtins.concatStringsSep "\n" exports} 14 gamescope --steam ${toString cfg.gamescopeSession.args} -- steam -tenfoot -pipewire-dmabuf 15 ''; 16 17 gamescopeSessionFile = 18 (pkgs.writeTextDir "share/wayland-sessions/steam.desktop" '' 19 [Desktop Entry] 20 Name=Steam 21 Comment=A digital distribution platform 22 Exec=${steam-gamescope}/bin/steam-gamescope 23 Type=Application 24 '').overrideAttrs (_: { passthru.providedSessions = [ "steam" ]; }); 25in { 26 options.programs.steam = { 27 enable = mkEnableOption (lib.mdDoc "steam"); 28 29 package = mkOption { 30 type = types.package; 31 default = pkgs.steam; 32 defaultText = literalExpression "pkgs.steam"; 33 example = literalExpression '' 34 pkgs.steam-small.override { 35 extraEnv = { 36 MANGOHUD = true; 37 OBS_VKCAPTURE = true; 38 RADV_TEX_ANISO = 16; 39 }; 40 extraLibraries = p: with p; [ 41 atk 42 ]; 43 } 44 ''; 45 apply = steam: steam.override (prev: { 46 extraLibraries = pkgs: let 47 prevLibs = if prev ? extraLibraries then prev.extraLibraries pkgs else [ ]; 48 additionalLibs = with config.hardware.opengl; 49 if pkgs.stdenv.hostPlatform.is64bit 50 then [ package ] ++ extraPackages 51 else [ package32 ] ++ extraPackages32; 52 in prevLibs ++ additionalLibs; 53 } // optionalAttrs (cfg.gamescopeSession.enable && gamescopeCfg.capSysNice) 54 { 55 buildFHSEnv = pkgs.buildFHSEnv.override { 56 # use the setuid wrapped bubblewrap 57 bubblewrap = "${config.security.wrapperDir}/.."; 58 }; 59 }); 60 description = lib.mdDoc '' 61 The Steam package to use. Additional libraries are added from the system 62 configuration to ensure graphics work properly. 63 64 Use this option to customise the Steam package rather than adding your 65 custom Steam to {option}`environment.systemPackages` yourself. 66 ''; 67 }; 68 69 remotePlay.openFirewall = mkOption { 70 type = types.bool; 71 default = false; 72 description = lib.mdDoc '' 73 Open ports in the firewall for Steam Remote Play. 74 ''; 75 }; 76 77 dedicatedServer.openFirewall = mkOption { 78 type = types.bool; 79 default = false; 80 description = lib.mdDoc '' 81 Open ports in the firewall for Source Dedicated Server. 82 ''; 83 }; 84 85 gamescopeSession = mkOption { 86 description = mdDoc "Run a GameScope driven Steam session from your display-manager"; 87 default = {}; 88 type = types.submodule { 89 options = { 90 enable = mkEnableOption (mdDoc "GameScope Session"); 91 args = mkOption { 92 type = types.listOf types.string; 93 default = [ ]; 94 description = mdDoc '' 95 Arguments to be passed to GameScope for the session. 96 ''; 97 }; 98 99 env = mkOption { 100 type = types.attrsOf types.string; 101 default = { }; 102 description = mdDoc '' 103 Environmental variables to be passed to GameScope for the session. 104 ''; 105 }; 106 }; 107 }; 108 }; 109 }; 110 111 config = mkIf cfg.enable { 112 hardware.opengl = { # this fixes the "glXChooseVisual failed" bug, context: https://github.com/NixOS/nixpkgs/issues/47932 113 enable = true; 114 driSupport = true; 115 driSupport32Bit = true; 116 }; 117 118 security.wrappers = mkIf (cfg.gamescopeSession.enable && gamescopeCfg.capSysNice) { 119 # needed or steam fails 120 bwrap = { 121 owner = "root"; 122 group = "root"; 123 source = "${pkgs.bubblewrap}/bin/bwrap"; 124 setuid = true; 125 }; 126 }; 127 128 programs.gamescope.enable = mkDefault cfg.gamescopeSession.enable; 129 services.xserver.displayManager.sessionPackages = mkIf cfg.gamescopeSession.enable [ gamescopeSessionFile ]; 130 131 # optionally enable 32bit pulseaudio support if pulseaudio is enabled 132 hardware.pulseaudio.support32Bit = config.hardware.pulseaudio.enable; 133 134 hardware.steam-hardware.enable = true; 135 136 environment.systemPackages = [ 137 cfg.package 138 cfg.package.run 139 ] ++ lib.optional cfg.gamescopeSession.enable steam-gamescope; 140 141 networking.firewall = lib.mkMerge [ 142 (mkIf cfg.remotePlay.openFirewall { 143 allowedTCPPorts = [ 27036 ]; 144 allowedUDPPortRanges = [ { from = 27031; to = 27036; } ]; 145 }) 146 147 (mkIf cfg.dedicatedServer.openFirewall { 148 allowedTCPPorts = [ 27015 ]; # SRCDS Rcon port 149 allowedUDPPorts = [ 27015 ]; # Gameplay traffic 150 }) 151 ]; 152 }; 153 154 meta.maintainers = with maintainers; [ mkg20001 ]; 155}