After one has successfully installed the Xmonad window manager, the next task is to take a look at the configuration. Over all you can start to use an unconfigured Xmonad. But the main advantages of this window manager comes from a nice configuration.
A Xmonad is configured in the
xmonad.hs file. This file is
typically located within your home directory in:
As you can see, the configuration is a Haskell file. This means, that you configure your Xmonad in the language Haskell. So you have all the power of Haskell at your and, to define your configuration.
xmonad.hs configuration can be found on github.com/frosch03.
What parts can you configure
The configuration of a Xmonad is done within the module, that
main function. Within
main, the window manager is
started with the
xmonad function. That function is supplied with
a data structure, called
defaultConfig. Within Haskell a data
structure can be altered, while passing it to a function, in the
This tells us, that the function
xmonad is called with o
defaultConfig, where the value of
overwritten by the value of
According to this, the following sections describe parts of the
defaultConfig data structure, that are used to overwrite the
default one, while
xmonad is called.
The virtual Desktops
First of all, there are virtual desktops. A virtual desktop, in the xmonad sense, is a subset of the running applications. These applications are shown in the context of their desktop. One application is always mapped to exactly one desktop.
It is usual not to use more than 9 desktops in xmonad. This is due to the fact, that each desktop is accessed by a shortcut and it might be a good idea to use a combination of modifiers together with a number key. But after all it is up to you to use as many desktops as you wish.
To setup your desktops you define a list of strings. Each string stands for a desktop. One way is to use just numbers for your desktop's names.
But because we have the whole power of Haskell to configure Xmonad, one can write this as:
I like to give names to my desktops. These names remind me, what kind of applications i can expect at these desktops. So my desktop configuration would look something like this:
The mappings of Applications onto Desktops
So tiling window managers are famous for automatically organizing your windows, right? This includes routing applications onto specific desktops. The configuration of the routing is described within this section.
First of all, different applications need a way to differentiate
between them. For my configuration, i go mainly with the X11
XMonad/ManageHook.hs exports the
className function, that
WM_CLASS, and also the
title function, that matches
If you have a look into
XMonad/ManageHook.hs, you can find more
functions to match window properties.
In order to route the applications to desktops, i like to define
various lists of strings. These strings are used to match similar
applications, that i like to go onto the same desktop. For
example, i use multiple applications for instant messaging like
Pidgin or Empathy. They go into the
These are the strings i use, to route most of my applications. In the next step, you see, how this lists help to do the actual routing.
The actual routing is attached to the
myManagedHook label, which
is composed from a list of list of atomic routes.
This syntax may look a little confusing, but what it actually
say's (corresponding to the irc-line) is: For each string inside
ircApps, if that string equals the title of the application,
shift the application onto the desktop called
Later, while calling the
xmonad function, the
will be overwritten with this definition. (Actually, the
manageHook property will be extended with this definitions)
Routing applications to different desktops was the first automation step. In this section, the second step is described, namely how to align multiple applications within that desktop. In this section, that will describe some of the existing layouts. There are many more layouts defined in the xmonad-contrib library. For inspiration you might want to have a look to other XMonad configurations. Also you can risk a look into the xmonad-contrib sources. There are all the layouts defined, but as usual, the documentation could be better.
A layout definition for a desktop starts with the function call
onWorkspaces. There are two parameters to supply, the list of
the names of desktops, where the layout should apply, and the
actual layout itself.
This translates to the following. The desktop with name
its applications with one of the three supplied layouts. The
Full simply shows an application in full screen. The
(Tall 1 (1/2) (3/100)) layout splits the screen vertically into
two half's ((1/2)), separated by gaps 3% ((3/100)). With
Mirror the supplied layout is modified, such that it splits the
Multiple layouts are combined with the
The result of such a
onWorkspaces definition is again something,
that can be supplied to another
definition. Therefore the layout definition of a XMonad is a long
concatenation of single layout statements. My whole layout
definition is bound to the
myLayout name. Note the
clause with all the local definitions.
This shows, that on the
code desktop there are just two
different variations of the
tiled layout. On the
the split is at (1/3), either horizontally or vertically, of the
screen. The idea behind this layout is, that the smaller window
can hold a interpreter window, like the ghci. Within the bigger
window, an editor with the corresponding source file has place.
web desktop, i used earlier only a full screen layout:
The actual layout, shown earlier, showed a
Full layout and also
gaps layout. This
gaps layout inserts a spacer of 250 pixels
on the left and the right. I think, that a browser that is
smaller, can help reading text on pages with no line break.
im desktop a layout is used, that places a specific
window on one side.
withIM (18/100) (Role "buddy_list") points
out, that a window with the role
buddy_list gets a column of 18%
of the screen width. Usually this is on the left side, but the
reflectHoriz switches that to the right. The rest of the
screen is managed with either
Circle. So on the
im desktop, there are three layouts to
The other desktops have similar layouts or just a single one.
The Key Bindings
Another important thing for XMonad to configure, are the keybindings. They are important, because XMonad is mostly controlled via the keyboard. There are keybindings for opening a terminal, moving windows within the layout, shifting them to other desktops, or switching the actual one. Here are keybindings cheetshets for the default key bindings.
Additionally one can change this key bindings or add new ones. The following lists my key bindings, which i add to the default ones.
One can choose the modifiers out of:
modMask corresponds to your modifier key (for me that is the windows-key)
shiftMask is your shift key
controlMask corresponds to ctrl
They are combined with the
(.|.) operator. A key binding is
defined with a tuple. The first element is also a tuple from the
modifiers in the front, and the key in the second. The second
element is the command, that is issued, if the key is pressed.
The last line shows, that this configurations are additional. As
you can see, my definition is bound to the identifier
myKeys. The union of my keys and the default keys (
defaultConfig) is labeled
newKeys, which will be used later to
overwrite the default configuration.
The xmonad call within main
Last but not least, here is the call to
xmonad within the main
function. This call looks like the following:
The additional call to
withUrgencyHook is for my information
bar. That configuration will be covered in another article. Also
logHook is for displaying the bar.
Beside that, the width of the border is set to 1 pixel via
borderWidth. A color is specified for the focused window with
focusedBorderColor, and another color for the normal windows
normalBorderColor. The modifier key
set to the
mod4Mask, which in my case corresponds to the
Then the different configurations, defined earlier, are
placed. The key's
newKeys is already the combination of the
default keys, and the newly defined
just overwritten with
newKeys. The same is true for
myLayout. For the
manageHooks, the defined
myManakgeHook gets combined with the default one, and the
And there you have it, that are the basic building blocks of a XMonad configuration. You can compile your configuration by:
If that doesn't throws any errors, the running XMonad can be restarted by:
That's it, for the basic configuration part. In another post, i will describe, how to build a information bar with dzen2.
Again, you can find my whole configuration file on github.com/frosch03.