如何使用Xlib/XCB获取内部和外部窗口尺寸?

4
有没有一种可靠的方法来获取XCB / Xlib顶级窗口的内部和外部矩形?(即框架和客户端矩形。)
这是我尝试过的:
- xcb_get_geometry在窗口调整大小后始终返回初始尺寸(怎么回事?) - 我想我会重复调用xcb_query_tree,直到找到窗口的框架窗口 - 这是正确的方法吗?我认为ICCCM / EWMH应该提供此功能,但找不到任何信息。还有其他标准/非标准的方法吗?无论如何,在compiz / ubuntu10中无法正常工作,因为xcb_query_tree将客户端窗口报告为具有根=父项(在正常的ubuntu wm下,窗口会得到适当的重新父化)。 - xcb_translate_coordinates()似乎是2007年获得基于根的坐标[1]的唯一可靠方法 - 现在是否仍然如此?即XCB_CONFIGURE_NOTIFY是否与WM不兼容?
[1] {{link1:http://fixunix.com/xwindows/91652-finding-position-top-level-windows.html}}
1个回答

2

这只是一个部分答案,它仅解释了如何找到窗口的内部尺寸。另外我不确定这是否是标准方法,但对我来说有效。

在创建窗口时,您可以订阅XCB_EVENT_MASK_RESIZE_REDIRECT事件:

xcb_window_t           window    = xcb_generate_id          (connection);
const xcb_setup_t     *setup     = xcb_get_setup            (connection);
xcb_screen_t          *screen    = xcb_setup_roots_iterator (setup).data;
uint32_t               mask      = XCB_CW_EVENT_MASK;
uint32_t               valwin[1] = { XCB_EVENT_MASK_EXPOSURE
                                   | XCB_EVENT_MASK_RESIZE_REDIRECT };

xcb_create_window(
    connection,
    XCB_COPY_FROM_PARENT,
    window,
    screen->root,
    0, 0,
    800, 600,
    0,
    XCB_WINDOW_CLASS_INPUT_OUTPUT,
    screen->root_visual,
    mask, valwin);
xcb_map_window(connection, window);
xcb_flush(connection);

在事件循环中,您可以跟踪调整大小:

xcb_generic_event_t *event;
uint16_t width = 0, height = 0;
while ((event = xcb_wait_for_event(connection)) != NULL) {
    switch (event->response_type & ~0x80) {
    case XCB_EXPOSE: {
        /* ... */
        break;
    }
    case XCB_RESIZE_REQUEST: {
        auto resize = (xcb_resize_request_event_t*) event;
        if (resize->width > 0) width = resize->width;
        if (resize->height > 0) height = resize->height;
        break;
    }
    default:
        break;
    }
    free(event);
    xcb_flush(connection);
}

请注意,我不确定当您使用xcb_configure_window在应用程序代码中启动调整大小时,是否会发出此事件。我从未测试过它,只是在xcb_configure_window的包装函数中更新widthheight

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接