Auto remove the dead .desktop files
I opened this issue panel-plugins/xfce4-whiskermenu-plugin#64 (closed) that, in short, describes a major problem in my view: when a user edits any app via say Whisker menu or MenuLibre, then a new .desktop file is created .local/share/applications
. But if the user uninstalls the app the .desktop file stays in that directory, and thus is shown in the Whisker Menu, or the Application Finder. This will confuse anyone, since editing any app is as easy as right click and edit from the Whisker menu, yet removing dead .desktop files needs a lot more: open the file manager, show the hidden files, go to .local/share/applications
and delete a .desktop file that's associated with that zombie app, and in most cases such files' names do not match the app's name.
We have a custom linux distro (tromjaro.com) and use XFCE by default. We came up with this script that checks that .local/share/applications
folder against system folders where apps (snaps, flatpaks, repos) usually keep the .desktop files, and the script will rename any .desktop file from .local/share/applications
if it doesn't find that .desktop file in the system's folders. It is a simple solution. And if users reinstall the same app that they edited in the past, the .desktop file that they edited will be brought back to life.
Simply, if you install Peek (a desktop recorder), and rename it as Desktop Recorder, then it happens to remove it later on, the "Desktop Recorder" app will be gone from all menus. If you then reinstall Peek, it will be available again in the menu as "Desktop Recorder". Simple and useful.
Here's the script:
#!/bin/bash
data="$HOME"/.local/share/applications/tweaked-desktop-files
detectfiles() {
for file in "$HOME"/.local/share/applications/*.desktop; do
[ -d "$file" ] || grep -xq "$file" "$data" && continue
name=$(basename "$file") || continue
[ -f /usr/share/applications/"$name" ] ||
ls /var/lib/flatpak/app/*/current/active/files/share/applications/"$name" >/dev/null 2>&1 ||
[ -f /var/lib/snapd/desktop/applications/"$name" ] &&
echo "$file" >> "$data"
done
}
fixfiles() {
lastmod=$(stat -c "%Y" "$data")
tmp="$(mktemp -u)"
[ -f "$data" ] && cp "$data" "$tmp" && copied='true'
[ "$copied" = 'true' ] && while IFS= read -r file; do
[ -f "$file" ] || { sed -i "/^$file$/d" "$tmp" ; continue; }
name=$(basename "$file") || continue
[ -f /usr/share/applications/"$name" ] ||
ls /var/lib/flatpak/app/*/current/active/files/share/applications/"$name" >/dev/null 2>&1 ||
[ -f /var/lib/snapd/desktop/applications/"$name" ] ||
mv "$file" "$file.bak"
done < "$data"
[ "$copied" = 'true' ] && [ "$(stat -c '%Y' "$data")" = "$lastmod" ] && mv "$tmp" "$data"
for bakfile in "$HOME"/.local/share/applications/*.desktop.bak; do
origfile="${bakfile/%.bak}"
[ -f "$origfile" ] && continue
name=$(basename "$origfile") || continue
[ -f /usr/share/applications/"$name" ] ||
ls /var/lib/flatpak/app/*/current/active/files/share/applications/"$name" >/dev/null 2>&1 ||
[ -f /var/lib/snapd/desktop/applications/"$name" ] &&
mv "$bakfile" "$origfile"
done
}
pidof -q -o %PPID -x fix-tweaked-desktop-files && exit
while :; do
local_new=$(ls -ad "$HOME"/.local/share/applications/*.desktop 2>/dev/null)
pacman_new=$(ls -ad /usr/share/applications/*.desktop 2>/dev/null)
flatpak_new=$(ls -ad /var/lib/flatpak/app/*/current/active/files/share/applications/*.desktop 2>/dev/null)
snap_new=$(ls -ad /var/lib/snapd/desktop/applications/*.desktop 2>/dev/null)
[ "$local_new" != "$local_old" ] && detectfiles
[ "$pacman_new" != "$pacman_old" ] ||
[ "$flatpak_new" != "$flatpak_old" ] ||
[ "$snap_new" != "$snap_old" ] && fixfiles
local_old=$local_new
pacman_old=$pacman_new
flatpak_old=$flatpak_new
snap_old=$snap_new
sleep 5
done
We were wondering if you'd be interested to add this as a core functionality for Whisker Menu or XFCE in general.