QQuickCanvas renames
[profile/ivi/qtdeclarative.git] / src / quick / items / qquickitem.cpp
index 032427d..667b919 100644 (file)
@@ -3,7 +3,7 @@
 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
 ** Contact: http://www.qt-project.org/
 **
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the QtQml module of the Qt Toolkit.
 **
 ** $QT_BEGIN_LICENSE:LGPL$
 ** GNU Lesser General Public License Usage
 
 #include "qquickitem.h"
 
-#include "qquickcanvas.h"
-#include <QtDeclarative/qjsengine.h>
-#include "qquickcanvas_p.h"
+#include "qquickwindow.h"
+#include <QtQml/qjsengine.h>
+#include "qquickwindow_p.h"
 
 #include "qquickevents_p_p.h"
 #include "qquickscreen_p.h"
 
-#include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/qdeclarativecomponent.h>
-#include <QtDeclarative/qdeclarativeinfo.h>
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlcomponent.h>
+#include <QtQml/qqmlinfo.h>
 #include <QtGui/qpen.h>
-#include <QtGui/qcursor.h>
 #include <QtGui/qguiapplication.h>
-#include <QtGui/qinputpanel.h>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/qinputmethod.h>
 #include <QtCore/qdebug.h>
 #include <QtCore/qcoreevent.h>
 #include <QtCore/qnumeric.h>
 
-#include <private/qdeclarativeengine_p.h>
-#include <QtQuick/private/qdeclarativestategroup_p.h>
-#include <private/qdeclarativeopenmetaobject_p.h>
-#include <QtQuick/private/qdeclarativestate_p.h>
+#include <private/qqmlglobal_p.h>
+#include <private/qqmlengine_p.h>
+#include <QtQuick/private/qquickstategroup_p.h>
+#include <private/qqmlopenmetaobject_p.h>
+#include <QtQuick/private/qquickstate_p.h>
 #include <private/qlistmodelinterface_p.h>
 #include <private/qquickitem_p.h>
-#include <private/qdeclarativeaccessors_p.h>
+#include <private/qqmlaccessors_p.h>
 #include <QtQuick/private/qquickaccessibleattached_p.h>
 
 #include <float.h>
 
 QT_BEGIN_NAMESPACE
 
-static void QQuickItem_parentNotifier(QObject *o, intptr_t, QDeclarativeNotifier **n)
+#ifdef FOCUS_DEBUG
+void printFocusTree(QQuickItem *item, QQuickItem *scope = 0, int depth = 1);
+void printFocusTree(QQuickItem *item, QQuickItem *scope, int depth)
+{
+    qWarning()
+            << QByteArray(depth, '\t').constData()
+            << (scope && QQuickItemPrivate::get(scope)->subFocusItem == item ? '*' : ' ')
+            << item->hasFocus()
+            << item->hasActiveFocus()
+            << item->isFocusScope()
+            << item;
+    foreach (QQuickItem *child, item->childItems()) {
+        printFocusTree(
+                child,
+                item->isFocusScope() || !scope ? item : scope,
+                item->isFocusScope() || !scope ? depth + 1 : depth);
+    }
+}
+#endif
+
+static void QQuickItem_parentNotifier(QObject *o, intptr_t, QQmlNotifier **n)
 {
     QQuickItemPrivate *d = QQuickItemPrivate::get(static_cast<QQuickItem *>(o));
     *n = &d->parentNotifier;
@@ -86,11 +107,11 @@ QML_PRIVATE_ACCESSOR(QQuickItem, qreal, y, y)
 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, width, width)
 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, height, height)
 
-static QDeclarativeAccessors QQuickItem_parent = { QQuickItem_parentRead, QQuickItem_parentNotifier };
-static QDeclarativeAccessors QQuickItem_x = { QQuickItem_xRead, 0 };
-static QDeclarativeAccessors QQuickItem_y = { QQuickItem_yRead, 0 };
-static QDeclarativeAccessors QQuickItem_width = { QQuickItem_widthRead, 0 };
-static QDeclarativeAccessors QQuickItem_height = { QQuickItem_heightRead, 0 };
+static QQmlAccessors QQuickItem_parent = { QQuickItem_parentRead, QQuickItem_parentNotifier };
+static QQmlAccessors QQuickItem_x = { QQuickItem_xRead, 0 };
+static QQmlAccessors QQuickItem_y = { QQuickItem_yRead, 0 };
+static QQmlAccessors QQuickItem_width = { QQuickItem_widthRead, 0 };
+static QQmlAccessors QQuickItem_height = { QQuickItem_heightRead, 0 };
 
 QML_DECLARE_PROPERTIES(QQuickItem) {
     { QML_PROPERTY_NAME(parent), 0, &QQuickItem_parent },
@@ -108,37 +129,37 @@ void QQuickItemPrivate::registerAccessorProperties()
 /*!
     \qmlclass Transform QQuickTransform
     \inqmlmodule QtQuick 2
-    \ingroup qml-transform-elements
-    \brief The Transform elements provide a way of building advanced transformations on Items.
+    \ingroup qtquick-visual-transforms
+    \brief For specifying advanced transformations on Items
 
-    The Transform element is a base type which cannot be instantiated directly.
+    The Transform type is a base type which cannot be instantiated directly.
     The following concrete Transform types are available:
 
     \list
-    \o \l Rotation
-    \o \l Scale
-    \o \l Translate
+    \li \l Rotation
+    \li \l Scale
+    \li \l Translate
     \endlist
 
-    The Transform elements let you create and control advanced transformations that can be configured
+    The Transform types let you create and control advanced transformations that can be configured
     independently using specialized properties.
 
-    You can assign any number of Transform elements to an \l Item. Each Transform is applied in order,
+    You can assign any number of Transforms to an \l Item. Each Transform is applied in order,
     one at a time.
 */
 
 /*!
     \qmlclass Translate QQuickTranslate
     \inqmlmodule QtQuick 2
-    \ingroup qml-transform-elements
-    \brief The Translate object provides a way to move an Item without changing its x or y properties.
+    \ingroup qtquick-visual-transforms
+    \brief Provides a way to move an Item without changing its x or y properties
 
     The Translate object provides independent control over position in addition to the Item's x and y properties.
 
-    The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element
+    The following example moves the Y axis of the \l Rectangle items while still allowing the \l Row
     to lay the items out as if they had not been transformed:
     \qml
-    import QtQuick 1.0
+    import QtQuick 2.0
 
     Row {
         Rectangle {
@@ -172,10 +193,10 @@ void QQuickItemPrivate::registerAccessorProperties()
 /*!
     \qmlclass Scale QQuickScale
     \inqmlmodule QtQuick 2
-    \ingroup qml-transform-elements
-    \brief The Scale element provides a way to scale an Item.
+    \ingroup qtquick-visual-transforms
+    \brief Provides a way to scale an Item
 
-    The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
+    The Scale type gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically,
     it allows a different scale for the x and y axes, and allows the scale to be relative to an
     arbitrary point.
 
@@ -214,8 +235,8 @@ void QQuickItemPrivate::registerAccessorProperties()
 /*!
     \qmlclass Rotation QQuickRotation
     \inqmlmodule QtQuick 2
-    \ingroup qml-transform-elements
-    \brief The Rotation object provides a way to rotate an Item.
+    \ingroup qtquick-visual-transforms
+    \brief Provides a way to rotate an Item
 
     The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property.
     Specifically, it allows (z axis) rotation to be relative to an arbitrary point.
@@ -233,7 +254,7 @@ void QQuickItemPrivate::registerAccessorProperties()
     rotations you must specify the axis to rotate around in addition to the origin point.
 
     The following example shows various 3D-like rotations applied to an \l Image.
-    \snippet doc/src/snippets/declarative/rotation.qml 0
+    \snippet qml/rotation.qml 0
 
     \image axisrotation.png
 
@@ -442,8 +463,8 @@ QQuickItemKeyFilter::QQuickItemKeyFilter(QQuickItem *item)
 {
     QQuickItemPrivate *p = item?QQuickItemPrivate::get(item):0;
     if (p) {
-        m_next = p->keyHandler;
-        p->keyHandler = this;
+        m_next = p->extra.value().keyHandler;
+        p->extra->keyHandler = this;
     }
 }
 
@@ -482,8 +503,8 @@ void QQuickItemKeyFilter::componentComplete()
 /*!
     \qmlclass KeyNavigation QQuickKeyNavigationAttached
     \inqmlmodule QtQuick 2
-    \ingroup qml-basic-interaction-elements
-    \brief The KeyNavigation attached property supports key navigation by arrow keys.
+    \ingroup qtquick-input
+    \brief Supports key navigation by arrow keys
 
     Key-based user interfaces commonly allow the use of arrow keys to navigate between
     focusable items.  The KeyNavigation attached property enables this behavior by providing a
@@ -491,7 +512,7 @@ void QQuickItemKeyFilter::componentComplete()
 
     The following example provides key navigation for a 2x2 grid of items:
 
-    \snippet doc/src/snippets/declarative/keynavigation.qml 0
+    \snippet qml/keynavigation.qml 0
 
     The top-left item initially receives focus by setting \l {Item::}{focus} to
     \c true. When an arrow key is pressed, the focus will move to the
@@ -545,7 +566,7 @@ void QQuickItemKeyFilter::componentComplete()
 
 QQuickKeyNavigationAttached::QQuickKeyNavigationAttached(QObject *parent)
 : QObject(*(new QQuickKeyNavigationAttachedPrivate), parent),
-  QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
+  QQuickItemKeyFilter(qmlobject_cast<QQuickItem*>(parent))
 {
     m_processPost = true;
 }
@@ -695,10 +716,10 @@ void QQuickKeyNavigationAttached::setBacktab(QQuickItem *i)
     or after the attached item's own key handling.
 
     \list
-    \o KeyNavigation.BeforeItem - process the key events before normal
+    \li KeyNavigation.BeforeItem - process the key events before normal
     item key processing.  If the event is used for key navigation, it will be accepted and will not
     be passed on to the item.
-    \o KeyNavigation.AfterItem (default) - process the key events after normal item key
+    \li KeyNavigation.AfterItem (default) - process the key events after normal item key
     handling.  If the item accepts the key event it will not be
     handled by the KeyNavigation attached property handler.
     \endlist
@@ -886,16 +907,18 @@ const QQuickKeysAttached::SigMap QQuickKeysAttached::sigMap[] = {
     { 0, 0 }
 };
 
-bool QQuickKeysAttachedPrivate::isConnected(const char *signalName)
+bool QQuickKeysAttached::isConnected(const char *signalName)
 {
-    return isSignalConnected(signalIndex(signalName));
+    Q_D(QQuickKeysAttached);
+    int signal_index = d->signalIndex(signalName);
+    return d->isSignalConnected(signal_index);
 }
 
 /*!
     \qmlclass Keys QQuickKeysAttached
     \inqmlmodule QtQuick 2
-    \ingroup qml-basic-interaction-elements
-    \brief The Keys attached property provides key handling to Items.
+    \ingroup qtquick-input
+    \brief Provides key handling to Items
 
     All visual primitives support key handling via the Keys
     attached property.  Keys can be handled via the onPressed
@@ -912,13 +935,13 @@ bool QQuickKeysAttachedPrivate::isConnected(const char *signalName)
     be used to test for a certain key; in this case, the left cursor
     key:
 
-    \snippet doc/src/snippets/declarative/keys/keys-pressed.qml key item
+    \snippet qml/keys/keys-pressed.qml key item
 
     Some keys may alternatively be handled via specific signal properties,
     for example \e onSelectPressed.  These handlers automatically set
     \e event.accepted to true.
 
-    \snippet doc/src/snippets/declarative/keys/keys-handler.qml key item
+    \snippet qml/keys/keys-handler.qml key item
 
     See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
 
@@ -932,21 +955,21 @@ bool QQuickKeysAttachedPrivate::isConnected(const char *signalName)
     If \l priority is Keys.BeforeItem (default) the order of key event processing is:
 
     \list 1
-    \o Items specified in \c forwardTo
-    \o specific key handlers, e.g. onReturnPressed
-    \o onKeyPress, onKeyRelease handlers
-    \o Item specific key handling, e.g. TextInput key handling
-    \o parent item
+    \li Items specified in \c forwardTo
+    \li specific key handlers, e.g. onReturnPressed
+    \li onKeyPress, onKeyRelease handlers
+    \li Item specific key handling, e.g. TextInput key handling
+    \li parent item
     \endlist
 
     If priority is Keys.AfterItem the order of key event processing is:
 
     \list 1
-    \o Item specific key handling, e.g. TextInput key handling
-    \o Items specified in \c forwardTo
-    \o specific key handlers, e.g. onReturnPressed
-    \o onKeyPress, onKeyRelease handlers
-    \o parent item
+    \li Item specific key handling, e.g. TextInput key handling
+    \li Items specified in \c forwardTo
+    \li specific key handlers, e.g. onReturnPressed
+    \li onKeyPress, onKeyRelease handlers
+    \li parent item
     \endlist
 
     If the event is accepted during any of the above steps, key
@@ -969,10 +992,10 @@ bool QQuickKeysAttachedPrivate::isConnected(const char *signalName)
     or after the attached item's own key handling.
 
     \list
-    \o Keys.BeforeItem (default) - process the key events before normal
+    \li Keys.BeforeItem (default) - process the key events before normal
     item key processing.  If the event is accepted it will not
     be passed on to the item.
-    \o Keys.AfterItem - process the key events after normal item key
+    \li Keys.AfterItem - process the key events after normal item key
     handling.  If the item accepts the key event it will not be
     handled by the Keys attached property handler.
     \endlist
@@ -1280,11 +1303,11 @@ bool QQuickKeysAttachedPrivate::isConnected(const char *signalName)
 
 QQuickKeysAttached::QQuickKeysAttached(QObject *parent)
 : QObject(*(new QQuickKeysAttachedPrivate), parent),
-  QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
+  QQuickItemKeyFilter(qmlobject_cast<QQuickItem*>(parent))
 {
     Q_D(QQuickKeysAttached);
     m_processPost = false;
-    d->item = qobject_cast<QQuickItem*>(parent);
+    d->item = qmlobject_cast<QQuickItem*>(parent);
 }
 
 QQuickKeysAttached::~QQuickKeysAttached()
@@ -1329,12 +1352,12 @@ void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
     }
 
     // first process forwards
-    if (d->item && d->item->canvas()) {
+    if (d->item && d->item->window()) {
         d->inPress = true;
         for (int ii = 0; ii < d->targets.count(); ++ii) {
             QQuickItem *i = d->targets.at(ii);
             if (i && i->isVisible()) {
-                d->item->canvas()->sendEvent(i, event);
+                d->item->window()->sendEvent(i, event);
                 if (event->isAccepted()) {
                     d->inPress = false;
                     return;
@@ -1348,7 +1371,7 @@ void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
     QByteArray keySignal = keyToSignal(event->key());
     if (!keySignal.isEmpty()) {
         keySignal += "(QQuickKeyEvent*)";
-        if (d->isConnected(keySignal)) {
+        if (isConnected(keySignal)) {
             // If we specifically handle a key then default to accepted
             ke.setAccepted(true);
             int idx = QQuickKeysAttached::staticMetaObject.indexOfSignal(keySignal);
@@ -1371,12 +1394,12 @@ void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
         return;
     }
 
-    if (d->item && d->item->canvas()) {
+    if (d->item && d->item->window()) {
         d->inRelease = true;
         for (int ii = 0; ii < d->targets.count(); ++ii) {
             QQuickItem *i = d->targets.at(ii);
             if (i && i->isVisible()) {
-                d->item->canvas()->sendEvent(i, event);
+                d->item->window()->sendEvent(i, event);
                 if (event->isAccepted()) {
                     d->inRelease = false;
                     return;
@@ -1396,12 +1419,12 @@ void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
 void QQuickKeysAttached::inputMethodEvent(QInputMethodEvent *event, bool post)
 {
     Q_D(QQuickKeysAttached);
-    if (post == m_processPost && d->item && !d->inIM && d->item->canvas()) {
+    if (post == m_processPost && d->item && !d->inIM && d->item->window()) {
         d->inIM = true;
         for (int ii = 0; ii < d->targets.count(); ++ii) {
             QQuickItem *i = d->targets.at(ii);
             if (i && i->isVisible() && (i->flags() & QQuickItem::ItemAcceptsInputMethod)) {
-                d->item->canvas()->sendEvent(i, event);
+                d->item->window()->sendEvent(i, event);
                 if (event->isAccepted()) {
                     d->imeItem = i;
                     d->inIM = false;
@@ -1440,18 +1463,19 @@ QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj)
 /*!
     \qmlclass LayoutMirroring QQuickLayoutMirroringAttached
     \inqmlmodule QtQuick 2
+    \ingroup qtquick-positioners
     \ingroup qml-utility-elements
-    \brief The LayoutMirroring attached property is used to mirror layout behavior.
+    \brief Property used to mirror layout behavior
 
     The LayoutMirroring attached property is used to horizontally mirror \l {anchor-layout}{Item anchors},
-    \l{Using QML Positioner and Repeater Items}{positioner} elements (such as \l Row and \l Grid)
+    \l{Using QML Positioner and Repeater Items}{positioner} types (such as \l Row and \l Grid)
     and views (such as \l GridView and horizontal \l ListView). Mirroring is a visual change: left
-    anchors become right anchors, and positioner elements like \l Grid and \l Row reverse the
+    anchors become right anchors, and positioner types like \l Grid and \l Row reverse the
     horizontal layout of child items.
 
     Mirroring is enabled for an item by setting the \l enabled property to true. By default, this
     only affects the item itself; setting the \l childrenInherit property to true propagates the mirroring
-    behavior to all child elements as well. If the \c LayoutMirroring attached property has not been defined
+    behavior to all child items as well. If the \c LayoutMirroring attached property has not been defined
     for an item, mirroring is not enabled.
 
     The following example shows mirroring in action. The \l Row below is specified as being anchored
@@ -1460,7 +1484,7 @@ QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj)
     from left to right by default, they are now positioned from right to left instead, as demonstrated
     by the numbering and opacity of the items:
 
-    \snippet doc/src/snippets/declarative/layoutmirroring.qml 0
+    \snippet qml/layoutmirroring.qml 0
 
     \image layoutmirroring.png
 
@@ -1484,8 +1508,8 @@ QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj)
 
     This property holds whether the item's layout is mirrored horizontally. Setting this to true
     horizontally reverses \l {anchor-layout}{anchor} settings such that left anchors become right,
-    and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} elements
-    (such as \l Row and \l Grid) and view elements (such as \l {GridView}{GridView} and \l {ListView}{ListView})
+    and right anchors become left. For \l{Using QML Positioner and Repeater Items}{positioner} types
+    (such as \l Row and \l Grid) and view types (such as \l {GridView}{GridView} and \l {ListView}{ListView})
     this also mirrors the horizontal layout direction of the item.
 
     The default value is false.
@@ -1505,7 +1529,7 @@ QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) :
 {
     if (QQuickItem *item = qobject_cast<QQuickItem*>(parent)) {
         itemPrivate = QQuickItemPrivate::get(item);
-        itemPrivate->attachedLayoutDirection = this;
+        itemPrivate->extra.value().layoutDirectionAttached = this;
     } else
         qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
 }
@@ -1579,7 +1603,7 @@ void QQuickItemPrivate::setImplicitLayoutMirror(bool mirror, bool inherit)
     if (isMirrorImplicit)
         setLayoutMirror(inherit ? inheritedLayoutMirror : false);
     for (int i = 0; i < childItems.count(); ++i) {
-        if (QQuickItem *child = qobject_cast<QQuickItem *>(childItems.at(i))) {
+        if (QQuickItem *child = qmlobject_cast<QQuickItem *>(childItems.at(i))) {
             QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child);
             childPrivate->setImplicitLayoutMirror(inheritedLayoutMirror, inheritMirrorFromParent);
         }
@@ -1595,11 +1619,10 @@ void QQuickItemPrivate::setLayoutMirror(bool mirror)
             anchor_d->fillChanged();
             anchor_d->centerInChanged();
             anchor_d->updateHorizontalAnchors();
-            emit _anchors->mirroredChanged();
         }
         mirrorChange();
-        if (attachedLayoutDirection) {
-            emit attachedLayoutDirection->enabledChanged();
+        if (extra.isAllocated() && extra->layoutDirectionAttached) {
+            emit extra->layoutDirectionAttached->enabledChanged();
         }
     }
 }
@@ -1612,40 +1635,96 @@ void QQuickItemPrivate::setAccessibleFlagAndListener()
         if (item->d_func()->isAccessible)
             break; // already set - grandparents should have the flag set as well.
 
-        if (item->canvas() && item->canvas()->rootItem() == item)
-            break; // don't add a listener to the canvas root item
-
         item->d_func()->isAccessible = true;
         item = item->d_func()->parentItem;
     }
 }
 
+void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
+{
+    Q_Q(QQuickItem);
+    Q_ASSERT(scope);
+
+    QQuickItemPrivate *scopePrivate = QQuickItemPrivate::get(scope);
+
+    QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
+    // Correct focus chain in scope
+    if (oldSubFocusItem) {
+        QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
+        while (sfi && sfi != scope) {
+            QQuickItemPrivate::get(sfi)->subFocusItem = 0;
+            sfi = sfi->parentItem();
+        }
+    }
+
+    if (focus) {
+        scopePrivate->subFocusItem = q;
+        QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
+        while (sfi && sfi != scope) {
+            QQuickItemPrivate::get(sfi)->subFocusItem = q;
+            sfi = sfi->parentItem();
+        }
+    } else {
+        scopePrivate->subFocusItem = 0;
+    }
+}
+
+
 /*!
     \class QQuickItem
-    \brief The QQuickItem class provides the most basic of all visual items in QML.
+    \brief The QQuickItem class provides the most basic of all visual items in QML
 
     \inmodule QtQuick
 
-    All visual items in Qt Declarative inherit from QQuickItem.  Although QQuickItem
+    All visual items in Qt Quick inherit from QQuickItem.  Although QQuickItem
     has no visual appearance, it defines all the properties that are
     common across visual items - such as the x and y position, the
     width and height, \l {anchor-layout}{anchoring} and key handling.
 
-    You can subclass QQuickItem to provide your own custom visual item that inherits
-    these features. Note that, because it does not draw anything, QQuickItem sets the
-    QGraphicsItem::ItemHasNoContents flag. If you subclass QQuickItem to create a visual
-    item, you will need to unset this flag.
+    You can subclass QQuickItem to provide your own custom visual item
+    that inherits these features.
+
+    \section1 Custom Items using Scene Graph
+
+    All visual QML items are rendered using the scene graph, a
+    low-level, high-performance rendering stack, closely tied to
+    OpenGL. It is possible for subclasses of QQuickItem to add their
+    own custom content into the scene graph by setting the
+    QQuickItem::ItemHasContents flag and reimplementing the
+    QQuickItem::updatePaintNode() function.
 
+    \warning It is crucial that OpenGL operations and interaction with
+    the scene graph happens exclusively on the rendering thread,
+    primarily during the updatePaintNode() call. The best rule of
+    thumb is to only use classes with the "QSG" prefix inside the
+    QQuickItem::updatePaintNode() function.
+
+    To read more about how the scene graph rendering works, see
+    \l{Scene Graph and Rendering}
+
+    \section1 Custom Items using QPainter
+
+    The QQuickItem provides a subclass, QQuickPaintedItem, which
+    allows the users to render content using QPainter.
+
+    \warning Using QQuickPaintedItem uses an indirect 2D surface to
+    render its content, either using software rasterization or using
+    an OpenGL framebuffer object (FBO), so the rendering is a two-step
+    operation. First rasterize the surface, then draw the
+    surface. Using scene graph API directly is always significantly
+    faster.
+
+    \sa QQuickWindow, QQuickPaintedItem
 */
 
 /*!
     \qmlclass Item QQuickItem
     \inherits QtObject
     \inqmlmodule QtQuick 2
-    \ingroup qml-basic-visual-elements
-    \brief The Item is the most basic of all visual items in QML.
+    \ingroup qtquick-visual
+    \brief A basic visual QML type
 
-    All visual items in Qt Declarative inherit from Item.  Although Item
+    All visual items in Qt Quick inherit from Item.  Although Item
     has no visual appearance, it defines all the properties that are
     common across visual items - such as the x and y position, the
     width and height, \l {anchor-layout}{anchoring} and key handling.
@@ -1676,7 +1755,7 @@ void QQuickItemPrivate::setAccessibleFlagAndListener()
 
     \section1 Key Handling
 
-    Key handling is available to all Item-based visual elements via the \l {Keys}{Keys}
+    Key handling is available to all Item-based visual types via the \l {Keys}{Keys}
     attached property.  The \e Keys attached property provides basic handlers such
     as \l {Keys::onPressed}{onPressed} and \l {Keys::onReleased}{onReleased},
     as well as handlers for specific keys, such as
@@ -1793,10 +1872,13 @@ QQuickItem::~QQuickItem()
 
     Q_D(QQuickItem);
 
+    if (d->windowRefCount > 1)
+        d->windowRefCount = 1; // Make sure window is set to null in next call to derefWindow().
     if (d->parentItem)
         setParentItem(0);
-    else if (d->canvas && d->itemNodeInstance)
-        QQuickCanvasPrivate::get(d->canvas)->cleanup(d->itemNodeInstance); // cleanup root
+    else if (d->window)
+        d->derefWindow();
+
     // XXX todo - optimize
     while (!d->childItems.isEmpty())
         d->childItems.first()->setParentItem(0);
@@ -1824,11 +1906,14 @@ QQuickItem::~QQuickItem()
     }
 
     d->changeListeners.clear();
-    delete d->_anchorLines; d->_anchorLines = 0;
+
+    if (d->extra.isAllocated()) {
+        delete d->extra->contents; d->extra->contents = 0;
+        delete d->extra->layer; d->extra->layer = 0;
+    }
+
     delete d->_anchors; d->_anchors = 0;
     delete d->_stateGroup; d->_stateGroup = 0;
-    delete d->_contents; d->_contents = 0;
-    delete d->_layer;
 }
 
 /*!
@@ -1851,7 +1936,7 @@ QQuickItem::~QQuickItem()
     The default transform origin is \c Item.Center.
 
     To set an arbitrary transform origin point use the \l Scale or \l Rotation
-    transform elements.
+    transform types.
 */
 
 /*!
@@ -1869,6 +1954,17 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
     if (parentItem == d->parentItem)
         return;
 
+    if (parentItem) {
+        QQuickItem *itemAncestor = parentItem->parentItem();
+        while (itemAncestor != 0) {
+            if (itemAncestor == this) {
+                qWarning("QQuickItem::setParentItem: Parent is already part of this items subtree.");
+                return;
+            }
+            itemAncestor = itemAncestor->parentItem();
+        }
+    }
+
     d->removeFromDirtyList();
 
     QQuickItem *oldParentItem = d->parentItem;
@@ -1879,54 +1975,85 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
 
         QQuickItem *scopeItem = 0;
 
-        if (d->canvas && hasFocus()) {
-            scopeItem = oldParentItem;
-            while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
+        if (hasFocus())
             scopeFocusedItem = this;
-        } else if (d->canvas && !isFocusScope() && d->subFocusItem) {
-            scopeItem = oldParentItem;
-            while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
+        else if (!isFocusScope() && d->subFocusItem)
             scopeFocusedItem = d->subFocusItem;
-        }
 
-        if (scopeFocusedItem)
-            QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
-                                                                QQuickCanvasPrivate::DontChangeFocusProperty);
+        if (scopeFocusedItem) {
+            scopeItem = oldParentItem;
+            while (!scopeItem->isFocusScope() && scopeItem->parentItem())
+                scopeItem = scopeItem->parentItem();
+            if (d->window) {
+                QQuickWindowPrivate::get(d->window)->clearFocusInScope(scopeItem, scopeFocusedItem,
+                                                                QQuickWindowPrivate::DontChangeFocusProperty);
+                if (scopeFocusedItem != this)
+                    QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, true);
+            } else {
+                QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, false);
+            }
+        }
 
+        const bool wasVisible = isVisible();
         op->removeChild(this);
-    } else if (d->canvas) {
-        QQuickCanvasPrivate::get(d->canvas)->parentlessItems.remove(this);
+        if (wasVisible) {
+            emit oldParentItem->visibleChildrenChanged();
+        }
+    } else if (d->window) {
+        QQuickWindowPrivate::get(d->window)->parentlessItems.remove(this);
     }
 
-    d->parentItem = parentItem;
-
-    QQuickCanvas *parentCanvas = parentItem?QQuickItemPrivate::get(parentItem)->canvas:0;
-    if (d->canvas != parentCanvas) {
-        QQuickItemPrivate::InitializationState initState;
-        initState.clear();
-        d->initCanvas(&initState, parentCanvas);
+    QQuickWindow *oldParentWindow = oldParentItem ? QQuickItemPrivate::get(oldParentItem)->window : 0;
+    QQuickWindow *parentWindow = parentItem ? QQuickItemPrivate::get(parentItem)->window : 0;
+    if (oldParentWindow == parentWindow) {
+        // Avoid freeing and reallocating resources if the window stays the same.
+        d->parentItem = parentItem;
+    } else {
+        if (oldParentWindow)
+            d->derefWindow();
+        d->parentItem = parentItem;
+        if (parentWindow)
+            d->refWindow(parentWindow);
     }
 
     d->dirty(QQuickItemPrivate::ParentChanged);
 
     if (d->parentItem)
         QQuickItemPrivate::get(d->parentItem)->addChild(this);
+    else if (d->window)
+        QQuickWindowPrivate::get(d->window)->parentlessItems.insert(this);
 
     d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
     d->setEffectiveEnableRecur(0, d->calcEffectiveEnable());
 
-    if (scopeFocusedItem && d->parentItem && d->canvas) {
-        // We need to test whether this item becomes scope focused
-        QQuickItem *scopeItem = 0;
-        scopeItem = d->parentItem;
-        while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
+    if (d->parentItem) {
+        if (!scopeFocusedItem) {
+            if (hasFocus())
+                scopeFocusedItem = this;
+            else if (!isFocusScope() && d->subFocusItem)
+                scopeFocusedItem = d->subFocusItem;
+        }
 
-        if (scopeItem->scopedFocusItem()) {
-            QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
-            emit scopeFocusedItem->focusChanged(false);
-        } else {
-            QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
-                                                              QQuickCanvasPrivate::DontChangeFocusProperty);
+        if (scopeFocusedItem) {
+            // We need to test whether this item becomes scope focused
+            QQuickItem *scopeItem = d->parentItem;
+            while (!scopeItem->isFocusScope() && scopeItem->parentItem())
+                scopeItem = scopeItem->parentItem();
+
+            if (QQuickItemPrivate::get(scopeItem)->subFocusItem
+                    || (!scopeItem->isFocusScope() && scopeItem->hasFocus())) {
+                if (scopeFocusedItem != this)
+                    QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, false);
+                QQuickItemPrivate::get(scopeFocusedItem)->focus = false;
+                emit scopeFocusedItem->focusChanged(false);
+            } else {
+                if (d->window) {
+                    QQuickWindowPrivate::get(d->window)->setFocusInScope(scopeItem, scopeFocusedItem,
+                                                                  QQuickWindowPrivate::DontChangeFocusProperty);
+                } else {
+                    QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, true);
+                }
+            }
         }
     }
 
@@ -1940,6 +2067,8 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
     }
 
     emit parentChanged(d->parentItem);
+    if (isVisible() && d->parentItem)
+        emit d->parentItem->visibleChildrenChanged();
 }
 
 void QQuickItem::stackBefore(const QQuickItem *sibling)
@@ -1952,19 +2081,15 @@ void QQuickItem::stackBefore(const QQuickItem *sibling)
 
     QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
 
-    int myIndex = parentPrivate->childItems.indexOf(this);
-    int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
+    int myIndex = parentPrivate->childItems.lastIndexOf(this);
+    int siblingIndex = parentPrivate->childItems.lastIndexOf(const_cast<QQuickItem *>(sibling));
 
     Q_ASSERT(myIndex != -1 && siblingIndex != -1);
 
     if (myIndex == siblingIndex - 1)
         return;
 
-    parentPrivate->childItems.removeAt(myIndex);
-
-    if (myIndex < siblingIndex) --siblingIndex;
-
-    parentPrivate->childItems.insert(siblingIndex, this);
+    parentPrivate->childItems.move(myIndex, myIndex < siblingIndex ? siblingIndex - 1 : siblingIndex);
 
     parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
     parentPrivate->markSortedChildrenDirty(this);
@@ -1983,19 +2108,15 @@ void QQuickItem::stackAfter(const QQuickItem *sibling)
 
     QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(d->parentItem);
 
-    int myIndex = parentPrivate->childItems.indexOf(this);
-    int siblingIndex = parentPrivate->childItems.indexOf(const_cast<QQuickItem *>(sibling));
+    int myIndex = parentPrivate->childItems.lastIndexOf(this);
+    int siblingIndex = parentPrivate->childItems.lastIndexOf(const_cast<QQuickItem *>(sibling));
 
     Q_ASSERT(myIndex != -1 && siblingIndex != -1);
 
     if (myIndex == siblingIndex + 1)
         return;
 
-    parentPrivate->childItems.removeAt(myIndex);
-
-    if (myIndex < siblingIndex) --siblingIndex;
-
-    parentPrivate->childItems.insert(siblingIndex + 1, this);
+    parentPrivate->childItems.move(myIndex, myIndex > siblingIndex ? siblingIndex + 1 : siblingIndex);
 
     parentPrivate->dirty(QQuickItemPrivate::ChildrenStackingChanged);
     parentPrivate->markSortedChildrenDirty(this);
@@ -2013,15 +2134,10 @@ QQuickItem *QQuickItem::parentItem() const
     return d->parentItem;
 }
 
-QSGEngine *QQuickItem::sceneGraphEngine() const
-{
-    return canvas()->sceneGraphEngine();
-}
-
-QQuickCanvas *QQuickItem::canvas() const
+QQuickWindow *QQuickItem::window() const
 {
     Q_D(const QQuickItem);
-    return d->canvas;
+    return d->window;
 }
 
 static bool itemZOrder_sort(QQuickItem *lhs, QQuickItem *rhs)
@@ -2038,7 +2154,7 @@ QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
     // the childItems list.  This is by far the most common case.
     bool haveZ = false;
     for (int i = 0; i < childItems.count(); ++i) {
-        if (QQuickItemPrivate::get(childItems.at(i))->z != 0.) {
+        if (QQuickItemPrivate::get(childItems.at(i))->z() != 0.) {
             haveZ = true;
             break;
         }
@@ -2087,108 +2203,120 @@ void QQuickItemPrivate::removeChild(QQuickItem *child)
     emit q->childrenChanged();
 }
 
-void QQuickItemPrivate::InitializationState::clear()
+void QQuickItemPrivate::refWindow(QQuickWindow *c)
 {
-    focusScope = 0;
-}
+    // An item needs a window if it is referenced by another item which has a window.
+    // Typically the item is referenced by a parent, but can also be referenced by a
+    // ShaderEffect or ShaderEffectSource. 'windowRefCount' counts how many items with
+    // a window is referencing this item. When the reference count goes from zero to one,
+    // or one to zero, the window of this item is updated and propagated to the children.
+    // As long as the reference count stays above zero, the window is unchanged.
+    // refWindow() increments the reference count.
+    // derefWindow() decrements the reference count.
 
-void QQuickItemPrivate::InitializationState::clear(QQuickItem *fs)
-{
-    focusScope = fs;
-}
-
-QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *item)
-{
-    if (!focusScope) {
-        QQuickItem *fs = item->parentItem();
-        while (!fs->isFocusScope())
-            fs = fs->parentItem();
-        focusScope = fs;
+    Q_Q(QQuickItem);
+    Q_ASSERT((window != 0) == (windowRefCount > 0));
+    Q_ASSERT(c);
+    if (++windowRefCount > 1) {
+        if (c != window)
+            qWarning("QQuickItem: Cannot use same item on different windows at the same time.");
+        return; // Window already set.
     }
-    return focusScope;
-}
 
-void QQuickItemPrivate::initCanvas(InitializationState *state, QQuickCanvas *c)
-{
-    Q_Q(QQuickItem);
+    Q_ASSERT(window == 0);
+    window = c;
+
+    if (polishScheduled)
+        QQuickWindowPrivate::get(window)->itemsToPolish.insert(q);
+
+    if (!parentItem)
+        QQuickWindowPrivate::get(window)->parentlessItems.insert(q);
 
-    if (canvas) {
-        removeFromDirtyList();
-        QQuickCanvasPrivate *c = QQuickCanvasPrivate::get(canvas);
-        if (polishScheduled)
-            c->itemsToPolish.remove(q);
-        if (c->mouseGrabberItem == q)
-            c->mouseGrabberItem = 0;
-        if ( hoverEnabled )
-            c->hoverItems.removeAll(q);
-        if (itemNodeInstance)
-            c->cleanup(itemNodeInstance);
-        if (!parentItem)
-            c->parentlessItems.remove(q);
+    for (int ii = 0; ii < childItems.count(); ++ii) {
+        QQuickItem *child = childItems.at(ii);
+        QQuickItemPrivate::get(child)->refWindow(c);
     }
 
-    canvas = c;
+    dirty(Window);
 
-    if (canvas && polishScheduled)
-        QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
+    if (extra.isAllocated() && extra->screenAttached)
+        extra->screenAttached->windowChanged(c);
+    itemChange(QQuickItem::ItemSceneChange, c);
+}
 
-    itemNodeInstance = 0;
-    opacityNode = 0;
-    clipNode = 0;
-    rootNode = 0;
-    groupNode = 0;
-    paintNode = 0;
-    beforePaintNode = 0;
+void QQuickItemPrivate::derefWindow()
+{
+    Q_Q(QQuickItem);
+    Q_ASSERT((window != 0) == (windowRefCount > 0));
+
+    if (!window)
+        return; // This can happen when destroying recursive shader effect sources.
+
+    if (--windowRefCount > 0)
+        return; // There are still other references, so don't set window to null yet.
+
+    q->releaseResources();
+    removeFromDirtyList();
+    QQuickWindowPrivate *c = QQuickWindowPrivate::get(window);
+    if (polishScheduled)
+        c->itemsToPolish.remove(q);
+    QMutableHashIterator<int, QQuickItem *> itemTouchMapIt(c->itemForTouchPointId);
+    while (itemTouchMapIt.hasNext()) {
+        if (itemTouchMapIt.next().value() == q)
+            itemTouchMapIt.remove();
+    }
+    if (c->mouseGrabberItem == q)
+        c->mouseGrabberItem = 0;
+    if ( hoverEnabled )
+        c->hoverItems.removeAll(q);
+    if (itemNodeInstance)
+        c->cleanup(itemNodeInstance);
+    if (!parentItem)
+        c->parentlessItems.remove(q);
+
+    window = 0;
 
-    InitializationState _dummy;
-    InitializationState *childState = state;
+    itemNodeInstance = 0;
 
-    if (c && q->isFocusScope()) {
-        _dummy.clear(q);
-        childState = &_dummy;
+    if (extra.isAllocated()) {
+        extra->opacityNode = 0;
+        extra->clipNode = 0;
+        extra->rootNode = 0;
+        extra->beforePaintNode = 0;
     }
 
-    if (!parentItem && canvas)
-        QQuickCanvasPrivate::get(canvas)->parentlessItems.insert(q);
+    groupNode = 0;
+    paintNode = 0;
 
     for (int ii = 0; ii < childItems.count(); ++ii) {
         QQuickItem *child = childItems.at(ii);
-        QQuickItemPrivate::get(child)->initCanvas(childState, c);
-    }
-
-    if (c && focus) {
-        // Fixup
-        if (state->getFocusScope(q)->scopedFocusItem()) {
-            focus = false;
-            emit q->focusChanged(false);
-        } else {
-            QQuickCanvasPrivate::get(canvas)->setFocusInScope(state->getFocusScope(q), q);
-        }
+        QQuickItemPrivate::get(child)->derefWindow();
     }
 
-    dirty(Canvas);
+    dirty(Window);
 
-    if (screenAttached)
-        screenAttached->canvasChanged(c);
-    itemChange(QQuickItem::ItemSceneChange, c);
+    if (extra.isAllocated() && extra->screenAttached)
+        extra->screenAttached->windowChanged(0);
+    itemChange(QQuickItem::ItemSceneChange, (QQuickWindow *)0);
 }
 
+
 /*!
-Returns a transform that maps points from canvas space into item space.
+Returns a transform that maps points from window space into item space.
 */
-QTransform QQuickItemPrivate::canvasToItemTransform() const
+QTransform QQuickItemPrivate::windowToItemTransform() const
 {
     // XXX todo - optimize
-    return itemToCanvasTransform().inverted();
+    return itemToWindowTransform().inverted();
 }
 
 /*!
-Returns a transform that maps points from item space into canvas space.
+Returns a transform that maps points from item space into window space.
 */
-QTransform QQuickItemPrivate::itemToCanvasTransform() const
+QTransform QQuickItemPrivate::itemToWindowTransform() const
 {
     // XXX todo
-    QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToCanvasTransform():QTransform();
+    QTransform rv = parentItem?QQuickItemPrivate::get(parentItem)->itemToWindowTransform():QTransform();
     itemToParentTransform(rv);
     return rv;
 }
@@ -2208,11 +2336,11 @@ void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
         t = m.toTransform();
     }
 
-    if (scale != 1. || rotation != 0.) {
+    if (scale() != 1. || rotation() != 0.) {
         QPointF tp = computeTransformOrigin();
         t.translate(tp.x(), tp.y());
-        t.scale(scale, scale);
-        t.rotate(rotation);
+        t.scale(scale(), scale());
+        t.rotate(rotation());
         t.translate(-tp.x(), -tp.y());
     }
 }
@@ -2273,34 +2401,53 @@ bool QQuickItem::isComponentComplete() const
 }
 
 QQuickItemPrivate::QQuickItemPrivate()
-: _anchors(0), _contents(0), baselineOffset(0), _anchorLines(0), _stateGroup(0), origin(QQuickItem::Center),
-
-  flags(0), widthValid(false), heightValid(false), componentComplete(true),
-  keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(false), focus(false), activeFocus(false), notifiedFocus(false),
-  notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
-  effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
-  inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
-  inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false),
-  staticSubtreeGeometry(false),
-  isAccessible(false),
-
-  canvas(0), parentItem(0), sortedChildItems(&childItems),
-
-  subFocusItem(0),
-
-  x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
-  z(0), scale(1), rotation(0), opacity(1),
-
-  attachedLayoutDirection(0), acceptedMouseButtons(0),
-  imHints(Qt::ImhNone),
-
-  keyHandler(0),
-
-  dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
-
-  itemNodeInstance(0), opacityNode(0), clipNode(0), rootNode(0), groupNode(0), paintNode(0)
-  , beforePaintNode(0), effectRefCount(0), hideRefCount(0)
-  , screenAttached(0), _layer(0)
+    : _anchors(0)
+    , _stateGroup(0)
+    , flags(0)
+    , widthValid(false)
+    , heightValid(false)
+    , baselineOffsetValid(false)
+    , componentComplete(true)
+    , keepMouse(false)
+    , keepTouch(false)
+    , hoverEnabled(false)
+    , smooth(true)
+    , antialiasing(false)
+    , focus(false)
+    , activeFocus(false)
+    , notifiedFocus(false)
+    , notifiedActiveFocus(false)
+    , filtersChildMouseEvents(false)
+    , explicitVisible(true)
+    , effectiveVisible(true)
+    , explicitEnable(true)
+    , effectiveEnable(true)
+    , polishScheduled(false)
+    , inheritedLayoutMirror(false)
+    , effectiveLayoutMirror(false)
+    , isMirrorImplicit(true)
+    , inheritMirrorFromParent(false)
+    , inheritMirrorFromItem(false)
+    , isAccessible(false)
+    , culled(false)
+    , dirtyAttributes(0)
+    , nextDirtyItem(0)
+    , prevDirtyItem(0)
+    , window(0)
+    , windowRefCount(0)
+    , parentItem(0)
+    , sortedChildItems(&childItems)
+    , subFocusItem(0)
+    , x(0)
+    , y(0)
+    , width(0)
+    , height(0)
+    , implicitWidth(0)
+    , implicitHeight(0)
+    , baselineOffset(0)
+    , itemNodeInstance(0)
+    , groupNode(0)
+    , paintNode(0)
 {
 }
 
@@ -2325,7 +2472,7 @@ void QQuickItemPrivate::init(QQuickItem *parent)
 
     registerAccessorProperties();
 
-    baselineOffset.invalidate();
+    baselineOffsetValid = false;
 
     if (parent) {
         q->setParentItem(parent);
@@ -2334,21 +2481,14 @@ void QQuickItemPrivate::init(QQuickItem *parent)
     }
 }
 
-void QQuickItemPrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
+void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
 {
     if (!o)
         return;
 
     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
 
-    // This test is measurably (albeit only slightly) faster than qobject_cast<>()
-    const QMetaObject *mo = o->metaObject();
-    while (mo && mo != &QQuickItem::staticMetaObject) {
-        mo = mo->d.superdata;
-    }
-
-    if (mo) {
-        QQuickItem *item = static_cast<QQuickItem *>(o);
+    if (QQuickItem *item = qmlobject_cast<QQuickItem *>(o)) {
         item->setParentItem(that);
     } else {
         if (o->inherits("QGraphicsItem"))
@@ -2393,14 +2533,14 @@ void QQuickItemPrivate::data_append(QDeclarativeListProperty<QObject> *prop, QOb
     specify it.
  */
 
-int QQuickItemPrivate::data_count(QDeclarativeListProperty<QObject> *prop)
+int QQuickItemPrivate::data_count(QQmlListProperty<QObject> *prop)
 {
     Q_UNUSED(prop);
     // XXX todo
     return 0;
 }
 
-QObject *QQuickItemPrivate::data_at(QDeclarativeListProperty<QObject> *prop, int i)
+QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *prop, int i)
 {
     Q_UNUSED(prop);
     Q_UNUSED(i);
@@ -2408,13 +2548,13 @@ QObject *QQuickItemPrivate::data_at(QDeclarativeListProperty<QObject> *prop, int
     return 0;
 }
 
-void QQuickItemPrivate::data_clear(QDeclarativeListProperty<QObject> *prop)
+void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *prop)
 {
     Q_UNUSED(prop);
     // XXX todo
 }
 
-QObject *QQuickItemPrivate::resources_at(QDeclarativeListProperty<QObject> *prop, int index)
+QObject *QQuickItemPrivate::resources_at(QQmlListProperty<QObject> *prop, int index)
 {
     const QObjectList children = prop->object->children();
     if (index < children.count())
@@ -2423,18 +2563,18 @@ QObject *QQuickItemPrivate::resources_at(QDeclarativeListProperty<QObject> *prop
         return 0;
 }
 
-void QQuickItemPrivate::resources_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
+void QQuickItemPrivate::resources_append(QQmlListProperty<QObject> *prop, QObject *o)
 {
     // XXX todo - do we really want this behavior?
     o->setParent(prop->object);
 }
 
-int QQuickItemPrivate::resources_count(QDeclarativeListProperty<QObject> *prop)
+int QQuickItemPrivate::resources_count(QQmlListProperty<QObject> *prop)
 {
     return prop->object->children().count();
 }
 
-void QQuickItemPrivate::resources_clear(QDeclarativeListProperty<QObject> *prop)
+void QQuickItemPrivate::resources_clear(QQmlListProperty<QObject> *prop)
 {
     // XXX todo - do we really want this behavior?
     const QObjectList children = prop->object->children();
@@ -2442,7 +2582,7 @@ void QQuickItemPrivate::resources_clear(QDeclarativeListProperty<QObject> *prop)
         children.at(index)->setParent(0);
 }
 
-QQuickItem *QQuickItemPrivate::children_at(QDeclarativeListProperty<QQuickItem> *prop, int index)
+QQuickItem *QQuickItemPrivate::children_at(QQmlListProperty<QQuickItem> *prop, int index)
 {
     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
     if (index >= p->childItems.count() || index < 0)
@@ -2451,7 +2591,7 @@ QQuickItem *QQuickItemPrivate::children_at(QDeclarativeListProperty<QQuickItem>
         return p->childItems.at(index);
 }
 
-void QQuickItemPrivate::children_append(QDeclarativeListProperty<QQuickItem> *prop, QQuickItem *o)
+void QQuickItemPrivate::children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *o)
 {
     if (!o)
         return;
@@ -2463,13 +2603,13 @@ void QQuickItemPrivate::children_append(QDeclarativeListProperty<QQuickItem> *pr
     o->setParentItem(that);
 }
 
-int QQuickItemPrivate::children_count(QDeclarativeListProperty<QQuickItem> *prop)
+int QQuickItemPrivate::children_count(QQmlListProperty<QQuickItem> *prop)
 {
     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
     return p->childItems.count();
 }
 
-void QQuickItemPrivate::children_clear(QDeclarativeListProperty<QQuickItem> *prop)
+void QQuickItemPrivate::children_clear(QQmlListProperty<QQuickItem> *prop)
 {
     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
@@ -2477,10 +2617,45 @@ void QQuickItemPrivate::children_clear(QDeclarativeListProperty<QQuickItem> *pro
         p->childItems.at(0)->setParentItem(0);
 }
 
-int QQuickItemPrivate::transform_count(QDeclarativeListProperty<QQuickTransform> *prop)
+void QQuickItemPrivate::visibleChildren_append(QQmlListProperty<QQuickItem>*, QQuickItem *self)
+{
+    // do nothing
+    qmlInfo(self) << "QQuickItem: visibleChildren property is readonly and cannot be assigned to.";
+}
+
+int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop)
+{
+    QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
+    int visibleCount = 0;
+    int c = p->childItems.count();
+    while (c--) {
+        if (p->childItems.at(c)->isVisible()) visibleCount++;
+    }
+
+    return visibleCount;
+}
+
+QQuickItem *QQuickItemPrivate::visibleChildren_at(QQmlListProperty<QQuickItem> *prop, int index)
+{
+    QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
+    const int childCount = p->childItems.count();
+    if (index >= childCount || index < 0)
+        return 0;
+
+    int visibleCount = -1;
+    for (int i = 0; i < childCount; i++) {
+        if (p->childItems.at(i)->isVisible()) visibleCount++;
+        if (visibleCount == index) return p->childItems.at(i);
+    }
+    return 0;
+}
+
+int QQuickItemPrivate::transform_count(QQmlListProperty<QQuickTransform> *prop)
 {
     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
-    return QQuickItemPrivate::get(that)->transforms.count();
+    QQuickItemPrivate *p = QQuickItemPrivate::get(that);
+
+    return p->transforms.count();
 }
 
 void QQuickTransform::appendToItem(QQuickItem *item)
@@ -2521,7 +2696,7 @@ void QQuickTransform::prependToItem(QQuickItem *item)
     p->dirty(QQuickItemPrivate::Transform);
 }
 
-void QQuickItemPrivate::transform_append(QDeclarativeListProperty<QQuickTransform> *prop, QQuickTransform *transform)
+void QQuickItemPrivate::transform_append(QQmlListProperty<QQuickTransform> *prop, QQuickTransform *transform)
 {
     if (!transform)
         return;
@@ -2530,7 +2705,7 @@ void QQuickItemPrivate::transform_append(QDeclarativeListProperty<QQuickTransfor
     transform->appendToItem(that);
 }
 
-QQuickTransform *QQuickItemPrivate::transform_at(QDeclarativeListProperty<QQuickTransform> *prop, int idx)
+QQuickTransform *QQuickItemPrivate::transform_at(QQmlListProperty<QQuickTransform> *prop, int idx)
 {
     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
@@ -2541,7 +2716,7 @@ QQuickTransform *QQuickItemPrivate::transform_at(QDeclarativeListProperty<QQuick
         return p->transforms.at(idx);
 }
 
-void QQuickItemPrivate::transform_clear(QDeclarativeListProperty<QQuickTransform> *prop)
+void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
 {
     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
     QQuickItemPrivate *p = QQuickItemPrivate::get(that);
@@ -2559,7 +2734,7 @@ void QQuickItemPrivate::transform_clear(QDeclarativeListProperty<QQuickTransform
 
 /*!
     \property QQuickItem::childrenRect
-    \brief The geometry of an item's children.
+    \brief Specifies the geometry of an item's children
 
     This property holds the (collective) position and size of the item's children.
 */
@@ -2591,8 +2766,8 @@ void QQuickItemPrivate::transform_clear(QDeclarativeListProperty<QQuickTransform
 
   \table
   \row
-  \o \image declarative-item_stacking1.png
-  \o Same \c z - later children above earlier children:
+  \li \image declarative-item_stacking1.png
+  \li Same \c z - later children above earlier children:
   \qml
   Item {
       Rectangle {
@@ -2606,8 +2781,8 @@ void QQuickItemPrivate::transform_clear(QDeclarativeListProperty<QQuickTransform
   }
   \endqml
   \row
-  \o \image declarative-item_stacking2.png
-  \o Higher \c z on top:
+  \li \image declarative-item_stacking2.png
+  \li Higher \c z on top:
   \qml
   Item {
       Rectangle {
@@ -2622,8 +2797,8 @@ void QQuickItemPrivate::transform_clear(QDeclarativeListProperty<QQuickTransform
   }
   \endqml
   \row
-  \o \image declarative-item_stacking3.png
-  \o Same \c z - children above parents:
+  \li \image declarative-item_stacking3.png
+  \li Same \c z - children above parents:
   \qml
   Item {
       Rectangle {
@@ -2637,8 +2812,8 @@ void QQuickItemPrivate::transform_clear(QDeclarativeListProperty<QQuickTransform
   }
   \endqml
   \row
-  \o \image declarative-item_stacking4.png
-  \o Lower \c z below:
+  \li \image declarative-item_stacking4.png
+  \li Lower \c z below:
   \qml
   Item {
       Rectangle {
@@ -2670,16 +2845,31 @@ void QQuickItemPrivate::transform_clear(QDeclarativeListProperty<QQuickTransform
     explicit property changes. In such cases it may be better to use the
     \l opacity property instead.)
 
-    Setting this property to \c false automatically causes \l focus to be set
-    to \c false, and this item will longer receive mouse and keyboard events.
-    (In contrast, setting the \l opacity to 0 does not affect the \l focus
-    property and the receiving of key events.)
+    If this property is set to \c false, the item will no longer receive mouse
+    events, but will continue to receive key events and will retain the keyboard
+    \l focus if it has been set. (In contrast, setting the \l enabled property
+    to \c false stops both mouse and keyboard events, and also removes focus
+    from the item.)
 
     \note This property's value is only affected by changes to this property or
     the parent's \c visible property. It does not change, for example, if this
     item moves off-screen, or if the \l opacity changes to 0.
 */
 
+/*!
+    \qmlproperty bool QtQuick2::Item::enabled
+
+    This property holds whether the item receives mouse and keyboard events.
+    By default this is true.
+
+    Setting this property directly affects the \c enabled value of child
+    items. When set to \c false, the \c enabled values of all child items also
+    become \c false. When set to \c true, the \c enabled values of child items
+    are returned to \c true, unless they have explicitly been set to \c false.
+
+    Setting this property to \c false automatically causes \l activeFocus to be
+    set to \c false, and this item will longer receive keyboard events.
+*/
 
 /*!
   \qmlproperty AnchorLine QtQuick2::Item::anchors.top
@@ -2702,13 +2892,15 @@ void QQuickItemPrivate::transform_clear(QDeclarativeListProperty<QQuickTransform
   \qmlproperty real QtQuick2::Item::anchors.verticalCenterOffset
   \qmlproperty real QtQuick2::Item::anchors.baselineOffset
 
-  \qmlproperty bool QtQuick2::Item::anchors.mirrored
+  \qmlproperty bool QtQuick2::Item::anchors.alignWhenCentered
 
   Anchors provide a way to position an item by specifying its
   relationship with other items.
 
   Margins apply to top, bottom, left, right, and fill anchors.
   The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
+  It will not override a specific margin that has been previously set; to clear an explicit margin
+  set it's value to \c undefined.
   Note that margins are anchor-specific and are not applied if an item does not
   use anchors.
 
@@ -2716,8 +2908,8 @@ void QQuickItemPrivate::transform_clear(QDeclarativeListProperty<QQuickTransform
 
   \table
   \row
-  \o \image declarative-anchors_example.png
-  \o Text anchored to Image, horizontally centered and vertically below, with a margin.
+  \li \image declarative-anchors_example.png
+  \li Text anchored to Image, horizontally centered and vertically below, with a margin.
   \qml
   Item {
       Image {
@@ -2734,8 +2926,8 @@ void QQuickItemPrivate::transform_clear(QDeclarativeListProperty<QQuickTransform
   }
   \endqml
   \row
-  \o \image declarative-anchors_example2.png
-  \o
+  \li \image declarative-anchors_example2.png
+  \li
   Left of Text anchored to right of Image, with a margin. The y
   property of both defaults to 0.
 
@@ -2761,7 +2953,12 @@ void QQuickItemPrivate::transform_clear(QDeclarativeListProperty<QQuickTransform
 
   To clear an anchor value, set it to \c undefined.
 
-  \c anchors.mirrored returns true it the layout has been \l {LayoutMirroring}{mirrored}.
+  \c anchors.alignWhenCentered (default true) forces centered anchors to align to a
+  whole pixel, i.e. if the item being centered has an odd width/height the item
+  will be positioned on a whole pixel rather than being placed on a half-pixel.
+  This ensures the item is painted crisply.  There are cases where this is not
+  desirable, for example when rotating the item jitters may be apparent as the
+  center is rounded.
 
   \note You can only anchor an item to siblings or a parent.
 
@@ -2770,7 +2967,7 @@ void QQuickItemPrivate::transform_clear(QDeclarativeListProperty<QQuickTransform
 
 /*!
   \property QQuickItem::baselineOffset
-  \brief The position of the item's baseline in local coordinates.
+  \brief Speciifies the position of the item's baseline in local coordinates
 
   The baseline of a \l Text item is the imaginary line on which the text
   sits. Controls containing text usually set their baseline to the
@@ -2789,14 +2986,6 @@ QQuickAnchors *QQuickItemPrivate::anchors() const
     return _anchors;
 }
 
-QQuickItemPrivate::AnchorLines *QQuickItemPrivate::anchorLines() const
-{
-    Q_Q(const QQuickItem);
-    if (!_anchorLines) _anchorLines =
-        new AnchorLines(const_cast<QQuickItem *>(q));
-    return _anchorLines;
-}
-
 void QQuickItemPrivate::siblingOrderChanged()
 {
     Q_Q(QQuickItem);
@@ -2808,9 +2997,9 @@ void QQuickItemPrivate::siblingOrderChanged()
     }
 }
 
-QDeclarativeListProperty<QObject> QQuickItemPrivate::data()
+QQmlListProperty<QObject> QQuickItemPrivate::data()
 {
-    return QDeclarativeListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
+    return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::data_append,
                                              QQuickItemPrivate::data_count,
                                              QQuickItemPrivate::data_at,
                                              QQuickItemPrivate::data_clear);
@@ -2819,12 +3008,12 @@ QDeclarativeListProperty<QObject> QQuickItemPrivate::data()
 QRectF QQuickItem::childrenRect()
 {
     Q_D(QQuickItem);
-    if (!d->_contents) {
-        d->_contents = new QQuickContents(this);
+    if (!d->extra.isAllocated() || !d->extra->contents) {
+        d->extra.value().contents = new QQuickContents(this);
         if (d->componentComplete)
-            d->_contents->complete();
+            d->extra->contents->complete();
     }
-    return d->_contents->rectF();
+    return d->extra->contents->rectF();
 }
 
 QList<QQuickItem *> QQuickItem::childItems() const
@@ -2853,6 +3042,8 @@ void QQuickItem::setClip(bool c)
   This function is called to handle this item's changes in
   geometry from \a oldGeometry to \a newGeometry. If the two
   geometries are the same, it doesn't do anything.
+
+  Derived classes must call the base class method within their implementation.
  */
 void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
 {
@@ -2891,16 +3082,45 @@ void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeo
 }
 
 /*!
-    Called by the rendering thread when it is time to sync the state of the QML objects with the
-    scene graph objects. The function should return the root of the scene graph subtree for
-    this item. \a oldNode is the node that was returned the last time the function was called.
+    Called by the rendering thread, as a result of
+    QQuickItem::update(), when it is time to sync the state of the QML
+    objects with the scene graph objects.
+
+    The function should return the root of the scene graph subtree for
+    this item. Most implementations will return a single
+    QSGGeometryNode containing the visual representation of this item.
+    \a oldNode is the node that was returned the last time the
+    function was called.
+
+    \code
+    QSGNode *MyItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
+    {
+        QSGSimpleRectNode *n = static_cast<QSGSimpleRectNode *>(node);
+        if (!n) {
+            n = new QSGSimpleRectNode();
+            n->setColor(Qt::red);
+        }
+        n->setRect(boundingRect());
+        return n;
+    }
+    \endcode
 
     The main thread is blocked while this function is executed so it is safe to read
     values from the QQuickItem instance and other objects in the main thread.
 
-    \warning This is the only function in which it is allowed to make use of scene graph
-    objects from the main thread. Use of scene graph objects outside this function will
-    result in race conditions and potential crashes.
+    If no call to QQuickItem::updatePaintNode() result in actual scene graph
+    changes, like QSGNode::markDirty() or adding and removing nodes, then
+    the underlying implementation may decide to not render the scene again as
+    the visual outcome is identical.
+
+    \warning It is crucial that OpenGL operations and interaction with
+    the scene graph happens exclusively on the rendering thread,
+    primarily during the QQuickItem::updatePaintNode() call. The best
+    rule of thumb is to only use classes with the "QSG" prefix inside
+    the QQuickItem::updatePaintNode() function.
+
+    \sa QSGMaterial, QSGSimpleMaterial, QSGGeometryNode, QSGGeometry,
+    QSGFlatColorMaterial, QSGTextureMaterial, QSGNode::markDirty()
  */
 
 QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
@@ -2909,6 +3129,23 @@ QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
     return 0;
 }
 
+/*!
+    This function is called when the item's scene graph resources are no longer needed.
+    It allows items to free its resources, for instance textures, that are not owned by scene graph
+    nodes. Note that scene graph nodes are managed by QQuickWindow and should not be deleted by
+    this function. Scene graph resources are no longer needed when the parent is set to null and
+    the item is not used by any \l ShaderEffect or \l ShaderEffectSource.
+
+    This function is called from the main thread. Therefore, resources used by the scene graph
+    should not be deleted directly, but by calling \l QObject::deleteLater().
+
+    \note The item destructor still needs to free its scene graph resources if not already done.
+ */
+
+void QQuickItem::releaseResources()
+{
+}
+
 QSGTransformNode *QQuickItemPrivate::createTransformNode()
 {
     return new QSGTransformNode;
@@ -2918,8 +3155,9 @@ void QQuickItem::updatePolish()
 {
 }
 
-void QQuickItem::sendAccessibilityUpdate()
+void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
 {
+    changeListeners.append(ChangeListener(listener, types));
 }
 
 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
@@ -2938,7 +3176,8 @@ void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListen
         changeListeners.append(change);
 }
 
-void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
+void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
+                                                             GeometryChangeTypes types)
 {
     ChangeListener change(listener, types);
     if (types == NoChange) {
@@ -2967,7 +3206,10 @@ void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
 
 void QQuickItem::focusInEvent(QFocusEvent *)
 {
-    QAccessible::updateAccessibility(this, 0, QAccessible::Focus);
+#ifndef QT_NO_ACCESSIBILITY
+    QAccessibleEvent ev(this, QAccessible::Focus);
+    QAccessible::updateAccessibility(&ev);
+#endif
 }
 
 void QQuickItem::focusOutEvent(QFocusEvent *)
@@ -2989,9 +3231,8 @@ void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
     event->ignore();
 }
 
-void QQuickItem::mouseDoubleClickEvent(QMouseEvent *event)
+void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
 {
-    mousePressEvent(event);
 }
 
 void QQuickItem::mouseUngrabEvent()
@@ -3029,6 +3270,7 @@ void QQuickItem::hoverLeaveEvent(QHoverEvent *event)
     Q_UNUSED(event);
 }
 
+#ifndef QT_NO_DRAGANDDROP
 void QQuickItem::dragEnterEvent(QDragEnterEvent *event)
 {
     Q_UNUSED(event);
@@ -3050,6 +3292,7 @@ void QQuickItem::dropEvent(QDropEvent *event)
 {
     Q_UNUSED(event);
 }
+#endif // QT_NO_DRAGANDDROP
 
 bool QQuickItem::childMouseEventFilter(QQuickItem *, QEvent *)
 {
@@ -3063,25 +3306,6 @@ void QQuickItem::windowDeactivateEvent()
     }
 }
 
-Qt::InputMethodHints QQuickItem::inputMethodHints() const
-{
-    Q_D(const QQuickItem);
-    return d->imHints;
-}
-
-void QQuickItem::setInputMethodHints(Qt::InputMethodHints hints)
-{
-    Q_D(QQuickItem);
-    d->imHints = hints;
-
-    if (!d->canvas || d->canvas->activeFocusItem() != this)
-        return;
-
-    QInputPanel *p = qApp->inputPanel();
-    if (p->inputItem() == this)
-        qApp->inputPanel()->update(Qt::ImHints);
-}
-
 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
 {
     Q_D(const QQuickItem);
@@ -3092,8 +3316,6 @@ QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
         v = (bool)(flags() & ItemAcceptsInputMethod);
         break;
     case Qt::ImHints:
-        v = (int)inputMethodHints();
-        break;
     case Qt::ImCursorRectangle:
     case Qt::ImFont:
     case Qt::ImCursorPosition:
@@ -3102,8 +3324,8 @@ QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
     case Qt::ImMaximumTextLength:
     case Qt::ImAnchorPosition:
     case Qt::ImPreferredLanguage:
-        if (d->keyHandler)
-            v = d->keyHandler->inputMethodQuery(query);
+        if (d->extra.isAllocated() && d->extra->keyHandler)
+            v = d->extra->keyHandler->inputMethodQuery(query);
     default:
         break;
     }
@@ -3113,46 +3335,54 @@ QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
 
 QQuickAnchorLine QQuickItemPrivate::left() const
 {
-    return anchorLines()->left;
+    Q_Q(const QQuickItem);
+    return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Left);
 }
 
 QQuickAnchorLine QQuickItemPrivate::right() const
 {
-    return anchorLines()->right;
+    Q_Q(const QQuickItem);
+    return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Right);
 }
 
 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
 {
-    return anchorLines()->hCenter;
+    Q_Q(const QQuickItem);
+    return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::HCenter);
 }
 
 QQuickAnchorLine QQuickItemPrivate::top() const
 {
-    return anchorLines()->top;
+    Q_Q(const QQuickItem);
+    return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Top);
 }
 
 QQuickAnchorLine QQuickItemPrivate::bottom() const
 {
-    return anchorLines()->bottom;
+    Q_Q(const QQuickItem);
+    return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Bottom);
 }
 
 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
 {
-    return anchorLines()->vCenter;
+    Q_Q(const QQuickItem);
+    return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::VCenter);
 }
 
 QQuickAnchorLine QQuickItemPrivate::baseline() const
 {
-    return anchorLines()->baseline;
+    Q_Q(const QQuickItem);
+    return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Baseline);
 }
 
 qreal QQuickItem::baselineOffset() const
 {
     Q_D(const QQuickItem);
-    if (!d->baselineOffset.isValid()) {
-        return 0.0;
-    } else
+    if (d->baselineOffsetValid) {
         return d->baselineOffset;
+    } else {
+        return 0.0;
+    }
 }
 
 void QQuickItem::setBaselineOffset(qreal offset)
@@ -3162,6 +3392,7 @@ void QQuickItem::setBaselineOffset(qreal offset)
         return;
 
     d->baselineOffset = offset;
+    d->baselineOffsetValid = true;
 
     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
         const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
@@ -3171,9 +3402,23 @@ void QQuickItem::setBaselineOffset(qreal offset)
                 anchor->updateVerticalAnchors();
         }
     }
+
+    if (d->_anchors && (d->_anchors->usedAnchors() & QQuickAnchors::BaselineAnchor))
+        QQuickAnchorsPrivate::get(d->_anchors)->updateVerticalAnchors();
+
     emit baselineOffsetChanged(offset);
 }
 
+
+/*!
+ * Schedules a call to updatePaintNode() for this item.
+ *
+ * The call to QQuickItem::updatePaintNode() will always happen if the
+ * item is showing in a QQuickWindow.
+ *
+ * Only items which specifies QQuickItem::ItemHasContents are allowed
+ * to call QQuickItem::update().
+ */
 void QQuickItem::update()
 {
     Q_D(QQuickItem);
@@ -3186,16 +3431,27 @@ void QQuickItem::polish()
     Q_D(QQuickItem);
     if (!d->polishScheduled) {
         d->polishScheduled = true;
-        if (d->canvas) {
-            QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(d->canvas);
+        if (d->window) {
+            QQuickWindowPrivate *p = QQuickWindowPrivate::get(d->window);
             bool maybeupdate = p->itemsToPolish.isEmpty();
             p->itemsToPolish.insert(this);
-            if (maybeupdate) d->canvas->maybeUpdate();
+            if (maybeupdate) d->window->maybeUpdate();
         }
     }
 }
 
-void QQuickItem::mapFromItem(QDeclarativeV8Function *args) const
+/*!
+    \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
+    \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y, real width, real height)
+
+    Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in \a
+    item's coordinate system, to this item's coordinate system, and returns an object with \c x and
+    \c y (and optionally \c width and \c height) properties matching the mapped coordinate.
+
+    If \a item is a \c null value, this maps the point or rect from the coordinate system of
+    the root QML view.
+*/
+void QQuickItem::mapFromItem(QQmlV8Function *args) const
 {
     if (args->Length() != 0) {
         v8::Local<v8::Value> item = (*args)[0];
@@ -3217,10 +3473,22 @@ void QQuickItem::mapFromItem(QDeclarativeV8Function *args) const
         qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
         qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
 
-        QPointF p = mapFromItem(itemObj, QPointF(x, y));
+        if (args->Length() > 3) {
+            qreal w = (*args)[3]->NumberValue();
+            qreal h = (args->Length() > 4)?(*args)[4]->NumberValue():0;
+
+            QRectF r = mapRectFromItem(itemObj, QRectF(x, y, w, h));
+
+            rv->Set(v8::String::New("x"), v8::Number::New(r.x()));
+            rv->Set(v8::String::New("y"), v8::Number::New(r.y()));
+            rv->Set(v8::String::New("width"), v8::Number::New(r.width()));
+            rv->Set(v8::String::New("height"), v8::Number::New(r.height()));
+        } else {
+            QPointF p = mapFromItem(itemObj, QPointF(x, y));
 
-        rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
-        rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
+            rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
+            rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
+        }
     }
 }
 
@@ -3232,13 +3500,24 @@ QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
     // invalid cases
     if (ok) *ok = true;
 
-    QTransform t = d->itemToCanvasTransform();
-    if (other) t *= QQuickItemPrivate::get(other)->canvasToItemTransform();
+    QTransform t = d->itemToWindowTransform();
+    if (other) t *= QQuickItemPrivate::get(other)->windowToItemTransform();
 
     return t;
 }
 
-void QQuickItem::mapToItem(QDeclarativeV8Function *args) const
+/*!
+    \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
+    \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y, real width, real height)
+
+    Maps the point (\a x, \a y) or rect (\a x, \a y, \a width, \a height), which is in this
+    item's coordinate system, to \a item's coordinate system, and returns an object with \c x and
+    \c y (and optionally \c width and \c height) properties matching the mapped coordinate.
+
+    If \a item is a \c null value, this maps the point or rect to the coordinate system of the
+    root QML view.
+*/
+void QQuickItem::mapToItem(QQmlV8Function *args) const
 {
     if (args->Length() != 0) {
         v8::Local<v8::Value> item = (*args)[0];
@@ -3260,10 +3539,22 @@ void QQuickItem::mapToItem(QDeclarativeV8Function *args) const
         qreal x = (args->Length() > 1)?(*args)[1]->NumberValue():0;
         qreal y = (args->Length() > 2)?(*args)[2]->NumberValue():0;
 
-        QPointF p = mapToItem(itemObj, QPointF(x, y));
+        if (args->Length() > 3) {
+            qreal w = (*args)[3]->NumberValue();
+            qreal h = (args->Length() > 4)?(*args)[4]->NumberValue():0;
+
+            QRectF r = mapRectToItem(itemObj, QRectF(x, y, w, h));
+
+            rv->Set(v8::String::New("x"), v8::Number::New(r.x()));
+            rv->Set(v8::String::New("y"), v8::Number::New(r.y()));
+            rv->Set(v8::String::New("width"), v8::Number::New(r.width()));
+            rv->Set(v8::String::New("height"), v8::Number::New(r.height()));
+        } else {
+            QPointF p = mapToItem(itemObj, QPointF(x, y));
 
-        rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
-        rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
+            rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
+            rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
+        }
     }
 }
 
@@ -3294,29 +3585,43 @@ QQuickItem *QQuickItem::childAt(qreal x, qreal y) const
     return 0;
 }
 
-QDeclarativeListProperty<QObject> QQuickItemPrivate::resources()
+QQmlListProperty<QObject> QQuickItemPrivate::resources()
 {
-    return QDeclarativeListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
+    return QQmlListProperty<QObject>(q_func(), 0, QQuickItemPrivate::resources_append,
                                              QQuickItemPrivate::resources_count,
                                              QQuickItemPrivate::resources_at,
                                              QQuickItemPrivate::resources_clear);
 }
 
-QDeclarativeListProperty<QQuickItem> QQuickItemPrivate::children()
+QQmlListProperty<QQuickItem> QQuickItemPrivate::children()
 {
-    return QDeclarativeListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
+    return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::children_append,
                                              QQuickItemPrivate::children_count,
                                              QQuickItemPrivate::children_at,
                                              QQuickItemPrivate::children_clear);
 
 }
 
-QDeclarativeListProperty<QDeclarativeState> QQuickItemPrivate::states()
+/*!
+  \qmlproperty real QtQuick2::Item::visibleChildren
+  This read-only property lists all of the item's children that are currently visible.
+  Note that a child's visibility may have changed explicitly, or because the visibility
+  of this (it's parent) item or another grandparent changed.
+*/
+QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren()
+{
+    return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append,
+                                             QQuickItemPrivate::visibleChildren_count,
+                                             QQuickItemPrivate::visibleChildren_at);
+
+}
+
+QQmlListProperty<QQuickState> QQuickItemPrivate::states()
 {
     return _states()->statesProperty();
 }
 
-QDeclarativeListProperty<QDeclarativeTransition> QQuickItemPrivate::transitions()
+QQmlListProperty<QQuickTransition> QQuickItemPrivate::transitions()
 {
     return _states()->transitionsProperty();
 }
@@ -3346,14 +3651,19 @@ void QQuickItem::setState(const QString &state)
     d->setState(state);
 }
 
-QDeclarativeListProperty<QQuickTransform> QQuickItem::transform()
+QQmlListProperty<QQuickTransform> QQuickItem::transform()
 {
-    return QDeclarativeListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
+    return QQmlListProperty<QQuickTransform>(this, 0, QQuickItemPrivate::transform_append,
                                                      QQuickItemPrivate::transform_count,
                                                      QQuickItemPrivate::transform_at,
                                                      QQuickItemPrivate::transform_clear);
 }
 
+/*!
+  \reimp
+  Derived classes should call the base class method before adding their own action to
+  perform at classBegin.
+*/
 void QQuickItem::classBegin()
 {
     Q_D(QQuickItem);
@@ -3362,10 +3672,15 @@ void QQuickItem::classBegin()
         d->_stateGroup->classBegin();
     if (d->_anchors)
         d->_anchors->classBegin();
-    if (d->_layer)
-        d->_layer->classBegin();
+    if (d->extra.isAllocated() && d->extra->layer)
+        d->extra->layer->classBegin();
 }
 
+/*!
+  \reimp
+  Derived classes should call the base class method before adding their own actions to
+  perform at componentComplete.
+*/
 void QQuickItem::componentComplete()
 {
     Q_D(QQuickItem);
@@ -3377,50 +3692,38 @@ void QQuickItem::componentComplete()
         QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
     }
 
-    if (d->_layer)
-        d->_layer->componentComplete();
+    if (d->extra.isAllocated() && d->extra->layer)
+        d->extra->layer->componentComplete();
+
+    if (d->extra.isAllocated() && d->extra->keyHandler)
+        d->extra->keyHandler->componentComplete();
+
+    if (d->extra.isAllocated() && d->extra->contents)
+        d->extra->contents->complete();
 
-    if (d->keyHandler)
-        d->keyHandler->componentComplete();
-    if (d->_contents)
-        d->_contents->complete();
+    if (d->window && d->dirtyAttributes) {
+        d->addToDirtyList();
+        QQuickWindowPrivate::get(d->window)->dirtyItem(this);
+    }
 }
 
-QDeclarativeStateGroup *QQuickItemPrivate::_states()
+QQuickStateGroup *QQuickItemPrivate::_states()
 {
     Q_Q(QQuickItem);
     if (!_stateGroup) {
-        _stateGroup = new QDeclarativeStateGroup;
+        _stateGroup = new QQuickStateGroup;
         if (!componentComplete)
             _stateGroup->classBegin();
-        FAST_CONNECT(_stateGroup, SIGNAL(stateChanged(QString)),
-                     q, SIGNAL(stateChanged(QString)))
+        qmlobject_connect(_stateGroup, QQuickStateGroup, SIGNAL(stateChanged(QString)),
+                          q, QQuickItem, SIGNAL(stateChanged(QString)))
     }
 
     return _stateGroup;
 }
 
-QQuickItemPrivate::AnchorLines::AnchorLines(QQuickItem *q)
-{
-    left.item = q;
-    left.anchorLine = QQuickAnchorLine::Left;
-    right.item = q;
-    right.anchorLine = QQuickAnchorLine::Right;
-    hCenter.item = q;
-    hCenter.anchorLine = QQuickAnchorLine::HCenter;
-    top.item = q;
-    top.anchorLine = QQuickAnchorLine::Top;
-    bottom.item = q;
-    bottom.anchorLine = QQuickAnchorLine::Bottom;
-    vCenter.item = q;
-    vCenter.anchorLine = QQuickAnchorLine::VCenter;
-    baseline.item = q;
-    baseline.anchorLine = QQuickAnchorLine::Baseline;
-}
-
 QPointF QQuickItemPrivate::computeTransformOrigin() const
 {
-    switch (origin) {
+    switch (origin()) {
     default:
     case QQuickItem::TopLeft:
         return QPointF(0, 0);
@@ -3445,8 +3748,8 @@ QPointF QQuickItemPrivate::computeTransformOrigin() const
 
 void QQuickItemPrivate::transformChanged()
 {
-    if (_layer)
-        _layer->updateMatrix();
+    if (extra.isAllocated() && extra->layer)
+        extra->layer->updateMatrix();
 }
 
 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
@@ -3454,11 +3757,11 @@ void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
     Q_Q(QQuickItem);
 
     Q_ASSERT(e->isAccepted());
-    if (keyHandler) {
+    if (extra.isAllocated() && extra->keyHandler) {
         if (e->type() == QEvent::KeyPress)
-            keyHandler->keyPressed(e, false);
+            extra->keyHandler->keyPressed(e, false);
         else
-            keyHandler->keyReleased(e, false);
+            extra->keyHandler->keyReleased(e, false);
 
         if (e->isAccepted())
             return;
@@ -3474,13 +3777,13 @@ void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
     if (e->isAccepted())
         return;
 
-    if (keyHandler) {
+    if (extra.isAllocated() && extra->keyHandler) {
         e->accept();
 
         if (e->type() == QEvent::KeyPress)
-            keyHandler->keyPressed(e, true);
+            extra->keyHandler->keyPressed(e, true);
         else
-            keyHandler->keyReleased(e, true);
+            extra->keyHandler->keyReleased(e, true);
     }
 }
 
@@ -3489,8 +3792,8 @@ void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
     Q_Q(QQuickItem);
 
     Q_ASSERT(e->isAccepted());
-    if (keyHandler) {
-        keyHandler->inputMethodEvent(e, false);
+    if (extra.isAllocated() && extra->keyHandler) {
+        extra->keyHandler->inputMethodEvent(e, false);
 
         if (e->isAccepted())
             return;
@@ -3503,10 +3806,10 @@ void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
     if (e->isAccepted())
         return;
 
-    if (keyHandler) {
+    if (extra.isAllocated() && extra->keyHandler) {
         e->accept();
 
-        keyHandler->inputMethodEvent(e, true);
+        extra->keyHandler->inputMethodEvent(e, true);
     }
 }
 
@@ -3575,6 +3878,7 @@ void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
     }
 }
 
+#ifndef QT_NO_DRAGANDDROP
 void QQuickItemPrivate::deliverDragEvent(QEvent *e)
 {
     Q_Q(QQuickItem);
@@ -3595,6 +3899,7 @@ void QQuickItemPrivate::deliverDragEvent(QEvent *e)
         break;
     }
 }
+#endif // QT_NO_DRAGANDDROP
 
 void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
 {
@@ -3608,67 +3913,74 @@ void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
 void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
 {
     if (hasActiveFocus())
-        qApp->inputPanel()->update(queries);
+        qApp->inputMethod()->update(queries);
 }
 
 /*! \internal */
 // XXX todo - do we want/need this anymore?
-// Note that it's now used for varying clip rect
 QRectF QQuickItem::boundingRect() const
 {
     Q_D(const QQuickItem);
     return QRectF(0, 0, d->width, d->height);
 }
 
+/*! \internal */
+QRectF QQuickItem::clipRect() const
+{
+    Q_D(const QQuickItem);
+    return QRectF(0, 0, d->width, d->height);
+}
+
+
 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
 {
     Q_D(const QQuickItem);
-    return d->origin;
+    return d->origin();
 }
 
 void QQuickItem::setTransformOrigin(TransformOrigin origin)
 {
     Q_D(QQuickItem);
-    if (origin == d->origin)
+    if (origin == d->origin())
         return;
 
-    d->origin = origin;
+    d->extra.value().origin = origin;
     d->dirty(QQuickItemPrivate::TransformOrigin);
 
-    emit transformOriginChanged(d->origin);
+    emit transformOriginChanged(d->origin());
 }
 
 QPointF QQuickItem::transformOriginPoint() const
 {
     Q_D(const QQuickItem);
-    if (!d->transformOriginPoint.isNull())
-        return d->transformOriginPoint;
+    if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
+        return d->extra->userTransformOriginPoint;
     return d->computeTransformOrigin();
 }
 
 void QQuickItem::setTransformOriginPoint(const QPointF &point)
 {
     Q_D(QQuickItem);
-    if (d->transformOriginPoint == point)
+    if (d->extra.value().userTransformOriginPoint == point)
         return;
 
-    d->transformOriginPoint = point;
+    d->extra->userTransformOriginPoint = point;
     d->dirty(QQuickItemPrivate::TransformOrigin);
 }
 
 qreal QQuickItem::z() const
 {
     Q_D(const QQuickItem);
-    return d->z;
+    return d->z();
 }
 
 void QQuickItem::setZ(qreal v)
 {
     Q_D(QQuickItem);
-    if (d->z == v)
+    if (d->z() == v)
         return;
 
-    d->z = v;
+    d->extra.value().z = v;
 
     d->dirty(QQuickItemPrivate::ZValue);
     if (d->parentItem) {
@@ -3678,8 +3990,8 @@ void QQuickItem::setZ(qreal v)
 
     emit zChanged();
 
-    if (d->_layer)
-        d->_layer->updateZ();
+    if (d->extra.isAllocated() && d->extra->layer)
+        d->extra->layer->updateZ();
 }
 
 
@@ -3692,8 +4004,8 @@ void QQuickItem::setZ(qreal v)
 
   \table
   \row
-  \o \image declarative-rotation.png
-  \o
+  \li \image declarative-rotation.png
+  \li
   \qml
   Rectangle {
       color: "blue"
@@ -3726,8 +4038,8 @@ void QQuickItem::setZ(qreal v)
 
   \table
   \row
-  \o \image declarative-scale.png
-  \o
+  \li \image declarative-scale.png
+  \li
   \qml
   Rectangle {
       color: "blue"
@@ -3763,8 +4075,8 @@ void QQuickItem::setZ(qreal v)
 
   \table
   \row
-  \o \image declarative-item_opacity1.png
-  \o
+  \li \image declarative-item_opacity1.png
+  \li
   \qml
     Item {
         Rectangle {
@@ -3778,8 +4090,8 @@ void QQuickItem::setZ(qreal v)
     }
   \endqml
   \row
-  \o \image declarative-item_opacity2.png
-  \o
+  \li \image declarative-item_opacity2.png
+  \li
   \qml
     Item {
         Rectangle {
@@ -3795,11 +4107,10 @@ void QQuickItem::setZ(qreal v)
   \endqml
   \endtable
 
-  If an item's opacity is set to 0, the item will no longer receive mouse
-  events, but will continue to receive key events and will retain the keyboard
-  \l focus if it has been set. (In contrast, setting the \l visible property
-  to \c false stops both mouse and keyboard events, and also removes focus
-  from the item.)
+  Changing an items opacity will not affect delivery of input events.  (In contrast
+  setting \l visible property to \c false stops mouse events, and setting the
+  \l enabled property to \c false stops mouse and keyboard events, and also removes
+  active focus from the item.)
 */
 
 /*!
@@ -3812,16 +4123,16 @@ void QQuickItem::setZ(qreal v)
 qreal QQuickItem::rotation() const
 {
     Q_D(const QQuickItem);
-    return d->rotation;
+    return d->rotation();
 }
 
 void QQuickItem::setRotation(qreal r)
 {
     Q_D(QQuickItem);
-    if (d->rotation == r)
+    if (d->rotation() == r)
         return;
 
-    d->rotation = r;
+    d->extra.value().rotation = r;
 
     d->dirty(QQuickItemPrivate::BasicTransform);
 
@@ -3833,16 +4144,16 @@ void QQuickItem::setRotation(qreal r)
 qreal QQuickItem::scale() const
 {
     Q_D(const QQuickItem);
-    return d->scale;
+    return d->scale();
 }
 
 void QQuickItem::setScale(qreal s)
 {
     Q_D(QQuickItem);
-    if (d->scale == s)
+    if (d->scale() == s)
         return;
 
-    d->scale = s;
+    d->extra.value().scale = s;
 
     d->dirty(QQuickItemPrivate::BasicTransform);
 
@@ -3852,16 +4163,16 @@ void QQuickItem::setScale(qreal s)
 qreal QQuickItem::opacity() const
 {
     Q_D(const QQuickItem);
-    return d->opacity;
+    return d->opacity();
 }
 
 void QQuickItem::setOpacity(qreal o)
 {
     Q_D(QQuickItem);
-    if (d->opacity == o)
+    if (d->opacity() == o)
         return;
 
-    d->opacity = o;
+    d->extra.value().opacity = o;
 
     d->dirty(QQuickItemPrivate::OpacityValue);
 
@@ -3883,8 +4194,12 @@ void QQuickItem::setVisible(bool v)
         return;
 
     d->explicitVisible = v;
+    if (!v)
+        d->dirty(QQuickItemPrivate::Visible);
 
-    d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
+    const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
+    if (childVisibilityChanged && d->parentItem)
+        emit d->parentItem->visibleChildrenChanged();   // signal the parent, not this!
 }
 
 bool QQuickItem::isEnabled() const
@@ -3916,43 +4231,46 @@ bool QQuickItemPrivate::calcEffectiveVisible() const
     return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
 }
 
-void QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
+bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
 {
     Q_Q(QQuickItem);
 
     if (newEffectiveVisible && !explicitVisible) {
         // This item locally overrides visibility
-        return;
+        return false;   // effective visibility didn't change
     }
 
     if (newEffectiveVisible == effectiveVisible) {
         // No change necessary
-        return;
+        return false;   // effective visibility didn't change
     }
 
     effectiveVisible = newEffectiveVisible;
     dirty(Visible);
     if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
 
-    if (canvas) {
-        QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
-        if (canvasPriv->mouseGrabberItem == q)
+    if (window) {
+        QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window);
+        if (windowPriv->mouseGrabberItem == q)
             q->ungrabMouse();
     }
 
+    bool childVisibilityChanged = false;
     for (int ii = 0; ii < childItems.count(); ++ii)
-        QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
+        childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
 
-    for (int ii = 0; ii < changeListeners.count(); ++ii) {
-        const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
-        if (change.types & QQuickItemPrivate::Visibility)
-            change.listener->itemVisibilityChanged(q);
+    itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible);
+#ifndef QT_NO_ACCESSIBILITY
+    if (isAccessible) {
+        QAccessibleEvent ev(q, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide);
+        QAccessible::updateAccessibility(&ev);
     }
-
-    if (isAccessible)
-        QAccessible::updateAccessibility(q, 0, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide );
-
+#endif
     emit q->visibleChanged();
+    if (childVisibilityChanged)
+        emit q->visibleChildrenChanged();
+
+    return true;    // effective visibility DID change
 }
 
 bool QQuickItemPrivate::calcEffectiveEnable() const
@@ -3979,24 +4297,24 @@ void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffec
 
     effectiveEnable = newEffectiveEnable;
 
-    if (canvas) {
-        QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
-        if (canvasPriv->mouseGrabberItem == q)
+    if (window) {
+        QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window);
+        if (windowPriv->mouseGrabberItem == q)
             q->ungrabMouse();
         if (scope && !effectiveEnable && activeFocus) {
-            canvasPriv->clearFocusInScope(
-                    scope, q,  QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
+            windowPriv->clearFocusInScope(
+                    scope, q,  QQuickWindowPrivate::DontChangeFocusProperty | QQuickWindowPrivate::DontChangeSubFocusItem);
         }
     }
 
     for (int ii = 0; ii < childItems.count(); ++ii) {
         QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
-                flags & QQuickItem::ItemIsFocusScope ? q : scope, newEffectiveEnable);
+                (flags & QQuickItem::ItemIsFocusScope) && scope ? q : scope, newEffectiveEnable);
     }
 
-    if (canvas && scope && effectiveEnable && focus) {
-        QQuickCanvasPrivate::get(canvas)->setFocusInScope(
-                scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
+    if (window && scope && effectiveEnable && focus) {
+        QQuickWindowPrivate::get(window)->setFocusInScope(
+                scope, q, QQuickWindowPrivate::DontChangeFocusProperty | QQuickWindowPrivate::DontChangeSubFocusItem);
     }
 
     emit q->enabledChanged();
@@ -4026,11 +4344,11 @@ QString QQuickItemPrivate::dirtyToString() const
     DIRTY_TO_STRING(ChildrenStackingChanged);
     DIRTY_TO_STRING(ParentChanged);
     DIRTY_TO_STRING(Clip);
-    DIRTY_TO_STRING(Canvas);
+    DIRTY_TO_STRING(Window);
     DIRTY_TO_STRING(EffectReference);
     DIRTY_TO_STRING(Visible);
     DIRTY_TO_STRING(HideReference);
-    DIRTY_TO_STRING(PerformanceHints);
+    DIRTY_TO_STRING(Antialiasing);
 
     return rv;
 }
@@ -4041,11 +4359,11 @@ void QQuickItemPrivate::dirty(DirtyType type)
     if (type & (TransformOrigin | Transform | BasicTransform | Position | Size))
         transformChanged();
 
-    if (!(dirtyAttributes & type) || (canvas && !prevDirtyItem)) {
+    if (!(dirtyAttributes & type) || (window && !prevDirtyItem)) {
         dirtyAttributes |= type;
-        if (canvas) {
+        if (window && componentComplete) {
             addToDirtyList();
-            QQuickCanvasPrivate::get(canvas)->dirtyItem(q);
+            QQuickWindowPrivate::get(window)->dirtyItem(q);
         }
     }
 }
@@ -4054,11 +4372,11 @@ void QQuickItemPrivate::addToDirtyList()
 {
     Q_Q(QQuickItem);
 
-    Q_ASSERT(canvas);
+    Q_ASSERT(window);
     if (!prevDirtyItem) {
         Q_ASSERT(!nextDirtyItem);
 
-        QQuickCanvasPrivate *p = QQuickCanvasPrivate::get(canvas);
+        QQuickWindowPrivate *p = QQuickWindowPrivate::get(window);
         nextDirtyItem = p->dirtyItemList;
         if (nextDirtyItem) QQuickItemPrivate::get(nextDirtyItem)->prevDirtyItem = &nextDirtyItem;
         prevDirtyItem = &p->dirtyItemList;
@@ -4082,31 +4400,41 @@ void QQuickItemPrivate::removeFromDirtyList()
 
 void QQuickItemPrivate::refFromEffectItem(bool hide)
 {
-    ++effectRefCount;
-    if (1 == effectRefCount) {
+    ++extra.value().effectRefCount;
+    if (1 == extra->effectRefCount) {
         dirty(EffectReference);
         if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
     }
     if (hide) {
-        if (++hideRefCount == 1)
+        if (++extra->hideRefCount == 1)
             dirty(HideReference);
     }
 }
 
 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
 {
-    Q_ASSERT(effectRefCount);
-    --effectRefCount;
-    if (0 == effectRefCount) {
+    Q_ASSERT(extra->effectRefCount);
+    --extra->effectRefCount;
+    if (0 == extra->effectRefCount) {
         dirty(EffectReference);
         if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
     }
     if (unhide) {
-        if (--hideRefCount == 0)
+        if (--extra->hideRefCount == 0)
             dirty(HideReference);
     }
 }
 
+void QQuickItemPrivate::setCulled(bool cull)
+{
+    if (cull == culled)
+        return;
+
+    culled = cull;
+    if ((cull && ++extra->hideRefCount == 1) || (!cull && --extra->hideRefCount == 0))
+        dirty(HideReference);
+}
+
 void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
 {
     Q_Q(QQuickItem);
@@ -4176,20 +4504,22 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt
 
 /*!
     \property QQuickItem::smooth
-    \brief whether the item is smoothly transformed.
+    \brief Specifies whether the item is smoothed or not
 
-    This property is provided purely for the purpose of optimization. Turning
-    smooth transforms off is faster, but looks worse; turning smooth
-    transformations on is slower, but looks better.
+    Primarily used in image based items to decide if the item should use smooth
+    sampling or not. Smooth sampling is performed using linear interpolation, while
+    non-smooth is performed using nearest neighbor.
 
-    By default smooth transformations are off.
+    In Qt Quick 2.0, this property has minimal impact on performance.
+
+    By default is true.
 */
 
 /*!
-    Returns true if the item should be drawn with antialiasing and
+    Returns true if the item should be drawn with
     smooth pixmap filtering, false otherwise.
 
-    The default is false.
+    The default is true.
 
     \sa setSmooth()
 */
@@ -4217,6 +4547,47 @@ void QQuickItem::setSmooth(bool smooth)
     emit smoothChanged(smooth);
 }
 
+/*!
+    \property QQuickItem::antialiasing
+    \brief Specifies whether the item is antialiased or not
+
+    Primarily used in Rectangle and image based elements to decide if the item should
+    use antialiasing or not. Items with antialiasing enabled require more memory and
+    are potentially slower to render.
+
+    The default is false.
+*/
+
+/*!
+    Returns true if the item should be drawn with antialiasing, false otherwise.
+
+    The default is false.
+
+    \sa setAntialiasing()
+*/
+bool QQuickItem::antialiasing() const
+{
+    Q_D(const QQuickItem);
+    return d->antialiasing;
+}
+
+/*!
+    Sets whether the item should be drawn with antialiasing to \a antialiasing.
+
+    \sa antialiasing()
+*/
+void QQuickItem::setAntialiasing(bool antialiasing)
+{
+    Q_D(QQuickItem);
+    if (d->antialiasing == antialiasing)
+        return;
+
+    d->antialiasing = antialiasing;
+    d->dirty(QQuickItemPrivate::Antialiasing);
+
+    emit antialiasingChanged(antialiasing);
+}
+
 QQuickItem::Flags QQuickItem::flags() const
 {
     Q_D(const QQuickItem);
@@ -4237,8 +4608,8 @@ void QQuickItem::setFlags(Flags flags)
     Q_D(QQuickItem);
 
     if ((flags & ItemIsFocusScope) != (d->flags & ItemIsFocusScope)) {
-        if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->canvas) {
-            qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a canvas.");
+        if (flags & ItemIsFocusScope && !d->childItems.isEmpty() && d->window) {
+            qWarning("QQuickItem: Cannot set FocusScope once item has children and is in a window.");
             flags &= ~ItemIsFocusScope;
         } else if (d->flags & ItemIsFocusScope) {
             qWarning("QQuickItem: Cannot unset FocusScope flag.");
@@ -4353,6 +4724,12 @@ void QQuickItem::resetWidth()
 void QQuickItemPrivate::implicitWidthChanged()
 {
     Q_Q(QQuickItem);
+    for (int ii = 0; ii < changeListeners.count(); ++ii) {
+        const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
+        if (change.types & QQuickItemPrivate::ImplicitWidth) {
+            change.listener->itemImplicitWidthChanged(q);
+        }
+    }
     emit q->implicitWidthChanged();
 }
 
@@ -4375,7 +4752,7 @@ qreal QQuickItem::implicitWidth() const
 
     Defines the natural width or height of the Item if no \l width or \l height is specified.
 
-    The default implicit size for most items is 0x0, however some elements have an inherent
+    The default implicit size for most items is 0x0, however some items have an inherent
     implicit size which cannot be overridden, e.g. Image, Text.
 
     Setting the implicit size is useful for defining components that have a preferred size
@@ -4383,7 +4760,7 @@ qreal QQuickItem::implicitWidth() const
 
     \qml
     // Label.qml
-    import QtQuick 1.1
+    import QtQuick 2.0
 
     Item {
         property alias icon: image.source
@@ -4400,7 +4777,7 @@ qreal QQuickItem::implicitWidth() const
     }
     \endqml
 
-    \bold Note: using implicitWidth of Text or TextEdit and setting the width explicitly
+    \b Note: using implicitWidth of Text or TextEdit and setting the width explicitly
     incurs a performance penalty as the text must be laid out twice.
 */
 
@@ -4416,7 +4793,9 @@ void QQuickItem::setImplicitWidth(qreal w)
     if (d->width == w || widthValid()) {
         if (changed)
             d->implicitWidthChanged();
-        return;
+        if (d->width == w || widthValid())
+            return;
+        changed = false;
     }
 
     qreal oldWidth = d->width;
@@ -4475,6 +4854,12 @@ void QQuickItem::resetHeight()
 void QQuickItemPrivate::implicitHeightChanged()
 {
     Q_Q(QQuickItem);
+    for (int ii = 0; ii < changeListeners.count(); ++ii) {
+        const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
+        if (change.types & QQuickItemPrivate::ImplicitHeight) {
+            change.listener->itemImplicitHeightChanged(q);
+        }
+    }
     emit q->implicitHeightChanged();
 }
 
@@ -4505,7 +4890,9 @@ void QQuickItem::setImplicitHeight(qreal h)
     if (d->height == h || heightValid()) {
         if (changed)
             d->implicitHeightChanged();
-        return;
+        if (d->height == h || heightValid())
+            return;
+        changed = false;
     }
 
     qreal oldHeight = d->height;
@@ -4534,12 +4921,14 @@ void QQuickItem::setImplicitSize(qreal w, qreal h)
     if (d->width == w || widthValid()) {
         if (wChanged)
             d->implicitWidthChanged();
-        wDone = true;
+        wDone = d->width == w || widthValid();
+        wChanged = false;
     }
     if (d->height == h || heightValid()) {
         if (hChanged)
             d->implicitHeightChanged();
-        hDone = true;
+        hDone = d->height == h || heightValid();
+        hChanged = false;
     }
     if (wDone && hDone)
         return;
@@ -4609,18 +4998,51 @@ void QQuickItem::setFocus(bool focus)
     if (d->focus == focus)
         return;
 
-    if (d->canvas) {
+    if (d->window || d->parentItem) {
         // Need to find our nearest focus scope
         QQuickItem *scope = parentItem();
-        while (scope && !scope->isFocusScope())
+        while (scope && !scope->isFocusScope() && scope->parentItem())
             scope = scope->parentItem();
-        if (focus)
-            QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
-        else
-            QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
+        if (d->window) {
+            if (focus)
+                QQuickWindowPrivate::get(d->window)->setFocusInScope(scope, this);
+            else
+                QQuickWindowPrivate::get(d->window)->clearFocusInScope(scope, this);
+        } else {
+            // do the focus changes from setFocusInScope/clearFocusInScope that are
+            // unrelated to a window
+            QVarLengthArray<QQuickItem *, 20> changed;
+            QQuickItem *oldSubFocusItem = QQuickItemPrivate::get(scope)->subFocusItem;
+            if (oldSubFocusItem) {
+                QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(scope, false);
+                QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
+                changed << oldSubFocusItem;
+            } else if (!scope->isFocusScope() && scope->hasFocus()) {
+                QQuickItemPrivate::get(scope)->focus = false;
+                changed << scope;
+            }
+            d->updateSubFocusItem(scope, focus);
+
+            d->focus = focus;
+            changed << this;
+            emit focusChanged(focus);
+
+            QQuickWindowPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
+        }
     } else {
+        QVarLengthArray<QQuickItem *, 20> changed;
+        QQuickItem *oldSubFocusItem = d->subFocusItem;
+        if (!isFocusScope() && oldSubFocusItem) {
+            QQuickItemPrivate::get(oldSubFocusItem)->updateSubFocusItem(this, false);
+            QQuickItemPrivate::get(oldSubFocusItem)->focus = false;
+            changed << oldSubFocusItem;
+        }
+
         d->focus = focus;
+        changed << this;
         emit focusChanged(focus);
+
+        QQuickWindowPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
     }
 }
 
@@ -4642,13 +5064,20 @@ QQuickItem *QQuickItem::scopedFocusItem() const
 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
 {
     Q_D(const QQuickItem);
-    return d->acceptedMouseButtons;
+    return d->acceptedMouseButtons();
 }
 
 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
 {
     Q_D(QQuickItem);
-    d->acceptedMouseButtons = buttons;
+    if (buttons & Qt::LeftButton)
+        d->extra.setFlag();
+    else
+        d->extra.clearFlag();
+
+    buttons &= ~Qt::LeftButton;
+    if (buttons || d->extra.isAllocated())
+        d->extra.value().acceptedMouseButtons = buttons;
 }
 
 bool QQuickItem::filtersChildMouseEvents() const
@@ -4666,13 +5095,11 @@ void QQuickItem::setFiltersChildMouseEvents(bool filter)
 bool QQuickItem::isUnderMouse() const
 {
     Q_D(const QQuickItem);
-    if (!d->canvas)
+    if (!d->window)
         return false;
 
-    QPoint cursorPos = QCursor::pos();
-    if (QRectF(0, 0, width(), height()).contains(mapFromScene(cursorPos))) // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
-        return true;
-    return false;
+    QPointF cursorPos = QGuiApplicationPrivate::lastCursorPosition;
+    return contains(mapFromScene(d->window->mapFromGlobal(cursorPos.toPoint())));
 }
 
 bool QQuickItem::acceptHoverEvents() const
@@ -4690,31 +5117,35 @@ void QQuickItem::setAcceptHoverEvents(bool enabled)
 void QQuickItem::grabMouse()
 {
     Q_D(QQuickItem);
-    if (!d->canvas)
+    if (!d->window)
         return;
-    QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
-    if (canvasPriv->mouseGrabberItem == this)
+    QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(d->window);
+    if (windowPriv->mouseGrabberItem == this)
         return;
 
-    QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
-    canvasPriv->mouseGrabberItem = this;
-    if (oldGrabber)
-        oldGrabber->mouseUngrabEvent();
+    QQuickItem *oldGrabber = windowPriv->mouseGrabberItem;
+    windowPriv->mouseGrabberItem = this;
+    if (oldGrabber) {
+        QEvent ev(QEvent::UngrabMouse);
+        d->window->sendEvent(oldGrabber, &ev);
+    }
 }
 
 void QQuickItem::ungrabMouse()
 {
     Q_D(QQuickItem);
-    if (!d->canvas)
+    if (!d->window)
         return;
-    QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
-    if (canvasPriv->mouseGrabberItem != this) {
+    QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(d->window);
+    if (windowPriv->mouseGrabberItem != this) {
         qWarning("QQuickItem::ungrabMouse(): Item is not the mouse grabber.");
         return;
     }
 
-    canvasPriv->mouseGrabberItem = 0;
-    mouseUngrabEvent();
+    windowPriv->mouseGrabberItem = 0;
+
+    QEvent ev(QEvent::UngrabMouse);
+    d->window->sendEvent(this, &ev);
 }
 
 bool QQuickItem::keepMouseGrab() const
@@ -4757,20 +5188,20 @@ void QQuickItem::setKeepMouseGrab(bool keep)
 
     \sa ungrabTouchPoints(), setKeepTouchGrab()
 */
-void QQuickItem::grabTouchPoints(const QList<int> &ids)
+void QQuickItem::grabTouchPoints(const QVector<int> &ids)
 {
     Q_D(QQuickItem);
-    if (!d->canvas)
+    if (!d->window)
         return;
-    QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
+    QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(d->window);
 
     QSet<QQuickItem*> ungrab;
     for (int i = 0; i < ids.count(); ++i) {
-        QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
+        QQuickItem *oldGrabber = windowPriv->itemForTouchPointId.value(ids.at(i));
         if (oldGrabber == this)
             return;
 
-        canvasPriv->itemForTouchPointId[ids.at(i)] = this;
+        windowPriv->itemForTouchPointId[ids.at(i)] = this;
         if (oldGrabber)
             ungrab.insert(oldGrabber);
     }
@@ -4786,11 +5217,11 @@ void QQuickItem::grabTouchPoints(const QList<int> &ids)
 void QQuickItem::ungrabTouchPoints()
 {
     Q_D(QQuickItem);
-    if (!d->canvas)
+    if (!d->window)
         return;
-    QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
+    QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(d->window);
 
-    QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
+    QMutableHashIterator<int, QQuickItem*> i(windowPriv->itemForTouchPointId);
     while (i.hasNext()) {
         i.next();
         if (i.value() == this)
@@ -4836,25 +5267,23 @@ void QQuickItem::setKeepTouchGrab(bool keep)
 }
 
 /*!
-    \qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
+  Returns true if this item contains \a point, which is in local coordinates;
+  returns false otherwise.
 
-    Maps the point (\a x, \a y), which is in \a item's coordinate system, to
-    this item's coordinate system, and returns an object with \c x and \c y
-    properties matching the mapped coordinate.
+  This function can be overwritten in order to handle point collisions in items
+  with custom shapes. The default implementation checks if the point is inside
+  the item's bounding rect.
 
-    If \a item is a \c null value, this maps the point from the coordinate
-    system of the root QML view.
+  Note that it's normally used to check if the item is under the mouse cursor,
+  and for that reason, the implementation of this function should be as light-weight
+  as possible.
 */
-/*!
-    \qmlmethod object QtQuick2::Item::mapToItem(Item item, real x, real y)
-
-    Maps the point (\a x, \a y), which is in this item's coordinate system, to
-    \a item's coordinate system, and returns an object with \c x and \c y
-    properties matching the mapped coordinate.
+bool QQuickItem::contains(const QPointF &point) const
+{
+    Q_D(const QQuickItem);
+    return QRectF(0, 0, d->width, d->height).contains(point);
+}
 
-    If \a item is a \c null value, this maps \a x and \a y to the coordinate
-    system of the root QML view.
-*/
 QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
 {
     QPointF p = mapToScene(point);
@@ -4866,22 +5295,22 @@ QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) cons
 QPointF QQuickItem::mapToScene(const QPointF &point) const
 {
     Q_D(const QQuickItem);
-    return d->itemToCanvasTransform().map(point);
+    return d->itemToWindowTransform().map(point);
 }
 
 QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) const
 {
     Q_D(const QQuickItem);
-    QTransform t = d->itemToCanvasTransform();
+    QTransform t = d->itemToWindowTransform();
     if (item)
-        t *= QQuickItemPrivate::get(item)->canvasToItemTransform();
+        t *= QQuickItemPrivate::get(item)->windowToItemTransform();
     return t.mapRect(rect);
 }
 
 QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
 {
     Q_D(const QQuickItem);
-    return d->itemToCanvasTransform().mapRect(rect);
+    return d->itemToWindowTransform().mapRect(rect);
 }
 
 QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
@@ -4893,21 +5322,21 @@ QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) co
 QPointF QQuickItem::mapFromScene(const QPointF &point) const
 {
     Q_D(const QQuickItem);
-    return d->canvasToItemTransform().map(point);
+    return d->windowToItemTransform().map(point);
 }
 
 QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) const
 {
     Q_D(const QQuickItem);
-    QTransform t = item?QQuickItemPrivate::get(item)->itemToCanvasTransform():QTransform();
-    t *= d->canvasToItemTransform();
+    QTransform t = item?QQuickItemPrivate::get(item)->itemToWindowTransform():QTransform();
+    t *= d->windowToItemTransform();
     return t.mapRect(rect);
 }
 
 QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
 {
     Q_D(const QQuickItem);
-    return d->canvasToItemTransform().mapRect(rect);
+    return d->windowToItemTransform().mapRect(rect);
 }
 
 
@@ -4985,9 +5414,9 @@ QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
 
   \l {Filter}{Filters} include things like \l {Blur}{blurring}
   the item, or giving it a \l Reflection.  Some
-  filters may not be available on all canvases; if a filter is not
-  available on a certain canvas, it will simply not be applied for
-  that canvas (but the QML will still be considered valid).
+  filters may not be available on all windows; if a filter is not
+  available on a certain window, it will simply not be applied for
+  that window (but the QML will still be considered valid).
 
   \qml
   Item {
@@ -5334,7 +5763,8 @@ qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
 bool QQuickItem::isTextureProvider() const
 {
     Q_D(const QQuickItem);
-    return d->_layer && d->_layer->effectSource() ? d->_layer->effectSource()->isTextureProvider() : false;
+    return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
+           d->extra->layer->effectSource()->isTextureProvider() : false;
 }
 
 /*!
@@ -5349,20 +5779,20 @@ bool QQuickItem::isTextureProvider() const
 QSGTextureProvider *QQuickItem::textureProvider() const
 {
     Q_D(const QQuickItem);
-    return d->_layer && d->_layer->effectSource() ? d->_layer->effectSource()->textureProvider() : 0;
+    return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
+           d->extra->layer->effectSource()->textureProvider() : 0;
 }
 
-
-
 QQuickItemLayer *QQuickItemPrivate::layer() const
 {
-    if (!_layer)
-        _layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
-    return _layer;
+    if (!extra.isAllocated() || !extra->layer) {
+        extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
+        if (!componentComplete)
+            extra->layer->classBegin();
+    }
+    return extra->layer;
 }
 
-
-
 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
     : m_item(item)
     , m_enabled(false)
@@ -5371,11 +5801,11 @@ QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
     , m_componentComplete(true)
     , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
     , m_format(QQuickShaderEffectSource::RGBA)
+    , m_name("source")
     , m_effectComponent(0)
     , m_effect(0)
     , m_effectSource(0)
 {
-    m_name = QLatin1String("source");
 }
 
 QQuickItemLayer::~QQuickItemLayer()
@@ -5416,11 +5846,14 @@ void QQuickItemLayer::setEnabled(bool e)
 
 void QQuickItemLayer::classBegin()
 {
+    Q_ASSERT(!m_effectSource);
+    Q_ASSERT(!m_effect);
     m_componentComplete = false;
 }
 
 void QQuickItemLayer::componentComplete()
 {
+    Q_ASSERT(!m_componentComplete);
     m_componentComplete = true;
     if (m_enabled)
         activate();
@@ -5428,16 +5861,15 @@ void QQuickItemLayer::componentComplete()
 
 void QQuickItemLayer::activate()
 {
-    QQuickItem *parentItem = m_item->parentItem();
-    if (!m_effectSource)
-        m_effectSource = new QQuickShaderEffectSource();
+    Q_ASSERT(!m_effectSource);
+    m_effectSource = new QQuickShaderEffectSource();
 
+    QQuickItem *parentItem = m_item->parentItem();
     if (parentItem) {
         m_effectSource->setParentItem(parentItem);
         m_effectSource->stackAfter(m_item);
     }
 
-    m_effectSource->setVisible(!m_effectComponent && m_item->isVisible());
     m_effectSource->setSourceItem(m_item);
     m_effectSource->setHideSource(true);
     m_effectSource->setSmooth(m_smooth);
@@ -5447,25 +5879,10 @@ void QQuickItemLayer::activate()
     m_effectSource->setWrapMode(m_wrapMode);
     m_effectSource->setFormat(m_format);
 
-    if (m_effectComponent) {
-        if (!m_effect) {
-            QObject *created = m_effectComponent->create();
-            m_effect = qobject_cast<QQuickShaderEffect *>(created);
-            if (!m_effect) {
-                qWarning("Item: layer.effect is not a shader effect");
-                delete created;
-            }
-        }
-        if (m_effect) {
-            if (parentItem) {
-                m_effect->setParentItem(parentItem);
-                m_effect->stackAfter(m_effectSource);
-            }
-            m_effect->setVisible(m_item->isVisible());
-            m_effect->setProperty(m_name.toLatin1(), qVariantFromValue<QObject *>(m_effectSource));
-            m_effect->update();
-        }
-    }
+    if (m_effectComponent)
+        activateEffect();
+
+    m_effectSource->setVisible(m_item->isVisible() && !m_effect);
 
     updateZ();
     updateGeometry();
@@ -5478,16 +5895,50 @@ void QQuickItemLayer::activate()
 
 void QQuickItemLayer::deactivate()
 {
+    Q_ASSERT(m_effectSource);
+
+    if (m_effectComponent)
+        deactivateEffect();
+
     delete m_effectSource;
     m_effectSource = 0;
 
-    delete m_effect;
-    m_effect = 0;
-
     QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
     id->removeItemChangeListener(this,  QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
 }
 
+void QQuickItemLayer::activateEffect()
+{
+    Q_ASSERT(m_effectSource);
+    Q_ASSERT(m_effectComponent);
+    Q_ASSERT(!m_effect);
+
+    QObject *created = m_effectComponent->beginCreate(m_effectComponent->creationContext());
+    m_effect = qobject_cast<QQuickItem *>(created);
+    if (!m_effect) {
+        qWarning("Item: layer.effect is not a QML Item.");
+        m_effectComponent->completeCreate();
+        delete created;
+        return;
+    }
+    QQuickItem *parentItem = m_item->parentItem();
+    if (parentItem) {
+        m_effect->setParentItem(parentItem);
+        m_effect->stackAfter(m_effectSource);
+    }
+    m_effect->setVisible(m_item->isVisible());
+    m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
+    m_effectComponent->completeCreate();
+}
+
+void QQuickItemLayer::deactivateEffect()
+{
+    Q_ASSERT(m_effectSource);
+    Q_ASSERT(m_effectComponent);
+
+    delete m_effect;
+    m_effect = 0;
+}
 
 
 /*!
@@ -5495,22 +5946,37 @@ void QQuickItemLayer::deactivate()
 
     Holds the effect that is applied to this layer.
 
-    The effect must be a \l ShaderEffect.
+    The effect is typically a \l ShaderEffect component, although any \l Item component can be
+    assigned. The effect should have a source texture property with a name matching \l samplerName.
+
+    \sa samplerName
  */
 
-void QQuickItemLayer::setEffect(QDeclarativeComponent *component)
+void QQuickItemLayer::setEffect(QQmlComponent *component)
 {
     if (component == m_effectComponent)
         return;
+
+    bool updateNeeded = false;
+    if (m_effectSource && m_effectComponent) {
+        deactivateEffect();
+        updateNeeded = true;
+    }
+
     m_effectComponent = component;
 
-    if (m_effect) {
-        delete m_effect;
-        m_effect = 0;
+    if (m_effectSource && m_effectComponent) {
+        activateEffect();
+        updateNeeded = true;
     }
 
-    if (m_effectSource)
-        activate();
+    if (updateNeeded) {
+        updateZ();
+        updateGeometry();
+        updateOpacity();
+        updateMatrix();
+        m_effectSource->setVisible(m_item->isVisible() && !m_effect);
+    }
 
     emit effectChanged(component);
 }
@@ -5547,9 +6013,9 @@ void QQuickItemLayer::setMipmap(bool mipmap)
     allow you to save some texture memory.
 
     \list
-    \o ShaderEffectSource.Alpha - GL_ALPHA
-    \o ShaderEffectSource.RGB - GL_RGB
-    \o ShaderEffectSource.RGBA - GL_RGBA
+    \li ShaderEffectSource.Alpha - GL_ALPHA
+    \li ShaderEffectSource.RGB - GL_RGB
+    \li ShaderEffectSource.RGBA - GL_RGBA
     \endlist
 
     \note Some OpenGL implementations do not support the GL_ALPHA format.
@@ -5644,10 +6110,10 @@ void QQuickItemLayer::setSize(const QSize &size)
     specified.
 
     \list
-    \o ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
-    \o ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
-    \o ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
-    \o ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
+    \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
+    \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
+    \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
+    \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
     \endlist
 
     \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
@@ -5656,7 +6122,7 @@ void QQuickItemLayer::setSize(const QSize &size)
 
 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
 {
-    if (mode != m_wrapMode)
+    if (mode == m_wrapMode)
         return;
     m_wrapMode = mode;
 
@@ -5666,6 +6132,27 @@ void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
     emit wrapModeChanged(mode);
 }
 
+/*!
+    \qmlproperty string QtQuick2::Item::layer.samplerName
+
+    Holds the name of the effect's source texture property.
+
+    samplerName needs to match the name of the effect's source texture property
+    so that the Item can pass the layer's offscreen surface to the effect correctly.
+
+    \sa effect, ShaderEffect
+ */
+
+void QQuickItemLayer::setName(const QByteArray &name) {
+    if (m_name == name)
+        return;
+    if (m_effect) {
+        m_effect->setProperty(m_name, QVariant());
+        m_effect->setProperty(name, qVariantFromValue<QObject *>(m_effectSource));
+    }
+    m_name = name;
+    emit nameChanged(name);
+}
 
 void QQuickItemLayer::itemOpacityChanged(QQuickItem *item)
 {
@@ -5681,8 +6168,9 @@ void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QR
 void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
 {
     Q_UNUSED(item)
-    if (parent == m_effectSource || parent == m_effect)
-        return;
+    Q_ASSERT(item == m_item);
+    Q_ASSERT(parent != m_effectSource);
+    Q_ASSERT(parent == 0 || parent != m_effect);
 
     m_effectSource->setParentItem(parent);
     if (parent)
@@ -5705,25 +6193,31 @@ void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
 void QQuickItemLayer::itemVisibilityChanged(QQuickItem *)
 {
     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
+    Q_ASSERT(l);
     l->setVisible(m_item->isVisible());
 }
 
 void QQuickItemLayer::updateZ()
 {
+    if (!m_componentComplete || !m_enabled)
+        return;
     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
+    Q_ASSERT(l);
     l->setZ(m_item->z());
 }
 
 void QQuickItemLayer::updateOpacity()
 {
     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
+    Q_ASSERT(l);
     l->setOpacity(m_item->opacity());
 }
 
 void QQuickItemLayer::updateGeometry()
 {
     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
-    QRectF bounds = m_item->boundingRect();
+    Q_ASSERT(l);
+    QRectF bounds = m_item->clipRect();
     l->setWidth(bounds.width());
     l->setHeight(bounds.height());
     l->setX(bounds.x() + m_item->x());
@@ -5737,14 +6231,25 @@ void QQuickItemLayer::updateMatrix()
     if (!m_componentComplete || !m_enabled)
         return;
     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
+    Q_ASSERT(l);
     QQuickItemPrivate *ld = QQuickItemPrivate::get(l);
     l->setScale(m_item->scale());
     l->setRotation(m_item->rotation());
     ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
-    ld->origin = QQuickItemPrivate::get(m_item)->origin;
+    if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
+        ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
     ld->dirty(QQuickItemPrivate::Transform);
 }
 
+QQuickItemPrivate::ExtraData::ExtraData()
+: z(0), scale(1), rotation(0), opacity(1),
+  contents(0), screenAttached(0), layoutDirectionAttached(0),
+  keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
+  opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
+  acceptedMouseButtons(0), origin(QQuickItem::Center)
+{
+}
+
 QT_END_NAMESPACE
 
 #include <moc_qquickitem.cpp>