My xmonad Config

After many hours of tweaking, starting on the shores of xmobar/demu and later ending up in gnomeConfig waters, I think I’ve finally settled on something approaching a completed config. The default gnomeConfig is so close to being perfect, yet it misses out with a lack of libnotify support (and, due to the limitations of the gnome workspace switcher, doesn’t handle multiple monitors, but that’s for another day).

sudo add-apt-repository ppa:richardgv/compton; sudo apt-get update; sudo apt-get install xmonad libghc-xmonad-dev libghc-xmonad-contrib-dev compton roxterm gnome-panel

If you’re using apt, and a non-exotic display manager, an entry for xmonad/gnome should appear automatically on the log-in screen.


xmonad.hs

import XMonad
import XMonad.Config.Gnome
import XMonad.Hooks.ManageHelpers
import XMonad.Hooks.UrgencyHook
import XMonad.Actions.CycleWS
import XMonad.Layout.Fullscreen
import XMonad.Layout.NoBorders
import XMonad.Util.NamedWindows

import qualified XMonad.StackSet as W
import qualified Data.Map as M

--------------------------------------------------------------------------------
-- Vars:
-- 
myTerminal = "roxterm" -- gnome-terminal doesn't set the X11 urgent flag on
                       -- the bell character (^G)
myBrowser  = "firefox"
myEmail    = "thundbird"
myFileMan  = "nautilus"
myEditor   = "sublime-text"
myMonitor  = "gnome-system-monitor"
myPiracy   = "transmission-gtk"
myMusic    = "clementine"
myFeeds    = "liferea"

 -- Blend in with the Ubuntu Ambiance theme
myNormalBorderColor  = "#413F3B"
myFocusedBorderColor = "#A2A094"

--------------------------------------------------------------------------------
-- Urgency Hook:
-- 
-- Use libnotify notifications when the X11 urgent hint is set
data LibNotifyUrgencyHook = LibNotifyUrgencyHook deriving (Read, Show)
instance UrgencyHook LibNotifyUrgencyHook where
  urgencyHook LibNotifyUrgencyHook w = do
    name <- getName w
    wins <- gets windowset
    whenJust (W.findTag w wins) (flash name)
    where flash name index = spawn $ "notify-send " ++ "'Workspace "    ++ index     ++ "' "
                                                    ++ "'Activity in: " ++ show name ++ "' "
                                                    ++ "--icon=notification-gpm-monitor"

--------------------------------------------------------------------------------
-- Window rules:
-- 
-- To find the property name associated with a program, use
-- > xprop | grep WM_CLASS
-- and click on the client you're interested in.
--
myManageHook = composeAll [
      title      =? "Bottom Expanded Edge Panel"                   --> doIgnore
    , (className =? "Firefox" <&&> title =? "Library")             --> doFloat
    , (className =? "Firefox" <&&> title =? "Firefox Preferences") --> doFloat
    , className  =? "File-roller"                                  --> doFloat
  ] <+> composeOne [ isFullscreen -?> doFullFloat ]

--------------------------------------------------------------------------------
-- Keybinds:
-- 
keysToAdd x = [
      ((modMask x .|. shiftMask, xK_Left),  prevWS) -- Shift to previous workspace
    , ((modMask x .|. shiftMask, xK_Right), nextWS) -- Shift to next workspace
    , ((modMask x .|. shiftMask, xK_Down),  shiftToPrev) -- Shift window to previous workspace
    , ((modMask x .|. shiftMask, xK_Up),    shiftToNext) -- Shift window to next workspace
    , ((modMask x .|. shiftMask, xK_f), spawn myBrowser)
    , ((modMask x .|. shiftMask, xK_e), spawn myEmail)
    , ((modMask x .|. shiftMask, xK_d), spawn myFileMan)
    , ((modMask x .|. shiftMask, xK_s), spawn myEditor)
    , ((modMask x .|. shiftMask, xK_m), spawn myMonitor)
    , ((modMask x .|. shiftMask, xK_p), spawn myPiracy)
    , ((modMask x .|. shiftMask, xK_u), spawn myMusic)
    , ((modMask x .|. shiftMask, xK_l), spawn myFeeds)
  ]

myKeys x = keys gnomeConfig x `M.union` M.fromList (keysToAdd x)

--------------------------------------------------------------------------------
-- Startup:
-- 
-- Enable compositing for transparency, shaped windows, smooth transitions, etc.
--   -f = enable window fading
--   -I = opacity step in
--   -O = opacity step out
--   --backend glx = better performance
--   --vsync opengl = doesn't work for all drivers, see 'man compton'
-- 
-- Rebind backward/forward keys to home/end.
myStartupHook :: X ()
myStartupHook = do
  spawn "compton -f -I 0.10 -O 0.10 --backend glx --vsync opengl"
  spawn "notify-send 'Xmonad Started/Recompiled' --icon=emblem-system"

--------------------------------------------------------------------------------
-- Main:
-- 
main = xmonad
  $ withUrgencyHook LibNotifyUrgencyHook
  $ gnomeConfig {
      keys = myKeys
    , terminal = myTerminal
    , layoutHook  = (fullscreenFloat . fullscreenFull) $ smartBorders $ layoutHook gnomeConfig
    , manageHook  = myManageHook  <+> manageHook  gnomeConfig
    , startupHook = myStartupHook <+> startupHook gnomeConfig
    , handleEventHook = fullscreenEventHook <+> handleEventHook gnomeConfig
    , normalBorderColor  = myNormalBorderColor
    , focusedBorderColor = myFocusedBorderColor
  }

Additionally, I use Synapse as my general-purpose launcher:

sudo apt-get install synapse