xmonad 0.5 is out, and I haven't upgraded my installation in a while. It's pretty nice that configuration is now done in /.xmonad/xmonad.hs, then there's no need to recompile xmonad all the time. The configuration change did require a reorganisation of my old Config.hs, so I took a look at some of the samples to see what other people did.
I ended up with something which looks like this:
This is my xmonad.hs:
-
-- XMonad Core
-
import XMonad
-
import XMonad.Layout
-
import XMonad.Operations
-
import qualified XMonad.StackSet as W
-
-
-- GHC hierarchical libraries
-
import Data.Bits ((.|.))
-
import qualified Data.Map as M
-
import Graphics.X11
-
import Graphics.X11.Xlib
-
import Graphics.X11.Xlib.Extras
-
import System.IO
-
-
-- Contribs
-
import XMonad.Actions.CycleWS
-
import XMonad.Actions.SwapWorkspaces
-
import XMonad.Actions.Submap
-
import XMonad.Actions.WindowBringer
-
import XMonad.Actions.FloatKeys
-
-
import XMonad.Hooks.UrgencyHook
-
import XMonad.Layout.NoBorders
-
import XMonad.Layout.Tabbed
-
import XMonad.Layout.WindowNavigation
-
import XMonad.Layout.Grid
-
import XMonad.Layout.LayoutHints
-
import XMonad.Layout.Dishes
-
import XMonad.Util.EZConfig
-
import XMonad.Util.Run
-
-
import XMonad.Prompt.Shell
-
import XMonad.Prompt
-
-
import XMonad.Hooks.DynamicLog ( PP(..), dynamicLogWithPP, dzenColor, wrap, defaultPP )
-
-
myfont = "\"-xos4-terminus-medium-r-normal--12-120-72-72-c-60-iso8859-1\""
-
fgcolor = "black"
-
bgcolor = "white"
-
-
statusBarCmd= "dzen2 -e '' -w 660 -h 15 -ta l -xs 1 -fg " ++ fgcolor ++ " -bg " ++ bgcolor ++ " -fn " ++ myfont
-
-
-- Get ready!
-
main = do din <- spawnPipe statusBarCmd
-
xmonad $ withUrgencyHook dzenUrgencyHook { args = ["-bg", "darkgreen", "-xs", "1"] }
-
$ defaultConfig
-
{ workspaces = workspaces'
-
, modMask = modMask'
-
, numlockMask = 0
-
, layoutHook = layoutHook'
-
, terminal = "urxvtc || urxvt"
-
, normalBorderColor = "#dddddd"
-
, focusedBorderColor = "#3499dd"
-
, defaultGaps = [(15,0,0,0)]
-
, logHook = dynamicLogWithPP $ myPP din
-
}
-
`additionalKeys` keys'
-
-
modMask' = mod4Mask
-
workspaces' = map show [1] ++ ["web", "mail", "chat", "code"] ++ map show [6 .. 9 :: Int]
-
-
layoutHook' =
-
configurableNavigation noNavigateBorders $
-
layouts
-
layouts =
-
Mirror tiled
-
||| tiled
-
||| Grid
-
||| layoutHints Full
-
||| Dishes 2 (1/5)
-
||| noBorders (tabbed shrinkText
-
defaultTConf { fontName = myfont })
-
where
-
tiled = Tall nmaster delta ratio
-
nmaster = 2 -- The default number of windows in the master pane
-
ratio = 1/2 -- Default proportion of screen occupied by master pane
-
delta = 3/100 -- Percent of screen to increment by when resizing panes
-
noFollow CrossingEvent {} = return False
-
noFollow _ = return True
-
keys' =
-
[ ((modMask' .|. shiftMask, xK_d ), spawn "date | dzen2 -p 2 -xs 1") -- %! Print current date
-
, ((modMask', xK_p), shellPrompt defaultXPConfig)
-
]
-
++
-
-- modMask'-[1..0] %! Switch to workspace N
-
-- modMask'-shift-[1..0] %! Move client to workspace N
-
[((m .|. modMask', k), windows $ f i)
-
| (i, k) <- zip workspaces' $ [xK_1 .. xK_9] ++ [xK_0]
-
, (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]]
-
++
-
-- modMask'-{e,r} %! Switch to physical/Xinerama screens 1 or 2
-
-- modMask'-shift-{e,r} %! Move client to screen 1 or 2
-
[((m .|. modMask', key), screenWorkspace sc>>= flip whenJust (windows . f))
-
| (key, sc) <- zip [xK_e, xK_w] [0..]
-
, (f, m) <- [(W.view, 0), (W.shift, shiftMask)]]
-
++
-
[((modMask' .|. mod1Mask, k), windows $ swapWithCurrent i)
-
| (i, k) <- zip workspaces' $ [xK_1 .. xK_9] ++ [xK_0]]
-
-- float keys
-
++
-
[
-
((modMask', xK_d ), withFocused (keysResizeWindow (-10,-10) (1,1)))
-
, ((modMask', xK_s ), withFocused (keysResizeWindow (10,10) (1,1)))
-
, ((modMask', xK_a ), withFocused (keysMoveWindowTo (512,384) (1, 0)))
-
]
-
-
-
myPP h = defaultPP
-
{ ppCurrent = dzenColor "white" "#cd8b00" . pad
-
, ppVisible = dzenColor "white" "#666666" . pad
-
, ppHidden = dzenColor "black" "#cccccc" . pad
-
, ppHiddenNoWindows = dzenColor "#999999" "#cccccc" . pad
-
, ppWsSep = dzenColor "#bbbbbb" "#cccccc" "^r(1x18)"
-
, ppSep = dzenColor "#bbbbbb" "#cccccc" "^r(1x18)"
-
, ppLayout = dzenColor "black" "#cccccc" .
-
(\ x -> case x of
-
"TilePrime Horizontal" ->
-
" ^i(/home/emertens/images/tile_horz.xpm) "
-
"TilePrime Vertical" ->
-
" ^i(/home/emertens/images/tile_vert.xpm) "
-
"Hinted Full" ->
-
" ^i(/home/emertens/images/fullscreen.xpm) "
-
_ -> pad x
-
)
-
, ppTitle = (' ':) . escape
-
, ppOutput = hPutStrLn h
-
}
-
where
-
escape = concatMap (\x -> if x == '^' then "^^" else [x])
-
pad = wrap " " " "
I use a simple shell script for starting xmonad:
-
ssh-add ~/.ssh/id_dsa </dev/null>/dev/null
-
Esetroot /usr/share/backgrounds/warty-final-ubuntu.png
-
unclutter -idle 2 &
-
urxvtd -f -o
-
irxevent -d
-
-
gnome-settings-daemon &
-
gnome-volume-manager &
-
-
export PATH=$PATH:`dirname $0`
-
`dirname $0`/status &
-
-
xmonad
Finally, the dzen2 status bar is run using this script:
-
#!/bin/sh
-
-
BG=white
-
FG=black
-
FONT="-xos4-terminus-medium-r-normal--12-120-72-72-c-60-iso8859-1"
-
-
BFG="#444"
-
-
gcpubar -i 2 -fg '#444' -w 30 -h 10 | dzen2 -e '' -x 1360 -fg $FG \
-
-bg $BG -fn $FONT -h 15 -xs 1 &
-
-
while :; do
-
MEM=`memstatus.awk /proc/meminfo`
-
CPU=`cpustatus.awk`
-
DATE=`date +"%d-%m %k:%M"`
-
-
REM=`awk '/remaining capacity/ { print $3 }' /proc/acpi/battery/BAT0/state`
-
LAST=`awk '/last full/ { print $4}' /proc/acpi/battery/BAT0/info`
-
STATE=`awk '{print $2}' /proc/acpi/ac_adapter/ADP1/state`
-
if [ "$STATE" = "on-line" ]; then
-
BAT=$(echo $REM $LAST | awk '{printf "Bat: %.1f%%, AC", ($1/$2)*100'})
-
else
-
PRESENT=`awk '/present rate/ { print $3}' /proc/acpi/battery/BAT0/state`
-
BAT=$(echo $REM $LAST $PRESENT | \
-
awk '{printf "Bat: %.1f%%, %d min", ($1/$2)*100, ($1/$3)*60}')
-
fi
-
-
LOAD=`awk '{print $1 " " $2 " " $3}' /proc/loadavg`
-
-
echo "$CPU $MEM | $DATE | $BAT | $LOAD"
-
sleep 5
-
done | dzen2 -e '' -x 660 -w 700 -fg $FG -bg $BG -fn $FONT -h 15 -xs 1
Two awk scripts are used - one for the memory usage and one for CPU frequencies. Why awk? No idea, it just seemed like a good choice at the time.
memstatus.awk:
-
#!/usr/bin/awk -f
-
BEGIN {
-
BG="darkgrey";
-
FG="#444";
-
WIDTH=30;
-
HEIGHT=10;
-
}
-
-
/MemTotal/ {t=$2};
-
/MemFree/ {f=$2};
-
/SwapTotal/ {st=$2};
-
/SwapFree/ {sf=$2};
-
-
END {
-
mw=int(WIDTH*(t-f)/t);
-
fw=WIDTH-mw;
-
sw=int(WIDTH*(st-sf)/st);
-
-
printf("Mem: ^ib(1)^fg(%s)^r(%dx%d)^fg(%s)^r(%dx%d)" \
-
"^fg(%s)^r(2x%d)^fg(%s)^r(%dx%d)^fg(%s)^r(%dx%d)^ib(0)^fg()\n",
-
FG, mw, HEIGHT,
-
BG, fw, HEIGHT,
-
"black",
-
HEIGHT, BG, WIDTH-sw,
-
HEIGHT, FG, sw, HEIGHT);
-
}
-
#!/usr/bin/awk -f
-
BEGIN {
-
BG="darkgrey"
-
FG="#444"
-
WIDTH=30
-
HEIGHT=10
-
CPUS=0
-
-
cmd = "ls /sys/devices/system/cpu"
-
while ((cmd | getline)> 0) {
-
if ($1 ~ /cpu/) {
-
CPUS++
-
}
-
}
-
close(cmd)
-
-
printf "CPU: "
-
for (i=0; i <CPUS; i++) {
-
cfn="/sys/devices/system/cpu/cpu" i "/cpufreq/scaling_cur_freq"
-
mfn="/sys/devices/system/cpu/cpu" i "/cpufreq/scaling_max_freq"
-
getline cf <cfn
-
getline mf <mfn
-
cw=int(WIDTH*(mf-cf)/mf)
-
-
printf("^ib(1)^fg(%s)^r(%dx%d)^fg(%s)^r(%dx%d)^ib(0)^fg()",
-
FG, cw, HEIGHT, BG, WIDTH-cw, HEIGHT)
-
-
close(cfn)
-
close(mfn)
-
-
if (i <CPUS - 1) {
-
printf("^ib(0)^fg()^r(5x0)^ib(1)")
-
}
-
-
}
-
printf("\n");
-
}



