#!/bin/zsh -- # poor woman's dock. auto-layouts programs given to it as args, for window # managers without a dock/wharf. # BUGS # # a DockApp owns a slot for life. that is, if a DockApp crashes or is # stopped using this program, there will be an empty slot visible. this # makes sense if the dockapp crashed or some such, because it can be # restarted in the same place. there should probably be a command that # says "stop this, and make the other DockApps slide to fill the empty space", # or at least, "stop this, and let the next DockApp I start fill the space" # though. # # program lets you start same DockApp with exact same parameters. this means # --restart and --shutdown will operate on all of them, which is OK, but it # also means that --stop and --restart will # only operate on the youngest of the matching DockApps. this is most likely # to bite you when "parameters" really means "no parameters," as that is more # likely to occur than multiple instances with the exact same parameters. # # program makes the nasty assumption that for dock apps, the name and window # title are always the same (give or take upper/lower case). # # yes, this needs procedures and should really be perl. # ${=FOO} is zsh for "split at blank boundaries" btw # # yes, in the time I wrote this, I could have added a real dock to beryl. # apparently, WithdrawnState is the WM_STATE to look out for, then reparent etc. # On the other hand, the wmpinboard docks say that AfterStep's Wharf expects # NormalState. :-/ # 2007/05/08 Azundris init # 2007/05/11 Azundris support basic transparency TRANS=0.4 NICE=20 if [[ "x$1" = "x--help" || "x$1" = "x-h" || "x$1" = "x-help" || "x$1" = "x" ]] then echo "$0 -- poor woman's dock" echo echo "$0 [--instance ]" echo " if you wish to run one than one $0, you need to give the instances names;" echo " *all* calls must then use the --instance argument, as the *first* argument." echo echo "$0 --init [--horizontal|--vertical] [--trans ]" echo " setup poor woman's dock; align horizontally / vertically" echo echo "$0 [--add] [ ...]" echo " add dock-application with all parameters given to dock" echo echo "$0 --restart" echo " restart all formerly started dockapps that have gone away (crashed)," echo " with the same parameters and in the same location as before." echo echo "$0 --restart ..." echo " restart given formerly started dockapps if they have gone away (crashed)," echo " with the same parameters and in the same location as before." echo " can either be just the name of the excutable," echo " or that name, plus any arguments, in which case the entirety" echo " of them needs to be grouped with quotes, like so:" echo " $0 --restart \"wmnet -W wlan0\" wmtop \"wmwifi -bw -s -i 10 -tc\"" echo echo "$0 --shutdown" echo " stop all DockApps." echo echo "Example:" echo " $0 --init --horizontal" echo " $0 wmtop -a rainbow -s 1000 -r 2000" echo " $0 wmnet -W wlan0" echo " $0 wmwifi -bw -s -i 10 -tc" exit fi ## --instance NO=".default" if [[ "x$1" = "x--instance" ]] then shift NO=".$1" shift fi P=$HOME/.poordock F=$P/offset$NO O=$P/orientation$NO A=$P/dockapps$NO mkdir -p $P 2>/dev/null ## --init if [[ "x$1" = "x--init" ]] then echo "0" > $F if [[ "x$2" = "x--horizontal" || "x$2" = "x--vertical" ]] then $0 --shutdown >/dev/null 2>/dev/null echo $2 > $O rm $A 2>/dev/null else if [[ $# -gt 1 ]] then echo "$0: error: funky args after --init -- please use none, --horizonal, or --vertical!" exit 1 fi fi exit 0 fi ## --shutdown if [[ "x$1" = "x--shutdown" || "x$1" = "x--stop" ]] then shift if [[ "$#" -eq 0 ]] then echo "stopping all ..." while read LINE do OFFSET=`echo $LINE|cut -d' ' -f1` CMD=`echo $LINE|cut -d' ' -f2-` # might have args, if so, drop 'em APP=`echo $CMD|cut -d' ' -f1` PID=`pgrep -n -u $USER -xf "$CMD"` if [ $? -eq 0 ] then kill $PID else echo "$0: notice: $CMD wasn't running ..." fi done < $A sleep 1 while read LINE do OFFSET=`echo $LINE|cut -d' ' -f1` CMD=`echo $LINE|cut -d' ' -f2-` # might have args, if so, drop 'em APP=`echo $CMD|cut -d' ' -f1` PID=`pgrep -n -u $USER -xf "$CMD"` if [ $? -eq 0 ] then kill -9 $PID fi done < $A else while [[ "x$1" != "x" ]] do echo "stopping $* ..." LINE=`grep $1 $A` if [[ $? -eq 1 ]] then echo "error: $1 never ran in this session ..." else OFFSET=`echo $LINE|cut -d' ' -f1` CMD=`echo $LINE|cut -d' ' -f2-` # might have args, if so, drop 'em APP=`echo $CMD|cut -d' ' -f1` PID=`pgrep -n -u $USER -xf "$CMD"` if [ $? -eq 0 ] then kill $PID else echo "$0: notice: $CMD wasn't running ..." fi if [[ "x$PID" != "x" ]] then sleep 1 kill -9 $PID 2>/dev/null fi shift fi done fi exit 0 fi ## --restart if [[ "x$1" = "x--restart" ]] then shift if [[ "$#" -eq 0 ]] then echo "restarting all ..." while read LINE do OFFSET=`echo $LINE|cut -d' ' -f1` CMD=`echo $LINE|cut -d' ' -f2-` # might have args, if so, drop 'em APP=`echo $CMD|cut -d' ' -f1` pgrep -n -u $USER -xf "$CMD" > /dev/null 2>&1 if [ $? -eq 0 ] then # echo "$0: notice: an instance of $CMD is still running!" # we'll still re-apply properties below though; # maybe the user restarted by hand, let's do them # a service else if [[ "x$ORIENTATION" = "--horizontal" ]] then nice -$NICE xstartup 0 0,$OFFSET,0,-1,-1 -t $TRANS $APP ${=CMD} else nice -$NICE xstartup 0 0,0,$OFFSET,-1,-1 -t $TRANS $APP ${=CMD} fi fi wmctrl -r $APP -b add,below,add,hidden wmctrl -r $APP -b add,skip_taskbar,add,skip_pager done < $A else while [[ "x$1" != "x" ]] do echo "restarting $* ..." LINE=`grep $1 $A` if [[ $? -eq 1 ]] then echo "$0: error: $1 never ran in this session ..." else OFFSET=`echo $LINE|cut -d' ' -f1` CMD=`echo $LINE|cut -d' ' -f2-` # might have args, if so, drop 'em APP=`echo $CMD|cut -d' ' -f1` pgrep -n -u $USER -xf "$CMD" > /dev/null 2>&1 if [[ $? -eq 0 ]] then echo "$0: error: an instance of $CMD is still running!" # we'll still re-apply properties below though; # maybe the user restarted by hand, let's do them # a service else if [[ "x$ORIENTATION" = "--horizontal" ]] then nice -$NICE xstartup 0 0,$OFFSET,0,-1,-1 -t $TRANS $APP ${=CMD} else nice -$NICE xstartup 0 0,0,$OFFSET,-1,-1 -t $TRANS $APP ${=CMD} fi fi wmctrl -r $APP -b add,below,add,hidden wmctrl -r $APP -b add,skip_taskbar,add,skip_pager shift fi done fi exit 0 fi ## --add / --start [default] if [[ "x$1" = "x--add" || "x$1" = "x--start" ]] then shift fi # get offset if [ -f $F ] then OFFSET=`cat $F` else OFFSET=0 fi # get orientation if [ -f $O ] then ORIENTATION=`cat $O` else ORIENTATION="--vertical" fi # start DockApp if [[ "x$ORIENTATION" = "--horizontal" ]] then nice -$NICE xstartup 0 0,$OFFSET,0,-1,-1 -t $TRANS $1 $* else nice -$NICE xstartup 0 0,0,$OFFSET,-1,-1 -t $TRANS $1 $* fi # set properties wmctrl -r $1 -b add,below,add,hidden wmctrl -r $1 -b add,skip_taskbar,add,skip_pager # calculate new offset wmctrl -l -G|grep -i " $1"|while read L do if [[ "x$ORIENTATION" = "--horizontal" ]] then SIZE=`echo $L|sed -e's/0x[0-9a-f]* *[0-9-]* *[0-9-]* *[0-9-]* *\([0-9-]*\) .*/\1/'` else SIZE=`echo $L|sed -e's/0x[0-9a-f]* *[0-9-]* *[0-9-]* *[0-9-]* *[0-9-]* *\([0-9-]*\) .*/\1/'` fi ID=`echo $L|sed -e's/\(0x[0-9a-f]*\) .*/\1/'` APP=`echo $L|sed -e's/0x[0-9a-f]* *[0-9-]* *[0-9-]* *[0-9-]* *[0-9-]* *[0-9-]* [ ]*[^ ]* *//'` echo "WINID: $ID? ($APP,$W)" done echo "$OFFSET $*" >> $A let OFFSET="$OFFSET+$SIZE" echo $OFFSET > $F exit 0