1
0
Fork 0
mirror of https://github.com/nix-community/home-manager.git synced 2025-11-08 19:46:05 +01:00
home-manager/modules/services/dunst.nix
2025-09-11 10:15:27 +02:00

227 lines
5.8 KiB
Nix

{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
literalExpression
mkOption
optional
types
;
cfg = config.services.dunst;
eitherStrBoolIntList = with types; either str (either bool (either int (listOf str)));
toDunstIni = lib.generators.toINI {
mkKeyValue =
key: value:
let
value' =
if lib.isBool value then
(lib.hm.booleans.yesNo value)
else if lib.isString value then
''"${value}"''
else
toString value;
in
"${key}=${value'}";
};
themeType = types.submodule {
options = {
package = mkOption {
type = types.package;
example = literalExpression "pkgs.adwaita-icon-theme";
description = "Package providing the theme.";
};
name = mkOption {
type = types.str;
example = "Adwaita";
description = "The name of the theme within the package.";
};
size = mkOption {
type = types.str;
default = "32x32";
example = "16x16";
description = "The desired icon size.";
};
};
};
hicolorTheme = {
package = pkgs.hicolor-icon-theme;
name = "hicolor";
size = "32x32";
};
in
{
meta.maintainers = [ lib.maintainers.rycee ];
options = {
services.dunst = {
enable = lib.mkEnableOption "the dunst notification daemon";
package = lib.mkPackageOption pkgs "dunst" { };
configFile = mkOption {
type = with types; nullOr (either str path);
default = null;
description = ''
Path to the configuration file read by dunst.
Note that the configuration generated by Home Manager will be
written to {file}`$XDG_CONFIG_HOME/dunst/dunstrc`
regardless. This allows using a mutable configuration file generated
from the immutable one, useful in scenarios where live reloading is
desired.
'';
};
iconTheme = mkOption {
type = themeType;
default = hicolorTheme;
description = "Set the icon theme.";
};
waylandDisplay = mkOption {
type = types.str;
default = "";
description = "Set the service's {env}`WAYLAND_DISPLAY` environment variable.";
};
settings = mkOption {
type = types.submodule {
freeformType = with types; attrsOf (attrsOf eitherStrBoolIntList);
options = {
global.icon_path = mkOption {
type = types.separatedString ":";
description = "Paths where dunst will look for icons.";
};
};
};
default = { };
description = "Configuration written to {file}`$XDG_CONFIG_HOME/dunst/dunstrc`.";
example = literalExpression ''
{
global = {
width = "(200,300)";
height = "(0,150)";
offset = "(30,50)";
origin = "top-right";
transparency = 10;
frame_color = "#eceff1";
font = "Droid Sans 9";
};
urgency_normal = {
background = "#37474f";
foreground = "#eceff1";
timeout = 10;
};
};
'';
};
};
};
config = lib.mkIf cfg.enable {
assertions = [
(lib.hm.assertions.assertPlatform "services.dunst" pkgs lib.platforms.linux)
];
home.packages = [ cfg.package ];
xdg.dataFile."dbus-1/services/org.knopwob.dunst.service".source =
"${cfg.package}/share/dbus-1/services/org.knopwob.dunst.service";
xdg.configFile."dunst/dunstrc" = lib.mkIf (cfg.settings != { }) {
text = toDunstIni cfg.settings;
};
services.dunst.settings.global.icon_path =
let
useCustomTheme =
cfg.iconTheme.package != hicolorTheme.package
|| cfg.iconTheme.name != hicolorTheme.name
|| cfg.iconTheme.size != hicolorTheme.size;
basePaths = [
"/run/current-system/sw"
config.home.profileDirectory
cfg.iconTheme.package
]
++ optional useCustomTheme hicolorTheme.package;
themes = [
cfg.iconTheme
]
++ optional useCustomTheme (hicolorTheme // { size = cfg.iconTheme.size; });
categories = [
"actions"
"animations"
"apps"
"categories"
"devices"
"emblems"
"emotes"
"filesystem"
"intl"
"legacy"
"mimetypes"
"places"
"status"
"stock"
];
mkPath =
{
basePath,
theme,
category,
}:
"${basePath}/share/icons/${theme.name}/${theme.size}/${category}";
in
lib.concatMapStringsSep ":" mkPath (
lib.cartesianProduct {
basePath = basePaths;
theme = themes;
category = categories;
}
);
systemd.user.services.dunst = {
Unit = {
Description = "Dunst notification daemon";
After = [ config.wayland.systemd.target ];
PartOf = [ config.wayland.systemd.target ];
X-Reload-Triggers = lib.mkIf (cfg.settings != { }) [
"${config.xdg.configFile."dunst/dunstrc".source}"
];
};
Service = {
Type = "dbus";
BusName = "org.freedesktop.Notifications";
ExecStart = lib.escapeShellArgs (
[ "${cfg.package}/bin/dunst" ]
++
# Using `-config` breaks dunst's drop-ins, so only use it when an alternative path is set
lib.optionals (cfg.configFile != null) [
"-config"
cfg.configFile
]
);
ExecReload = "${cfg.package}/bin/dunstctl reload";
Environment = lib.optionalString (cfg.waylandDisplay != "") "WAYLAND_DISPLAY=${cfg.waylandDisplay}";
};
};
};
}