gpt4 book ai didi

c++ - Xlib。检查窗口是否重叠

转载 作者:行者123 更新时间:2023-11-30 04:49:35 25 4
gpt4 key购买 nike

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

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

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

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。

最佳答案

这是正常的,正如它的名字所说,该属性只表示窗口是否被隐藏(例如,因为它被最小化)。

如果您想检查您的窗口上方的其他窗口并隐藏其中的一部分,则必须手动执行。

例如,获取所有顶级窗口的列表:

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 原子)。
  • 查询上方显示的每个窗口的大小。可能使用 Shape extension如果你想考虑非矩形窗口
  • 检查这些是否与您自己的显示区域相交。

关于c++ - Xlib。检查窗口是否重叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55340008/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com