Skip to content

Fix mount icons surviving unmount, and all volumes sharing one identity - #359

Open
svan71 wants to merge 2 commits into
icedman:mainfrom
svan71:fix-stale-mount-icons
Open

Fix mount icons surviving unmount, and all volumes sharing one identity#359
svan71 wants to merge 2 commits into
icedman:mainfrom
svan71:fix-stale-mount-icons

Conversation

@svan71

@svan71 svan71 commented Jul 30, 2026

Copy link
Copy Markdown

Two mount-icon problems with the same origin, plus the /tmp entries they leave behind.

One identity for every volume

_getMountName() computed a name and then returned the literal 'Volume', so every mount collapsed onto a single id and a single /tmp/<user>-mount-volume-…desktop entry. That entry was written only when absent, so its Name, Exec and Icon stayed frozen on whichever drive was mounted first after boot, and no second drive could ever get an icon of its own.

The entry is now always rewritten — name, path and icon belong to whatever is mounted right now.

Icons surviving unmount

Mount bookkeeping applied mount-added / mount-removed deltas. On mount-removed the GMount has already lost its drive and volume, so an id derived from its name at that point can disagree with the id it was added under — and the icon is left behind for the rest of the session.

Bookkeeping now reconciles against Gio.VolumeMonitor.get_mounts() instead of applying deltas, so it never has to derive an id from a mount that is already going away. Both handlers also refresh now: the dock only reconciles mount icons from layout(), which a plain animate() never reaches while the dock is autohidden.

Leftover /tmp entries

setupMountIcon() writes one desktop entry per mount and nothing ever removed it, so entries for unmounted volumes survived the session — and any still present when the session ended stayed in /tmp indefinitely. checkMounts() now sweeps the entries against the reconciled mount table, which covers both cases without tracking removals separately.

Also

The unmount action used umount(8), which needs root for anything that is not a fuse mount and unmounts behind udisks' back when it does work. It now uses gio mount -u.

Verification

On GNOME 50, with a loop-device volume mounted and unmounted in a nested headless shell: the icon appears and disappears with the mount, a second volume gets its own icon and name, and the stale /tmp entry is gone after reconcile. No JS errors.

svan71 added 2 commits July 30, 2026 16:07
_getMountName() computed a name and then returned the literal 'Volume', so
every mount collapsed onto a single id and a single /tmp desktop entry. The
entry was written only when absent, so its Name, Exec and Icon stayed frozen
on the first drive mounted after boot, and no second drive could ever get an
icon.

Mount bookkeeping now reconciles against Gio.VolumeMonitor.get_mounts()
instead of applying add/remove deltas. On 'mount-removed' the GMount has
already lost its drive and volume, so any id derived from its name at that
point can disagree with the id it was added under, leaving the icon behind
for the rest of the session. Both handlers also refresh now - the dock only
reconciles mount icons from layout(), which a plain animate() never reaches
while the dock is autohidden.

Also unmount via 'gio mount -u' rather than umount(8), which needs root for
anything that is not a fuse mount and bypasses udisks when it does succeed,
quote paths, and fall back to the location URI for network mounts.
setupMountIcon() writes /tmp/<user>-mount-<name>-dash2dock-lite.desktop per
mount and nothing ever removed it, so entries for unmounted volumes survived
the rest of the session - and any still present when the session ended stayed
in /tmp indefinitely.

checkMounts() now sweeps the entries against the reconciled mount table, which
covers both cases without tracking removals separately.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant