Qt4 窗口管理器。单独窗口中X窗口的内部内容?
我正在使用Xlib和Qt4.7编写自己的窗口管理器。因此,在我的应用程序中,我从XServer捕获所有事件 问题是下一个。当我在“MapRequest”事件上显示窗口时,有时它的内部内容会显示在单独的窗口中。在打开新网页后,我经常在浏览器(如Firefox和Google Chrome)中遇到这个问题,有时在Qt Creator和Dolphin中打开对话框窗口后,也在媒体播放器中遇到这个问题。这可能是什么原因?我错过了什么 欢迎任何意见 下面是MapRequest处理程序Qt4 窗口管理器。单独窗口中X窗口的内部内容?,qt4,xlib,window-managers,x11,qt4.7,Qt4,Xlib,Window Managers,X11,Qt4.7,我正在使用Xlib和Qt4.7编写自己的窗口管理器。因此,在我的应用程序中,我从XServer捕获所有事件 问题是下一个。当我在“MapRequest”事件上显示窗口时,有时它的内部内容会显示在单独的窗口中。在打开新网页后,我经常在浏览器(如Firefox和Google Chrome)中遇到这个问题,有时在Qt Creator和Dolphin中打开对话框窗口后,也在媒体播放器中遇到这个问题。这可能是什么原因?我错过了什么 欢迎任何意见 下面是MapRequest处理程序 bool Manager
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;
}
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);
mClientAttr=pWinAttr;
mWmHints=XGetWMHints(QX11Info::display(),pWindow);
XGrabServer(QX11Info::display());
Xtexttle;
XGetWMName(QX11Info::display()、pWindow和lTitle);
this->setWindowTitle(QString::fromUtf8((const char*)lTitle.value));
qDebug()show();
XMapWindow(QX11Info::display(),pWindow);
XRaiseWindow(QX11Info::display(),this->winId());
XSetInputFocus(QX11Info::display(),pWindow,RevertToParent,CurrentTime);
XUngrabServer(QX11Info::display());
XSync(QX11Info::display(),false);
问题在于,您必须仅显示顶级窗口,并且仅在应该显示它们时才显示。我也有同样的问题,我发现我在更多的地方显示了客户端窗口,而不是MapRequest事件处理程序!所以请检查您的代码,也许您正在处理另一个事件,该事件显示一个没有显式请求的窗口
如果您需要任何进一步的帮助,请发布所有事件处理程序,然后评论我的答案,我将对其进行编辑并尝试为您提供帮助。我已经找到问题的原因。我在客户端的事件掩码中有一个奇数标志(SubstructureRedirectMask)。此标志仅适用于根窗口和我自己创建的窗口。但在一个案例中,它仍然不起作用。当我在网页(例如YouTube)上有一个视频并尝试将其扩展到全屏时,视频会出现在单独的窗口中。我确信除了MapRequest,我不会在其他地方创建边界。也许我对“顶级窗口”的检查不正确?请不要将代码添加为单独的答案,而是编辑您的问题。然后,当您在网页上看到flash对象时,它是一个X窗口。当您单击全屏按钮时,窗口应作为顶级窗口重新租入并调整大小。您是否忘记在ReparentNotify处理程序中使用override_redirect标志?我根本没有ReparentNotify处理程序。但我有这个事件的调试输出,我并没有从带有视频的窗口接收ReparentNotify,只有MapRequest。MapRequest中的调试输出表示它是“顶级”窗口,而不是“覆盖_重定向”窗口。它有正常类型。我不知道如何知道这个窗口不应该有边界。还有什么其他特性会对其产生影响?
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);