繁体   English   中英

xcb 正确的 window 尺寸

[英]xcb correct window size

我对 xcb Window 大小有疑问 我使用xcb_create_window function 创建了一个 window

    xcb_create_window(mScreen->connection(),
                  XCB_COPY_FROM_PARENT,
                  mWindow,
                  mScreen->screen()->root,
                  x, // left corner of the window client area
                  y, // upper corner of the window client area
                  width, // width of the client area
                  height, // height of the client area
                  0,
                  XCB_WINDOW_CLASS_INPUT_OUTPUT,
                  mScreen->screen()->root_visual,
                  value_mask,
                  value_list);
    auto reply = XCB_REPLY(xcb_intern_atom, mScreen->connection(), true, strlen("WM_PROTOCOLS"), "WM_PROTOCOLS");
    auto atomDelete = XCB_REPLY(xcb_intern_atom, mScreen->connection(), false, strlen("WM_DELETE_WINDOW"), "WM_DELETE_WINDOW");

    xcb_change_property(mScreen->connection(), XCB_PROP_MODE_REPLACE, mWindow, reply->atom, 4, 32, 1, &atomDelete->atom);
    xcb_change_property(mScreen->connection(), XCB_PROP_MODE_REPLACE, mWindow, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, strlen(windowName), windowName);
    xcb_flush(mScreen->connection());

在 Win32 API 上,我有可能通过使用AdjustWindowRect function 来调整 window 矩形,它主要添加边框和标题大小以确保客户端 window 确实具有预期的大小。

我的问题是如何使用 xcb 实现此目的? 有什么方法可以计算确保客户端 window das 具有预期大小所需的附加大小?

扩展 Window 管理器提示

_NET_REQUEST_FRAME_EXTENTS (其他根 Window 消息)

基本原理:在映射 window 之前,客户端无法计算其窗口框架的尺寸,但某些工具包需要此信息。 向 window 经理询问范围的估计是一个可行的解决方案。 估计值可能取决于当前主题、字体大小或其他 window 属性。 客户端可以通过监听 _NET_FRAME_EXTENTS PropertyNotify 事件来跟踪框架尺寸的变化。

_NET_FRAME_EXTENTS (应用程序 Window 属性)

Window 管理器必须将 _NET_FRAME_EXTENTS 设置为窗口框架的范围。 左、右、上、下是Window管理器添加的各个边框的宽度。

以下代码获取 window 的边距,遵循 Erdal Küçük 的建议:

  • 创建 window

  • 配置东西(如标题或关闭按钮)

  • 等待属性消息

  • 如果 .NET_FRAME_EXTENTS 读取数据

     uint32_t value_mask, value_list[32]{}; auto windowHandle = xcb_generate_id(xcb_connection()); value_mask = XCB_CW_EVENT_MASK; value_list[0] = XCB_EVENT_MASK_PROPERTY_CHANGE; xcb_create_window(screen->connection(), XCB_COPY_FROM_PARENT, windowHandle, screen->root, 100, 100, 100, 100, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, value_mask, value_list); auto protocols = XCB_REPLY(xcb_intern_atom, screen->connection(), true, strlen("WM_PROTOCOLS"), "WM_PROTOCOLS"); auto atomDelete = XCB_REPLY(xcb_intern_atom, screen->connection(), false, strlen("WM_DELETE_WINDOW"), "WM_DELETE_WINDOW"); auto atomExtents = XCB_REPLY(xcb_intern_atom, screen->connection(), false, strlen(".NET_FRAME_EXTENTS"), ".NET_FRAME_EXTENTS"); xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, windowHandle, protocols->atom, XCB_ATOM_ATOM, 32, 1, &atomDelete->atom); xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, windowHandle, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, strlen(""), ""); xcb_map_window(xcb_connection(), windowHandle); xcb_flush(xcb_connection()); xcb_generic_event_t* event; for (;;) { while ((event = xcb_poll_for_event(screen->connection()))) { switch (event->response_type & 0x7f) { case XCB_PROPERTY_NOTIFY: { auto propertyNotify = (const xcb_property_notify_event_t*)event; if (propertyNotify->atom == atomExtents->atom) { free(event); goto end; } break; } default: break; } free(event); } } end: auto extends = XCB_REPLY(xcb_get_property, xcb_connection(), false, windowHandle, atomExtents->atom, XCB_ATOM_CARDINAL, 0, 4); if (extends && extends->type == XCB_ATOM_CARDINAL && extends->format == 32 && extends->value_len == 4) { uint32_t* data = std::pointer_cast<uint32_t*>(xcb_get_property_value(extends.get())); windowMargins.l = -data[0]; windowMargins.r = data[1]; windowMargins.t = -data[2]; windowMargins.b = data[3]; } xcb_destroy_window(xcb_connection(), windowHandle);

暂无
暂无

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

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