A simple shell status bar for OpenBSD and cwm(1)
810 words, 4 minutes
These days, I try to use simple and stock software as much as possible on my
OpenBSD laptop. I’ve been playing with cwm(1) for weeks and I was missing a
status bar. After trying things like Tint2, Polybar etc, I discovered
@gonzalo’s termbar
. Thanks a lot!
As I love scripting, I decided to build my own.
The idea behind termbar is to launch an terminal that will loop printing the information you want ; via a shell script. It’s a bit like using xsetroot with dwm(1). That terminal will be ignored by cwm(1) and stay in some reserved placed.
The termbar resources
Using an Xresources file, start defining a dedicated resource class and a set of properties:
# vim ~/.Xresources
(...)
! ~/scripts/termbar inside xterm(1)
termbar*faceName: CodeNewRoman Nerd Font:style=Bold:size=13
termbar*geometry: 191x1+0+0
termbar*internalBorder: 6
termbar*saveLines: 0
termbar*scrollBar: false
termbar*title: termbar
termbar*foreground: qogir_white
termbar*background: qogir_black
termbar*color1: qogir_red
termbar*color3: qogir_orange
You can add those in a .Xdefaults if you prefer.
The termbar script
I’m using ksh(1) as a default shell. And I write all my scripts with it trying to stay as compatible as possible with sh(1). If you’re using bash, you may have to tweak a few things in my following script.
The script uses native OpenBSD commands (like apm, sysctl, …) to extract and format informations via functions. Then it loops into calling those functions, printing the whole result and pausing for a second.
# cat ~/scripts/termbar
#!/bin/ksh
trap 'exec $0' HUP # Restart itself
trap 'tput cnorm; exit 1' INT QUIT TERM
_norm="\033[39m"
_alrt="\033[31m"
_warn="\033[33m"
_rset="\033[0m"
_hide="\033[2m"
set -A _bat "${_norm}" "${_warn}" "${_alrt}"
set -A _pwr "${_norm}"
set -A _net "" "直"
set -A _nic "em0" "iwm0"
set -A _vol "奄" "奔" "墳"
function bat {
[[ $(apm -a) -eq 1 ]] \
&& echo -n "${_pwr[0]} " \
|| echo -n "${_bat[$(apm -b)]} "
echo -n "$(apm -l)%${_norm}"
}
function cal {
[[ $(date "+%H") -ge 6 && $(date "+%H") -le 22 ]] \
&& echo -n "${_norm}" \
|| echo -n "${_warn}"
echo -n $(date '+%a %d %b %H:%M')${_norm}
}
function cpu {
echo -n "龍$(sysctl -n hw.setperf)% "
echo -n " $(sysctl -n hw.sensors.cpu0.temp0 | cut -d '.' -f 1)°C"
}
function grp {
echo -n "${_hide}[ "
echo -n "$(xprop -root 32c '\t$0' _NET_CURRENT_DESKTOP | cut -f 2)"
echo -n " ]${_rset}"
}
function net {
[[ -z "$(ifconfig ${_nic[0]} | grep 'status: no carrier')" ]] \
&& (echo -n ${_net[0]} ; return)
echo -n $(ifconfig ${_nic[1]} | \
awk '/ieee80211:/ { print "直" $3 "(" $8 ")" }')
}
function vol {
_v=$(sndioctl -n output.level | awk '{ print int($0*100) '})
[[ $(sndioctl -n input.mute) -eq 1 ]] \
&& echo -n "${_norm}${_norm} " \
|| echo -n "${_warn}${_norm} "
[[ $(sndioctl -n output.mute) -eq 1 ]] \
&& echo -n "婢" \
|| echo -n "${_vol[$(($_v*3/101))]}"
echo -n "$_v%"
}
function win {
_wid=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)
_win=$(xprop -id $_wid '\t$0' _NET_WM_NAME | awk -F '"' '{ print $2 }')
echo -n " ${_win}"
}
tput civis # Hide cursor
while true; do
_l="$(grp) $(win)"
_r="$(cpu) $(bat) $(net) $(vol) $(cal)"
#tput clear cup 1 0
tput cup 1 0
printf "%-120.120s\r" "$_l"
tput cup 1 120
printf "%110.110s" "$_r"
sleep 1
done
tput cnorm # Show cursor
#EOF
I use a few colors to show current cwm group and alert me when battery is low or when it is time to go to bed… printf is used to format the strings and tput helps placing the text where it should be. Using shell colors can mess all the display without it. This seem to be because printf will count those non-printable characters when aligning but xterm will obviously not display them.
The alignment has to be calculated depending on your screen resolution and font size.
Let cwm(1) know about termbar
The .cwmrc file should contain the following lines:
# cat ~/.cwmrc
(...)
ignore termbar
autogroup 0 termbar
(...)
gap 30 0 0 0
This will allow termbar to be displayed and managed as a statusbar or dock. And the gap value depends on the font you use.
Launch termbar automatically
As I’m using xenodm(1), I added termbar to the .xsession file so that it starts automatically when I log in.
# cat ~/.xsession
(...)
xterm -name termbar -class termbar -e /home/jdoe/scripts/termbar &
exec /usr/local/bin/ck-launch-session /usr/X11R6/bin/cwm
The xterm command is configured to use the “termbar” class and run the “termbar” script. You’ll need a Nerd Font if you want fancy icons in your bar. Or you can use plain text and the default DejaVu font.
The script doesn’t appear in top, since I update only every seconds. So I don’t need to write it in C for better performance. I tried using lower delays to update and it worked well. But I don’t really need it.
That’s all folks!