1
0
mirror of https://github.com/nix-community/home-manager synced 2024-06-26 16:38:34 +02:00
home-manager/modules/services/twmn.nix
Emily 9f9e277b60 treewide: remove now-redundant lib.mdDoc calls
These (and the `*MD` functions apart from `literalMD`) are now no-ops
in nixpkgs and serve no purpose other than to add additional noise and
potentially mislead people into thinking unmarked DocBook documentation
will still be accepted.

Note that if backporting changes including documentation to 23.05,
the `mdDoc` calls will need to be re-added.

To reproduce this commit, run:

    $ NIX_PATH=nixpkgs=flake:nixpkgs/e7e69199f0372364a6106a1e735f68604f4c5a25 \
      nix shell nixpkgs#coreutils \
      -c find . -name '*.nix' \
      -exec nix run -- github:emilazy/nix-doc-munge/98dadf1f77351c2ba5dcb709a2a171d655f15099 \
      --strip {} +
    $ ./format
2023-07-17 18:49:09 +01:00

381 lines
10 KiB
Nix

{ config, lib, pkgs, stdenv, ... }:
with lib;
let
cfg = config.services.twmn;
animationOpts = {
curve = mkOption {
type = types.ints.between 0 40;
default = 38;
example = 19;
description = ''
The qt easing-curve animation to use for the animation. See
[
QEasingCurve documentation](https://doc.qt.io/qt-5/qeasingcurve.html#Type-enum).
'';
};
duration = mkOption {
type = types.ints.unsigned;
default = 1000;
example = 618;
description = "The animation duration in milliseconds.";
};
};
in {
meta.maintainers = [ hm.maintainers.austreelis ];
options.services.twmn = {
enable = mkEnableOption "twmn, a tiling window manager notification daemon";
duration = mkOption {
type = types.ints.unsigned;
default = 3000;
example = 5000;
description = ''
The time each notification remains visible, in milliseconds.
'';
};
extraConfig = mkOption {
type = types.attrs;
default = { };
example = literalExpression
''{ main.activation_command = "\${pkgs.hello}/bin/hello"; }'';
description = ''
Extra configuration options to add to the twmnd config file. See
<https://github.com/sboli/twmn/blob/master/README.md>
for details.
'';
};
host = mkOption {
type = types.str;
default = "127.0.0.1";
example = "laptop.lan";
description = "Host address to listen on for notifications.";
};
icons = {
critical = mkOption {
type = types.nullOr types.path;
default = null;
description = "Path to the critical notifications' icon.";
};
info = mkOption {
type = types.nullOr types.path;
default = null;
description = "Path to the informative notifications' icon.";
};
warning = mkOption {
type = types.nullOr types.path;
default = null;
description = "Path to the warning notifications' icon.";
};
};
port = mkOption {
type = types.port;
default = 9797;
description = "UDP port to listen on for notifications.";
};
screen = mkOption {
type = types.nullOr types.int;
default = null;
example = 0;
description = ''
Screen number to display notifications on when using a multi-head
desktop.
'';
};
soundCommand = mkOption {
type = types.str;
default = "";
description = "Command to execute to play a notification's sound.";
};
text = {
color = mkOption {
type = types.str;
default = "#999999";
example = "lightgray";
description = ''
Notification's text color. RGB hex and keywords (e.g. `lightgray`)
are supported.
'';
};
font = {
package = mkOption {
type = types.nullOr types.package;
default = null;
example = literalExpression "pkgs.dejavu_fonts";
description = ''
Notification text's font package. If `null` then
the font is assumed to already be available in your profile.
'';
};
family = mkOption {
type = types.str;
default = "Sans";
example = "Noto Sans";
description = "Notification text's font family.";
};
size = mkOption {
type = types.ints.unsigned;
default = 13;
example = 42;
description = "Notification text's font size.";
};
variant = mkOption {
# These are the font variant supported by twmn
# See https://github.com/sboli/twmn/blob/master/README.md?plain=1#L42
type = types.enum [
"oblique"
"italic"
"ultra-light"
"light"
"medium"
"semi-bold"
"bold"
"ultra-bold"
"heavy"
"ultra-condensed"
"extra-condensed"
"condensed"
"semi-condensed"
"semi-expanded"
"expanded"
"extra-expanded"
"ultra-expanded"
];
default = "medium";
example = "heavy";
description = "Notification text's font variant.";
};
};
maxLength = mkOption {
type = types.nullOr types.ints.unsigned;
default = null;
example = 80;
description = ''
Maximum length of the text before it is cut and suffixed with "...".
Never cuts if `null`.
'';
};
};
window = {
alwaysOnTop =
mkEnableOption "forcing the notification window to always be on top";
animation = {
easeIn = mkOption {
type = types.submodule { options = animationOpts; };
default = { };
example = literalExpression ''
{
curve = 19;
duration = 618;
}
'';
description = "Options for the notification appearance's animation.";
};
easeOut = mkOption {
type = types.submodule { options = animationOpts; };
default = { };
example = literalExpression ''
{
curve = 19;
duration = 618;
}
'';
description =
"Options for the notification disappearance's animation.";
};
bounce = {
enable = mkEnableOption
"notification bounce when displaying next notification directly";
duration = mkOption {
type = types.ints.unsigned;
default = 500;
example = 618;
description = "The bounce animation duration in milliseconds.";
};
};
};
color = mkOption {
type = types.str;
default = "#000000";
example = "lightgray";
description = ''
Notification's background color. RGB hex and keywords (e.g.
`lightgray`) are supported.
'';
};
height = mkOption {
type = types.ints.unsigned;
default = 18;
example = 42;
description = ''
Height of the slide bar. Useful to match your tiling window
manager's bar.
'';
};
offset = {
x = mkOption {
type = types.int;
default = 0;
example = 50;
description = ''
Offset of the notification's slide starting point in pixels on the
horizontal axis (positive is rightward).
'';
};
y = mkOption {
type = types.int;
default = 0;
example = -100;
description = ''
Offset of the notification's slide starting point in pixels on the
vertical axis (positive is upward).
'';
};
};
opacity = mkOption {
type = types.ints.between 0 100;
default = 100;
example = 80;
description = "The notification window's opacity.";
};
position = mkOption {
type = types.enum [
"tr"
"top_right"
"tl"
"top_left"
"br"
"bottom_right"
"bl"
"bottom_left"
"tc"
"top_center"
"bc"
"bottom_center"
"c"
"center"
];
default = "top_right";
example = "bottom_left";
description = ''
Position of the notification slide. The notification will slide
in vertically from the border if placed in
`top_center` or `bottom_center`,
horizontally otherwise.
'';
};
};
};
#################
# Implementation
config = mkIf cfg.enable {
assertions = [
(lib.hm.assertions.assertPlatform "services.twmn" pkgs
lib.platforms.linux)
];
home.packages =
lib.optional (!isNull cfg.text.font.package) cfg.text.font.package
++ [ pkgs.twmn ];
xdg.configFile."twmn/twmn.conf".text = let
conf = recursiveUpdate {
gui = {
always_on_top = if cfg.window.alwaysOnTop then "true" else "false";
background_color = cfg.window.color;
bounce =
if cfg.window.animation.bounce.enable then "true" else "false";
bounce_duration = toString cfg.window.animation.bounce.duration;
font = cfg.text.font.family;
font_size = toString cfg.text.font.size;
font_variant = cfg.text.font.variant;
foreground_color = cfg.text.color;
height = toString cfg.window.height;
in_animation = toString cfg.window.animation.easeIn.curve;
in_animation_duration = toString cfg.window.animation.easeIn.duration;
max_length = toString
(if isNull cfg.text.maxLength then -1 else cfg.text.maxLength);
offset_x = with cfg.window.offset;
if x < 0 then toString x else "+${toString x}";
offset_y = with cfg.window.offset;
if y < 0 then toString y else "+${toString y}";
opacity = toString cfg.window.opacity;
out_animation = toString cfg.window.animation.easeOut.curve;
out_animation_duration =
toString cfg.window.animation.easeOut.duration;
position = cfg.window.position;
screen = toString cfg.screen;
};
# map null values to empty strings because formats.toml generator fails
# when encountering a null.
icons = mapAttrs (_: toString) cfg.icons;
main = {
duration = toString cfg.duration;
host = cfg.host;
port = toString cfg.port;
sound_command = cfg.soundCommand;
};
} cfg.extraConfig;
mkLine = name: value: "${name}=${value}";
mkSection = section: conf: ''
[${section}]
${concatStringsSep "\n" (mapAttrsToList mkLine conf)}
'';
in concatStringsSep "\n" (mapAttrsToList mkSection conf) + "\n";
systemd.user.services.twmnd = {
Unit = {
Description = "twmn daemon";
After = [ "graphical-session-pre.target" ];
PartOf = [ "graphical-session.target" ];
X-Restart-Triggers =
[ "${config.xdg.configFile."twmn/twmn.conf".source}" ];
};
Install.WantedBy = [ "graphical-session.target" ];
Service = {
ExecStart = "${pkgs.twmn}/bin/twmnd";
Restart = "on-failure";
Type = "simple";
StandardOutput = "null";
};
};
};
}