【发布时间】:2021-04-27 23:23:15
【问题描述】:
我有一个方法应该返回活动窗口的位置和大小。例如,在 Plasma 上可以找到作品,但在 Gnome 上,几何图形比此屏幕截图中看到的真实窗口大一点:
我正在使用xcb_get_geometry_reply 来获取窗口信息。知道什么可能导致这种行为以及如何减轻它吗?
【问题讨论】:
我有一个方法应该返回活动窗口的位置和大小。例如,在 Plasma 上可以找到作品,但在 Gnome 上,几何图形比此屏幕截图中看到的真实窗口大一点:
我正在使用xcb_get_geometry_reply 来获取窗口信息。知道什么可能导致这种行为以及如何减轻它吗?
【问题讨论】:
知道是什么导致了这种行为
我认为你得到的值是正确的。您可以在窗口周围看到阴影(至少在右侧和底部,但我敢打赌左侧和顶部也存在阴影)。我敢打赌,阴影是通过拥有一个更大的窗口然后使其部分透明来实现的。
所以,你得到的值是正确的,因为它们也包括阴影。
以及如何缓解?
您可以在终端中运行xprop -frame 和/或xprop,然后单击窗口。 GTK 是否设置了一些包含阴影大小的属性? (我不知道这个问题的答案;这只是一个猜测)(这甚至是 GTK 窗口吗?)
【讨论】:
xprop -frame,然后比较带有和不带有边框的窗口的屏幕截图,看起来_GTK_FRAME_EXTENTS(CARDINAL) 有四个值,分别是窗口左侧、右侧、顶部和底部位置的偏移量,所以可能就是这样。知道如何从代码中查询这个值吗?
xprop -id <WindowId> 我得到了我需要的数据。直接从代码中以某种方式执行此操作而不调用应用程序仍然会很好,但如果没有其他方法,那么它会这样做。
xcb_get_geometry),您可以使用xcb_get_property 来查询属性。在此之前,您需要xcb_intern_atom(c, "_GTK_FRAME_EXTENTS", strlen("_GTK_FRAME_EXTENTS")) 来获取原子。然后xcb_get_property(c, 0, win, atom, XCB_ATOM_CARDINAL, 0, 42)(42 只是随机猜测,可能是 4 更好,但我总是很困惑这是否计算字节或值)。
uint32_t 并从中获取四个值(每个 32 位值需要四个字节和 4*4=16),而不是 (char*)xcb_get_property_value(reply)。
感谢 Uli Schlachter 指出了正确的方向,我得到了一个可行的解决方案,以防有人看到这篇文章。
auto connection = QX11Info::connection();
auto atom_cookie = xcb_intern_atom(connection, 0, strlen("_GTK_FRAME_EXTENTS"), "_GTK_FRAME_EXTENTS");
ScopedCPointer<xcb_intern_atom_reply_t> atom_reply(xcb_intern_atom_reply(connection, atom_cookie, nullptr));
if (!atom_reply.isNull()) {
auto cookie = xcb_get_property(connection, 0, windowId, atom_reply->atom, XCB_ATOM_CARDINAL, 0, 4);
ScopedCPointer<xcb_get_property_reply_t> reply(xcb_get_property_reply(connection, cookie, nullptr));
if (!reply.isNull()) {
int length = xcb_get_property_value_length(reply.data());
if (length != 0) {
auto gtkFrameExtents = static_cast<uint32_t*>(xcb_get_property_value(reply.data()));
auto left = gtkFrameExtents[0];
auto right = gtkFrameExtents[1];
auto top = gtkFrameExtents[2];
auto bottom = gtkFrameExtents[3];
}
}
}
【讨论】: