... finally I'm tiling too!

Short story: I've just switched to xmonad as my window manager of choice within a Gnome desktop environment; I give some tips on how to achieve that quickly on a current Debian/unstable machine.

/me and tiling window managers

I switched to Gnome a long time ago. The benefit of that over good old window managers is enjoying an integrated environment and a workplace that you can find on other machines (e.g., the netbook you installed for your mother, the office desktop, the student lab machines, ...). Still, I've never been particularly happy about Gnome's default window manager: metacity. The feature I was missing the most is the ability to configure windows programmatically so that they appear where and how I want by default; sadly enough, the Gnome session mechanism is not yet able to do that properly.

Hence, I've tried various time switching to a tiling window manager, imposing the extra requirement that it should integrate with Gnome. The coolest guy on the block of that area seems to be awesome and I gave it a try some months ago. I liked most of its (sometime revolutionary) principles, like window tagging, but I equally hated various aspects of it:

  • Documentation back then was horrible, starting from the manpage speaking of mod{1,2,3,4,5} without giving a hint about where the heck they are mapped to by default, ranging to the lack of references manual about what you can call from LUA configuration files. ... use the source, Luke ...

  • Community was mainly composed by super-users, which is good if you want to do some super-configuration. ... but is deeply bad™ if you are trying to get hints on how to make awesome cope with Gnome. I remember having been treated as a total luser on IRC, with people more interested in convincing me that I should stop using Gnome than in helping out achieving what I wanted to.

People nowadays tell me that awesome works fine with Gnome, so maybe I've just been unlucky back then, but sometime the first impression does count.

I've never considered seriously xmonad, thinking (with no sound reason, apparently) that it was a project of the series: "I'm a fan of programming language $LANG, all my apps should be written in $LANG, my window manager is no exception", with LANG=haskell.

Then two things happened:

  1. a couple of weeks ago I stumbled upon the xmonad wiki and documentation, and I was impressed by the average quality of the information shipped there. It is not something you usually find in "language showcase" projects.

  2. Patrick blogged about its switch to xmonad + Gnome, with enthusiastic feedback. If that's not a sign I don't know what it can be :-)

Getting started with xmonad + Gnome on Debian

There is a page explaining how to use xmonad with Gnome in the xmonad wiki, but a handful of additional tips will help you get started in Debian, even if you know (almost) nothing about Haskell (yet).

  • You should install packages xmonad and libghc6-xmonad-dev. Without the latter you will not be able to configure your xmonad; in particular you will not have access to the Gnome configuration library, which offers sane defaults for using xmonad with Gnome. (See below for a rant on the disk usage of installing the second package ...)

The (crazy) way in which xmonad works is that you create your config file as ~/.xmonad/xmonad.hs. That file is a full fledged Haskell program, which gets compiled to obtain your own xmonad executable which you run as your own window manager. /usr/bin/xmonad is the executable you initially run, but is just a wrapper around the compilation + run mechanism

  • Since you have installed libghc6-xmonad-dev, you have access to a module pre-configuring xmonad for Gnome, just use the following as your starting xmonad.hs:

      import XMonad
      import XMonad.Config.Gnome
      main = xmonad $ gnomeConfig {
               modMask = mod4Mask

The modMask setting means that ALT will get delivered to applications, while all xmonad commands are delivered via the infamous windows key: no more conflicts between apps and WM \o/.

  • At this point you can configure xmonad as your Gnome window manager. Disable re-spawning of metacity in your session option, and run somewhere killall metacity ; xmonad & . For the next session runs you will have to remember the running xmonad in your Gnome session, as usual.

The default Gnome configuration is quite nice: you can retain your Nautilus desktop (in spite of what is written on the wiki), mod-p will get you a gnome-run dialog box, and appropriate padding for the (upper!) Gnome panel.

The only glitch is that you will get 9 desktops which can clutter your workspace switched. My solution is to have the appler show workspaces on 2 rows but beware of bug 524065, which is really annoying.

  • Compositing works as well, by the means of xcompmgr. Just install it and register in your session the result of running xcompmgr -c &. No wonder that it is way faster than compositing manager support in metacity.

  • Finally, you can configure window placement in your xmonad.hs by doing something like the following (it already includes the shorter snippet given before):

      import XMonad
      import XMonad.Config.Gnome
      myManageHook = composeAll [
                      (className =? "Pidgin" <&&> title =? "Buddy List") --> doFloat
                     , (className =? "Gnome-panel" <&&> title =? "Run Application") --> doFloat
                     -- , (className =? "XEyes") --> doShift "7"
      main = xmonad $ gnomeConfig {
               modMask = mod4Mask
             , manageHook = myManageHook <+> manageHook gnomeConfig

The above example will make the pidgin buddy list and run application dialog box float by default. The commented line is an example of how to deliver specific windows to arbitrary workspaces. To find out window properties on which match in your xmonad.hs, my magic command is xprop | egrep "CLASS|NAME".

Note that you don't need to care about panel placement because it is already taken care of by the default gnome config. Still beware of not using myManageHook as your only management hook, you should update the default one using the <+> monad as I did above.

xmonad rant

So, what's wrong with xmonad + Gnome in Debian? Well, the fact that it will take about 200 Mb of disk space on amd64 by default. o_O

Why so? Because xmonad is affected by the static linking hell which seems to be shared by modern statically typed functional languages, including in the category both Haskell and my beloved OCaml. In short, applications written for those language link statically code written in the implementation language in most cases; they rely on legacy shared libraries only for bindings to C libraries.

For xmonad that means that if you are fine with the default configuration you will get a cheap 2 Mb binary package. If you are not, you will need to write your conffile ... which is a Haskell program ... using several contrib libraries ... and needing ghc6 to be compiled and run as your own window manager executable.

This is plainly dumb and induces all the usual problems of static linking, like disk consumption due to non-shared (Haskell) code, and worries about staying up to date with the latest library release in case of fixes (including security fixes) need to be propagated to user executables.

Truth to be said, /usr/bin/xmonad does a wonderful job in hiding all this to the final user, but still the design choice is an unpleasant one.