1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.xserver.xautolock;
7in
8 {
9 options = {
10 services.xserver.xautolock = {
11 enable = mkEnableOption "xautolock";
12 enableNotifier = mkEnableOption "xautolock.notify" // {
13 description = ''
14 Whether to enable the notifier feature of xautolock.
15 This publishes a notification before the autolock.
16 '';
17 };
18
19 time = mkOption {
20 default = 15;
21 type = types.int;
22
23 description = ''
24 Idle time to wait until xautolock locks the computer.
25 '';
26 };
27
28 locker = mkOption {
29 default = "${pkgs.xlockmore}/bin/xlock"; # default according to `man xautolock`
30 example = "${pkgs.i3lock}/bin/i3lock -i /path/to/img";
31 type = types.str;
32
33 description = ''
34 The script to use when automatically locking the computer.
35 '';
36 };
37
38 nowlocker = mkOption {
39 default = null;
40 example = "${pkgs.i3lock}/bin/i3lock -i /path/to/img";
41 type = types.nullOr types.str;
42
43 description = ''
44 The script to use when manually locking the computer with <command>xautolock -locknow</command>.
45 '';
46 };
47
48 notify = mkOption {
49 default = 10;
50 type = types.int;
51
52 description = ''
53 Time (in seconds) before the actual lock when the notification about the pending lock should be published.
54 '';
55 };
56
57 notifier = mkOption {
58 default = null;
59 example = "${pkgs.libnotify}/bin/notify-send \"Locking in 10 seconds\"";
60 type = types.nullOr types.str;
61
62 description = ''
63 Notification script to be used to warn about the pending autolock.
64 '';
65 };
66
67 killer = mkOption {
68 default = null; # default according to `man xautolock` is none
69 example = "${pkgs.systemd}/bin/systemctl suspend";
70 type = types.nullOr types.str;
71
72 description = ''
73 The script to use when nothing has happend for as long as <option>killtime</option>
74 '';
75 };
76
77 killtime = mkOption {
78 default = 20; # default according to `man xautolock`
79 type = types.int;
80
81 description = ''
82 Minutes xautolock waits until it executes the script specified in <option>killer</option>
83 (Has to be at least 10 minutes)
84 '';
85 };
86
87 extraOptions = mkOption {
88 type = types.listOf types.str;
89 default = [ ];
90 example = [ "-detectsleep" ];
91 description = ''
92 Additional command-line arguments to pass to
93 <command>xautolock</command>.
94 '';
95 };
96 };
97 };
98
99 config = mkIf cfg.enable {
100 environment.systemPackages = with pkgs; [ xautolock ];
101 systemd.user.services.xautolock = {
102 description = "xautolock service";
103 wantedBy = [ "graphical-session.target" ];
104 partOf = [ "graphical-session.target" ];
105 serviceConfig = with lib; {
106 ExecStart = strings.concatStringsSep " " ([
107 "${pkgs.xautolock}/bin/xautolock"
108 "-noclose"
109 "-time ${toString cfg.time}"
110 "-locker '${cfg.locker}'"
111 ] ++ optionals cfg.enableNotifier [
112 "-notify ${toString cfg.notify}"
113 "-notifier '${cfg.notifier}'"
114 ] ++ optionals (cfg.nowlocker != null) [
115 "-nowlocker '${cfg.nowlocker}'"
116 ] ++ optionals (cfg.killer != null) [
117 "-killer '${cfg.killer}'"
118 "-killtime ${toString cfg.killtime}"
119 ] ++ cfg.extraOptions);
120 Restart = "always";
121 };
122 };
123 assertions = [
124 {
125 assertion = cfg.enableNotifier -> cfg.notifier != null;
126 message = "When enabling the notifier for xautolock, you also need to specify the notify script";
127 }
128 {
129 assertion = cfg.killer != null -> cfg.killtime >= 10;
130 message = "killtime has to be at least 10 minutes according to `man xautolock`";
131 }
132 ] ++ (lib.flip map [ "locker" "notifier" "nowlocker" "killer" ]
133 (option:
134 {
135 assertion = cfg."${option}" != null -> builtins.substring 0 1 cfg."${option}" == "/";
136 message = "Please specify a canonical path for `services.xserver.xautolock.${option}`";
137 })
138 );
139 };
140 }