feat(hyprdrive,hyprlua): notification action buttons for timer/screenrec
timer-run now offers Dismiss/Snooze 2m/Snooze 5m buttons via notify-send -A (beacon/mnotifd both implement the freedesktop Actions spec) and rings the alarm on a loop until the notification resolves, instead of playing once and going silent. screenrec.sh gets a real "Stop Recording" button in the same vein, replacing a broken anonymous --action= and a `$nid=` assignment bug that never actually captured the notification id; also fixes hyprlua's stale `dunstctl close` call left over from the mnotifd migration (dunst is no longer running). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>main
parent
9640e09677
commit
008e4d980c
|
|
@ -1,5 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
# screenrec.sh — toggle screen recording via wf-recorder.
|
||||
# Press the bound key once to start (region picked via slurp): a
|
||||
# "Stop Recording" button appears on the notification and the script blocks
|
||||
# on it. Either clicking that button, or pressing the same keybind again,
|
||||
# ends the recording.
|
||||
|
||||
endrec () {
|
||||
killall -s SIGINT wf-recorder
|
||||
|
|
@ -14,16 +18,22 @@ endrec () {
|
|||
mkdir -p ~/Videos
|
||||
statecon=$( pidof wf-recorder )
|
||||
|
||||
|
||||
outfile="$HOME/Videos/$(date +'%Y%m%d%H%M%S').mp4"
|
||||
#$outfile
|
||||
nid=""
|
||||
if [ "$statecon" == '' ]; then
|
||||
wf-recorder -g "$(slurp)" -f $outfile &
|
||||
$nid=$(notify-send -p -u critical -t 0 "recording started" --action="goto endrecplace"
|
||||
)
|
||||
|
||||
if [ -z "$statecon" ]; then
|
||||
wf-recorder -g "$(slurp)" -f "$outfile" &
|
||||
|
||||
# --id-fd keeps the notification id off stdout so -A's chosen action
|
||||
# (the only thing we read back) isn't mixed in with it.
|
||||
nidfile=$(mktemp)
|
||||
action=$(notify-send -u critical -t 0 --id-fd=3 \
|
||||
-A "stop=Stop Recording" \
|
||||
"recording started" "output: $outfile" 3>"$nidfile")
|
||||
nid=$(<"$nidfile")
|
||||
rm -f "$nidfile"
|
||||
|
||||
[ "$action" == "stop" ] && endrec
|
||||
else
|
||||
endrec
|
||||
fi
|
||||
|
||||
pidof wf-recorder && endrec
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
#!/usr/bin/env bash
|
||||
# timer-run <total_seconds> [label]
|
||||
# Runs entirely in background. No terminal needed after launch.
|
||||
# Sends a dunst notification + audio beep when done.
|
||||
# Sends a desktop notification (with Dismiss / Snooze 2m / Snooze 5m action
|
||||
# buttons, via beacon) + audio beep when done.
|
||||
#
|
||||
# Install: ~/.config/scripts/timer-run (companion: timer-pick in same dir)
|
||||
|
||||
|
|
@ -60,20 +61,41 @@ if [[ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ]]; then
|
|||
done
|
||||
fi
|
||||
|
||||
if command -v notify-send &>/dev/null; then
|
||||
notify-send \
|
||||
--urgency=critical \
|
||||
--expire-time=0 \
|
||||
--icon=alarm-timer \
|
||||
"$NOTIF_SUMMARY" \
|
||||
"$NOTIF_BODY"
|
||||
fi
|
||||
|
||||
# ── audio alert ───────────────────────────────────────────────────────────────
|
||||
# ── audio alert (rings on a loop until dismissed/snoozed) ─────────────────────
|
||||
_ALARM_SOUND="/usr/share/sounds/freedesktop/stereo/alarm-clock-elapsed.oga"
|
||||
|
||||
play_alarm() {
|
||||
if command -v paplay &>/dev/null && [[ -f "$_ALARM_SOUND" ]]; then
|
||||
paplay "$_ALARM_SOUND" 2>/dev/null
|
||||
elif command -v canberra-gtk-play &>/dev/null; then
|
||||
canberra-gtk-play --id=alarm-clock-elapsed 2>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
( while true; do play_alarm; sleep 1; done ) &
|
||||
RING_PID=$!
|
||||
|
||||
# ── notification with action buttons ──────────────────────────────────────────
|
||||
# -A implies --wait: notify-send blocks until the card is closed or an action
|
||||
# is invoked, printing the chosen action's id to stdout. beacon supports the
|
||||
# spec's Actions/ActionInvoked, so this works without any custom hint.
|
||||
ACTION=""
|
||||
if command -v notify-send &>/dev/null; then
|
||||
ACTION=$(notify-send \
|
||||
--urgency=critical \
|
||||
--expire-time=0 \
|
||||
--icon=alarm-timer \
|
||||
-A "dismiss=Dismiss" \
|
||||
-A "snooze2=Snooze 2m" \
|
||||
-A "snooze5=Snooze 5m" \
|
||||
"$NOTIF_SUMMARY" \
|
||||
"$NOTIF_BODY")
|
||||
fi
|
||||
|
||||
kill "$RING_PID" 2>/dev/null
|
||||
wait "$RING_PID" 2>/dev/null
|
||||
|
||||
case "$ACTION" in
|
||||
snooze2) exec bash "$0" 120 "$LABEL" ;;
|
||||
snooze5) exec bash "$0" 300 "$LABEL" ;;
|
||||
esac
|
||||
|
|
|
|||
|
|
@ -1,25 +1,39 @@
|
|||
#!/bin/bash
|
||||
|
||||
# screenrec.sh — toggle screen recording via wf-recorder.
|
||||
# Press the bound key once to start (region picked via slurp): a
|
||||
# "Stop Recording" button appears on the notification and the script blocks
|
||||
# on it. Either clicking that button, or pressing the same keybind again,
|
||||
# ends the recording.
|
||||
|
||||
endrec () {
|
||||
killall -s SIGINT wf-recorder
|
||||
dunstctl close $nid
|
||||
# mnotifd (the notif daemon) has no dunstctl; close the "recording started"
|
||||
# card via the freedesktop CloseNotification method instead.
|
||||
[ -n "$nid" ] && gdbus call --session --dest org.freedesktop.Notifications \
|
||||
--object-path /org/freedesktop/Notifications \
|
||||
--method org.freedesktop.Notifications.CloseNotification "$nid" >/dev/null 2>&1
|
||||
notify-send "recording ended - output to $outfile"
|
||||
}
|
||||
|
||||
mkdir -p ~/Videos
|
||||
statecon=$( pidof wf-recorder )
|
||||
|
||||
|
||||
outfile="$HOME/Videos/$(date +'%Y%m%d%H%M%S').mp4"
|
||||
#$outfile
|
||||
nid=""
|
||||
if [ "$statecon" == '' ]; then
|
||||
wf-recorder -g "$(slurp)" -f $outfile &
|
||||
$nid=$(notify-send -p -u critical -t 0 "recording started" --action="goto endrecplace"
|
||||
)
|
||||
|
||||
if [ -z "$statecon" ]; then
|
||||
wf-recorder -g "$(slurp)" -f "$outfile" &
|
||||
|
||||
# --id-fd keeps the notification id off stdout so -A's chosen action
|
||||
# (the only thing we read back) isn't mixed in with it.
|
||||
nidfile=$(mktemp)
|
||||
action=$(notify-send -u critical -t 0 --id-fd=3 \
|
||||
-A "stop=Stop Recording" \
|
||||
"recording started" "output: $outfile" 3>"$nidfile")
|
||||
nid=$(<"$nidfile")
|
||||
rm -f "$nidfile"
|
||||
|
||||
[ "$action" == "stop" ] && endrec
|
||||
else
|
||||
endrec
|
||||
fi
|
||||
|
||||
pidof wf-recorder && endrec
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
#!/usr/bin/env bash
|
||||
# timer-run <total_seconds> [label]
|
||||
# Runs entirely in background. No terminal needed after launch.
|
||||
# Sends a dunst notification + audio beep when done.
|
||||
# Sends a desktop notification (with Dismiss / Snooze 2m / Snooze 5m action
|
||||
# buttons, via mnotifd) + audio beep when done.
|
||||
#
|
||||
# Install: ~/.config/scripts/timer-run (companion: timer-pick in same dir)
|
||||
|
||||
|
|
@ -42,13 +43,13 @@ DURATION_STR=$(fmt_dur "$TOTAL")
|
|||
NOTIF_SUMMARY="⏰ Timer done${LABEL:+ — $LABEL}"
|
||||
NOTIF_BODY="Set for ${DURATION_STR}. Finished at $(date '+%H:%M:%S')."
|
||||
|
||||
# ── dunst notification ────────────────────────────────────────────────────────
|
||||
# ── desktop notification ──────────────────────────────────────────────────────
|
||||
# notify-send needs DBUS_SESSION_BUS_ADDRESS. If not in env, find it via the
|
||||
# running dunst process (reliable on single-user Wayland/Hyprland setups).
|
||||
# running mnotifd notif daemon (reliable on single-user Wayland/Hyprland setups).
|
||||
if [[ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ]]; then
|
||||
local_uid=$(id -u)
|
||||
# try to grab it from the environment of any process owned by this user
|
||||
for pid in $(pgrep -u "$local_uid" dunst 2>/dev/null); do
|
||||
for pid in $(pgrep -u "$local_uid" -f '[m]notifd/main.py' 2>/dev/null); do
|
||||
addr=$(cat /proc/$pid/environ 2>/dev/null \
|
||||
| tr '\0' '\n' \
|
||||
| grep '^DBUS_SESSION_BUS_ADDRESS=' \
|
||||
|
|
@ -60,20 +61,41 @@ if [[ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ]]; then
|
|||
done
|
||||
fi
|
||||
|
||||
if command -v notify-send &>/dev/null; then
|
||||
notify-send \
|
||||
--urgency=critical \
|
||||
--expire-time=0 \
|
||||
--icon=alarm-timer \
|
||||
"$NOTIF_SUMMARY" \
|
||||
"$NOTIF_BODY"
|
||||
fi
|
||||
|
||||
# ── audio alert ───────────────────────────────────────────────────────────────
|
||||
# ── audio alert (rings on a loop until dismissed/snoozed) ─────────────────────
|
||||
_ALARM_SOUND="/usr/share/sounds/freedesktop/stereo/alarm-clock-elapsed.oga"
|
||||
|
||||
play_alarm() {
|
||||
if command -v paplay &>/dev/null && [[ -f "$_ALARM_SOUND" ]]; then
|
||||
paplay "$_ALARM_SOUND" 2>/dev/null
|
||||
elif command -v canberra-gtk-play &>/dev/null; then
|
||||
canberra-gtk-play --id=alarm-clock-elapsed 2>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
( while true; do play_alarm; sleep 1; done ) &
|
||||
RING_PID=$!
|
||||
|
||||
# ── notification with action buttons ──────────────────────────────────────────
|
||||
# -A implies --wait: notify-send blocks until the card is closed or an action
|
||||
# is invoked, printing the chosen action's id to stdout. mnotifd supports the
|
||||
# spec's Actions/ActionInvoked, so this works without any custom hint.
|
||||
ACTION=""
|
||||
if command -v notify-send &>/dev/null; then
|
||||
ACTION=$(notify-send \
|
||||
--urgency=critical \
|
||||
--expire-time=0 \
|
||||
--icon=alarm-timer \
|
||||
-A "dismiss=Dismiss" \
|
||||
-A "snooze2=Snooze 2m" \
|
||||
-A "snooze5=Snooze 5m" \
|
||||
"$NOTIF_SUMMARY" \
|
||||
"$NOTIF_BODY")
|
||||
fi
|
||||
|
||||
kill "$RING_PID" 2>/dev/null
|
||||
wait "$RING_PID" 2>/dev/null
|
||||
|
||||
case "$ACTION" in
|
||||
snooze2) exec bash "$0" 120 "$LABEL" ;;
|
||||
snooze5) exec bash "$0" 300 "$LABEL" ;;
|
||||
esac
|
||||
|
|
|
|||
Loading…
Reference in New Issue