Improved handling of child windows.

Don't force-create QWindows until they're explicitly created or shown.
This commit is contained in:
Samuel Rødal 2011-05-04 12:38:39 +02:00
parent 9ff98b92a1
commit f838dcc050
7 changed files with 46 additions and 47 deletions

View File

@ -1,6 +1,6 @@
#include "window.h" #include "window.h"
#include <private/qguiapplication_qpa_p.h> #include <private/qguiapplication_p.h>
#include <private/qwindowsurface_p.h> #include <private/qwindowsurface_p.h>
#include <QPainter> #include <QPainter>
@ -15,22 +15,17 @@ QColor colorTable[] =
}; };
Window::Window(QWindow *parent) Window::Window(QWindow *parent)
: QWindow(0) : QWindow(parent)
, m_backgroundColorIndex(colorIndexId++) , m_backgroundColorIndex(colorIndexId++)
{ {
setSurfaceType(RasterSurface); setSurfaceType(RasterSurface);
setWindowTitle(QLatin1String("Window")); setWindowTitle(QLatin1String("Window"));
if (parent) if (parent)
setGeometry(QRect(10, 10, 40, 40)); setGeometry(QRect(160, 120, 320, 240));
else else
setGeometry(QRect(10, 10, 640, 480)); setGeometry(QRect(10, 10, 640, 480));
if (parent) {
setParent(parent);
setGeometry(QRect(160, 120, 320, 240));
}
create(); create();
QGuiApplicationPrivate::platformIntegration()->createWindowSurface(this, winId()); QGuiApplicationPrivate::platformIntegration()->createWindowSurface(this, winId());

View File

@ -44,6 +44,7 @@
#include <QtCore/qcoreapplication.h> #include <QtCore/qcoreapplication.h>
#include <QtGui/qwindowdefs.h> #include <QtGui/qwindowdefs.h>
#include <QtCore/qlocale.h>
#include <QtCore/qpoint.h> #include <QtCore/qpoint.h>
#include <QtCore/qsize.h> #include <QtCore/qsize.h>

View File

@ -54,11 +54,10 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QWindow::QWindow(QWindow *parent) QWindow::QWindow(QWindow *parent)
: QObject(*new QWindowPrivate()) : QObject(*new QWindowPrivate(), parent)
{ {
if (parent) { Q_D(QWindow);
setParent(parent); d->parentWindow = parent;
}
} }
QWindow::~QWindow() QWindow::~QWindow()
@ -90,15 +89,15 @@ void QWindow::create()
d->windowFlags = d->platformWindow->setWindowFlags(d->windowFlags); d->windowFlags = d->platformWindow->setWindowFlags(d->windowFlags);
if (!d->windowTitle.isNull()) if (!d->windowTitle.isNull())
d->platformWindow->setWindowTitle(d->windowTitle); d->platformWindow->setWindowTitle(d->windowTitle);
}
Q_ASSERT(d->platformWindow);
QObjectList childObjects = children(); QObjectList childObjects = children();
for (int i = 0; i < childObjects.size(); i ++) { for (int i = 0; i < childObjects.size(); i ++) {
QObject *object = childObjects.at(i); QObject *object = childObjects.at(i);
if(object->isWindowType()) { if(object->isWindowType()) {
QWindow *window = static_cast<QWindow *>(object); QWindow *window = static_cast<QWindow *>(object);
window->setParent(this); if (window->d_func()->platformWindow)
window->d_func()->platformWindow->setParent(d->platformWindow);
}
} }
} }
} }
@ -120,26 +119,20 @@ void QWindow::setParent(QWindow *parent)
{ {
Q_D(QWindow); Q_D(QWindow);
if (d->parent == parent) if (d->parentWindow == parent)
return; return;
QObject::setParent(parent); QObject::setParent(parent);
if (parent) { if (d->platformWindow) {
if (parent->d_func()->platformWindow) { if (parent && parent->d_func()->platformWindow) {
if(!d->platformWindow) {
create();
}
d->platformWindow->setParent(parent->d_func()->platformWindow); d->platformWindow->setParent(parent->d_func()->platformWindow);
d->parent = parent; } else if (!parent) {
}
} else {
d->parent = 0;
if (d->parentWindow) {
d->platformWindow->setParent(0); d->platformWindow->setParent(0);
} }
} }
d->parentWindow = parent;
} }
void QWindow::setWindowFormat(const QWindowFormat &format) void QWindow::setWindowFormat(const QWindowFormat &format)

View File

@ -59,6 +59,7 @@ public:
: QObjectPrivate() : QObjectPrivate()
, windowFlags(Qt::Window) , windowFlags(Qt::Window)
, surfaceType(QWindow::RasterSurface) , surfaceType(QWindow::RasterSurface)
, parentWindow(0)
, platformWindow(0) , platformWindow(0)
, visible(false) , visible(false)
, glContext(0) , glContext(0)

View File

@ -64,8 +64,7 @@ void q_createNativeChildrenAndSetParent(QWindow *parentWindow, const QWidget *pa
if (childWidget->testAttribute(Qt::WA_NativeWindow)) { if (childWidget->testAttribute(Qt::WA_NativeWindow)) {
if (!childWidget->windowHandle()) if (!childWidget->windowHandle())
childWidget->winId(); childWidget->winId();
} if (childWidget->windowHandle())
if (childWidget->windowHandle()) {
childWidget->windowHandle()->setParent(parentWindow); childWidget->windowHandle()->setParent(parentWindow);
} else { } else {
q_createNativeChildrenAndSetParent(parentWindow,childWidget); q_createNativeChildrenAndSetParent(parentWindow,childWidget);
@ -93,6 +92,13 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
QWindow *win = topData()->window; QWindow *win = topData()->window;
if (!q->isWindow()) {
if (QWidget *nativeParent = q->nativeParentWidget()) {
if (nativeParent->windowHandle())
win->setParent(nativeParent->windowHandle());
}
}
win->setWindowFlags(data.window_flags); win->setWindowFlags(data.window_flags);
win->setGeometry(q->geometry()); win->setGeometry(q->geometry());
win->create(); win->create();
@ -111,16 +117,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
setWinId(win->winId()); setWinId(win->winId());
// first check children. and create them if necessary // first check children. and create them if necessary
q_createNativeChildrenAndSetParent(q->windowHandle(),q); // q_createNativeChildrenAndSetParent(q->windowHandle(),q);
//if we we have a parent, then set correct parent;
if (!q->isWindow()) {
if (QWidget *nativeParent = q->nativeParentWidget()) {
if (nativeParent->windowHandle()) {
win->setParent(nativeParent->windowHandle());
}
}
}
QGuiApplicationPrivate::platformIntegration()->moveToScreen(q, topData()->screenIndex); QGuiApplicationPrivate::platformIntegration()->moveToScreen(q, topData()->screenIndex);
// qDebug() << "create_sys" << q << q->internalWinId(); // qDebug() << "create_sys" << q << q->internalWinId();
@ -381,6 +378,9 @@ void QWidgetPrivate::show_sys()
QApplication::postEvent(q, new QUpdateLaterEvent(q->rect())); QApplication::postEvent(q, new QUpdateLaterEvent(q->rect()));
if (!q->isWindow() && !q->testAttribute(Qt::WA_NativeWindow))
return;
QWindow *window = q->windowHandle(); QWindow *window = q->windowHandle();
if (window) { if (window) {
QRect geomRect = q->geometry(); QRect geomRect = q->geometry();

View File

@ -108,6 +108,11 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
QMouseEvent translated(event->type(), mapped, event->globalPos(), event->button(), event->buttons(), event->modifiers()); QMouseEvent translated(event->type(), mapped, event->globalPos(), event->button(), event->buttons(), event->modifiers());
QGuiApplication::sendSpontaneousEvent(widget, &translated); QGuiApplication::sendSpontaneousEvent(widget, &translated);
if (event->type() == QEvent::MouseButtonPress && event->button() == Qt::RightButton) {
QContextMenuEvent e(QContextMenuEvent::Mouse, mapped, event->globalPos(), event->modifiers());
QGuiApplication::sendSpontaneousEvent(widget, &e);
}
} }
void QWidgetWindow::handleKeyEvent(QKeyEvent *event) void QWidgetWindow::handleKeyEvent(QKeyEvent *event)

View File

@ -113,6 +113,10 @@ QXcbWindow::QXcbWindow(QWindow *window)
QRect rect = window->geometry(); QRect rect = window->geometry();
xcb_window_t xcb_parent_id = m_screen->root();
if (window->parent() && window->parent()->windowHandle())
xcb_parent_id = static_cast<QXcbWindow *>(window->parent()->windowHandle())->xcb_window();
#if defined(XCB_USE_GLX) || defined(XCB_USE_EGL) #if defined(XCB_USE_GLX) || defined(XCB_USE_EGL)
if (window->surfaceType() == QWindow::OpenGLSurface if (window->surfaceType() == QWindow::OpenGLSurface
&& QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) && QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
@ -133,11 +137,11 @@ QXcbWindow::QXcbWindow(QWindow *window)
visualInfo = XGetVisualInfo(DISPLAY_FROM_XCB(this), VisualIDMask, &visualInfoTemplate, &matchingCount); visualInfo = XGetVisualInfo(DISPLAY_FROM_XCB(this), VisualIDMask, &visualInfoTemplate, &matchingCount);
#endif //XCB_USE_GLX #endif //XCB_USE_GLX
if (visualInfo) { if (visualInfo) {
Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), m_screen->root(), visualInfo->visual, AllocNone); Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), xcb_parent_id, visualInfo->visual, AllocNone);
XSetWindowAttributes a; XSetWindowAttributes a;
a.colormap = cmap; a.colormap = cmap;
m_window = XCreateWindow(DISPLAY_FROM_XCB(this), m_screen->root(), rect.x(), rect.y(), rect.width(), rect.height(), m_window = XCreateWindow(DISPLAY_FROM_XCB(this), xcb_parent_id, rect.x(), rect.y(), rect.width(), rect.height(),
0, visualInfo->depth, InputOutput, visualInfo->visual, 0, visualInfo->depth, InputOutput, visualInfo->visual,
CWColormap, &a); CWColormap, &a);
@ -153,7 +157,7 @@ QXcbWindow::QXcbWindow(QWindow *window)
Q_XCB_CALL(xcb_create_window(xcb_connection(), Q_XCB_CALL(xcb_create_window(xcb_connection(),
XCB_COPY_FROM_PARENT, // depth -- same as root XCB_COPY_FROM_PARENT, // depth -- same as root
m_window, // window id m_window, // window id
m_screen->root(), // parent window id xcb_parent_id, // parent window id
rect.x(), rect.x(),
rect.y(), rect.y(),
rect.width(), rect.width(),