1
0
Fork 0
mirror of https://github.com/nix-community/home-manager.git synced 2025-11-08 19:46:05 +01:00
home-manager/modules/programs/lutris.nix

244 lines
8.5 KiB
Nix

{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
mkOption
mkEnableOption
mkIf
types
optional
optionalAttrs
optionalString
nameValuePair
mapAttrs'
filter
filterAttrs
filterAttrsRecursive
attrNames
concatStringsSep
toLower
recursiveUpdate
listToAttrs
getExe
;
cfg = config.programs.lutris;
settingsFormat = pkgs.formats.yaml { };
formatWineName = (package: toLower package.name);
in
{
options.programs.lutris = {
enable = mkEnableOption "lutris.";
package = lib.mkPackageOption pkgs "lutris" { };
steamPackage = mkOption {
default = null;
example = "pkgs.steam or osConfig.programs.steam.package";
description = ''
This must be the same you use for your system, or two instances will conflict,
for example, if you configure steam through the nixos module, a good value is "osConfig.programs.steam.package"
'';
type = types.nullOr types.package;
};
extraPackages = mkOption {
default = [ ];
example = "with pkgs; [mangohud winetricks gamescope gamemode umu-launcher]";
description = ''
List of packages to pass as extraPkgs to lutris.
Please note runners are not detected properly this way, use a proper option for those.
'';
type = types.listOf types.package;
};
defaultWinePackage = mkOption {
default = null;
example = "pkgs.proton-ge-bin";
description = ''
The wine/proton package to set as the default for lutris.
It must still be set under proton/winePackages.
'';
type = types.nullOr types.package;
};
protonPackages = mkOption {
default = [ ];
example = "[ pkgs.proton-ge-bin ]";
description = ''
List of proton packages to be added for lutris to use with umu-launcher.
'';
type = types.listOf types.package;
};
winePackages = mkOption {
default = [ ];
example = "[ pkgs.wineWow64Packages.full ]";
description = ''
List of wine packages to be added for lutris to use.
'';
type = types.listOf types.package;
};
runners = mkOption {
default = { };
example = ''
runners = {
cemu.package = pkgs.cemu;
pcsx2.config = {
system.disable_screen_saver = true;
runner.runner_executable = "$\{pkgs.pcsx2}/bin/pcsx2-qt";
};
};
'';
description = ''
Attribute set of Lutris runners along with their configurations.
Each runner must be named exactly as lutris expects on `lutris --list-runners`.
Note that runners added here won't be configurable through Lutris using the GUI.
'';
type = types.attrsOf (
types.submodule {
options = {
package = mkOption {
default = null;
example = "pkgs.cemu";
description = ''
The package to use for this runner, nix will try to find the executable for this package.
A more specific path can be set by using settings.runner.runner_executable instead.
Uncompatible with certain runners, such as wine.
'';
type = types.nullOr types.package;
};
settings = mkOption {
default = { };
description = ''
Settings passed directly to lutris for this runner's config at XDG_CONFIG/lutris/runners.
'';
type = types.submodule {
options = {
runner = mkOption {
default = { };
description = ''
Runner specific options.
For references, you must look for the file of said runner on lutris' source code.
'';
type = types.submodule {
freeformType = settingsFormat.type;
options = {
runner_executable = mkOption {
type = types.either types.str types.path;
default = "";
description = ''
Specific option to point to a runner executable directly, don't set runner.package if you set this.
Uncompatible with certain runners such as wine.
'';
};
};
};
};
system = mkOption {
default = { };
description = ''
Lutris system options for this runner.
Reference for system options:
https://github.com/lutris/lutris/blob/master/lutris/sysoptions.py#L78
'';
type = types.submodule { freeformType = settingsFormat.type; };
};
};
};
};
};
}
);
};
};
meta.maintainers = [ lib.hm.maintainers.bikku ];
config = mkIf cfg.enable {
assertions = [
(lib.hm.assertions.assertPlatform "programs.lutris" pkgs lib.platforms.linux)
(lib.hm.assertions.assertPlatform "programs.lutris" pkgs lib.platforms.x86_64)
];
warnings =
let
redundantRunners = attrNames (
filterAttrs (
_: runner_config:
runner_config.package != null && runner_config.settings.runner.runner_executable != ""
) cfg.runners
);
in
filter (e: e != "") [
(optionalString (redundantRunners != [ ]) ''
Under programs.lutris.runners, the following lutris runners had both a
<runner>.package and <runner>.settings.runner.runner_executable options set:
- ${concatStringsSep ", " redundantRunners}
Note that runner_executable overrides package, setting both is pointless.
'')
(optionalString ((cfg.runners.wine.package or null) != null) ''
Setting programs.lutris.runners.wine.package does nothing.
Use the respective options, proton/winePackages and defaultWinePackage.
'')
(optionalString ((cfg ? runners.wine.settings.runner.version) && (cfg.defaultWinePackage != null))
''
Found conflicting options under programs.lutris, both runners.wine.settings.version and defaultWinePackage
were set.
''
)
];
home.packages =
let
lutris-overrides = {
# This only adds pkgs.steam to the extraPkgs, I see no reason to ever enable it.
steamSupport = false;
extraPkgs = (prev: cfg.extraPackages ++ optional (cfg.steamPackage != null) cfg.steamPackage);
};
in
[ (cfg.package.override lutris-overrides) ];
xdg.configFile =
let
buildRunnerConfig = (
runner_name: runner_config:
# Remove the unset values so they don't end up on the final config.
filterAttrsRecursive (name: value: value != { } && value != null && value != "") {
"${runner_name}" =
runner_config.settings.runner
# If set translate .package to runner_executable
// (optionalAttrs (runner_config.package != null) {
runner_executable = getExe runner_config.package;
});
inherit (runner_config.settings) system;
}
);
# Extra default config for wine if defaultWinePackage was set
wine_extra = optionalAttrs (cfg.defaultWinePackage != null) {
wine = {
package = null;
settings = {
runner.version = formatWineName cfg.defaultWinePackage;
system = { };
};
};
};
in
mapAttrs' (
runner_name: runner_config:
nameValuePair "lutris/runners/${runner_name}.yml" {
source = settingsFormat.generate "${runner_name}.yml" (buildRunnerConfig runner_name runner_config);
}
) (recursiveUpdate wine_extra cfg.runners);
xdg.dataFile =
let
buildWineLink =
type: packages:
map (
# lutris seems to not detect wine/proton if the name has some caps
package:
(nameValuePair "lutris/runners/${type}/${formatWineName package}" {
source = package;
})
) packages;
steamcompattools = map (proton: proton.steamcompattool) cfg.protonPackages;
in
listToAttrs (buildWineLink "wine" cfg.winePackages ++ buildWineLink "proton" steamcompattools);
};
}