Question Details

No question body available.

Tags

c xcb

Answers (1)

April 11, 2026 Score: 0 Rep: 1,272 Quality: Low Completeness: 80%

Well xcb is definitely a tough one, not to mention that on my Debian your example did not work, and when I've used setxkbmap it disabled permanently ALT+SHIFT for the testing. Anyway I was able to hit the InidcatorState change, maybe you need to handle the state in the handle events. I've added few printf calls just to see what event I am getting and also refer to this file: https://xcb.freedesktop.org/manual/xkb8hsource.html not well documented api in any case. Here is the small change I had to do to make it work, so maybe it will help you find a way to capture the next event.

// Source - https://stackoverflow.com/q/79924054
// Posted by cutecoder, modified by community. See post 'Timeline' for change history
// Retrieved 2026-04-11, License - CC BY-SA 4.0

#include #include

#include #include

struct display { xcbconnectiont xcb; uint8_t xkb_base_event, xkb_base_error; int32_t keyboard_device_id; } display;

void open_display(void) { int connection_error; xcb_xkb_use_extension_cookie_t xkb_cookie; xcb_xkb_get_device_info_cookie_t device_cookie; const xcb_query_extension_reply_t
extensionreply; xcbxkbuseextensionreplyt xkb_reply; xcb_xkb_get_device_info_reply_t devicereply; xcbgenericerrort error;

display.xcb = xcb_connect(NULL, NULL); if (!display.xcb) { printf("oops\r\n"); exit(-1); } else { printf("ook\r\n"); }

xcb_prefetch_extension_data(display.xcb, &xcb_xkb_id);

xkb_cookie = xcb_xkb_use_extension(display.xcb, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION);

device_cookie = xcb_xkb_get_device_info(display.xcb, XCB_XKB_ID_USE_CORE_KBD, 0, 0, 0, 0, 0, 0);

extension_reply = xcb_get_extension_data(display.xcb, &xcb_xkb_id);

display.xkb_base_event = extension_reply->first_event; display.xkb_base_error = extension_reply->first_error;

xkb_reply = xcb_xkb_use_extension_reply(display.xcb, xkb_cookie, &error); free(xkb_reply);

device_reply = xcb_xkb_get_device_info_reply(display.xcb, device_cookie, NULL); display.keyboard_device_id = device_reply->deviceID; free(device_reply);

xcb_xkb_select_events(display.xcb, display.keyboard_device_id, ~0, 0, ~0, 0, 0, NULL); }

static void handle_xkb_event(xcb_generic_event_t
genericevent) {

switch ((( xcb
xkbnewkeyboardnotifyeventt*)genericevent)->xkbType) {

case XCBXKBNEWKEYBOARDNOTIFY: { xcbxkbnewkeyboardnotifyeventt event; printf("xkb: NEW_KEYBOARD_NOTIFY\n"); event = (xcb_xkb_new_keyboard_notify_event_t) genericevent; if (event->oldDeviceID == display.keyboarddeviceid) { printf("xkb: NEWKEYBOARDNOTIFY\n"); display.keyboarddeviceid = event->deviceID; } break; }

case XCB
XKBMAPNOTIFY: { xcbxkbmapnotifyeventt *event;

event = (xcb
xkbmapnotifyeventt) generic_event; printf("xkb: MAP_NOTIFY\n"); break; }

case XCB_XKB_STATE_NOTIFY: { xcb_xkb_state_notify_event_t
event;

event = (xcbxkbstatenotifyeventt*) genericevent; printf("xkb: STATENOTIFY\n"); break; }

case XCB
XKBINDICATORSTATENOTIFY: {

xcb
xkbindicatorstatenotifyeventt *event; event = (xcbxkbindicatorstatenotifyeventt*) genericevent; if (event->xkbType == XCBXKBNEWKEYBOARDNOTIFY) { xcbxkbnewkeyboardnotifyeventt event; printf("xkb: NEW_KEYBOARD_NOTIFY\n"); event = (xcb_xkb_new_keyboard_notify_event_t) genericevent; if (event->oldDeviceID == display.keyboarddeviceid) { printf("xkb: NEWKEYBOARDNOTIFY\n"); display.keyboarddeviceid = event->deviceID; } } else { printf("evnet is: %d\r\n", event->xkbType); } printf("xkb: INDICATORSTATENOTIFY\n"); break; }

case XCB
XKBEXTENSIONDEVICENOTIFY: { xcbxkbextensiondevicenotifyeventt *event; event = ( xcbxkbextensiondevicenotifyeventt *) genericevent; if (event->xkbType == XCBXKBNEWKEYBOARDNOTIFY) { xcbxkbnewkeyboardnotifyeventt event; printf("xkb: NEW_KEYBOARD_NOTIFY\n"); event = (xcb_xkb_new_keyboard_notify_event_t) genericevent; if (event->oldDeviceID == display.keyboarddeviceid) { printf("xkb: NEWKEYBOARDNOTIFY\n"); display.keyboarddeviceid = event->deviceID; } } printf("xkb: EXTENSIONDEVICENOTIFY\n"); break; } } }

int main(void) { xcb
genericeventt *event;

opendisplay();

for (;;) { xcb
flush(display.xcb); while (event = xcbwaitforevent(display.xcb), event != NULL) { if (event->responsetype == display.xkbbaseevent) { handlexkbevent(event); } else { printf("shall not pass here\r\n"); }

free(event); } }

return 0; }