6

How to make a submenu in a dynamic quicklist (of dbusMenuItems) in python?

The official documentation is very scarce: https://wiki.ubuntu.com/Unity/LauncherAPI

Here is my minimal coding example: dbus_snippet.py

    #!/usr/bin/env python
    from gi.repository import Unity, Gio, GObject, Dbusmenu
    import os
    import subprocess

    launchers = []
    qlList = []

    #(not all references are links due to askubuntu's reputation-system)
    #askubuntu "how-to-add-checkbox-or-radio-buttons-to-a-unity-quicklist"
    #https://lazka.github.io/pgi-docs/Dbusmenu-0.4/classes/Menuitem.html#Dbusmenu.Menuitem

    #(project that this research may go into)
    #(github thirschbuechler/ubuntu-recentquicklists)


    def check_item_activated_callback (menuitem, a, b):#for the submenu
        if menuitem.property_get_int (Dbusmenu.MENUITEM_PROP_TOGGLE_STATE) == Dbusmenu.MENUITEM_TOGGLE_STATE_CHECKED:
           menuitem.property_set_int (Dbusmenu.MENUITEM_PROP_TOGGLE_STATE, Dbusmenu.MENUITEM_TOGGLE_STATE_UNCHECKED)
        else:
           menuitem.property_set_int (Dbusmenu.MENUITEM_PROP_TOGGLE_STATE, Dbusmenu.MENUITEM_TOGGLE_STATE_CHECKED)

    def check_item_activated(menuitem, a, arg):#main menu item
        process = subprocess.Popen("gedit ",shell=True)

    def createItem(name, arg, qlnummer):
        item = Dbusmenu.Menuitem.new()
        item.property_set (Dbusmenu.MENUITEM_PROP_LABEL, name)
        item.property_set_bool (Dbusmenu.MENUITEM_PROP_VISIBLE, True)
        item.connect("item-activated", check_item_activated,arg)
        check1 = Dbusmenu.Menuitem.new ()
        check1.property_set (Dbusmenu.MENUITEM_PROP_LABEL, "Checkbox")
        check1.property_set (Dbusmenu.MENUITEM_PROP_TOGGLE_TYPE, Dbusmenu.MENUITEM_TOGGLE_CHECK)
        check1.property_set_int (Dbusmenu.MENUITEM_PROP_TOGGLE_STATE, Dbusmenu.MENUITEM_TOGGLE_STATE_CHECKED)
        check1.property_set_bool (Dbusmenu.MENUITEM_PROP_VISIBLE, True)
        check1.property_set (Dbusmenu.MENUITEM_PROP_CHILD_DISPLAY, Dbusmenu.MENUITEM_CHILD_DISPLAY_SUBMENU)
        #check1.property_set (Dbusmenu.MENUITEM_PROP_CHILD_DISPLAY,  'children-display')
        #https://lazka.github.io/pgi-docs/Dbusmenu-0.4/constants.html#Dbusmenu.MENUITEM_CHILD_DISPLAY_SUBMENU

        check1.connect (Dbusmenu.MENUITEM_SIGNAL_ITEM_ACTIVATED, check_item_activated_callback, None)
        item.child_append(check1)   

        qlList[qlnummer].child_append(item) 



    def update(a=None):
        #delete old ones 
        for i in range(len(qlList)):
            for c in qlList[i].get_children():
                qlList[i].child_delete(c)

    def main():

        launchers.append(Unity.LauncherEntry.get_for_desktop_id ("nautilus.desktop"))
        launchers.append(Unity.LauncherEntry.get_for_desktop_id ("nemo.desktop"))


        for i in range(len(launchers)):
            qli = Dbusmenu.Menuitem.new()
            qlList.append(qli)


        update()

        for i in range(len(launchers)):
            createItem("item1","arg1",i)
            launchers[i].set_property("quicklist", qlList[i])

        loop = GObject.MainLoop()

        loop.run()

    main()

What do I mean by submenu (made in gimp): enter image description here

Why do I think this is even possible? An option called Dbusmenu.MENUITEM_PROP_CHILD_DISPLAY, reads "have the subitems displayed as a submenu" sounds awfully close to what I want to do, but I've failed to archive that. The above snippet adds a dbus-item to another one, and sets the submenu-property (on the Nemo/Nautilus launcher)

(Bonus: I haven't found anything to make check_item_activated distinguish rightclick, leftclick and middle-mouse-button, but prove me wrong)

7
  • QuickLists don't have submenus and I've not seen it being done. Have you considered making an indicator ? It is possible to have q menu with submenus, even dynamically made. Sep 13, 2016 at 22:15
  • Yes, you are right, an indicator would be an option, technically. However, mye goal is to simulate Windows' ability to pin recent files to quicklaunch items, without resorting to two user interfaces which are phyiscally apart (quicklaunch and appindicator). I've updated my question to reflect my starting point with "Dbusmenu.MENUITEM_PROP_CHILD_DISPLAY"
    – hirsch
    Sep 14, 2016 at 5:41
  • Something like this has been done already : askubuntu.com/a/747787/295286 Sep 14, 2016 at 5:44
  • This is incorrect, my question about submenus isn't answered there. Regarding the underlying project: Yeah, but only for Libreoffice, as far as I can see. Mine already automatically gets ALL THE FILES for ALL THE LAUNCHERS :)
    – hirsch
    Sep 14, 2016 at 5:48
  • 3
    I've put a bounty on this question. It expires within one week from today. If you see an answer here that fits your requirement, let me know and I'll award bounty to that post Sep 16, 2016 at 3:20

1 Answer 1

0

I don't know how to do this with dbus but ....

You can just do this by editing .desktop files , the changes are automatically picked up. It should be simple enough to write a class to write or edit .desktop files in ~/.local/share/applications/

The launcher needs an Action line where the quicklist names are defined , for each of the names you need a [Desktop Action name] block which contains Name and Exec lines. Its documented in your link.

You can only go one level deep as far as i'm aware and i've not managed to add anything but launchers to the quicklist.

This has the benefit of ensuring that the menus are available after your program exits and on reboot.

Heres an example that lists various hosts as submenu items from the gnome-terminal icon.

[Desktop Entry]
Name=Terminal
Comment=Use the command line
Keywords=shell;prompt;command;commandline;
TryExec=gnome-terminal
Exec=gnome-terminal
Icon=utilities-terminal
Type=Application
X-GNOME-DocPath=gnome-terminal/index.html
X-GNOME-Bugzilla-Version=3.16.2
Categories=GNOME;GTK;System;TerminalEmulator;
StartupNotify=true
X-GNOME-SingleWindow=false
OnlyShowIn=GNOME;Unity;
Actions=New;host1;host2
X-Ubuntu-Gettext-Domain=gnome-terminal

[Desktop Action New]
Name=New Terminal
Exec=gnome-terminal
OnlyShowIn=Unity

[Desktop Action host1]
Name=SSH to HOST1
Exec=gnome-terminal -e 'ssh host1' -t 'SSH to host1'
OnlyShowIn=Unity

[Desktop Action host2]
Name=SSH to HOST2
Exec=gnome-terminal -e 'ssh host2' -t 'SSH to host2'
OnlyShowIn=Unity
7
  • dude, these are not submenus, and it's not in python either (you've said yourself it's static). Submenu = only pops up when you click (or place the cursor on) a menu item. My script can already do menus
    – hirsch
    Sep 16, 2016 at 17:40
  • i have never seen one in unity and have used it daily for many years.
    – Amias
    Sep 18, 2016 at 9:12
  • There is a reason it doesn't distinguish between right and left clicks , pretty sure its because its designed for touch as well as mice. That would also be the reason for not having submenus as they doesn't play nicely with touch like mice do.
    – Amias
    Sep 18, 2016 at 9:16
  • I haven't seen one either, but the interface-defintions hint that it might be possible.. that's kind of the point of the question. Also, I can easily think of examples how an implementation on touch-devices would be possible: A long-press, double-tap, horizontal swipe or the android settings-button (in conjuntion with an ordinary tap) might do the trick (though I am by no means an interface designer)
    – hirsch
    Sep 18, 2016 at 11:47
  • that might be possible on a tightly controlled platform like IOS which has tight hardware specs but with the generic hardware support required here it won't be.
    – Amias
    Sep 18, 2016 at 11:59

You must log in to answer this question.

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