This Blog continues on

Monday, November 05, 2007

Desktop Widgets with PyGTK, Launchpad Remote Control

Desktop Widgets with PyGTK, Launchpad Remote Control

We shall today be looking at a dumb hack I glanced upon while foolishly
reading the list of GDK Constants in the PyGTK documentation. This hack sets
the type hint of a GTK Window instance (the thing that tells the window
manager how to treat it) as a desktop window, and hence embeds the thing in
the desktop.

It even works quite well:

  • The window and widgets appear in the desktop

  • The widgets are raised when the "Show desktop" command happens

  • The widgets appear on all desktops (in Gnome and XFCE4, but not in KDE)

  • The widgets appear fully functional

So I got all excited and tried to think of an awesome use-case as the first
plugin for a new kind of desktop widget framework. One which couldn't care
less about eye-candy, and focussed on truly functional and useful
desktop-based applets. As a friend commented while I was discussing the idea:
"I am often hacking away in emacs when I decide that I want to know what the
weather is like, but I am too lazy to look out the window, so I use my weather

And that is the point, these desklet things are absolutely useless in my
opinion. I thought and thought and I came up with a handful of barely useful
things, which are too dumb to even mention. I would be grateful if anyone has
any ideas.

Maybe I am the problem. I don't use a desktop at all. I turn the feature off
in XFCE4 (my preferred desktop environment) and don't have to suffer icons and
right click and things like this. (Incidentally the hack works on noremal
desktops, even preserving the original desktop functionality - so you can
click on icons and see the weather at the same time.

So my lack of real-world use-case discouraged me from attempting the
framework. But I would feel bad not to mention it here at least.

A nice simple thought was to use Malone's XMLRPC to read any numbered bug from
the launchpad and display it on the desktop. As I say this isn't a real world
application, since you would just fire up a browser. And then I realised that
you can only use the Malone XMLRPC for filing bugs.

So I guess it will be a less pleasant thing that just opens your browser at
the bug page. Hopefully Launchpad will add simple things like this to the API
sooner rather than later.

So, on to the process:

First let's get the Launchpad bit out of the way


# Python standard library module that does portable web-browser opening
import webbrowser
# You could make the product optional

def navigate_bug(number):
Open the web browser at the required URL
url = BASE_URL % number
Now we can concentrate on the more interesting desktop embedding

import gtk
# Create the user interface for the application
class BugEntry(object):
A miniature user interface for entering a bug number.
def __init__(self):
# an entry, a button, and a box to put them in
hb = gtk.HBox()
self.entry = gtk.Entry()
button = gtk.Button(stock=gtk.STOCK_OK)
hb.pack_start(button, expand=False)

# Connect a signal callback for the button
button.connect('clicked', self.on_button_clicked)

# A window to hold it all
self.window = gtk.Window()

# Set the type hint on the window to make the window manager think it
# is a desktop

# Don't forget to size and move your window where you want it
self.window.move(100, 100)
# If you wan to resize it: self.window.resize(x, y)

def on_button_clicked(self, button):
Called when the button is clicked
# A sane implementation would catch errors in the conversion,
# But we just call the web browser launcher function:

if __name__ == '__main__':
# Instantiate the interface, and run the gtk main loop
be = BugEntry()
Ok it looks really ugly, but you can see the promise there, The main thing is
that it really really works.

If anyone can think of a decent thing to do with this, please let me know!