XCB:检测 window 的名称/标题的更改

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

XCB 允许我们...

这两个我都成功了。具体来说,这是我如何监视所有 windows 的 _NET_WM_NAME 属性 的变化(通过订阅根 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);
}

/* ... */

这在大多数情况下似乎工作正常,但我注意到当我在浏览器中更改标签时我没有收到事件,即使这确实改变了浏览器 window标题.

我是做错了还是 XCB 做不到?


以上代码大部分归功于

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):

您显示的代码不会监控所有 windows 的 属性 变化。它仅监视根 window.

上的 属性 更改

如果您想监听所有 windows 上的 属性 变化...好吧,这很复杂。您可以 select 获得 SubstructureNotify。每当创建新的 sub-window 时,这应该会为您提供 CreateNotify 事件。对于 window,您将再次 select SubstructureNotify 等递归地获取所有 windows。

对于您找到此遗嘱的每个 windows,您还想发送一个 QueryTree 请求以获取其 children。您还必须 select child windows 的事件,这些事件在您的程序启动之前已经存在。

当然,在请求 SubstructureNotify 时,您还应该 select 获得 PropertyNotifyMask。这样,只要任何 window 更改任何 属性 (*).

,您就会得到通知

(*):嗯,当然有可能创建一个 window 并立即更改一个 属性。这个 属性 很可能会在您有机会请求 PropertyNotify 之前设置。因此,如果您真的想查看所有属性,您还需要在 windows 上请求 属性 更改后的 ListProperties 请求...