browser icon
You are using an insecure version of your web browser. Please update your browser!
Using an outdated browser makes your computer unsafe. For a safer, faster, more enjoyable user experience, please update your browser today or try a newer browser.

XMonad with dzen and Conky

Geschrieben von am 14. June 2012

Because I switched from Gnome to Xmonad on my Ubuntu system recently, I decided to share my configuration files with you, since I put some work into setting up everything the way I wanted.

This is my laptop configuration, the desktop one only differs in a few details (e.g. the total width of the bar due to a bigger screen resolution and no battery state etc.)

In terms of packages I think I installed xmonad, dmenu, dzen2 and conky. There is already a lot of material on how to setup Xmonad as a gnome-session, so I won't go into that. I'll only show the files here that I feel are most interesting - so without further ado:

.xmonad/xmonad.hs

Should be pretty self-explanatory with all the comments.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import XMonad
import XMonad.Hooks.DynamicLog
import XMonad.Util.Run ( spawnPipe )
import XMonad.Util.EZConfig ( additionalKeys )
import System.IO ( hPutStrLn )
import System.Exit ( ExitCode(ExitSuccess), exitWith )
import XMonad.Config.Gnome ( gnomeConfig )
import XMonad.Hooks.ManageHelpers
import XMonad.Config.Desktop ( desktopLayoutModifiers )
import XMonad.Layout.NoBorders ( smartBorders )
import XMonad.Hooks.ManageHelpers ( isFullscreen, isDialog, doFullFloat )
import XMonad.Hooks.UrgencyHook ( NoUrgencyHook(NoUrgencyHook), withUrgencyHook )
import XMonad.Layout.ComboP ( Property(Role) )
import XMonad.Layout.PerWorkspace ( onWorkspace )
import Control.Monad ( liftM2 )
import XMonad.Layout.IM ( withIM )
import XMonad.Layout.Reflect ( reflectHoriz )
import qualified XMonad.StackSet as W ( sink, shift, greedyView )

main = do
    -- I use two dzen bars, the left one contains the Xomand workspaces
    -- and title etc., eth right one contains the output from conky
    -- with some stats etc.
    status <- spawnPipe myDzenStatus
    conky  <- spawnPipe myDzenConky

    -- Since gnome isn't starting any init script like .xinitrc, I'm running
    -- my own init script manually    
    init <- spawn "/home/manni/.startxmonad"

    -- I'm still running Xomand as a gnome session which is nice to keep
    -- some custom settings, power management etc.
    -- Might swap that later...
    xmonad $ withUrgencyHook NoUrgencyHook $ gnomeConfig
    {
        -- Mix custom manage hook with the gnome one
        manageHook = myManageHook <+> manageHook gnomeConfig
        -- Defining 9 workspaces, some of them "named"
        , workspaces = ["1:www", "2:mail", "3:chat", "4:music", "5:edit", "6", "7", "8", "9"]
        , layoutHook = myLayout
        , logHook = myLogHook status
        -- Use Windows key for all the keyboard shotcuts instead of Alt
        , modMask = mod4Mask
        -- Gnome terminal sucks, use urxvt instead
        , terminal = "urxvt"
        -- I like the focused windo to be the one the mouse is hovering
        -- over. Takes a bit to get used to...
        , focusFollowsMouse = True

    -- Define some additional key bindings
    } `additionalKeys`
        -- Use Ctrl + Alt + L to lock the screen
        [ ((mod1Mask .|. controlMask, xK_l), spawn "gnome-screensaver-command --lock")
        -- Take a delayed screen shot using Ctrl + Print
        , ((controlMask, xK_Print), spawn "sleep 0.2; scrot -s")
        -- Take a screen shot using the Print key
        , ((0, xK_Print), spawn "scrot")
        -- Use Windows + P to open dmenu
        , ((mod4Mask, xK_p), spawn "dmenu_run -b")
        -- As former Windows user I like to have Windows + E for nautilus
        , ((mod4Mask, xK_e), spawn "nautilus")
        -- Use Windows + Shift + Q to exit XMonad (logout)
        , ((mod4Mask .|. shiftMask, xK_q), io (exitWith ExitSuccess))
    ]

-- The Manage hook places windows on certain workspaces automatically
-- and takes care of fullscreen / floating windows
myManageHook = composeAll . concat $
    [ [isDialog --> doFloat]
    , [isFullscreen --> doFullFloat]
    , [className =? c --> doFloat | c <- myCFloats&#93;
    , &#91;title =? t --> doFloat | t <- myTFloats&#93;
    , &#91;resource =? r --> doFloat | r <- myRFloats&#93;
    , &#91;(className =? i <||> resource =? i) --> doIgnore | i <- myIgnores&#93;
    , &#91;(className =? x <||> title =? x <||> resource =? x) --> doSink | x <- mySinks&#93;
    , &#91;(className =? x <||> title =? x <||> resource =? x) --> doFullFloat | x <- myFullscreens&#93;
    , &#91;(className =? x <||> title =? x <||> resource =? x) --> doShift "1:www" | x <- my1Shifts&#93;
    , &#91;(className =? x <||> title =? x <||> resource =? x) --> doShift "2:mail" | x <- my2Shifts&#93;
    , &#91;(className =? x <||> title =? x <||> resource =? x) --> doShift "3:chat" | x <- my3Shifts&#93;
    , &#91;(className =? x <||> title =? x <||> resource =? x) --> doShift "4:music" | x <- my4Shifts&#93;
    , &#91;(className =? x <||> title =? x <||> resource =? x) --> doShiftAndGo "5:edit" | x <- my5Shifts&#93;
    , &#91;(className =? x <||> title =? x <||> resource =? x) --> doShiftAndGo "6" | x <- my6Shifts&#93;
    , &#91;(className =? x <||> title =? x <||> resource =? x) --> doShiftAndGo "7" | x <- my7Shifts&#93;
    , &#91;(className =? x <||> title =? x <||> resource =? x) --> doShiftAndGo "8" | x <- my8Shifts&#93;
    , &#91;(className =? x <||> title =? x <||> resource =? x) --> doShiftAndGo "9" | x <- my9Shifts&#93;
    &#93;
    where
    -- Hook used to shift windows without focusing them
    doShiftAndGo = doF . liftM2 (.) W.greedyView W.shift
    -- Hook used to push floating windows back into the layout
    -- This is used for gimp windwos to force them into a layout.
    doSink = ask >>= \w -> liftX (reveal w) >> doF (W.sink w)
    -- Float dialogs, Download windows and Save dialogs
    myCFloats = ["Sysinfo", "XMessage"]
    myTFloats = ["Downloads", "Save As..."]
    myRFloats = ["Dialog"]
    -- Ignore gnome leftovers
    myIgnores = ["Unity-2d-panel", "Unity-2d-launcher", "desktop_window", "kdesktop"]
    mySinks = ["gimp"]
    -- Run VLC, firefox and VLC on fullscreen
    myFullscreens = ["vlc", "Image Viewer", "firefox"]
    -- Define default workspaces for some programs
    my1Shifts = ["Firefox-bin", "Firefox", "firefox", "Firefox Web Browser", "opera", "Opera"]
    my2Shifts = ["thunderbird", "Thunderbird-bin", "thunderbird-bin", "Thunderbird"]
    my3Shifts = ["Pidgin Internet Messenger", "Buddy List", "pidgin", "skype", "skype-wrapper", "Skype"]
    my4Shifts = ["Banshee"]
    my5Shifts = ["geany", "eclipse", "Eclipse"]
    my6Shifts = ["hotot"]
    my7Shifts = ["urxvt"]
    my8Shifts = ["gimp", "GIMP Image Editor"]
    my9Shifts = ["vlc", "nautilus"]

-- Define a special layout for the GIMP workspace with the two toolbar
-- windows on each side of the main windows.
-- Also change the ratio for main/other windows to the golden section
-- instead of 1:1
myLayout = onWorkspace "8" gimpLayout $ smartBorders (desktopLayoutModifiers (resizableTile ||| Mirror resizableTile ||| Full))
    where
    resizableTile = Tall nmaster delta ratio
    gimpLayout = (withIM (0.12) (Role "gimp-toolbox") $ reflectHoriz $ withIM (0.15) (Role "gimp-dock") Full)
    nmaster = 1
    ratio = toRational (2/(1+sqrt(5)::Double))
    delta = 3/100

-- Forward the window information to the left dzen bar and format it
myLogHook h = dynamicLogWithPP $ myDzenPP { ppOutput = hPutStrLn h }

-- Left bar is 1000px wide, right one 500, rest is taken by trayer
myDzenStatus = "dzen2 -x '0' -w '1000' -ta 'l'" ++ myDzenStyle
myDzenConky  = "conky -c ~/.conkyrc | dzen2 -x '1000' -w '500' -ta 'r'" ++ myDzenStyle

-- Bar style 24px high and colors
myDzenStyle  = " -h '24' -y '0' -fg '#777777' -bg '#222222'"

-- Very plain formatting, non-empty workspaces are highlighted,
-- urgent workspaces (e.g. active IM window) are highlighted in red
myDzenPP  = dzenPP
    { ppCurrent = dzenColor "#3399ff" "" . wrap " " " "
    , ppHidden  = dzenColor "#dddddd" "" . wrap " " " "
    , ppHiddenNoWindows = dzenColor "#777777" "" . wrap " " " "
    , ppUrgent  = dzenColor "#ff0000" "" . wrap " " " "
    , ppSep     = "  "
    , ppLayout  = \y -> ""
    , ppTitle   = dzenColor "#ffffff" "" . wrap " " " "
    }

.conkyrc

The most interesting part here is where I grab the ouput from amixer and format it to display the sound volume. Maybe I will replace this and the battery status with a nice icon later (then I have to switch over to "native" conky instead of just piping it into a dzen bar..

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
background yes
out_to_x no
out_to_console yes
update_interval 3
total_run_times 0
use_spacer none

TEXT
^fg(\#666666)${cpu cpu1}%^fg() \
^fg(\#888888)${mem}^fg() \
^fg(\#666666)${execi 1 amixer sget 'Master',0 | grep Mono: | sed 's/^[^[]*\[/[/g' | sed 's/\[[^%]*dB\] //g' | sed 's/^\[.*off\]/[-]/g' | sed 's/ \[on\]//g'}^fg() \
^fg(\#888888)${execi 1 /home/manni/battery.sh}^fg() \
^fg(\#aaaaaa)${time %b %d %H:%M}^fg()

.startxmonad

My startup script which aside from running some default programs at startup also starts the trayer, which I use to display all my tray icons (nm-applet, skype, pidgin etc.).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!/bin/bash

# Start the trayer int the upper right corner as part of the bar
# 180px wide with opaque gray background
trayer --edge top --align right --SetDockType true --SetPartialStrut true --expand false --width 180 --widthtype pixel --transparent true --tint 0x222222 --alpha 0 --height 24 &

# Fix the weird cross cursor and use normal arrow instead
xcompmgr -c &

firefox &
hotot &
pidgin &
thunderbird &

battery.sh

This generates output to show the battery state which I try and keep short, because my laptop screen is not that big.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash
REM=`cat /proc/acpi/battery/BAT1/state | grep remaining | sed 's/^.*: *\(.*\) mAh/\1/g'`
FULL=`cat /proc/acpi/battery/BAT1/info | grep last  | sed 's/^.*: *\(.*\) mAh/\1/g'`
PERCENT=`expr $REM \* 100 / $FULL`

if cat /proc/acpi/battery/BAT1/state | grep -q " charging"
then
    if [ $PERCENT != 100 ]
    then
    	echo -n "AC $PERCENT%"
    else
    	echo -n "AC"
    fi
else
    TIME=`cat /proc/acpi/battery/BAT*/state | awk '{if ($0 ~ "present rate:"){rate = $3} if($0 ~ "remaining capacity:"){cap = $3}} END {printf "(%d:%02d)\n" ,(cap / rate), (((cap % rate) / rate) * 60)}'`
    echo -n "$PERCENT% $TIME"
fi

echo ""

Find ich gut!
1
  • Twitter
  • Facebook
  • email
  • RSS

Leave a Reply

Your email address will not be published. Required fields are marked *