2023-09-06 08:57:25 +00:00
|
|
|
# <https://github.com/ErikReider/SwayNotificationCenter>
|
|
|
|
# sway notification daemon
|
|
|
|
# alternative to mako, dunst, etc
|
|
|
|
#
|
2023-09-06 09:13:34 +00:00
|
|
|
# debugging:
|
|
|
|
# - `journalctl --user -u swaync`
|
|
|
|
# - `G_MESSAGES_DEBUG=all swaync`
|
2023-09-06 10:22:56 +00:00
|
|
|
# - reveal notification center: `swaync-client -t -sw`
|
2023-09-06 08:57:25 +00:00
|
|
|
#
|
2023-09-07 00:11:14 +00:00
|
|
|
# configuration:
|
|
|
|
# - defaults: /run/current-system/etc/profiles/per-user/colin/etc/xdg/swaync/
|
|
|
|
# - `man 5 swaync`
|
2023-09-07 09:09:47 +00:00
|
|
|
# - view document tree: `GTK_DEBUG=interactive swaync` (`systemctl stop --user swaync` first)
|
2023-09-07 00:11:14 +00:00
|
|
|
# - examples:
|
|
|
|
# - thread: <https://github.com/ErikReider/SwayNotificationCenter/discussions/183>
|
|
|
|
# - buttons-grid and menubar: <https://gist.github.com/JannisPetschenka/fb00eec3efea9c7fff8c38a01ce5d507>
|
2023-09-11 23:03:57 +00:00
|
|
|
{ config, lib, pkgs, ... }:
|
2023-09-15 10:20:18 +00:00
|
|
|
let
|
|
|
|
cfg = config.sane.programs.swaynotificationcenter;
|
2023-12-05 16:57:24 +00:00
|
|
|
|
2023-09-15 16:09:28 +00:00
|
|
|
systemctl-toggle = pkgs.writeShellApplication {
|
|
|
|
name = "systemctl-toggle";
|
|
|
|
runtimeInputs = [
|
|
|
|
pkgs.systemd
|
|
|
|
];
|
|
|
|
text = ''
|
|
|
|
if systemctl is-active "$@"; then
|
|
|
|
systemctl stop "$@"
|
|
|
|
else
|
|
|
|
systemctl start "$@"
|
|
|
|
fi
|
|
|
|
'';
|
|
|
|
};
|
2024-02-27 11:04:15 +00:00
|
|
|
|
|
|
|
printIsActive = pkgs.writeShellApplication {
|
|
|
|
name = "print-is-active";
|
|
|
|
runtimeInputs = [
|
|
|
|
pkgs.systemd
|
|
|
|
];
|
|
|
|
text = ''
|
|
|
|
if systemctl is-active "$@"; then
|
|
|
|
echo true
|
|
|
|
else
|
|
|
|
echo false
|
|
|
|
fi
|
|
|
|
'';
|
|
|
|
};
|
2023-09-15 10:20:18 +00:00
|
|
|
in
|
2023-09-06 08:57:25 +00:00
|
|
|
{
|
|
|
|
sane.programs.swaynotificationcenter = {
|
2023-09-07 08:54:43 +00:00
|
|
|
configOption = with lib; mkOption {
|
|
|
|
type = types.submodule {
|
|
|
|
options = {
|
|
|
|
backlight = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "intel_backlight";
|
|
|
|
description = ''
|
|
|
|
name of entry in /sys/class/backlight which indicates the primary backlight.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
default = {};
|
|
|
|
};
|
2024-02-14 11:09:20 +00:00
|
|
|
|
2023-09-11 23:03:57 +00:00
|
|
|
# prevent dbus from automatically activating swaync so i can manage it as a systemd service instead
|
2024-03-10 23:16:33 +00:00
|
|
|
packageUnwrapped = pkgs.rmDbusServices pkgs.swaynotificationcenter;
|
2024-02-14 11:09:20 +00:00
|
|
|
|
2024-02-15 16:38:38 +00:00
|
|
|
sandbox.method = "bwrap";
|
|
|
|
sandbox.whitelistAudio = true;
|
|
|
|
sandbox.whitelistDbus = [
|
|
|
|
"user" # mpris; portal
|
|
|
|
"system" # backlight
|
|
|
|
];
|
|
|
|
sandbox.whitelistWayland = true;
|
|
|
|
sandbox.extraPaths = [
|
|
|
|
"/sys/class/backlight"
|
|
|
|
"/sys/devices"
|
|
|
|
];
|
|
|
|
sandbox.extraRuntimePaths = [
|
|
|
|
# systemd/private allows one to `systemctl --user {status,start,stop,...}`
|
|
|
|
# notably, it does *not* allow for `systemd-run` (that's dbus: org.freedesktop.systemd1.Manager.StartTransientUnit).
|
|
|
|
# that doesn't necessarily mean this is entirely safe against privilege escalation though.
|
|
|
|
# TODO: audit the safety of this systemd sandboxing.
|
|
|
|
# few alternatives:
|
|
|
|
# - superd
|
|
|
|
# - simply `xdg-open app://dino`, etc. `pkill` to stop, `pgrep` to query.
|
|
|
|
# - more robust: `xdg-open sane-service://start?service=dino`
|
|
|
|
# - still need `pgrep` to query if it's running, or have the service mark a pid file
|
|
|
|
# - dbus activation for each app
|
|
|
|
"systemd/private"
|
|
|
|
];
|
|
|
|
sandbox.extraConfig = [
|
|
|
|
# systemctl calls seem to require same pid namespace
|
2024-02-25 12:00:00 +00:00
|
|
|
"--sane-sandbox-keep-namespace" "pid"
|
2024-02-15 16:38:38 +00:00
|
|
|
];
|
|
|
|
|
2024-02-14 11:09:20 +00:00
|
|
|
# glib/gio applications support many notification backends ("portal", "gtk", "freedesktop", ...).
|
|
|
|
# swaync implements only the `org.freedesktop.Notifications` dbus interface ("freedesktop"/fdo).
|
|
|
|
# however gio applications may be tricked into using one of the other backends, particularly
|
|
|
|
# if xdg-desktop-portal-gtk is installed and GIO_USE_PORTALS=1.
|
|
|
|
# so, explicitly specify the desired backend.
|
|
|
|
# the glib code which consumes this is `g_notification_backend_new_default`, calling into `_g_io_module_get_default_type`.
|
|
|
|
env.GNOTIFICATION_BACKEND = "freedesktop";
|
|
|
|
|
2023-09-15 10:20:18 +00:00
|
|
|
suggestedPrograms = [ "feedbackd" ];
|
2024-02-14 11:09:20 +00:00
|
|
|
|
2024-03-13 08:18:34 +00:00
|
|
|
fs.".config/swaync/style.css".symlink.target = ./style.css;
|
2023-09-06 09:03:19 +00:00
|
|
|
fs.".config/swaync/config.json".symlink.text = builtins.toJSON {
|
|
|
|
"$schema" = "/etc/xdg/swaync/configSchema.json";
|
|
|
|
positionX = "right";
|
|
|
|
positionY = "top";
|
|
|
|
layer = "overlay";
|
|
|
|
control-center-layer = "top";
|
|
|
|
layer-shell = true;
|
2023-09-07 00:11:14 +00:00
|
|
|
cssPriority = "user"; # "application"|"user". "user" in order to override the system gtk theme.
|
2023-09-06 09:03:19 +00:00
|
|
|
control-center-margin-top = 0;
|
|
|
|
control-center-margin-bottom = 0;
|
|
|
|
control-center-margin-right = 0;
|
|
|
|
control-center-margin-left = 0;
|
|
|
|
notification-2fa-action = true;
|
|
|
|
notification-inline-replies = false;
|
|
|
|
notification-icon-size = 64;
|
|
|
|
notification-body-image-height = 100;
|
|
|
|
notification-body-image-width = 200;
|
2023-09-06 09:20:00 +00:00
|
|
|
timeout = 30;
|
2023-09-06 09:03:19 +00:00
|
|
|
timeout-low = 5;
|
|
|
|
timeout-critical = 0;
|
2023-09-07 00:11:14 +00:00
|
|
|
fit-to-screen = true; #< have notification center take full vertical screen space
|
2023-10-28 11:43:26 +00:00
|
|
|
# control-center-width:
|
2024-03-13 08:29:23 +00:00
|
|
|
# pinephone native display is 720 x 1440
|
|
|
|
# - for compositor scale=2.0 => 360
|
|
|
|
# - for compositor scale=1.8 => 400
|
|
|
|
# - for compositor scale=1.6 => 450
|
2023-10-28 11:43:26 +00:00
|
|
|
# if it's set to something wider than the screen, then it overflows and items aren't visible.
|
2024-03-13 08:29:23 +00:00
|
|
|
control-center-width = 360;
|
2023-09-06 09:03:19 +00:00
|
|
|
control-center-height = 600;
|
2024-03-13 08:29:23 +00:00
|
|
|
notification-window-width = 360;
|
2023-09-06 09:03:19 +00:00
|
|
|
keyboard-shortcuts = true;
|
|
|
|
image-visibility = "when-available";
|
2023-09-06 09:20:00 +00:00
|
|
|
transition-time = 100;
|
2023-09-07 00:11:14 +00:00
|
|
|
hide-on-clear = true; #< hide control center when clicking "clear all"
|
2023-09-06 09:03:19 +00:00
|
|
|
hide-on-action = true;
|
|
|
|
script-fail-notify = true;
|
2024-03-24 08:22:53 +00:00
|
|
|
scripts = import ./scripts.nix {
|
|
|
|
inherit pkgs;
|
2023-09-06 09:03:19 +00:00
|
|
|
};
|
|
|
|
widgets = [
|
2023-09-07 00:11:14 +00:00
|
|
|
# what to show in the notification center (and in which order).
|
|
|
|
# these are configurable further via `widget-config`.
|
|
|
|
# besides these listed, there are general-purpose UI tools:
|
|
|
|
# - label (show some text)
|
|
|
|
# - buttons-grid (labels which trigger actions when clicked)
|
|
|
|
# - menubar (tree of labels/actions)
|
2023-09-06 09:03:19 +00:00
|
|
|
"title"
|
|
|
|
"dnd"
|
2023-09-07 00:11:14 +00:00
|
|
|
"inhibitors"
|
2023-09-15 16:09:28 +00:00
|
|
|
"buttons-grid"
|
2023-09-07 00:11:14 +00:00
|
|
|
"backlight"
|
|
|
|
"volume"
|
|
|
|
"mpris"
|
2023-09-06 09:03:19 +00:00
|
|
|
"notifications"
|
|
|
|
];
|
|
|
|
widget-config = {
|
2023-09-07 00:11:14 +00:00
|
|
|
backlight = {
|
|
|
|
label = " ";
|
2023-09-15 10:20:18 +00:00
|
|
|
device = cfg.config.backlight;
|
2023-09-07 00:11:14 +00:00
|
|
|
};
|
2023-09-15 16:09:28 +00:00
|
|
|
buttons-grid = {
|
2023-10-07 04:14:42 +00:00
|
|
|
actions =
|
2023-09-15 16:51:43 +00:00
|
|
|
# {
|
|
|
|
# type = "toggle";
|
|
|
|
# label = "feedbackd";
|
|
|
|
# command = "${systemctl-toggle}/bin/systemctl-toggle --user feedbackd";
|
|
|
|
# active = "${pkgs.systemd}/bin/systemctl is-active --user feedbackd.service";
|
|
|
|
# }
|
2023-10-07 04:14:42 +00:00
|
|
|
lib.optionals config.sane.programs.eg25-control.enabled [
|
2023-09-15 16:09:28 +00:00
|
|
|
{
|
|
|
|
type = "toggle";
|
2023-11-17 09:18:14 +00:00
|
|
|
label = ""; # GPS services; other icons: gps, ⌖, 🛰, 🌎,
|
2023-09-15 16:51:43 +00:00
|
|
|
command = "/run/wrappers/bin/sudo ${systemctl-toggle}/bin/systemctl-toggle eg25-control-gps";
|
2024-02-27 11:04:15 +00:00
|
|
|
update-command = "${printIsActive}/bin/print-is-active eg25-control-gps.service";
|
|
|
|
active = true;
|
2023-09-15 16:09:28 +00:00
|
|
|
}
|
2023-10-28 11:43:26 +00:00
|
|
|
{
|
|
|
|
type = "toggle";
|
2023-11-17 09:18:14 +00:00
|
|
|
label = ""; # icons: 5g, 📡, 📱, ᯤ, ⚡, , 🌐, 📶, 🗼, , , ,
|
2023-10-28 11:43:26 +00:00
|
|
|
# modem and NetworkManager auto-establishes a connection when powered.
|
|
|
|
# though some things like `wg-home` VPN tunnel will remain routed over the old interface.
|
|
|
|
command = "/run/wrappers/bin/sudo ${systemctl-toggle}/bin/systemctl-toggle eg25-control-powered";
|
2024-02-27 11:04:15 +00:00
|
|
|
update-command = "${printIsActive}/bin/print-is-active eg25-control-powered.service";
|
|
|
|
active = true;
|
2023-10-28 11:43:26 +00:00
|
|
|
}
|
2023-11-14 01:31:30 +00:00
|
|
|
] ++ lib.optionals false [
|
2023-09-19 16:25:17 +00:00
|
|
|
{
|
|
|
|
type = "toggle";
|
2023-11-14 01:31:30 +00:00
|
|
|
label = "vpn::hn"; # route all traffic through servo; useful to debug moby's networking
|
2023-09-19 16:25:17 +00:00
|
|
|
command = "/run/wrappers/bin/sudo ${systemctl-toggle}/bin/systemctl-toggle wg-quick-vpn-servo";
|
2024-02-27 11:04:15 +00:00
|
|
|
update-command = "${printIsActive}/bin/print-is-active wg-quick-vpn-servo.service";
|
|
|
|
active = true;
|
2023-09-19 16:25:17 +00:00
|
|
|
}
|
2023-09-21 19:53:02 +00:00
|
|
|
] ++ lib.optionals config.sane.programs.calls.config.autostart [
|
|
|
|
{
|
|
|
|
type = "toggle";
|
|
|
|
label = "SIP";
|
2023-09-22 23:10:50 +00:00
|
|
|
command = "${systemctl-toggle}/bin/systemctl-toggle --user gnome-calls";
|
2024-02-27 11:04:15 +00:00
|
|
|
update-command = "${printIsActive}/bin/print-is-active --user gnome-calls";
|
|
|
|
active = true;
|
2023-09-21 19:53:02 +00:00
|
|
|
}
|
2023-11-14 00:38:06 +00:00
|
|
|
] ++ lib.optionals config.sane.programs."gnome.geary".enabled [
|
|
|
|
{
|
|
|
|
type = "toggle";
|
2023-11-17 09:18:14 +00:00
|
|
|
label = ""; # email (Geary); other icons: ✉, [E], 📧,
|
2023-11-14 00:38:06 +00:00
|
|
|
command = "${systemctl-toggle}/bin/systemctl-toggle --user geary";
|
2024-02-27 11:04:15 +00:00
|
|
|
update-command = "${printIsActive}/bin/print-is-active --user geary";
|
|
|
|
active = true;
|
2023-11-14 00:38:06 +00:00
|
|
|
}
|
2023-12-09 16:45:40 +00:00
|
|
|
# ] ++ lib.optionals config.sane.programs.abaddon.enabled [
|
2024-03-16 11:17:47 +00:00
|
|
|
# # XXX: disabled in favor of dissent: abaddon has troubles auto-connecting at start
|
2023-11-21 03:32:59 +00:00
|
|
|
# {
|
|
|
|
# type = "toggle";
|
|
|
|
# label = ""; # Discord chat client; icons: , 🎮
|
2023-12-09 16:45:40 +00:00
|
|
|
# command = "${systemctl-toggle}/bin/systemctl-toggle --user abaddon";
|
2024-02-27 11:04:15 +00:00
|
|
|
# update-command = "${printIsActive}/bin/print-is-active --user abaddon";
|
|
|
|
# active = true;
|
2023-11-21 03:32:59 +00:00
|
|
|
# }
|
2024-03-16 11:17:47 +00:00
|
|
|
] ++ lib.optionals config.sane.programs.dissent.enabled [
|
2023-12-09 16:45:40 +00:00
|
|
|
{
|
|
|
|
type = "toggle";
|
|
|
|
label = ""; # Discord chat client; icons: , 🎮
|
2024-03-16 11:17:47 +00:00
|
|
|
command = "${systemctl-toggle}/bin/systemctl-toggle --user dissent";
|
|
|
|
update-command = "${printIsActive}/bin/print-is-active --user dissent";
|
2024-02-27 11:04:15 +00:00
|
|
|
active = true;
|
2023-12-09 16:45:40 +00:00
|
|
|
}
|
2023-11-17 04:05:59 +00:00
|
|
|
] ++ lib.optionals config.sane.programs.signal-desktop.enabled [
|
|
|
|
{
|
|
|
|
type = "toggle";
|
2023-11-17 09:18:14 +00:00
|
|
|
label = "💬"; # Signal messenger; other icons:
|
2023-11-17 04:05:59 +00:00
|
|
|
command = "${systemctl-toggle}/bin/systemctl-toggle --user signal-desktop";
|
2024-03-02 18:33:35 +00:00
|
|
|
update-command = "${printIsActive}/bin/print-is-active --user signal-desktop";
|
2024-02-27 11:04:15 +00:00
|
|
|
active = true;
|
2023-11-17 04:05:59 +00:00
|
|
|
}
|
2023-10-07 04:14:42 +00:00
|
|
|
] ++ lib.optionals config.sane.programs.dino.enabled [
|
2023-09-21 19:53:02 +00:00
|
|
|
{
|
|
|
|
type = "toggle";
|
2023-10-02 06:12:24 +00:00
|
|
|
label = "XMPP"; # XMPP calls (jingle)
|
2023-09-22 23:10:50 +00:00
|
|
|
command = "${systemctl-toggle}/bin/systemctl-toggle --user dino";
|
2024-02-27 11:04:15 +00:00
|
|
|
update-command = "${printIsActive}/bin/print-is-active --user dino";
|
|
|
|
active = true;
|
2023-09-21 19:53:02 +00:00
|
|
|
}
|
2023-10-07 04:14:42 +00:00
|
|
|
] ++ lib.optionals config.sane.programs.fractal.enabled [
|
2023-10-02 06:12:24 +00:00
|
|
|
{
|
|
|
|
type = "toggle";
|
2023-10-28 11:43:26 +00:00
|
|
|
label = "[m]"; # Matrix messages
|
2023-10-02 06:12:24 +00:00
|
|
|
command = "${systemctl-toggle}/bin/systemctl-toggle --user fractal";
|
2024-02-27 11:04:15 +00:00
|
|
|
update-command = "${printIsActive}/bin/print-is-active --user fractal";
|
|
|
|
active = true;
|
2023-10-02 06:12:24 +00:00
|
|
|
}
|
2023-09-15 16:09:28 +00:00
|
|
|
];
|
|
|
|
};
|
2023-09-07 00:11:14 +00:00
|
|
|
dnd = {
|
|
|
|
text = "Do Not Disturb";
|
|
|
|
};
|
2023-09-06 09:03:19 +00:00
|
|
|
inhibitors = {
|
|
|
|
text = "Inhibitors";
|
|
|
|
button-text = "Clear All";
|
|
|
|
clear-all-button = true;
|
|
|
|
};
|
2023-09-07 00:11:14 +00:00
|
|
|
mpris = {
|
2024-03-13 08:18:34 +00:00
|
|
|
image-size = 48;
|
2023-09-07 00:11:14 +00:00
|
|
|
image-radius = 8;
|
|
|
|
};
|
2023-09-06 09:03:19 +00:00
|
|
|
title = {
|
|
|
|
text = "Notifications";
|
|
|
|
clear-all-button = true;
|
|
|
|
button-text = "Clear All";
|
|
|
|
};
|
2023-09-07 00:11:14 +00:00
|
|
|
volume = {
|
|
|
|
label = " ";
|
2023-09-06 09:03:19 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
2023-09-12 04:44:38 +00:00
|
|
|
services.swaync = {
|
|
|
|
# swaync ships its own service, but i want to add `environment` variables and flags for easier debugging.
|
|
|
|
# seems that's not possible without defining an entire nix-native service (i.e. this).
|
2024-02-19 12:57:44 +00:00
|
|
|
description = "swaynotificationcenter (swaync) desktop notification daemon";
|
2024-03-21 16:02:06 +00:00
|
|
|
depends = [ "sound" ]; #< TODO: else it will NEVER see the pulse socket in its sandbox
|
|
|
|
partOf = [ "graphical-session" ];
|
2024-02-19 12:57:44 +00:00
|
|
|
|
2024-03-21 15:05:23 +00:00
|
|
|
command = "env G_MESSAGES_DEBUG=all swaync";
|
2024-03-21 16:59:04 +00:00
|
|
|
readiness.waitDbus = "org.freedesktop.Notifications";
|
2023-09-12 04:44:38 +00:00
|
|
|
};
|
2023-09-07 07:34:22 +00:00
|
|
|
};
|
2023-09-15 10:20:18 +00:00
|
|
|
|
|
|
|
sane.programs.feedbackd.config = lib.mkIf cfg.enabled {
|
|
|
|
# claim control over feedbackd: we'll proxy the sounds we want on behalf of notifying programs
|
|
|
|
proxied = true;
|
|
|
|
};
|
2023-09-06 08:57:25 +00:00
|
|
|
}
|