screen-locker: Make xautolock optional, reorganize options (#2343)

* screen-locker: Make xautolock optional, reorganize options

xautolock isn't really needed to trigger xss-lock on the basis of time
since the built-in screensaver functionality of X serves as one of the
event sources for xss-lock. Keeping it around and defaulting to
"enabled" to avoid unexpected breakage.

Also shuffled around the options to submodules for xss-lock and
xautolock to get rid of prefixes in option names and to make
enableDetectSleep a bit clearer.

* screen-locker: update maintainership

* tests/screen-locker: Stub i3lock and xss-lock

* screen-locker: add package options for xss-lock and xautolock
This commit is contained in:
Josh Robson Chase 2021-10-05 12:58:25 -04:00 committed by GitHub
parent 88f9b33384
commit e4df31dcea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 221 additions and 55 deletions

3
.github/CODEOWNERS vendored
View file

@ -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

View file

@ -127,4 +127,10 @@
githubId = 605641;
name = "Bart Bakker";
};
jrobsonchase = {
email = "josh@robsonchase.com";
github = "jrobsonchase";
githubId = 1553581;
name = "Josh Robson Chase";
};
}

View file

@ -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'.
'';
}
];
};
}

View file

@ -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 <option>xautolock.enable</option> is true, it will use this setting.
See <link xlink:href="https://linux.die.net/man/1/xautolock"/>.
Otherwise, this will be used with <command>xset</command> to configure
the X server's screensaver timeout.
'';
};
xautolockExtraOptions = mkOption {
type = types.listOf types.str;
default = [ ];
description = ''
Extra command-line arguments to pass to <command>xautolock</command>.
'';
};
xssLockExtraOptions = mkOption {
type = types.listOf types.str;
default = [ ];
description = ''
Extra command-line arguments to pass to <command>xss-lock</command>.
'';
};
};
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 <command>xautolock</command> 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 <option>xautolock.enable</option> is false.
'';
};
extraOptions = mkOption {
type = types.listOf types.str;
default = [ ];
description = ''
Extra command-line arguments to pass to <command>xautolock</command>.
No effect if <option>xautolock.enable</option> 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 <command>xss-lock</command> 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 <command>xss-lock</command>.
'';
};
};
};
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);
};
};
})
]);
}

View file

@ -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

View file

@ -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.*'
'';
};
}

View file

@ -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;
}

View file

@ -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;
};
}

View file

@ -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'
'';
};
}