swaync: remove sxmo timer rules
This commit is contained in:
@@ -18,71 +18,6 @@
|
|||||||
let
|
let
|
||||||
cfg = config.sane.programs.swaynotificationcenter;
|
cfg = config.sane.programs.swaynotificationcenter;
|
||||||
|
|
||||||
fbcli-wrapper = pkgs.writeShellApplication {
|
|
||||||
name = "swaync-fbcli";
|
|
||||||
runtimeInputs = [
|
|
||||||
config.sane.programs.feedbackd.package
|
|
||||||
pkgs.procps # for pkill
|
|
||||||
cfg.package
|
|
||||||
];
|
|
||||||
text = ''
|
|
||||||
# if in Do Not Disturb, don't do any feedback
|
|
||||||
# TODO: better solution is to actually make use of feedbackd profiles.
|
|
||||||
# i.e. set profile to `quiet` when in DnD mode
|
|
||||||
if [ "$SWAYNC_URGENCY" != "Critical" ] && [ "$(swaync-client --get-dnd)" = "true" ]; then
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
# kill children if killed, to allow that killing this parent process will end the real fbcli call
|
|
||||||
cleanup() {
|
|
||||||
echo "aborting fbcli notification (PID $child)"
|
|
||||||
pkill -P "$child"
|
|
||||||
exit 0 # exit cleanly to avoid swaync alerting a script failure
|
|
||||||
}
|
|
||||||
trap cleanup SIGINT SIGQUIT SIGTERM
|
|
||||||
|
|
||||||
# feedbackd stops playback when the caller exits
|
|
||||||
# and fbcli will exit immediately if it has no stdin.
|
|
||||||
# so spoof a stdin:
|
|
||||||
/bin/sh -c "true | fbcli $*" &
|
|
||||||
child=$!
|
|
||||||
wait
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
fbcli = "${fbcli-wrapper}/bin/swaync-fbcli";
|
|
||||||
|
|
||||||
# we do this because swaync's exec naively splits the command on space to produce its argv, rather than parsing the shell.
|
|
||||||
# [ "pkill" "-f" "fbcli" "--event" ... ] -> breaks pkill
|
|
||||||
# [ "pkill" "-f" "fbcli --event ..." ] -> is what we want
|
|
||||||
fbcli-stop-wrapper = pkgs.writeShellApplication {
|
|
||||||
name = "fbcli-stop";
|
|
||||||
runtimeInputs = [
|
|
||||||
pkgs.procps # for pkill
|
|
||||||
];
|
|
||||||
text = ''
|
|
||||||
pkill -e -f "${fbcli} $*"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
fbcli-stop = "${fbcli-stop-wrapper}/bin/fbcli-stop";
|
|
||||||
|
|
||||||
kill-singleton_ = pkgs.writeShellApplication {
|
|
||||||
name = "kill-singleton";
|
|
||||||
runtimeInputs = [
|
|
||||||
pkgs.procps # for pgrep
|
|
||||||
pkgs.gnugrep
|
|
||||||
];
|
|
||||||
text = ''
|
|
||||||
pids=$(pgrep --full "$*" | tr '\n' ' ') || true
|
|
||||||
# only act if there's exactly one pid
|
|
||||||
if echo "$pids" | grep -Eq '^[0-9]+ ?$'; then
|
|
||||||
kill "$pids"
|
|
||||||
else
|
|
||||||
echo "kill-singleton: skipping because multiple pids match: $pids"
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
kill-singleton = "${kill-singleton_}/bin/kill-singleton";
|
|
||||||
|
|
||||||
systemctl-toggle = pkgs.writeShellApplication {
|
systemctl-toggle = pkgs.writeShellApplication {
|
||||||
name = "systemctl-toggle";
|
name = "systemctl-toggle";
|
||||||
runtimeInputs = [
|
runtimeInputs = [
|
||||||
@@ -207,93 +142,8 @@ in
|
|||||||
hide-on-clear = true; #< hide control center when clicking "clear all"
|
hide-on-clear = true; #< hide control center when clicking "clear all"
|
||||||
hide-on-action = true;
|
hide-on-action = true;
|
||||||
script-fail-notify = true;
|
script-fail-notify = true;
|
||||||
scripts = {
|
scripts = import ./scripts.nix {
|
||||||
# a script can match regex on these fields. only fired if all listed fields match:
|
inherit pkgs;
|
||||||
# - app-name
|
|
||||||
# - desktop-entry
|
|
||||||
# - summary
|
|
||||||
# - body
|
|
||||||
# - urgency (Low/Normal/Critical)
|
|
||||||
# - category
|
|
||||||
# additionally, the script can be run either on receipt or action:
|
|
||||||
# - run-on = "receive" or "action"
|
|
||||||
# when script is run, these env vars are available:
|
|
||||||
# - SWAYNC_BODY
|
|
||||||
# - SWAYNC_DESKTOP_ENTRY
|
|
||||||
# - SWAYNC_URGENCY
|
|
||||||
# - SWAYNC_TIME
|
|
||||||
# - SWAYNC_APP_NAME
|
|
||||||
# - SWAYNC_CATEGORY
|
|
||||||
# - SWAYNC_REPLACES_ID
|
|
||||||
# - SWAYNC_ID
|
|
||||||
# - SWAYNC_SUMMARY
|
|
||||||
|
|
||||||
# rules to use for testing. trigger with:
|
|
||||||
# - `notify-send test test:message` (etc)
|
|
||||||
# should also be possible to trigger via any messaging app
|
|
||||||
fbcli-test-im = {
|
|
||||||
body = "test:message";
|
|
||||||
exec = "${fbcli} --event proxied-message-new-instant";
|
|
||||||
};
|
|
||||||
fbcli-test-call = {
|
|
||||||
body = "test:call";
|
|
||||||
exec = "${fbcli} --event phone-incoming-call -t 20";
|
|
||||||
};
|
|
||||||
fbcli-test-call-stop = {
|
|
||||||
body = "test:call-stop";
|
|
||||||
exec = "${fbcli-stop} --event phone-incoming-call -t 20";
|
|
||||||
};
|
|
||||||
fbcli-test-timer = {
|
|
||||||
body = "test:timer";
|
|
||||||
exec = "${fbcli} --event timeout-completed";
|
|
||||||
};
|
|
||||||
|
|
||||||
incoming-im-known-app-name = {
|
|
||||||
# trigger notification sound on behalf of these IM clients.
|
|
||||||
app-name = "(Chats|Dino|discord|dissent|Element|Fractal)";
|
|
||||||
body = "^(?!Incoming call).*$"; #< don't match Dino Incoming calls
|
|
||||||
exec = "${fbcli} --event proxied-message-new-instant";
|
|
||||||
};
|
|
||||||
incoming-im-known-desktop-entry = {
|
|
||||||
# trigger notification sound on behalf of these IM clients.
|
|
||||||
# these clients don't have an app-name (listed as "<unknown>"), but do have a desktop-entry
|
|
||||||
desktop-entry = "com.github.uowuo.abaddon";
|
|
||||||
exec = "${fbcli} --event proxied-message-new-instant";
|
|
||||||
};
|
|
||||||
incoming-call = {
|
|
||||||
app-name = "Dino";
|
|
||||||
body = "^Incoming call$";
|
|
||||||
exec = "${fbcli} --event phone-incoming-call -t 20";
|
|
||||||
};
|
|
||||||
incoming-call-acted-on = {
|
|
||||||
# when the notification is clicked, stop sounding the ringer
|
|
||||||
app-name = "Dino";
|
|
||||||
body = "^Incoming call$";
|
|
||||||
run-on = "action";
|
|
||||||
exec = "${fbcli-stop} --event phone-incoming-call -t 20";
|
|
||||||
};
|
|
||||||
timer-done = {
|
|
||||||
# sxmo_timer.sh fires off notifications like "Done with 10m" when a 10minute timer completes.
|
|
||||||
# it sends such a notification every second until dismissed
|
|
||||||
app-name = "notify-send";
|
|
||||||
summary = "^Done with .*$";
|
|
||||||
# XXX: could use alarm-clock-elapsed, but that's got a duration > 1s
|
|
||||||
# which isn't great for sxmo's 1s repeat.
|
|
||||||
# TODO: maybe better to have sxmo only notify once, and handle this like with Dino's incoming call
|
|
||||||
exec = "${fbcli} --event timeout-completed";
|
|
||||||
};
|
|
||||||
timer-done-acted-on = {
|
|
||||||
# when the notification is clicked, kill whichever sxmo process is sending it
|
|
||||||
app-name = "notify-send";
|
|
||||||
summary = "^Done with .*$";
|
|
||||||
run-on = "action";
|
|
||||||
# process tree looks like:
|
|
||||||
# - foot -T <...> /nix/store/.../sh /nix/store/.../.sxmo_timer.sh-wrapped timerrun <duration>
|
|
||||||
# - /nix/store/.../sh /nix/store/.../.sxmo_timer.sh-wrapped timerrun duration
|
|
||||||
# we want to match exactly one of those, reliably.
|
|
||||||
# foot might not be foot, but alacritty, kitty, or any other terminal.
|
|
||||||
exec = "${kill-singleton} ^[^ ]* ?[^ ]*sxmo_timer.sh(-wrapped)? timerrun";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
notification-visibility = {
|
notification-visibility = {
|
||||||
# match incoming notifications and decide if they should be visible.
|
# match incoming notifications and decide if they should be visible.
|
||||||
|
114
hosts/common/programs/swaynotificationcenter/scripts.nix
Normal file
114
hosts/common/programs/swaynotificationcenter/scripts.nix
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
# this file defines the `scripts` entry within ~/.config/swaync/config.json.
|
||||||
|
# it describes special things to do in response to specific notifications,
|
||||||
|
# e.g. sound a ringer when we get a call, ...
|
||||||
|
{ pkgs }:
|
||||||
|
let
|
||||||
|
fbcli-wrapper = pkgs.writeShellApplication {
|
||||||
|
name = "swaync-fbcli";
|
||||||
|
runtimeInputs = [
|
||||||
|
pkgs.feedbackd
|
||||||
|
pkgs.procps # for pkill
|
||||||
|
pkgs.swaynotificationcenter
|
||||||
|
];
|
||||||
|
text = ''
|
||||||
|
# if in Do Not Disturb, don't do any feedback
|
||||||
|
# TODO: better solution is to actually make use of feedbackd profiles.
|
||||||
|
# i.e. set profile to `quiet` when in DnD mode
|
||||||
|
if [ "$SWAYNC_URGENCY" != "Critical" ] && [ "$(swaync-client --get-dnd)" = "true" ]; then
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# kill children if killed, to allow that killing this parent process will end the real fbcli call
|
||||||
|
cleanup() {
|
||||||
|
echo "aborting fbcli notification (PID $child)"
|
||||||
|
pkill -P "$child"
|
||||||
|
exit 0 # exit cleanly to avoid swaync alerting a script failure
|
||||||
|
}
|
||||||
|
trap cleanup SIGINT SIGQUIT SIGTERM
|
||||||
|
|
||||||
|
# feedbackd stops playback when the caller exits
|
||||||
|
# and fbcli will exit immediately if it has no stdin.
|
||||||
|
# so spoof a stdin:
|
||||||
|
/bin/sh -c "true | fbcli $*" &
|
||||||
|
child=$!
|
||||||
|
wait
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
fbcli = "${fbcli-wrapper}/bin/swaync-fbcli";
|
||||||
|
|
||||||
|
# we do this because swaync's exec naively splits the command on space to produce its argv, rather than parsing the shell.
|
||||||
|
# [ "pkill" "-f" "fbcli" "--event" ... ] -> breaks pkill
|
||||||
|
# [ "pkill" "-f" "fbcli --event ..." ] -> is what we want
|
||||||
|
fbcli-stop-wrapper = pkgs.writeShellApplication {
|
||||||
|
name = "fbcli-stop";
|
||||||
|
runtimeInputs = [
|
||||||
|
pkgs.procps # for pkill
|
||||||
|
];
|
||||||
|
text = ''
|
||||||
|
pkill -e -f "${fbcli} $*"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
fbcli-stop = "${fbcli-stop-wrapper}/bin/fbcli-stop";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# a script can match regex on these fields. only fired if all listed fields match:
|
||||||
|
# - app-name
|
||||||
|
# - desktop-entry
|
||||||
|
# - summary
|
||||||
|
# - body
|
||||||
|
# - urgency (Low/Normal/Critical)
|
||||||
|
# - category
|
||||||
|
# additionally, the script can be run either on receipt or action:
|
||||||
|
# - run-on = "receive" or "action"
|
||||||
|
# when script is run, these env vars are available:
|
||||||
|
# - SWAYNC_BODY
|
||||||
|
# - SWAYNC_DESKTOP_ENTRY
|
||||||
|
# - SWAYNC_URGENCY
|
||||||
|
# - SWAYNC_TIME
|
||||||
|
# - SWAYNC_APP_NAME
|
||||||
|
# - SWAYNC_CATEGORY
|
||||||
|
# - SWAYNC_REPLACES_ID
|
||||||
|
# - SWAYNC_ID
|
||||||
|
# - SWAYNC_SUMMARY
|
||||||
|
|
||||||
|
# rules to use for testing. trigger with:
|
||||||
|
# - `notify-send test test:message` (etc)
|
||||||
|
# should also be possible to trigger via any messaging app
|
||||||
|
fbcli-test-im = {
|
||||||
|
body = "test:message";
|
||||||
|
exec = "${fbcli} --event proxied-message-new-instant";
|
||||||
|
};
|
||||||
|
fbcli-test-call = {
|
||||||
|
body = "test:call";
|
||||||
|
exec = "${fbcli} --event phone-incoming-call -t 20";
|
||||||
|
};
|
||||||
|
fbcli-test-call-stop = {
|
||||||
|
body = "test:call-stop";
|
||||||
|
exec = "${fbcli-stop} --event phone-incoming-call -t 20";
|
||||||
|
};
|
||||||
|
|
||||||
|
incoming-im-known-app-name = {
|
||||||
|
# trigger notification sound on behalf of these IM clients.
|
||||||
|
app-name = "(Chats|Dino|discord|dissent|Element|Fractal)";
|
||||||
|
body = "^(?!Incoming call).*$"; #< don't match Dino Incoming calls
|
||||||
|
exec = "${fbcli} --event proxied-message-new-instant";
|
||||||
|
};
|
||||||
|
incoming-im-known-desktop-entry = {
|
||||||
|
# trigger notification sound on behalf of these IM clients.
|
||||||
|
# these clients don't have an app-name (listed as "<unknown>"), but do have a desktop-entry
|
||||||
|
desktop-entry = "com.github.uowuo.abaddon";
|
||||||
|
exec = "${fbcli} --event proxied-message-new-instant";
|
||||||
|
};
|
||||||
|
incoming-call = {
|
||||||
|
app-name = "Dino";
|
||||||
|
body = "^Incoming call$";
|
||||||
|
exec = "${fbcli} --event phone-incoming-call -t 20";
|
||||||
|
};
|
||||||
|
incoming-call-acted-on = {
|
||||||
|
# when the notification is clicked, stop sounding the ringer
|
||||||
|
app-name = "Dino";
|
||||||
|
body = "^Incoming call$";
|
||||||
|
run-on = "action";
|
||||||
|
exec = "${fbcli-stop} --event phone-incoming-call -t 20";
|
||||||
|
};
|
||||||
|
}
|
Reference in New Issue
Block a user