Sample Header Ad - 728x90

xcb: Asynchronous pointer grab not propagating events

4 votes
1 answer
1645 views
I am trying to make an image appear under my cursor whenever I click on my desktop. I decided to use xcb to accomplish this. I figured I should capture the pointer from the root window (I don't really know a better way to do it), because I always want the image to appear, no matter where I click. The application that displays the image should not interfere with my normal workflow. Here is how I capture the pointer so far: #include #include #include #include #include #include #include #include #include #include void setup(xcb_connection_t *connection) { xcb_generic_error_t *err; xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data; xcb_void_cookie_t grab_cookie = xcb_grab_button(connection, True, screen->root, XCB_NONE, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE, XCB_BUTTON_INDEX_1, XCB_MOD_MASK_ANY); xcb_generic_error_t *error = xcb_request_check(connection, grab_cookie); if (error != NULL) { xcb_disconnect(connection); perror("could not subscribe to events on a window, bailing out"); exit(1); } free(error); xcb_flush(connection); } int main(int argc, char *argv[]) { xcb_generic_event_t *e; Display *dpy = XOpenDisplay(NULL); xcb_connection_t *connection = XGetXCBConnection(dpy); setup(connection); while ((e = xcb_wait_for_event(connection))) { switch(e->response_type & ~0x80) { case XCB_BUTTON_PRESS: printf("Click.\n"); break; default: break; } free(e); } xcb_ungrab_pointer(connection, XCB_TIME_CURRENT_TIME); } The code line that grabs the cursor is in the setup method: xcb_void_cookie_t grab_cookie = xcb_grab_button(connection, True, screen->root, XCB_NONE, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, XCB_NONE, XCB_NONE, XCB_BUTTON_INDEX_1, XCB_MOD_MASK_ANY); As far as I can tell by "autocorrecting" man xcb_grab_button, my pointer events should not be influenced if I put XCB_GRAB_MODE_ASYNC as the fifth argument to the function (the manual says something different, but it is generally quite poor, so I would be very surprised if it weren't by mistake). However, this is not the case: When I click, the click simply gets swallowed by my application and, e.g., Firefox does not react to it. How can grab the cursor such that my click events do not get eaten? If such a feature does not exist in X, would you recommend that I simply "resend" the click events or is there a better option? My window manager is i3, in case this information changes anything.
Asked by PawkyPenguin (1001 rep)
Oct 11, 2017, 03:10 AM
Last activity: Jan 8, 2020, 07:38 AM