diff --git a/hosts/common/programs/swaynotificationcenter/default.nix b/hosts/common/programs/swaynotificationcenter/default.nix index 13ce816bd..369825346 100644 --- a/hosts/common/programs/swaynotificationcenter/default.nix +++ b/hosts/common/programs/swaynotificationcenter/default.nix @@ -41,6 +41,7 @@ in "feedbackd" "procps" "swaynotificationcenter" + "util-linux" ]; }; }; @@ -62,7 +63,15 @@ in }; # prevent dbus from automatically activating swaync so i can manage it as a systemd service instead - packageUnwrapped = pkgs.rmDbusServices pkgs.swaynotificationcenter; + packageUnwrapped = pkgs.rmDbusServices (pkgs.pkgsDebug.swaynotificationcenter.overrideAttrs (upstream: { + version = "0.10.1-unstable-2024-04-16"; + src = pkgs.fetchFromGitHub { + owner = "ErikReider"; + repo = "SwayNotificationCenter"; + rev = "8cb9be59708bb051616d7e14d9fa0b87b86985af"; + hash = "sha256-UAegyzqutGulp6H7KplEfwHV0MfFfOHgYNNu+AQHx3g="; + }; + })); suggestedPrograms = [ "feedbackd" "swaync-fbcli" #< used to sound ringer diff --git a/hosts/common/programs/swaynotificationcenter/scripts.nix b/hosts/common/programs/swaynotificationcenter/scripts.nix index ec74d3301..db2fa09c6 100644 --- a/hosts/common/programs/swaynotificationcenter/scripts.nix +++ b/hosts/common/programs/swaynotificationcenter/scripts.nix @@ -24,14 +24,14 @@ # - SWAYNC_SUMMARY # rules to use for testing. trigger with: - # - `notify-send test test:message` (etc) + # - `notify-send --app-id=foo subject body` (etc) # should also be possible to trigger via any messaging app fbcli-test-im = { body = "test:message"; exec = "swaync-fbcli start proxied-message-new-instant"; }; fbcli-test-call = { - body = "test:call"; + body = "test:call-start"; exec = "swaync-fbcli start phone-incoming-call"; }; fbcli-test-call-stop = { diff --git a/hosts/common/programs/swaynotificationcenter/swaync-fbcli b/hosts/common/programs/swaynotificationcenter/swaync-fbcli index daf35c371..09e7d13b9 100755 --- a/hosts/common/programs/swaynotificationcenter/swaync-fbcli +++ b/hosts/common/programs/swaynotificationcenter/swaync-fbcli @@ -1,5 +1,9 @@ #!/usr/bin/env nix-shell -#!nix-shell -i bash -p feedbackd -p procps -p swaynotificationcenter +#!nix-shell -i bash -p feedbackd -p procps -p swaynotificationcenter -p util-linux + +# this script does some really unusual indirection with the `start` action: +# IT'S INTENTIONAL. +# swaync is picky about how its scripts are terminated. not a great idea to directly signal them. action="$1" event="$2" @@ -7,16 +11,26 @@ event="$2" log() { if [ -n "$SWAYNC_DEBUG" ]; then - printf "%s\n" "$1" + printf "%s\n" "$1" >&2 fi } -child= +# child= # kill children if killed, to allow that killing this parent process will end the real fbcli call cleanup() { - log "aborting fbcli notification (PID $child)" - pkill -P "$child" + log "aborting fbcli notification" + # "trap -": to avoid recursing + trap - SIGINT SIGQUIT SIGTERM + # "kill 0" means kill the current process group (i.e. all descendants) + kill 0 + # pkill -g 0 + # if [ -n "$child" ]; then + # pkill -P "$child" + # kill "$child" + # else + # pkill -P $$ + # fi exit 0 # exit cleanly to avoid swaync alerting a script failure } @@ -35,38 +49,51 @@ startInline() { fbcliArgs+=(-t "$timeout") fi + 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. log "${fbcliArgs[*]}" - sleep $((3 + ${timeout:+ + $timeout})) | ${fbcliArgs[@]} + bash -c "sleep $((3 + ${timeout:+ + $timeout})) | ${fbcliArgs[*]}" & + # child=$! + wait } start() { # 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 + if [ "$SWAYNC_URGENCY" != "Critical" ] && [ "$(swaync-client --get-dnd --skip-wait)" = "true" ]; then + log "DND: skipping" exit fi - trap cleanup SIGINT SIGQUIT SIGTERM - - startInline & + # startInline & + log "$0 start-inline $event" + # setsid -f "$0" start-inline "$event" + # setsid -f -w "$0" start-stage-1 "$event" || true + setsid -f -w "$0" start-stage-1 "$event" > /dev/null 2> /dev/null < /dev/null & + # "$0" start-stage-1 "$event" & child=$! wait } stop() { - pkill --echo --signal SIGINT --full "swaync-fbcli(-wrapped)? start $event" + pkill --echo --full "swaync-fbcli(-wrapped)? start-stage-2 $event" || true } + case "$action" in start) start ;; - startInline) - startInline # support this for debugging + start-stage-1) + # setsid -f -w "$0" start-stage-2 "$event" + "$0" start-stage-2 "$event" + ;; + start-stage-2) + startInline ;; stop) stop