XCB允许我们...
WM_NAME
和_NET_WM_NAME
属性XCB_EVENT_MASK_PROPERTY_CHANGE
我成功地做到了这两个。具体来说,这是我监视所有窗口的
_NET_WM_NAME
属性中的更改的方式(通过订阅根窗口中的事件):/* ... */
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);
}
/* ... */
这似乎在大多数情况下都可以正常工作,但是我注意到,即使更改了浏览器窗口的标题,我在浏览器中更改选项卡时也没有收到事件。我做错了吗,还是XCB无法做到?
上面代码的功劳主要归功于this answer on a related question。
最佳答案
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):
您显示的代码不会监视所有窗口的属性更改。它仅监视根窗口上的属性更改。
如果要在所有窗口上侦听属性更改,那么……很复杂。您可以选择
SubstructureNotify
。每当创建新的子窗口时,这都应该为您提供CreateNotify
事件。对于该窗口,您将再次选择SubstructureNotify
等以递归方式获取所有窗口。对于您发现的每个窗口,您还希望发送
QueryTree
请求以获取其子级。您还必须为程序启动之前已经存在的子窗口选择事件。当然,在请求
PropertyNotifyMask
时,还应该选择SubstructureNotify
。这样,只要任何窗口更改了任何属性(*),您都应该得到通知。(*):嗯,当然有可能创建窗口并立即更改属性。最有可能在您有机会要求
PropertyNotify
之前设置此属性。因此,如果您真的想查看所有属性,则在要求更改属性后,还需要在窗口上发送ListProperties
请求...
关于c - XCB : detect change of a window's name/title,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64246090/