xmonad logo

      xmonad

      a guided tour

Getting started with xmonad

This is a guided tour of the core features of the xmonad window manager, allowing you to gain an understanding of the motivation, and use, of a dynamic tiling window manager, and learn how to achieve the kind of screen configuration you want, simply and easily.

Starting xmonad

We'll assume you've been able to build xmonad from hackage (or from your package system), when starting xmonad directly from your .xsession or .xinitrc file, like so:

    # .xsession

    xrdb -merge .Xresources
    xpmroot ~/background.xpm &

    $HOME/bin/xmonad
    

Note the use of xpmroot to set a background image.

Opening clients

When you start xmonad, without launching clients, you'll be presented with an empty screen:

Let's start some clients, to fill the screen. xmonad uses the mod1 key (alt) by default, and we can start by launching a terminal with mod-shift-return. The new terminal will fill the screen (and we'll use a bit of image postprocessing to contrast the terminals a bit):

Let's open up another terminal mod-shift-return:

The window manager has now tiled the screen such that both windows fit, without overlaps, filling the plane. Note that the new window was inserted to the left of the previous window. What happens if we insert another client? mod-shift-return.

xmonad uses a simple tiling algorithm to tile the windows to fill the screen without gaps, while ensuring space is managed in a reasonable way. xmonad, by default, divides the screen into two `panes', a master pane and a subordinate pane. All windows are then partioned into these two panes. The ratio each pane takes up on the screen is configurable, as are the number of clients in each pane. By convention, one pane is denoted as the `master' pane, and is used to place the largest window. Other tiling algorithms are possible, (for example, fullscreen mode), and in these the concept of a `pane' has no real meaning. The division of the screen into two panes, with a special master pane, is an idea inherited from dwm.

Tiling modes

We can try out the other tiling modes now, with mod-space, which cycles through the available tiling algorithms:

The next mode up is the 'wide' mode, a logical mirror of the initial tiling. This is useful for smaller screens. If we hit mod-space again, we end up in fullscreen mode, where the currently focused window is maximisd:

Other tiling algorithms may be written directly in configuration files.

Moving focus

Let's return now to the original 'tall' tiling, mod-space. We can move focus around with the mouse, or with mod-j and mod-k (which moves the window focus up or down) (coloured red here for emphasis):

We can also increase, or decrease, the number of windows stored in the master pane, with mod-comma and mod-period:

and again mod-comma:

Use mod-period a few times to decrement the master pane count back to 1, to return to the default tiling.

Shuffling window order

Now, let's open up another client, we'll launch glxgears:

We can shuffle the window ordering in three ways: mod-return, mod-shift-j and mod-shift-k. First, let's try mod-return, which swaps the focused window with the window in the master pane:

mod-shift-j (and its inverse, mod-shift-k), swap the currently focused window with its neighbour above or below. This allows us to 'bubblesort' the window ordering, to achieve a desired ordering of windows. Applying mod-shift-j twice:

and we're back where we started.

Resizing clients

We can resize the ratio between the master and subordinate areas with mod-h and mod-l. Hitting mod-h a few times:

Now, let's cycle to wide mode, and shrink (mod-space, then mod-l):

We can return to tall mode by cycling through the tiling modes some more.

Deleting windows

When a window is closed naturally, or using mod-shift-c to kill it, focus is moved to the next window down in the workspace list. Let's kill glxgears. Focus should move to the xterm below it:

To fully quit xmonad, use mod-shift-q to exit X (don't do that now!).

Launching clients from dmenu

Assuming you have installed 'dmenu', you can launch programs from the status bar, by typing a few characters of the program's name. Use mod-p to launch dmenu, and then type 'fir' to find firefox:

After firefox launchs, it is inserted above the focused window:

Now, let's close a terminal, use mod-space to enter wide mode, and mod-return to move firefox ito the master window:

Using other workspaces

xmonad has, by default, 9 virtual workspaces. You can switch between them using mod-1 to mod-9. Switching to workspace 4 mod-4 we find it empty:

Let's open xclock here, using dmenu:

We can now move firefox from workspace 1 this new workspace 4, by first switching back to workspace 1, mod-1, then using mod-shift-4 on firefox's window, to toss it over to #4. This removes firefox from workspace 1, passing focus there to the next window in the list, and view workspace 4, after , looks like:

Workspace 4 is using tall tiling, and workspace 1 is still in wide mode. xmonad allows you to run different tiling modes on each workspace. And that is the core set of window manager operations covered:

  • inserting clients
  • deleting clients
  • moving focus
  • permuting window order
  • resizing the gap
  • viewing workspaces
  • moving clients between workspaces

Configuration

xmonad is written and configured in Haskell. To configure xmonad you edit the source file Config.hs, recompile the application, and dynamically reload xmonad with mod-q.

Let's examine the available configuration options. Looking in Config.hs, we find the following values able to be configured:

  • the number of workspaces
  • the mod key
  • numlock mask
  • default resize increment
  • default number of windows in master pane
  • border width
  • border colours
  • default status bar height

And of course:

  • the keybindings

And, interestingly:

  • the default layout algorithms:

Let's change a couple of values, the border with, and the border colours. Editing Config.hs to look like:

    normalBorderColor  = "#323232"
    focusedBorderColor = "#5FBF77"
    borderWidth        = 10
    

Easy enough. The config file is just Haskell, so you can use any Haskell you wish to mess with it. Let's now recompile the configuration:

    $ runhaskell Setup.lhs build
    Preprocessing executables for xmonad-0.1...
    Building xmonad-0.1...
    ...
    [5 of 6] Compiling Config           ( Config.hs, /usr/obj/cabal/xmonad/xmonad-tmp/Config.o )
    [6 of 6] Compiling Main             ( Main.hs, /usr/obj/cabal/xmonad/xmonad-tmp/Main.o )
    Linking /usr/obj/cabal/xmonad/xmonad ...
    

Ok, it built, and our config changes type checked. Now, let's remove the old xmonad binary, and install the new one:

    $ rm -f `which xmonad`
    $ runhaskell Setup.lhs install
    copy /usr/obj/cabal/xmonad/xmonad to /home/dons/bin/xmonad
    

Now we can use mod-q to restart xmonad, to see our changes reflected in the window manager:

Funky! Since the configuration file is just Haskell, you can use any Haskell modules you wish, to do custom configuration. We have a library of xmonad extensions written by users, available. These include alternate tiling algorithms (such as spiral or mosaic tiling), and custom key bindings. To use these, just download the extension you want, modify your Config.hs to import that module, and reconfigure as above.

Using dzen as a status bar

Tiling is all well and good, but often we want a set of system information and data displayed in some kind of status bar visible at all times. xmonad supports using arbitrary programs as status bars. One particularly suitable program is 'dzen', an X status bar which displays text read from standard input.

To use dzen as a status bar, reserve space for it on the screen, by setting a 'gap' at the top (or bottom) of the screen in your Config.hs

    defaultGaps = [(18,0,0,0)]
    

The gap settings specify offsets to leave blank on each edge of the screen. Since xmonad supports Xinerama, you can supply different gaps for each physical screen (allowing you to run different clients as statusbars, on each screen). After recompiling and reloading, the screen now has a gap at the top:

We can now launch dzen, and it wil appear in the gap, display the date:

    while true ; do
        date +"%H.%M %a %b %d"
        sleep 60
    done | dzen2 -ta r -fg '#a8a3f7' -bg '#3f3c6d' 
    

giving us a nice status bar:

We can hide or raise the status bar on any screen with mod-b.

With just these basics it should be possible to get started productively using xmonad as your tiling window manager. With custom configuration in Haskell, you can try out all sorts of interesting tiling or key binding ideas quite cheaply, as well as producing nice eye candy.

Throw away the mouse, and get productive in X!