【问题标题】:xcb_get_geometry_reply returns slightly larger window geometry then the real window on Gnomexcb_get_geometry_reply 返回比 Gnome 上的真实窗口稍大的窗口几何图形
【发布时间】:2021-04-27 23:23:15
【问题描述】:

我有一个方法应该返回活动窗口的位置和大小。例如,在 Plasma 上可以找到作品,但在 Gnome 上,几何图形比此屏幕截图中看到的真实窗口大一点:

我正在使用xcb_get_geometry_reply 来获取窗口信息。知道什么可能导致这种行为以及如何减轻它吗?

【问题讨论】:

    标签: x11 gnome xcb


    【解决方案1】:

    知道是什么导致了这种行为

    我认为你得到的值是正确的。您可以在窗口周围看到阴影(至少在右侧和底部,但我敢打赌左侧和顶部也存在阴影)。我敢打赌,阴影是通过拥有一个更大的窗口然后使其部分透明来实现的。

    所以,你得到的值是正确的,因为它们也包括阴影。

    以及如何缓解?

    您可以在终端中运行xprop -frame 和/或xprop,然后单击窗口。 GTK 是否设置了一些包含阴影大小的属性? (我不知道这个问题的答案;这只是一个猜测)(这甚至是 GTK 窗口吗?)

    【讨论】:

    • 我也在怀疑阴影,是的,这就是问题,如何找出几何的哪一部分是阴影以及实际的窗口是什么。只需为随机窗口运行xprop -frame,然后比较带有和不带有边框的窗口的屏幕截图,看起来_GTK_FRAME_EXTENTS(CARDINAL) 有四个值,分别是窗口左侧、右侧、顶部和底部位置的偏移量,所以可能就是这样。知道如何从代码中查询这个值吗?
    • 看起来这确实可行。我已经有了 windowId,通过调用xprop -id <WindowId> 我得到了我需要的数据。直接从代码中以某种方式执行此操作而不调用应用程序仍然会很好,但如果没有其他方法,那么它会这样做。
    • 由于您已经在使用XCB(问题是关于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 更好,但我总是很困惑这是否计算字节或值)。
    • 感谢您的提示,我将尝试一下,看起来比我现在调用 xprop 时所拥有的更好。
    • 您想要转换为 uint32_t 并从中获取四个值(每个 32 位值需要四个字节和 4*4=16),而不是 (char*)xcb_get_property_value(reply)
    【解决方案2】:

    感谢 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];
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2010-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多