我正在使用 Xlib 和 Qt 4.7 编写自己的窗口管理器。所以在我的应用程序中,我捕获了来自 XServer 的所有事件。
问题是下一个。当我在“MapRequest”事件上显示窗口时,有时它的内部内容会显示在单独的窗口中。大多数情况下,我在打开新网页后在浏览器(如 Firefox 和 Google Chrome)中遇到此问题,有时在打开对话窗口后在 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);