i3 перехватывает горячие клавиши через xcb_grab_key() с параметром owner_events = 0 на корневом (root) X-окне. Соответствующий код лежит в src/bindings.c: программа проходит по списку привязок и для каждой вызывает xcb_grab_key. Из-за owner_events = 0 i3 полностью крадёт клавиши у всех остальных окон — они вообще не получают эти события. Можно было бы выставить owner_events = 1, чтобы пропускать событие дальше, но это поведение X11 работает не так, как хочется: событие уходит только обратно на root-окно, а не тому окну, которое было в фокусе.
Когда событие нажатия/отпускания клавиши приходит, i3 направляет его в handle_event() (файл src/handlers.c). Там по типу XCB_KEY_PRESS или XCB_KEY_RELEASE вызывается handle_key_press() (файл src/key_press.c). Эта функция получает исходный xcb_key_press_event_t от XCB, ищет по нему привязку (Binding) через get_binding_from_xcb_event(), и если находит — запускает команду через run_binding().
Автор статьи разобрался, что это событие можно просто перепослать другому окну через xcb_send_event(). Но проблема: даже если переслать событие, целевое окно всё равно теряет фокус, потому что i3 перехватывает клавиши глобально. Автор признаётся, что не починил эту проблему, и просит подсказать, как это сделать.
В целом i3 — аккуратный и читаемый код, но его механизм захвата клавиш ломает фокус для окон, которые должны получать эти же нажатия.