diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index aa7c0d2ea..e165a6f22 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -311,6 +311,9 @@
/modules/services/redshift-gammastep @rycee @petabyteboy @thiagokokada
/tests/modules/redshift-gammastep @thiagokokada
+/modules/services/screen-locker.nix @jrobsonchase
+/tests/modules/services/screen-locker @jrobsonchase
+
/modules/services/status-notifier-watcher.nix @pltanton
/modules/services/syncthing.nix @rycee
diff --git a/modules/lib/maintainers.nix b/modules/lib/maintainers.nix
index 20663a281..badab65bf 100644
--- a/modules/lib/maintainers.nix
+++ b/modules/lib/maintainers.nix
@@ -127,4 +127,10 @@
githubId = 605641;
name = "Bart Bakker";
};
+ jrobsonchase = {
+ email = "josh@robsonchase.com";
+ github = "jrobsonchase";
+ githubId = 1553581;
+ name = "Josh Robson Chase";
+ };
}
diff --git a/modules/misc/news.nix b/modules/misc/news.nix
index a2aa80d70..a81a86f3b 100644
--- a/modules/misc/news.nix
+++ b/modules/misc/news.nix
@@ -2203,6 +2203,16 @@ in
A new module is available: 'programs.bottom'.
'';
}
+
+ {
+ time = "2021-09-23T17:04:48+00:00";
+ message = ''
+ 'xautolock' is now optional in 'services.screen-locker', and the
+ 'services.screen-locker' options have been reorganized for clarity.
+ See the 'xautolock' and 'xss-lock' options modules in
+ 'services.screen-locker'.
+ '';
+ }
];
};
}
diff --git a/modules/services/screen-locker.nix b/modules/services/screen-locker.nix
index 4da24b74e..34794d1c1 100644
--- a/modules/services/screen-locker.nix
+++ b/modules/services/screen-locker.nix
@@ -7,6 +7,20 @@ let
cfg = config.services.screen-locker;
in {
+ meta.maintainers = [ lib.hm.maintainers.jrobsonchase ];
+
+ imports = let
+ origOpt = name: [ "services" "screen-locker" name ];
+ xautolockOpt = name: [ "services" "screen-locker" "xautolock" name ];
+ xssLockOpt = name: [ "services" "screen-locker" "xss-lock" name ];
+ in [
+ (mkRenamedOptionModule (origOpt "xssLockExtraOptions")
+ (xssLockOpt "extraOptions"))
+ (mkRenamedOptionModule (origOpt "xautolockExtraOptions")
+ (xautolockOpt "extraOptions"))
+ (mkRenamedOptionModule (origOpt "enableDetectSleep")
+ (xautolockOpt "detectSleep"))
+ ];
options.services.screen-locker = {
enable = mkEnableOption "screen locker for X session";
@@ -17,81 +31,118 @@ in {
example = "\${pkgs.i3lock}/bin/i3lock -n -c 000000";
};
- enableDetectSleep = mkOption {
- type = types.bool;
- default = true;
- description = ''
- Whether to reset timers when awaking from sleep.
- '';
- };
-
inactiveInterval = mkOption {
type = types.int;
default = 10;
description = ''
Inactive time interval in minutes after which session will be locked.
The minimum is 1 minute, and the maximum is 1 hour.
+ If is true, it will use this setting.
See .
+ Otherwise, this will be used with xset to configure
+ the X server's screensaver timeout.
'';
};
- xautolockExtraOptions = mkOption {
- type = types.listOf types.str;
- default = [ ];
- description = ''
- Extra command-line arguments to pass to xautolock.
- '';
- };
-
- xssLockExtraOptions = mkOption {
- type = types.listOf types.str;
- default = [ ];
- description = ''
- Extra command-line arguments to pass to xss-lock.
- '';
- };
- };
-
- config = mkIf cfg.enable {
- assertions = [
- (lib.hm.assertions.assertPlatform "services.screen-locker" pkgs
- lib.platforms.linux)
- ];
-
- systemd.user.services.xautolock-session = {
- Unit = {
- Description = "xautolock, session locker service";
- After = [ "graphical-session-pre.target" ];
- PartOf = [ "graphical-session.target" ];
+ xautolock = {
+ enable = mkOption {
+ type = types.bool;
+ default = true;
+ description = "Use xautolock for time-based locking.";
};
- Install = { WantedBy = [ "graphical-session.target" ]; };
+ package = mkOption {
+ type = types.package;
+ default = pkgs.xautolock;
+ description = ''
+ Package providing the xautolock binary.
+ '';
+ };
- Service = {
- ExecStart = concatStringsSep " " ([
- "${pkgs.xautolock}/bin/xautolock"
- "-time ${toString cfg.inactiveInterval}"
- "-locker '${pkgs.systemd}/bin/loginctl lock-session $XDG_SESSION_ID'"
- ] ++ optional cfg.enableDetectSleep "-detectsleep"
- ++ cfg.xautolockExtraOptions);
+ detectSleep = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether to reset xautolock timers when awaking from sleep.
+ No effect if is false.
+ '';
+ };
+
+ extraOptions = mkOption {
+ type = types.listOf types.str;
+ default = [ ];
+ description = ''
+ Extra command-line arguments to pass to xautolock.
+ No effect if is false.
+ '';
};
};
- systemd.user.services.xss-lock = {
- Unit = {
- Description = "xss-lock, session locker service";
- After = [ "graphical-session-pre.target" ];
- PartOf = [ "graphical-session.target" ];
+ xss-lock = {
+ package = mkOption {
+ type = types.package;
+ default = pkgs.xss-lock;
+ description = ''
+ Package providing the xss-lock binary.
+ '';
};
- Install = { WantedBy = [ "graphical-session.target" ]; };
-
- Service = {
- ExecStart = concatStringsSep " "
- ([ "${pkgs.xss-lock}/bin/xss-lock" "-s \${XDG_SESSION_ID}" ]
- ++ cfg.xssLockExtraOptions ++ [ "-- ${cfg.lockCmd}" ]);
+ extraOptions = mkOption {
+ type = types.listOf types.str;
+ default = [ ];
+ description = ''
+ Extra command-line arguments to pass to xss-lock.
+ '';
};
};
};
+ config = mkIf cfg.enable (mkMerge [
+ {
+ assertions = [
+ (lib.hm.assertions.assertPlatform "services.screen-locker" pkgs
+ lib.platforms.linux)
+ ];
+
+ systemd.user.services.xss-lock = {
+ Unit = {
+ Description = "xss-lock, session locker service";
+ After = [ "graphical-session-pre.target" ];
+ PartOf = [ "graphical-session.target" ];
+ };
+
+ Install = { WantedBy = [ "graphical-session.target" ]; };
+
+ Service = {
+ ExecStart = concatStringsSep " "
+ ([ "${cfg.xss-lock.package}/bin/xss-lock" "-s \${XDG_SESSION_ID}" ]
+ ++ cfg.xss-lock.extraOptions ++ [ "-- ${cfg.lockCmd}" ]);
+ };
+ };
+ }
+ (mkIf (!cfg.xautolock.enable) {
+ systemd.user.services.xss-lock.Service.ExecStartPre =
+ "${pkgs.xorg.xset}/bin/xset s ${toString (cfg.inactiveInterval * 60)}";
+ })
+ (mkIf cfg.xautolock.enable {
+ systemd.user.services.xautolock-session = {
+ Unit = {
+ Description = "xautolock, session locker service";
+ After = [ "graphical-session-pre.target" ];
+ PartOf = [ "graphical-session.target" ];
+ };
+
+ Install = { WantedBy = [ "graphical-session.target" ]; };
+
+ Service = {
+ ExecStart = concatStringsSep " " ([
+ "${cfg.xautolock.package}/bin/xautolock"
+ "-time ${toString cfg.inactiveInterval}"
+ "-locker '${pkgs.systemd}/bin/loginctl lock-session \${XDG_SESSION_ID}'"
+ ] ++ optional cfg.xautolock.detectSleep "-detectsleep"
+ ++ cfg.xautolock.extraOptions);
+ };
+ };
+ })
+ ]);
}
diff --git a/tests/default.nix b/tests/default.nix
index cf51d4aaa..a65ee7c25 100644
--- a/tests/default.nix
+++ b/tests/default.nix
@@ -132,6 +132,7 @@ import nmt {
./modules/services/playerctld
./modules/services/polybar
./modules/services/redshift-gammastep
+ ./modules/services/screen-locker
./modules/services/sxhkd
./modules/services/syncthing
./modules/services/trayer
diff --git a/tests/modules/services/screen-locker/basic-configuration.nix b/tests/modules/services/screen-locker/basic-configuration.nix
new file mode 100644
index 000000000..9eee2a8e2
--- /dev/null
+++ b/tests/modules/services/screen-locker/basic-configuration.nix
@@ -0,0 +1,30 @@
+{ config, pkgs, ... }:
+
+{
+ config = {
+ services.screen-locker = {
+ enable = true;
+ inactiveInterval = 5;
+ lockCmd = "${pkgs.i3lock}/bin/i3lock -n -c AA0000";
+ xss-lock = { extraOptions = [ "-test" ]; };
+ xautolock = {
+ enable = true;
+ detectSleep = true;
+ extraOptions = [ "-test" ];
+ };
+ };
+
+ test.stubs.i3lock = { };
+ test.stubs.xss-lock = { };
+
+ nmt.script = ''
+ xssService=home-files/.config/systemd/user/xss-lock.service
+ xautolockService=home-files/.config/systemd/user/xautolock-session.service
+
+ assertFileExists $xssService
+ assertFileRegex $xssService 'ExecStart=.*/bin/xss-lock.*-test.*i3lock -n -c AA0000'
+ assertFileExists $xautolockService
+ assertFileRegex $xautolockService 'ExecStart=.*/bin/xautolock.*-time 5.*-detectsleep.*-test.*'
+ '';
+ };
+}
diff --git a/tests/modules/services/screen-locker/default.nix b/tests/modules/services/screen-locker/default.nix
new file mode 100644
index 000000000..667defc51
--- /dev/null
+++ b/tests/modules/services/screen-locker/default.nix
@@ -0,0 +1,5 @@
+{
+ screen-locker-basic-configuration = ./basic-configuration.nix;
+ screen-locker-no-xautolock = ./no-xautolock.nix;
+ screen-locker-moved-options = ./moved-options.nix;
+}
diff --git a/tests/modules/services/screen-locker/moved-options.nix b/tests/modules/services/screen-locker/moved-options.nix
new file mode 100644
index 000000000..4c9cad19e
--- /dev/null
+++ b/tests/modules/services/screen-locker/moved-options.nix
@@ -0,0 +1,36 @@
+{ config, pkgs, options, lib, ... }:
+
+{
+ config = {
+ services.screen-locker = {
+ enable = true;
+ inactiveInterval = 5;
+ lockCmd = "${pkgs.i3lock}/bin/i3lock -n -c AA0000";
+ xssLockExtraOptions = [ "-test" ];
+ xautolockExtraOptions = [ "-test" ];
+ enableDetectSleep = true;
+ };
+
+ test.stubs.i3lock = { };
+ test.stubs.xss-lock = { };
+
+ # Use the same verification script as the basic configuration. The result
+ # with the old options should be identical.
+ nmt.script = (import ./basic-configuration.nix {
+ inherit config pkgs;
+ }).config.nmt.script;
+
+ test.asserts.warnings.expected = with lib;
+ let
+ renamed = {
+ xssLockExtraOptions = "xss-lock.extraOptions";
+ xautolockExtraOptions = "xautolock.extraOptions";
+ enableDetectSleep = "xautolock.detectSleep";
+ };
+ in mapAttrsToList (old: new:
+ builtins.replaceStrings [ "\n" ] [ " " ] ''
+ The option `services.screen-locker.${old}' defined in
+ ${showFiles options.services.screen-locker.${old}.files}
+ has been renamed to `services.screen-locker.${new}'.'') renamed;
+ };
+}
diff --git a/tests/modules/services/screen-locker/no-xautolock.nix b/tests/modules/services/screen-locker/no-xautolock.nix
new file mode 100644
index 000000000..03ab0868c
--- /dev/null
+++ b/tests/modules/services/screen-locker/no-xautolock.nix
@@ -0,0 +1,24 @@
+{ config, pkgs, ... }:
+
+{
+ config = {
+ services.screen-locker = {
+ enable = true;
+ inactiveInterval = 5;
+ lockCmd = "${pkgs.i3lock}/bin/i3lock -n -c AA0000";
+ xss-lock = { extraOptions = [ "-test" ]; };
+ xautolock = { enable = false; };
+ };
+
+ test.stubs.i3lock = { };
+ test.stubs.xss-lock = { };
+
+ nmt.script = ''
+ xssService=home-files/.config/systemd/user/xss-lock.service
+
+ assertFileExists $xssService
+ assertFileRegex $xssService 'ExecStart=.*/bin/xss-lock.*-test.*i3lock -n -c AA0000'
+ assertFileRegex $xssService 'ExecStartPre=.*/xset s 300'
+ '';
+ };
+}