From 65e5b835a94b3bca9a1e219e5c43c1bc5fc04598 Mon Sep 17 00:00:00 2001 From: Jos van Bakel Date: Mon, 3 Jan 2022 20:03:20 +0100 Subject: [PATCH] swayidle: add module (#2610) Swayidle is an idle management daemon for Wayland. This modules adds support for running swayidle as a SystemD user unit and makes it configurable through home-manager. --- .github/CODEOWNERS | 3 + modules/misc/news.nix | 8 ++ modules/modules.nix | 1 + modules/services/swayidle.nix | 118 ++++++++++++++++++ tests/default.nix | 1 + .../services/swayidle/basic-configuration.nix | 52 ++++++++ tests/modules/services/swayidle/default.nix | 1 + 7 files changed, 184 insertions(+) create mode 100644 modules/services/swayidle.nix create mode 100644 tests/modules/services/swayidle/basic-configuration.nix create mode 100644 tests/modules/services/swayidle/default.nix diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index abddaa5a552..c2516f7b653 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -399,3 +399,6 @@ /tests/modules/targets-darwin @midchildan Makefile @thiagokokada + +/modules/services/swayidle.nix @c0deaddict +/tests/modules/services/swayidle @c0deaddict diff --git a/modules/misc/news.nix b/modules/misc/news.nix index 9c194d77af5..7a77fe8a1d1 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -2336,6 +2336,14 @@ in A new module is available: 'xsession.windowManager.herbstluftwm'. ''; } + + { + time = "2022-01-03T10:34:45+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.swayidle'. + ''; + } ]; }; } diff --git a/modules/modules.nix b/modules/modules.nix index 534d9c55ca1..b970e0def44 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -218,6 +218,7 @@ let ./services/spotifyd.nix ./services/stalonetray.nix ./services/status-notifier-watcher.nix + ./services/swayidle.nix ./services/sxhkd.nix ./services/syncthing.nix ./services/systembus-notify.nix diff --git a/modules/services/swayidle.nix b/modules/services/swayidle.nix new file mode 100644 index 00000000000..4a6c5b2f119 --- /dev/null +++ b/modules/services/swayidle.nix @@ -0,0 +1,118 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.swayidle; + + mkTimeout = t: + [ "timeout" (toString t.timeout) (escapeShellArg t.command) ] + ++ optionals (t.resumeCommand != null) [ + "resume" + (escapeShellArg t.resumeCommand) + ]; + + mkEvent = e: [ e.event (escapeShellArg e.command) ]; + + args = (concatMap mkTimeout cfg.timeouts) ++ (concatMap mkEvent cfg.events) + ++ cfg.extraArgs; + +in { + meta.maintainers = [ maintainers.c0deaddict ]; + + options.services.swayidle = let + + timeoutModule = { ... }: { + options = { + timeout = mkOption { + type = types.ints.positive; + description = "Timeout in seconds"; + example = 60; + }; + + command = mkOption { + type = types.str; + description = "Command to run after timeout seconds of inactivity"; + }; + + resumeCommand = mkOption { + type = with types; nullOr str; + default = null; + description = "Command to run when there is activity again"; + }; + }; + }; + + eventModule = { ... }: { + options = { + event = mkOption { + type = types.enum [ "before-sleep" "after-resume" "lock" "unlock" ]; + description = "Event name"; + }; + + command = mkOption { + type = types.str; + description = "Command to run when event occurs"; + }; + }; + }; + + in { + enable = mkEnableOption "Idle manager for Wayland"; + + package = mkOption { + type = types.package; + default = pkgs.swayidle; + defaultText = literalExpression "pkgs.swayidle"; + description = "Swayidle package to install."; + }; + + timeouts = mkOption { + type = with types; listOf (submodule timeoutModule); + default = [ ]; + description = "List of commands to run after idle timeout"; + example = '' + [ + { timeout = 60; command = "swaylock -fF"; } + ] + ''; + }; + + events = mkOption { + type = with types; listOf (submodule eventModule); + default = [ ]; + example = '' + [ + { event = "before-sleep"; command = "swaylock"; } + { event = "lock"; command = "lock"; } + ] + ''; + description = "Run command on occurence of a event"; + }; + + extraArgs = mkOption { + type = with types; listOf str; + default = [ ]; + description = "Extra arguments to pass to swayidle"; + }; + }; + + config = mkIf cfg.enable { + systemd.user.services.swayidle = { + Unit = { + Description = "Idle manager for Wayland"; + Documentation = "man:swayidle(1)"; + PartOf = [ "graphical-session.target" ]; + }; + + Service = { + Type = "simple"; + ExecStart = + "${cfg.package}/bin/swayidle -w ${concatStringsSep " " args}"; + }; + + Install = { WantedBy = [ "sway-session.target" ]; }; + }; + }; +} diff --git a/tests/default.nix b/tests/default.nix index 686cc36a129..c170a721224 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -146,6 +146,7 @@ import nmt { ./modules/services/polybar ./modules/services/redshift-gammastep ./modules/services/screen-locker + ./modules/services/swayidle ./modules/services/sxhkd ./modules/services/syncthing ./modules/services/trayer diff --git a/tests/modules/services/swayidle/basic-configuration.nix b/tests/modules/services/swayidle/basic-configuration.nix new file mode 100644 index 00000000000..d3c6bef73a0 --- /dev/null +++ b/tests/modules/services/swayidle/basic-configuration.nix @@ -0,0 +1,52 @@ +{ config, pkgs, lib, ... }: + +{ + config = { + services.swayidle = { + enable = true; + package = config.lib.test.mkStubPackage { }; + timeouts = [ + { + timeout = 50; + command = ''notify-send -t 10000 -- "Screen lock in 10 seconds"''; + } + { + timeout = 60; + command = "swaylock -fF"; + } + { + timeout = 300; + command = ''swaymsg "output * dpms off"''; + resumeCommand = ''swaymsg "output * dpms on"''; + } + ]; + events = [ + { + event = "before-sleep"; + command = "swaylock -fF"; + } + { + event = "lock"; + command = "swaylock -fF"; + } + ]; + }; + + nmt.script = let + escapeForRegex = builtins.replaceStrings [ "'" "*" ] [ "'\\''" "\\*" ]; + expectedArgs = escapeForRegex (lib.concatStringsSep " " [ + "-w" + "timeout 50 'notify-send -t 10000 -- \"Screen lock in 10 seconds\"'" + "timeout 60 'swaylock -fF'" + "timeout 300 'swaymsg \"output * dpms off\"' resume 'swaymsg \"output * dpms on\"'" + "before-sleep 'swaylock -fF'" + "lock 'swaylock -fF'" + ]); + in '' + serviceFile=home-files/.config/systemd/user/swayidle.service + + assertFileExists $serviceFile + assertFileRegex $serviceFile 'ExecStart=.*/bin/swayidle ${expectedArgs}' + ''; + }; +} diff --git a/tests/modules/services/swayidle/default.nix b/tests/modules/services/swayidle/default.nix new file mode 100644 index 00000000000..124fe1d7d8a --- /dev/null +++ b/tests/modules/services/swayidle/default.nix @@ -0,0 +1 @@ +{ swayidle-basic-configuration = ./basic-configuration.nix; }