使用 XCB 获取活动 window 的 WId
Get WId of active window with XCB
使用 XCB 获得活动 window(具有输入焦点的那个)的正确方法是什么?
reply = xcb_get_input_focus_reply(connection, xcb_get_input_focus(connection), nullptr);
std::cout << "WId: " << reply->focus;
这似乎有时有效,有时无效。
我还看到有人提到查询 _NET_ACTIVE_WINDOW root window 属性 但我不知道这是如何完成的,XCB 是否始终支持它?
编辑: 上面xcb_get_input_focus的做法只是一部分,得到回复->焦点后,需要跟进parent windows 通过 xcb_query_tree.
据我所知,符合 EWMH 的 window 管理员应将根 window 的 _NET_ACTIVE_WINDOW
属性设置为当前活动 window ID =37=].
为了得到它,
- 使用
xcb_intern_atom
得到_NET_ACTIVE_WINDOW
的原子值
- 获取根 window ID,例如使用
xcb_setup_roots_iterator(xcb_get_setup(connection)).data->root
- 使用
xcb_get_property
、xcb_get_property_reply
、xcb_get_property_value
获取根window. 的属性值
_NET_ACTIVE_WINDOW
的类型为 CARDINAL
,对于 XCB 而言,其大小为 32 位。
或者您可以使用 libxcb-ewmh 将此任务包装到 xcb_ewmh_get_active_window
函数中。
这个解决方案对我有用,它或多或少是从一些 X11 代码迁移到 XCB。基本上获得焦点 window 并跟随父级 window 的路径,直到 window id 等于父级或根 id,这就是顶层 window .
WId ImageGrabber::getActiveWindow()
{
xcb_connection_t* connection = QX11Info::connection();
xcb_get_input_focus_reply_t* focusReply;
xcb_query_tree_cookie_t treeCookie;
xcb_query_tree_reply_t* treeReply;
focusReply = xcb_get_input_focus_reply(connection, xcb_get_input_focus(connection), nullptr);
xcb_window_t window = focusReply->focus;
while (1) {
treeCookie = xcb_query_tree(connection, window);
treeReply = xcb_query_tree_reply(connection, treeCookie, nullptr);
if (!treeReply) {
window = 0;
break;
}
if (window == treeReply->root || treeReply->parent == treeReply->root) {
break;
} else {
window = treeReply->parent;
}
free(treeReply);
}
free(treeReply);
return window;
}
使用 XCB 获得活动 window(具有输入焦点的那个)的正确方法是什么?
reply = xcb_get_input_focus_reply(connection, xcb_get_input_focus(connection), nullptr);
std::cout << "WId: " << reply->focus;
这似乎有时有效,有时无效。
我还看到有人提到查询 _NET_ACTIVE_WINDOW root window 属性 但我不知道这是如何完成的,XCB 是否始终支持它?
编辑: 上面xcb_get_input_focus的做法只是一部分,得到回复->焦点后,需要跟进parent windows 通过 xcb_query_tree.
据我所知,符合 EWMH 的 window 管理员应将根 window 的 _NET_ACTIVE_WINDOW
属性设置为当前活动 window ID =37=].
为了得到它,
- 使用
xcb_intern_atom
得到_NET_ACTIVE_WINDOW
的原子值
- 获取根 window ID,例如使用
xcb_setup_roots_iterator(xcb_get_setup(connection)).data->root
- 使用
xcb_get_property
、xcb_get_property_reply
、xcb_get_property_value
获取根window. 的属性值
_NET_ACTIVE_WINDOW
的类型为 CARDINAL
,对于 XCB 而言,其大小为 32 位。
或者您可以使用 libxcb-ewmh 将此任务包装到 xcb_ewmh_get_active_window
函数中。
这个解决方案对我有用,它或多或少是从一些 X11 代码迁移到 XCB。基本上获得焦点 window 并跟随父级 window 的路径,直到 window id 等于父级或根 id,这就是顶层 window .
WId ImageGrabber::getActiveWindow()
{
xcb_connection_t* connection = QX11Info::connection();
xcb_get_input_focus_reply_t* focusReply;
xcb_query_tree_cookie_t treeCookie;
xcb_query_tree_reply_t* treeReply;
focusReply = xcb_get_input_focus_reply(connection, xcb_get_input_focus(connection), nullptr);
xcb_window_t window = focusReply->focus;
while (1) {
treeCookie = xcb_query_tree(connection, window);
treeReply = xcb_query_tree_reply(connection, treeCookie, nullptr);
if (!treeReply) {
window = 0;
break;
}
if (window == treeReply->root || treeReply->parent == treeReply->root) {
break;
} else {
window = treeReply->parent;
}
free(treeReply);
}
free(treeReply);
return window;
}