i3 uses xcb_grab_key() with owner_events = 0 on the root x window to intercept keys. the relevant code in src/bindings.c looks like all unpatched code snippets refer to i3 4.25.1, if you want to follow along. 172struct Binding_Keycode *binding_keycode; 173TAILQ_FOREACH(binding_keycode, &(bind->keycodes_head), keycodes) { 174 const int keycode = binding_keycode->keycode; 175 const int mods = (binding_keycode->modifiers & 0xFFFF); 176 DLOG("Binding %p Grabbing keycode %d with mods %d\n", bind, keycode, mods); 177 xcb_grab_key(conn, 0, root, mods, keycode, XCB_GRAB_MODE_ASYNC, 178 XCB_GRAB_MODE_ASYNC); 179} this code isn't super relevant, except that i3 entirely steals its bindings from anyone else by intercepting on the root window. if you're thinking that setting owner_events = 1 to allow event passthrough so we don't have to re-emit… that would be great, but that appears to instruct x to pass the event through to only the root window. which is not what we want. in i3's handle_event() in src/handlers.c, if it gets an xcb event, it sends it off to a specialized handler based on its type: 1481switch (type) { 1482case XCB_KEY_PRESS: 1483case XCB_KEY_RELEASE: 1484 handle_key_press((xcb_key_press_event_t *)event); 1485 break; 1486 } handle_key_press() (src/key_press.c) looks like this — it receives a keypress event, looks up a binding based on that event, and, if it finds one, runs the associated command: yes, i do know one of the lines is too long. i opted to leave it that way, as that's how it is in the i3 source. i should note, though: i3 has really nice source code! i found it very readable and pleasant to work inside. 12 18void handle_key_press(xcb_key_press_event_t *event) { 19 const bool key_release = (event->response_type == XCB_KEY_RELEASE); 20 21 last_timestamp = event->time; 22 23 DLOG("%s %d, state raw = 0x%x\n", (key_release ? "KeyRelease" : "KeyPress"), event->detail, event->state); 24 25 Binding *bind = get_binding_from_xcb_event((xcb_generic_event_t *)even...
First seen: 2026-05-23 23:45
Last seen: 2026-05-24 15:55