A. Here's a basic version of xzibit being used to share a window from one desktop to another.
Untitled from Thomas Thurman on Vimeo.
The reason it's slow is because I'm using a rather noddy test server written in Python
. Next is to replace that server with one that is a) fast and b) actually transmits updates to the window properly.B. What I have on the project so far:
1. xzibit-bus-server, a simple bus based on Unix domain sockets.
This will be replaced by Telepathy tubes when everything else is stable, but for now it lets me test the system easily using a single session. The bus takes messages of the form <length><message>
, where <length>
is four little-endian bytes, and relays them to everyone listening on the bus except the sender. The first byte of <message>
is an opcode; the only defined opcode is 1, which should be followed by an IPv4 address (always 127.0.0.1 in practice) and a two-byte port number. Here is a test script
for the bus.2. A patch to Mutter/Metacity's theming code to draw the envelope buttons on the titlebar.
The Mutter plugin system doesn't currently allow for adding extra buttons, so this can't be done in the plugin. I may work on extending it later so that it can. The envelopes respond to a window's _XZIBIT_SHARE property:
3. xzibit-share, a program that gets spawned when the envelope is clicked.
- 0 or absent means the window is shareable, and gets a black envelope;
- 1 means being shared and gets a red envelope;
- 2 means being received from a remote contact and gets a cyan envelope;
- 3 means unshareable and gets no envelope.
be done in the WM, but I imagine it will become complicated enough that a separate program becomes easier to maintain. Its job is to change the _XZIBIT_SHARE property for a window. (This may be a problem under SELinux, which doesn't allow clients to modify one another's window properties, so we may need to replace it with a message sent to the root window.) It also currently puts up the "choose a contact" dialogue when you turn sharing on for a window, though the names are all fake; the name chosen is set as the _XZIBIT_CONTACT property on the window. This is currently a Perl script, but obviously would be rather faster in C.4. state-toggle, a simple program to change its own _XZIBIT_SHARE property
, used for testing the theming code before I got the previous script working.5. xzibit-plugin, a Mutter plugin that detects changes to _XZIBIT_SHARE
. If a window goes shareable, it takes care of sharing it by spawning the server and sending out a notification on the bus. It also monitors the bus for notifications and spawns the client as necessary.
, a thin wrapper around gtk-vnc (basically the same as vinagre without the UI). This is spawned by xzibit-plugin on the receiving side. Note that this can't be done directly by the WM process because WMs creating their own windows is a bad thing.
, an RFB server written in Python for testing, which is currently what is spawned on the server side when a window is shared. It only
sends static content. It will either send you a picture of Xzibit
, or take a screenshot of a given window and send that. This is how the demo above works.C. What's next.
Next we have to replace noddy-rfb-server. There are two considerations for its replacement:
- Whether we should use vino, and how much. Vino as it stands is unsuitable because it only works on a screen as a whole, but perhaps we can use part of its code. On the other hand, RFB servers are simple to write, so we could start entirely homebrew and add in parts of vino for simplicity and efficiency later. On the gripping hand, we don't really want to have to maintain our own RFB server.
- Whether it should be in-process. If it's in the WM, it can use the images of each window that the compositor already has. But again, I think this is rather beyond the current power of the plugin mechanism, so it'll require another patch. If it's separate, the WM stays more lightweight, and doesn't get slowed down by encoding RFB, but then again there's an extra process kicking around for each window. (But again, we could have one master RFB-server process that we told to listen to each window.)
Your thoughts on these questions are welcomed.D. Multiplexing.
We have two or three choices in the end:
- Have an RFB connection per window, and a custom control connection. This is what we're doing now.
- Have a single RFB connection, and use an extension to multiplex all the windows across it.
- Have a single RFB connection sending a conventional RFB image with all the windows composited on it, and use an extension to say which part is which.
The custom control connection in the first option becomes part of the extension in the others. We can quite easily switch between implementations and see which is the most efficient.E. Other things we haven't considered.
Requests to display windows aren't the only thing we'll need to send over the control connection. We also need to send information about transiency, for example, and to deal with resizing somehow.