Gentoo Wiki


Xgl now supports multiheaded displays, but Compiz is not yet designed for them. Fortunately, it is still possible to have independent Xgl & Compiz instances working peacefully on one or many separate screens, while managing others with different window managers: this way, you do not have to limit yourself to a single screen, or to discard your third monitor because the attached video card won't run GLX.

Note: The overlay now contains an unofficial patch to Xgl that makes it report Xinerama information. Even if Compiz does not use Xinerama, this patch makes it possible for other applications that use Xinerama to properly detect display borders (Movie Players, gnome-panel etc.). When metacity runs on Xgl, this patch will become very important too.

The patch was written by Jürg Billeter ( (mailing list posting [1]). I have revised the patch into a form that applies cleanly to current CVS (end of April). It is here [2].

Duncanthrax 14:08, 28 April 2006 (UTC)

Also don't forget to start Xgl with the argument +xinerama to enable xinerama support


Getting a multiscreens (no xinerama) X11 system up

Basically, the prerequise to this is to get your modular X11 implementation configured so it runs a multiscreen display; this is a well covered subject, see for instance the Dual Monitors HOWTO -- just make sure at least one screen does meet the requirements for XGL (see the Xgl HOWTO). Of course, you do not need all of your screens to do so.

Set the WMs on a per-screen basis

For the sake of simplicity, we will consider the case of one display (:0) with two screens (:0.0 and :0.1). Screen :0.0 will be the main screen, on which we want to run Xgl and Compiz, while screen :0.1 is the secondary one, when we will run any other window manager. Nothing really changes if you have more screens to manage -- just adapt to suit your needs.

fluxbox -screen 1
Why? Because most WMs will have conflicting key-bindings with Compiz, incorrect or conflicting focus behavior applied on the Xgl window.
File: $HOME/.twmrc
One problem with twm though is that is uses an explicit interactive placement policy by default, that is highly impractical if you ever want to run other things on screen :0.0, such as a screen saver or a movie later on; that's why I wrote ffwm:
File: ffwm.c
/* -----------------------------------------------------------------------------
   ffwm - Force Focus Window Manager
        The X11 WM that makes twm looks fancy

   Written by Sylvain Fourmanoit <>, 2006.
   This code is public domain.

   What it does 
   Technically, ffwm does not even qualify as a WM: all it does is to connect to
   the current display, and force the input focus on all top-level windows
   children of the default root.

   It was written to allow correct focus behavior on multi-heads displays with a
   different WMs on different screens.

   How to compile
   Without output: cc -lX11 -o ffwm ffwm.c
   With output   : cc -DDEBUG -lX11 -o ffwm ffwm.c

   The only thing you need is some X11 implementation with libraries and headers,
   and a ANSI C compiler with support for variadic macros.

#include <X11/Xlib.h>

  Debug code: set to one to get some output.
#ifdef DEBUG
#include <stdio.h>
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define debug(...) do { } while (0)

int hdlr(Display * dpy, XErrorEvent * xev) { debug("Error!\n"); return 0; }

int main() {
  int i, nchildren;
  Display * dpy;
  Window * children, dummy;
  XEvent xev;

  if ((dpy = XOpenDisplay(NULL))) {
    if (XQueryTree(dpy, DefaultRootWindow(dpy), &dummy, &dummy, 
                   &children, &nchildren)) {
      debug("Number of child window: %d\n", nchildren);
      if (nchildren)
        XSetInputFocus(dpy, children[0], RevertToPointerRoot, CurrentTime);
      for (i=0; i<nchildren; ++i) {
        debug("Listen for window %d: 0x%x\n", i, children[i]);
        XSelectInput(dpy, children[i], EnterWindowMask);

    XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureNotifyMask);
    debug("Now listening for events on display %p\n", dpy);
    while (!XNextEvent(dpy, &xev)) {
      switch (xev.type) {
      case CreateNotify:
        debug("Create window: 0x%x\n", ((XCreateWindowEvent*)&xev)->window);
        XSelectInput(dpy, ((XCreateWindowEvent*)&xev)->window, EnterWindowMask);
      case EnterNotify:
        debug("Enter window: 0x%x\n", ((XEnterWindowEvent*)&xev)->window);
        XSetInputFocus(dpy, ((XEnterWindowEvent*)&xev)->window,
                       RevertToPointerRoot, CurrentTime);
  } else debug("Could not open the display\n");
  return 0L;

Basically, ffwm does the same job as twm configured as above; the only difference is that it won't try to enforce any placement policy on future windows created on :0.0.

Making life better: the other (optional) tweaks

By now, things should already be working fine: we would have a normal fluxbox config running on screen 1, and Xgl running soomthly as a rootless server (most on the time as our :1 display) on screen :0.0 with Compiz as our window manager. Depending on how we configured X11 in the first place, we would be able to switch from one screen to the other with the pointer transparenty.

Adding keybindings

I do not know about you, but one thing that enhances my productifity is having fast access to the same programs on the same key combinations on the current screen, regarless of what system I use. The easy solution to that is to use xbindkeys xbindkeys (in portage), in combination with some "display mangling" script. For instance, imagine that sometime, I run metacity on both my screens, and other time, I run the previously explained setting (Xgl window on :0.0 that act as a server for :1, and fluxbox on :0.1) -- when running metacity, I will want to launch the programs on the default screen, but when I run Xgl/Fluxbox, I will want to run the programs not on :0.0 not, but on :1.0:

#! /bin/bash

function managed() {   # Based on the fact that ffwm doesn't set NET_ atoms on :0.0 root
   DISPLAY=:0.0 xprop -root | grep -q NET

test "x$1" == x && exit 1


if test "x$CMD" == "xterm" ; then
   CMD="aterm +sb -tr -bg black -fg White"
   managed || {
      test "x$DISPLAY" == "x:0.0" && \
        CMD="urxvt +sb -depth 32 -fg grey90 -bg rgba:0000/0000/0000/9999"

managed || {
   test "x$DISPLAY" == 'x:0.0' && DISPLAY=:1.0

exec $CMD $*

This way, when invoking: some_program

The correct display will be inferred each time. Moreover, launching: term

Will infere a different pseudo terminal with real transparency (urxvt) than the normal aterm when launch over Xgl.

I can then set my favorite launch settings uing xkbinkeys:

File: $HOME/.xbindkeysrc

"xlaunch term"

"xlaunch sshcall"

"xlaunch emacs"

"xlaunch firefox"

"xlaunch term -e pine"


One side advantage of this method is that it is easy to run any program on the "unmanaged" :0.0 when needed, such as screensaver, instead than through the Xgl server; one less indirection layer means less cycles lost; just include the usual:

DISPLAY=:0 xscreensaver -no-splash &

in the session initialisation script.

movie player

Same remark apply to movie players: I do watch most of my movies fullscreen, forcing the display, through a simple lplayer wrapper script to mplayer:

File: lplayer
#! /bin/sh

export DISPLAY=:0.0
xscreensaver-command -exit
/usr/bin/mplayer -loop 0 -fs -zoom $*
xscreensaver -no-splash &
Retrieved from ""

Last modified: Thu, 14 Aug 2008 03:50:00 +0000 Hits: 9,855