Qt4 窗口管理器。单独窗口中X窗口的内部内容?

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

我正在使用Xlib和Qt4.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;
}
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);