Make the second menu entry an action instead of a report

"Apply now" had nothing to do in the normal case. Enabling applies, the
watcher handles everything installed afterwards, and the settings and
applications screens apply on their way out - so pressing it answered
"already applied to 14 applications" and that was the whole interaction.

It is now "Re-apply everything": the state is taken back and written again
from scratch. That is the answer to the question the status block can raise
but nothing could act on - Steam showing as not patched after a client
update, an application that drifted, a flag file edited by hand.

Uninstalling an application used to leave the entry shadowing it behind, in
the user home where the package manager cannot see it, offering to start a
program that is gone. A plain apply only looks at what exists now, so the
watcher never noticed either. Those are removed on every apply now, not just
when rebuilding.
This commit is contained in:
Felitendo committed 2026-08-16 20:44:19 +02:00
1 parent 9896260636
commit 4004023297
9 files changed
+90 -20

No files matched your search

+2
View File
@@ -110,6 +110,8 @@ mca_apply() {
[[ $CFG_AUTOSTART == yes ]] && mca_autostart_apply
[[ $CFG_SPOTIFY == yes ]] && mca_spotify_apply
mca_prune_orphans
if (( MCA_CHANGES )) && mca_have update-desktop-database; then
update-desktop-database "$MCA_APPDIR" 2>/dev/null || true
fi
+10 -4
View File
@@ -495,7 +495,7 @@ mca_ui_menu() {
mca_ui_status
printf '\n'
printf ' [1] %s\n' "$(mca_msg "Turn autoscroll on or off")"
printf ' [2] %s\n' "$(mca_msg "Apply now")"
printf ' [2] %s\n' "$(mca_msg "Re-apply everything")"
printf ' [3] %s\n' "$(mca_msg "Applications")"
printf ' [4] %s\n' "$(mca_msg "Settings")"
printf ' [q] %s\n' "$(mca_msg "Quit")"
@@ -519,18 +519,24 @@ mca_ui_menu() {
fi
[[ -n $MCA_UI_NEEDS_ACK ]] && mca_pause
;;
# Not a plain apply: with the watcher running there is never
# anything left for one to do, and a menu entry that answers
# "already done" every time is not an action. This is the repair -
# everything is taken back and written again from scratch, which is
# what fixes an application that drifted, a flag file somebody
# edited, or Steam after it restored its own script.
2)
mca_ui_cooked mca_do_apply
mca_ui_cooked mca_do_apply --rebuild
mca_pause
;;
3)
if mca_ui_apps; then
[[ $CFG_ENABLED == yes ]] && mca_ui_cooked mca_do_apply --changed
[[ $CFG_ENABLED == yes ]] && mca_ui_cooked mca_do_apply --rebuild
fi
;;
4)
if mca_ui_settings; then
[[ $CFG_ENABLED == yes ]] && mca_ui_cooked mca_do_apply --changed
[[ $CFG_ENABLED == yes ]] && mca_ui_cooked mca_do_apply --rebuild
fi
;;
q|Q) mca_ui_term_restore; trap - EXIT INT TERM; return 0 ;;
+34
View File
@@ -418,6 +418,40 @@ mca_spotify_apply() {
return 0
}
# ---------------------------------------------------------------------------
# Leftovers
# ---------------------------------------------------------------------------
# mca_prune_orphans
# Removes generated entries whose application is gone.
#
# Uninstalling something deletes its entry from /usr/share/applications, but the
# copy shadowing it is in the user's home and pacman knows nothing about it. It
# would sit in the menu forever, offering to start a program that is no longer
# installed - and the watcher would not notice, because a plain apply only ever
# looks at what is there now.
mca_prune_orphans() {
local kind path source line
local -a lines=()
[[ -f $MCA_LEDGER ]] || return 0
mapfile -t lines < "$MCA_LEDGER"
for line in "${lines[@]}"; do
IFS=$'\t' read -r kind path source <<< "$line"
[[ $kind == shadow && -n $source ]] || continue
[[ -e $source ]] && continue
# Only ever remove something still recognisably ours.
if [[ -f $path ]] && grep -q "^$MCA_MARK_SHADOW=" "$path" 2>/dev/null; then
rm -f -- "$path"
MCA_CHANGES=$(( MCA_CHANGES + 1 ))
fi
mca_ledger_forget "$path"
done
return 0
}
# ---------------------------------------------------------------------------
# Undo
# ---------------------------------------------------------------------------
+16 -8
View File
@@ -76,11 +76,11 @@ mca_do_disable() {
}
mca_do_apply() {
local changed=0 arg
local rebuild=0 arg
for arg in "$@"; do
case "$arg" in
--changed) changed=1 ;;
--rebuild) rebuild=1 ;;
--quiet) MCA_QUIET=1 ;;
esac
done
@@ -95,17 +95,24 @@ mca_do_apply() {
return 1
fi
# A settings change can take an application out of scope as well as bring
# one in, and only a full undo can tell the difference, so that path starts
# from a clean slate. The watcher never does this: rewriting files that are
# already correct would make it trigger itself.
if (( changed )); then
# Start from a clean slate. Needed after a settings change, which can take
# an application out of scope as well as bring one in and where only a full
# undo can tell the difference, and it is what makes the repair a repair:
# whatever drifted is written again rather than left because it is "already
# applied".
#
# The watcher never does this. Rewriting files that are already correct
# would change their timestamps, and it is watching those directories.
if (( rebuild )); then
mca_revert
fi
mca_apply
if (( MCA_CHANGES )); then
if (( rebuild )); then
mca_ok "$(mca_msg "Applied again to %d applications." "$MCA_N_ON")"
mca_say " $(mca_msg "Applications that are already running pick this up when they are restarted.")"
elif (( MCA_CHANGES )); then
mca_ok "$(mca_msg "Applied to %d applications." "$MCA_N_ON")"
mca_say " $(mca_msg "Applications that are already running pick this up when they are restarted.")"
else
@@ -160,6 +167,7 @@ mca_do_help() {
enable $(mca_msg "Turn autoscroll on")
disable $(mca_msg "Turn it off and put everything back")
apply $(mca_msg "Apply to anything installed since the last run")
apply --rebuild $(mca_msg "Take everything back and apply it again")
status $(mca_msg "Show what is covered")
list $(mca_msg "List every application that was found")
-h, --help $(mca_msg "Show this help")