How to add support for the global menu to a python non-gtk, non-qt app?

I'm looking for good documentation (an example, tutorial, or guide) on how to add global menu support to a non-gtk, non-qt application. (In gtk it works 'magically' for the main menu...). The toolkit I want to use this with is kivy, which supports the glib-mainloop (e.g. for gstreamer), so in principle all should work there.

I have seen the API reference of Dbusmenu and here, but that is not very helpful for understanding the mechanisms.

There is a short example for creating a launcher-quicklist which contains a dbus-menu, but not for the global-menu / appmenu.

There is a wiki page that does not contain any relevant information other then "Work on supporting other the application menu on other toolkits would be welcome, but not a priority for the DX team, help wanted."

There is a little information in this graphic from the indicator-appmenu source code, but its not enough, can not be found on developer.ubuntu.com and requires more explanation:

enter image description here

So:

  • What is the procedure that gets a set of menu items (Dbusmenu.Menuitem) to be displayed?
  • What role does the client and the server play? (Which of those is supposed to be run in my application? Or both?)

Similar question


Solution 1:

In general, I'd recommend using the toolkit supported ways to put menus in the global menubar... but, I'm assuming it's too late to convince you at this point :-) Also, I'll note that even thought we're using Dbusmenu and registration in 12.04 the goal is to move to GMenuModel and marking the window with its menus by 14.04, so this information will become dated. Ofcourse, the toolkit plug-ins will be updated ;-) (last time I'll try, I promise)

The basic principle involved is that we need to know what menus are associated with which window. We track the window using its XID and the menus are a path to the Dbusmenu Server on DBus. You'll need both of those pieces of information to register. The registration interface is pretty simple in that you basically pass both of those pieces of information to the registrar. The registrar's well known name on DBus is com.canonical.AppMenu.Registrar.

For an example of how this can work you can look at the mock-json-app sample code that is in indicator-appmenu. This is a small tool that will take the JSON file output by dbusmenu-dumper (which is in libdbusmenu-tools) and make a window that claims to have that menu. It also handles things like the appmenu crashing, which might not be really required for most application (though is really important in development :-) ).

To create a Dbusmenu Server you basically just need to allocate the object and tell it where to appear on DBus (so you can give the location to the registrar). For plugins like appmenu-gtk we use a generated path so that there is no conflict, but if you're controlling the app you can probably use a fixed path. Then you create a tree structure of Dbusmenu Menuitem objects. The root one isn't shown, but is passed to the Dbusmenu Server to start out the menus. The first level bellow the root will be shown as items across the Ubuntu Menubar.

Good luck, thanks to all the people who harassed me to answer this question. I still believe that you should use the toolkit support (I lied about it being the last time), but good luck!