├── LICENSE ├── README.md ├── awmtt.sh └── example.jpg /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 max demian 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # awmtt 2 | awmtt (AwesomeWM Testing Tool) is a bash script that helps you test your Awesome configuration files. 3 | It requires Xephyr, an Xorg-Application which can spawn a nested instance of xorg-server, allowing you to open multiple instances of Desktop Environments or Window Mangers like AwesomeWM. 4 | 5 | ### Installation 6 | ArchLinux users can find awmtt in the [AUR](https://aur.archlinux.org/packages/awmtt/). 7 | 8 | Example Debian/Ubuntu manual installation: 9 | ``` bash 10 | sudo apt-get install xserver-xephyr 11 | sudo wget -O /usr/bin/awmtt https://raw.githubusercontent.com/mikar/awmtt/master/awmtt.sh 12 | sudo chmod a+x /usr/bin/awmtt 13 | ``` 14 | 15 | ### Screenshot 16 | Here's an example of what it looks like: 17 | ![ScreenShot](https://github.com/mikar/awmtt/blob/master/example.jpg) 18 | 19 | ### Usage 20 | ``` 21 | awmtt start [-B ] [-C ] [-D ] [-S ] [-a ]... [-x ] 22 | awmtt (stop [all] | restart) 23 | awmtt run [-D ] 24 | awmtt theme (get | set | list | random) [-N] 25 | 26 | Arguments: 27 | start Spawn nested Awesome via Xephyr 28 | stop Stops the last Xephyr process 29 | all Stop all instances of Xephyr 30 | restart Restart all instances of Xephyr 31 | run Run a command inside a Xephyr instance (specify which one with -D) 32 | theme Some basic theming control via: 33 | get Get current theme name 34 | set Set theme to 35 | list List available themes 36 | random Set a random theme 37 | 38 | Options: 39 | -B|--binary Specify path to awesome binary (for testing custom awesome builds) 40 | -C|--config Specify configuration file 41 | -D|--display Specify the display to use (e.g. 1) 42 | -N|--notest Don't use a testfile but your actual rc.lua (i.e. $HOME/.config/awesome/rc.lua) 43 | This happens by default if there is no rc.lua.test file. 44 | -S|--size Specify the window size 45 | -a|--aopt Pass option to awesome binary (e.g. --no-argb or --check). Can be repeated. 46 | -x|--xopts Pass options to xephyr binary (e.g. -keybd ephyr,,,xkblayout=de). Needs to be last. 47 | -h|--help Show this help text and exit 48 | 49 | Examples: 50 | awmtt start (uses defaults: -C $HOME/.config/awesome/rc.lua.test -D 1 -S 1024x640) 51 | awmtt start -C /etc/xdg/awesome/rc.lua -D 3 -S 1280x800 -x -keybd ephyr,,,xkbmodel=pc105,xkblayout=de,xkbrules=evdev,xkboption=grp:alts_toogle 52 | awmtt theme set zenburn -N 53 | ``` 54 | 55 | ### Xephyr 56 | Have a look at http://awesome.naquadah.org/wiki/Using_Xephyr and its documentation to learn more about how to use it. 57 | For instance, you can press `Control-Mod3-Shift` to have Xephyr grab focus while inside the window so that you can't accidentally leave it. To let go, press `Control-(Right-)Shift`. 58 | -------------------------------------------------------------------------------- /awmtt.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # awmtt: awesomewm testing tool 3 | # https://github.com/mikar/awmtt 4 | 5 | #{{{ Usage 6 | usage() { 7 | cat <] [-C ] [-D ] [-S ] [-a ]... [-x ] 9 | awmtt (stop [all] | restart) 10 | awmtt run [-D ] 11 | awmtt theme (get | set | list | random) [-N] 12 | 13 | Arguments: 14 | start Spawn nested Awesome via Xephyr 15 | stop Stops the last Xephyr process 16 | all Stop all instances of Xephyr 17 | restart Restart all instances of Xephyr 18 | run Run a command inside a Xephyr instance (specify which one with -D) 19 | theme Some basic theming control via: 20 | get Get current theme name 21 | set Set theme to 22 | list List available themes 23 | random Set a random theme 24 | 25 | Options: 26 | -B|--binary Specify path to awesome binary (for testing custom awesome builds) 27 | -C|--config Specify configuration file 28 | -D|--display Specify the display to use (e.g. 1) 29 | -N|--notest Don't use a testfile but your actual rc.lua (i.e. $HOME/.config/awesome/rc.lua) 30 | This happens by default if there is no rc.lua.test file. 31 | -S|--size Specify the window size 32 | -a|--aopt Pass option to awesome binary (e.g. --no-argb or --check). Can be repeated. 33 | -x|--xopts Pass options to xephyr binary (e.g. -keybd ephyr,,,xkblayout=de). Needs to be last. 34 | -h|--help Show this help text and exit 35 | 36 | Examples: 37 | awmtt start (uses defaults: -C $HOME/.config/awesome/rc.lua.test -D 1 -S 1024x640) 38 | awmtt start -C /etc/xdg/awesome/rc.lua -D 3 -S 1280x800 39 | awmtt theme set zenburn -N 40 | EOF 41 | exit 0 42 | } 43 | [ "$#" -lt 1 ] && usage 44 | #}}} 45 | 46 | #{{{ Utilities 47 | awesome_pid() { pgrep -n "awesome"; } 48 | xephyr_pid() { pgrep -f xephyr_$D; } 49 | errorout() { echo "error: $*" >&2; exit 1; } 50 | #}}} 51 | 52 | #{{{ Executable check 53 | AWESOME=$(which awesome) 54 | XEPHYR=$(which Xephyr) 55 | [[ -x "$AWESOME" ]] || errorout 'Please install Awesome first' 56 | [[ -x "$XEPHYR" ]] || errorout 'Please install Xephyr first' 57 | #}}} 58 | 59 | #{{{ Default Variables 60 | # Display and window size 61 | D=1 62 | SIZE="1024x640" 63 | AWESOME_OPTIONS="" 64 | XEPHYR_OPTIONS="" 65 | # Path to rc.lua 66 | if [[ "$XDG_CONFIG_HOME" ]]; then 67 | RC_FILE="$XDG_CONFIG_HOME"/awesome/rc.lua.test 68 | else 69 | RC_FILE="$HOME"/.config/awesome/rc.lua.test 70 | fi 71 | [[ ! -f "$RC_FILE" ]] && RC_FILE="$HOME"/.config/awesome/rc.lua 72 | #}}} 73 | 74 | #{{{ Hostname Check - this is probably only useful for me. I have the same rc.lua running on two different machines 75 | HOSTNAME=$(uname -n) 76 | #}}} 77 | 78 | #{{{ Functions 79 | #{{{ Start function 80 | start() { 81 | # check for free $DISPLAYs 82 | for ((i=0;;i++)); do 83 | if [[ ! -f "/tmp/.X${i}-lock" ]]; then 84 | D=$i; 85 | break; 86 | fi; 87 | done 88 | 89 | "$XEPHYR" :$D -name xephyr_$D -ac -br -noreset -screen "$SIZE" $XEPHYR_OPTIONS >/dev/null 2>&1 & 90 | sleep 1 91 | DISPLAY=:$D.0 "$AWESOME" -c "$RC_FILE" $AWESOME_OPTIONS & 92 | sleep 1 93 | 94 | # print some useful info 95 | if [[ "$RC_FILE" =~ .test$ ]]; then 96 | echo "Using a test file ($RC_FILE)" 97 | else 98 | echo "Caution: NOT using a test file ($RC_FILE)" 99 | fi 100 | 101 | echo "Display: $D, Awesome PID: $(awesome_pid), Xephyr PID: $(xephyr_pid)" 102 | } 103 | #}}} 104 | #{{{ Stop function 105 | stop() { 106 | if [[ "$1" == all ]]; then 107 | echo "Stopping all instances of Xephyr" 108 | kill $(pgrep Xephyr) >/dev/null 2>&1 109 | elif [[ $(xephyr_pid) ]]; then 110 | echo "Stopping Xephyr for display $D" 111 | kill $(xephyr_pid) 112 | else 113 | echo "Xephyr is not running or you did not specify the correct display with -D" 114 | exit 0 115 | fi 116 | } 117 | #}}} 118 | #{{{ Restart function 119 | restart() { 120 | # TODO: (maybe use /tmp/.X{i}-lock files) Find a way to uniquely identify an awesome instance 121 | # (without storing the PID in a file). Until then all instances spawned by this script are restarted... 122 | echo -n "Restarting Awesome... " 123 | for i in $(pgrep -f "awesome -c"); do 124 | kill -s SIGHUP $i; 125 | done 126 | } 127 | #}}} 128 | #{{{ Run function 129 | run() { 130 | [[ -z "$D" ]] && D=1 131 | DISPLAY=:$D.0 "$@" & 132 | LASTPID=$! 133 | echo "PID is $LASTPID" 134 | } 135 | #}}} 136 | #{{{ Theme function 137 | theme() { 138 | # List themes 139 | theme_list() { #TODO: list only directories 140 | if [[ -d $(dirname "$RC_FILE")/themes ]]; then 141 | ls /usr/share/awesome/themes $(dirname "$RC_FILE")/themes 142 | else 143 | ls /usr/share/awesome/themes "$HOME"/.config/awesome/themes 144 | fi 145 | } 146 | case "$1" in 147 | l|list) theme_list 148 | exit 0 149 | ;; 150 | esac 151 | 152 | # Check for Beautiful library 153 | BEAUTIFUL=$(grep -c 'beautiful.init' "$RC_FILE") 154 | [[ "$BEAUTIFUL" -ge 1 ]] || errorout 'Could not detect theme library "beautiful". Exiting.' 155 | 156 | if [[ "$HOSTNAME" == laptop ]]; then 157 | curtheme=$(grep "^themelap" "$RC_FILE" | awk -F\/ '{print $2}') 158 | elif [[ "$HOSTNAME" == htpc ]]; then 159 | curtheme=$(grep "^themehtpc" "$RC_FILE" | awk -F\/ '{print $2}') 160 | else 161 | curtheme=$(grep -oP "[^\/]+(?=\/theme.lua)" "$RC_FILE") 162 | fi 163 | 164 | # Change theme 165 | theme_set() { 166 | if [[ "$HOSTNAME" == laptop ]]; then 167 | theme=themelap 168 | elif [[ "$HOSTNAME" == htpc ]]; then 169 | theme=themehtpc 170 | else 171 | theme="^beautiful\.init" 172 | fi 173 | 174 | if [[ "$file" ]]; then 175 | [[ $(theme_list | grep -c $file) -lt 1 ]] && errorout 'No such theme.' 176 | echo "changing $curtheme to $file in $RC_FILE" 177 | sed -i "/$theme.*\/theme\.lua\"/s/[^/]*\(\/theme\.lua\)/$file\1/" "$RC_FILE" 178 | else 179 | [[ $(theme_list | grep -c $2) -lt 1 ]] && errorout 'No such theme.' 180 | echo "changing $curtheme to $2 in $RC_FILE" 181 | sed -i "/$theme.*\/theme\.lua\"/s/[^/]*\(\/theme\.lua\)/$2\1/" "$RC_FILE" 182 | fi 183 | } 184 | # Print themename 185 | theme_get() { 186 | echo "$curtheme" 187 | } 188 | # Select random theme and start Xephyr instance 189 | theme_random() { 190 | themes=$(ls -1 $(dirname "$RC_FILE")/themes /usr/share/awesome/themes | grep -vE '/home/|/usr/|icons|README') 191 | file=$(echo "$themes" | sort --random-sort | head -1) 192 | theme_set 193 | D=11 && start 194 | } 195 | 196 | case "$1" in 197 | g|get) theme_get;; 198 | s|set) theme_set "${args[@]}";; 199 | r|random) theme_random;; 200 | *) errorout "unrecognized argument. Use theme (list | random | get | set )";; 201 | esac 202 | } 203 | #}}} 204 | 205 | #{{{ Parse options 206 | parse_options() { 207 | while [[ -n "$1" ]]; do 208 | case "$1" in 209 | start) input=start;; 210 | stop) input=stop;; 211 | restart) input=restart;; 212 | run) input=run;; 213 | theme) input=theme;; 214 | -B|--binary) shift; AWESOME="$1";; 215 | -C|--config) shift; RC_FILE="$1";; 216 | -D|--display) shift; D="$1" 217 | [[ ! "$D" =~ ^[0-9] ]] && errorout "$D is not a valid display number";; 218 | -N|--notest) RC_FILE="$HOME"/.config/awesome/rc.lua;; 219 | -S|--size) shift; SIZE="$1";; 220 | -a|--aopt) shift; AWESOME_OPTIONS+="$1";; 221 | -x|--xopts) shift; XEPHYR_OPTIONS="$@";; 222 | -h|--help) usage;; 223 | *) args+=("$1");; 224 | esac 225 | shift 226 | done 227 | } 228 | #}}} 229 | #}}} 230 | 231 | #{{{ Main 232 | main() { 233 | case "$input" in 234 | start) start "${args[@]}";; 235 | stop) stop "${args[@]}";; 236 | restart) restart "${args[@]}";; 237 | run) run "${args[@]}";; 238 | theme) theme "${args[@]}";; 239 | *) echo "Option missing or not recognized";; 240 | esac 241 | } 242 | #}}} 243 | 244 | parse_options "$@" 245 | main 246 | -------------------------------------------------------------------------------- /example.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gmdfalk/awmtt/92ababc7616bff1a7ac0a8e75e0d20a37c1e551e/example.jpg --------------------------------------------------------------------------------