Оконный менеджер.Внутреннее содержимое X окон в отдельном окне? - PullRequest
0 голосов
/ 27 октября 2011

Я пишу свой собственный диспетчер окон, используя 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);

1 Ответ

0 голосов
/ 28 октября 2011

Проблема в том, что вы должны показывать ТОЛЬКО свои окна верхнего уровня, и только тогда, когда они должны быть показаны. У меня была та же проблема, и я обнаружил, что я показываю окно клиента в большем количестве мест, чем обработчик событий MapRequest! Так что проверьте свой код, возможно, вы обрабатываете другое событие, которое показывает окно без явного запроса!

Если вам нужна дополнительная помощь, пожалуйста, опубликуйте все ваши обработчики событий, затем прокомментируйте мой ответ, я отредактирую его и постараюсь помочь вам.

...