2011-10-27 5 views
0

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); 

답변

0

문제는 표시해야 할 때만 최상위 창만 표시해야한다는 것입니다. 나는 같은 문제가 있었고 MapRequest 이벤트 핸들러보다 많은 곳에서 클라이언트 윈도우를 보여주고 있다는 것을 발견했습니다! 코드를 확인하십시오. 명시 적 요청없이 창을 표시하는 다른 이벤트를 처리하고있을 수도 있습니다!

추가 도움이 필요하면 모든 이벤트 처리기를 게시 한 다음 내 대답에 댓글을 달아서 편집하고 도움을 요청하십시오.

+0

나는 이미 문제의 원인을 발견했다. 클라이언트 이벤트 마스크에 하나의 이상한 플래그가 있습니다 (SubstructureRedirectMask). 이 플래그는 루트 창과 내가 만든 창에 대해서만 필요합니다. 그러나 한 경우에는 여전히 작동하지 않습니다. 웹 페이지 (예 : YouTube)에 비디오를 가지고 전체 화면으로 확장하려고하면 비디오가 별도의 창에 나타납니다. 나는 MapRequest를 제외한 다른 장소에 경계를 만들지 않을 것이라고 확신한다. 어쩌면 "최상위 창"에 대한 내 검사가 정확하지 않을 수 있습니까? – Nemo

+0

코드를 별도의 답변으로 추가하지 말고 대신 질문을 편집하십시오. – AlQafir

+0

그러면 웹 페이지에서 플래시 객체를 볼 때 X 윈도우가됩니다. 전체 화면 단추를 클릭하면 창의 크기가 최상위 창으로 변경되고 크기가 조정됩니다. ReparentNotify 핸들러에서 override_redirect 플래그를 사용하는 것을 잊어 버리십니까? – AlQafir