/* gcc -Wall `pkg-config --libs --cflags x11 xi` focusout.c -o focusout */ #include #include #include static const char *notify_modes[] = { "Normal", "Grab", "Ungrab", "Grabbed" }; static const char *notify_details[] = { "Ancestor", "Virtual", "Inferior", "Nonlinear", "NonlinearVirtual", "Pointer", "PointerRoot", "DetailNone" }; int main (void) { Display *display; Window toplevel, mid, focus; XEvent event; XIEnterEvent *ev; int opcode, firstevent, firsterror; unsigned char mask[XIMaskLen (XI_LASTEVENT)]; XIEventMask event_mask; display = XOpenDisplay (NULL); if (XQueryExtension (display, "XInputExtension", &opcode, &firstevent, &firsterror)) { int major, minor; major = 2; minor = 0; if (XIQueryVersion (display, &major, &minor) == BadRequest) return 1; } else return 1; toplevel = XCreateSimpleWindow (display, DefaultRootWindow (display), 10, 10, 10, 10, 0, 0, 0); mid = XCreateSimpleWindow (display, toplevel, 0, 0, 10, 10, 0, 0, 0); focus = XCreateSimpleWindow (display, mid, -1, -1, 1, 1, 0, 0, 0); XISetMask (mask, XI_KeyPress); XISetMask (mask, XI_KeyRelease); XISetMask (mask, XI_FocusIn); XISetMask (mask, XI_FocusOut); event_mask.deviceid = XIAllMasterDevices; event_mask.mask = mask; event_mask.mask_len = sizeof (mask); XISelectEvents (display, toplevel, &event_mask, 1); XISelectEvents (display, mid, &event_mask, 1); XISelectEvents (display, focus, &event_mask, 1); XSelectInput (display, toplevel, StructureNotifyMask | PropertyChangeMask | FocusChangeMask); XSelectInput (display, mid, KeyPressMask | KeyReleaseMask | FocusChangeMask); XSelectInput (display, focus, KeyPressMask | KeyReleaseMask | FocusChangeMask); XMapWindow (display, focus); XMapWindow (display, mid); XMapWindow (display, toplevel); while (XNextEvent (display, &event) == 0) { switch (event.type) { case FocusIn: XSetInputFocus (display, focus, RevertToParent, CurrentTime); case FocusOut: printf (" %s %s %7s %s\n", event.type == FocusIn ? "IN " : "OUT", event.xany.window == toplevel ? " top " : event.xany.window == mid ? " mid " : event.xany.window == focus ? "focus" : " ??? ", notify_modes[event.xfocus.mode], notify_details[event.xfocus.detail]); break; case GenericEvent: XGetEventData (display, &event.xcookie); ev = (XIEnterEvent *) event.xcookie.data; switch (ev->evtype) { case XI_FocusIn: XSetInputFocus (display, focus, RevertToParent, CurrentTime); case XI_FocusOut: printf ("XI2 %s %s %7s %s\n", ev->evtype == XI_FocusIn ? "IN " : "OUT", ev->event == toplevel ? " top " : ev->event == mid ? " mid " : ev->event == focus ? "focus" : " ??? ", notify_modes[ev->mode], notify_details[ev->detail]); break; default: break; } XFreeEventData (display, &event.xcookie); break; default: break; } } return 0; }