BurntSushi / xgb

The X Go Binding is a low-level API to communicate with the X server. It is modeled on XCB and supports many X extensions.
Other
488 stars 75 forks source link

Constructors for xproto.ClientMessageDataUnion always expects 20 bytes #2

Closed guelfey closed 11 years ago

guelfey commented 11 years ago

I didn't look at the code of the other "constructors", but xproto.ClientMessageDataUnionData32New()` always expects a slice with 5 elements. It's very annoying if you have to pass additional arguments and it shouldn't be too hard to implement this or at least mention it in the documentation.

BurntSushi commented 11 years ago

I'm not sure I follow. ClientMessages are defined by the X protocol specification to always contain 20 bytes of user data:

The data always consists of either 20 8-bit values or 10 16-bit values or 5 32-bit values, although particular message types might not make use of all of these values.

If you don't use a value, the convention is to set it to zero.

XGB provides convenience constructors for creating 8-bit, 16-bit or 32-bit versions of ClientMessage events.

It's very annoying if you have to pass additional arguments

You can't. ClientMessages can only have 5 32 bit values.

Let me know if this clarifies things, or if I've misunderstood.

guelfey commented 11 years ago

Ok, I didn't read the protocol spec for ClientMessages. I used Xlib when programming in C, and you didn't have to initialize all values if the client wouldn't need all of them. For example, most of the ICCCM events only need two 32bit values, so you have to pass additional values that aren't used.

I'd suggest to either use arrays with fixed sizes or to set missing bytes / values to 0.

BurntSushi commented 11 years ago

Ok, I didn't read the protocol spec for ClientMessages.

Yup. You should consider the spec as documentation for XGB. The API of XGB (and XCB) is supposed to mirror the spec precisely.

I used Xlib when programming in C, and you didn't have to initialize all values if the client wouldn't need all of them.

XGB is comparable only to XCB, not Xlib. Xlib often provides conveniences and abstractions that hide the X protocol. It is the goal of XCB (and consequently, XGB) not to do that.

My library, xgbutil, provides abstractions and conveniences that might be comparable to Xlib (or more likely, xcb-util).

For example, most of the ICCCM events only need two 32bit values, so you have to pass additional values that aren't used.

You should be using xevent.NewClientMessage in xgbutil. Or, if you're really just using ICCCM, then use the xgbtuil/icccm package.

I'd suggest to either use arrays with fixed sizes or to set missing bytes / values to 0.

Arrays are a possibility, but they would cause an inconsistency in the public API. (Arrays are not often used directly in Go.) Plus, while ClientMessages are of a fixed size, this may not be true of other union types in X. So that arrays don't work in the general case.

I'm also not sure it's wise to set missing bytes/values to 0, since this may not be true of all union types through the X protocol extensions.

Remember, the xproto/xproto.go file is auto-generated. I am very weary of adding special exceptions to the code generator.

guelfey commented 11 years ago

You should be using xevent.NewClientMessage in xgbutil.

Oh, I must have overlooked this function. This, of course, does exactly what I want.

Or, if you're really just using ICCCM, then use the xgbtuil/icccm package.

While xgbutil/icccm can check if some client messages are DELETE_WINDOW or TAKE_FOCUS messages, it doesn't provide functions for sending them, so you need to use the "raw" protocol (or xevent) here.

BurntSushi commented 11 years ago

While xgbutil/icccm can check if some client messages are DELETE_WINDOW or TAKE_FOCUS messages, it doesn't provide functions for sending them, so you need to use the "raw" protocol (or xevent) here.

Absolutely right. Wingo does it here.

You must be writing a WM :-)