#!/usr/bin/env bash hc() { "${herbstclient_command[@]:-herbstclient}" "$@" ;} monitor=${1:-0} geometry=( $(herbstclient monitor_rect "$monitor") ) if [ -z "$geometry" ] ;then echo "Invalid monitor $monitor" exit 1 fi # geometry has the format W H X Y x=${geometry[0]} y=${geometry[1]} panel_width=${geometry[2]} if [ "$HOSTNAME" = warthog ]; then panel_height=30 font="-*-fixed-medium-*-*-*-26-*-*-*-*-*-*-*" iconpath=${HOME}/.config/herbstluftwm/icons_large else panel_height=16 font="-*-fixed-medium-*-*-*-12-*-*-*-*-*-*-*" iconpath=${HOME}/.config/herbstluftwm/icons fi # Colors xrdb=( $(xrdb -query | grep -P "color[0-9]*:" | sort | cut -f 2-) ) # define an array with proper colornames. declare -A color index=0 for name in black brightgreen brightyellow brightblue brightmagenta brightcyan brightwhite red green yellow blue magenta cyan white grey brightred; do color[${name}]=${xrdb[$index]} ((index++)) done bgcolor=$(hc get frame_border_normal_color) selbg=$(hc get window_border_active_color) selfg='#101010' #### # Try to find textwidth binary. # In e.g. Ubuntu, this is named dzen2-textwidth. if which textwidth &> /dev/null ; then textwidth="textwidth"; elif which dzen2-textwidth &> /dev/null ; then textwidth="dzen2-textwidth"; else echo "This script requires the textwidth tool of the dzen2 project." exit 1 fi #### # true if we are using the svn version of dzen2 # depending on version/distribution, this seems to have version strings like # "dzen-" or "dzen-x.x.x-svn" if dzen2 -v 2>&1 | head -n 1 | grep -q '^dzen-\([^,]*-svn\|\),'; then dzen2_svn="true" else dzen2_svn="" fi if awk -Wv 2>/dev/null | head -1 | grep -q '^mawk'; then # mawk needs "-W interactive" to line-buffer stdout correctly # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=593504 uniq_linebuffered() { awk -W interactive '$0 != l { print ; l=$0 ; fflush(); }' "$@" } else # other awk versions (e.g. gawk) issue a warning with "-W interactive", so # we don't want to use it there. uniq_linebuffered() { awk '$0 != l { print ; l=$0 ; fflush(); }' "$@" } fi # ICONS function icon() { echo -n "^fg(#000000)^ro(1x$height)^fg()^bg(${color[${2}]})^fg(#151515) ^i(${iconpath}/${1}.xbm) ^fg()^bg()" } # CPU function cpu() { cpu=$(sensors | grep "Core" | cut -b 18-21) temp=$(sensors | grep "Physical id 0:" | awk '{print $4}' | cut -b 2-3) if [[ $temp -le 70 ]]; then echo -n $(icon temp brightblue) ${cpu} else echo -n $(icon temp red) ${cpu} fi } # BATTERY function battery() { if [ "$HOSTNAME" != warthog ]; then return fi status=$(acpi -a | cut -d':' -f2) battery=$(acpi -b | cut -d, -f2 | sed -e 's/[^0-9]//g') if [[ $status == " on-line" ]]; then echo -n $(icon ac2 brightmagenta) ${battery}% elif [[ $battery -le 20 ]]; then echo -n $(icon battery_horz1 red) ${battery}% elif [[ $battery -le 65 ]]; then echo -n $(icon battery_horz2 yellow) ${battery}% else echo -n $(icon battery_horz3 green) ${battery}% fi } # VOLUME function volume() { vol=$(amixer get Master | grep "%" | head -n1 | awk -F"[][]" '{if($6~"off"){print "0%";} else {print $2;}}' | tr -d '%') if [[ $vol -le 0 ]]; then echo -n $(icon volume_off grey) $(echo $vol | dzen2-gdbar -s o -nonl) else echo -n $(icon volume_on white) $(echo $vol | dzen2-gdbar -s o -nonl) fi } hc pad $monitor $panel_height { ### Event generator ### # based on different input data (mpc, date, hlwm hooks, ...) this generates events, formed like this: # \t [...] # e.g. # date ^fg(#efefef)18:33^fg(#909090), 2013-10-^fg(#efefef)29 #mpc idleloop player & while true ; do # "date" output is checked once a second, but an event is only # generated if the output changed compared to the previous run. date +$'date\t^fg(#efefef)%H:%M^fg(#909090), %Y-%m-^fg(#efefef)%d' sleep 1 || break done > >(uniq_linebuffered) & childpid=$! hc --idle kill $childpid } 2> /dev/null | { IFS=$'\t' read -ra tags <<< "$(hc tag_status $monitor)" visible=true date="" windowtitle="" while true ; do ### Output ### # This part prints dzen data based on the _previous_ data handling run, # and then waits for the next event to happen. bordercolor="#26221C" separator="^bg()^fg($selbg)|" # draw tags for i in "${tags[@]}" ; do case ${i:0:1} in '#') echo -n "^bg($selbg)^fg($selfg)" ;; '+') echo -n "^bg(#9CA668)^fg(#141414)" ;; ':') echo -n "^bg()^fg(#ffffff)" ;; '!') echo -n "^bg(#FF0675)^fg(#141414)" ;; *) echo -n "^bg()^fg(#ababab)" ;; esac if [ ! -z "$dzen2_svn" ] ; then # clickable tags if using SVN dzen echo -n "^ca(1,\"${herbstclient_command[@]:-herbstclient}\" " echo -n "focus_monitor \"$monitor\" && " echo -n "\"${herbstclient_command[@]:-herbstclient}\" " echo -n "use \"${i:1}\") ${i:1} ^ca()" else # non-clickable tags if using older dzen echo -n " ${i:1} " fi done echo -n "$separator" echo -n "^bg()^fg() ${windowtitle//^/^^}" # small adjustments right="" # custom functions for func in cpu volume battery; do right="${right} $(${func})" done right="${right} ^bg()$(icon clock2 green) $date" right_text_only=$(echo -n "$right" | sed 's.\^[^(]*([^)]*)..g') # get width of right aligned text.. and add some space.. width=$($textwidth "$font" "$right_text_only ") echo -n "^pa($(($panel_width - $width)))$right" echo ### Data handling ### # This part handles the events generated in the event loop, and sets # internal variables based on them. The event and its arguments are # read into the array cmd, then action is taken depending on the event # name. # "Special" events (quit_panel/togglehidepanel/reload) are also handled # here. # wait for next event IFS=$'\t' read -ra cmd || break # find out event origin case "${cmd[0]}" in tag*) #echo "resetting tags" >&2 IFS=$'\t' read -ra tags <<< "$(hc tag_status $monitor)" ;; date) #echo "resetting date" >&2 date="${cmd[@]:1}" ;; quit_panel) exit ;; togglehidepanel) currentmonidx=$(hc list_monitors | sed -n '/\[FOCUS\]$/s/:.*//p') if [ "${cmd[1]}" -ne "$monitor" ] ; then continue fi if [ "${cmd[1]}" = "current" ] && [ "$currentmonidx" -ne "$monitor" ] ; then continue fi echo "^togglehide()" if $visible ; then visible=false hc pad $monitor 0 else visible=true hc pad $monitor $panel_height fi ;; reload) exit ;; focus_changed|window_title_changed) windowtitle="${cmd[@]:2}" ;; #player) # ;; esac done ### dzen2 ### # After the data is gathered and processed, the output of the previous block # gets piped to dzen2. } 2> /dev/null | dzen2 -w $panel_width -x $x -y $y -fn "$font" -h $panel_height \ -e 'button3=;button4=;button5=' \ -ta l -bg "$bgcolor" -fg '#efefef'