Whimsy is a free, small, highly hackable window manager written in Python.
It's currently around 1000 lines SLOC (physical source lines of code, according to sloccount) and supports a tiny bit of the Extended Window Manager Hints (EWMH) spec.
Most window managers are written in C or C++ and bend over backwards to implement config files, or IPC with pipes/sockets, or other contrived schemes to essentially try and add some flexibility to a static, compiled language. Why reinvent all that for the thousandth time? Using a dynamic language like Python cuts out a lot of junk that's just not essential to the task of managing windows. It's also much more flexible—which is my main goal—and plenty fast enough as well.
Whimsy is entirely written in Python. There are no funky Python-to-C bridges or wrappers or anything of that nature. It uses python-xlib to communicate with the X server. python-xlib is also written in pure Python.
$ wget http://incise.org/files/dev/whimsy-0.1a1.tgz
$ tar zxvf whimsy-0.1a1.tgz
$ sh whimsy-0.1a1/fetch-python-xlib.sh
$ mv Xlib whimsy-0.1a1/
$ export PYTHONPATH="$PWD/whimsy-0.1a1:$PYTHONPATH"
$ python whimsy-0.1a1/config.py
If you have a window manager running, then you'll get an exception saying so. You will need to kill your window manager and/or start up a new X server and/or edit your .xinitrc or .xsession file. Due to its early stage of development, I do not recommend using whimsy as the final blocking command in your .xinitrc or .xsession, as this will cause your whole X session to die if whimsy does. What I would do is put this in its place:
while true; do sleep 1000000; done
That way, when X starts up, you'll be greeted with a terminal with which to start whimsy (python path/to/whimsy-0.1a1/config.py), and your X session will run forever.
As you can see, you actually run your config file. In that sense, whimsy is almost a library or toolkit, and your config file is a little script that uses it. As long as you keep the top level whimsy directory in your PYTHONPATH, you can put your config script anywhere and call it anything. It will just need to import whimsy.base_config. You can also check out my personal config script, example_config.py, and run it like this:
$ python whimsy/example_config.py
Running it inside of screen is a decent idea, so if it crashes you can switch to a virtual console and re-attach and see what went wrong and start it up again.
You could also install python-xlib via your package manager, although Whimsy is developed against python-xlib's svn trunk so you could potentially have compatability problems with older versions of python-xlib.
The most important things you will need to know are:
* Alt+left click will move a window
* Alt+right click will resize a window
* Ctrl+Alt+X will open an xterm
Beyond that, you can view the default key/mouse bindings in config.py. My own personal config file is example_config.py.
There are no window borders/decorations. There is support for viewports/large desktops, which are basically like virtual desktops, but are "physically" linked in that a window hanging off of one will show up partially in the next, instead of each desktop being its own isolated little world. (Desktops are implemented by hiding/showing windows. Viewports are implemented by moving all windows over by one screen's-width or screen's-height.) There aren't many window management operations implemented other than the basics: moving, resizing, closing, raising, lowering.
Whimsy is built in a somewhat decentralized, indirect way. The main point of a window manager, especially one that you want to customize, is to decide what to do with X events, and then do it. All of this decision-making and execution of actions is kept largely decoupled from the core of the window manager. It's essentially an implementation of MVC using the observer pattern, with a single "publisher" object, which is called the hub.
Right now the only models are the window manager and the client.
The tick controller is dead simple and simply sends out tick signals (through the hub, to whoever wants to receive them) in an almost-endless loop. Some handlers for things like SIGINT call its stop method which will abort the endless loop at the end of the current iteration and allow for a clean shutdown and exit.
The X event controller responds to tick signals and checks for new X events. It then sends out its own signal when it finds an event. Event handlers can in turn listen for that signal and do whatever they want to handle the event.
Actions are the callbacks that actually implement the desired functionality to handle events.
Filters inspect events and return a boolean indicating whether the event meets certain conditions, such as certain keyboard state, or what type of window is involved.
I think that the X server could probably be considered the view. MVC can be confusing. I don't take it too seriously.