|
Swallowing X apps
To Swallow an X app, you basically reparent the toplevel window
of the desired app, to find the apps window the method is to continually
XQueryTree on the root window, and XFetchName on each window until the
name of the app you want to swallow appears. Then you just reparent that
window. A number of issues arise here.
-
The window manager desires to reparent
that window itself and put its decoration windows around it. So by the
time your program gets around to looking for the window it could be the
child or the child of a child of a window manager window. Thus you have to
XQueryTree to 3 levels down. Window managers such as twm and afterstep only put one window
between the app window and the root window, whilst the CDE and fvwm etc place
two. This appears to be the max in practice, but i havent checked
Enlightment which id guess might even do more. Once the window has been found,
the window manager will probably be managing it, so you must inform it to no
longer worry about that window, which is done via XWithdrawWindow.
-
When the window is withdrawn prior to being reparented then according to
ICCCM Version 2.0, Section 4.1.4 when a client withdraws a window it should
wait until the WM_STATE property is updated or removed by the windowmanager
before reparenting the window, the code (at the end) i use doesn't do this
yet, so i moronically reparented loads of times and eventually
it gets reparented. I figured it out, but the code here does the wrong thing.
The full XSwallow (http://www.csn.ul.ie/~caolan/docs/XSwallow.html) netscape
plugin which prompted this article now does the right thing.
-
The program to be swallowed must appear on the screen before being swallowed, so
theres a brief time before the window appears and when its reparanted to the
swallowing app. To solve this irritation you could run the program to be
swallowed as an icon and/or off screen, something like
xload -iconic -geometry +9000+9000
-
Another issue is that a window manager that requires you to
place a programs window manually when its run will be awkward to use, as
you'll have to manually place the program thats going to be swallowed, then
have it dissappear and reappear. Running it iconic though appears to solve this
little annoyance for all the window managers that i used that have this behaviour
(twm/afterstep). On the other hand fvwm95 wont get rid of the window if it is
run iconic, for this window manager you have to run the app non-iconic or
the window wont go away.
-
Now yet another issue is
the kind of behaviour that the window manager WindowMaker exhibits
in which an application that is run under it will be assigned a slot
on its dock, even after the application is reparented that icon remains, this
can be over come by telling WindowMaker that it is to no longer care about
this app by setting the WMHints of the swallowed app so that the window_group
member is changed to the root window of the screen, doing that will get
WindowMaker to ignore the app
Seeing as the swallowing app has to look for the windows name it makes sense
to make that name unique. So you could run the app to be swallow with a
unique name (done usually via a -name commandline option) to make the chance
of the swallowing program swallowing the wrong program minimal.
The source of a small program that swallows any X app that calls itself
"barf" is available (http://www.csn.ul.ie/~caolan/pub/X/xswallow.c)
compile it like this
gcc -o xswallow xswallow.c -lXaw -lXt -lX11 -L/usr/X11R6/lib
run thus
./xswallow &
and get it to swallow for example xload like this
./xload -name barf &
apps window, it really dumb but shows the swallowing clearly. Once the app
is swallowed, its just another window and the managing of child windows is
outside the scope of this likkle hack.
All told this looks like a very handy way to include X programs within others,
without pain.
Links
Caolan McNamara (1996) <caolan@skynet.ie>
|