Gnome 3 and XMonad

Every now and then I like to mess around with my desktop environment + windows manager. During the last year I’ve been using a few pieces of Gnome 3 and the awesome wm. They are a great combination and work pretty well together, but to really get the most out of them I think it’s necessary to get fluent with Lua.

Don’t get me wrong. I like learning new languages, but if I’m going to spend time learning a new one, I would rather prefer it to be interesting. Interesting is a matter of taste, and it happens that I find Haskell more interesting than Lua.

So here is where XMonad makes its appearance on the scene. XMonad is a tiling window manager written and configured with Haskell. Haskell is a pure functional language. A couple of years ago, when I first heard about it, I wrongly thought it was yet another for-research-only language, but after seeing damn good projects written in it I’ve decided to give it a try. At first glance Haskell might seem kind of esoteric language, but as soon as you get used to the functional paradigm you’ll start spotting its benefits.

Let’s go back to the topic of this post. I will describe how to configure and get a usable desktop environment with XMonad 0.10 as the window manager. I’m using Debian wheezy but, excluding the installation step, this guide should work on any distro. Be wary, this is not an introduction to XMonad. If you feel lost you should go and read its very well written documentation.

In order to install XMonad we’ll use our dear ol’ apt-get.

$ sudo apt-get install xmonad libghc-xmonad-contrib-dev libghc-xmonad-dev

Debian kindly provide us with a session file which allow us to select Gnome3/XMonad duo in GDM, but if you want a more flexible approach you should create a local session file. For example:

rul@hesperos:~$ cat .config/gnome-session/sessions/xmonad-gnome.session 
[GNOME Session]
Name=XMonad/Gnome (with notifications) 
RequiredComponents=gnome-panel;gnome-settings-daemon;
RequiredProviders=windowmanager;notifications;
DefaultProvider-windowmanager=xmonad
DefaultProvider-notifications=notification-daemon

And then call it from your ~/.xsession file:

rul@hesperos:~$ cat ~/.xsession`
exec gnome-session --session xmonad-gnome "$@"

Then startx from a tty or choosing System default in GDM should get your session running.

Anyway, for what I want to show you the session file provided by Debian is more than enough. To get started, just select XMonad/GNOME in GDM.

The next step is to tune your new and shiny XMonad/GNOME session. To get the most out of this combination you will need to adapt it to suit your needs. In XMonad all the action takes place in the ~/.xmonad/xmonad.hs file. Here you’ll program and re-define functions in order to configure your window manager. The rest of this post will provide you with tips to fix some initial annoyances.

Re-map mod key

I use Alt key a lot. In XMonad you’ll use mod key a lot. You will unleash hell if you don’t re-map the mod key to something less used, i.e. the Windows key.

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

You’ll be annoyed when you want to watch a fullscreen video and find out that gnome-panel doesn’t dissapear. Here is the tweak:

import XMonad
import XMonad.Hooks.ManageHelpers
 
myManageHook = composeAll [
  isFullscreen --> doFullFloat
]
 
 main = xmonad $ gnomeConfig {
   manageHook       = myManageHook <+> manageHook gnomeConfig
 }
Smart borders

In XMonad borders are useful to show which window is focused. When there is only one window in the workspace, or when a window is in fullscreen mode, is kind of dumb to show the borders. Here is how to remove them:

import XMonad import XMonad.Config.Gnome import XMonad.Layout.NoBorders

main = xmonad $ gnomeConfig { layoutHook = smartBorders (layoutHook gnomeConfig) }

Notifications

After struggling with different notifications daemons, I’ve opted for the one used by XFCE. It provides both flexibility and beauty. In Debian you can install it with:

$ sudo apt-get install xfce4-notifyd

The xfce4-notifyd-config application provides you with some configurations. I’ve chosen the Smoke theme.

We’ll need to make some adjustments in XMonad in order to unleash xfce4-notifyd’s full potential:

import XMonad
import XMonad.Hooks.ManageHelpers
import XMonad.Config.Gnome

myManageHook = composeAll [
  (className =? "Xfce4-notifyd" -->  doIgnore)
]

main = xmonad $ gnomeConfig {
  manageHook       = myManageHook <+> manageHook gnomeConfig
}
Floating windows

Some clients which should start in float mode, starts in tiling mode. This could give you some ugly-looking windows. You can configure window placement doing something like this:

import XMonad
import XMonad.Hooks.ManageHelpers
import XMonad.Config.Gnome

myManageHook = composeAll [
    (className =? "Pidgin" <&&> (title =? "Pidgin" <||> title =? "Accounts")) --> doCenterFloat
  , (className =? "Pidgin") --> doShift "3"
  , (className =? "Gnome-panel" <&&> title =? "Run Application") --> doCenterFloat
  , (className =? "Gcr-prompter") --> doCenterFloat
]

main = xmonad $ gnomeConfig {
  manageHook       = myManageHook <+> manageHook gnomeConfig
}

The doShift line will move all Pidgin windows to workspace 3.

Give color to the borders

XMonad default focused window color is red. You can change it doing something like the following:

import XMonad
import XMonad.Config.Gnome

main = xmonad $ gnomeConfig {
    borderWidth        = 2
  , normalBorderColor  = "#cccccc"
  , focusedBorderColor = "#3300ff"
}
Final touch: add compositing

You can add some compositing (transparency, shadows, etc.) with xcompmgr. To install it just apt-get it, and do something like this:

$ echo "xcompmgr -c&" >> ~/.xprofile

Restart your session and you should have xcompmgr up and running.

Putting all together

That’s all. Here’s how your final ~/.xmonad/xmonad.hs should look like:

import XMonad
import XMonad.Hooks.ManageHelpers
import XMonad.Config.Gnome
import XMonad.Layout.NoBorders

myManageHook = composeAll [
    (className =? "Pidgin" <&&> (title =? "Pidgin" <||> title =? "Accounts")) --> doCenterFloat
  , (className =? "Pidgin") --> doShift "3"
  , (className =? "Gnome-panel" <&&> title =? "Run Application") --> doCenterFloat
  , (className =? "Gcr-prompter") --> doCenterFloat
  , (className =? "Xfce4-notifyd" -->  doIgnore)
  , isFullscreen --> doFullFloat
   ]

main = xmonad $ gnomeConfig {
  modMask            = mod4Mask
  , layoutHook  = smartBorders (layoutHook gnomeConfig)
  , borderWidth      = 2
  , normalBorderColor  = "#cccccc"
  , focusedBorderColor = "#3300ff"
  , manageHook       = myManageHook <+> manageHook gnomeConfig
  }

Enjoy! :-)


Posted on January 30, 2013 by Raúl Benencia

Comments? Sure! Just send me an email with it and I'll happily include it here.