简体   繁体   English

xcb 正确的 window 尺寸

[英]xcb correct window size

I have a question regarding xcb Window size I create a window using xcb_create_window function我对 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());

On Win32 API I have the possibilty to adjust a window rect by using AdjustWindowRect function which basically adds border and caption size to ensure client window does have the expected size.在 Win32 API 上,我有可能通过使用AdjustWindowRect function 来调整 window 矩形,它主要添加边框和标题大小以确保客户端 window 确实具有预期的大小。

My question how do I achieve this with xcb?我的问题是如何使用 xcb 实现此目的? Is there any way to compute the additonal size that is needed to ensure client window das have the expected size?有什么方法可以计算确保客户端 window das 具有预期大小所需的附加大小?

Extended Window Manager Hints扩展 Window 管理器提示

_NET_REQUEST_FRAME_EXTENTS (Other Root Window Messages) _NET_REQUEST_FRAME_EXTENTS (其他根 Window 消息)

Rationale: A client cannot calculate the dimensions of its window's frame before the window is mapped, but some toolkits need this information.基本原理:在映射 window 之前,客户端无法计算其窗口框架的尺寸,但某些工具包需要此信息。 Asking the window manager for an estimate of the extents is a workable solution.向 window 经理询问范围的估计是一个可行的解决方案。 The estimate may depend on the current theme, font sizes or other window properties.估计值可能取决于当前主题、字体大小或其他 window 属性。 The client can track changes to the frame's dimensions by listening for _NET_FRAME_EXTENTS PropertyNotify events.客户端可以通过监听 _NET_FRAME_EXTENTS PropertyNotify 事件来跟踪框架尺寸的变化。

_NET_FRAME_EXTENTS (Application Window Properties) _NET_FRAME_EXTENTS (应用程序 Window 属性)

The Window Manager MUST set _NET_FRAME_EXTENTS to the extents of the window's frame. Window 管理器必须将 _NET_FRAME_EXTENTS 设置为窗口框架的范围。 left, right, top and bottom are widths of the respective borders added by the Window Manager.左、右、上、下是Window管理器添加的各个边框的宽度。

The following code gets margins of a window followed suggestion from Erdal Küçük:以下代码获取 window 的边距,遵循 Erdal Küçük 的建议:

  • create window创建 window

  • configure stuff (like title or close button)配置东西(如标题或关闭按钮)

  • wait for property message等待属性消息

  • in case .NET_FRAME_EXTENTS read data如果 .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