swaync-fbcli: fix CPU pegging when canceling a phone ringer

This commit is contained in:
2024-04-16 02:18:35 +00:00
parent 6b5e0e57bc
commit 259c3af526
3 changed files with 52 additions and 16 deletions

View File

@@ -41,6 +41,7 @@ in
"feedbackd" "feedbackd"
"procps" "procps"
"swaynotificationcenter" "swaynotificationcenter"
"util-linux"
]; ];
}; };
}; };
@@ -62,7 +63,15 @@ in
}; };
# prevent dbus from automatically activating swaync so i can manage it as a systemd service instead # 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 = [ suggestedPrograms = [
"feedbackd" "feedbackd"
"swaync-fbcli" #< used to sound ringer "swaync-fbcli" #< used to sound ringer

View File

@@ -24,14 +24,14 @@
# - SWAYNC_SUMMARY # - SWAYNC_SUMMARY
# rules to use for testing. trigger with: # 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 # should also be possible to trigger via any messaging app
fbcli-test-im = { fbcli-test-im = {
body = "test:message"; body = "test:message";
exec = "swaync-fbcli start proxied-message-new-instant"; exec = "swaync-fbcli start proxied-message-new-instant";
}; };
fbcli-test-call = { fbcli-test-call = {
body = "test:call"; body = "test:call-start";
exec = "swaync-fbcli start phone-incoming-call"; exec = "swaync-fbcli start phone-incoming-call";
}; };
fbcli-test-call-stop = { fbcli-test-call-stop = {

View File

@@ -1,5 +1,9 @@
#!/usr/bin/env nix-shell #!/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" action="$1"
event="$2" event="$2"
@@ -7,16 +11,26 @@ event="$2"
log() { log() {
if [ -n "$SWAYNC_DEBUG" ]; then if [ -n "$SWAYNC_DEBUG" ]; then
printf "%s\n" "$1" printf "%s\n" "$1" >&2
fi fi
} }
child= # child=
# kill children if killed, to allow that killing this parent process will end the real fbcli call # kill children if killed, to allow that killing this parent process will end the real fbcli call
cleanup() { cleanup() {
log "aborting fbcli notification (PID $child)" log "aborting fbcli notification"
pkill -P "$child" # "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 exit 0 # exit cleanly to avoid swaync alerting a script failure
} }
@@ -35,38 +49,51 @@ startInline() {
fbcliArgs+=(-t "$timeout") fbcliArgs+=(-t "$timeout")
fi fi
trap cleanup SIGINT SIGQUIT SIGTERM
# feedbackd stops playback when the caller exits # feedbackd stops playback when the caller exits
# and fbcli will exit immediately if it has no stdin. # and fbcli will exit immediately if it has no stdin.
# so spoof a stdin. # so spoof a stdin.
log "${fbcliArgs[*]}" log "${fbcliArgs[*]}"
sleep $((3 + ${timeout:+ + $timeout})) | ${fbcliArgs[@]} bash -c "sleep $((3 + ${timeout:+ + $timeout})) | ${fbcliArgs[*]}" &
# child=$!
wait
} }
start() { start() {
# if in Do Not Disturb, don't do any feedback # if in Do Not Disturb, don't do any feedback
# TODO: better solution is to actually make use of feedbackd profiles. # TODO: better solution is to actually make use of feedbackd profiles.
# i.e. set profile to `quiet` when in DnD mode # 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 exit
fi fi
trap cleanup SIGINT SIGQUIT SIGTERM # startInline &
log "$0 start-inline $event"
startInline & # 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=$! child=$!
wait wait
} }
stop() { 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 case "$action" in
start) start)
start start
;; ;;
startInline) start-stage-1)
startInline # support this for debugging # setsid -f -w "$0" start-stage-2 "$event"
"$0" start-stage-2 "$event"
;;
start-stage-2)
startInline
;; ;;
stop) stop)
stop stop