Ubuntu – Sort Unity Launcher icons alphabetically

desktopgsettingslauncherunity

I like to keep my locked Launcher applications sorted alphabetically, and I was wondering if it would be possible to write a script that sorts them, so I don't have to do it myself every time I add a new program.

If there is a folder somewhere that contains all the names and locations of the icons I should be able to figure it out from there.

Best Answer

Keep the launcher sorted alphabetically

Running the script below in the background (see further below how to do that) will keep your launcher sorted alphabetically from a to z:

The top three launcher items before running the script: Gnome-terminal, Virtualbox, LibreOffice

enter image description here

Running the script: dconf-editor, Files, Firefox

enter image description here

What the script does

The (interface-) names of the applications is defined in .desktop files. These files can be stored in either /usr/share/applications or ~/.local/share/applications. The latter "overrules" the global one, if the local one exists.

The script checks for changes in the launcher list, running (in a loop, every two seconds) the command:

gsettings get com.canonical.Unity.Launcher favorites

This returns a list of launcher items, ordered like the current order of the launcher.

If the launcher changes (e.g. if you add a new launcher), the script looks up the referring interface names in the .desktop files (preserving the precedence of the local .desktop files) and sorts the launcher items, according to these interface-names.

Subsequently, the script sets the sorted launcher by the command:

gsettings set com.canonical.Unity.Launcher favorites "<sorted_launcheritems_list>"

How to use

  1. Copy the script below into an empty file, save it as sort_launcher.py
  2. Test-run it by running (in a terminal) the command:

    python3 /path/to/sort_launcher.py
    
  3. If it works fine, add it to your startup applications: Dash > Startup Applications > Add the command:

    /bin/bash -c "sleep 15&&python3 /path/to/sort_launcher.py"
    

The script

#!/usr/bin/env python3
import subprocess
import os
import time

home = os.environ["HOME"]
# define the two directories to search .desktop files, the string to identify application launchers
dir1 = "/usr/share/applications/"; dir2 = home+"/.local/share/applications/"; s = "application://"
# the key to read / write the launcher
lget = "gsettings get "; lset = "gsettings set "; key = "com.canonical.Unity.Launcher favorites"

# read current launcher
def read_current():
    return eval(subprocess.check_output(["/bin/bash", "-c", lget+key]).decode("utf-8").strip())

def sort_launcher(launchers):
    # split up launcher items in applications / others
    apps = []; others = []
    for it in launchers:
        apps.append(it) if it.startswith(s) else others.append(it)
    # create a sorted application (launcher-) list
    sort_list = []
    app_launchers = []
    for item in apps:
        check = get_interfacename(item)
        if check:
            app_launchers.append([check, item])
    app_launchers.sort(key=lambda x: x[0])
    # set the sorted launcher
    launcher_set = [item[1] for item in app_launchers]+others
    subprocess.Popen(["/bin/bash", "-c", lset+key+' "'+str(launcher_set)+'"'])

def get_interfacename(item):
    name = []
    for dr in [dir1, dir2]:
        subject = dr+item.replace(s, "")
        try:
            app = [l.strip() for l in open(subject).readlines() if l.startswith("Name=")][0]
            name.append(app)
        except FileNotFoundError:
            pass
        else:
            name.append(app)
            return name[-1].strip("Name=").lower()

# check every two seconds for changes, update launcher if necessary
current_launcher1 = read_current()
sort_launcher(current_launcher1)
while True:
    time.sleep(2)
    current_launcher2 = read_current()
    if current_launcher1 != current_launcher2:
        sort_launcher(current_launcher2)
    else:
        pass
    current_launcher1 = current_launcher2

Notes

  • The script sorts by US-English names of the applications
  • In system monitor, the script shows cpu 0%, which means the script adds practically nothing to the processor load.
Related Question