Making panel applets for Gnome 2 and 3

29 Feb 2012


Originally posted at

In recent times, there’s been a lot of changes to the Gnome environment with the 3.x releases, including the introduction of the Gnome Shell and things like the GObject introspection stuff going on in the background. However, the Shell is a bit on the unstable side (even if you’ve got a good graphics card), and so I’ve been sticking with the “fallback” environment which still uses the standard panel layout.

Well, that’s what it looks like at first glance. Once you start digging around, it turns out that the panel you’re now seeing is superficially similar to the old one, but it’s built in a very different way under the hood, and that makes writing applets for it a somewhat different problem. Primary among the changes for the panel is the removal of Bonobo in favour of D-Bus, so we’re going to have to build the services needed for applets in a new way.

Now, if you start looking around the web for guides to making Gnome panel applets, you’ll find two things. a) lots of guides of how to do this in a 2.x environment (e.g. this) but little/no 3.x guides, because of b) that applets are officially deprecated as of 3.x (that, and 2.x has been out since 2002 v.s. 2011 for the 3.0 release). The reason they’re officially deprecated is that we’re all meant to be using the Shell now, which is a very different thing, and so needs to do things in a completely different way. However, I (and I suspect a fair chunk of the world) will be sticking with non-Shell environments for a while yet, so there’s still a need for 3.x panel applets.

Earlier on I noted how the 2.x and 3.x panels were very different things, but despite the major interface changes, your core applet is still going to be the same. In both cases, some form of messaging bus (Bonobo, D-Bus) provides information about what applets are available, and then invokes the launchers for them on demand. For either 2.x or 3.x you’re going to be writing a whole bunch of messaging system boilerplate, when what you really want to be doing is actually writing your own applet!

I’ve therefore written a little boilerplate generator that makes applets that work on both 2.x and 3.x panels. Using Genshi, it generates the Bonobo server files, D-Bus service files, a pair of factory helpers that build either a 2.x or 3.x applet, and then a simple applet stub that you can expand that looks like the following:

It’ll also generate a bunch of Debian package files so you can package up your applet right away. It’ll work straight out of the box, with a little label saying “It works!”, but you can then customise just the applet stub file and it’ll happily continue to work with both 2.x and 3.x. One potential issue is making sure that you’re importing from gi.repository for 3.x and then falling back to the relevant individual modules for 2.x as shown at the top of the applet stub, but otherwise it should be fairly simple to build your applet of choice.

As the interface files need to be hardcoded to a particular path for the applet, the best option for further development is to install the generated package, then make the main applet (/usr/lib/gnome-applets/ a symlink to a version of the file that you can edit. If you then add the applet to your panel, the python process for the factory (called -factory{2,3}.py depending on your panel version) can be killed every time you want to refresh the code (don’t forget to answer yes when the panel asks if you want to reload the applet that just died!). Unfortunately given the process model for panel applets, there aren’t any easier ways to do development, but this works fairly well.

Previously: (Re-)adding a tray icon to Rhythmbox Next: NAntScript, now with added functions