Merge branch 'newdocs'
[profile/ivi/qtdeclarative.git] / src / quick / items / qquickwindow.cpp
index 0924c24..4ea31a0 100644 (file)
@@ -1,38 +1,38 @@
 /****************************************************************************
 **
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
 **
 ** This file is part of the QtQml module of the Qt Toolkit.
 **
 ** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
 ** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 **
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 **
 ** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
 **
 **
 ** $QT_END_LICENSE$
@@ -80,47 +80,73 @@ void QQuickWindowPrivate::updateFocusItemTransform()
         qApp->inputMethod()->setInputItemTransform(QQuickItemPrivate::get(focus)->itemToWindowTransform());
 }
 
+
 class QQuickWindowIncubationController : public QObject, public QQmlIncubationController
 {
+    Q_OBJECT
+
 public:
-    QQuickWindowIncubationController(QQuickWindowPrivate *window)
-    : m_window(window), m_eventSent(false) {}
+    QQuickWindowIncubationController(const QQuickWindow *window)
+        : m_window(QQuickWindowPrivate::get(const_cast<QQuickWindow *>(window)))
+    {
+        // Allow incubation for 1/3 of a frame.
+        m_incubation_time = qMax(1, int(1000 / QGuiApplication::primaryScreen()->refreshRate()) / 3);
+
+        m_animation_driver = m_window->windowManager->animationDriver();
+        if (m_animation_driver) {
+            connect(m_animation_driver, SIGNAL(stopped()), this, SLOT(animationStopped()));
+            connect(window, SIGNAL(frameSwapped()), this, SLOT(incubate()));
+        }
+    }
 
 protected:
     virtual bool event(QEvent *e)
     {
         if (e->type() == QEvent::User) {
-            Q_ASSERT(m_eventSent);
-            volatile bool *amtp = m_window->windowManager->allowMainThreadProcessing();
-            while (incubatingObjectCount()) {
-                if (amtp)
-                    incubateWhile(amtp, 2);
-                else
-                    incubateFor(5);
-                QCoreApplication::processEvents();
-            }
-
-            m_eventSent = false;
+            incubate();
+            return true;
         }
         return QObject::event(e);
     }
 
+public slots:
+    void incubate() {
+        if (incubatingObjectCount()) {
+            if (m_animation_driver && m_animation_driver->isRunning()) {
+                incubateFor(m_incubation_time);
+            } else {
+                incubateFor(m_incubation_time * 2);
+                if (incubatingObjectCount())
+                    QCoreApplication::postEvent(this, new QEvent(QEvent::User));
+            }
+        }
+    }
+
+    void animationStopped() { incubate(); }
+
+protected:
     virtual void incubatingObjectCountChanged(int count)
     {
-        if (count && !m_eventSent) {
-            m_eventSent = true;
+        if (count && (!m_animation_driver || !m_animation_driver->isRunning()))
             QCoreApplication::postEvent(this, new QEvent(QEvent::User));
-        }
-        // If no animations are running, the renderer may be waiting
-        m_window->windowManager->wakeup();
     }
 
 private:
     QQuickWindowPrivate *m_window;
-    bool m_eventSent;
+    int m_incubation_time;
+    QAnimationDriver *m_animation_driver;
 };
 
+#include "qquickwindow.moc"
+
+
 #ifndef QT_NO_ACCESSIBILITY
+/*!
+    Returns an accessibility interface for this window, or 0 if such an
+    interface cannot be created.
+
+    \warning The caller is responsible for deleting the returned interface.
+*/
 QAccessibleInterface *QQuickWindow::accessibleRoot() const
 {
     return QAccessible::queryAccessibleInterface(const_cast<QQuickWindow*>(this));
@@ -196,14 +222,14 @@ void QQuickWindow::hideEvent(QHideEvent *)
 void QQuickWindow::focusOutEvent(QFocusEvent *)
 {
     Q_D(QQuickWindow);
-    d->rootItem->setFocus(false);
+    d->contentItem->setFocus(false);
 }
 
 /*! \reimp */
 void QQuickWindow::focusInEvent(QFocusEvent *)
 {
     Q_D(QQuickWindow);
-    d->rootItem->setFocus(true);
+    d->contentItem->setFocus(true);
     d->updateFocusItemTransform();
 }
 
@@ -233,9 +259,8 @@ void QQuickWindowPrivate::polishItems()
  * This parameter enables that this window can be rendered without
  * being shown on screen. This feature is very limited in what it supports.
  *
- * There needs to be another window actually showing that we can make current
- * to get a surface to make current AND for this feature to be useful
- * one needs to hook into beforeRender() and set the render tareget.
+ * For this feature to be useful one needs to hook into beforeRender()
+ * and set the render target.
  *
  */
 void QQuickWindowPrivate::setRenderWithoutShowing(bool render)
@@ -284,10 +309,10 @@ void QQuickWindowPrivate::syncSceneGraph()
 
     emit q->beforeSynchronizing();
     if (!renderer) {
-        forceUpdate(rootItem);
+        forceUpdate(contentItem);
 
         QSGRootNode *rootNode = new QSGRootNode;
-        rootNode->appendChildNode(QQuickItemPrivate::get(rootItem)->itemNode());
+        rootNode->appendChildNode(QQuickItemPrivate::get(contentItem)->itemNode());
         renderer = context->createRenderer();
         renderer->setRootNode(rootNode);
     }
@@ -323,7 +348,7 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size)
 }
 
 QQuickWindowPrivate::QQuickWindowPrivate()
-    : rootItem(0)
+    : contentItem(0)
     , activeFocusItem(0)
     , mouseGrabberItem(0)
 #ifndef QT_NO_CURSOR
@@ -357,18 +382,18 @@ void QQuickWindowPrivate::init(QQuickWindow *c)
 
     Q_Q(QQuickWindow);
 
-    rootItem = new QQuickRootItem;
-    QQmlEngine::setObjectOwnership(rootItem, QQmlEngine::CppOwnership);
-    QQuickItemPrivate *rootItemPrivate = QQuickItemPrivate::get(rootItem);
-    rootItemPrivate->window = q;
-    rootItemPrivate->windowRefCount = 1;
-    rootItemPrivate->flags |= QQuickItem::ItemIsFocusScope;
+    contentItem = new QQuickRootItem;
+    QQmlEngine::setObjectOwnership(contentItem, QQmlEngine::CppOwnership);
+    QQuickItemPrivate *contentItemPrivate = QQuickItemPrivate::get(contentItem);
+    contentItemPrivate->window = q;
+    contentItemPrivate->windowRefCount = 1;
+    contentItemPrivate->flags |= QQuickItem::ItemIsFocusScope;
 
     // In the absence of a focus in event on some platforms assume the window will
-    // be activated immediately and set focus on the rootItem
+    // be activated immediately and set focus on the contentItem
     // ### Remove when QTBUG-22415 is resolved.
-    //It is important that this call happens after the rootItem has a window..
-    rootItem->setFocus(true);
+    //It is important that this call happens after the contentItem has a window..
+    contentItem->setFocus(true);
 
     windowManager = QQuickWindowManager::instance();
     context = windowManager->sceneGraphContext();
@@ -380,21 +405,26 @@ void QQuickWindowPrivate::init(QQuickWindow *c)
     QObject::connect(context, SIGNAL(invalidated()), q, SLOT(cleanupSceneGraph()), Qt::DirectConnection);
 }
 
+/*!
+    \property QQuickWindow::data
+    \internal
+*/
+
 QQmlListProperty<QObject> QQuickWindowPrivate::data()
 {
-    initRootItem();
-    return QQuickItemPrivate::get(rootItem)->data();
+    initContentItem();
+    return QQuickItemPrivate::get(contentItem)->data();
 }
 
-void QQuickWindowPrivate::initRootItem()
+void QQuickWindowPrivate::initContentItem()
 {
     Q_Q(QQuickWindow);
     q->connect(q, SIGNAL(widthChanged(int)),
-            rootItem, SLOT(setWidth(int)));
+            contentItem, SLOT(setWidth(int)));
     q->connect(q, SIGNAL(heightChanged(int)),
-            rootItem, SLOT(setHeight(int)));
-    rootItem->setWidth(q->width());
-    rootItem->setHeight(q->height());
+            contentItem, SLOT(setHeight(int)));
+    contentItem->setWidth(q->width());
+    contentItem->setHeight(q->height());
 }
 
 static QMouseEvent *touchToMouseEvent(QEvent::Type type, const QTouchEvent::TouchPoint &p, QTouchEvent *event, QQuickItem *item, bool transformNeeded = true)
@@ -497,7 +527,7 @@ bool QQuickWindowPrivate::translateTouchToMouse(QQuickItem *item, QTouchEvent *e
                     lastMousePosition = me->windowPos();
 
                     bool accepted = me->isAccepted();
-                    bool delivered = deliverHoverEvent(rootItem, me->windowPos(), last, me->modifiers(), accepted);
+                    bool delivered = deliverHoverEvent(contentItem, me->windowPos(), last, me->modifiers(), accepted);
                     if (!delivered) {
                         //take care of any exits
                         accepted = clearHover();
@@ -564,7 +594,7 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, F
     Q_Q(QQuickWindow);
 
     Q_ASSERT(item);
-    Q_ASSERT(scope || item == rootItem);
+    Q_ASSERT(scope || item == contentItem);
 
 #ifdef FOCUS_DEBUG
     qWarning() << "QQuickWindowPrivate::setFocusInScope():";
@@ -584,7 +614,7 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, F
     QVarLengthArray<QQuickItem *, 20> changed;
 
     // Does this change the active focus?
-    if (item == rootItem || (scopePrivate->activeFocus && item->isEnabled())) {
+    if (item == contentItem || (scopePrivate->activeFocus && item->isEnabled())) {
         oldActiveFocusItem = activeFocusItem;
         newActiveFocusItem = item;
         while (newActiveFocusItem->isFocusScope()
@@ -613,7 +643,7 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, F
         }
     }
 
-    if (item != rootItem && !(options & DontChangeSubFocusItem)) {
+    if (item != contentItem && !(options & DontChangeSubFocusItem)) {
         QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
         if (oldSubFocusItem) {
             QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
@@ -624,13 +654,13 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, F
     }
 
     if (!(options & DontChangeFocusProperty)) {
-//        if (item != rootItem || QGuiApplication::focusWindow() == q) {    // QTBUG-22415
+//        if (item != contentItem || QGuiApplication::focusWindow() == q) {    // QTBUG-22415
             itemPrivate->focus = true;
             changed << item;
 //        }
     }
 
-    if (newActiveFocusItem && rootItem->hasFocus()) {
+    if (newActiveFocusItem && contentItem->hasFocus()) {
         activeFocusItem = newActiveFocusItem;
 
         QQuickItemPrivate::get(newActiveFocusItem)->activeFocus = true;
@@ -660,7 +690,7 @@ void QQuickWindowPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item,
     Q_Q(QQuickWindow);
 
     Q_ASSERT(item);
-    Q_ASSERT(scope || item == rootItem);
+    Q_ASSERT(scope || item == contentItem);
 
 #ifdef FOCUS_DEBUG
     qWarning() << "QQuickWindowPrivate::clearFocusInScope():";
@@ -681,10 +711,10 @@ void QQuickWindowPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item,
 
     QVarLengthArray<QQuickItem *, 20> changed;
 
-    Q_ASSERT(item == rootItem || item == scopePrivate->subFocusItem);
+    Q_ASSERT(item == contentItem || item == scopePrivate->subFocusItem);
 
     // Does this change the active focus?
-    if (item == rootItem || scopePrivate->activeFocus) {
+    if (item == contentItem || scopePrivate->activeFocus) {
         oldActiveFocusItem = activeFocusItem;
         newActiveFocusItem = scope;
 
@@ -708,7 +738,7 @@ void QQuickWindowPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item,
         }
     }
 
-    if (item != rootItem && !(options & DontChangeSubFocusItem)) {
+    if (item != contentItem && !(options & DontChangeSubFocusItem)) {
         QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
         if (oldSubFocusItem && !(options & DontChangeFocusProperty)) {
             QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
@@ -774,21 +804,6 @@ void QQuickWindowPrivate::cleanup(QSGNode *n)
     q->maybeUpdate();
 }
 
-
-/*!
-    \qmlmodule QtQuick.Window 2
-    \title QML Module QtQuick.Window 2.0
-    \brief Contains types for window management
-
-    This QML module contains types for creating top-level windows and accessing screen information.
-
-    To use the types in this module, import the module with the following line:
-
-    \code
-    import QtQuick.Window 2.0
-    \endcode
-*/
-
 /*!
     \qmltype Window
     \instantiates QQuickWindow
@@ -902,6 +917,12 @@ void QQuickWindowPrivate::cleanup(QSGNode *n)
     may result in the entire scene graph and its OpenGL context being deleted. The
     sceneGraphInvalidated() signal will be emitted when this happens.
 
+    \sa {OpenGL Under QML Example}
+
+*/
+
+/*!
+    Constructs a window for displaying a QML scene with parent window \a parent.
 */
 QQuickWindow::QQuickWindow(QWindow *parent)
     : QWindow(*(new QQuickWindowPrivate), parent)
@@ -910,6 +931,9 @@ QQuickWindow::QQuickWindow(QWindow *parent)
     d->init(this);
 }
 
+/*!
+    \internal
+*/
 QQuickWindow::QQuickWindow(QQuickWindowPrivate &dd, QWindow *parent)
     : QWindow(dd, parent)
 {
@@ -917,6 +941,9 @@ QQuickWindow::QQuickWindow(QQuickWindowPrivate &dd, QWindow *parent)
     d->init(this);
 }
 
+/*!
+    Destroys the window.
+*/
 QQuickWindow::~QQuickWindow()
 {
     Q_D(QQuickWindow);
@@ -926,7 +953,7 @@ QQuickWindow::~QQuickWindow()
     QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
     delete d->incubationController; d->incubationController = 0;
 
-    delete d->rootItem; d->rootItem = 0;
+    delete d->contentItem; d->contentItem = 0;
 }
 
 
@@ -941,7 +968,7 @@ QQuickWindow::~QQuickWindow()
     functions can be used to prevent this from happening, if handling the cleanup is
     not feasible in the application, at the cost of higher memory usage.
 
-    \sa sceneGraphInvalidated(), setPersistentOpenGLContext(), setPersistentSceneGraph().
+    \sa sceneGraphInvalidated(), setPersistentOpenGLContext(), setPersistentSceneGraph()
  */
 
 void QQuickWindow::releaseResources()
@@ -954,8 +981,8 @@ void QQuickWindow::releaseResources()
 
 
 /*!
-    Controls whether the OpenGL context can be released as a part of a call to
-    releaseResources().
+    Sets whether the OpenGL context can be released as a part of a call to
+    releaseResources() to \a persistent.
 
     The OpenGL context might still be released when the user makes an explicit
     call to hide().
@@ -984,8 +1011,8 @@ bool QQuickWindow::isPersistentOpenGLContext() const
 
 
 /*!
-    Controls whether the scene graph nodes and resources can be released as a
-    part of a call to releaseResources().
+    Sets whether the scene graph nodes and resources can be released as a
+    part of a call to releaseResources() to \a persistent.
 
     The scene graph nodes and resources might still be released when the user
     makes an explicit call to hide().
@@ -1017,7 +1044,8 @@ bool QQuickWindow::isPersistentSceneGraph() const
 
 
 /*!
-  Returns the invisible root item of the scene.
+    \property QQuickWindow::contentItem
+    \brief The invisible root item of the scene.
 
   A QQuickWindow always has a single invisible root item containing all of its content.
   To add items to this window, reparent the items to the contentItem or to an existing
@@ -1027,7 +1055,7 @@ QQuickItem *QQuickWindow::contentItem() const
 {
     Q_D(const QQuickWindow);
 
-    return d->rootItem;
+    return d->contentItem;
 }
 
 /*!
@@ -1065,14 +1093,6 @@ QQuickItem *QQuickWindow::mouseGrabberItem() const
 }
 
 
-/*!
-    \qmlproperty color QtQuick.Window2::Window::color
-
-    The background color for the window.
-
-    Setting this property is more efficient than using a separate Rectangle.
-*/
-
 bool QQuickWindowPrivate::clearHover()
 {
     Q_Q(QQuickWindow);
@@ -1121,7 +1141,7 @@ bool QQuickWindow::event(QEvent *e)
         break;
 #endif
     case QEvent::WindowDeactivate:
-        rootItem()->windowDeactivateEvent();
+        contentItem()->windowDeactivateEvent();
         break;
     case QEvent::FocusAboutToChange:
         if (d->activeFocusItem)
@@ -1180,7 +1200,7 @@ bool QQuickWindowPrivate::deliverInitialMousePressEvent(QQuickItem *item, QMouse
     QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
     for (int ii = children.count() - 1; ii >= 0; --ii) {
         QQuickItem *child = children.at(ii);
-        if (!child->isVisible() || !child->isEnabled())
+        if (!child->isVisible() || !child->isEnabled() || QQuickItemPrivate::get(child)->culled)
             continue;
         if (deliverInitialMousePressEvent(child, event))
             return true;
@@ -1213,7 +1233,7 @@ bool QQuickWindowPrivate::deliverMouseEvent(QMouseEvent *event)
     if (!mouseGrabberItem &&
          event->type() == QEvent::MouseButtonPress &&
          (event->buttons() & event->button()) == event->buttons()) {
-        if (deliverInitialMousePressEvent(rootItem, event))
+        if (deliverInitialMousePressEvent(contentItem, event))
             event->accept();
         else
             event->ignore();
@@ -1271,7 +1291,7 @@ void QQuickWindow::mouseDoubleClickEvent(QMouseEvent *event)
 #endif
 
     if (!d->mouseGrabberItem && (event->buttons() & event->button()) == event->buttons()) {
-        if (d->deliverInitialMousePressEvent(d->rootItem, event))
+        if (d->deliverInitialMousePressEvent(d->contentItem, event))
             event->accept();
         else
             event->ignore();
@@ -1316,7 +1336,7 @@ void QQuickWindow::mouseMoveEvent(QMouseEvent *event)
         d->lastMousePosition = event->windowPos();
 
         bool accepted = event->isAccepted();
-        bool delivered = d->deliverHoverEvent(d->rootItem, event->windowPos(), last, event->modifiers(), accepted);
+        bool delivered = d->deliverHoverEvent(d->contentItem, event->windowPos(), last, event->modifiers(), accepted);
         if (!delivered) {
             //take care of any exits
             accepted = d->clearHover();
@@ -1342,7 +1362,7 @@ bool QQuickWindowPrivate::deliverHoverEvent(QQuickItem *item, const QPointF &sce
     QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
     for (int ii = children.count() - 1; ii >= 0; --ii) {
         QQuickItem *child = children.at(ii);
-        if (!child->isVisible() || !child->isEnabled())
+        if (!child->isVisible() || !child->isEnabled() || QQuickItemPrivate::get(child)->culled)
             continue;
         if (deliverHoverEvent(child, scenePos, lastScenePos, modifiers, accepted))
             return true;
@@ -1408,7 +1428,7 @@ bool QQuickWindowPrivate::deliverWheelEvent(QQuickItem *item, QWheelEvent *event
     QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
     for (int ii = children.count() - 1; ii >= 0; --ii) {
         QQuickItem *child = children.at(ii);
-        if (!child->isVisible() || !child->isEnabled())
+        if (!child->isVisible() || !child->isEnabled() || QQuickItemPrivate::get(child)->culled)
             continue;
         if (deliverWheelEvent(child, event))
             return true;
@@ -1439,12 +1459,12 @@ void QQuickWindow::wheelEvent(QWheelEvent *event)
     qWarning() << "QQuickWindow::wheelEvent()" << event->pixelDelta() << event->angleDelta();
 #endif
 
-    //if the actual wheel event was accepted, accept the compatability wheel event and return early
+    //if the actual wheel event was accepted, accept the compatibility wheel event and return early
     if (d->lastWheelEventAccepted && event->angleDelta().isNull())
         return;
 
     event->ignore();
-    d->deliverWheelEvent(d->rootItem, event);
+    d->deliverWheelEvent(d->contentItem, event);
     d->lastWheelEventAccepted = event->isAccepted();
 }
 #endif // QT_NO_WHEELEVENT
@@ -1515,7 +1535,7 @@ bool QQuickWindowPrivate::deliverTouchEvent(QTouchEvent *event)
     // or some item accepted a point and should receive an update
     if (newPoints.count() > 0 || updatedPoints.count() > 0) {
         QSet<int> acceptedNewPoints;
-        event->setAccepted(deliverTouchPoints(rootItem, event, newPoints, &acceptedNewPoints, &updatedPoints));
+        event->setAccepted(deliverTouchPoints(contentItem, event, newPoints, &acceptedNewPoints, &updatedPoints));
     } else
         event->ignore();
 
@@ -1555,7 +1575,7 @@ bool QQuickWindowPrivate::deliverTouchPoints(QQuickItem *item, QTouchEvent *even
     QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
     for (int ii = children.count() - 1; ii >= 0; --ii) {
         QQuickItem *child = children.at(ii);
-        if (!child->isEnabled() || !child->isVisible())
+        if (!child->isEnabled() || !child->isVisible() || QQuickItemPrivate::get(child)->culled)
             continue;
         if (deliverTouchPoints(child, event, newPoints, acceptedNewPoints, updatedPoints))
             return true;
@@ -1786,7 +1806,7 @@ void QQuickWindowPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QEvent *e
                 e->mouseButtons(),
                 e->keyboardModifiers());
         QQuickDropEventEx::copyActions(&enterEvent, *e);
-        event->setAccepted(deliverDragEvent(grabber, rootItem, &enterEvent));
+        event->setAccepted(deliverDragEvent(grabber, contentItem, &enterEvent));
     }
 }
 
@@ -1795,7 +1815,7 @@ bool QQuickWindowPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QQuickIte
     Q_Q(QQuickWindow);
     bool accepted = false;
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
-    if (!item->isVisible() || !item->isEnabled())
+    if (!item->isVisible() || !item->isEnabled() || QQuickItemPrivate::get(item)->culled)
         return false;
 
     QPointF p = item->mapFromScene(event->pos());
@@ -1846,7 +1866,7 @@ void QQuickWindowPrivate::updateCursor(const QPointF &scenePos)
     Q_Q(QQuickWindow);
 
     QQuickItem *oldCursorItem = cursorItem;
-    cursorItem = findCursorItem(rootItem, scenePos);
+    cursorItem = findCursorItem(contentItem, scenePos);
 
     if (cursorItem != oldCursorItem) {
         if (cursorItem)
@@ -1865,13 +1885,18 @@ QQuickItem *QQuickWindowPrivate::findCursorItem(QQuickItem *item, const QPointF
             return 0;
     }
 
-    QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
-    for (int ii = children.count() - 1; ii >= 0; --ii) {
-        QQuickItem *child = children.at(ii);
-        if (!child->isVisible() || !child->isEnabled())
-            continue;
-        if (QQuickItem *cursorItem = findCursorItem(child, scenePos))
-            return cursorItem;
+    const int numCursorsInHierarchy = itemPrivate->extra.isAllocated() ? itemPrivate->extra.value().numItemsWithCursor : 0;
+    const int numChildrenWithCursor = itemPrivate->hasCursor ? numCursorsInHierarchy-1 : numCursorsInHierarchy;
+
+    if (numChildrenWithCursor > 0) {
+        QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
+        for (int ii = children.count() - 1; ii >= 0; --ii) {
+            QQuickItem *child = children.at(ii);
+            if (!child->isVisible() || !child->isEnabled() || QQuickItemPrivate::get(child)->culled)
+                continue;
+            if (QQuickItem *cursorItem = findCursorItem(child, scenePos))
+                return cursorItem;
+        }
     }
 
     if (itemPrivate->hasCursor) {
@@ -1967,8 +1992,21 @@ bool QQuickWindowPrivate::dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent
     return overThreshold;
 }
 
+bool QQuickWindowPrivate::isRenderable() const
+{
+    if (geometry.width() <= 0 || geometry.height() <= 0)
+        return false;
+    // Change to be applied after the visibility property is integrated in qtbase:
+//    return visibility != QWindow::Hidden || (renderWithoutShowing && platformWindow);
+    // Temporary version which is implementation-agnostic but slightly less efficient:
+    const QQuickWindow *q = q_func();
+    return q->isVisible() || (renderWithoutShowing && platformWindow);
+}
+
 /*!
-    Propagates an event to a QQuickItem on the window
+    Propagates an event \a e to a QQuickItem \a item on the window.
+
+    The return value is currently not used.
 */
 bool QQuickWindow::sendEvent(QQuickItem *item, QEvent *e)
 {
@@ -2076,7 +2114,7 @@ void QQuickWindowPrivate::cleanupNodesOnShutdown()
 {
     Q_Q(QQuickWindow);
     cleanupNodes();
-    cleanupNodesOnShutdown(rootItem);
+    cleanupNodesOnShutdown(contentItem);
     QSet<QQuickItem *>::const_iterator it = parentlessItems.begin();
     for (; it != parentlessItems.end(); ++it)
         cleanupNodesOnShutdown(*it);
@@ -2386,9 +2424,17 @@ QOpenGLContext *QQuickWindow::openglContext() const
     return 0;
 }
 
+/*!
+    \fn void QQuickWindow::frameSwapped()
+
+    This signal is emitted when the frame buffers have been swapped.
+
+    This signal will be emitted from the scene graph rendering thread.
+*/
+
 
 /*!
-    \fn void QSGContext::sceneGraphInitialized()
+    \fn void QQuickWindow::sceneGraphInitialized()
 
     This signal is emitted when the scene graph has been initialized.
 
@@ -2398,7 +2444,7 @@ QOpenGLContext *QQuickWindow::openglContext() const
 
 
 /*!
-    \fn void QSGContext::sceneGraphInvalidated()
+    \fn void QQuickWindow::sceneGraphInvalidated()
 
     This signal is emitted when the scene graph has been invalidated.
 
@@ -2424,7 +2470,7 @@ QOpenGLContext *QQuickWindow::openglContext() const
 void QQuickWindow::setRenderTarget(QOpenGLFramebufferObject *fbo)
 {
     Q_D(QQuickWindow);
-    if (d->context && d->context && QThread::currentThread() != d->context->thread()) {
+    if (d->context && QThread::currentThread() != d->context->thread()) {
         qWarning("QQuickWindow::setRenderThread: Cannot set render target from outside the rendering thread");
         return;
     }
@@ -2441,11 +2487,22 @@ void QQuickWindow::setRenderTarget(QOpenGLFramebufferObject *fbo)
 
 /*!
     \overload
- */
+
+    Sets the render target for this window to be an FBO with
+    \a fboId and \a size.
+
+    The specified FBO must be created in the context of the window
+    or one that shares with it.
+
+    \warning
+    This function can only be called from the thread doing
+    the rendering.
+*/
+
 void QQuickWindow::setRenderTarget(uint fboId, const QSize &size)
 {
     Q_D(QQuickWindow);
-    if (d->context && d->context && QThread::currentThread() != d->context->thread()) {
+    if (d->context && QThread::currentThread() != d->context->thread()) {
         qWarning("QQuickWindow::setRenderThread: Cannot set render target from outside the rendering thread");
         return;
     }
@@ -2468,7 +2525,7 @@ uint QQuickWindow::renderTargetId() const
 }
 
 /*!
-    Returns the size of the currently set render target; otherwise returns an enpty size.
+    Returns the size of the currently set render target; otherwise returns an empty size.
  */
 QSize QQuickWindow::renderTargetSize() const
 {
@@ -2510,7 +2567,7 @@ QImage QQuickWindow::grabWindow()
 /*!
     Returns an incubation controller that splices incubation between frames
     for this window. QQuickView automatically installs this controller for you,
-    otherwise you will need to install it yourself using \l{QQmlEngine::setIncubationController}
+    otherwise you will need to install it yourself using \l{QQmlEngine::setIncubationController()}.
 
     The controller is owned by the window and will be destroyed when the window
     is deleted.
@@ -2520,7 +2577,7 @@ QQmlIncubationController *QQuickWindow::incubationController() const
     Q_D(const QQuickWindow);
 
     if (!d->incubationController)
-        d->incubationController = new QQuickWindowIncubationController(const_cast<QQuickWindowPrivate *>(d));
+        d->incubationController = new QQuickWindowIncubationController(this);
     return d->incubationController;
 }
 
@@ -2542,6 +2599,25 @@ QQmlIncubationController *QQuickWindow::incubationController() const
  */
 
 /*!
+    \fn void QQuickWindow::beforeSynchronizing()
+
+    This signal is emitted before the scene graph is synchronized with the QML state.
+
+    This signal can be used to do any preparation required before calls to
+    QQuickItem::updatePaintNode().
+
+    The GL context used for rendering the scene graph will be bound at this point.
+
+    \warning This signal is emitted from the scene graph rendering thread. If your
+    slot function needs to finish before execution continues, you must make sure that
+    the connection is direct (see Qt::ConnectionType).
+
+    \warning Make very sure that a signal handler for beforeSynchronizing leaves the GL
+    context in the same state as it was when the signal handler was entered. Failing to
+    do so can result in the scene not rendering properly.
+*/
+
+/*!
     \fn void QQuickWindow::beforeRendering()
 
     This signal is emitted before the scene starts rendering.
@@ -2552,8 +2628,9 @@ QQmlIncubationController *QQuickWindow::incubationController() const
     The GL context used for rendering the scene graph will be bound
     at this point.
 
-    \warning Since this signal is emitted from the scene graph rendering thread, the
-    receiver should be on the scene graph thread or the connection should be Qt::DirectConnection.
+    \warning This signal is emitted from the scene graph rendering thread. If your
+    slot function needs to finish before execution continues, you must make sure that
+    the connection is direct (see Qt::ConnectionType).
 
     \warning Make very sure that a signal handler for beforeRendering leaves the GL
     context in the same state as it was when the signal handler was entered. Failing to
@@ -2570,8 +2647,9 @@ QQmlIncubationController *QQuickWindow::incubationController() const
 
     The GL context used for rendering the scene graph will be bound at this point.
 
-    \warning Since this signal is emitted from the scene graph rendering thread, the
-    receiver should be on the scene graph thread or the connection should be Qt::DirectConnection.
+    \warning This signal is emitted from the scene graph rendering thread. If your
+    slot function needs to finish before execution continues, you must make sure that
+    the connection is direct (see Qt::ConnectionType).
 
     \warning Make very sure that a signal handler for afterRendering() leaves the GL
     context in the same state as it was when the signal handler was entered. Failing to
@@ -2581,8 +2659,8 @@ QQmlIncubationController *QQuickWindow::incubationController() const
 
 
 /*!
-    Sets weither the scene graph rendering of QML should clear the color buffer
-    before it starts rendering to \a enbled.
+    Sets whether the scene graph rendering of QML should clear the color buffer
+    before it starts rendering to \a enabled.
 
     By disabling clearing of the color buffer, it is possible to do GL painting
     under the scene graph.
@@ -2601,7 +2679,7 @@ void QQuickWindow::setClearBeforeRendering(bool enabled)
 
 
 /*!
-    Returns weither clearing of the color buffer is done before rendering or not.
+    Returns whether clearing of the color buffer is done before rendering or not.
  */
 
 bool QQuickWindow::clearBeforeRendering() const
@@ -2628,7 +2706,7 @@ bool QQuickWindow::clearBeforeRendering() const
     initialized.
 
     \warning The returned texture is not memory managed by the scene graph and
-    must be explicitely deleted by the caller on the rendering thread.
+    must be explicitly deleted by the caller on the rendering thread.
     This is acheived by deleting the texture from a QSGNode destructor
     or by using deleteLater() in the case where the texture already has affinity
     to the rendering thread.
@@ -2650,7 +2728,7 @@ QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image) const
 
 
 /*!
-    Creates a new QSGTexture object from an existing GL texture \a id.
+    Creates a new QSGTexture object from an existing GL texture \a id and \a size.
 
     The caller of the function is responsible for deleting the returned texture.
 
@@ -2676,11 +2754,20 @@ QSGTexture *QQuickWindow::createTextureFromId(uint id, const QSize &size, Create
     return 0;
 }
 
+/*!
+    \qmlproperty color QtQuick.Window2::Window::color
+
+    The background color for the window.
+
+    Setting this property is more efficient than using a separate Rectangle.
+*/
 
 /*!
-    Sets the color used to clear the opengl context to \a color.
+    \property QQuickWindow::color
+    \brief The color used to clear the OpenGL context.
 
     Setting the clear color has no effect when clearing is disabled.
+    By default, the clear color is white.
 
     \sa setClearBeforeRendering()
  */
@@ -2693,20 +2780,34 @@ void QQuickWindow::setColor(const QColor &color)
 
     d->clearColor = color;
     emit colorChanged(color);
+    d->dirtyItem(contentItem());
 }
 
-
-
-/*!
-    Returns the color used to clear the opengl context.
- */
-
 QColor QQuickWindow::color() const
 {
     return d_func()->clearColor;
 }
 
+/*!
+    \qmlproperty string QtQuick.Window2::Window::title
+
+    The window's title in the windowing system.
+
+    The window title might appear in the title area of the window decorations,
+    depending on the windowing system and the window flags. It might also
+    be used by the windowing system to identify the window in other contexts,
+    such as in the task switcher.
+ */
 
+/*!
+    \qmlproperty string QtQuick.Window2::Window::modality
+
+    The modality of the window.
+
+    A modal window prevents other windows from receiving input events.
+    Possible values are Qt.NonModal (the default), Qt.WindowModal,
+    and Qt.ApplicationModal.
+ */
 
 #include "moc_qquickwindow.cpp"