使用XCB获取活动窗口的宽度

Get WId of active window with XCB

本文关键字:窗口 活动 XCB 获取 使用      更新时间:2023-10-16

使用XCB获取活动窗口(具有输入焦点的一个(是什么?

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的方法仅是一个部分,在获得回复 -> focus之后,您需要通过XCB_QUERY_TREE。

据我所知,符合EWMH的窗口管理器有望将root窗口的_NET_ACTIVE_WINDOW属性设置为当前活动窗口的窗口ID。

为了获得它,

  1. 使用xcb_intern_atom获取_NET_ACTIVE_WINDOW的原子值
  2. 获取根窗口ID,例如使用xcb_setup_roots_iterator(xcb_get_setup(connection)).data->root
  3. 使用xcb_get_propertyxcb_get_property_replyxcb_get_property_value获取根窗口的属性值。

_NET_ACTIVE_WINDOW具有CARDINAL的类型,用于XCB的目的,大小为32位。

或者您可以使用将此任务包裹到xcb_ewmh_get_active_window函数的Libxcb-Ewmh。

此解决方案对我有用,它或多或少从某些X11代码迁移到XCB。基本上获取焦点窗口并跟踪父窗口的路径,直到窗口ID等于父级或root ID,然后是顶级窗口。

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;
}