[Xcb] [xpyb] SendEvent considered unusable

Eamon Walsh ewalsh.mailinglists at gmail.com
Thu Feb 4 19:47:30 PST 2010

Julien Danjou wrote:
> Hi,
> I've played with SendEvent today. It seems totally unusable as it is.
> For people not knowing xpyb, here is how it is defined:
>   def SendEvent(self, propagate, destination, event_mask, event):
>       ...
>       buf.write(str(buffer(array('b', event))))
>       ...
> Meaning event has to be a buffer actually. I had to write:
>     buf = struct.pack("BB2xIIII12x", 
>                       33, # XCB_CLIENT_MESSAGE 
>                       32, self.xid, Atom("WM_PROTOCOLS").value, 
>                       Atom("WM_TAKE_FOCUS").value, 
>                       xcb.xproto.Time.CurrentTime) 
> To send a message, because you cannot instanciante a
> ClientMessageEvent without having a buffer to initialize it, anyway.
> We also miss the opcode of events (like XCB_CLIENT_MESSAGE is 33).
> Eamon, do you think there is something we could do about that?
> I agree the generated code is correct, but that seems totally
> unusable to me.

OK.  So I see 3 issues here:

1. this issue with SendEvent is not properly documented in the xpyb
2. xpyb doesn't provide symbolic constants for event types.
3. xpyb doesn't allow wire objects to be instantiated directly and
filled out by the program.

Of these issues, 1 and 2 are relatively easy to fix, and I will try and
do so soon.  Issue 3 however is more of a challenge.  It would require
code to be generated from the XML to support writing to a structure
field instead of just unpacking it.  Properly supporting all the things
that can go in a structure (lists, unions, variable-length things) will
be non-trivial.

In the meantime, since the actual events that are typically sent through
SendEvent are limited to ClientMessage and a few others, you could  turn
the "pack" code above into a utility function ("create_client_event"). 
I will update the xpyb documentation to make a note of this and include
a sample helper function.

> PS: I already have been bitten by GetProperty returning
> xcb.List of Byte being a PITA to convert myself, and now that,
> it is too much for me. :-)

This issue is documented, but a helper function that unpacks the reply
value into an array of the appropriate cardinal size would be useful
here.  I'll add one to the docs.

xpyb is a thin wrapper and, unlike C, Python doesn't have the luxury of
being able to use the wire representation directly as program data and
vice versa.  So pack/unpack stuff like this is unfortunately going to be
necessary in a few cases.

There is a project out there called the Python X Library
(http://python-xlib.sourceforge.net/) that provides a more
object-oriented interface to the X protocol (windows are objects, for
example, and window-related protocol requests are methods on the
object)  I have been meaning to look at the potential for porting it on
top of xpyb.  It would allow a lot of xpyb's raw corners such as
SendEvent and GetProperty to be hidden.  However it may also hide some
of the flexibility of XCB, being more of an Xlib style interface. 
Haven't looked at it closely.

--Eamon W.

More information about the Xcb mailing list