Doc: Sanitized QML types
[profile/ivi/qtdeclarative.git] / src / quick / items / qquickitem.cpp
index 5ec0787..47bfc98 100644 (file)
@@ -1,10 +1,9 @@
 /****************************************************************************
 **
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** 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
@@ -35,6 +34,7 @@
 **
 **
 **
+**
 ** $QT_END_LICENSE$
 **
 ****************************************************************************/
 #include "qquickitem.h"
 
 #include "qquickcanvas.h"
-#include <QtDeclarative/qjsengine.h>
+#include <QtQml/qjsengine.h>
 #include "qquickcanvas_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;
@@ -84,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 },
@@ -107,15 +130,15 @@ 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.
+    \brief For specifying advanced transformations on Items
 
     The Transform element 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
@@ -129,14 +152,14 @@ void QQuickItemPrivate::registerAccessorProperties()
     \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.
+    \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
     to lay the items out as if they had not been transformed:
     \qml
-    import QtQuick 1.0
+    import QtQuick 2.0
 
     Row {
         Rectangle {
@@ -171,7 +194,7 @@ void QQuickItemPrivate::registerAccessorProperties()
     \qmlclass Scale QQuickScale
     \inqmlmodule QtQuick 2
     \ingroup qml-transform-elements
-    \brief The Scale element provides a way to scale an Item.
+    \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,
     it allows a different scale for the x and y axes, and allows the scale to be relative to an
@@ -213,7 +236,7 @@ void QQuickItemPrivate::registerAccessorProperties()
     \qmlclass Rotation QQuickRotation
     \inqmlmodule QtQuick 2
     \ingroup qml-transform-elements
-    \brief The Rotation object provides a way to rotate an Item.
+    \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.
@@ -231,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 doc/snippets/qml/rotation.qml 0
 
     \image axisrotation.png
 
@@ -440,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;
     }
 }
 
@@ -481,7 +504,7 @@ 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.
+    \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
@@ -489,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 doc/snippets/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
@@ -543,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;
 }
@@ -693,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
@@ -884,16 +907,20 @@ 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);
+    //### doing two string-based lookups isn't ideal
+    int signal_index = d->signalIndex(signalName);
+    int index = metaObject()->indexOfSignal(signalName);
+    return QQml_isSignalConnected(this, signal_index, index);
 }
 
 /*!
     \qmlclass Keys QQuickKeysAttached
     \inqmlmodule QtQuick 2
     \ingroup qml-basic-interaction-elements
-    \brief The Keys attached property provides key handling to Items.
+    \brief Provides key handling to Items
 
     All visual primitives support key handling via the Keys
     attached property.  Keys can be handled via the onPressed
@@ -910,13 +937,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 doc/snippets/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 doc/snippets/qml/keys/keys-handler.qml key item
 
     See \l{Qt::Key}{Qt.Key} for the list of keyboard codes.
 
@@ -930,21 +957,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
@@ -967,10 +994,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
@@ -1278,11 +1305,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()
@@ -1346,7 +1373,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);
@@ -1439,7 +1466,7 @@ QQuickKeysAttached *QQuickKeysAttached::qmlAttachedProperties(QObject *obj)
     \qmlclass LayoutMirroring QQuickLayoutMirroringAttached
     \inqmlmodule QtQuick 2
     \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)
@@ -1458,7 +1485,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 doc/snippets/qml/layoutmirroring.qml 0
 
     \image layoutmirroring.png
 
@@ -1503,7 +1530,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");
 }
@@ -1577,7 +1604,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);
         }
@@ -1596,37 +1623,110 @@ void QQuickItemPrivate::setLayoutMirror(bool mirror)
             emit _anchors->mirroredChanged();
         }
         mirrorChange();
-        if (attachedLayoutDirection) {
-            emit attachedLayoutDirection->enabledChanged();
+        if (extra.isAllocated() && extra->layoutDirectionAttached) {
+            emit extra->layoutDirectionAttached->enabledChanged();
+        }
+    }
+}
+
+void QQuickItemPrivate::setAccessibleFlagAndListener()
+{
+    Q_Q(QQuickItem);
+    QQuickItem *item = q;
+    while (item) {
+        if (item->d_func()->isAccessible)
+            break; // already set - grandparents should have the flag set as well.
+
+        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 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 QQuickCanvas, 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.
+    \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.
@@ -1774,10 +1874,13 @@ QQuickItem::~QQuickItem()
 
     Q_D(QQuickItem);
 
+    if (d->canvasRefCount > 1)
+        d->canvasRefCount = 1; // Make sure canvas is set to null in next call to derefCanvas().
     if (d->parentItem)
         setParentItem(0);
-    else if (d->canvas && d->itemNodeInstance)
-        QQuickCanvasPrivate::get(d->canvas)->cleanup(d->itemNodeInstance); // cleanup root
+    else if (d->canvas)
+        d->derefCanvas();
+
     // XXX todo - optimize
     while (!d->childItems.isEmpty())
         d->childItems.first()->setParentItem(0);
@@ -1803,11 +1906,16 @@ QQuickItem::~QQuickItem()
         if (change.types & QQuickItemPrivate::Destroyed)
             change.listener->itemDestroyed(this);
     }
+
     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;
 }
 
 /*!
@@ -1848,6 +1956,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;
@@ -1858,52 +1977,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,
+        if (scopeFocusedItem) {
+            scopeItem = oldParentItem;
+            while (!scopeItem->isFocusScope() && scopeItem->parentItem())
+                scopeItem = scopeItem->parentItem();
+            if (d->canvas) {
+                QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
                                                                 QQuickCanvasPrivate::DontChangeFocusProperty);
+                if (scopeFocusedItem != this)
+                    QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(this, true);
+            } else {
+                QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, false);
+            }
+        }
 
+        const bool wasVisible = isVisible();
         op->removeChild(this);
+        if (wasVisible) {
+            emit oldParentItem->visibleChildrenChanged();
+        }
+    } else if (d->canvas) {
+        QQuickCanvasPrivate::get(d->canvas)->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);
+    QQuickCanvas *oldParentCanvas = oldParentItem ? QQuickItemPrivate::get(oldParentItem)->canvas : 0;
+    QQuickCanvas *parentCanvas = parentItem ? QQuickItemPrivate::get(parentItem)->canvas : 0;
+    if (oldParentCanvas == parentCanvas) {
+        // Avoid freeing and reallocating resources if the canvas stays the same.
+        d->parentItem = parentItem;
+    } else {
+        if (oldParentCanvas)
+            d->derefCanvas();
+        d->parentItem = parentItem;
+        if (parentCanvas)
+            d->refCanvas(parentCanvas);
     }
 
     d->dirty(QQuickItemPrivate::ParentChanged);
 
     if (d->parentItem)
         QQuickItemPrivate::get(d->parentItem)->addChild(this);
+    else if (d->canvas)
+        QQuickCanvasPrivate::get(d->canvas)->parentlessItems.insert(this);
 
     d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
-    d->setEffectiveEnableRecur(d->calcEffectiveEnable());
+    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->canvas) {
+                    QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scopeItem, scopeFocusedItem,
+                                                                  QQuickCanvasPrivate::DontChangeFocusProperty);
+                } else {
+                    QQuickItemPrivate::get(scopeFocusedItem)->updateSubFocusItem(scopeItem, true);
+                }
+            }
         }
     }
 
@@ -1912,7 +2064,13 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
     d->itemChange(ItemParentHasChanged, d->parentItem);
 
     d->parentNotifier.notify();
+    if (d->isAccessible && d->parentItem) {
+        d->parentItem->d_func()->setAccessibleFlagAndListener();
+    }
+
     emit parentChanged(d->parentItem);
+    if (isVisible() && d->parentItem)
+        emit d->parentItem->visibleChildrenChanged();
 }
 
 void QQuickItem::stackBefore(const QQuickItem *sibling)
@@ -1986,11 +2144,6 @@ QQuickItem *QQuickItem::parentItem() const
     return d->parentItem;
 }
 
-QSGEngine *QQuickItem::sceneGraphEngine() const
-{
-    return canvas()->sceneGraphEngine();
-}
-
 QQuickCanvas *QQuickItem::canvas() const
 {
     Q_D(const QQuickItem);
@@ -2011,7 +2164,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;
         }
@@ -2074,71 +2227,114 @@ QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *it
 {
     if (!focusScope) {
         QQuickItem *fs = item->parentItem();
-        while (!fs->isFocusScope())
+        while (fs->parentItem() && !fs->isFocusScope())
             fs = fs->parentItem();
         focusScope = fs;
     }
     return focusScope;
 }
 
-void QQuickItemPrivate::initCanvas(InitializationState *state, QQuickCanvas *c)
+void QQuickItemPrivate::refCanvas(InitializationState *state, QQuickCanvas *c)
 {
-    Q_Q(QQuickItem);
+    // An item needs a canvas if it is referenced by another item which has a canvas.
+    // Typically the item is referenced by a parent, but can also be referenced by a
+    // ShaderEffect or ShaderEffectSource. 'canvasRefCount' counts how many items with
+    // a canvas is referencing this item. When the reference count goes from zero to one,
+    // or one to zero, the canvas of this item is updated and propagated to the children.
+    // As long as the reference count stays above zero, the canvas is unchanged.
+    // refCanvas() increments the reference count.
+    // derefCanvas() decrements the reference count.
 
-    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);
+    Q_Q(QQuickItem);
+    Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
+    Q_ASSERT(c);
+    if (++canvasRefCount > 1) {
+        if (c != canvas)
+            qWarning("QQuickItem: Cannot use same item on different canvases at the same time.");
+        return; // Canvas already set.
     }
 
+    Q_ASSERT(canvas == 0);
     canvas = c;
 
-    if (canvas && polishScheduled)
+    if (polishScheduled)
         QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
 
-    itemNodeInstance = 0;
-    opacityNode = 0;
-    clipNode = 0;
-    rootNode = 0;
-    groupNode = 0;
-    paintNode = 0;
-    beforePaintNode = 0;
-
     InitializationState _dummy;
     InitializationState *childState = state;
 
-    if (c && q->isFocusScope()) {
+    if (q->isFocusScope()) {
         _dummy.clear(q);
         childState = &_dummy;
     }
 
+    if (!parentItem)
+        QQuickCanvasPrivate::get(canvas)->parentlessItems.insert(q);
+
     for (int ii = 0; ii < childItems.count(); ++ii) {
         QQuickItem *child = childItems.at(ii);
-        QQuickItemPrivate::get(child)->initCanvas(childState, c);
+        QQuickItemPrivate::get(child)->refCanvas(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);
-        }
+    dirty(Canvas);
+
+    if (extra.isAllocated() && extra->screenAttached)
+        extra->screenAttached->canvasChanged(c);
+    itemChange(QQuickItem::ItemSceneChange, c);
+}
+
+void QQuickItemPrivate::derefCanvas()
+{
+    Q_Q(QQuickItem);
+    Q_ASSERT((canvas != 0) == (canvasRefCount > 0));
+
+    if (!canvas)
+        return; // This can happen when destroying recursive shader effect sources.
+
+    if (--canvasRefCount > 0)
+        return; // There are still other references, so don't set canvas to null yet.
+
+    q->releaseResources();
+    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);
+
+    canvas = 0;
+
+    itemNodeInstance = 0;
+
+    if (extra.isAllocated()) {
+        extra->opacityNode = 0;
+        extra->clipNode = 0;
+        extra->rootNode = 0;
+        extra->beforePaintNode = 0;
+    }
+
+    groupNode = 0;
+    paintNode = 0;
+
+    for (int ii = 0; ii < childItems.count(); ++ii) {
+        QQuickItem *child = childItems.at(ii);
+        QQuickItemPrivate::get(child)->derefCanvas();
     }
 
     dirty(Canvas);
 
-    itemChange(QQuickItem::ItemSceneChange, c);
+    if (extra.isAllocated() && extra->screenAttached)
+        extra->screenAttached->canvasChanged(0);
+    itemChange(QQuickItem::ItemSceneChange, (QQuickCanvas *)0);
 }
 
+
 /*!
 Returns a transform that maps points from canvas space into item space.
 */
@@ -2174,11 +2370,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());
     }
 }
@@ -2239,31 +2435,27 @@ 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),
+: _anchors(0), _stateGroup(0),
+  flags(0), widthValid(false), heightValid(false), baselineOffsetValid(false), componentComplete(true),
+  keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(true), 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),
+
+  dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
 
-  canvas(0), parentItem(0), sortedChildItems(&childItems),
+  canvas(0), canvasRefCount(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::ImhMultiLine),
+  baselineOffset(0),
 
-  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)
+  itemNodeInstance(0), groupNode(0), paintNode(0)
 {
 }
 
@@ -2285,7 +2477,10 @@ void QQuickItemPrivate::init(QQuickItem *parent)
 #endif
 
     Q_Q(QQuickItem);
-    baselineOffset.invalidate();
+
+    registerAccessorProperties();
+
+    baselineOffsetValid = false;
 
     if (parent) {
         q->setParentItem(parent);
@@ -2294,21 +2489,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"))
@@ -2353,14 +2541,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);
@@ -2368,13 +2556,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())
@@ -2383,18 +2571,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();
@@ -2402,7 +2590,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)
@@ -2411,7 +2599,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;
@@ -2423,13 +2611,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);
@@ -2437,10 +2625,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)
@@ -2481,7 +2704,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;
@@ -2490,7 +2713,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);
@@ -2501,7 +2724,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);
@@ -2519,7 +2742,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.
 */
@@ -2551,8 +2774,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 {
@@ -2566,8 +2789,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 {
@@ -2582,8 +2805,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 {
@@ -2597,8 +2820,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 {
@@ -2663,6 +2886,7 @@ void QQuickItemPrivate::transform_clear(QDeclarativeListProperty<QQuickTransform
   \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.
@@ -2676,8 +2900,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 {
@@ -2694,8 +2918,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.
 
@@ -2723,6 +2947,13 @@ void QQuickItemPrivate::transform_clear(QDeclarativeListProperty<QQuickTransform
 
   \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.
 
   For more information see \l {anchor-layout}{Anchor Layouts}.
@@ -2730,7 +2961,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
@@ -2749,14 +2980,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);
@@ -2768,9 +2991,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);
@@ -2779,12 +3002,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
@@ -2851,16 +3074,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 *)
@@ -2869,6 +3121,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 QQuickCanvas 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;
@@ -2878,6 +3147,11 @@ void QQuickItem::updatePolish()
 {
 }
 
+void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
+{
+    changeListeners.append(ChangeListener(listener, types));
+}
+
 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
 {
     ChangeListener change(listener, types);
@@ -2894,7 +3168,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) {
@@ -2923,6 +3198,10 @@ void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
 
 void QQuickItem::focusInEvent(QFocusEvent *)
 {
+#ifndef QT_NO_ACCESSIBILITY
+    QAccessibleEvent ev(this, QAccessible::Focus);
+    QAccessible::updateAccessibility(&ev);
+#endif
 }
 
 void QQuickItem::focusOutEvent(QFocusEvent *)
@@ -2944,9 +3223,8 @@ void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
     event->ignore();
 }
 
-void QQuickItem::mouseDoubleClickEvent(QMouseEvent *event)
+void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
 {
-    mousePressEvent(event);
 }
 
 void QQuickItem::mouseUngrabEvent()
@@ -3018,32 +3296,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);
-}
-
-void QQuickItem::updateMicroFocus()
-{
-    QInputPanel *p = qApp->inputPanel();
-    if (p->inputItem() == this)
-        qApp->inputPanel()->update(Qt::ImQueryInput);
-}
-
 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
 {
     Q_D(const QQuickItem);
@@ -3054,8 +3306,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:
@@ -3064,8 +3314,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;
     }
@@ -3075,46 +3325,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)
@@ -3124,6 +3382,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);
@@ -3133,9 +3392,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 QQuickCanvas.
+ *
+ * Only items which specifies QQuickItem::ItemHasContents are allowed
+ * to call QQuickItem::update().
+ */
 void QQuickItem::update()
 {
     Q_D(QQuickItem);
@@ -3157,7 +3430,18 @@ void QQuickItem::polish()
     }
 }
 
-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];
@@ -3179,10 +3463,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;
 
-        rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
-        rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
+            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()));
+        }
     }
 }
 
@@ -3200,7 +3496,18 @@ QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
     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];
@@ -3222,10 +3529,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()));
+        }
     }
 }
 
@@ -3256,29 +3575,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();
 }
@@ -3308,9 +3641,9 @@ 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);
@@ -3324,6 +3657,8 @@ void QQuickItem::classBegin()
         d->_stateGroup->classBegin();
     if (d->_anchors)
         d->_anchors->classBegin();
+    if (d->extra.isAllocated() && d->extra->layer)
+        d->extra->layer->classBegin();
 }
 
 void QQuickItem::componentComplete()
@@ -3336,47 +3671,34 @@ void QQuickItem::componentComplete()
         d->_anchors->componentComplete();
         QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
     }
-    if (d->keyHandler)
-        d->keyHandler->componentComplete();
-    if (d->_contents)
-        d->_contents->complete();
+
+    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();
 }
 
-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);
@@ -3401,6 +3723,8 @@ QPointF QQuickItemPrivate::computeTransformOrigin() const
 
 void QQuickItemPrivate::transformChanged()
 {
+    if (extra.isAllocated() && extra->layer)
+        extra->layer->updateMatrix();
 }
 
 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
@@ -3408,11 +3732,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;
@@ -3428,13 +3752,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);
     }
 }
 
@@ -3443,8 +3767,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;
@@ -3457,10 +3781,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);
     }
 }
 
@@ -3556,64 +3880,80 @@ void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
     Q_UNUSED(value);
 }
 
+/*!
+    Notify input method on updated query values if needed. \a indicates changed attributes.
+*/
+void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
+{
+    if (hasActiveFocus())
+        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) {
@@ -3622,6 +3962,9 @@ void QQuickItem::setZ(qreal v)
     }
 
     emit zChanged();
+
+    if (d->extra.isAllocated() && d->extra->layer)
+        d->extra->layer->updateZ();
 }
 
 
@@ -3634,8 +3977,8 @@ void QQuickItem::setZ(qreal v)
 
   \table
   \row
-  \o \image declarative-rotation.png
-  \o
+  \li \image declarative-rotation.png
+  \li
   \qml
   Rectangle {
       color: "blue"
@@ -3668,8 +4011,8 @@ void QQuickItem::setZ(qreal v)
 
   \table
   \row
-  \o \image declarative-scale.png
-  \o
+  \li \image declarative-scale.png
+  \li
   \qml
   Rectangle {
       color: "blue"
@@ -3705,8 +4048,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 {
@@ -3720,8 +4063,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 {
@@ -3754,16 +4097,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);
 
@@ -3775,16 +4118,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);
 
@@ -3794,16 +4137,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);
 
@@ -3825,8 +4168,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
@@ -3843,7 +4190,11 @@ void QQuickItem::setEnabled(bool e)
 
     d->explicitEnable = e;
 
-    d->setEffectiveEnableRecur(d->calcEffectiveEnable());
+    QQuickItem *scope = parentItem();
+    while (scope && !scope->isFocusScope())
+        scope = scope->parentItem();
+
+    d->setEffectiveEnableRecur(scope, d->calcEffectiveEnable());
 }
 
 bool QQuickItemPrivate::calcEffectiveVisible() const
@@ -3854,18 +4205,18 @@ 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;
@@ -3878,16 +4229,22 @@ void QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
             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);
     }
-
+#endif
     emit q->visibleChanged();
+    if (childVisibilityChanged)
+        emit q->visibleChildrenChanged();
+
+    return true;    // effective visibility DID change
 }
 
 bool QQuickItemPrivate::calcEffectiveEnable() const
@@ -3898,12 +4255,10 @@ bool QQuickItemPrivate::calcEffectiveEnable() const
     return explicitEnable && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveEnable);
 }
 
-void QQuickItemPrivate::setEffectiveEnableRecur(bool newEffectiveEnable)
+void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffectiveEnable)
 {
     Q_Q(QQuickItem);
 
-    // XXX todo - need to fixup focus
-
     if (newEffectiveEnable && !explicitEnable) {
         // This item locally overrides enable
         return;
@@ -3920,10 +4275,21 @@ void QQuickItemPrivate::setEffectiveEnableRecur(bool newEffectiveEnable)
         QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
         if (canvasPriv->mouseGrabberItem == q)
             q->ungrabMouse();
+        if (scope && !effectiveEnable && activeFocus) {
+            canvasPriv->clearFocusInScope(
+                    scope, q,  QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
+        }
     }
 
-    for (int ii = 0; ii < childItems.count(); ++ii)
-        QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(newEffectiveEnable);
+    for (int ii = 0; ii < childItems.count(); ++ii) {
+        QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
+                (flags & QQuickItem::ItemIsFocusScope) && scope ? q : scope, newEffectiveEnable);
+    }
+
+    if (canvas && scope && effectiveEnable && focus) {
+        QQuickCanvasPrivate::get(canvas)->setFocusInScope(
+                scope, q, QQuickCanvasPrivate::DontChangeFocusProperty | QQuickCanvasPrivate::DontChangeSubFocusItem);
+    }
 
     emit q->enabledChanged();
 }
@@ -3956,6 +4322,7 @@ QString QQuickItemPrivate::dirtyToString() const
     DIRTY_TO_STRING(EffectReference);
     DIRTY_TO_STRING(Visible);
     DIRTY_TO_STRING(HideReference);
+    DIRTY_TO_STRING(PerformanceHints);
 
     return rv;
 }
@@ -4007,27 +4374,27 @@ 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);
     }
 }
@@ -4101,13 +4468,15 @@ 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 elements 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.
 */
 
 /*!
@@ -4278,6 +4647,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();
 }
 
@@ -4308,7 +4683,7 @@ qreal QQuickItem::implicitWidth() const
 
     \qml
     // Label.qml
-    import QtQuick 1.1
+    import QtQuick 2.0
 
     Item {
         property alias icon: image.source
@@ -4325,7 +4700,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.
 */
 
@@ -4341,7 +4716,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;
@@ -4400,6 +4777,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();
 }
 
@@ -4430,7 +4813,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;
@@ -4459,12 +4844,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;
@@ -4534,15 +4921,34 @@ void QQuickItem::setFocus(bool focus)
     if (d->focus == focus)
         return;
 
-    if (d->canvas) {
+    if (d->canvas || 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->canvas) {
+            if (focus)
+                QQuickCanvasPrivate::get(d->canvas)->setFocusInScope(scope, this);
+            else
+                QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scope, this);
+        } else {
+            // do the focus changes from setFocusInScope/clearFocusInScope that are
+            // unrelated to a canvas
+            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;
+            }
+            d->updateSubFocusItem(scope, focus);
+
+            d->focus = focus;
+            changed << this;
+            emit focusChanged(focus);
+
+            QQuickCanvasPrivate::notifyFocusChangesRecur(changed.data(), changed.count() - 1);
+        }
     } else {
         d->focus = focus;
         emit focusChanged(focus);
@@ -4567,13 +4973,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
@@ -4594,10 +5007,8 @@ bool QQuickItem::isUnderMouse() const
     if (!d->canvas)
         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(cursorPos)); // ### refactor: d->canvas->mapFromGlobal(cursorPos))))
 }
 
 bool QQuickItem::acceptHoverEvents() const
@@ -4623,8 +5034,10 @@ void QQuickItem::grabMouse()
 
     QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
     canvasPriv->mouseGrabberItem = this;
-    if (oldGrabber)
-        oldGrabber->mouseUngrabEvent();
+    if (oldGrabber) {
+        QEvent ev(QEvent::UngrabMouse);
+        d->canvas->sendEvent(oldGrabber, &ev);
+    }
 }
 
 void QQuickItem::ungrabMouse()
@@ -4639,7 +5052,9 @@ void QQuickItem::ungrabMouse()
     }
 
     canvasPriv->mouseGrabberItem = 0;
-    mouseUngrabEvent();
+
+    QEvent ev(QEvent::UngrabMouse);
+    d->canvas->sendEvent(this, &ev);
 }
 
 bool QQuickItem::keepMouseGrab() const
@@ -4761,25 +5176,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);
@@ -5256,6 +5669,13 @@ qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
     This function can be called from any thread.
  */
 
+bool QQuickItem::isTextureProvider() const
+{
+    Q_D(const QQuickItem);
+    return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
+           d->extra->layer->effectSource()->isTextureProvider() : false;
+}
+
 /*!
     \fn QSGTextureProvider *QQuickItem::textureProvider() const
 
@@ -5265,6 +5685,480 @@ qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
     This function may only be called on the rendering thread.
  */
 
+QSGTextureProvider *QQuickItem::textureProvider() const
+{
+    Q_D(const QQuickItem);
+    return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
+           d->extra->layer->effectSource()->textureProvider() : 0;
+}
+
+QQuickItemLayer *QQuickItemPrivate::layer() const
+{
+    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)
+    , m_mipmap(false)
+    , m_smooth(false)
+    , m_componentComplete(true)
+    , m_wrapMode(QQuickShaderEffectSource::ClampToEdge)
+    , m_format(QQuickShaderEffectSource::RGBA)
+    , m_name("source")
+    , m_effectComponent(0)
+    , m_effect(0)
+    , m_effectSource(0)
+{
+}
+
+QQuickItemLayer::~QQuickItemLayer()
+{
+    delete m_effectSource;
+    delete m_effect;
+}
+
+
+
+/*!
+    \qmlproperty bool QtQuick2::Item::layer.enabled
+
+    Holds wether the item is layered or not. Layering is disabled by default.
+
+    A layered item is rendered into an offscreen surface and cached until
+    it is changed. Enabling layering for complex QML item hierarchies can
+    some times be an optimization.
+
+    None of the other layer properties have any effect when the layer
+    is disabled.
+ */
+
+void QQuickItemLayer::setEnabled(bool e)
+{
+    if (e == m_enabled)
+        return;
+    m_enabled = e;
+    if (m_componentComplete) {
+        if (m_enabled)
+            activate();
+        else
+            deactivate();
+    }
+
+    emit enabledChanged(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();
+}
+
+void QQuickItemLayer::activate()
+{
+    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->setSourceItem(m_item);
+    m_effectSource->setHideSource(true);
+    m_effectSource->setSmooth(m_smooth);
+    m_effectSource->setTextureSize(m_size);
+    m_effectSource->setSourceRect(m_sourceRect);
+    m_effectSource->setMipmap(m_mipmap);
+    m_effectSource->setWrapMode(m_wrapMode);
+    m_effectSource->setFormat(m_format);
+
+    if (m_effectComponent)
+        activateEffect();
+
+    m_effectSource->setVisible(m_item->isVisible() && !m_effect);
+
+    updateZ();
+    updateGeometry();
+    updateOpacity();
+    updateMatrix();
+
+    QQuickItemPrivate *id = QQuickItemPrivate::get(m_item);
+    id->addItemChangeListener(this, QQuickItemPrivate::Geometry | QQuickItemPrivate::Opacity | QQuickItemPrivate::Parent | QQuickItemPrivate::Visibility | QQuickItemPrivate::SiblingOrder);
+}
+
+void QQuickItemLayer::deactivate()
+{
+    Q_ASSERT(m_effectSource);
+
+    if (m_effectComponent)
+        deactivateEffect();
+
+    delete m_effectSource;
+    m_effectSource = 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;
+}
+
+
+/*!
+    \qmlproperty Component QtQuick2::Item::layer.effect
+
+    Holds the effect that is applied to this layer.
+
+    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(QQmlComponent *component)
+{
+    if (component == m_effectComponent)
+        return;
+
+    bool updateNeeded = false;
+    if (m_effectSource && m_effectComponent) {
+        deactivateEffect();
+        updateNeeded = true;
+    }
+
+    m_effectComponent = component;
+
+    if (m_effectSource && m_effectComponent) {
+        activateEffect();
+        updateNeeded = true;
+    }
+
+    if (updateNeeded) {
+        updateZ();
+        updateGeometry();
+        updateOpacity();
+        updateMatrix();
+        m_effectSource->setVisible(m_item->isVisible() && !m_effect);
+    }
+
+    emit effectChanged(component);
+}
+
+
+/*!
+    \qmlproperty bool QtQuick2::Item::layer.mipmap
+
+    If this property is true, mipmaps are generated for the texture.
+
+    \note Some OpenGL ES 2 implementations do not support mipmapping of
+    non-power-of-two textures.
+ */
+
+void QQuickItemLayer::setMipmap(bool mipmap)
+{
+    if (mipmap == m_mipmap)
+        return;
+    m_mipmap = mipmap;
+
+    if (m_effectSource)
+        m_effectSource->setMipmap(m_mipmap);
+
+    emit mipmapChanged(mipmap);
+}
+
+
+/*!
+    \qmlproperty enumeration QtQuick2::Item::layer.format
+
+    This property defines the internal OpenGL format of the texture.
+    Modifying this property makes most sense when the \a layer.effect is also
+    specified. Depending on the OpenGL implementation, this property might
+    allow you to save some texture memory.
+
+    \list
+    \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.
+ */
+
+void QQuickItemLayer::setFormat(QQuickShaderEffectSource::Format f)
+{
+    if (f == m_format)
+        return;
+    m_format = f;
+
+    if (m_effectSource)
+        m_effectSource->setFormat(m_format);
+
+    emit formatChanged(m_format);
+}
+
+
+/*!
+    \qmlproperty enumeration QtQuick2::Item::layer.sourceRect
+
+    This property defines which rectangular area of the \l sourceItem to
+    render into the texture. The source rectangle can be larger than
+    \l sourceItem itself. If the rectangle is null, which is the default,
+    the whole \l sourceItem is rendered to texture.
+ */
+
+void QQuickItemLayer::setSourceRect(const QRectF &sourceRect)
+{
+    if (sourceRect == m_sourceRect)
+        return;
+    m_sourceRect = sourceRect;
+
+    if (m_effectSource)
+        m_effectSource->setSourceRect(m_sourceRect);
+
+    emit sourceRectChanged(sourceRect);
+}
+
+
+
+/*!
+    \qmlproperty bool QtQuick2::Item::layer.smooth
+
+    Holds whether the layer is smoothly transformed.
+ */
+
+void QQuickItemLayer::setSmooth(bool s)
+{
+    if (m_smooth == s)
+        return;
+    m_smooth = s;
+
+    if (m_effectSource)
+        m_effectSource->setSmooth(m_smooth);
+
+    emit smoothChanged(s);
+}
+
+
+
+/*!
+    \qmlproperty size QtQuick2::Item::layer.textureSize
+
+    This property holds the requested pixel size of the layers texture. If it is empty,
+    which is the default, the size of the item is used.
+
+    \note Some platforms have a limit on how small framebuffer objects can be,
+    which means the actual texture size might be larger than the requested
+    size.
+ */
+
+void QQuickItemLayer::setSize(const QSize &size)
+{
+    if (size == m_size)
+        return;
+    m_size = size;
+
+    if (m_effectSource)
+        m_effectSource->setTextureSize(size);
+
+    emit sizeChanged(size);
+}
+
+
+
+/*!
+    \qmlproperty enumeration QtQuick2::Item::layer.wrapMode
+
+    This property defines the OpenGL wrap modes associated with the texture.
+    Modifying this property makes most sense when the \a layer.effect is
+    specified.
+
+    \list
+    \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
+    wrap mode with non-power-of-two textures.
+ */
+
+void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
+{
+    if (mode == m_wrapMode)
+        return;
+    m_wrapMode = mode;
+
+    if (m_effectSource)
+        m_effectSource->setWrapMode(m_wrapMode);
+
+    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)
+{
+    Q_UNUSED(item)
+    updateOpacity();
+}
+
+void QQuickItemLayer::itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &)
+{
+    updateGeometry();
+}
+
+void QQuickItemLayer::itemParentChanged(QQuickItem *item, QQuickItem *parent)
+{
+    Q_UNUSED(item)
+    Q_ASSERT(item == m_item);
+    Q_ASSERT(parent != m_effectSource);
+    Q_ASSERT(parent == 0 || parent != m_effect);
+
+    m_effectSource->setParentItem(parent);
+    if (parent)
+        m_effectSource->stackAfter(m_item);
+
+    if (m_effect) {
+        m_effect->setParentItem(parent);
+        if (parent)
+            m_effect->stackAfter(m_effectSource);
+    }
+}
+
+void QQuickItemLayer::itemSiblingOrderChanged(QQuickItem *)
+{
+    m_effectSource->stackAfter(m_item);
+    if (m_effect)
+        m_effect->stackAfter(m_effectSource);
+}
+
+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;
+    Q_ASSERT(l);
+    QRectF bounds = m_item->clipRect();
+    l->setWidth(bounds.width());
+    l->setHeight(bounds.height());
+    l->setX(bounds.x() + m_item->x());
+    l->setY(bounds.y() + m_item->y());
+}
+
+void QQuickItemLayer::updateMatrix()
+{
+    // Called directly from transformChanged(), so needs some extra
+    // checks.
+    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;
+    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>