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 buildCommand =
61 ''
62 echo "$config" > $out
63
64 # The default kdmrc would add "-nolisten tcp", and we already
65 # have that managed by nixos. Hence the grep.
66 cat ${kdebase_workspace}/share/config/kdm/kdmrc | grep -v nolisten >> $out
67 '';
68 };
69
70in
71
72{
73
74 ###### interface
75
76 options = {
77
78 services.xserver.displayManager.kdm = {
79
80 enable = mkOption {
81 type = types.bool;
82 default = false;
83 description = ''
84 Whether to enable the KDE display manager.
85 '';
86 };
87
88 enableXDMCP = mkOption {
89 type = types.bool;
90 default = false;
91 description = ''
92 Whether to enable XDMCP, which allows remote logins.
93 '';
94 };
95
96 themeDirectory = mkOption {
97 type = types.nullOr types.str;
98 default = null;
99 description = ''
100 The path to a KDM theme directory. This theme
101 will be used by the KDM greeter.
102 '';
103 };
104
105 setupScript = mkOption {
106 type = types.lines;
107 default = "";
108 description = ''
109 The path to a KDM setup script. This script is run as root just
110 before KDM starts. Can be used for setting up
111 monitors with xrandr, for example.
112 '';
113 };
114
115 extraConfig = mkOption {
116 type = types.lines;
117 default = "";
118 description = ''
119 Options appended to <filename>kdmrc</filename>, the
120 configuration file of KDM.
121 '';
122 };
123
124 };
125
126 };
127
128
129 ###### implementation
130
131 config = mkIf cfg.enable {
132
133 services.xserver.displayManager.slim.enable = false;
134
135 services.xserver.displayManager.job =
136 { execCmd =
137 ''
138 mkdir -m 0755 -p /var/lib/kdm
139 chown kdm /var/lib/kdm
140 ${(optionalString (config.system.boot.loader.id == "grub" && config.system.build.grub != null) "PATH=${config.system.build.grub}/sbin:$PATH ") +
141 "KDEDIRS=/run/current-system/sw exec ${kdebase_workspace}/bin/kdm -config ${kdmrc} -nodaemon"}
142 '';
143 logsXsession = true;
144 };
145
146 security.pam.services.kde = { allowNullPassword = true; startSession = true; };
147
148 users.extraUsers = singleton
149 { name = "kdm";
150 uid = config.ids.uids.kdm;
151 description = "KDM user";
152 };
153
154 environment.systemPackages =
155 [ pkgs.kde4.kde_wallpapers ]; # contains kdm's default background
156
157 };
158
159}