3
It would be really, really, nice to have an X equivalent of
4
screen(1) -- i.e., a way to run some X apps on a remote host, then
5
disconnect your local host and reattach later, and have them still
8
VNC does part of this, but you can't make it "rootless",
9
i.e. have individual windows show up as individual windows. (This is
10
esp. annoying to me because in my use case for this, the remote
11
windows are data visualizations, and sometimes I want to see them on
12
my little laptop screen and sometimes on my giant LCD, and picking a
13
fixed root window size to use for both cases sucks.)
15
NX does this, but it is completely #$@)#@$ing insane to deal with.
16
NoMachine are the last of the great 80s unix software vendors.
18
So here's a simple approach: Start up an Xvfb on the remote server to
19
be the detachable X session. Run a special window manager on it.
20
This window manager enables compositing on everything, watches for
21
damage, and on another socket listens for connections from a special
22
program. This special program attaches, gets a list of top-level
23
windows, and mirrors them onto a real display by opening one toplevel
24
for each real toplevel. The connection between the wm and the special
25
program is basically forwarding events (mouse, keyboard, configure,
26
focus, ClientMessage), some special queries, and maybe damage from the
27
real X display, and receiving notifications of new windows, new
28
metadata on windows, cursor changes, grabs, and compressed images of
31
The tricky parts on the window manager side are: sending the minimal
32
amount of data (for instance, watching how the redraw queue drains and
33
collapsing updates when possible); forwarding X events to clients
34
correctly (this needs XTest); handling grabs and override-redirect
35
windows properly; any necessary keyboard translation; figuring out
36
what cursors are wanted where.
38
The tricky parts for the client side are: just completeness, mostly --
39
grokking focus and grabs, positioning windows, enabling cursors, etc.
42
The trickiest thing overall, actually, may be maintaining stacking
43
order sync. Before processing any mouse event, stacking order must be
44
accurate. But how to achieve this? On the client side, it's probably
45
not actually possible. We get basically *nothing* to work with -- we
46
can work out the stacking order by hand, using a giant storm of
47
XQueryTree calls, but the problem with this approach is that we have
48
no way to get reliable notification when the stacking order has
49
changed. (Well, we could select for ConfigureNotify and some other
50
stuff on like every window in the world, but that probably isn't
51
useful.) So the only thing we actually have to work with is
52
_NET_CLIENT_LIST_STACKING. We can be notified when this is changed,
53
but then there's a race condition -- we get the notification that it's
54
changed (A), the mouse sends some events, it changes again (B), we
55
fetch the new stacking order, and deliver the events to be interpreted
56
against stacking order B. This appears to be unavoidable, though,
59
The other really tricky bit is translating keyboard events from client
60
to server. I think the approach to take is: client just packs up
61
events into logical form (including "nuisance" bits!) and sends them
62
off. Server unpacks them into keycode/mask, then uses XQueryPointer
63
(!) to determine the current mask, and then issues keystrokes to
64
adjust the mask to what it should be, and then issues the actual
67
NOTE: MOTION_NOTIFY and BUTTON_PRESS (and BUTTON_RELEASE) all include
68
mask bits too, so they should all use the above logic as well.
72
-- register as WM, so we will be able to rearrange children of the
73
root with impunity, knowing that no other wm dare mess with us
74
-- request substructure events on the root
75
-- enable automatic composition of all children of the root
76
-- gather up all pre-existing windows, if any
77
-- start listening for slave attachments
89
kill window for reals (probably a special out-of-band request from
92
"here is the current stacking"
96
new window (automatically mapped)
97
-- type, location, size, override or not, title, icon, etc.
98
window changed (in any of the above properties)
99
window went away (unmapped)
100
window configure request (including stacking)
101
current cursor changed (to ...)
102
start/release active grab on keyboard or mouse
106
maintaining stacking sync is reasonably hard -- require
107
a WM on the slave side that supports _NET_CLIENT_LIST (and monitor
109
we may want a cache for cursors
110
do we force the slave to keep a cache of window contents, so it
111
never has to request them from the master?
112
keyboard mapping, modifier maps
113
the "frozen" state that input devices can go into
114
can we really reliably detect grab/ungrab events?
119
XSync-based resize coordination as defined by EWMH (but the master
120
might want to do this locally)
124
generic ClientMessages
125
extended input events (XInput) (XTest does support these though,
126
even if the version whose proto spec is easiest to find does not)