Python Window Manager, Now With Twisted

And Now for the Big Event Loop

Last week I wrote about how to create a window manager in Python and posted code for a simple example window manager. The example I posted was about 260 lines long including comments. But if you want to write a window manager to suit your needs, it will quickly get bigger and more complicated. Last week, my event-handling code looked like this:

def handle_event(self):
    '''
    Wait for the next event and handle it.
    '''
    try:
        event = self.display.next_event()
    except Xlib.error.ConnectionClosedError:
        print >> sys.stderr, 'Display connection closed by server'
        raise KeyboardInterrupt

    if event.type in self.event_dispatch_table:
        handler = self.event_dispatch_table[event.type]
        handler(event)
    else:
        print 'unhandled event: {event}'.format(event=event)

The most important line is the call to self.display.next_event(). This next_event() function blocks until the next X event is received. But as your window manager gets more complicated, you’ll want to create your own events internal to the window manager, and you might event want to do something periodically (like updating a clock in the corner of your screen).

Before long, you’ll need to replace this one call to self.display.next_event() with something bigger and better and, well, bigger. To give a bit of perspective, the next_event() method in the Pointless Window Manager is 179 lines long.

Let me suggest an alternative to writing your own event loop.

Adding Twisted to the Equation

Twisted is an event driven Python framework primarily designed for networking. It comes complete with asynchronous scheduling and deferred tasks (Twisted provided the inspiration for the deferreds in MochiKit and Dojo). Since I’m already intimately familiar with Twisted because we use it for Trosnoth, it makes sense to let Twisted run the event loop for my window manager.

It turns out it’s not too difficult to use the Twisted reactor as my event loop. Display objects in python-xlib provide access to the file descriptor of the underlying socket, and Twisted’s default reactor provides a method for registering an object to be notified when a file descriptor is ready for reading.  Read on to get a copy of the actual code.

Dependencies

As with last week, you’ll need Python 2.6 or 2.7 and the Xlib module for Python. This week you’ll also need Twisted installed.

Download the Code

I hereby release the following source code into the public domain. You may download, modify, use or redistribute it freely. You can download this simple Twisted window manager here (zipped Python file, ~280 lines of code including comments).

If you’re planning on writing your own window manager, I recommend reading my debugging tips at the end of last week’s post.

This entry was posted in midlength and tagged , , , , , . Bookmark the permalink.

Comments are closed.