Say an update is running before it starts, not only after

Asked what happens if someone shuts the laptop down mid-update, the honest
answer turned out to be poor. The inhibitor does stop them - logind refuses and
falls back to org.freedesktop.login1.power-off-ignore-inhibit, which is
auth_admin_keep - so the desktop answers with an administrator password prompt
reading "Power off the system while an application is inhibiting this". systemd
ships that string untranslated, it never mentions updates, and no KDE catalog
contains any shutdown-blocked text at all. Only systemctl names the reason.

So a notification now goes out before the transaction, asking for the machine to
be left on. Notifications gained a tag: the result replaces the start message in
place rather than stacking a second, contradictory bubble beside it.

Tagged notifications also carry a queue flag. "An update is starting" is only
meaningful while somebody is looking, so unlike the result it is not spooled for
delivery at next login.
This commit is contained in:
Felitendo committed 2026-08-08 15:48:55 +02:00
1 parent 0f91a79ba6
commit 2eff62f9fd
10 files changed
+94 -11

No files matched your search

+1
View File
@@ -98,6 +98,7 @@ cau_config_load() {
CFG_RESOLVE_CONFLICTS=no; cau_config_bool AutoResolveConflicts yes && CFG_RESOLVE_CONFLICTS=yes
CFG_CLEAN_CACHE=no; cau_config_bool CleanCache yes && CFG_CLEAN_CACHE=yes
CFG_REMOVE_ORPHANS=no; cau_config_bool RemoveOrphans no && CFG_REMOVE_ORPHANS=yes
CFG_NOTIFY_START=no; cau_config_bool NotifyOnStart yes && CFG_NOTIFY_START=yes
CFG_NOTIFY_SUCCESS=no; cau_config_bool NotifyOnSuccess yes && CFG_NOTIFY_SUCCESS=yes
CFG_NOTIFY_ERROR=no; cau_config_bool NotifyOnError yes && CFG_NOTIFY_ERROR=yes
CFG_NOTIFY_REBOOT=no; cau_config_bool NotifyReboot yes && CFG_NOTIFY_REBOOT=yes
+29 -5
View File
@@ -19,10 +19,23 @@ CAU_NOTIFY_QUEUE_MAX=20
# Never fails: a machine without libnotify, or with nobody logged in, is a
# normal state, not an error.
cau_notify() {
local urgency="$1" title="$2" body="$3"
shift 3
cau_notify_tagged '' yes "$@"
}
# cau_notify_tagged <tag> <queue: yes|no> <urgency> <title> <body> [args...]
#
# A tag makes this notification replace the previous one carrying the same tag
# rather than stacking a second bubble beside it - that is what turns
# "installing updates" into "system updated" in place instead of leaving two
# messages that contradict each other.
#
# queue=no is for messages that only mean anything while somebody is looking.
# Telling a user at next login that an update started an hour ago is noise.
cau_notify_tagged() {
local tag="$1" queue="$2" urgency="$3" title="$4" body="$5"
shift 5
local -a args=("$@")
local delivered=0 user uid locale t b
local delivered=0 user uid locale t b prev newid
[[ $CFG_NOTIFICATIONS == yes ]] || return 0
@@ -34,17 +47,28 @@ cau_notify() {
t="$(cau_msg_in "$locale" "$title")"
b="$(cau_msg_in "$locale" "$body" "${args[@]}")"
if cau_as_user "$user" "$uid" notify-send \
prev=0
if [[ -n $tag ]]; then
prev="$(cau_state_read "notify_id_${tag}_${user}" 0)"
[[ $prev =~ ^[0-9]+$ ]] || prev=0
fi
if newid="$(cau_as_user "$user" "$uid" notify-send \
--app-name="$CAU_PRETTY" \
--icon="$CAU_NOTIFY_ICON" \
--urgency="$urgency" \
-- "$t" "$b" 2>/dev/null
--print-id --replace-id="$prev" \
-- "$t" "$b" 2>/dev/null)"
then
delivered=1
if [[ -n $tag && $newid =~ ^[0-9]+$ ]]; then
cau_state_write "notify_id_${tag}_${user}" "$newid"
fi
fi
done < <(cau_active_session_users)
(( delivered )) && return 0
[[ $queue == yes ]] || return 0
cau_notify_enqueue "$urgency" "$title" "$body" "${args[@]}"
}
+14
View File
@@ -133,6 +133,20 @@ cau_pacman_update() {
cau_info "Running a full system upgrade (pending list unavailable)"
fi
# Say so before the transaction starts, not after it finishes.
#
# While an upgrade runs, a shutdown request is refused by logind and the
# desktop answers with a polkit password prompt reading "Power off the
# system while an application is inhibiting this" - which never mentions
# updates and, on a German system, is not even translated. Somebody who was
# simply told beforehand does not end up staring at that.
if [[ $CFG_NOTIFY_START == yes ]]; then
cau_notify_tagged run no normal \
"Installing updates" \
"%d packages are being updated. Please leave the computer switched on until this is done." \
"${CAU_PACMAN_COUNT:-0}"
fi
mapfile -t flags < <(cau_pacman_flags)
log="$(mktemp)" || return 1