Where the icon is defined
The representation of an application in Dash and the the Unity launcher is defined in a .desktop file. Such a .desktop files includes a line to set the command to run the application, a line to set the icon of the application and a varying number of possible lines to set additional properties.
To see the current Unity launcher's content by command:
gsettings get com.canonical.Unity.Launcher favorites
If you run this command, you will (a.o.) get a list of references to .desktop files, in the order like they appear in the launcher. An application's mention in the list looks like: application://thunderbird.desktop
. It refers (in this example) to the file, thunderbird.desktop
.
When Unity gathers its information on login, it first looks into the local directory for .desktop files, (~/.local/share/applications
), and secondly in /usr/share/applications
. If a .desktop file exists in both directory, the local one has preference. Normally, during your session, the launcher's icon stays linked to the .desktop file in either one of these directories.
When the content of the linked desktop file is edited during your session, the result is applied immediately. However, the icon as it appears in the Unity launcher does not change until you either:
- log out / login
- remove the icon from the launcher and lock it again
Since you cannot remove the icon of a running application from the launcher, changing the icon of a running application is not possible.
To change the icon of an application in the launcher which is not running however, you can use the two scripts below.
The first one copies the .desktop file to the local directory and edits the Icon=
line in the local copy. The second one refreshes the icon in the launcher (and relinks it if necessary).
Script 1; change the icon
how to use
Copy the script below into an empty file, save it as change_icon.py
, run it by the command:
python3 change_icon.py <applicationnamme.desktop> </path/to/new/icon>
for example:
python3 change_icon.py thunderbird.desktop </path/to/new/icon>
for smoother use:
create a directory ~/bin
, copy the script into the directory, remove the language extension from the script, make it executable and (after logout / login), you can simly use the script by the command:
change_icon <applicationnamme.desktop> </path/to/new/icon>
More info on where to store and how to define icons, you can find here
The script
#!/usr/bin/env python3
import os
import shutil
import sys
file = sys.argv[1]
new_icon = sys.argv[2]
user_home = os.environ["HOME"]
dir_1 = user_home+"/.local/share/applications/"
dir_2 = "/usr/share/applications/"
dtfile_list1 = os.listdir(dir_1)
dtfile_list2 = os.listdir(dir_2)
subject = dir_1+file
if not os.path.exists(subject):
try:
shutil.copyfile(dir_2+file, dir_1+file)
except FileNotFoundError:
print("the file "+file+" does not exist")
def read_file(file):
with open(file) as edit:
return edit.readlines()
def write_file(file, linelist):
with open(file, "wt") as edit:
for line in linelist:
edit.write(line)
subject_lines = read_file(subject)
index = [i for i in range(len(subject_lines))
if subject_lines[i].startswith("Icon=")][0]
subject_lines[index] = "Icon="+new_icon+"\n"
write_file(subject, subject_lines)
Script 2; refresh the icon in the launcher
how to use
Copy the script below into an empty file, save it as refresh.py
, run it by the command:
python3 refresh.py <applicationnamme.desktop>
for smoother use:
Like in the script above, copy the script into ~/bin
, remove the language extension, make it executable and (after logout / login), you can simly use the script by the command:
refresh <applicationnamme.desktop>
for example:
refresh thunderbird.desktop
The script
#!/usr/bin/env python3
import subprocess
import time
import sys
desktopfile = sys.argv[-1]
def read_currentlauncher():
# reads the current launcher contents
return subprocess.check_output([
"gsettings", "get", "com.canonical.Unity.Launcher", "favorites"
]).decode("utf-8")
def set_launcher(llist):
# sets a defined unity launcher list
current_launcher = str(llist).replace(", ", ",")
subprocess.Popen([
"gsettings", "set", "com.canonical.Unity.Launcher", "favorites",
current_launcher,
])
def refresh_icon(desktopfile):
current_launcher = read_currentlauncher()
current_launcher_temp = eval(current_launcher)
item = [item for item in current_launcher_temp if desktopfile in item][0]
index = current_launcher_temp.index(item)
current_launcher_temp.pop(index)
set_launcher(current_launcher_temp)
time.sleep(2)
set_launcher(current_launcher)
refresh_icon(desktopfile)
XChangeProperty
with_NET_WM_ICON
? Would that update the icon? – Noitidart Oct 15 '14 at 20:18