XCB: detect change of a window's name / title

524 Views Asked by At

XCB allows us to...

  • read a window's name (title) via the WM_NAME and _NET_WM_NAME properties
  • monitor for changes in window properties via XCB_EVENT_MASK_PROPERTY_CHANGE

I'm successfully doing both of these. Specifically, here is how I monitor for changes in the _NET_WM_NAME property of all windows (by subscribing to events on the root window):

/* ... */

const uint32_t list[] = { XCB_EVENT_MASK_PROPERTY_CHANGE };
xcb_change_window_attributes(conn, root_window, XCB_CW_EVENT_MASK, &list);
xcb_flush(conn);

xcb_generic_event_t *evt;
while ((evt = xcb_wait_for_event(conn)))
{
    if (evt->response_type == XCB_PROPERTY_NOTIFY)
    {
        xcb_property_notify_event_t *e = (void *) evt;
        /* ... print the window name ... */
    }
    free(evt);
}

/* ... */

This seems to work fine for the most part, but I've noticed that I don't receive an event when I change tabs within my browser, even though that does change the browser window's title.

Am I doing it wrong or is that not possible with XCB?


Credit for the above code mostly goes to this answer on a related question.

1

There are 1 best solutions below

1
On BEST ANSWER

Specifically, here is how I monitor for changes in the _NET_WM_NAME property of all windows (by subscribing to events on the root window):

The code you show does not monitor property changes of all windows. It only monitors for property changes on the root window.

If you want to listen on property changes on all windows... well, it's complicated. You can select for SubstructureNotify. This should give you CreateNotify events whenever a new sub-window is created. For that window, you would again select SubstructureNotify etc to get all windows, recursively.

For each of the windows you found this will, you also want to send a QueryTree request to get its children. You also have to select the events for the child windows which already existed before your program started.

Of course, you should also select for PropertyNotifyMask while you are requesting SubstructureNotify. That way, you should get informed whenever any window changes any property (*).

(*): Well, of course it is possible for something to create a window and immediately change a property. Most likely, this property will be set before you get a chance to ask for PropertyNotify. Thus, if you really want to see all properties, you also need a ListProperties request on the windows after you asked for property changes...