#!/usr/bin/env bash # awmtt: awesomewm testing tool # https://github.com/mikar/awmtt #{{{ Usage usage() { cat <] [-C ] [-D ] [-S ] [-a ]... [-x ] awmtt (stop [all] | restart) awmtt run [-D ] awmtt theme (get | set | list | random) [-N] Arguments: start Spawn nested Awesome via Xephyr stop Stops the last Xephyr process all Stop all instances of Xephyr restart Restart all instances of Xephyr run Run a command inside a Xephyr instance (specify which one with -D) theme Some basic theming control via: get Get current theme name set Set theme to list List available themes random Set a random theme Options: -B|--binary Specify path to awesome binary (for testing custom awesome builds) -C|--config Specify configuration file -D|--display Specify the display to use (e.g. 1) -N|--notest Don't use a testfile but your actual rc.lua (i.e. $HOME/.config/awesome/rc.lua) This happens by default if there is no rc.lua.test file. -S|--size Specify the window size -a|--aopt Pass option to awesome binary (e.g. --no-argb or --check). Can be repeated. -x|--xopts Pass options to xephyr binary (e.g. -keybd ephyr,,,xkblayout=de). Needs to be last. -h|--help Show this help text and exit Examples: awmtt start (uses defaults: -C $HOME/.config/awesome/rc.lua.test -D 1 -S 1024x640) awmtt start -C /etc/xdg/awesome/rc.lua -D 3 -S 1280x800 awmtt theme set zenburn -N EOF exit 0 } [ "$#" -lt 1 ] && usage #}}} #{{{ Utilities awesome_pid() { pgrep -n "awesome"; } xephyr_pid() { pgrep -f xephyr_$D; } errorout() { echo "error: $*" >&2; exit 1; } #}}} #{{{ Executable check AWESOME=$(which awesome) XEPHYR=$(which Xephyr) [[ -x "$AWESOME" ]] || errorout 'Please install Awesome first' [[ -x "$XEPHYR" ]] || errorout 'Please install Xephyr first' #}}} #{{{ Default Variables # Display and window size D=1 SIZE="1024x640" AWESOME_OPTIONS="" XEPHYR_OPTIONS="" # Path to rc.lua if [[ "$XDG_CONFIG_HOME" ]]; then RC_FILE="$XDG_CONFIG_HOME"/awesome/rc.lua.test else RC_FILE="$HOME"/.config/awesome/rc.lua.test fi [[ ! -f "$RC_FILE" ]] && RC_FILE="$HOME"/.config/awesome/rc.lua #}}} #{{{ Hostname Check - this is probably only useful for me. I have the same rc.lua running on two different machines HOSTNAME=$(uname -n) #}}} #{{{ Functions #{{{ Start function start() { # check for free $DISPLAYs for ((i=0;;i++)); do if [[ ! -f "/tmp/.X${i}-lock" ]]; then D=$i; break; fi; done "$XEPHYR" :$D -name xephyr_$D -ac -br -noreset -screen "$SIZE" $XEPHYR_OPTIONS >/dev/null 2>&1 & sleep 1 DISPLAY=:$D.0 "$AWESOME" -c "$RC_FILE" $AWESOME_OPTIONS & sleep 1 # print some useful info if [[ "$RC_FILE" =~ .test$ ]]; then echo "Using a test file ($RC_FILE)" else echo "Caution: NOT using a test file ($RC_FILE)" fi echo "Display: $D, Awesome PID: $(awesome_pid), Xephyr PID: $(xephyr_pid)" } #}}} #{{{ Stop function stop() { if [[ "$1" == all ]]; then echo "Stopping all instances of Xephyr" kill $(pgrep Xephyr) >/dev/null 2>&1 elif [[ $(xephyr_pid) ]]; then echo "Stopping Xephyr for display $D" kill $(xephyr_pid) else echo "Xephyr is not running or you did not specify the correct display with -D" exit 0 fi } #}}} #{{{ Restart function restart() { # TODO: (maybe use /tmp/.X{i}-lock files) Find a way to uniquely identify an awesome instance # (without storing the PID in a file). Until then all instances spawned by this script are restarted... echo -n "Restarting Awesome... " for i in $(pgrep -f "awesome -c"); do kill -s SIGHUP $i; done } #}}} #{{{ Run function run() { [[ -z "$D" ]] && D=1 DISPLAY=:$D.0 "$@" & LASTPID=$! echo "PID is $LASTPID" } #}}} #{{{ Theme function theme() { # List themes theme_list() { #TODO: list only directories if [[ -d $(dirname "$RC_FILE")/themes ]]; then ls /usr/share/awesome/themes $(dirname "$RC_FILE")/themes else ls /usr/share/awesome/themes "$HOME"/.config/awesome/themes fi } case "$1" in l|list) theme_list exit 0 ;; esac # Check for Beautiful library BEAUTIFUL=$(grep -c 'beautiful.init' "$RC_FILE") [[ "$BEAUTIFUL" -ge 1 ]] || errorout 'Could not detect theme library "beautiful". Exiting.' if [[ "$HOSTNAME" == laptop ]]; then curtheme=$(grep "^themelap" "$RC_FILE" | awk -F\/ '{print $2}') elif [[ "$HOSTNAME" == htpc ]]; then curtheme=$(grep "^themehtpc" "$RC_FILE" | awk -F\/ '{print $2}') else curtheme=$(grep -oP "[^\/]+(?=\/theme.lua)" "$RC_FILE") fi # Change theme theme_set() { if [[ "$HOSTNAME" == laptop ]]; then theme=themelap elif [[ "$HOSTNAME" == htpc ]]; then theme=themehtpc else theme="^beautiful\.init" fi if [[ "$file" ]]; then [[ $(theme_list | grep -c $file) -lt 1 ]] && errorout 'No such theme.' echo "changing $curtheme to $file in $RC_FILE" sed -i "/$theme.*\/theme\.lua\"/s/[^/]*\(\/theme\.lua\)/$file\1/" "$RC_FILE" else [[ $(theme_list | grep -c $2) -lt 1 ]] && errorout 'No such theme.' echo "changing $curtheme to $2 in $RC_FILE" sed -i "/$theme.*\/theme\.lua\"/s/[^/]*\(\/theme\.lua\)/$2\1/" "$RC_FILE" fi } # Print themename theme_get() { echo "$curtheme" } # Select random theme and start Xephyr instance theme_random() { themes=$(ls -1 $(dirname "$RC_FILE")/themes /usr/share/awesome/themes | grep -vE '/home/|/usr/|icons|README') file=$(echo "$themes" | sort --random-sort | head -1) theme_set D=11 && start } case "$1" in g|get) theme_get;; s|set) theme_set "${args[@]}";; r|random) theme_random;; *) errorout "unrecognized argument. Use theme (list | random | get | set )";; esac } #}}} #{{{ Parse options parse_options() { while [[ -n "$1" ]]; do case "$1" in start) input=start;; stop) input=stop;; restart) input=restart;; run) input=run;; theme) input=theme;; -B|--binary) shift; AWESOME="$1";; -C|--config) shift; RC_FILE="$1";; -D|--display) shift; D="$1" [[ ! "$D" =~ ^[0-9] ]] && errorout "$D is not a valid display number";; -N|--notest) RC_FILE="$HOME"/.config/awesome/rc.lua;; -S|--size) shift; SIZE="$1";; -a|--aopt) shift; AWESOME_OPTIONS+="$1";; -x|--xopts) shift; XEPHYR_OPTIONS="$@";; -h|--help) usage;; *) args+=("$1");; esac shift done } #}}} #}}} #{{{ Main main() { case "$input" in start) start "${args[@]}";; stop) stop "${args[@]}";; restart) restart "${args[@]}";; run) run "${args[@]}";; theme) theme "${args[@]}";; *) echo "Option missing or not recognized";; esac } #}}} parse_options "$@" main