dwm config - volume, battery notification, unread e-mail count & more

written on Thursday, January 19, 2012 by

As many other dwm users do, I customized my .xinitrc file and the dwm status bar in to display some useful information. Here is my configuration:


This is what my .xinitrc looks like:

# set keyboard layout to Swiss German
setxkbmap ch

# Load .Xresources file
xrdb -merge ~/.Xresources

# Start xbindkeys
xbindkeys &

# Set some defaults
export BROWSER=chromium &
export EDITOR=vim &
xdg-mime default evince.desktop application/pdf &

# Loop
while true
    # Set root title

    # Check battery level
    BATT=$( acpi -b | sed 's/.*[charging|unknown], \([0-9]*\)%.*/\1/gi' )
    STATUS=$( acpi -b | sed 's/.*: \([a-zA-Z]*\),.*/\1/gi' )
    if ([ $BATT -le 5 ] && [ $STATUS == 'Discharging' ]); then
        # Beep
        echo -e "\007" >/dev/tty10 && sleep 0.2
        echo -e "\007" >/dev/tty10 && sleep 0.2
        echo -e "\007" >/dev/tty10 && sleep 0.2
        # Blink
        echo 'on' > /proc/acpi/ibm/light && sleep 1
        echo 'off' > /proc/acpi/ibm/light

    # Update every 10s
    sleep 10s
done &

# Set up rotated dual screen without touching my xorg.conf
xrandr --output DVI-1 --auto --rotate left --pos 0x0 --output DVI-0 --auto --pos 1080x720 --rotate normal

# Read .xsessionrc
sh ~/.xsessionrc &

# Set wallpaper
feh --bg-scale ~/.xwallpaper-dwm.png

# Set WM name (for Java apps)
wmname LG3D

# Run dwm
exec dwm


In my .Xresources, I'm setting the UXTerm color to white on black, as well as fixing a bug with the Alt key in SSH sessions. The last line is to set the window URGENT flag when the window uses the system bell.

UXTerm*eightBitInput: false
UXTerm*metaSendsEscape: true
UXTerm*reverseVideo: true
UXTerm*bellIsUrgent: true

As you've seen in my .xinitrc file, I didn't want to keep my xsetroot commands directly in that file. The main reason for this is that now I can update the status information from an external script, e.g. when pushing some volume buttons on my notebook.

UPTIME=`uptime | sed 's/.*up\s*//' | sed 's/,\s*[0-9]* user.*//' | sed 's/  / /g'`
VOLUME=$( amixer sget Master | grep -e 'Front Left:' | \
    sed 's/[^\[]*\[\([0-9]\{1,3\}%\).*\(on\|off\).*/\2 \1/' | sed 's/off/M/' | sed 's/on //' )
UNREADMAIL=`cat .unreadmail`
BATTERYSTATE=$( acpi -b | awk '{ split($5,a,":"); print substr($3,0,2), $4, "["a[1]":"a[2]"]" }' | tr -d ',' )
if [ `date +%S` == 30 -o `date +%S` == 00 ]; then python > .unreadmail; fi
xsetroot -name "Unread ${UNREADMAIL} | ${VOLUME} | ${DATETIME} | Up ${UPTIME}h | ${BATTERYSTATE}"

The uptime value doesn't look perfect, there are bugs if the uptime is <1h. But that doesn't bug me :)

In summary, my status bar displays the following things:

  • Unread e-mail count
  • Volume
  • Date and time
  • Uptime
  • Battery status

To check the unread mail count in my IMAP account, I created a little Python script. But because I don't want to query the server every second, I'm caching the value in a file and update it every 30 seconds. Create a cronjob or similar to update the file.

#!/usr/bin/env python

import imaplib

obj = imaplib.IMAP4_SSL('', '993')
obj.login('user', 'password')
print len(, 'UnSeen')[1][0].split())

This entry was tagged dwm and sysadmin