Xlib과 Qt 4.7을 사용하여 내 창 관리자를 쓰고 있습니다. 그래서 제 응용 프로그램에서 XServer의 모든 이벤트를 잡았습니다.창 관리자. X 윈도우의 내부 내용이 별도의 창에 있습니까?
다음은 문제입니다. 'MapRequest'이벤트에 창을 표시 할 때 내부 콘텐츠가 별도의 창에 표시되는 경우가 있습니다. 대부분의 경우 브라우저 (예 : Firefox 및 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);
나는 이미 문제의 원인을 발견했다. 클라이언트 이벤트 마스크에 하나의 이상한 플래그가 있습니다 (SubstructureRedirectMask). 이 플래그는 루트 창과 내가 만든 창에 대해서만 필요합니다. 그러나 한 경우에는 여전히 작동하지 않습니다. 웹 페이지 (예 : YouTube)에 비디오를 가지고 전체 화면으로 확장하려고하면 비디오가 별도의 창에 나타납니다. 나는 MapRequest를 제외한 다른 장소에 경계를 만들지 않을 것이라고 확신한다. 어쩌면 "최상위 창"에 대한 내 검사가 정확하지 않을 수 있습니까? – Nemo
코드를 별도의 답변으로 추가하지 말고 대신 질문을 편집하십시오. – AlQafir
그러면 웹 페이지에서 플래시 객체를 볼 때 X 윈도우가됩니다. 전체 화면 단추를 클릭하면 창의 크기가 최상위 창으로 변경되고 크기가 조정됩니다. ReparentNotify 핸들러에서 override_redirect 플래그를 사용하는 것을 잊어 버리십니까? – AlQafir