XGL/MultiHeads
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.
The patch was written by Jürg Billeter (j@bitron.ch) (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
Contents |
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.
- First, we start a rootless Xgl window on the unmanaged screen :0.0 full screen, and the associated Compiz machinery, as explained in the Xgl HOWTO.
- Second, we start a WM right on screen :0.1, making sure we do not manage the other screens. For instance:
fluxbox -screen 1
- Why? Because most WMs will have conflicting key-bindings with Compiz, incorrect or conflicting focus behavior applied on the Xgl window.
- Finally, we start some completely unobtrusive window manager on screen :0.0, which implements focus on mouse over, so that our full-screen Xgl window gets the focus when appropriate, while not ever getting decorated. A good candidate for that is twm (installed by default with modular X11), used with a resources file file such as:
| File: $HOME/.twmrc |
NoTitle NoHighlight |
- 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 <syfou@users.sourceforge.net>, 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__)
#else
#define debug(...) do { } while (0)
#endif
/*----------------------------------------------------------------------------*/
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))) {
XSetErrorHandler(hdlr);
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);
break;
case EnterNotify:
debug("Enter window: 0x%x\n", ((XEnterWindowEvent*)&xev)->window);
XSetInputFocus(dpy, ((XEnterWindowEvent*)&xev)->window,
RevertToPointerRoot, CurrentTime);
default:
break;
}
}
XCloseDisplay(dpy);
} 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:
| File: xlaunch.sh |
#! /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
CMD=$1
shift
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"
}
fi
managed || {
test "x$DISPLAY" == 'x:0.0' && DISPLAY=:1.0
}
exec $CMD $*
|
This way, when invoking:
xlaunch.sh some_program
The correct display will be inferred each time. Moreover, launching:
xlaunch.sh 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 |
"dualmouse" Control+Tab "xlaunch term" Mod1+F1 "xlaunch sshcall" Mod1+F2 "xlaunch emacs" Mod1+F3 "xlaunch firefox" Mod1+F4 "xlaunch term -e pine" Mod1+F6 |
screensaver
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 & |
Created by NickStallman.net, Luxury Homes Australia
Real estate agents should be using interactive floor plans and list their apartments, townhouses and units.
