Install Linux Icons Safely with xdg-icon-resource
Copy an icon in with xdg-icon-resource and there is no confirmation message, so you have to check where it landed yourself. This walks through installing a PNG or XPM icon, checking exactly where it went, and removing it again on purpose rather than by accident. Examples use xdg-icon-resource 1.1.3 from xdg-utils 1.1.3-4.1ubuntu3, installed on this machine.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about ten minutes. You need:
- An icon file ending in
.pngor.xpm, square, at the size you plan to install. - A shell on a desktop using the XDG icon theme layout.
- Root only for system mode. User mode needs no elevated privileges.
1. Check the command and the input
Confirm which executable is being used, then check the source file before changing the icon theme:
$ command -v xdg-icon-resource
/usr/bin/xdg-icon-resource
$ xdg-icon-resource --version
xdg-icon-resource 1.1.3
$ file /path/to/shinythings-myapp.png
/path/to/shinythings-myapp.png: PNG image data, 64 x 64, ...
The command only accepts PNG and XPM files. The image must be square, and --size describes the icon's theme size, such as 64: it is a label, not a request to resize the image. Do not trust a filename with a size baked in; inspect the file if the dimensions matter.
Checkpoint
Stop here if the source is missing, unreadable or not square. A successful copy does not make a badly sized icon useful to a desktop.
2. Install an application icon for your user
Use the apps context for a launcher or desktop application icon. Choose a name with a vendor prefix and leave off the file extension. This defaults to the hicolor theme:
$ xdg-icon-resource install --mode user --context apps --size 64 \
/path/to/shinythings-myapp.png shinythings-myapp
- No success message is normal. The icon is copied under the user's data directory, usually below
$XDG_DATA_HOME/icons/hicolor/64x64/apps/, or~/.local/share/icons/whenXDG_DATA_HOMEis unset. A same-named icon at that size gets overwritten. - The vendor check is on by default. For an
appsicon, the name must start with alphabetic characters followed by a dash:shinythings-myapppasses.--novendordisables the check but makes name collisions more likely; prefer a name you actually control.
Verify the copied resource without depending on a desktop menu refresh:
$ test -f "$HOME/.local/share/icons/hicolor/64x64/apps/shinythings-myapp.png" \
&& echo 'icon installed for this user'
icon installed for this user
If you set XDG_DATA_HOME, substitute that directory for $HOME/.local/share. Check as the same user who will actually use the icon.
3. Add several sizes or a file-type icon
Install each size separately under the same icon name. The desktop then picks the closest available resource:
$ xdg-icon-resource install --mode user --context apps --size 48 \
./shinythings-myapp-48.png shinythings-myapp
$ xdg-icon-resource install --mode user --context apps --size 64 \
./shinythings-myapp-64.png shinythings-myapp
For a file type, use the mimetypes context and a name such as application-x-foobar:
$ xdg-icon-resource install --mode user --context mimetypes --size 48 \
./mime-foobar-48.png application-x-foobar
$ xdg-icon-resource install --mode user --context mimetypes --size 64 \
./mime-foobar-64.png application-x-foobar
Other documented contexts are actions, devices, emblems, filesystems and stock. The context is part of the destination path, so picking apps when you meant mimetypes looks exactly like a missing icon rather than an installation mistake.
4. Batch changes without repeated cache updates
Adding several resources one at a time triggers a cache refresh each time. Skip that with --noupdate, then refresh once at the end:
$ xdg-icon-resource install --mode user --noupdate --context apps --size 48 \
./shinythings-myapp-48.png shinythings-myapp
$ xdg-icon-resource install --mode user --noupdate --context apps --size 64 \
./shinythings-myapp-64.png shinythings-myapp
$ xdg-icon-resource forceupdate --mode user --theme hicolor
forceupdate is useful after deferred updates, but it does not install an icon and cannot repair a wrong name, context or size. If the icon is still absent, check the destination path and confirm the desktop is reading the same user data directories.
5. Use system mode only when you mean all users
System mode writes to a shared icon directory: it is an administrative change, so name the target explicitly rather than relying on whether the shell happens to be root:
$ sudo xdg-icon-resource install --mode system --context apps --size 64 \
/path/to/shinythings-myapp.png shinythings-myapp
By default the tool picks system mode for root and user mode for anyone else. XDG_UTILS_INSTALL_MODE can override that with user or system, so check it before a scripted install:
$ printf 'XDG_UTILS_INSTALL_MODE=%s\n' "${XDG_UTILS_INSTALL_MODE:-unset}"
XDG_UTILS_INSTALL_MODE=unset
Warning
Do not add sudo just to make a user icon visible. It can put the resource in the shared tree while you are still checking the user's tree, which creates confusing duplicates.
6. Remove an icon and recover from mistakes
Uninstall removes files for the exact name, theme, context, size and mode you give it, with no confirmation prompt. Record those values from the install command before removing anything:
$ xdg-icon-resource uninstall --mode user --theme hicolor \
--context apps --size 64 shinythings-myapp
$ test ! -e "$HOME/.local/share/icons/hicolor/64x64/apps/shinythings-myapp.png" \
&& echo 'icon removed'
icon removed
Recovery
Run the original install command again from the source PNG or XPM file to undo an accidental removal. Finish with forceupdate if you used --noupdate. Keep the source file until the desktop has shown you the replacement you intended.
For diagnostics, set XDG_UTILS_DEBUG_LEVEL=1 or higher; the command reports more detail on standard error. Exit status 0 means success, and statuses 1 through 5 distinguish syntax, missing files, missing tools, an operation failure and unreadable input. Capture the status immediately if a script needs to act on it.
Done means
- The source file checks out: a readable, square PNG or XPM at the declared size.
- Theme, context, name and mode match the desktop and users that actually need the icon.
- Application names carry a vendor prefix unless you deliberately reviewed a reason for
--novendor. - Batches use
--noupdateplus oneforceupdateat the end, not a refresh after every install. - A verification command found the copied file, and the original source is still around for recovery.