Using Xephyr

From awesome
Jump to: navigation, search

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.

Get Xephyr[edit]

Archlinux[edit]

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

pacman -S xorg-server-xephyr

Gentoo[edit]

/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[edit]

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

 # apt-get install xserver-xephyr

Fedora[edit]

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

Run Xephyr[edit]

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[edit]

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)

More[edit]

Having Xephyr Grab and Release Input[edit]

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[edit]

Get pid of slave awesome and send it SIGHUP signal:

 $ pgrep awesome
 $ kill -s SIGHUP <pid_of_awesome_in_xephyr>

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[edit]

#!/bin/bash
# script xepyhr-awesome
# author: dante4d <dante4d@gmail.com>
Xephyr -ac -br -noreset -screen 800x600 :1 &
sleep 1
DISPLAY=:1.0 awesome -c ~/.config/awesome/rc.lua.new

Another script[edit]

#!/bin/bash
# Run Awesome in a nested server for tests
#
# Requirements: (Debian)
#
#  apt-get install xserver-xephyr
#  apt-get install -t unstable awesome
#
# Based on original script by dante4d <dante4d@gmail.com>
# See: http://awesome.naquadah.org/wiki/index.php?title=Using_Xephyr
#
# URL: http://hellekin.cepheide.org/awesome/awesome_test
#
# Copyright (c) 2009 Hellekin O. Wolf <hellekin@cepheide.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
# 

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
}

# WARNING: the following two functions expect that you only run one instance
# of Xephyr and the last launched Awesome runs in it

function awesome_pid() 
{
  /bin/pidof awesome | cut -d\  -f1
}
 
function xephyr_pid()

{
  /bin/pidof Xephyr | cut -d\  -f1
}

[ $# -lt 1 ] && usage

# If rc.lua.new is missing, make a default one.
RC_LUA=~/.config/awesome/rc.lua.new
test -f $RC_LUA || /bin/cp /etc/xdg/awesome/rc.lua $RC_LUA

# Just in case we're not running from /usr/bin
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
#
#{
#  /bin/pidof Xephyr | cut -d\  -f1
#}
#
#[ $# -lt 1 ] && usage
#
## If rc.lua.new is missing, make a default one.
#RC_LUA=~/.config/awesome/rc.lua.new
#test -f $RC_LUA || /bin/cp /etc/xdg/awesome/rc.lua $RC_LUA
#
## Just in case we're not running from /usr/bin
#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

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[edit]

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