How do I find the icon files used by non-default status menus (aka indicators)?
I'd like to find the location of the icons used by some non-default status menus (also called application indicators or indicator applets).
Where are these icons image files located?
In my screenshot I have ownCloud and Radiotray, but I would like a general answer not specific to these particular icons please. I don't know the file names or file types so searching is difficult.
Default location for non-default indicator icons?
There is no default location where these icons are stored. Any application (-developer) can store them where it is considered appropriate.
However, the good news is that indicators usually do not install endless lists of files and images. We can limit our search by (apart from looking into the code) looking into the output of the command:
dpkg-query -L <packagename>
In my example of
dpkg-query -L placesfiles
this would among others, output the following images:
/opt/placesfiles/images/dir_icon.png
/opt/placesfiles/images/placesfiles64.png
/usr/share/pixmaps/placesfiles.png
...Which would make the search quite limited.
From man dpkg-query
:
-l, --list [package-name-pattern...]
List packages matching given pattern. If no package-name-pattern
is given, list all packages in /var/lib/dpkg/status, excluding
the ones marked as not-installed (i.e. those which have been
previously purged). Normal shell wildcard characters are allowed
in package-name-pattern. Please note you will probably have to
quote package-name-pattern to prevent the shell from performing
filename expansion. For example this will list all package names
starting with “libc6”:
In the case of Radiotray, I found the following .png
files (running dpkg-query -L radiotray | grep png
):
/usr/share/radiotray/images/radiotray_connecting.png
/usr/share/radiotray/images/radiotray_on.png
/usr/share/radiotray/images/radiotray_off.png
/usr/share/radiotray/images/radiotray.png
/usr/share/pixmaps/radiotray.png
If we really need to find out, searching the code
...we can look through (inside) installed files for matches of the string "icon". Many of the indicators are written in one of the script- languages (like python
), which means they are very well search-able.
An example
Again using the radiotray
example
dpkg-query -L radiotray | xargs grep icon
in the output we find a.o.:
/usr/lib/python2.7/dist-packages/radiotray/SysTrayGui.py
self.icon.set_from_file(APP_ICON_CONNECT)
Looking into the file SysTrayGui.py
, we can see:
from lib.common import APPNAME, APPVERSION, APP_ICON_ON, APP_ICON_OFF, APP_ICON_CONNECT, APP_INDICATOR_ICON_ON, APP_INDICATOR_ICON_OFF
From this, we can conclude the mentioned icons are defined in the module common
inside the (sub) directory lib
. (See here how python finds it modules, section Subdirectories)
In this module, we can read the section:
# Media path
if os.path.exists(os.path.abspath('../data/images/')):
IMAGE_PATH = os.path.abspath('../data/images/')
else:
IMAGE_PATH = '%s/%s/images' % (datadir, APPDIRNAME)
# Images
APP_ICON = os.path.join(IMAGE_PATH, 'radiotray.png')
APP_ICON_ON = os.path.join(IMAGE_PATH, 'radiotray_on.png')
APP_ICON_OFF = os.path.join(IMAGE_PATH, 'radiotray_off.png')
APP_ICON_CONNECT = os.path.join(IMAGE_PATH, 'radiotray_connecting.gif')
APP_INDICATOR_ICON_ON = "radiotray_on"
APP_INDICATOR_ICON_OFF = "radiotray_off"
APP_INDICATOR_ICON_CONNECT = "radiotray_connecting"
...and here we are...
Exceptional situations
With practical all of my indicators, I managed to find the corresponding icons using the method(s) above.
In turns out to be possible however, to compile images together with the code into a single executable. No need to explain that in such cases you will not find a separate image, nor will you be able to replace them without editing the code and recompile.
The case of owncloud seems to be such a case. Using the above method(s) showed a set of icons was installed inside /usr/share/icons/hicolor/<size>/apps
. None of these icons turns out to be used however in the indicator on ubuntu.
OP did quite some work before (and after) he asked this question. One of them was to run:
gdbus call --session --dest com.canonical.indicator.application --object-path /com/canonical/indicator/application/service --method com.canonical.indicator.application.service.GetApplications
... which gives us quite some useful information. The output included a section:
('146028888067', 2, 'org.kde.StatusNotifierItem-22055-1', '/StatusNotifierItem/menu', '/tmp/iconcache-50ePXx', '', '', '', 'owncloud', 'ownCloud')
Looking into the directory /tmp/iconcache-50ePXx
, I found the exact icons that were used by the indicator:
... which seems to prove these icons are generated on the fly; closing owncloud makes the directory and its icons vanish.
It turned out to be possible to change the indicator's icon by replacing these icons:
which proves these are indeed the icons we were looking for.
To automate what I did manually however, would requires a script/wrapper, since the created directory's name is changed every time owncloud is launched. The most convenient option would of course be that the owncloud-client's code would be changed.
See also our discussion here.
To be continued...
Icons and their potential locations
There's two ways indicator could employ icons:
- Custom icon. This typically goes into
/usr/share/pixmaps/
, although it's possible some of the authors send indicator icons to other directories. Jacob Vlijm, whose answer is on this page and who is also author of SpaceView indicator, for example, chose to place icons for that indicator into/opt/spaceview/icon
. With these type of icons it's slightly tricky but not complex - usedpkg -L <package name>
orcat /var/lib/dpkg/info/PACKAGE.list
and search for an icon file, with.png
or.svg
extension. These are most typical - Standard, theme-specific icon. These typically can be found in
/usr/share/icons
folder. For instance, in my indicators such as Udisks Indicator, I frequently rely on what's in/usr/share/icons/gnome
, since these are standard and come with any Ubuntu installation. If you don't find an icon from queryingdpkg
, chances are the package uses a standard icon.
Going to the source
If an indicator is written in Python or Ruby, looking through source code for clues can be relatively easy, since these are scripts, and it is sufficient to use grep
to search through the source code. Compiled languages such as C and Vala don't come with source code, so you would have to obtain it, either via apt-get source package-name
or from wherever you obtained the package. ( Adventurous users could use hexdump
or decompile the executable file, but IMHO it's too much work just for curiosity about an icon ).
NOTE: if an icon resides in one of the standard directories, such as /usr/share/icons/
or /usr/share/pixmaps
, the author of the software may choose to call the icon simply by name, without extensions. For example, in my udisks-indicator
I use this line to call one of the standard icons:
self.app.set_icon("drive-harddisk-symbolic")
Notice the lack of .svg
or .png
extension. Thus, in this case, we have a name of the icon, and we can locate it using Linux standard commands such as locate
or find
.
Search using standard Linux tools
If you really want to have a command for searching icons, just use this simple combination:
dpkg -L <Package name here> | xargs file | grep -i image
Here's an example. I know for a fact that indicator diskman uses a custom icon. So what does this command tell us ?
$ dpkg -L indicator-diskman | xargs file | grep -i image
/usr/share/indicator-diskman/images: directory
/usr/share/indicator-diskman/images/drive-harddisk.svg: SVG Scalable Vector Graphics image
/usr/share/indicator-diskman/images/media-optical.png: PNG image data, 64 x 64, 8-bit/color RGBA, non-interlaced
/usr/share/indicator-diskman/images/disks.png: PNG image data, 64 x 64, 8-bit gray+alpha, non-interlaced
/usr/share/indicator-diskman/images/locked.png: PNG image data, 16 x 16, 8-bit/color RGBA, non-interlaced
/usr/share/indicator-diskman/images/lock.svg: SVG Scalable Vector Graphics image
/usr/share/indicator-diskman/images/unlocked.png: PNG image data, 16 x 16, 8-bit/color RGBA, non-interlaced
/usr/share/indicator-diskman/images/media-eject.svg: SVG Scalable Vector Graphics image
/usr/share/indicator-diskman/images/disk.png: PNG image data, 32 x 32, 8-bit/color RGBA, non-interlaced
/usr/share/pixmaps/indicator-diskman.png: PNG image data, 64 x 64, 8-bit gray+alpha, non-interlaced
Notice the /usr/share/pixmaps/indicator-diskman.png
the last image, which is what the indicator actually shows on the panel.
And what if the indicator uses a standard icon ? Well obviously there will be no output:
$ dpkg -L udisks-indicator | xargs file | grep -i image
$
Conclusion
While there's no set standard, there's set of typical places where icons go, and we can use dpkg
to query information about what files come with each specific package. Finally, maybe it's not the most technical suggestion, but consider sending developers an email or stopping by their IRC or chat, and simply asking them "Hey, what icon does your indicator use?". Developers usually are glad to hear from people who use their software and won't mind to answer a quick question.