FINALLY figured this out! At least somewhat... there's more to it that I don't entirely understand and this makes getting the final colors correct a bit challenging. But I was able to make the change and confirmed it works on 2 different distros running Cinnamon: Fedora 33 and Mint 19.3. If others with better knowledge want to fill in the gaps or post a better answer, then by all means please do so.
WARNING: THIS PROCESS IS PROBABLY TOO ADVANCED FOR NOVICES/THOSE WITH LOW TECHNICAL BACKGROUNDS. NO PROGRAMMING NEEDED BUT AIMED MORE AT POWER-USERS/TWEAKERS. If you accept the risk and don't mind mind "voiding your warranty" ;-) ... the last section has the commands I used to get the icons in the screenshot.

I'm going to limit this answer changing the NetworkManager icon for the Adwaita icon theme on Cinnamon DE bc I'm lazy and don't feel like testing everything the many, many, many combinations of Applet/Status/Panel Size/Icon Theme/Desktop Environment/Version/Resolution/Distro/etc.
Dependencies:
- ImageMagick for the convert tool (cli) or Pinta/Krita/Gimp/whatever (if you want to do it in a gui)
- Gpick (optional but handy for spotting exact color of displayed panel icons)
Overview:
You should have a basic understanding of how icon themes interact. The main points to be aware of are that Linux/Gnome/GTK follows the freedesktop standards which check multiple folders and then fallback to multiple themes from all of those folders. I'm not going to dive into this much here but this post covers it fairly well. For my purposes, we'll just be focusing on the system path of /usr/share/icons
and the user path of ~/.local/share/icons
. If you know the name of the icon you are interested in, you can see how the system will resolve it to a file path by calling the GTK api. There are also some very handy python scripts that will accept the icon name as an argument and do this lookup for you that you can find in this post -- including a modified version I wrote myself.
Now that you know (at least in theory) where and how icons get picked up and how to find the file path to an icon, you need to know what icon names are used by the applet and which applet. This part is a bit hard too. Basically, these are defined in the applet code. For the Cinnamon DE, you can find its applets under /usr/share/cinnamon/applets
and while they are written in a form of javascript, the documentation is somewhat outdated and hard to find. However, you don't really need to understand the details of applet code to find the icon names. Now, you might see a file called metadata.json
which contains an icon name but before you get excited - this is only specifying the icon used in the Cinnamon Spices / Applet download GUI - not the icon the applet actually uses on the systray. As I said, the actual icon names will be defined in the applet source code. For the NetworkManager applet under Cinnamon, this is /usr/share/cinnamon/applets/[email protected]/applet.js
that I mentioned in the OP. If you start searching for icons, in this you will see a TON of icon names for all the various wifi states, offline/disconnected/connected states, and device types (wifi, wired, vpn, cell-network/broadband/whatever). Other applets will likely be much simpler, but it depends on the applet. Most of the basic icon names for this applet are defined in the function _updateIcon
which starts around line 2205 in my copy. You can then plug these into the python script mentioned above to get some paths: get-icon-path.py network-vpn
.
Now here's another part that had my stumped for quite some time. Gnome/Gtk/Cinnamon have 2 basic types of icons. There's the regular icons which are also known as full color icons and what are called "Symbolic" icons (generally monochrome). For the longest time, I was under the impression that symbolic were 100% black and white with no color but this is not the case. I had also mistakenly thought that the only way I'd be able to get colored systray icons was to somehow dive into the world of custom css files / javascript tweaks to heavily modify my theming. I'm sure that would produce better results but I didn't want to take a course in OS theming or make a career out of this; I just wanted to change some basic colors and move on to bigger better things. So when you are searching for icons, you actually will get matches for both get-icon-path.py network-vpn
AND get-icon-path.py network-vpn-symbolic
. I don't entirely understand all the scenarios where one is used over the other; I imagine I would have to dedicate some time to reading the freedesktop.org / Gnome documention in depth for this. But for my changes I customized the network-vpn-symbolic
and network-wired-symbolic
icons (as well as a few intermediary/error states).
Once you have zeroed in on the exact icon files to modify, you can go ahead and create copies under ~/.local/share/icons/<theme>
. In my case <theme>
is Adwaita
. Also, your "Panel Settings" probably don't matter here: mine said I have a panel height of '32' and symbolic icon size of '28px' (and my resolution is 1920x1080 if that matters). I thought that this would play into the icon size and ending up wasting a lot of time hunting down larger icon sizes and scalable svg vector images... but the thing that actually proved this was working to me was 16x16 png file for network-wired that I had thrown in the folder on a whim. I also realized that even though /usr/share/icons/Adwaita/16x16
does NOT have a network-vpn, you can resize one of the other icons place it in the corresponding folder and it will get picked up.
The last troublesome part, that I still don't completely understand is how the final displayed color is set. It seems that there is some intermediary styles in the os that are altering the color from what I have stored in the png icon files but it does't appear to be as simple to calculate as adding/subtracting some offset. Mostly I have gotten as far as I have through trial and error.
My setup
My system setups / themes (for reference)
Attribute |
Fedora 33 |
Mint 19.3 |
Cinnamon version |
v4.8.6-1 |
v4.4.8 |
NetworkManager version |
v1.26.6-1 |
v1.10.14 |
Themes: Window border |
Mint-Y-Dark |
Mint-Y |
Themes: Icons |
Mint-Y-Dark-Aqua |
Mint-Y |
Themes: Controls |
Mint-Y-Dark-Aqua |
Mint-Y |
Themes: Mouse Pointer |
Adwaita |
DMZ-White |
Themes: Desktop |
Mint-Y-Dark-Aqua |
Mint-Y-Dark |
You will also note that these all inherit from Adwaita at some stage or another which is why Adwaita is the lowest common denominator I'm targeting. But for systray, I would think it would be based on your Icon theme (unverified).
$ cd /usr/share/icons
$ grep Inherit Mint-Y-Dark-Aqua/index.theme
Inherits=Mint-Y-Dark,Adwaita,gnome,hicolor
$ grep Inherit Mint-Y-Dark/index.theme
Inherits=Mint-Y,Adwaita,gnome,hicolor
$ grep Inherit Mint-Y/index.theme
Inherits=Adwaita,gnome,hicolor
Color table
As I mentioned about the colors for the final icons I was seeing are affected by some other styles/themes somewhere in the OS that I don't know how to get to / would require significantly more effort to find that I wish to expend. For other lazy people like myself, here are a few values that will probably work on a mostly default Cinnamon system. For everybody else, I'll outline the steps I used to get here below and you can experiment yourself.
ImageMagick color in png file |
color of displayed icon (according to gpick) |
DeepSaffron #ff9933 |
dark purple #3d1660 |
Light Blue #00fee1 |
light orange #c8995e |
Red #ff0000 |
medium green #4e9a06 |
Green #00ff00 |
orange #f5793e |
Blue #0000ff |
dark red #cc0000 |
Black #000000 |
white #ffffff |
White #ffffff |
black? #111647 |
Yellow #ffff00 |
dark purple #441446 |
Pink #ff00ff |
medium green #1b9c08 |
Tan? #0000ff |
dark red #cb9ae5 |
Gold (gold) |
dark purple #452964 |
Gray (gray) |
light purple #890ca7 |
Green (green) |
pale orange/pink #f9bb9e |
Tan (tan) |
green #4ac21e |
Brown (brown) |
gold? #827014 |
Cyan (cyan) |
orange #c27b40 |
Magenta (magenta) |
green #1b9c08 |
yellow green #beef00 |
purple #713691 |
dark purple #441446 |
orange #c19367 |
light blue #5294e2 |
light green #92b372 |
dark pink #441446 |
light purple #6253d2 |
light purple #6253d2 |
light green #8ddb8f |
mid blue #6689af |
bright green #8fe085 |
blue green? #0f808f |
red #d22600 |
??? #ff0ff0 |
deep green #1da30b |
??? #ff0f0f |
mid blue #fa83ec |
??? #ff000a |
lighter blue #c490fd |
??? #00f000 |
bright orange #f58049 |
??? #000fff |
very pale light light blue #cbf9f5 |
Recreating my icons from the screenshot
This is just going to show actual commands used for two specific network-manager icons. This is on a hard-wired desktop PC so I don't have wifi and I'm only really concerned with seeing at a glance if my VPN is connected or I am online without VPN. Since I already covered how to find the icons in the overview, this will just be covering how to recreate what I did in the screenshot above.
If you have other icon themes in ~/.local/share/icons
then rename it so that you don't have extra stuff to conflict with during the test. You can move it back/merge it afterward (I had this happen and it took me awhile to realize what was going on): mv ~/.local/share/icons ~/.local/share/icons.$(date +'%Y-%m-%d-%H%M%S').bak
# create directories
mkdir -p ~/.local/share/icons/Adwaita/16x16/devices;
mkdir -p ~/.local/share/icons/Adwaita/16x16/status;
# check what icons you have on your system
# for python script, see linked post above
get-icon-path.py network-vpn network-wired network-vpn-symbolic network-wired-symbolic
# OR alternately, you could run something like
# but this won't consider theme inheritance or user-folders
find /usr/share/icons/Adwaita /usr/share/icons/gnome \( -iname '*network-vpn*.png' -o -iname '*network-wired*.png' \) -not \( -iname '*acquir*' -o -iregex '.*/legacy/.*' -o -iname '*route*' -o -iname '*offline*' -o -iname '*disconnected*' \)|sort;
# recolor the default 16x16 network-wired icon
cd ~/.local/share/icons/Adwaita/16x16/devices;
f="/usr/share/icons/Adwaita/16x16/devices/network-wired-symbolic.symbolic.png";
c='cyan';convert "${f}" -fuzz 20% -fill ${c} +opaque none "$(basename "${f}")";
# no 16x16 icon is provided for network-vpn
# so recolor and resize the 64x64 network-vpn icon
cd ~/.local/share/icons/Adwaita/16x16/status;
f="/usr/share/icons/Adwaita/64x64/status/network-vpn-symbolic.symbolic.png";
c='#6689af';convert "${f}" -resize 16x16 -fuzz 20% -fill ${c} +opaque none "$(basename "${f}")";
# restart cinnamon desktop (or alternately, just log out then back in)
cinnamon --replace --clutter-display=:0 2> /dev/null &
Update: So far I have run the above commands on 2 instances of Mint 19.3 and 1 instances of Fedora 33 without issue. But on my 3rd instance of Mint 19.3, I noticed that the icons I listed above (e.g. network-vpn-symbolic.symbolic.png
did not exist but network-vpn.png
did). In this case, it is recommend to use the python script I mentioned earlier and look up the icon names network-vpn
and network-vpn-symbolic
; if you have symbolic use that, if not use the regular one. If you have a 16x16-sized default icon, then you can use the first convert command (without -resize); if not, then pick the highest resolution default icon you have (256 or 128 or 64 usually) and use the 2nd convert command (with -resize).
Update 2: Also note that the get-icon-path.py script does not work correctly over ssh sessions (and possibly in also in other non-graphical sessions). I suspect this is because you need an X11/graphical session for it to query.