{ config, lib, pkgs, ... }: with lib; let cfg = config.services.fnott; concatStringsSep' = sep: list: concatStringsSep sep (filter (x: x != "") list); mkKeyValue = generators.mkKeyValueDefault { } "="; genINI = generators.toINI { }; iniFormatType = with types; let iniAtom = types.nullOr (types.oneOf [ bool int float str ]) // { description = "INI atom (null, bool, int, float or string)"; }; in attrsOf (attrsOf iniAtom); in { options = { services.fnott = { enable = mkEnableOption '' fnott, a lightweight Wayland notification daemon for wlroots-based compositors ''; package = mkOption { type = types.package; default = pkgs.fnott; defaultText = literalExample "pkgs.fnott"; description = "Package providing fnott."; }; extraFlags = mkOption { type = types.listOf types.str; default = [ ]; example = [ "-s" ]; description = '' Extra arguments to use for executing fnott. ''; }; configFile = mkOption { type = types.either types.str types.path; default = "${config.xdg.configHome}/fnott/fnott.ini"; defaultText = "$XDG_CONFIG_HOME/fnott/fnott.ini"; description = '' Path to the configuration file read by fnott. Note that environment variables in the path won't be properly expanded. The configuration specified under will be generated and written to $XDG_CONFIG_HOME/fnott/fnott.ini regardless of this option. This allows using a mutable configuration file generated from the immutable one, useful in scenarios where live reloading is desired. ''; }; settings = mkOption { type = iniFormatType; default = { }; description = '' Configuration written to $XDG_CONFIG_HOME/fnott/fnott.ini. See fnott.ini 5 for a list of avaliable options and for an example configuration. ''; example = literalExample '' { main = { notification-margin = 5; }; low = { timeout = 5; title-font = "Dina:weight=bold:slant=italic"; title-color = "ffffff"; }; } ''; }; }; }; config = mkIf cfg.enable { assertions = [ (hm.assertions.assertPlatform "services.fnott" pkgs platforms.linux) ]; home.packages = [ cfg.package ]; systemd.user.services.fnott = { Unit = { Description = "Fnott notification daemon"; Documentation = "man:fnott(1)"; After = [ "graphical-session-pre.target" ]; PartOf = [ "graphical-session.target" ]; }; Service = { Type = "dbus"; BusName = "org.freedesktop.Notifications"; ExecStart = concatStringsSep' " " [ "${cfg.package}/bin/fnott" "-c ${escapeShellArg cfg.configFile}" (escapeShellArgs cfg.extraFlags) ]; }; }; xdg.configFile."fnott/fnott.ini" = { # FIXME: Remove after next version release (https://codeberg.org/dnkl/fnott/pulls/24). text = concatStringsSep' "\n" [ (optionalString (cfg.settings ? main) '' ${concatStringsSep "\n" (mapAttrsToList mkKeyValue cfg.settings.main)} '') (genINI (removeAttrs cfg.settings [ "main" ])) ]; }; }; }