From 5b132bf1244a008ad3ce67688030a7678831f77d Mon Sep 17 00:00:00 2001 From: Matias Linares Date: Fri, 23 Oct 2015 03:14:36 -0300 Subject: Initial commit --- herbstluftwm/autostart | 186 +++++++++++++++++++++++++++++++++++ herbstluftwm/bin/mvrs | Bin 0 -> 8056 bytes herbstluftwm/mvrs.sh | 36 +++++++ herbstluftwm/panel.bar.sh | 157 +++++++++++++++++++++++++++++ herbstluftwm/panel.sh | 223 ++++++++++++++++++++++++++++++++++++++++++ herbstluftwm/popups.sh | 46 +++++++++ herbstluftwm/restartpanels.sh | 16 +++ 7 files changed, 664 insertions(+) create mode 100755 herbstluftwm/autostart create mode 100755 herbstluftwm/bin/mvrs create mode 100755 herbstluftwm/mvrs.sh create mode 100755 herbstluftwm/panel.bar.sh create mode 100755 herbstluftwm/panel.sh create mode 100755 herbstluftwm/popups.sh create mode 100755 herbstluftwm/restartpanels.sh (limited to 'herbstluftwm') diff --git a/herbstluftwm/autostart b/herbstluftwm/autostart new file mode 100755 index 0000000..444d17a --- /dev/null +++ b/herbstluftwm/autostart @@ -0,0 +1,186 @@ +#!/bin/bash + +# this is a simple config for herbstluftwm + +# https://bbs.archlinux.org/viewtopic.php?id=128646 +#hc() { +# herbstclient "$@" +#} +hc() { + cmd+=(, $@) +} + +mvrs() { + ~/.config/herbstluftwm/mvrs.sh $1 $2 +} + +hc emit_hook reload + +# Some autostart configuration +nitrogen --restore & +#compton -b + +# remove all existing keybindings +hc keyunbind --all + +# keybindings +# if you have a super key you will be much happier with Mod set to Mod4 +#Mod=Mod1 # Use alt as the main modifier +Mod=Mod4 # Use the super key as the main modifier + +hc keybind $Mod-Shift-q quit +hc keybind $Mod-Shift-r reload +hc keybind $Mod-Shift-c close +#hc keybind $Mod-Return spawn st +hc keybind $Mod-Return spawn xterm +#hc keybind $Mod-p spawn dmenu_run -b -p $(hostname) -nb "#010101" +hc keybind $Mod-p spawn rofi -show run + +# basic movement +# focusing clients +hc keybind $Mod-h focus left +hc keybind $Mod-j focus down +hc keybind $Mod-k focus up +hc keybind $Mod-l focus right + +# moving clients +hc keybind $Mod-Shift-h shift left +hc keybind $Mod-Shift-j shift down +hc keybind $Mod-Shift-k shift up +hc keybind $Mod-Shift-l shift right + +# splitting frames +# create an empty frame at the specified direction +hc keybind $Mod-u split bottom 0.5 +hc keybind $Mod-o split right 0.5 +# let the current frame explode into subframes +hc keybind $Mod-Control-space split explode + +# resizing frames +resizestep=0.02 +hc keybind $Mod-Control-h spawn ~/.config/herbstluftwm/mvrs.sh left +$resizestep +hc keybind $Mod-Control-j spawn ~/.config/herbstluftwm/mvrs.sh down +$resizestep +hc keybind $Mod-Control-k spawn ~/.config/herbstluftwm/mvrs.sh up +$resizestep +hc keybind $Mod-Control-l spawn ~/.config/herbstluftwm/mvrs.sh right +$resizestep +hc keybind $Mod-Control-Left resize left +$resizestep +hc keybind $Mod-Control-Down resize down +$resizestep +hc keybind $Mod-Control-Up resize up +$resizestep +hc keybind $Mod-Control-Right resize right +$resizestep + +# tags +#tag_names=( {1..9} ) +tag_names=( "web" "editors" "chat" "games" "misc" ) +tag_keys=( {1..9} 0 ) + +hc rename default "${tag_names[0]}" || true +for i in ${!tag_names[@]} ; do + hc add "${tag_names[$i]}" + key="${tag_keys[$i]}" + if ! [ -z "$key" ] ; then + hc keybind "$Mod-$key" use_index "$i" + hc keybind "$Mod-Shift-$key" move_index "$i" + fi +done + +hc floating "games" on + +# cycle through tags +hc keybind $Mod-period use_index +1 --skip-visible +hc keybind $Mod-comma use_index -1 --skip-visible + +# layouting +hc keybind $Mod-r remove +hc keybind $Mod-space cycle_layout 1 +hc keybind $Mod-s floating toggle +hc keybind $Mod-f fullscreen toggle +hc keybind $Mod-Shift-p pseudotile toggle + +# Light and sound +hc keybind $Mod-Left spawn xbacklight -5 +hc keybind $Mod-Down spawn amixer set Master 3- +hc keybind $Mod-Up spawn amixer set Master 3+ +hc keybind $Mod-Right spawn xbacklight +5 + +# mouse +hc mouseunbind --all +hc mousebind $Mod-Button1 move +hc mousebind $Mod-Button2 zoom +hc mousebind $Mod-Button3 resize + +# focus +hc keybind $Mod-BackSpace cycle_monitor +hc keybind $Mod-Tab cycle_all +1 +hc keybind $Mod-Shift-Tab cycle_all -1 +hc keybind $Mod-c cycle +hc keybind $Mod-i jumpto urgent + +# theme +#hc attr theme.tiling.reset 1 +#hc attr theme.floating.reset 1 +#hc set frame_border_active_color '#9E003A' +#hc set frame_border_normal_color '#101010' +#hc set frame_bg_normal_color '#565656' +#hc set frame_bg_active_color '#000000' +#hc set frame_border_width 2 +#hc set always_show_frame 1 +hc set frame_bg_transparent 1 +hc set frame_transparent_width 1 +hc set frame_gap 2 +hc set frame_border_active_color '#000000' +hc set frame_border_normal_color '#1d1f21' +hc set frame_bg_normal_color '#151515' +hc set frame_bg_active_color '#151515' +hc set frame_border_width 0 +hc set window_border_width 2 +hc set window_border_normal_color '#3a3a3a' +hc set window_border_active_color '#cc342b' + +#hc attr theme.active.color '#9E003A' +#hc attr theme.normal.color '#252525' +#hc attr theme.urgent.color orange +#hc attr theme.inner_width 0 +#hc attr theme.inner_color '#191919' +#hc attr theme.border_width 2 +#hc attr theme.floating.border_width 2 +#hc attr theme.floating.outer_width 3 +#hc attr theme.floating.outer_color black +#hc attr theme.active.inner_color '#9E003A' +#hc attr theme.active.outer_color '#111111' +#hc attr theme.background_color '#141414' + + +#hc set window_gap 0 +hc set frame_padding 0 +#hc set smart_window_surroundings 1 +#hc set smart_frame_surroundings 1 +#hc set mouse_recenter_gap 0 + +# rules +hc unrule -F +#hc rule class=XTerm tag=3 # move all xterms to tag 3 +hc rule focus=on # normally focus new clients +#hc rule focus=off # normally do not focus new clients +# give focus to most common terminals +#hc rule class~'(.*[Rr]xvt.*|.*[Tt]erm|Konsole)' focus=on +hc rule windowtype~'_NET_WM_WINDOW_TYPE_(DIALOG|UTILITY|SPLASH)' pseudotile=on +hc rule windowtype='_NET_WM_WINDOW_TYPE_DIALOG' focus=on +hc rule windowtype~'_NET_WM_WINDOW_TYPE_(NOTIFICATION|DOCK|DESKTOP)' manage=off + +# unlock, just to be sure +hc unlock + +herbstclient set tree_style '╾│ ├└╼─┐' + +# do multi monitor setup here, e.g.: +# hc set_monitors 1280x1024+0+0 1280x1024+1280+0 +# or simply: +# hc detect_monitors +herbstclient chain "${cmd[@]}" + +# find the panel +panel=~/.config/herbstluftwm/panel.sh +[ -x "$panel" ] || panel=/etc/xdg/herbstluftwm/panel.sh +for monitor in $(herbstclient list_monitors | cut -d: -f1) ; do + # start it on each monitor + "$panel" $monitor & +done diff --git a/herbstluftwm/bin/mvrs b/herbstluftwm/bin/mvrs new file mode 100755 index 0000000..76adda2 Binary files /dev/null and b/herbstluftwm/bin/mvrs differ diff --git a/herbstluftwm/mvrs.sh b/herbstluftwm/mvrs.sh new file mode 100755 index 0000000..f7b3c14 --- /dev/null +++ b/herbstluftwm/mvrs.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# ./mvrs WINID X Y Width Height + +floating=$(herbstclient get_attr tags.focus.floating) + +if [[ x"$floating" == xfalse ]] +then + resizestep=0.02 + herbstclient resize $1 $2 +else + resizestep=15 + winid="$(herbstclient get_attr clients.focus.winid)" + + width=$(xwininfo -id "${winid}" | grep Width | awk '{print $2}') + height=$(xwininfo -id "${winid}" | grep Height | awk '{print $2}') + + case $1 in + left) + width=$(($width - ${resizestep})) + ;; + right) + width=$(($width + ${resizestep})) + ;; + up) + height=$(($height - ${resizestep})) + ;; + down) + height=$(($height + ${resizestep})) + ;; + esac + + + ~/.config/herbstluftwm/bin/mvrs ${winid} $width $height +fi + diff --git a/herbstluftwm/panel.bar.sh b/herbstluftwm/panel.bar.sh new file mode 100755 index 0000000..88f7ab1 --- /dev/null +++ b/herbstluftwm/panel.bar.sh @@ -0,0 +1,157 @@ +#!/bin/bash + +# todo: fontello icons + +# disable path name expansion or * will be expanded in the line +# cmd=( $line ) +set -f + +function uniq_linebuffered() { + awk -W interactive '$0 != l { print ; l=$0 ; fflush(); }' "$@" +} +function get_mpd_song() { + # use mpc to get currently playing song, uppercase it + song=$(mpc current -f %title%) + # let's skip ft. parts, etc. to get some more space + echo $song +} + +monitor=${1:-0} + +separator="\f3 | \fr" +song=$(get_mpd_song) +windowtitle="" + +herbstclient pad $monitor 18 +{ + # events: + # mpc events + mpc idleloop player & + mpc_pid=$! + + # date + while true ; do + date +'date_day %A %e. ' + date +'date_min %H:%M ' + sleep 1 || break + done > >(uniq_linebuffered) & + date_pid=$! + + while true + do + $HOME/scripts/battery-parse + sleep 2m || break + done & + battery_pid=$! + + while true + do + $HOME/scripts/nm-connected-device + sleep 3m || break + done & + nm_status_pid=$! + + # hlwm events + herbstclient --idle + + # exiting; kill stray event-emitting processes + kill $date_pid $mpd_pid $battery_pid $nm_status_pid +} 2> /dev/null | { + TAGS=( $(herbstclient tag_status $monitor) ) + #unset TAGS[${#TAGS[@]}-1] + date_day="" + date_min="" + Battery="" + network_status="" + visible=true + + while true ; do + # align left + echo -n "\l" + if [[ $windowtitle ]] + then + if [ ${#windowtitle} -gt 55 ] + then + windowtitle="$(echo -n $windowtitle | cut -c1-55)..." + fi + echo -n "\ur\fr$windowtitle$separator" + fi + + # Align center + echo -n "\c" + for i in "${TAGS[@]}" ; do + case ${i:0:1} in + '#') # current tag + echo -n "\u4\b4\fr" + ;; + '+') # active on other monitor + echo -n "\u7\b7\f8" + ;; + ':') + # Tag with windows + echo -n "\ur\br\f4" + ;; + '!') # urgent tag + echo -n "\u1\br\f1" + ;; + *) + echo -n "\ur\br\fr" + ;; + esac + echo -n " ${i:1} " # | tr '[:lower:]' '[:upper:]' + done + + # align right + echo -n "\r\ur\fr\br" + # display song and separator only if something's playing + if [[ $song ]]; then + if [ ${#song} -gt 30 ] + then + song="$(echo -n $song | cut -c1-30)..." + fi + echo -n "\ur\fr$song$separator" + fi + echo -n "$network_status" + echo -n "$separator" + echo -n "$Battery" + echo -n "$separator" + echo -n "$date_day" | tr '[:lower:]' '[:upper:]' + echo -n " \f2" + echo -n "$date_min " | tr '[:lower:]' '[:upper:]' + echo + # wait for next event + read line || break + cmd=( $line ) + # find out event origin + case "${cmd[0]}" in + tag*) + TAGS=( $(herbstclient tag_status $monitor) ) + #unset TAGS[${#TAGS[@]}-1] + ;; + date_day) + date_day="${cmd[@]:1}" + ;; + date_min) + date_min="${cmd[@]:1}" + ;; + player) + song=$(get_mpd_song) + ;; + focus_changed|window_title_changed) + windowtitle="${cmd[@]:2}" + ;; + Battery) + Battery="${cmd[1]} ${cmd[2]}" + ;; + network) + network_status="${cmd[1]} ${cmd[2]}" + ;; + quit_panel) + exit + ;; + reload) + exit + ;; + esac + done +} 2> /dev/null | bar $1 diff --git a/herbstluftwm/panel.sh b/herbstluftwm/panel.sh new file mode 100755 index 0000000..035bcf5 --- /dev/null +++ b/herbstluftwm/panel.sh @@ -0,0 +1,223 @@ +#!/bin/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]} +panel_height=16 +font="-Misc-Termsyn.Icons-Medium-R-Normal--11-79-100-100-C-60-ISO8859-1" +#font="-*-envy code r-*-*-*-*-11-*-*-*-*-*-*-*" +# font="DejaVu Sans Mono" +bgcolor=$(hc get frame_border_normal_color) +selbg=$(hc get window_border_active_color) +selfg='#101010' +popups="/home/matias/.config/herbstluftwm/popups.sh" + +#### +# Load the font for the panel, should implement something more optimized +# But for now it's fine +xset +fp /usr/share/fonts/local/ +xset fp rehash + +#### +# 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 + +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 3 || break + done > >(uniq_linebuffered) & + childpid=$! + + while true; do + mpc_output="$(mpc -f "player\t%title% - %artist%" || echo -n "player\t")" + echo "$mpc_output" | head -n 1 + sleep 11 || break + done > >(uniq_linebuffered) & + mpcpid=$! + + hc --idle + kill $childpid + kill $mpcpid +} 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 + battery=$(expr $(expr $(cat /sys/class/power_supply/BAT*/charge_now) \* 100) / $(cat /sys/class/power_supply/BAT*/charge_full)) + if [ "$battery" = "/" ] ;then + right="$separator^bg($hintcolor) $date $separator" + else + right="^bg($hintcolor) ^fg(#efefef)$song $separator " + if [[ $battery -lt 20 ]] + then + right="$right^fg(#ef7f7f)$battery%% $separator $date" + elif [[ $battery -lt 50 ]] + then + right="$right^fg(#e1e17f)$battery%% $separator $date" + else + right="$right^fg(#efefef)$battery%% $separator $date" + fi + fi + 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 + 22)))$(printf "$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="^ca(1, ${popups} cal)${cmd[@]:1}^ca()" + ;; + 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) + if [[ x"${cmd[@]:1}" != "x" ]] + then + song="^ca(1, ${popups} music) \uEA ^ca()" + else + song="wep" + fi + ;; + esac + done + + ### dzen2 ### + # After the data is gathered and processed, the output of the previous block + # gets piped to dzen2. font -> -fn "$font" + +} 2> /dev/null | dzen2 -w $panel_width -x $x -y $y -fn "$font" -h $panel_height \ + -e 'button3=;button4=exec:herbstclient use_index -1;button5=exec:herbstclient use_index +1' \ + -ta l -bg "$bgcolor" -fg '#efefef' diff --git a/herbstluftwm/popups.sh b/herbstluftwm/popups.sh new file mode 100755 index 0000000..0ba7d86 --- /dev/null +++ b/herbstluftwm/popups.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +dzen_bg="#444040" + +calendary() { + ( + cal + ) | dzen2 -p -bg "${dzen_bg}" -x "1195" -y "25" -w "165" -h "20" -l "5" -sa "c" -ta "c" \ + -title-name "popup_sysinfo" -e 'onstart=uncollapse;button1=exit;button3=exit' +} + +position(){ + pos=$(mpc | awk 'NR==2' | awk '{print $4}' | sed 's/(//' | sed 's/%)//') + bar=$(echo $pos | gdbar -w $1 -h 1.5 -fg "#FF3D00" -bg "#821D00") + echo -n "$bar" + return +} + +music() { + set -e + + popup_width=220 + padding=10 + + while : + do + echo "^p(10)$(mpc current -f %artist%) +^p($padding)$(mpc current -f %title%) +^p($padding)$(mpc current -f %album%) + +^p($padding)^ca(1,mpc prev)Prev^ca() ^ca(1,mpc toggle)Play/Pause^ca() ^ca(1,mpc stop)Stop^ca() ^ca(1,mpc next)Next^ca() +^p($padding)$(position $(($popup_width - $padding)) )" 2> /dev/null + sleep 1 + done | dzen2 -p -bg "${dzen_bg}" -y 25 -x 967 -l 5 -u -w $(($popup_width + $padding)) -ta l -title-name "popup_mpd" -e 'onstart=uncollapse;button3=exit' +} + +case $1 in + cal) + calendary + ;; + music) + music + ;; + *) + ;; +esac diff --git a/herbstluftwm/restartpanels.sh b/herbstluftwm/restartpanels.sh new file mode 100755 index 0000000..9d9110c --- /dev/null +++ b/herbstluftwm/restartpanels.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +installdir=/ + +XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" +defaultpanel="$XDG_CONFIG_HOME/herbstluftwm/panel.sh" + +[ -x "$defaultpanel" ] || defaultpanel="$installdir/etc/xdg/herbstluftwm/panel.sh" + +panelcmd="${1:-$defaultpanel}" + +herbstclient emit_hook quit_panel + +for i in $(herbstclient list_monitors | cut -d':' -f1) ; do + "$panelcmd" $i & +done -- cgit v1.2.3-70-g09d2