A while ago, I spent some time staring at gdb wondering why a passive grab didn't activate. Turns out it wasn't a bug in the server after all, it was a bug in the program. The modifiers were set like this:
modifiers.modifiers = AnyModifier;
AnyModifier is a define that comes from the core protocol:
#define AnyModifier (1<<15) /* used in GrabButton, GrabKey */
but XI2 provides its own define:
#define XIAnyModifier (1U << 31)
Passive grabs only activate if the modifiers match the current modifier state. An XI2 grab that uses AnyModifier won't activate as expected - AnyModifier looks like a normal modifier bitmask to the server.
I wanted to reply to the reporter with "don't mix core and XI2 defines" but there's one problem: you couldn't currently write an XI2 application without using some core defines (e.g. GrabModeAsync). I've looked through the protocol spec and added those defines that previously forced clients to mix input-related constants. New defines now available are:
- XIPropModeReplace, XIPropModePrepend, and XIPropModeAppend
- XIGrabModeSync and XIGrabModeAsync
- XIGrabSuccess, XIAlreadyGrabbed, XIGrabInvalidTime, XIGrabNotViewable, and
- XIOwnerEvents, XINoOwnerEvents
These will be available to any application compiling against XI 2.1 headers. All the above are identical to the core defines. Clients are still expected to use CurrentTime and None from the core protocol headers since neither of those two is input-related. For applications building against 2.1, the guideline to using XI2 can only be summarised as: Only use a define Foo if there is no equivalent XIFoo version.
The libXi man pages have also been updated where applicable to point out the new defines.
Many thanks to Timur Kristóf for uncovering this.
XIOwnerEvents and XINoOwnerEvents are new additions to improve readability. They simply map to True/False.