Meditation on Xmonad

December 15th, 2009

Ignorance is the root of all suffering – ignorance about reality, about what is. By holding wrong assumptions, we create false expectations and false needs. [0]

I will not reflect on large parts of reality, but only a small one: window managers (WM). [1]

The most basic ignorance about WMs is the ignorance about their existence. The computer does not just show data to us, but it can show it to us in any way we want. It is this basic understanding that leads to the first conclusion: If the way data is shown to us is lacking, it is not our fault, but the computer is not doing it’s job properly. Furthermore, if we have to spend a lot of time just telling the computer how we would like to see something, we are actually doing someone (or rather, something) else’s work.

Therefore, tiling WMs. If you arrange your own windows, why are you using a WM at all? Wouldn’t it be more honest, instead of saying “I’m running Windows / KDE / OS X to show my windows”, to admit “Windows / KDE / OS X is running me to show it’s windows.”? Sure, the computer can not read your mind and some occassional hints might be necessary, but the less work you do, the better.

Desire creates suffering. This is maybe the most misunderstood of Buddhist truthes. People hear “desire creates suffering” and think “What? Is this going to be a moral how material possesions are bad for me? Money, cars, houses and so on lead to greed, obsession, and so on. I get it.”. This is not what this is about. The problem with desire is not the desire itself. It is not a problem that we want to be happy, to be rich and so on. The problem is, instead, that what we want is impossible. Our desires fail us. We are mistaken about the nature of reality and expect the wrong things. We think that money could make us happier, so we want more of it, but it ultimately won’t. From wrong assumptions you can only get bad results.

In retrospect, I can see this clearly now on my journey to a better window manager. It was my unwillingness to let go of old habits, my wrong ideas about what I really need or want, that made adopting a new WM hard. So I went first to WMs that offered great configuralibity and many features. “You can do anything you want!” But this lead to useless features and distractions. It is only now that most WMs fail me because my hardware setup is a bit tricky, that I can understand. Only now when I understand better what my brain really needs, do I grow tired of those full of bad design.

Xmonad, in a way, is peace for me. It is mathematical in nature. The fact that it is written in Haskell might seem like a gimmick at first, but the connection is in fact very deep. I understand now that it could not have been written in anything else. Xmonad exemplifies the idea of purely functional programming. “Normal” programming is almost always imperative – the programmer tells the computer how to do something. But in functional programming, the hacker instead tells the computer what something is. This is a profound difference.[3]

In any other customizable WM I have ever used, I would create a complex configuration to tell it exactly what I wanted it to do in some case or another. I would do the bulk of the lifting, so to speak, either by constantly adjusting the windows the WM handled wrong or by writing elaborate procedures to automate this work. But with Xmonad, this is different. It is not my job to figure out how to arrange windows, so I should never have to tell my WM anything about this. The only thing I ever have to tell it is about what is. I should never write something like “to go to the next tag, you read in all tags, sort them, filter some out, find the current one and then shift to the next in the list”. I instead write: “I want the next non-empty, non-visible tag now”. I give Xmonad a few simple hints and that is it. “If it’s name is in this list, I want it floating. If I’m currently out of space here, try a different screen. There is a status bar I’m running, so be careful not to overlap it.”

For the first time, I feel like my WM is actually intelligent and wants to help me. It is not my slave, not my servant who follows my orders. It does not look down on me, thinking itself smarter than me, only an obstactle to its flawless performance. Instead, Xmonad is my friend. It understands window handling and can take care of it. I only tell it some personal preferences. If it doesn’t think I need something, it is probably right.

It is astonishing how easily we pick up delusions. We see something once and think it should always be that way. Rarely do we question “Is this really necessary? Is there no other way?”

For me, those are some of the delusions that clouded my judgement about WMs.

“I need space! I want to see my desktop wallpaper!” What for? Have I not something better to do than to stare at pretty pictures?

“I want to tell my WM what window is in the foreground and what in the background.” The very concept is wrong. There is no “foreground” with focus – you either see something or you don’t. A window you can not read might as well not be there at all.

“I understand now, I use a tiling WM. But I want to control what window is where!” Why? The very idea of a tiling WM is that the WM figures out what to show you and how. You simply tell it what application has your focus right now and what other applications belong to it (by giving them all the same tag / workspace).

“Xmonad has no stacked layout like wmii! I can not easily put dozens of windows in one column!” Why would you do this in the first place? You certainly can not read them all. Let Xmonad only show you the ones that matter and search for other ones if you need them. Or think about grouping them better. Why open 20 PDFs in separate windows if your viewer can take care of that?

“Xmonad has no title bars.[4] I will miss those!” Are you sure? What do you use them for? The window content itself tells you what the window is. If the content is not visible, then a title bar will only waste space. If you need to find something, let the WM do it for you. If you want status reports, use notifications.

By embracing not complexity, but simplicity, confusion ends. The best solution to a problem is to make it obsolete – as Gordon Bells said, “The cheapest, fastest, and most reliable components are those that aren’t there.”. By concentrating not on “how”, but on “what”, false desires disappear. By letting go off false desires, suffering ends.

guru

[0] Yeah, I have been reading Buddhist philosophy and history again. Can you tell?
[1] The old monks have understood one thing: Truths about reality must be visible everywhere. There can not be any aspect of reality that is not permeated by them. Thus, we can improve our efforts by just focusing on one simple object. Traditionally, one’s breath, a candle or a rock have served this purpose. Some Zen traditions use 只管打坐 (shikantaza, “simply correct sitting”) for this. If you can’t understand reality just by sitting down and concentrating, then reality can’t be understood at all.  Therefore we must be able to see all those Buddhist observations in everything we use, including the most fundamental GUI software – our window manager.
[2] I will focus exclusively on *nix. There are tiling WMs for Windows, OS X etc., but they are all very lacking.
[3] The classical example to demonstrate this is Quicksort. If you have ever programmed something, Quicksort was probably among it, but just to help you remember, I’m gonna tell you again what Quicksort is. We define Quicksort recursively like so: An empty sort is always sorted. To sort a list with at least one element, we take the first element (called the pivot) in the list and then separate the rest into two lists, one containing all the elements that are smaller and one containing all that are larger than the pivot. Now, to get the sorted result, we simply sort the first list, than add the pivot and finally add the sorted second list. Think about how you would solve this in an imperative language. In C, it would go something like this:

void swap(int *a, int *b)
{
  int t=*a; *a=*b; *b=t;
}
void sort(int arr[], int beg, int end)
{
  if (end > beg + 1) {
    int piv = arr[beg], l = beg + 1, r = end;
    while (l < r) {
      if (arr[l] <= piv)
        l++;
      else
        swap(&arr[l], &arr[--r]);
    }
    swap(&arr[--l], &arr[beg]);
    sort(arr, beg, l);
    sort(arr, r, end);
  }
}

This is a typical example – we tell the computer exactly what to do to get the result we are interested in. But remember I said that in a functional language, we tell the computer what something is. I already told you what Quicksort is, so let’s write this down in Haskell:

qsort [] = []
qsort (x:xs) = qsort lesser ++ [x] ++ qsort greater
     where lesser  = [y | y <- xs, y < x]
           greater = [y | y <- xs, y >= x]

And that’s it.
[4]Technically, you can add them, but they are not normally there.

3 responses

  1. Leo comments:

    I disagree that anyone can get an optimal workflow just by letting xmonad take care of managing windows, without an advanced configuration. Example: I work with an application that does not do tabbing. In a working session, I have, typically, 3-6 windows, and I often switch between them, and I usually want to have only two or three of them displayed — otherwise the windows are too small. Built-in xmonad layouts fail to make this convenient. Tiled layouts make everything too small. Full or tabbed only show one window at at time. Two-pane makes it very hard to intuitively select windows. The root of the problem is that xmonad fails to deal well with layouts that hide windows, and this is a big oversight. I have hacked out a configuration using CombineTwoP, but it’s a dirty hack, it has glitches, and many layouts don’t work very well within a combination.

  2. muflax comments:

    It’s true that hiding windows doesn’t work particularly well in xmonad. wmii has max-stack, which I often used for a column full of PDFs or similar things. I thought at first I would need something like this and was considering using ion3 or awesome (which had tabbing at some point), but they are so full of weird and inelegant design that I gave xmonad a chance anyway.

    What particular application are you talking about here?

    Right now, I don’t miss a tabbing layout at all. Documents, images and websites can be tabbed (through screen, tabbed or whatever viewer I’m using). I can’t actually think of any problem I’d work on that would require me to hide windows on a regular basis. The only task where I even use more than 2 or 3 windows at the same time is debugging. Maybe it’s just a question of space? Tiling WMs need quite large (or multiple) monitors, so maybe that’s an issue? But then again I’ve been using a single 15 inch 1024×768 CRT for ages and really got used it, so having 6 or 8 terminals open on a single screen doesn’t bother me at all.

  3. Leo comments:

    http://img42.yfrog.com/img42/1830/screenshot1tt.png

    There’s a screenshot of one workspace. The application in question is Mathematica. The layout is CombineTwoP with Tall on the left and Tabbed on the right. This solution works, with certain kinks:
    – standard keybindings you use to move windows around in tiled layouts don’t work, you have define additional keys
    – you can’t resize the split in the tiled pane on the left, nor can you easily swap the top and the bottom windows on the left
    – sometimes the tab focus goes haywire in the right pane (obviously a bug of some variety)
    – tabbed layouts in general don’t play well with a floating scratchpad (which I also use); in fact they are almost unusable unless a dirty hack is applied:
    http://article.gmane.org/gmane.comp.lang.haskell.xmonad/7966

    One can rave about xmonad’s minimalism all they want, but sometimes the default behavior gets in the way of having a usable system.

Leave a comment