{ config, lib, pkgs, ... }: with lib; let xcfg = config.services.xserver; dmcfg = xcfg.displayManager; cfg = dmcfg.sddm; xEnv = config.systemd.services."display-manager".environment; sddm = pkgs.sddm.override { inherit (cfg) themes; }; xserverWrapper = pkgs.writeScript "xserver-wrapper" '' #!/bin/sh ${concatMapStrings (n: "export ${n}=\"${getAttr n xEnv}\"\n") (attrNames xEnv)} exec ${dmcfg.xserverBin} ${dmcfg.xserverArgs} "$@" ''; Xsetup = pkgs.writeScript "Xsetup" '' #!/bin/sh ${cfg.setupScript} ''; Xstop = pkgs.writeScript "Xstop" '' #!/bin/sh ${cfg.stopScript} ''; cfgFile = pkgs.writeText "sddm.conf" '' [General] HaltCommand=${pkgs.systemd}/bin/systemctl poweroff RebootCommand=${pkgs.systemd}/bin/systemctl reboot [Theme] Current=${cfg.theme} ThemeDir=${sddm}/share/sddm/themes FacesDir=${sddm}/share/sddm/faces [Users] MaximumUid=${toString config.ids.uids.nixbld} HideUsers=${concatStringsSep "," dmcfg.hiddenUsers} HideShells=/run/current-system/sw/bin/nologin [XDisplay] MinimumVT=${toString xcfg.tty} ServerPath=${xserverWrapper} XephyrPath=${pkgs.xorg.xorgserver}/bin/Xephyr SessionCommand=${dmcfg.session.script} SessionDir=${dmcfg.session.desktops} XauthPath=${pkgs.xorg.xauth}/bin/xauth DisplayCommand=${Xsetup} DisplayStopCommand=${Xstop} ${optionalString cfg.autoLogin.enable '' [Autologin] User=${cfg.autoLogin.user} Session=${defaultSessionName}.desktop Relogin=${if cfg.autoLogin.relogin then "true" else "false"} ''} ${cfg.extraConfig} ''; defaultSessionName = let dm = xcfg.desktopManager.default; wm = xcfg.windowManager.default; in dm + optionalString (wm != "none") (" + " + wm); in { options = { services.xserver.displayManager.sddm = { enable = mkOption { type = types.bool; default = false; description = '' Whether to enable sddm as the display manager. ''; }; extraConfig = mkOption { type = types.str; default = ""; example = '' [Autologin] User=john Session=plasma.desktop ''; description = '' Extra lines appended to the configuration of SDDM. ''; }; theme = mkOption { type = types.str; default = "maui"; description = '' Greeter theme to use. ''; }; themes = mkOption { type = types.listOf types.package; default = []; description = '' Extra packages providing themes. ''; }; setupScript = mkOption { type = types.str; default = ""; example = '' # workaround for using NVIDIA Optimus without Bumblebee xrandr --setprovideroutputsource modesetting NVIDIA-0 xrandr --auto ''; description = '' A script to execute when starting the display server. ''; }; stopScript = mkOption { type = types.str; default = ""; description = '' A script to execute when stopping the display server. ''; }; autoLogin = mkOption { default = {}; description = '' Configuration for automatic login. ''; type = types.submodule { options = { enable = mkOption { type = types.bool; default = false; description = '' Automatically log in as the sepecified . ''; }; user = mkOption { type = types.nullOr types.str; default = null; description = '' User to be used for the autologin. ''; }; relogin = mkOption { type = types.bool; default = false; description = '' If true automatic login will kick in again on session exit, otherwise it will work only the first time. ''; }; }; }; }; }; }; config = mkIf cfg.enable { assertions = [ { assertion = cfg.autoLogin.enable -> cfg.autoLogin.user != null; message = '' SDDM auto-login requires services.xserver.displayManager.sddm.autoLogin.user to be set ''; } { assertion = cfg.autoLogin.enable -> elem defaultSessionName dmcfg.session.names; message = '' SDDM auto-login requires that services.xserver.desktopManager.default and services.xserver.windowMananger.default are set to valid values. The current default session: ${defaultSessionName} is not valid. ''; } ]; services.xserver.displayManager.slim.enable = false; services.xserver.displayManager.job = { logsXsession = true; execCmd = "exec ${sddm}/bin/sddm"; }; security.pam.services = { sddm = { allowNullPassword = true; startSession = true; }; sddm-greeter.text = '' auth required pam_succeed_if.so audit quiet_success user = sddm auth optional pam_permit.so account required pam_succeed_if.so audit quiet_success user = sddm account sufficient pam_unix.so password required pam_deny.so session required pam_succeed_if.so audit quiet_success user = sddm session required pam_env.so envfile=${config.system.build.pamEnvironment} session optional ${pkgs.systemd}/lib/security/pam_systemd.so session optional pam_keyinit.so force revoke session optional pam_permit.so ''; sddm-autologin.text = '' auth requisite pam_nologin.so auth required pam_succeed_if.so uid >= 1000 quiet auth required pam_permit.so account include sddm password include sddm session include sddm ''; }; users.extraUsers.sddm = { createHome = true; home = "/var/lib/sddm"; group = "sddm"; uid = config.ids.uids.sddm; }; environment.etc."sddm.conf".source = cfgFile; users.extraGroups.sddm.gid = config.ids.gids.sddm; }; }