#!/usr/bin/env nix-shell #!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" log() { if [ -n "$SWAYNC_DEBUG" ]; then printf "%s\n" "$1" >&2 fi } # kill children if killed, to allow that killing this parent process will end the real fbcli call cleanup() { 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 exit 0 # exit cleanly to avoid swaync alerting a script failure } startInline() { local timeout= case "$event" in phone-incoming-call) timeout=20 ;; *) ;; esac fbcliArgs=(fbcli --event "$event") if [ -n "$timeout" ]; then 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 # and do so asynchronously so that we don't block our signal handler. log "${fbcliArgs[*]}" # bash -c "sleep $((3 + ${timeout:+ + $timeout})) | ${fbcliArgs[*]}" & # (sleep $((3 + ${timeout:+ + $timeout})) | ${fbcliArgs[*]}) & sleep $((3 + ${timeout:+ + $timeout})) | ${fbcliArgs[*]} & 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 --skip-wait)" = "true" ]; then log "DND: skipping" exit fi log "$0 start-inline $event" # XXX(2024/04/15): don't pass stdin/stdout/stderr, else swaync is liable to get confused and peg CPU to 100% setsid -f "$0" start-inline "$event" > /dev/null 2> /dev/null < /dev/null || true } stop() { pkill --echo --full "swaync-fbcli(-wrapped)? start-inline $event" || true } case "$action" in start) start ;; start-inline) startInline # used internally by the `start` action ;; stop) stop ;; esac