How to Write a Window Manager in Python

Window Manager of Your Dreams

I wrote a few months ago about a bunch of different window managers which I’d investigated. In this post, I’ll present the source code for a new, very basic, window manager written entirely in Python. My purpose was to make the window manager as simple as possible so that you can play with the code and turn it into the window manager of your dreams!

What it Does

This window manager only does a few things:

if you press Mod1+Enter, a new xterm will be opened (Mod1 normally means Alt);

if you right-click on a window, that window will be raised to the top; and

if you right-click on a window then drag, you will move that window.

This was the simplest useful window manager I could imagine.

Dependencies

In order to run this code, you’ll need:

Python 2.6 or 2.7

The Xlib module for Python (the python-xlib package in Debian/Ubuntu)

For testing, I also recommend you get Xephyr (xserver-xephyr package).

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 window manager here (zipped Python file, ~260 lines of code including comments).

For more background information on writing and testing a window manager, read on.

How I Figured it Out

Reference Material: PLWM

In order to get this far, I had to play around for a while with the Pointless Window Manager (PLWM). PLWM is a window manager framework written in Python, and hasn’t been touched since 2004. It was the best Python example WM I could find to play with because it neither requires you to compile the old versions of a whole bunch of libraries (as PyWM does), nor does it require you to compile versions of libraries newer than those currently shipped with Ubuntu (as Qtile does). It relies only on the Python X Library which is easy to come by.

PLWM has an interesting design, and as you dive into the source code, it’s worth reading the documentation or you risk getting rather confused. It’s also worth noting that the PLWM source code uses some incantations which have fallen out of fashion since PLWM was last updated in 2004 (mostly because newer versions of Python introduce easier or clearer ways of doing things).

I spent a bit of time trying to write a PLWM configuration that I liked, and several times I became so frustrated that I put it to one side. Finally, using PLWM as a reference, I decided to write the simple window manager you saw above.

Another Reference: Disowning a Child Process in Python

While I’m mentioning the reference material I used, I should point out that I looked at a recipe on ActiveState to help me figure out how to disown the child xterms that are created when you press Alt+Enter. The system() method in the code above executes a command as a detached process with no controlling terminal and stdin, stdout and stderr all connected to /dev/null. I basically took the recipe for creating a daemon and used it with some extra exception handling and an execve() call after daemonising.

Debugging a Window Manager

Debugging with Xephyr

When debugging a window manager, I found Xephyr to be very useful. Basically, Xephyr creates a new X display that’s nested inside your current display. So you can make your window manager manage the Xephyr display while you’re still working with your gnome/kde/i3 window manager, and not be afraid of dire consequences if your test window manager crashes.

I use it by starting Xephyr on display 1.

$ Xephyr -screen 1024x768 -br :1

Then in another terminal I start my window manager on the same display.

$ DISPLAY=:1 python simplewm.py

Running Multiple X Servers

If you don’t want to use Xephyr, a trick that I learnt from Linux Journal is to run a second x-server so that Ctrl+Alt+F7 displays your usual WM, and Ctrl+Alt+F8 displays your WM under test. To start a new X server on display 1 with simplewm as the window manager, go to one of the ttys (Ctrl+Alt+F1) and type:

$ xinit /usr/bin/python simplewm.py -- :1

Conclusion

This article should give you a starting point so you can get working on your own custom window manager written in Python. What are you waiting for?