Keep clicking a notification working after a shell restart (#6636)

* Keep clicking a notification working after a shell restart

Notification actions lived only in the sending process: `-a` appended
`-A default=default`, so notify-send blocked on a D-Bus ActionInvoked signal and
the caller ran the command when it arrived. Nothing about that reached disk, so a
restored popup had no action to run and its sender stayed blocked forever.

Replace `-a` with `--exec <command>`, carried as an `omarchy-exec` hint into the
snapshot's `exec` role. It travels through the popup files and history, and the
shell runs it on click, so restored toasts behave exactly like live ones and the
sender exits immediately.

That drops the scaffolding whose only job was keeping a blocked sender alive: the
first-run invitations lose their `--show` re-entry and two transient units each,
omarchy-migrate-notify loses its transient service, and the screenshot,
recording, download, and taildrop toasts lose their wrapper subshells.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Keep a failed toast from failing the work it announces

Moving these sends out of their backgrounded subshells put a fallible command
on the foreground path, where the `&` used to swallow its exit status. A
notification outage — including the shell restart this branch targets — now
propagates:

- taildrop's receiver dies under `set -e` mid-delivery
- omarchy-capture-screenshot reports failure for a screenshot it already saved
- a completed download exits before scheduling its thumbnail cleanup, leaking
  the mktemp file

Announcing is best-effort in all three: the work is already done by the time
the toast goes out.

Also drop the first-run sleep that spaced out the welcome and Wi-Fi toasts.
It compensated for the background notify-send processes this branch removes;
each send now returns only once the server has taken the toast, so sending in
order is enough to stack them newest-on-top.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Stop tying the preview cleanup to the toast's expiry

The shell loads a notification thumbnail into memory when the toast appears and
never re-reads the file, so the preview only has to outlive that load. Deriving
the cleanup delay from the expiry was false precision, and it turned -t into a
variable for no reason: -t is already the helper's expiry setting.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
David Heinemeier Hansson
2026-08-09 12:30:47 +02:00
committed by GitHub
co-authored by Claude Opus 5
parent 99293aa05a
commit 5a58f79876
19 changed files with 220 additions and 226 deletions
+4 -22
View File
@@ -2,26 +2,8 @@
set -e
show_invitation() {
if [[ -n $(omarchy-notification-send -u critical -g  "Install Dictation with Voxtype" "Click to install voice dictation for Omarchy." -a) ]]; then
# Launch the installer in its own transient unit so this invitation service
# can exit right after the click. If it stayed alive for the life of the
# install terminal, the installer's omarchy-restart-shell would re-trigger
# this still-running *-invitation unit and pop the toast a second time.
# KillMode=process because the launcher's setsid forks and returns, so the
# unit's main process exits within milliseconds. The default control-group
# kill would take the terminal down with it before it ever appears.
systemd-run --user --collect --quiet -p KillMode=process \
--unit=omarchy-voxtype-install \
omarchy-launch-floating-terminal-with-presentation omarchy-voxtype-install
fi
}
if [[ ${1:-} == "--show" ]]; then
show_invitation
elif omarchy-done ensure voxtype-install-invitation; then
# Keep the notification action alive after the update terminal closes.
systemd-run --user --collect --quiet --service-type=exec \
--unit=omarchy-voxtype-install-invitation \
bash "$0" --show
if omarchy-done ensure voxtype-install-invitation; then
omarchy-notification-send -u critical -g  "Install Dictation with Voxtype" \
"Click to install voice dictation for Omarchy." \
--exec "omarchy-launch-floating-terminal-with-presentation omarchy-voxtype-install"
fi
+4 -22
View File
@@ -2,29 +2,11 @@
set -e
show_invitation() {
if [[ -n $(omarchy-notification-send -u critical -g 󰈷 "Setup Fingerprint Reader" "Enable sudo and unlocking with your fingerprint." -a) ]]; then
# Launch the setup in its own transient unit so this invitation service can
# exit right after the click. If it stayed alive for the life of the setup
# terminal, the setup's omarchy-restart-shell would re-trigger this
# still-running *-invitation unit and pop the toast a second time.
# KillMode=process because the launcher's setsid forks and returns, so the
# unit's main process exits within milliseconds. The default control-group
# kill would take the terminal down with it before it ever appears.
systemd-run --user --collect --quiet -p KillMode=process \
--unit=omarchy-setup-security-fingerprint \
omarchy-launch-floating-terminal-with-presentation omarchy-setup-security-fingerprint
fi
}
if [[ ${1:-} == "--show" ]]; then
show_invitation
# Only invite when there's a reader to use and it isn't set up yet (the lock
# PAM file is the last thing the setup writes on success).
elif omarchy-hw-fingerprint && [[ ! -f /etc/pam.d/omarchy-lock-fingerprint ]] &&
if omarchy-hw-fingerprint && [[ ! -f /etc/pam.d/omarchy-lock-fingerprint ]] &&
omarchy-done ensure fingerprint-setup-invitation; then
# Keep the notification action alive after the update terminal closes.
systemd-run --user --collect --quiet --service-type=exec \
--unit=omarchy-fingerprint-setup-invitation \
bash "$0" --show
omarchy-notification-send -u critical -g 󰈷 "Setup Fingerprint Reader" \
"Enable sudo and unlocking with your fingerprint." \
--exec "omarchy-launch-floating-terminal-with-presentation omarchy-setup-security-fingerprint"
fi
+3 -5
View File
@@ -1,5 +1,3 @@
(
if [[ -n $(omarchy-notification-send -u critical -g  "Learn Keybindings" "Super + K for cheatsheet.\nSuper + Space for application launcher.\nSuper + Alt + Space for Omarchy Menu." -a) ]]; then
omarchy-menu-keybindings
fi
) >/dev/null 2>&1 &
omarchy-notification-send -u critical -g  "Learn Keybindings" \
"Super + K for cheatsheet.\nSuper + Space for application launcher.\nSuper + Alt + Space for Omarchy Menu." \
--exec omarchy-menu-keybindings
+5 -14
View File
@@ -1,25 +1,16 @@
notify_update() {
(
if [[ -n $(omarchy-notification-send -u critical -g  "Update System" "$1" -a) ]]; then
omarchy-launch-floating-terminal-with-presentation omarchy-update
fi
) >/dev/null 2>&1 &
omarchy-notification-send -u critical -g  "Update System" "$1" \
--exec "omarchy-launch-floating-terminal-with-presentation omarchy-update"
}
notify_wifi() {
(
if [[ -n $(omarchy-notification-send -u critical -g 󰖩 "Setup Wi-Fi" "Click to configure the wireless network." -a) ]]; then
omarchy-shell shell toggle omarchy.network
fi
) >/dev/null 2>&1 &
omarchy-notification-send -u critical -g 󰖩 "Setup Wi-Fi" "Click to configure the wireless network." \
--exec "omarchy-shell shell toggle omarchy.network"
}
if ! ping -c3 -W1 1.1.1.1 >/dev/null 2>&1; then
# Newest stacks on top, and Wi-Fi is what you need first, so send it last.
notify_update "When you have internet, click to update the system."
# Both toasts are sent from background subshells, so let the update one
# register before queueing Wi-Fi. Newest stacks on top, and Wi-Fi is what
# you need first.
sleep 0.3
notify_wifi
else
notify_update "Click to update the system."