[英]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 具有预期大小所需的附加大小?
_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.