// gcc -o wm_take_focus wm_take_focus.c -lX11 #include #include #include Display *display; int screen_num; Window root; Atom XA_WM_TAKE_FOCUS; Window create_window(char * name, Window parent, int x, int y, int width, int height) { XSizeHints sh; XWMHints wmh; Window win = XCreateSimpleWindow(display, parent, x, y, width, height, 2, // border width BlackPixel(display, screen_num), WhitePixel(display, screen_num)); XStoreName(display, win, name); XSelectInput(display, win, FocusChangeMask | ButtonPressMask | ButtonReleaseMask ); sh.width = width; sh.height = height; sh.x = x; sh.y = y; sh.flags = USPosition | USSize; XSetWMNormalHints(display, win, &sh); wmh.input = False; wmh.flags = InputHint; XSetWMHints(display, win, &wmh); Atom protocols[1]; protocols[0] = XA_WM_TAKE_FOCUS = XInternAtom (display, "WM_TAKE_FOCUS", True); XSetWMProtocols (display, win, protocols, 1); return win; } int main(int argc, char **argv) { Window window, win; XEvent ev; char *display_name = NULL; if ((display = XOpenDisplay(display_name)) == NULL) { fprintf(stderr, "Couldn't open %s\n", XDisplayName(display_name)); return -1; } screen_num = DefaultScreen(display); root = RootWindow(display, screen_num); window = create_window("TestFrame", root, 100, 100, 200, 100); XMapWindow(display, window); XFlush(display); XSync(display, False); while (1) { XNextEvent(display, &ev); int i = 0; for (i = 0; i < 2; i++) { win = ev.xany.window; if (win == window) { fprintf(stderr, "event on frame %i: ", i); switch(ev.xany.type) { case ClientMessage: fprintf(stderr, "ClientMessage\n"); if (ev.xclient.data.l[0] == XA_WM_TAKE_FOCUS) { fprintf(stderr, " WM_TAKE_FOCUS\n"); XSetInputFocus(display, win, RevertToPointerRoot, CurrentTime); } break; case FocusIn: fprintf(stderr, "FocusIn\n"); break; case FocusOut: fprintf(stderr, "FocusOut\n"); break; default: fprintf(stderr, "%d\n", ev.xany.type); } } } } return 0; }