11

I would like to create a launcher that does the same thing as the trash icon where different quicklists are shown depending on whether or not there are items on the trash.

I would like something like: if folder A exists, show A,B,C on the quick list, if folder A does not exist, show D,E,F on the quick list.

2

1 Answer 1

3
+50

The following works:

  1. Create 2 files: mylauncher.desktop and mylauncher.py with contents as given below.
  2. Make mylauncher.desktop an executable.
  3. Add mylauncher.desktop to unity's launcher.
  4. Edit Foldernames and Folderlocations in mylauncher.py as necessary.
  5. Run python mylauncher.py in the background. You'll have to add this to one of your start-up scripts.

Source: https://wiki.ubuntu.com/Unity/LauncherAPI


Contents of mylauncher.desktop:

[Desktop Entry]
Name=My Launcher
Comment=A,B,C if A else D,E,F
Exec=nautilus %U
Icon=nautilus
Terminal=false
StartupNotify=true
Type=Application
OnlyShowIn=GNOME;Unity;
Actions=;

Contents of mylauncher.py:

updateinterval = 1 #Update interval in seconds. Set it to a +ve integer.
#In Foldernames and Folderlocations, spaces shouldn't be preceded by \.
Foldernames = ["A", "B", "C", "D", "E", "F"]
Folderlocations = ["/home/prasanth/A", "/home/prasanth/B", "/home/prasanth/C", "/home/prasanth/D", "/home/prasanth/E", "/home/prasanth/F"]
#####################################

from gi.repository import Unity, Gio, GObject, Dbusmenu
import os, subprocess

def nautilusopen(junk1, junk2, location): #Function that opens `location` in nautilus. Equivalent to `nautilus location` in bash.
    subprocess.Popen(['nautilus', "%s" % location])

launcher = Unity.LauncherEntry.get_for_desktop_id("mylauncher.desktop") #You won't have to modify this, except if you rename `mylauncher.desktop`

#Code block A: This code block builds 6 quicklist entries, 3 for when A is found and 3 for when it isn't
QLentries = [Dbusmenu.Menuitem.new() for i in Foldernames]
for i in xrange(6):
    QLentries[i].property_set(Dbusmenu.MENUITEM_PROP_LABEL, "Goto %s" % Foldernames[i])
    QLentries[i].connect("item-activated", nautilusopen, Folderlocations[i])
    QLentries[i].property_set_bool(Dbusmenu.MENUITEM_PROP_VISIBLE, True)
################

#Code block B: This code block creates 2 quicklists 1 for when A is found and 1 for when it isn't. Then it adds the first 3 quicklist entries to QLifA and the next 3 to QLifnotA
QLifA = Dbusmenu.Menuitem.new() #Quicklist if A is found
QLifnotA = Dbusmenu.Menuitem.new() #Quicklist if A is not found.
for i in xrange(3):
    QLifA.child_append(QLentries[i])
for i in xrange(3, 6):
    QLifnotA.child_append(QLentries[i])
################

#The rest of the code simply monitors the file system for A's existence and switches appropriately between QLifA and QLifnotA
prevState = None
def updateql():
    global prevState
    currentState = 'A' if os.path.exists(Folderlocations[0]) else 'notA' #currentState is 'A' if Folderlocations[0] (which is /home/prasanth/A) exists, 'notA' otherwise
    if currentState != prevState:
        if currentState == 'A':
            launcher.set_property("quicklist", QLifA)
        else:
            launcher.set_property("quicklist", QLifnotA)
        prevState = currentState
    return True

#GObject.timeout_add_seconds(updateinterval, updateql)
#mainloop = GObject.MainLoop()
#mainloop.run()

#If the 3-line commented block above worked as expected, the remainder of this script would be unnecessary. Unfortunately, it doesn't.
import signal
def alarmhandler(signum, frame):
    raise Exception('Alarm has rung')
signal.signal(signal.SIGALRM, alarmhandler)

mainloop = GObject.MainLoop()

while True:
    try:
        updateql()
        signal.alarm(updateinterval)
        mainloop.run()
    except KeyboardInterrupt:
        continue

EDIT: Use the following as mylauncher.py for the purpose mentioned in comments. Modifying to suit your needs should be straight forward and in case it isn't mention it in the comments.

from gi.repository import Unity, Gio, GObject, Dbusmenu
import os, subprocess

updateinterval = 1 #Update interval in seconds. Set it to a +ve integer.

#Quicklist entries if already mounted:
ifMountedEntry1text = """Unmount A""" #Text shown in the quicklist menu for this entry.
ifMountedEntry1command = """unmount A""" #Bash command to execute when entry 1 is clicked. Doubt if `unmount A` will work. Modify appropriately.

ifMountedEntry2text = """Open A""" #Maybe you'll want to open A directly from the launcher. Included just so you get a hang of how this works.
ifMountedEntry2command = """nautilus A"""
#Extend as required.

#Quicklist entries if not already mounted:
ifnotMountedEntry1text = """Mount A"""
ifnotMountedEntry1command = """mount A""" #Again modify `mount A` appropriately.
#Extend as required.

#My old file monitoring should work. But in case you want to change the criteria for modifying quicklists, it is better to do the following:
filemonitoringcommand = """if [ -d /folder/to/monitor/ ]; then echo True; else echo False; fi;""" #<Bash command>/<location to script> which prints 'True' if A is mounted, 'False' otherwise.
#####################

def systemcall(junk1, junk2, command):
    os.system(command)

launcher = Unity.LauncherEntry.get_for_desktop_id("mylauncher.desktop") #You won't have to modify this, except if you rename `mylauncher.desktop`

#Quicklist if already mounted:
QLifMounted = Dbusmenu.Menuitem.new()

ifMountedEntry1 = Dbusmenu.Menuitem.new()
ifMountedEntry1.property_set(Dbusmenu.MENUITEM_PROP_LABEL, ifMountedEntry1text) #Sets the text shown in the quicklist menu for this entry.
ifMountedEntry1.connect("item-activated", systemcall, ifMountedEntry1command) #Sets the corresponding bash command.
ifMountedEntry1.property_set_bool(Dbusmenu.MENUITEM_PROP_VISIBLE, True)
QLifMounted.child_append(ifMountedEntry1) #Adds the first entry to the quicklist

ifMountedEntry2 = Dbusmenu.Menuitem.new()
ifMountedEntry2.property_set(Dbusmenu.MENUITEM_PROP_LABEL, ifMountedEntry2text)
ifMountedEntry2.connect("item-activated", systemcall, ifMountedEntry2command)
ifMountedEntry2.property_set_bool(Dbusmenu.MENUITEM_PROP_VISIBLE, True)
QLifMounted.child_append(ifMountedEntry2)
#Extend as required.

#Quicklist if not already mounted:
QLifnotMounted = Dbusmenu.Menuitem.new()

ifnotMountedEntry1 = Dbusmenu.Menuitem.new()
ifnotMountedEntry1.property_set(Dbusmenu.MENUITEM_PROP_LABEL, ifnotMountedEntry1text)
ifnotMountedEntry1.connect("item-activated", systemcall, ifnotMountedEntry1command)
ifnotMountedEntry1.property_set_bool(Dbusmenu.MENUITEM_PROP_VISIBLE, True)
QLifnotMounted.child_append(ifnotMountedEntry1)
#Extend as required.

#The rest of the code uses `filemonitoringcommand` to monitor the filesystem and dynamically modifies (or rather switches between) quicklists.
prevState = None
def updateql():
    global prevState
    currentState = 'True' in os.popen(filemonitoringcommand).read()
    if currentState != prevState:
        if currentState == True:
            launcher.set_property("quicklist", QLifMounted) #If already mounted, sets QLifMounted as the quicklist.
        else:
            launcher.set_property("quicklist", QLifnotMounted) #Otherwise sets QLifnotMounted as the quicklist.
        prevState = currentState
    return True

#GObject.timeout_add_seconds(updateinterval, updateql)
#mainloop = GObject.MainLoop()
#mainloop.run()

#If the 3-line commented block above worked as expected, the remainder of this script would be unnecessary. Unfortunately, it doesn't.
import signal
def alarmhandler(signum, frame):
    raise Exception('Alarm has rung')
signal.signal(signal.SIGALRM, alarmhandler)

mainloop = GObject.MainLoop()

while True:
    try:
        updateql()
        signal.alarm(updateinterval)
        mainloop.run()
    except KeyboardInterrupt:
        continue
15
  • I have tried this but it does not work for me. The quicklist does not change. I am using ubuntu 12.10 64-bit. Feb 20, 2013 at 15:38
  • I'm using 12.04 32 bit. The python script should be run AFTER adding the launcher icon to the launcher.
    – Prasanth S
    Feb 21, 2013 at 2:45
  • Do the following.1) Put mylauncher.desktop in ~/.local/share/applications 2) Press the super-key and search for 'My Launcher'. 3) Drag the launcher icon that appears onto the unity launcher. 4) Run the python script. This should work.
    – Prasanth S
    Feb 21, 2013 at 3:09
  • @ReyLeonardAmorato I'm just curious. Did it work?
    – Prasanth S
    Feb 22, 2013 at 23:10
  • Hi. Sorry I couldn't find the time to go online lately, but your latest method worked for me. However, what I wanted is slightly different from what the script does. I would like to monitor a folder location, (script does this already) and if folder 'A' exists, show 'unmount' on the quicklist. Show 'mount' otherwise. I have no knowledge of python scripting so I have no idea how to modify the script you have provided. It would be great if you could help out with this final bit. Mar 13, 2013 at 12:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .