Ubuntu – How to program a one click indicator (add middle click functionality)

application-developmentindicatorpythonunity

I'm fairly fluent with creating Application indicators with menus. On the example below there is one menu item (quit). I wouldn't have any problems adding another item, my actual application, or line to run.

However, when I'm trying to do is make the item run when the indicator icon is clicked. Each time the indicator icon is clicked it will run. To remove the indicator icon, the user will click on quit.

Can someone tell me where to put my line to run in the code?

This is the indicator code:

#!/usr/bin/python

import os
import signal
import subprocess
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk as gtk
gi.require_version('AppIndicator3', '0.1')
from gi.repository import AppIndicator3 as appindicator

APPINDICATOR_ID = 'appreveallauncher'


def main():
    indicator = appindicator.Indicator.new(APPINDICATOR_ID,
                                            os.path.abspath('sample_icon.svg'),
                                            appindicator.IndicatorCategory.SYSTEM_SERVICES)
    indicator.set_status(appindicator.IndicatorStatus.ACTIVE)
    indicator.set_menu(build_menu())
    gtk.main()

def build_menu():
    menu = gtk.Menu()

    item_quit1 = gtk.MenuItem('Quit')
    item_quit1.connect('activate', quit)

    item_reveallauncher = gtk.MenuItem('Reveal Launcher')
    item_reveallauncher.connect('activate', reveallauncher)

    # This is my attempt to add the middle click functionality

    menu_items = gtk.MenuItem("Reveal Launcher Middle Click")
    menu.append(menu_items)
    menu_items.connect("activate", menu_items)
    menu_items.set_secondary_activate_target(menu_items)    


    menu.append(item_reveallauncher)
    menu.append(item_quit1)
    menu.show_all()
    return menu

def menu_items(_):
    subprocess.call("xdotool key alt+F1", shell=True) 


def reveallauncher(_):
    subprocess.call("xdotool key alt+F1", shell=True) 

def quit1(_):
    gtk.main_quit()


if __name__ == "__main__":
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    main()

#   last = self.get_last_menuitem(self.app_menu) 
#   self.app.set_secondary_activate_target(last)

Here is the line:

subprocess.call("xdotool key alt+F1", shell=True)

This is the error when running the above code:

Traceback (most recent call last):
  File "/home/users/l/j/ljames/workspace/pythontest/src/basic.py", line 57, in <module>
    main()
  File "/home/users/l/j/ljames/workspace/pythontest/src/basic.py", line 19, in main
    indicator.set_menu(build_menu())
  File "/home/users/l/j/ljames/workspace/pythontest/src/basic.py", line 35, in build_menu
    menu_items.connect("activate", menu_items)
TypeError: second argument must be callable

What I'm trying to achieve is to have the Ubuntu Launcher reveal when the indicator is clicked.

Update

I have updated my code sample above to include the lines of the desired action. Sergiy Kolodyazhnyy has indicated in his answer the middle click resolution. I commented the necessary lines at the bottom. Now I'm trying to get the right syntax and position for those lines.

Best Answer

Short answer is that you can't. Clicking on indicator icon only brings up the menu. What can be done is to set the middle (scrollwheel) click ( on touchpads that's right and left click pressed together ), which is done by setting Indicator object's secondary activate target.

Here's an example of something I use within my own launcher-list-indicator on lines 152 and 153:

152         last = self.get_last_menuitem(self.app_menu)
153         self.app.set_secondary_activate_target(last)

When user presses middle click over idicator item, it will activate the specific menu-item without bringing down the menu.

What you also can do as alternative, is to use scroll events, something like that:

86         self.app.connect("scroll-event", self.set_next)
Related Question