1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 dmcfg = config.services.xserver.displayManager;
8 cfg = dmcfg.kdm;
9
10 inherit (pkgs.kde4) kdebase_workspace;
11
12 defaultConfig =
13 ''
14 [Shutdown]
15 HaltCmd=${config.systemd.package}/sbin/shutdown -h now
16 RebootCmd=${config.systemd.package}/sbin/shutdown -r now
17 ${optionalString (config.system.boot.loader.id == "grub") ''
18 BootManager=${if config.boot.loader.grub.version == 2 then "Grub2" else "Grub"}
19 ''}
20
21 [X-*-Core]
22 Xrdb=${pkgs.xorg.xrdb}/bin/xrdb
23 SessionsDirs=${dmcfg.session.desktops}
24 Session=${dmcfg.session.script}
25 FailsafeClient=${pkgs.xterm}/bin/xterm
26
27 [X-:*-Core]
28 ServerCmd=${dmcfg.xserverBin} ${dmcfg.xserverArgs}
29 # KDM calls `rm' somewhere to clean up some temporary directory.
30 SystemPath=${pkgs.coreutils}/bin
31 # The default timeout (15) is too short in a heavily loaded boot process.
32 ServerTimeout=60
33 # Needed to prevent the X server from dying on logout and not coming back:
34 TerminateServer=true
35 ${optionalString (cfg.setupScript != "")
36 ''
37 Setup=${cfg.setupScript}
38 ''}
39
40 [X-*-Greeter]
41 HiddenUsers=root,${concatStringsSep "," dmcfg.hiddenUsers}
42 PluginsLogin=${kdebase_workspace}/lib/kde4/kgreet_classic.so
43 ${optionalString (cfg.themeDirectory != null)
44 ''
45 UseTheme=true
46 Theme=${cfg.themeDirectory}
47 ''
48 }
49
50 ${optionalString (cfg.enableXDMCP)
51 ''
52 [Xdmcp]
53 Enable=true
54 ''}
55 '';
56
57 kdmrc = pkgs.stdenv.mkDerivation {
58 name = "kdmrc";
59 config = defaultConfig + cfg.extraConfig;
60 preferLocalBuild = true;
61 buildCommand =
62 ''
63 echo "$config" > $out
64
65 # The default kdmrc would add "-nolisten tcp", and we already
66 # have that managed by nixos. Hence the grep.
67 cat ${kdebase_workspace}/share/config/kdm/kdmrc | grep -v nolisten >> $out
68 '';
69 };
70
71in
72
73{
74
75 ###### interface
76
77 options = {
78
79 services.xserver.displayManager.kdm = {
80
81 enable = mkOption {
82 type = types.bool;
83 default = false;
84 description = ''
85 Whether to enable the KDE display manager.
86 '';
87 };
88
89 enableXDMCP = mkOption {
90 type = types.bool;
91 default = false;
92 description = ''
93 Whether to enable XDMCP, which allows remote logins.
94 '';
95 };
96
97 themeDirectory = mkOption {
98 type = types.nullOr types.str;
99 default = null;
100 description = ''
101 The path to a KDM theme directory. This theme
102 will be used by the KDM greeter.
103 '';
104 };
105
106 setupScript = mkOption {
107 type = types.lines;
108 default = "";
109 description = ''
110 The path to a KDM setup script. This script is run as root just
111 before KDM starts. Can be used for setting up
112 monitors with xrandr, for example.
113 '';
114 };
115
116 extraConfig = mkOption {
117 type = types.lines;
118 default = "";
119 description = ''
120 Options appended to <filename>kdmrc</filename>, the
121 configuration file of KDM.
122 '';
123 };
124
125 };
126
127 };
128
129
130 ###### implementation
131
132 config = mkIf cfg.enable {
133
134 services.xserver.displayManager.slim.enable = false;
135
136 services.xserver.displayManager.job =
137 { execCmd =
138 ''
139 mkdir -m 0755 -p /var/lib/kdm
140 chown kdm /var/lib/kdm
141 ${(optionalString (config.system.boot.loader.id == "grub" && config.system.build.grub != null) "PATH=${config.system.build.grub}/sbin:$PATH ") +
142 "KDEDIRS=/run/current-system/sw exec ${kdebase_workspace}/bin/kdm -config ${kdmrc} -nodaemon -logfile /dev/stderr"}
143 '';
144 logsXsession = true;
145 };
146
147 security.pam.services.kde = { allowNullPassword = true; startSession = true; };
148
149 users.extraUsers = singleton
150 { name = "kdm";
151 uid = config.ids.uids.kdm;
152 description = "KDM user";
153 };
154
155 environment.systemPackages =
156 [ pkgs.kde4.kde_wallpapers ]; # contains kdm's default background
157
158 };
159
160}