Hello everybody (esp. Peter ;-), I tried to get to the bottom of my lost XI_Enter events today. As I mentioned, I'm not getting those events which should occur when a cursor is inside the window when it is first created. I've experimented a bit with the relevant part from xinput, and I've stripped it down to a minimal example which shows the problem (source code attached).
It seems to be some kind of race condition: if there is any significant delay between creation of the window and the first call to XNextEvent, then the XI_Event is very unlikely to arrive, as opposed to the standard EnterNotify. After removing the sleep(1) in the code, it works almost always. The standard events are never lost, neither are any subsequent XI_Enter or XI_Leave events. It's only the very first one, and only if the cursor is already inside the window upon creation. My xserver, inputproto, libXi and xinput have been rebuilt from FDO git master yesterday. I'd really appreciate it if some of you with more inside knowledge could have a look at this and tell me if I am forgetting something.. Yours, Florian -- 0666 - Filemode of the Beast
#include <X11/Xlib.h> #include <X11/extensions/XInput2.h> #include <string.h> #define BitIsOn(ptr, bit) (((unsigned char *) (ptr))[(bit)>>3] & (1 << ((bit) & 7))) #define SetBit(ptr, bit) (((unsigned char *) (ptr))[(bit)>>3] |= (1 << ((bit) & 7))) static Window create_win(Display *dpy) { Window win = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, 200, 200, 0, CopyFromParent, InputOutput, CopyFromParent, 0,0 ); //Window win = XCreateSimpleWindow(dpy, win, 0, 0, 400, 400, 0, 0, WhitePixel(dpy, 0)); XSelectInput(dpy, win, StructureNotifyMask | SubstructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | VisibilityChangeMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonMotionMask ); XMapWindow(dpy, win); XFlush(dpy); return win; } int main( int argc, char *argv[] ) { Display *display = XOpenDisplay(NULL); XIEventMask mask; Window win; win = create_win(display); XSync(display,False); /* Select for motion events */ mask.deviceid = XIAllMasterDevices; mask.mask_len = 2; mask.mask = calloc(mask.mask_len, sizeof(char)); SetBit(mask.mask, XI_ButtonPress); SetBit(mask.mask, XI_ButtonRelease); SetBit(mask.mask, XI_Motion); SetBit(mask.mask, XI_Enter); SetBit(mask.mask, XI_Leave); XISelectEvents(display, win, &mask, 1); free(mask.mask); XSync(display,False); // removing this sleep increases the probability of // actually receiving the first XI_Enter sleep(1); while(1) { XEvent xev; XNextEvent(display, &xev); //fghPrintEvent(&xev); printf("\n"); XIEvent ev = *((XIEvent*)&xev); if (ev.type == EnterNotify) printf("got standard EnterNotify\n"); if (ev.type == LeaveNotify) printf("got standard LeaveNotify\n"); if (ev.type == GenericEvent) { XIDeviceEvent *event = (XIDeviceEvent*)&ev; switch (event->evtype) { case XI_Enter: printf("XI_Enter\n"); break; case XI_Leave: printf("XI_Leave\n"); break; default: break; } } XIFreeEventData(&ev); } XDestroyWindow(display, win); return 0; } // build with gcc -lX11 -lXi -Wall -o xi2test xi2test.c
_______________________________________________ xorg mailing list xorg@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/xorg