Using Xephyr

Here's a brief howto on running nested X servers (X session inside client window of another X session) using Xephyr. This comes handy when testing things without disturbing your normal awesome desktop.

I prefer to run Xephyr and awesome in terminals of their own to see real-time stdout/stderr output.

Archlinux
/usr/bin/Xephyr is provided by xorg-server-xephyr package. Install it using:

pacman -S xorg-server-xephyr

Gentoo
/usr/bin/Xephyr is provided by the ebuild x11-base/xorg-server. The USE-Flag kdrive has to be enabled for Xephyr to be built.

Debian/Ubuntu
/usr/bin/Xephyr is provided by xserver-xephyr package. You can get it using :

# apt-get install xserver-xephyr

Fedora
/usr/bin/Xephyr is provided in the xorg-x11-server-Xephyr package.

Run Xephyr
This runs new X server in X client window:

$ Xephyr -ac -br -noreset -screen 800x600 :1


 * -ac : disable access control restrictions
 * -br : create root window with black background
 * -noreset : don't reset after last client exists
 * -screen 800x600 : Specify screen characteristics

Once running, you can change value of DISPLAY envirnomental variable to :1.0 and run X apps inside your slave X:

$ DISPLAY=:1.0 $ xterm

New xterm window will appear inside slave X.

Run awesome in Xephyr
Set the DISPLAY variable:

$ DISPLAY=:1.0

And run awesome in slave X:

$ awesome -c ~/.config/awesome/rc.lua.new

This is good to test modifications of rc.lua. In case of errors, you don't spoil your top-level instance of awesome (resulting in blank root window and no keys bound to do something).

You may also create a shell file to allow quick iterations:

Xephyr -ac -br -noreset -screen 1024x768 :1.0 & ZEPHYR_PID=$! sleep 1 DISPLAY=:1.0 awesome -c rc.lua kill $ZEPHYR_PID

(invoke awesome using the original startup-file, or a copy of this file)

Having Xephyr Grab and Release Input
One thing you'll quickly notice is that Awesome will not pass keypresses for keybindings down to the Xephyr session. To make this work, the Xephyr session should grab the keyboard. While the Xephyr window has focus, press Control-mod3-shift to have Xephyr grab focus. You will now see that the mouse can't leave the window. If you want Xephyr to let go, press control-shift (note: on some systems it should be RIGHT control-shift). If your modifiers are still not working, then there is some Xephyr wackiness going on. You can use xmodmap and xev to see what the errors are. For me, it was not recognizing the "windows key" as Super_L. I bound it within the Xephyr session using xmodmap:

$ xmodmap - keycode 133 = Super_L   # Your keycode might be different. See what it is using xev. # Press Control-D here to finish xmodmap input.

It is also somewhat likely that you are not using the default keymap for your system. You will have to rebind that too.

$ setxkbmap us dvorak

Remotely restart awesome
Get pid of slave awesome and send it SIGHUP signal:

$ pgrep awesome $ kill -s SIGHUP 

Considering that your main awesome always starts before one in xephyr, you can write the command as an one-liner and wrap into a script.

$ pgrep awesome | tail -1 | xargs kill -s SIGHUP

Or if you'd rather like to use awesome-client:

$ export DISPLAY=:1.0 $ echo 'awesome.restart' | awesome-client

Script I use to debug rc.lua
Xephyr -ac -br -noreset -screen 800x600 :1 & sleep 1 DISPLAY=:1.0 awesome -c ~/.config/awesome/rc.lua.new
 * 1) !/bin/bash
 * 2) script xepyhr-awesome
 * 3) author: dante4d 

Another script
# # # # # # # #  #  function usage {  cat <<USAGE awesome_test start|stop|restart|run start   Start nested Awesome in Xephyr stop    Stop Xephyr restart Reload nested Awesome configuration run     Run command in nested Awesome USAGE exit 0 } function awesome_pid {  /bin/pidof awesome | cut -d\  -f1 } function xephyr_pid {  /bin/pidof Xephyr | cut -d\  -f1 } [ $# -lt 1 ] && usage RC_LUA=~/.config/awesome/rc.lua.new test -f $RC_LUA || /bin/cp /etc/xdg/awesome/rc.lua $RC_LUA AWESOME=`which awesome` XEPHYR=`which Xephyr` test -x $AWESOME || { echo "Awesome executable not found. Please install Awesome"; exit 1; } test -x $XEPHYR || { echo "Xephyr executable not found. Please install Xephyr"; exit 1; } case "$1" in  start)     $XEPHYR -ac -br -noreset -screen 800x600 :1 &     sleep 1     DISPLAY=:1.0 $AWESOME -c $RC_LUA &     sleep 1     echo Awesome ready for tests. PID is $(awesome_pid)     ;;   stop) echo -n "Stopping Nested Awesome... " if [ -z $(xephyr_pid) ]; then echo "Not running: not stopped :)"      exit 0     else       kill $(xephyr_pid)       echo "Done."     fi     ;;   restart) echo -n "Restarting Awesome... " kill -s SIGHUP $(awesome_pid) ;;  run)     shift     DISPLAY=:1.0 "$@" &     ;;   *) usage ;; esac # #{ #} # # # # #
 * 1) !/bin/bash
 * 2) Run Awesome in a nested server for tests
 * 1) Requirements: (Debian)
 * 1)  apt-get install xserver-xephyr
 * 2)  apt-get install -t unstable awesome
 * 1) Based on original script by dante4d 
 * 2) See: http://awesome.naquadah.org/wiki/index.php?title=Using_Xephyr
 * 1) URL: http://hellekin.cepheide.org/awesome/awesome_test
 * 1) Copyright (c) 2009 Hellekin O. Wolf 
 * 1) This program is free software: you can redistribute it and/or modify
 * 2) it under the terms of the GNU General Public License as published by
 * 3) the Free Software Foundation, either version 3 of the License, or
 * 4) (at your option) any later version.
 * 1) This program is distributed in the hope that it will be useful,
 * 2) but WITHOUT ANY WARRANTY; without even the implied warranty of
 * 3) MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * 4) GNU General Public License for more details.
 * 1) You should have received a copy of the GNU General Public License
 * 2) along with this program.  If not, see .
 * 1) WARNING: the following two functions expect that you only run one instance
 * 2) of Xephyr and the last launched Awesome runs in it
 * 1) If rc.lua.new is missing, make a default one.
 * 1) Just in case we're not running from /usr/bin
 * 1)  /bin/pidof Xephyr | cut -d\  -f1
 * 1) [ $# -lt 1 ] && usage
 * 1) If rc.lua.new is missing, make a default one.
 * 2) RC_LUA=~/.config/awesome/rc.lua.new
 * 3) test -f $RC_LUA || /bin/cp /etc/xdg/awesome/rc.lua $RC_LUA
 * 1) Just in case we're not running from /usr/bin
 * 2) AWESOME=`which awesome`
 * 3) XEPHYR=`which Xephyr`
 * 1) test -x $AWESOME || { echo "Awesome executable not found. Please install Awesome"; exit 1; }
 * 2) test -x $XEPHYR || { echo "Xephyr executable not found. Please install Xephyr"; exit 1; }
 * 1) case "$1" in
 * 2)  start)
 * 3)    $XEPHYR -ac -br -noreset -screen 800x600 :1 &
 * 4)    sleep 1
 * 5)    DISPLAY=:1.0 $AWESOME -c $RC_LUA &
 * 6)    sleep 1
 * 7)    echo Awesome ready for tests. PID is $(awesome_pid)
 * 8)  stop)
 * 9)    echo -n "Stopping Nested Awesome... "
 * 10)    if [ -z $(xephyr_pid) ]; then
 * 11)      echo "Not running: not stopped :)"
 * 12)      exit 0
 * 13)    else
 * 14)      kill $(xephyr_pid)
 * 15)      echo "Done."
 * 16)    fi
 * 17)  restart)
 * 18)    echo -n "Restarting Awesome... "
 * 19)    kill -s SIGHUP $(awesome_pid)
 * 20)  run)
 * 21)    shift
 * 22)    DISPLAY=:1.0 "$@" &
 * 23)    usage
 * 24) esac
 * 1)    DISPLAY=:1.0 "$@" &
 * 2)    usage
 * 3) esac
 * 1)    usage
 * 2) esac
 * 1) esac

Then

awesome_test start|stop|restart|run

start   Start nested Awesome in Xephyr stop    Stop Xephyr restart Reload nested Awesome configuration run     Run command in nested Awesome

Yet another script
This script is loosely based on the above by dante4d. It adds functionality to spawn and control multiple instances of Xephyr with -D as well as using different configuration files with -C or window sizes with -S. You may also use it to change themes but there's no warranty attached to the regular expressions.

You can find the script on GitHub: https://github.com/mikar/awmtt