Search code examples
c++linuxx11xcb

A good way to handle multiple windows in xcb


I'm working on an X11 app using xcb. The problem is, I want to make multiple windows, but I cannot find any way to tell from the event loop, from which window the event comes from. Should I open multiple connections? Is there a way to separate somehow those events when using one connection? Also i've seen that X11lib has Context Manager, and I've couldn't find any information on does the xcb has an analogue for that.

I've tried to find something on the topic in the xcb documentation and in google. Didn't find so much about handling multiple windows and events from them.


Solution

  • It depends on the actual event type, but for most types there is a separate field for window ID. Some examples:

    xcb_generic_event_t *e;
    while ((e = xcb_wait_for_event(connection))) {
        uint8_t type = XCB_EVENT_RESPONSE_TYPE(e);
        switch (type) {
            case XCB_CREATE_NOTIFY: {
                xcb_create_notify_event_t *create_event =
                    (xcb_create_notify_event_t *)e;
                xcb_window_t wid = create_event->window;
                break;
            }
            case XCB_ENTER_NOTIFY: {
                xcb_enter_notify_event_t *enter_event =
                    (xcb_enter_notify_event_t *)e;
                xcb_window_t wid = enter_event->event;
                break;
            }
            case XCB_BUTTON_PRESS: {
                xcb_button_press_event_t *press_event =
                    (xcb_button_press_event_t *)e;
                xcb_window_t wid = press_event->event;
                break;
            }
            case XCB_PROPERTY_NOTIFY: {
                xcb_property_notify_event_t *notify_event =
                    (xcb_property_notify_event_t *)e;
                xcb_window_t wid = notify_event->window;
                break;
            }
            case XCB_EXPOSE: {
                xcb_expose_event_t *expose_event = (xcb_expose_event_t *)e;
                xcb_window_t wid = expose_event->window;
                break;
            }
            ...
        }
    }