我正在使用Xlib和Qt 4.7编写自己的Window Manager。所以在我的应用程序中,我从XServer捕获所有事件。
接下来是问题所在。当我在“MapRequest”事件上显示窗口时,有时其内部内容显示在单独的窗口中。在打开新网页后,我经常在浏览器(如Firefox和谷歌浏览器)中面对这个问题,有时在打开对话窗口后的Qt Creator和Dolphin中,也在媒体播放器中。可能是什么原因?我错过了什么?
欢迎任何建议。
这是MapRequest处理程序。
bool Manager::mapRequestHandler(XEvent* pEvent)
{
Window lWindow = pEvent->xmaprequest.window;
QMWindowWidget* lWidget = findWidget(lWindow);
if (!lWidget)
{
lWidget = (QMWindowWidget*)QWidget::find(lWindow);
}
if (lWidget)
{
XMapWindow(QX11Info::display(), lWindow);
lWidget->show();
XRaiseWindow(QX11Info::display(), lWidget->winId());
return true;
}
else
{
qDebug()<<"CREATING WINDOW IN MAP_REQUEST...";
createClientWindow(lWindow); //this function calls only here.
qDebug()<<"WINDOW CREATED";
return true;
}
return false;
}
这是createClientWindow()函数。
void Manager::createClientWindow(Qt::HANDLE pWinID)
{
XWindowAttributes lWinAttr;
if(!XGetWindowAttributes(QX11Info::display(), pWinID, &lWinAttr))
{
return;
}
if(lWinAttr.override_redirect)
{
return;
}
QStringList lWindowType = getWindowType(pWinID);
if(lWindowType[0] == "Desktop")
{
return;
}
else if(lWindowType[0] == "Splash" || lWindowType[0] == "Dock" ||
lWindowType[0] == "KDE_override" || lWindowType[0] == "Popup_menu")
{
XMapWindow(QX11Info::display(), pWinID);
XRaiseWindow(QX11Info::display(), pWinID);
return;
}
else
{
QMWindowWidget *lWindowWidget = new QMWindowWidget(pWinID, lWinAttr);
connect(lWindowWidget, SIGNAL(destroyed(QObject*)), this, SLOT(slotWidgetDestroyed(QObject*)));
mListWindows.append(lWindowWidget);
}
}
QMWindowWidget的构造函数。
mClientAttr = pWinAttr;
mWmHints = XGetWMHints(QX11Info::display(), pWindow);
XGrabServer(QX11Info::display());
XTextProperty lTitle;
XGetWMName(QX11Info::display(), pWindow, &lTitle);
this->setWindowTitle(QString::fromUtf8((const char*)lTitle.value));
qDebug()<<pWindow<<(const char*)lTitle.value;
int widgetX = pWinAttr.x - 3;
int widgetY = pWinAttr.y - 33;
if (widgetX < 0)
{
widgetX = 0;
}
if (widgetY < 0)
{
widgetY = 0;
}
XAddToSaveSet(QX11Info::display(), pWindow);
XSetWindowBorderWidth(QX11Info::display(), pWindow, 0);
XResizeWindow(QX11Info::display(), pWindow, pWinAttr.width, pWinAttr.height);
this->setGeometry(widgetX, widgetY, pWinAttr.width + 6, pWinAttr.height + 33);
XSelectInput(QX11Info::display(),this->winId(),
KeyReleaseMask | KeyPressMask |
ButtonMotionMask|
ButtonPressMask | ButtonReleaseMask |
FocusChangeMask |
ExposureMask |
StructureNotifyMask |
SubstructureNotifyMask |
SubstructureRedirectMask);
XReparentWindow(QX11Info::display(), pWindow, this->winId(), 3, 30);
XSelectInput(QX11Info::display(), pWindow,
ColormapChangeMask |
PropertyChangeMask |
StructureNotifyMask);
this->show();
XMapWindow(QX11Info::display(), pWindow);
XRaiseWindow(QX11Info::display(), this->winId());
XSetInputFocus(QX11Info::display(), pWindow, RevertToParent, CurrentTime);
XUngrabServer(QX11Info::display());
XSync(QX11Info::display(), false);
答案 0 :(得分:0)
问题是你必须只显示你的顶级窗口,并且只有当它们应该显示时才显示。我有同样的问题,我发现我在更多地方显示客户端窗口然后MapRequest事件处理程序!因此,请检查您的代码,也许您正在处理另一个显示窗口而没有明确请求的事件!
如果您需要任何进一步的帮助,请发布您的所有活动处理程序,然后评论我的回答,我会编辑它并尝试为您提供帮助。