简体   繁体   English

使用XCB获取活动窗口的WId

[英]Get WId of active window with XCB

What would be the proper way to get the active window (the one with input focus) with XCB? 用XCB获取活动窗口(具有输入焦点的窗口)的正确方法是什么?

reply = xcb_get_input_focus_reply(connection, xcb_get_input_focus(connection), nullptr);
std::cout << "WId: " << reply->focus;

This seems to be work sometimes and sometimes not. 有时这有时是可行的,有时不是。

I also saw someone mentioned querying _NET_ACTIVE_WINDOW root window property but I can't figure out how that is done and is it always supported with XCB? 我还看到有人提到查询_NET_ACTIVE_WINDOW根窗口属性,但我不知道该怎么做,并且XCB始终支持它吗?

Edit: The approach above with xcb_get_input_focus is only one part, after getting the reply->focus, you need to follow up the parent windows via xcb_query_tree. 编辑: 上面使用xcb_get_input_focus的方法只是一部分,在得到reply-> focus之后,您需要通过xcb_query_tree跟踪父窗口。

As far as I know, EWMH-compliant window managers are expected to set _NET_ACTIVE_WINDOW attribute of root window to the window ID of the currently active window. 据我所知,符合EWMH的窗口管理器_NET_ACTIVE_WINDOW根窗口的_NET_ACTIVE_WINDOW属性设置为当前活动窗口的窗口ID。

In order to get it, 为了得到它,

  1. Use xcb_intern_atom to get the atom value for _NET_ACTIVE_WINDOW 使用xcb_intern_atom得到的原子值_NET_ACTIVE_WINDOW
  2. Get the root window ID, eg using xcb_setup_roots_iterator(xcb_get_setup(connection)).data->root 获取根窗口ID,例如,使用xcb_setup_roots_iterator(xcb_get_setup(connection)).data->root
  3. Use xcb_get_property , xcb_get_property_reply , and xcb_get_property_value to get the value of the attribute of the root window. 使用xcb_get_propertyxcb_get_property_replyxcb_get_property_value来获取根窗口的属性值。

_NET_ACTIVE_WINDOW has type of CARDINAL , which, for XCB purposes, has size of 32 bits. _NET_ACTIVE_WINDOW具有CARDINAL类型,出于XCB的目的,其大小为32位。

Or you could use libxcb-ewmh which wraps this task into xcb_ewmh_get_active_window function. 或者,您可以使用libxcb-ewmh将此任务包装到xcb_ewmh_get_active_window函数中。

This solution works for me, it's more or less migration from some X11 code to XCB. 该解决方案对我有用,它或多或少是从某些X11代码迁移到XCB的。 Basically get the focus window and follow up the the path of the parent window until the window id is equal to parent or root id, this is then the top level window. 基本上获取焦点窗口,并跟踪父窗口的路径,直到窗口ID等于父ID或根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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM