首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >西利卜。检查窗口是否重叠

西利卜。检查窗口是否重叠
EN

Stack Overflow用户
提问于 2019-03-25 14:23:47
回答 1查看 563关注 0票数 1

我需要检查(在我的C++应用程序中)应用程序的窗口是否被另一个窗口重叠(部分或完全)。如何使用xlib获取这些信息?

我尝试获取窗口的WM_STATE属性,并将其与NormalState进行比较。然而,当我重叠目标窗口时,我的条件(state != NormalState)没有被执行。我还尝试将_NET_WM_STATE属性与_NET_WM_STATE_HIDDEN进行比较,但该方法没有给出所需的结果。

我试图实现spectras解决方案所建议的,现在它看起来像工作变体(注意:GetWindowProperty是我围绕相应Xlib函数的包装器):

代码语言:javascript
运行
复制
bool ApplicationHelper::IsWindowOverlapped(const void* hWnd, _XDisplay* pd)
{
    Display* pDisplay = pd == nullptr ? XOpenDisplay(nullptr) : pd;
    if(pDisplay == nullptr)
    {
        return true;
    }
    auto root = XDefaultRootWindow(pDisplay);
    Window parent;
    /*Window* windowList;
    unsigned nchildren;
    if (!XQueryTree(pDisplay, root, &root, &parent, &windowList, &nchildren))
    {
        if(pd == nullptr)
        {
            XCloseDisplay(pDisplay);
        }
        return true;
    }*/

    Atom propCleints = XInternAtom(pDisplay, "_NET_CLIENT_LIST_STACKING", True);
    unsigned long ulBytesReturned = 0;
    Window *windowList = (Window *)GetWindowProperty(pDisplay, root, propCleints, &ulBytesReturned);
    unsigned long nchildren = ulBytesReturned / sizeof(Window);
    int32_t actualDesktop = GetWindowDesktop(pDisplay, (TWindow) hWnd);

    WindowRect targetWindowRect;
    GetWindowRect(hWnd, targetWindowRect, pDisplay);
    GdkRectangle targetGdkRect;
    targetGdkRect.x = targetWindowRect.x;
    targetGdkRect.y = targetWindowRect.y;
    targetGdkRect.width = targetWindowRect.width;
    targetGdkRect.height = targetWindowRect.height;
    bool handleWindow = false;
    bool res = false;
    for (unsigned long i = 0; i < nchildren; ++i)
    {
        auto window = windowList[i];
        if((Window)hWnd == window)
        {
            handleWindow = true;
            continue;
        }
        if(handleWindow)
        {
            if((GetWindowDesktop(pDisplay, window) != actualDesktop) || IsWindowHidden((void*)window, pDisplay))
            {
                continue;
            }
            else
            {
                WindowRect rc;
                GetWindowRect((void*)window, rc, pDisplay);
                GdkRectangle gdkRect;
                gdkRect.x = rc.x;
                gdkRect.y = rc.y;
                gdkRect.width = rc.width;
                gdkRect.height = rc.height;
                if(gdk_rectangle_intersect(&targetGdkRect, &gdkRect, nullptr))
                {
                    res = true;
                    break;
                }
            }
        }
    }
    XFree(windowList);
    if(pd == nullptr)
    {
        XCloseDisplay(pDisplay);
    }

    return res;
}

此代码总是返回true。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-25 18:53:00

顾名思义,属性只指示窗口是否被隐藏(例如,因为它被最小化了)。

如果你想检查你上面的其他窗口并隐藏它的一部分,你必须手动完成它。

例如,它获得了所有顶级窗口的列表:

代码语言:javascript
运行
复制
auto root = XDefaultRootWindow(display);
Window parent;
Window * children;
unsigned nchildren;
if (!XQueryTree(display, root, &root, &parent, &children, &nchildren)) {
    std::cout <<"Failed to query top level windows list\n";
    return 1;
}

for (unsigned idx = 0; idx < nchildren; ++idx) {
    auto window = children[idx];
    // do something with window
}

XFree(children);

你需要:

  • 找出你自己的窗口在列表中的位置。任何在之后出现的窗口都是按堆叠顺序排列的。
  • 查询您上面每个窗口的桌面(_NET_WM_DESKTOP原子),消除当前桌面上没有显示的任何窗口。
  • 查询您上面每个窗口的显示状态(_NET_WM_STATE原子,在列表中查找_NET_WM_STATE_HIDDEN原子)。
  • 查询您上面显示的每个窗口的大小。如果您想要计算非矩形窗口,则可能使用形状扩展
  • 检查是否有任何这些相交与您自己的显示区域。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55340008

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档