Improved handling of child windows.
authorSamuel Rødal <samuel.rodal@nokia.com>
Wed, 4 May 2011 10:38:39 +0000 (12:38 +0200)
committerSamuel Rødal <samuel.rodal@nokia.com>
Wed, 4 May 2011 11:14:29 +0000 (13:14 +0200)
Don't force-create QWindows until they're explicitly created or shown.

examples/qpa/windows/window.cpp
src/gui/guikernel/qguiapplication.h
src/gui/guikernel/qwindow.cpp
src/gui/guikernel/qwindow_p.h
src/gui/kernel/qwidget_qpa.cpp
src/gui/kernel/qwidgetwindow_qpa.cpp
src/plugins/platforms/xcb/qxcbwindow.cpp

index 0f3355b..d08db57 100644 (file)
@@ -1,6 +1,6 @@
 #include "window.h"
 
-#include <private/qguiapplication_qpa_p.h>
+#include <private/qguiapplication_p.h>
 #include <private/qwindowsurface_p.h>
 
 #include <QPainter>
@@ -15,22 +15,17 @@ QColor colorTable[] =
 };
 
 Window::Window(QWindow *parent)
-    : QWindow(0)
+    : QWindow(parent)
     , m_backgroundColorIndex(colorIndexId++)
 {
     setSurfaceType(RasterSurface);
     setWindowTitle(QLatin1String("Window"));
 
     if (parent)
-        setGeometry(QRect(10, 10, 40, 40));
+        setGeometry(QRect(160, 120, 320, 240));
     else
         setGeometry(QRect(10, 10, 640, 480));
 
-    if (parent) {
-        setParent(parent);
-        setGeometry(QRect(160, 120, 320, 240));
-    }
-
     create();
     QGuiApplicationPrivate::platformIntegration()->createWindowSurface(this, winId());
 
index 16f56d0..f1ac01d 100644 (file)
@@ -44,6 +44,7 @@
 
 #include <QtCore/qcoreapplication.h>
 #include <QtGui/qwindowdefs.h>
+#include <QtCore/qlocale.h>
 #include <QtCore/qpoint.h>
 #include <QtCore/qsize.h>
 
index 7b57a94..6064795 100644 (file)
 QT_BEGIN_NAMESPACE
 
 QWindow::QWindow(QWindow *parent)
-    : QObject(*new QWindowPrivate())
+    : QObject(*new QWindowPrivate(), parent)
 {
-    if (parent) {
-        setParent(parent);
-    }
+    Q_D(QWindow);
+    d->parentWindow = parent;
 }
 
 QWindow::~QWindow()
@@ -90,15 +89,15 @@ void QWindow::create()
         d->windowFlags = d->platformWindow->setWindowFlags(d->windowFlags);
         if (!d->windowTitle.isNull())
             d->platformWindow->setWindowTitle(d->windowTitle);
-    }
-    Q_ASSERT(d->platformWindow);
-
-    QObjectList childObjects = children();
-    for (int i = 0; i < childObjects.size(); i ++) {
-        QObject *object = childObjects.at(i);
-        if(object->isWindowType()) {
-            QWindow *window = static_cast<QWindow *>(object);
-            window->setParent(this);
+
+        QObjectList childObjects = children();
+        for (int i = 0; i < childObjects.size(); i ++) {
+            QObject *object = childObjects.at(i);
+            if(object->isWindowType()) {
+                QWindow *window = static_cast<QWindow *>(object);
+                if (window->d_func()->platformWindow)
+                    window->d_func()->platformWindow->setParent(d->platformWindow);
+            }
         }
     }
 }
@@ -120,26 +119,20 @@ void QWindow::setParent(QWindow *parent)
 {
     Q_D(QWindow);
 
-    if (d->parent == parent)
+    if (d->parentWindow == parent)
         return;
 
     QObject::setParent(parent);
 
-    if (parent) {
-        if (parent->d_func()->platformWindow) {
-            if(!d->platformWindow) {
-                create();
-            }
+    if (d->platformWindow) {
+        if (parent && parent->d_func()->platformWindow) {
             d->platformWindow->setParent(parent->d_func()->platformWindow);
-            d->parent = parent;
-        }
-    } else  {
-        d->parent = 0;
-        if (d->parentWindow) {
+        } else if (!parent) {
             d->platformWindow->setParent(0);
         }
     }
 
+    d->parentWindow = parent;
 }
 
 void QWindow::setWindowFormat(const QWindowFormat &format)
index 304ab3b..6f1038e 100644 (file)
@@ -59,6 +59,7 @@ public:
         : QObjectPrivate()
         , windowFlags(Qt::Window)
         , surfaceType(QWindow::RasterSurface)
+        , parentWindow(0)
         , platformWindow(0)
         , visible(false)
         , glContext(0)
index 8c55708..5ef3b89 100644 (file)
@@ -64,9 +64,8 @@ void q_createNativeChildrenAndSetParent(QWindow *parentWindow, const QWidget *pa
                 if (childWidget->testAttribute(Qt::WA_NativeWindow)) {
                     if (!childWidget->windowHandle())
                         childWidget->winId();
-                }
-                if (childWidget->windowHandle()) {
-                    childWidget->windowHandle()->setParent(parentWindow);
+                    if (childWidget->windowHandle())
+                        childWidget->windowHandle()->setParent(parentWindow);
                 } else {
                     q_createNativeChildrenAndSetParent(parentWindow,childWidget);
                 }
@@ -93,6 +92,13 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
 
     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->setGeometry(q->geometry());
     win->create();
@@ -111,16 +117,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
     setWinId(win->winId());
 
 //    first check children. and create them if necessary
-    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());
-            }
-        }
-    }
+//    q_createNativeChildrenAndSetParent(q->windowHandle(),q);
 
     QGuiApplicationPrivate::platformIntegration()->moveToScreen(q, topData()->screenIndex);
 //    qDebug() << "create_sys" << q << q->internalWinId();
@@ -381,6 +378,9 @@ void QWidgetPrivate::show_sys()
 
     QApplication::postEvent(q, new QUpdateLaterEvent(q->rect()));
 
+    if (!q->isWindow() && !q->testAttribute(Qt::WA_NativeWindow))
+        return;
+
     QWindow *window = q->windowHandle();
     if (window) {
         QRect geomRect = q->geometry();
index a58a037..ec60e57 100644 (file)
@@ -108,6 +108,11 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
 
     QMouseEvent translated(event->type(), mapped, event->globalPos(), event->button(), event->buttons(), event->modifiers());
     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)
index b0df622..8488655 100644 (file)
@@ -113,6 +113,10 @@ QXcbWindow::QXcbWindow(QWindow *window)
 
     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 (window->surfaceType() == QWindow::OpenGLSurface
         && QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
@@ -133,11 +137,11 @@ QXcbWindow::QXcbWindow(QWindow *window)
         visualInfo = XGetVisualInfo(DISPLAY_FROM_XCB(this), VisualIDMask, &visualInfoTemplate, &matchingCount);
 #endif //XCB_USE_GLX
         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;
             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,
                                       CWColormap, &a);
 
@@ -153,7 +157,7 @@ QXcbWindow::QXcbWindow(QWindow *window)
         Q_XCB_CALL(xcb_create_window(xcb_connection(),
                                      XCB_COPY_FROM_PARENT,            // depth -- same as root
                                      m_window,                        // window id
-                                     m_screen->root(),                // parent window id
+                                     xcb_parent_id,                   // parent window id
                                      rect.x(),
                                      rect.y(),
                                      rect.width(),