Eu resolvi o mistério. Aparentemente XCB_GRAB_MODE_ASYNC
não faz o que eu pensava: O manual (correto) xcb_grab_pointer
diz que o processamento de evento do ponteiro continua normalmente. Eu pensei que isso se referiria aos eventos sendo propagados para outros clientes, mas esse não é o caso. Os eventos ainda são ouvidos apenas pelo meu aplicativo. Para propagar os eventos, eles precisam ser repetidos após o recebimento:
xcb_generic_event_t *e;
xcb_generic_error_t *err;
xcb_connection_t *connection = xcb_connect(NULL, NULL);
xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data;
xcb_void_cookie_t grab_cookie = xcb_grab_button_checked(connection, True, screen->root, XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE, XCB_GRAB_MODE_SYNC, 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);
do {
xcb_allow_events(connection, XCB_ALLOW_REPLAY_POINTER, XCB_CURRENT_TIME);
e = xcb_poll_for_event(connection);
if(!e) {
continue;
}
switch(e->response_type & EVENT_MASK) {
case XCB_BUTTON_RELEASE:
case XCB_BUTTON_PRESS:
printf("Hello.\n");
break;
default:
break;
free(e);
} while(1);
xcb_ungrab_pointer(connection, XCB_TIME_CURRENT_TIME);
Antes do loop while, o ponteiro pressionado e liberado para o botão index1 são capturados. O quinto argumento tem que ser XCB_GRAB_MODE_SYNC
para que o servidor X enfileira eventos até que xcb_allow_events
seja chamado (o manual do Xlib, man XGrabPointer
, fornece informações detalhadas, embora eu não confie em detalhes, já que é não para XCB). A chamada subseqüente para xcb_allow_events
dentro do while
-loop descongela (descongela) o processamento de evento do ponteiro. Passar o parâmetro XCB_ALLOW_REPLAY_POINTER
reproduz os eventos do botão.
É importante usar xcb_poll_for_event
dentro do loop, embora eu não entenda completamente o motivo.