44

In 2010 Stefano Palazzo , asked a related question, Putting an arbitrary gtk.Widget into an appindicator.Indicator, and similar one was asked on StackOverflow. In both cases the consensus is that Ubuntu's App Indicators are limited. As Michael Ekstrand put it:

The Application Indicator menu support is based on D-Bus menus, which are limited in what they support - they only support basic menu functionality, not more exotic things such as arbitrary widgets.

However, it contradicts what we see in Bluetooth indicator today, in 2016: it uses toggle switches.

enter image description here

Same could be observed with Ubuntu One indicator from 13.04:

enter image description here

So obviously there is a way. I've studied indicator-bluetooth source code, but it's written in Vala. I,however, work primarily in python, and learning Vala just to rewrite all of my already existing indicators is a bit too much work.

So the core of the question : How can one use Gtk.Widgets, or at the very minimum a toggle switch just like in the Bluetooth indicator, using Python ?

NOTE: I am willing to put bounty on this question to reward an answer which will provide a working example in python. Other languages are not accepted.

  • 6
    Application indicator is limited even does not support icon on the fly (it just loads image file from filesystem). Those indicators you have mentioned are SYSTEM indicators (bluetooth, ubuntu one, sound, power ,...). They are different and they are not using libappindicator. I have already posted few posts that may help clarify the difference . I already got a system indicator working using C. but in python i'm still struggling. – user.dz Oct 3 '16 at 8:57
  • 2
    Is there a way to attract the attention of the Ubuntu core devs to this question? – don.joey Oct 4 '16 at 11:55
  • 1
    At least test = Gtk.CheckMenuItem("Monkey") works adding a checkbutton, but there should be more. While that one works, this one should work, but doesn't: Gtk.CheckMenuItemToggled("Monkey"). I am pretty sure it can work anyhow. See: developer.gnome.org/gtk3/stable/GtkCheckMenuItem.html – Jacob Vlijm Oct 8 '16 at 17:11
  • 1
    @JacobVlijm yes, adding any single menuitem works, it also works to add a Gtk.Box and add Gtk.Label to that box, but nothing else( it says the widget can contain only one item. – Sergiy Kolodyazhnyy Oct 8 '16 at 17:21
  • 1
    Gtk.ImageMenuItem is deprecated and discouraged to use btw: developer.gnome.org/gtkmm/stable/deprecated.html – Jacob Vlijm Oct 9 '16 at 7:56
1

This problem exists because while AppIndicators make it easy to create an indicator menu, they do get in the way of making one. Let's look at the differences between example python code using AppIndicator and one using GLib Menus the way the Bluetooth code does.

Firstly you're instructed to make a gtk.Menu, these are old style Gtk menu objects that use Gtk.Action that are now deprecated. AppIndicator takes the gtk.Menu object from you during the set_menu(...) process and parses it, pushing each of the menus it finds onto the indicator service created using libdbusmenu. This process of parsing means that anything not supported by AppIndicator is filtered out, no matter what you do.

Next let's look at the Bluetooth menu. That's created using Gio.Menu objects, these are new style Gnome menus using the GAction system. It then registered it's own service without using AppIndicator or libdbusmenu and set's it's up using a custom x-canonical-type property to create the switch widget which is passed to libido for parsing.

This whole exercise is pretty bad, since it's all Canonical's own Unity customisations. So as soon as unity goes, there's no appindicators anyway.

protected by David Foerster May 3 '17 at 17:29

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.