2020-05-01 14:50:28 +00:00
{ config , lib , pkgs , . . . }:
let
cfg = config . programs . steam ;
2023-04-25 23:17:53 +00:00
gamescopeCfg = config . programs . gamescope ;
2024-05-07 12:59:35 +00:00
extraCompatPaths = lib . makeSearchPathOutput " s t e a m c o m p a t t o o l " " " cfg . extraCompatPackages ;
2023-04-25 23:17:53 +00:00
steam-gamescope = let
exports = builtins . attrValues ( builtins . mapAttrs ( n : v : " e x p o r t ${ n } = ${ v } " ) cfg . gamescopeSession . env ) ;
in
pkgs . writeShellScriptBin " s t e a m - g a m e s c o p e " ''
$ { builtins . concatStringsSep " \n " exports }
2024-04-17 11:37:58 +00:00
gamescope - - steam $ { builtins . toString cfg . gamescopeSession . args } - - steam - tenfoot - pipewire-dmabuf
2023-04-25 23:17:53 +00:00
'' ;
gamescopeSessionFile =
( pkgs . writeTextDir " s h a r e / w a y l a n d - s e s s i o n s / s t e a m . d e s k t o p " ''
[ Desktop Entry ]
Name = Steam
Comment = A digital distribution platform
Exec = $ { steam-gamescope } /bin/steam-gamescope
Type = Application
'' ) . o v e r r i d e A t t r s ( _ : { p a s s t h r u . p r o v i d e d S e s s i o n s = [ " s t e a m " ] ; } ) ;
2020-05-01 14:50:28 +00:00
in {
2021-02-19 19:06:01 +00:00
options . programs . steam = {
2024-04-17 11:37:58 +00:00
enable = lib . mkEnableOption " s t e a m " ;
2021-02-19 19:06:01 +00:00
2024-04-17 11:37:58 +00:00
package = lib . mkOption {
type = lib . types . package ;
2023-03-07 19:24:28 +00:00
default = pkgs . steam ;
2024-04-17 11:37:58 +00:00
defaultText = lib . literalExpression " p k g s . s t e a m " ;
example = lib . literalExpression ''
2023-03-07 19:24:28 +00:00
pkgs . steam-small . override {
2023-01-29 13:56:57 +00:00
extraEnv = {
MANGOHUD = true ;
OBS_VKCAPTURE = true ;
RADV_TEX_ANISO = 16 ;
} ;
extraLibraries = p : with p ; [
2023-03-07 19:24:28 +00:00
atk
] ;
}
'' ;
apply = steam : steam . override ( prev : {
2024-02-20 19:21:35 +00:00
extraEnv = ( lib . optionalAttrs ( cfg . extraCompatPackages != [ ] ) {
2024-05-07 12:59:35 +00:00
STEAM_EXTRA_COMPAT_TOOLS_PATHS = extraCompatPaths ;
2024-04-17 11:37:58 +00:00
} ) // ( lib . optionalAttrs cfg . extest . enable {
2024-03-25 22:38:33 +00:00
LD_PRELOAD = " ${ pkgs . pkgsi686Linux . extest } / l i b / l i b e x t e s t . s o " ;
2024-03-14 22:54:02 +00:00
} ) // ( prev . extraEnv or { } ) ;
2023-03-07 19:24:28 +00:00
extraLibraries = pkgs : let
prevLibs = if prev ? extraLibraries then prev . extraLibraries pkgs else [ ] ;
2024-06-16 10:50:18 +00:00
additionalLibs = with config . hardware . graphics ;
2023-01-09 03:36:01 +00:00
if pkgs . stdenv . hostPlatform . is64bit
2022-10-19 15:05:13 +00:00
then [ package ] ++ extraPackages
else [ package32 ] ++ extraPackages32 ;
2023-03-07 19:24:28 +00:00
in prevLibs ++ additionalLibs ;
2024-05-26 14:03:50 +00:00
extraPkgs = p : ( cfg . extraPackages ++ lib . optionals ( prev ? extraPkgs ) ( prev . extraPkgs p ) ) ;
2024-04-17 11:37:58 +00:00
} // lib . optionalAttrs ( cfg . gamescopeSession . enable && gamescopeCfg . capSysNice )
2023-04-25 23:17:53 +00:00
{
buildFHSEnv = pkgs . buildFHSEnv . override {
# use the setuid wrapped bubblewrap
bubblewrap = " ${ config . security . wrapperDir } / . . " ;
} ;
2023-03-07 19:24:28 +00:00
} ) ;
2022-10-19 15:05:13 +00:00
description = ''
2023-03-07 19:24:28 +00:00
The Steam package to use . Additional libraries are added from the system
configuration to ensure graphics work properly .
Use this option to customise the Steam package rather than adding your
custom Steam to { option } ` environment . systemPackages ` yourself .
2022-10-19 15:05:13 +00:00
'' ;
} ;
2024-05-26 14:03:50 +00:00
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 .
'' ;
} ;
2024-04-17 11:37:58 +00:00
extraCompatPackages = lib . mkOption {
type = lib . types . listOf lib . types . package ;
2024-02-20 19:21:35 +00:00
default = [ ] ;
2024-04-17 11:37:58 +00:00
example = lib . literalExpression ''
2024-03-16 11:07:52 +00:00
with pkgs ; [
proton-ge-bin
]
'' ;
2024-02-20 19:21:35 +00:00
description = ''
Extra packages to be used as compatibility tools for Steam on Linux . Packages will be included
in the ` STEAM_EXTRA_COMPAT_TOOLS_PATHS ` environmental variable . For more information see
2024-03-14 22:54:02 +00:00
https://github.com/ValveSoftware/steam-for-linux/issues/6310.
These packages must be Steam compatibility tools that have a ` steamcompattool ` output .
2024-02-20 19:21:35 +00:00
'' ;
} ;
2024-05-26 14:55:38 +00:00
fontPackages = lib . mkOption {
type = lib . types . listOf lib . types . package ;
2024-05-28 04:05:43 +00:00
# `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 " b u i l t i n s . f i l t e r l i b . t y p e s . p a c k a g e . c h e c k c o n f i g . f o n t s . p a c k a g e s " ;
2024-05-26 14:55:38 +00:00
example = lib . literalExpression " w i t h p k g s ; [ s o u r c e - h a n - s a n s ] " ;
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.
'' ;
} ;
2024-04-17 11:37:58 +00:00
remotePlay . openFirewall = lib . mkOption {
type = lib . types . bool ;
2021-02-19 19:06:01 +00:00
default = false ;
description = ''
Open ports in the firewall for Steam Remote Play .
'' ;
} ;
2024-04-17 11:37:58 +00:00
dedicatedServer . openFirewall = lib . mkOption {
type = lib . types . bool ;
2021-02-19 19:06:01 +00:00
default = false ;
description = ''
Open ports in the firewall for Source Dedicated Server .
'' ;
} ;
2023-04-25 23:17:53 +00:00
2024-04-17 11:37:58 +00:00
localNetworkGameTransfers . openFirewall = lib . mkOption {
type = lib . types . bool ;
2024-02-23 20:59:16 +00:00
default = false ;
description = ''
Open ports in the firewall for Steam Local Network Game Transfers .
'' ;
} ;
2024-04-17 11:37:58 +00:00
gamescopeSession = lib . mkOption {
2023-04-25 23:17:53 +00:00
description = " R u n a G a m e S c o p e d r i v e n S t e a m s e s s i o n f r o m y o u r d i s p l a y - m a n a g e r " ;
2023-04-27 17:59:05 +00:00
default = { } ;
2024-04-17 11:37:58 +00:00
type = lib . types . submodule {
2023-04-25 23:17:53 +00:00
options = {
2024-04-17 11:37:58 +00:00
enable = lib . mkEnableOption " G a m e S c o p e S e s s i o n " ;
args = lib . mkOption {
type = lib . types . listOf lib . types . str ;
2023-04-25 23:17:53 +00:00
default = [ ] ;
description = ''
Arguments to be passed to GameScope for the session .
'' ;
} ;
2024-04-17 11:37:58 +00:00
env = lib . mkOption {
type = lib . types . attrsOf lib . types . str ;
2023-04-25 23:17:53 +00:00
default = { } ;
description = ''
Environmental variables to be passed to GameScope for the session .
'' ;
} ;
} ;
} ;
} ;
2023-11-25 09:13:41 +00:00
2024-04-17 11:37:58 +00:00
extest . enable = lib . mkEnableOption ''
2024-03-04 05:11:41 +00:00
Load the extest library into Steam , to translate X11 input events to
uinput events ( e . g . for using Steam Input on Wayland )
'' ;
2024-05-07 12:59:35 +00:00
protontricks = {
enable = lib . mkEnableOption " p r o t o n t r i c k s , a s i m p l e w r a p p e r f o r r u n n i n g W i n e t r i c k s c o m m a n d s f o r P r o t o n - e n a b l e d g a m e s " ;
package = lib . mkPackageOption pkgs " p r o t o n t r i c k s " { } ;
} ;
2021-02-19 19:06:01 +00:00
} ;
2020-05-01 14:50:28 +00:00
2024-04-17 11:37:58 +00:00
config = lib . mkIf cfg . enable {
2024-06-16 10:50:18 +00:00
hardware . graphics = { # this fixes the "glXChooseVisual failed" bug, context: https://github.com/NixOS/nixpkgs/issues/47932
2020-05-01 14:50:28 +00:00
enable = true ;
2024-06-16 10:50:18 +00:00
enable32Bit = true ;
2020-05-01 14:50:28 +00:00
} ;
2024-04-17 11:37:58 +00:00
security . wrappers = lib . mkIf ( cfg . gamescopeSession . enable && gamescopeCfg . capSysNice ) {
2023-04-25 23:17:53 +00:00
# needed or steam fails
bwrap = {
owner = " r o o t " ;
group = " r o o t " ;
source = " ${ pkgs . bubblewrap } / b i n / b w r a p " ;
setuid = true ;
} ;
} ;
2024-05-26 14:55:38 +00:00
programs . steam . extraPackages = cfg . fontPackages ;
2024-04-17 11:37:58 +00:00
programs . gamescope . enable = lib . mkDefault cfg . gamescopeSession . enable ;
services . displayManager . sessionPackages = lib . mkIf cfg . gamescopeSession . enable [ gamescopeSessionFile ] ;
2023-04-25 23:17:53 +00:00
2024-09-04 10:44:21 +00:00
# enable 32bit pulseaudio/pipewire support if needed
2020-05-01 14:50:28 +00:00
hardware . pulseaudio . support32Bit = config . hardware . pulseaudio . enable ;
2024-09-04 10:44:21 +00:00
services . pipewire . alsa . support32Bit = config . services . pipewire . alsa . enable ;
2020-05-01 14:50:28 +00:00
hardware . steam-hardware . enable = true ;
2022-10-19 15:05:13 +00:00
environment . systemPackages = [
cfg . package
cfg . package . run
2024-05-07 12:59:35 +00:00
] ++ lib . optional cfg . gamescopeSession . enable steam-gamescope
++ lib . optional cfg . protontricks . enable ( cfg . protontricks . package . override { inherit extraCompatPaths ; } ) ;
2021-02-19 19:06:01 +00:00
networking . firewall = lib . mkMerge [
2024-04-17 11:37:58 +00:00
( lib . mkIf ( cfg . remotePlay . openFirewall || cfg . localNetworkGameTransfers . openFirewall ) {
2024-02-23 20:59:16 +00:00
allowedUDPPorts = [ 27036 ] ; # Peer discovery
} )
2024-04-17 11:37:58 +00:00
( lib . mkIf cfg . remotePlay . openFirewall {
2021-02-19 19:06:01 +00:00
allowedTCPPorts = [ 27036 ] ;
2024-02-23 20:59:16 +00:00
allowedUDPPortRanges = [ { from = 27031 ; to = 27035 ; } ] ;
2021-02-19 19:06:01 +00:00
} )
2024-04-17 11:37:58 +00:00
( lib . mkIf cfg . dedicatedServer . openFirewall {
2021-02-19 19:06:01 +00:00
allowedTCPPorts = [ 27015 ] ; # SRCDS Rcon port
allowedUDPPorts = [ 27015 ] ; # Gameplay traffic
} )
2024-02-23 20:59:16 +00:00
2024-04-17 11:37:58 +00:00
( lib . mkIf cfg . localNetworkGameTransfers . openFirewall {
2024-02-23 20:59:16 +00:00
allowedTCPPorts = [ 27040 ] ; # Data transfers
} )
2021-02-19 19:06:01 +00:00
] ;
2020-05-01 14:50:28 +00:00
} ;
2024-05-18 20:50:10 +00:00
meta . maintainers = lib . teams . steam . members ;
2020-05-01 14:50:28 +00:00
}