2020-05-01 16:50:28 +02:00
{
config ,
lib ,
pkgs ,
. . .
} :
let
cfg = config . programs . steam ;
2023-04-25 17:17:53 -06:00
gamescopeCfg = config . programs . gamescope ;
2024-05-07 14:59:35 +02:00
extraCompatPaths = lib . makeSearchPathOutput " s t e a m c o m p a t t o o l " " " cfg . extraCompatPackages ;
2023-04-25 17:17:53 -06: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 }
2025-02-15 18:41:55 +01:00
gamescope - - steam $ { builtins . toString cfg . gamescopeSession . args } - - steam $ { builtins . toString cfg . gamescopeSession . steamArgs }
2023-04-25 17:17:53 -06: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
( _ : {
passthru . providedSessions = [ " s t e a m " ] ;
} ) ;
2020-05-01 16:50:28 +02:00
in
{
2021-02-19 20:06:01 +01:00
options . programs . steam = {
2024-04-17 14:37:58 +03:00
enable = lib . mkEnableOption " s t e a m " ;
2021-02-19 20:06:01 +01:00
2024-04-17 14:37:58 +03:00
package = lib . mkOption {
type = lib . types . package ;
2023-03-07 20:24:28 +01:00
default = pkgs . steam ;
2024-04-17 14:37:58 +03:00
defaultText = lib . literalExpression " p k g s . s t e a m " ;
example = lib . literalExpression ''
2024-09-19 18:21:35 +03:00
pkgs . steam . override {
2023-01-29 14:56:57 +01:00
extraEnv = {
MANGOHUD = true ;
OBS_VKCAPTURE = true ;
RADV_TEX_ANISO = 16 ;
} ;
extraLibraries = p : with p ; [
2023-03-07 20:24:28 +01:00
atk
] ;
}
'' ;
apply =
steam :
steam . override (
prev :
{
2024-02-20 20:21:35 +01:00
extraEnv =
( lib . optionalAttrs ( cfg . extraCompatPackages != [ ] ) {
2024-05-07 14:59:35 +02:00
STEAM_EXTRA_COMPAT_TOOLS_PATHS = extraCompatPaths ;
2024-04-17 14:37:58 +03:00
} )
// ( lib . optionalAttrs cfg . extest . enable {
2024-03-25 23:38:33 +01:00
LD_PRELOAD = " ${ pkgs . pkgsi686Linux . extest } / l i b / l i b e x t e s t . s o " ;
2024-03-14 23:54:02 +01:00
} )
// ( prev . extraEnv or { } ) ;
2023-03-07 20:24:28 +01:00
extraLibraries =
pkgs :
let
prevLibs = if prev ? extraLibraries then prev . extraLibraries pkgs else [ ] ;
2024-06-16 13:50:18 +03:00
additionalLibs =
with config . hardware . graphics ;
2023-01-09 05:36:01 +02:00
if pkgs . stdenv . hostPlatform . is64bit then
2022-10-19 17:05:13 +02:00
[ package ] ++ extraPackages
else
[ package32 ] ++ extraPackages32 ;
2023-03-07 20:24:28 +01:00
in
prevLibs ++ additionalLibs ;
2024-05-26 22:03:50 +08:00
extraPkgs = p : ( cfg . extraPackages ++ lib . optionals ( prev ? extraPkgs ) ( prev . extraPkgs p ) ) ;
2024-04-17 14:37:58 +03:00
}
// lib . optionalAttrs ( cfg . gamescopeSession . enable && gamescopeCfg . capSysNice ) {
2023-04-25 17:17:53 -06:00
buildFHSEnv = pkgs . buildFHSEnv . override {
# use the setuid wrapped bubblewrap
bubblewrap = " ${ config . security . wrapperDir } / . . " ;
} ;
2023-03-07 20:24:28 +01:00
}
) ;
2022-10-19 17:05:13 +02:00
description = ''
2023-03-07 20:24:28 +01: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 17:05:13 +02:00
'' ;
} ;
2024-05-26 22:03:50 +08: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 14:37:58 +03:00
extraCompatPackages = lib . mkOption {
type = lib . types . listOf lib . types . package ;
2024-02-20 20:21:35 +01:00
default = [ ] ;
2024-04-17 14:37:58 +03:00
example = lib . literalExpression ''
2024-03-16 12:07:52 +01:00
with pkgs ; [
proton-ge-bin
]
'' ;
2024-02-20 20:21:35 +01: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 23:54:02 +01: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 20:21:35 +01:00
'' ;
} ;
2024-05-26 22:55:38 +08:00
fontPackages = lib . mkOption {
type = lib . types . listOf lib . types . package ;
2024-05-28 12:05:43 +08: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 22:55:38 +08: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 14:37:58 +03:00
remotePlay . openFirewall = lib . mkOption {
type = lib . types . bool ;
2021-02-19 20:06:01 +01:00
default = false ;
description = ''
Open ports in the firewall for Steam Remote Play .
'' ;
} ;
2024-04-17 14:37:58 +03:00
dedicatedServer . openFirewall = lib . mkOption {
type = lib . types . bool ;
2021-02-19 20:06:01 +01:00
default = false ;
description = ''
Open ports in the firewall for Source Dedicated Server .
'' ;
} ;
2023-04-25 17:17:53 -06:00
2024-04-17 14:37:58 +03:00
localNetworkGameTransfers . openFirewall = lib . mkOption {
type = lib . types . bool ;
2024-02-23 21:59:16 +01:00
default = false ;
description = ''
Open ports in the firewall for Steam Local Network Game Transfers .
'' ;
} ;
2024-04-17 14:37:58 +03:00
gamescopeSession = lib . mkOption {
2023-04-25 17:17:53 -06: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 11:59:05 -06:00
default = { } ;
2024-04-17 14:37:58 +03:00
type = lib . types . submodule {
2023-04-25 17:17:53 -06:00
options = {
2024-04-17 14:37:58 +03: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 17:17:53 -06:00
default = [ ] ;
description = ''
Arguments to be passed to GameScope for the session .
'' ;
} ;
2024-04-17 14:37:58 +03:00
env = lib . mkOption {
type = lib . types . attrsOf lib . types . str ;
2023-04-25 17:17:53 -06:00
default = { } ;
description = ''
Environmental variables to be passed to GameScope for the session .
'' ;
} ;
2025-02-15 18:41:55 +01:00
steamArgs = lib . mkOption {
type = lib . types . listOf lib . types . str ;
default = [
" - t e n f o o t "
" - p i p e w i r e - d m a b u f "
] ;
description = ''
Arguments to be passed to Steam for the session .
'' ;
} ;
2023-04-25 17:17:53 -06:00
} ;
} ;
} ;
2023-11-25 20:13:41 +11:00
2024-04-17 14:37:58 +03:00
extest . enable = lib . mkEnableOption ''
2024-03-04 16:11:41 +11: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 14:59:35 +02: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 20:06:01 +01:00
} ;
2020-05-01 16:50:28 +02:00
2024-04-17 14:37:58 +03:00
config = lib . mkIf cfg . enable {
2024-06-16 13:50:18 +03:00
hardware . graphics = {
# this fixes the "glXChooseVisual failed" bug, context: https://github.com/NixOS/nixpkgs/issues/47932
2020-05-01 16:50:28 +02:00
enable = true ;
2024-06-16 13:50:18 +03:00
enable32Bit = true ;
2020-05-01 16:50:28 +02:00
} ;
2024-04-17 14:37:58 +03:00
security . wrappers = lib . mkIf ( cfg . gamescopeSession . enable && gamescopeCfg . capSysNice ) {
2023-04-25 17:17:53 -06: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 22:55:38 +08:00
programs . steam . extraPackages = cfg . fontPackages ;
2024-04-17 14:37:58 +03:00
programs . gamescope . enable = lib . mkDefault cfg . gamescopeSession . enable ;
services . displayManager . sessionPackages = lib . mkIf cfg . gamescopeSession . enable [
gamescopeSessionFile
] ;
2023-04-25 17:17:53 -06:00
2024-09-04 13:44:21 +03:00
# enable 32bit pulseaudio/pipewire support if needed
2024-12-30 13:46:50 +00:00
services . pulseaudio . support32Bit = config . services . pulseaudio . enable ;
2024-09-04 13:44:21 +03:00
services . pipewire . alsa . support32Bit = config . services . pipewire . alsa . enable ;
2020-05-01 16:50:28 +02:00
hardware . steam-hardware . enable = true ;
2022-10-19 17:05:13 +02:00
environment . systemPackages =
[
cfg . package
cfg . package . run
2024-05-07 14:59:35 +02:00
]
++ lib . optional cfg . gamescopeSession . enable steam-gamescope
++ lib . optional cfg . protontricks . enable (
cfg . protontricks . package . override { inherit extraCompatPaths ; }
) ;
2021-02-19 20:06:01 +01:00
networking . firewall = lib . mkMerge [
2024-04-17 14:37:58 +03:00
( lib . mkIf ( cfg . remotePlay . openFirewall || cfg . localNetworkGameTransfers . openFirewall ) {
2024-02-23 21:59:16 +01:00
allowedUDPPorts = [ 27036 ] ; # Peer discovery
} )
2024-04-17 14:37:58 +03:00
( lib . mkIf cfg . remotePlay . openFirewall {
2021-02-19 20:06:01 +01:00
allowedTCPPorts = [ 27036 ] ;
2024-02-23 21:59:16 +01:00
allowedUDPPortRanges = [
{
from = 27031 ;
to = 27035 ;
}
] ;
2021-02-19 20:06:01 +01:00
} )
2024-04-17 14:37:58 +03:00
( lib . mkIf cfg . dedicatedServer . openFirewall {
2021-02-19 20:06:01 +01:00
allowedTCPPorts = [ 27015 ] ; # SRCDS Rcon port
allowedUDPPorts = [ 27015 ] ; # Gameplay traffic
} )
2024-02-23 21:59:16 +01:00
2024-04-17 14:37:58 +03:00
( lib . mkIf cfg . localNetworkGameTransfers . openFirewall {
2024-02-23 21:59:16 +01:00
allowedTCPPorts = [ 27040 ] ; # Data transfers
} )
2021-02-19 20:06:01 +01:00
] ;
2020-05-01 16:50:28 +02:00
} ;
2024-05-18 21:50:10 +01:00
meta . maintainers = lib . teams . steam . members ;
2020-05-01 16:50:28 +02:00
}