I've noticed an issue with grabs as well, not sure if it's related to
this one.  It's really easy to reproduce, though:  All you need is a
little test client that passively grabs button 1 on the MD (like the one
attached).  A passive core grab will do as well.  What happens is that
(1) clients selecting for core events will receive emulated pointer
events despite the passive grab and (2) sometimes ButtonRelease events
go missing (this goes both for the grabbing and non-grabbing clients,
but not necessarily at the same time).

Tom

On 10/15/2012 11:09 PM, Peter Hutterer wrote:
> On Fri, Oct 12, 2012 at 03:38:24PM +0200, Thierry Reding wrote:
>> Hi,
>>
>> I've been seeing a very strange issue. Originally this was observed when
>> using a browser with an onscreen keyboard. It would sometimes happen
>> that the keys on the keyboard would get stuck and be repeatedly sent.
> 
> But on the whole, this issue looks convoluted enough that you may have to
> write a little test application to reliably reproduce this.
> 
> Cheers,
>    Peter
/* gcc -Wall grab.c -o grab -lXi -lX11 */

#include <X11/Xlib.h>
#include <X11/extensions/XInput2.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

Display *dpy;
Window root;
int opcode;

void init_xi2() {
	int event, error;
	int major = 2, minor = 0;
	if (!XQueryExtension(dpy, "XInputExtension", &opcode, &event, &error) ||
			XIQueryVersion(dpy, &major, &minor) == BadRequest ||
			major < 2) {
		printf("Error: XI2 required\n");
		exit(EXIT_FAILURE);
	}
}

void grab(int dev) {
	unsigned char mask_data[2] = {0,}; 
	XISetMask(mask_data, XI_ButtonPress);
	XISetMask(mask_data, XI_ButtonRelease);
	XIEventMask mask = { XIAllDevices, sizeof(mask_data), mask_data };
	XIGrabModifiers mods = { XIAnyModifier };
	XIGrabButton(dpy, dev, 1, root, None, GrabModeAsync, GrabModeAsync, False, &mask, 1, &mods);
}


int main(int argc, char *argv[]) {
	dpy = XOpenDisplay(NULL);
	root = DefaultRootWindow(dpy);

	init_xi2();
	if (argc < 2 || atoi(argv[1]) <= 0) {
		printf("Usage: %s <device number>\n", argv[0]);
		return EXIT_FAILURE;
	}
	int dev = atoi(argv[1]);

	grab(dev);

	while (true) {
		XEvent ev;
		XNextEvent(dpy, &ev);
		if (XGetEventData(dpy, &ev.xcookie) && ev.xcookie.extension == opcode) {
			switch (ev.xcookie.evtype) {
				case XI_ButtonPress:
					printf("Press\n");
					break;
				case XI_ButtonRelease:
					printf("Release\n");
					break;
			}
		}
		XFreeEventData(dpy, &ev.xcookie);
	}

	return EXIT_SUCCESS;
}
_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to