Doc: Sanitized QML types
[profile/ivi/qtdeclarative.git] / src / quick / items / qquickitem.cpp
index 67da4c8..47bfc98 100644 (file)
@@ -3,7 +3,7 @@
 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
 ** Contact: http://www.qt-project.org/
 **
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the QtQml module of the Qt Toolkit.
 **
 ** $QT_BEGIN_LICENSE:LGPL$
 ** GNU Lesser General Public License Usage
 #include "qquickitem.h"
 
 #include "qquickcanvas.h"
-#include <QtDeclarative/qjsengine.h>
+#include <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/private/qguiapplication_p.h>
 #include <QtGui/qinputmethod.h>
 #include <QtCore/qdebug.h>
 #include <QtCore/qcoreevent.h>
 #include <QtCore/qnumeric.h>
 
-#include <private/qdeclarativeengine_p.h>
-#include <QtQuick/private/qdeclarativestategroup_p.h>
-#include <private/qdeclarativeopenmetaobject_p.h>
-#include <QtQuick/private/qdeclarativestate_p.h>
+#include <private/qqmlglobal_p.h>
+#include <private/qqmlengine_p.h>
+#include <QtQuick/private/qquickstategroup_p.h>
+#include <private/qqmlopenmetaobject_p.h>
+#include <QtQuick/private/qquickstate_p.h>
 #include <private/qlistmodelinterface_p.h>
 #include <private/qquickitem_p.h>
-#include <private/qdeclarativeaccessors_p.h>
+#include <private/qqmlaccessors_p.h>
 #include <QtQuick/private/qquickaccessibleattached_p.h>
 
 #include <float.h>
 
 QT_BEGIN_NAMESPACE
 
-static void QQuickItem_parentNotifier(QObject *o, intptr_t, QDeclarativeNotifier **n)
+#ifdef FOCUS_DEBUG
+void printFocusTree(QQuickItem *item, QQuickItem *scope = 0, int depth = 1);
+void printFocusTree(QQuickItem *item, QQuickItem *scope, int depth)
+{
+    qWarning()
+            << QByteArray(depth, '\t').constData()
+            << (scope && QQuickItemPrivate::get(scope)->subFocusItem == item ? '*' : ' ')
+            << item->hasFocus()
+            << item->hasActiveFocus()
+            << item->isFocusScope()
+            << item;
+    foreach (QQuickItem *child, item->childItems()) {
+        printFocusTree(
+                child,
+                item->isFocusScope() || !scope ? item : scope,
+                item->isFocusScope() || !scope ? depth + 1 : depth);
+    }
+}
+#endif
+
+static void QQuickItem_parentNotifier(QObject *o, intptr_t, QQmlNotifier **n)
 {
     QQuickItemPrivate *d = QQuickItemPrivate::get(static_cast<QQuickItem *>(o));
     *n = &d->parentNotifier;
@@ -86,11 +107,11 @@ QML_PRIVATE_ACCESSOR(QQuickItem, qreal, y, y)
 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, width, width)
 QML_PRIVATE_ACCESSOR(QQuickItem, qreal, height, height)
 
-static QDeclarativeAccessors QQuickItem_parent = { QQuickItem_parentRead, QQuickItem_parentNotifier };
-static QDeclarativeAccessors QQuickItem_x = { QQuickItem_xRead, 0 };
-static QDeclarativeAccessors QQuickItem_y = { QQuickItem_yRead, 0 };
-static QDeclarativeAccessors QQuickItem_width = { QQuickItem_widthRead, 0 };
-static QDeclarativeAccessors QQuickItem_height = { QQuickItem_heightRead, 0 };
+static QQmlAccessors QQuickItem_parent = { QQuickItem_parentRead, QQuickItem_parentNotifier };
+static QQmlAccessors QQuickItem_x = { QQuickItem_xRead, 0 };
+static QQmlAccessors QQuickItem_y = { QQuickItem_yRead, 0 };
+static QQmlAccessors QQuickItem_width = { QQuickItem_widthRead, 0 };
+static QQmlAccessors QQuickItem_height = { QQuickItem_heightRead, 0 };
 
 QML_DECLARE_PROPERTIES(QQuickItem) {
     { QML_PROPERTY_NAME(parent), 0, &QQuickItem_parent },
@@ -109,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
@@ -131,7 +152,7 @@ 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.
 
@@ -173,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
@@ -215,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.
@@ -233,7 +254,7 @@ void QQuickItemPrivate::registerAccessorProperties()
     rotations you must specify the axis to rotate around in addition to the origin point.
 
     The following example shows various 3D-like rotations applied to an \l Image.
-    \snippet doc/src/snippets/declarative/rotation.qml 0
+    \snippet doc/snippets/qml/rotation.qml 0
 
     \image axisrotation.png
 
@@ -442,8 +463,8 @@ QQuickItemKeyFilter::QQuickItemKeyFilter(QQuickItem *item)
 {
     QQuickItemPrivate *p = item?QQuickItemPrivate::get(item):0;
     if (p) {
-        m_next = p->keyHandler;
-        p->keyHandler = this;
+        m_next = p->extra.value().keyHandler;
+        p->extra->keyHandler = this;
     }
 }
 
@@ -483,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
@@ -491,7 +512,7 @@ void QQuickItemKeyFilter::componentComplete()
 
     The following example provides key navigation for a 2x2 grid of items:
 
-    \snippet doc/src/snippets/declarative/keynavigation.qml 0
+    \snippet 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
@@ -545,7 +566,7 @@ void QQuickItemKeyFilter::componentComplete()
 
 QQuickKeyNavigationAttached::QQuickKeyNavigationAttached(QObject *parent)
 : QObject(*(new QQuickKeyNavigationAttachedPrivate), parent),
-  QQuickItemKeyFilter(qobject_cast<QQuickItem*>(parent))
+  QQuickItemKeyFilter(qmlobject_cast<QQuickItem*>(parent))
 {
     m_processPost = true;
 }
@@ -695,10 +716,10 @@ void QQuickKeyNavigationAttached::setBacktab(QQuickItem *i)
     or after the attached item's own key handling.
 
     \list
-    \o KeyNavigation.BeforeItem - process the key events before normal
+    \li KeyNavigation.BeforeItem - process the key events before normal
     item key processing.  If the event is used for key navigation, it will be accepted and will not
     be passed on to the item.
-    \o KeyNavigation.AfterItem (default) - process the key events after normal item key
+    \li KeyNavigation.AfterItem (default) - process the key events after normal item key
     handling.  If the item accepts the key event it will not be
     handled by the KeyNavigation attached property handler.
     \endlist
@@ -886,16 +907,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
@@ -912,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.
 
@@ -932,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
@@ -969,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
@@ -1280,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()
@@ -1348,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);
@@ -1441,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)
@@ -1460,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
 
@@ -1505,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");
 }
@@ -1579,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);
         }
@@ -1598,8 +1623,8 @@ void QQuickItemPrivate::setLayoutMirror(bool mirror)
             emit _anchors->mirroredChanged();
         }
         mirrorChange();
-        if (attachedLayoutDirection) {
-            emit attachedLayoutDirection->enabledChanged();
+        if (extra.isAllocated() && extra->layoutDirectionAttached) {
+            emit extra->layoutDirectionAttached->enabledChanged();
         }
     }
 }
@@ -1612,30 +1637,86 @@ void QQuickItemPrivate::setAccessibleFlagAndListener()
         if (item->d_func()->isAccessible)
             break; // already set - grandparents should have the flag set as well.
 
-        if (item->canvas() && item->canvas()->rootItem() == item)
-            break; // don't add a listener to the canvas root item
-
         item->d_func()->isAccessible = true;
         item = item->d_func()->parentItem;
     }
 }
 
+void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
+{
+    Q_Q(QQuickItem);
+    Q_ASSERT(scope);
+
+    QQuickItemPrivate *scopePrivate = QQuickItemPrivate::get(scope);
+
+    QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem;
+    // Correct focus chain in scope
+    if (oldSubFocusItem) {
+        QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
+        while (sfi && sfi != scope) {
+            QQuickItemPrivate::get(sfi)->subFocusItem = 0;
+            sfi = sfi->parentItem();
+        }
+    }
+
+    if (focus) {
+        scopePrivate->subFocusItem = q;
+        QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
+        while (sfi && sfi != scope) {
+            QQuickItemPrivate::get(sfi)->subFocusItem = q;
+            sfi = sfi->parentItem();
+        }
+    } else {
+        scopePrivate->subFocusItem = 0;
+    }
+}
+
+
 /*!
     \class QQuickItem
-    \brief The QQuickItem class provides the most basic of all visual items in QML.
+    \brief 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
 */
 
 /*!
@@ -1643,9 +1724,9 @@ void QQuickItemPrivate::setAccessibleFlagAndListener()
     \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.
@@ -1793,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);
@@ -1824,11 +1908,14 @@ QQuickItem::~QQuickItem()
     }
 
     d->changeListeners.clear();
-    delete d->_anchorLines; d->_anchorLines = 0;
+
+    if (d->extra.isAllocated()) {
+        delete d->extra->contents; d->extra->contents = 0;
+        delete d->extra->layer; d->extra->layer = 0;
+    }
+
     delete d->_anchors; d->_anchors = 0;
     delete d->_stateGroup; d->_stateGroup = 0;
-    delete d->_contents; d->_contents = 0;
-    delete d->_layer;
 }
 
 /*!
@@ -1890,19 +1977,24 @@ 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);
@@ -1913,35 +2005,57 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
         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(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);
+                }
+            }
         }
     }
 
@@ -2030,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);
@@ -2055,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;
         }
@@ -2118,78 +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);
-        if (!parentItem)
-            c->parentlessItems.remove(q);
+    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 && canvas)
+    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);
 
-    if (screenAttached)
-        screenAttached->canvasChanged(c);
-    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.
 */
@@ -2225,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());
     }
 }
@@ -2290,10 +2435,9 @@ 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),
@@ -2301,23 +2445,17 @@ QQuickItemPrivate::QQuickItemPrivate()
   staticSubtreeGeometry(false),
   isAccessible(false),
 
-  canvas(0), parentItem(0), sortedChildItems(&childItems),
+  dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
+
+  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::ImhNone),
+  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)
-  , screenAttached(0), _layer(0)
+  itemNodeInstance(0), groupNode(0), paintNode(0)
 {
 }
 
@@ -2342,7 +2480,7 @@ void QQuickItemPrivate::init(QQuickItem *parent)
 
     registerAccessorProperties();
 
-    baselineOffset.invalidate();
+    baselineOffsetValid = false;
 
     if (parent) {
         q->setParentItem(parent);
@@ -2351,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"))
@@ -2410,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);
@@ -2425,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())
@@ -2440,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();
@@ -2459,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)
@@ -2468,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;
@@ -2480,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);
@@ -2494,13 +2625,13 @@ void QQuickItemPrivate::children_clear(QDeclarativeListProperty<QQuickItem> *pro
         p->childItems.at(0)->setParentItem(0);
 }
 
-void QQuickItemPrivate::visibleChildren_append(QDeclarativeListProperty<QQuickItem>*, QQuickItem *self)
+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(QDeclarativeListProperty<QQuickItem> *prop)
+int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop)
 {
     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
     int visibleCount = 0;
@@ -2512,7 +2643,7 @@ int QQuickItemPrivate::visibleChildren_count(QDeclarativeListProperty<QQuickItem
     return visibleCount;
 }
 
-QQuickItem *QQuickItemPrivate::visibleChildren_at(QDeclarativeListProperty<QQuickItem> *prop, int index)
+QQuickItem *QQuickItemPrivate::visibleChildren_at(QQmlListProperty<QQuickItem> *prop, int index)
 {
     QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object));
     const int childCount = p->childItems.count();
@@ -2527,10 +2658,12 @@ QQuickItem *QQuickItemPrivate::visibleChildren_at(QDeclarativeListProperty<QQuic
     return 0;
 }
 
-int QQuickItemPrivate::transform_count(QDeclarativeListProperty<QQuickTransform> *prop)
+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)
@@ -2571,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;
@@ -2580,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);
@@ -2591,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);
@@ -2609,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.
 */
@@ -2641,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 {
@@ -2656,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 {
@@ -2672,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 {
@@ -2687,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 {
@@ -2753,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.
@@ -2766,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 {
@@ -2784,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.
 
@@ -2813,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}.
@@ -2820,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
@@ -2839,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);
@@ -2858,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);
@@ -2869,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
@@ -2941,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 *)
@@ -2959,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;
@@ -2968,8 +3147,9 @@ void QQuickItem::updatePolish()
 {
 }
 
-void QQuickItem::sendAccessibilityUpdate()
+void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
 {
+    changeListeners.append(ChangeListener(listener, types));
 }
 
 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
@@ -2988,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) {
@@ -3017,7 +3198,10 @@ void QQuickItem::inputMethodEvent(QInputMethodEvent *event)
 
 void QQuickItem::focusInEvent(QFocusEvent *)
 {
-    QAccessible::updateAccessibility(QAccessibleEvent(QAccessible::Focus, this, 0));
+#ifndef QT_NO_ACCESSIBILITY
+    QAccessibleEvent ev(this, QAccessible::Focus);
+    QAccessible::updateAccessibility(&ev);
+#endif
 }
 
 void QQuickItem::focusOutEvent(QFocusEvent *)
@@ -3039,9 +3223,8 @@ void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
     event->ignore();
 }
 
-void QQuickItem::mouseDoubleClickEvent(QMouseEvent *event)
+void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
 {
-    mousePressEvent(event);
 }
 
 void QQuickItem::mouseUngrabEvent()
@@ -3113,24 +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;
-
-    if (qApp->focusObject() == this)
-        qApp->inputMethod()->update(Qt::ImHints);
-}
-
 QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
 {
     Q_D(const QQuickItem);
@@ -3141,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:
@@ -3151,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;
     }
@@ -3162,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)
@@ -3211,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);
@@ -3220,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);
@@ -3244,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];
@@ -3266,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;
+
+            QRectF r = mapRectFromItem(itemObj, QRectF(x, y, w, h));
+
+            rv->Set(v8::String::New("x"), v8::Number::New(r.x()));
+            rv->Set(v8::String::New("y"), v8::Number::New(r.y()));
+            rv->Set(v8::String::New("width"), v8::Number::New(r.width()));
+            rv->Set(v8::String::New("height"), v8::Number::New(r.height()));
+        } else {
+            QPointF p = mapFromItem(itemObj, QPointF(x, y));
 
-        rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
-        rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
+            rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
+            rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
+        }
     }
 }
 
@@ -3287,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];
@@ -3309,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()));
+        }
     }
 }
 
@@ -3343,17 +3575,17 @@ 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);
@@ -3366,20 +3598,20 @@ QDeclarativeListProperty<QQuickItem> QQuickItemPrivate::children()
   Note that a child's visibility may have changed explicitly, or because the visibility
   of this (it's parent) item or another grandparent changed.
 */
-QDeclarativeListProperty<QQuickItem> QQuickItemPrivate::visibleChildren()
+QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren()
 {
-    return QDeclarativeListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append,
+    return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append,
                                              QQuickItemPrivate::visibleChildren_count,
                                              QQuickItemPrivate::visibleChildren_at);
 
 }
 
-QDeclarativeListProperty<QDeclarativeState> QQuickItemPrivate::states()
+QQmlListProperty<QQuickState> QQuickItemPrivate::states()
 {
     return _states()->statesProperty();
 }
 
-QDeclarativeListProperty<QDeclarativeTransition> QQuickItemPrivate::transitions()
+QQmlListProperty<QQuickTransition> QQuickItemPrivate::transitions()
 {
     return _states()->transitionsProperty();
 }
@@ -3409,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);
@@ -3425,8 +3657,8 @@ void QQuickItem::classBegin()
         d->_stateGroup->classBegin();
     if (d->_anchors)
         d->_anchors->classBegin();
-    if (d->_layer)
-        d->_layer->classBegin();
+    if (d->extra.isAllocated() && d->extra->layer)
+        d->extra->layer->classBegin();
 }
 
 void QQuickItem::componentComplete()
@@ -3440,50 +3672,33 @@ void QQuickItem::componentComplete()
         QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
     }
 
-    if (d->_layer)
-        d->_layer->componentComplete();
+    if (d->extra.isAllocated() && d->extra->layer)
+        d->extra->layer->componentComplete();
+
+    if (d->extra.isAllocated() && d->extra->keyHandler)
+        d->extra->keyHandler->componentComplete();
 
-    if (d->keyHandler)
-        d->keyHandler->componentComplete();
-    if (d->_contents)
-        d->_contents->complete();
+    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);
@@ -3508,8 +3723,8 @@ QPointF QQuickItemPrivate::computeTransformOrigin() const
 
 void QQuickItemPrivate::transformChanged()
 {
-    if (_layer)
-        _layer->updateMatrix();
+    if (extra.isAllocated() && extra->layer)
+        extra->layer->updateMatrix();
 }
 
 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
@@ -3517,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;
@@ -3537,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);
     }
 }
 
@@ -3552,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;
@@ -3566,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);
     }
 }
 
@@ -3676,62 +3891,69 @@ void QQuickItem::updateInputMethod(Qt::InputMethodQueries 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) {
@@ -3741,8 +3963,8 @@ void QQuickItem::setZ(qreal v)
 
     emit zChanged();
 
-    if (d->_layer)
-        d->_layer->updateZ();
+    if (d->extra.isAllocated() && d->extra->layer)
+        d->extra->layer->updateZ();
 }
 
 
@@ -3755,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"
@@ -3789,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"
@@ -3826,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 {
@@ -3841,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 {
@@ -3875,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);
 
@@ -3896,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);
 
@@ -3915,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);
 
@@ -3946,6 +4168,8 @@ void QQuickItem::setVisible(bool v)
         return;
 
     d->explicitVisible = v;
+    if (!v)
+        d->dirty(QQuickItemPrivate::Visible);
 
     const bool childVisibilityChanged = d->setEffectiveVisibleRecur(d->calcEffectiveVisible());
     if (childVisibilityChanged && d->parentItem)
@@ -4009,15 +4233,13 @@ bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
     for (int ii = 0; ii < childItems.count(); ++ii)
         childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
 
-    for (int ii = 0; ii < changeListeners.count(); ++ii) {
-        const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii);
-        if (change.types & QQuickItemPrivate::Visibility)
-            change.listener->itemVisibilityChanged(q);
+    itemChange(QQuickItem::ItemVisibleHasChanged, effectiveVisible);
+#ifndef QT_NO_ACCESSIBILITY
+    if (isAccessible) {
+        QAccessibleEvent ev(q, effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide);
+        QAccessible::updateAccessibility(&ev);
     }
-
-    if (isAccessible)
-        QAccessible::updateAccessibility(QAccessibleEvent(effectiveVisible ? QAccessible::ObjectShow : QAccessible::ObjectHide, q, 0));
-
+#endif
     emit q->visibleChanged();
     if (childVisibilityChanged)
         emit q->visibleChildrenChanged();
@@ -4061,7 +4283,7 @@ void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffec
 
     for (int ii = 0; ii < childItems.count(); ++ii) {
         QQuickItemPrivate::get(childItems.at(ii))->setEffectiveEnableRecur(
-                flags & QQuickItem::ItemIsFocusScope ? q : scope, newEffectiveEnable);
+                (flags & QQuickItem::ItemIsFocusScope) && scope ? q : scope, newEffectiveEnable);
     }
 
     if (canvas && scope && effectiveEnable && focus) {
@@ -4152,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);
     }
 }
@@ -4246,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
+
+    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.
 
-    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.
+    In Qt Quick 2.0, this property has minimal impact on performance.
 
-    By default smooth transformations are off.
+    By default is true.
 */
 
 /*!
@@ -4423,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();
 }
 
@@ -4470,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.
 */
 
@@ -4486,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;
@@ -4545,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();
 }
 
@@ -4575,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;
@@ -4604,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;
@@ -4679,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);
@@ -4712,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
@@ -4739,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
@@ -4768,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()
@@ -4784,7 +5052,9 @@ void QQuickItem::ungrabMouse()
     }
 
     canvasPriv->mouseGrabberItem = 0;
-    mouseUngrabEvent();
+
+    QEvent ev(QEvent::UngrabMouse);
+    d->canvas->sendEvent(this, &ev);
 }
 
 bool QQuickItem::keepMouseGrab() const
@@ -4906,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);
@@ -5404,7 +5672,8 @@ qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
 bool QQuickItem::isTextureProvider() const
 {
     Q_D(const QQuickItem);
-    return d->_layer && d->_layer->effectSource() ? d->_layer->effectSource()->isTextureProvider() : false;
+    return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
+           d->extra->layer->effectSource()->isTextureProvider() : false;
 }
 
 /*!
@@ -5419,23 +5688,20 @@ bool QQuickItem::isTextureProvider() const
 QSGTextureProvider *QQuickItem::textureProvider() const
 {
     Q_D(const QQuickItem);
-    return d->_layer && d->_layer->effectSource() ? d->_layer->effectSource()->textureProvider() : 0;
+    return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
+           d->extra->layer->effectSource()->textureProvider() : 0;
 }
 
-
-
 QQuickItemLayer *QQuickItemPrivate::layer() const
 {
-    if (!_layer) {
-        _layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
+    if (!extra.isAllocated() || !extra->layer) {
+        extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
         if (!componentComplete)
-            _layer->classBegin();
+            extra->layer->classBegin();
     }
-    return _layer;
+    return extra->layer;
 }
 
-
-
 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
     : m_item(item)
     , m_enabled(false)
@@ -5556,10 +5822,11 @@ void QQuickItemLayer::activateEffect()
     Q_ASSERT(m_effectComponent);
     Q_ASSERT(!m_effect);
 
-    QObject *created = m_effectComponent->create();
+    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;
     }
@@ -5570,6 +5837,7 @@ void QQuickItemLayer::activateEffect()
     }
     m_effect->setVisible(m_item->isVisible());
     m_effect->setProperty(m_name, qVariantFromValue<QObject *>(m_effectSource));
+    m_effectComponent->completeCreate();
 }
 
 void QQuickItemLayer::deactivateEffect()
@@ -5593,7 +5861,7 @@ void QQuickItemLayer::deactivateEffect()
     \sa samplerName
  */
 
-void QQuickItemLayer::setEffect(QDeclarativeComponent *component)
+void QQuickItemLayer::setEffect(QQmlComponent *component)
 {
     if (component == m_effectComponent)
         return;
@@ -5654,9 +5922,9 @@ void QQuickItemLayer::setMipmap(bool mipmap)
     allow you to save some texture memory.
 
     \list
-    \o ShaderEffectSource.Alpha - GL_ALPHA
-    \o ShaderEffectSource.RGB - GL_RGB
-    \o ShaderEffectSource.RGBA - GL_RGBA
+    \li ShaderEffectSource.Alpha - GL_ALPHA
+    \li ShaderEffectSource.RGB - GL_RGB
+    \li ShaderEffectSource.RGBA - GL_RGBA
     \endlist
 
     \note Some OpenGL implementations do not support the GL_ALPHA format.
@@ -5751,10 +6019,10 @@ void QQuickItemLayer::setSize(const QSize &size)
     specified.
 
     \list
-    \o ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
-    \o ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
-    \o ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
-    \o ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
+    \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically
+    \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically
+    \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically
+    \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically
     \endlist
 
     \note Some OpenGL ES 2 implementations do not support the GL_REPEAT
@@ -5763,7 +6031,7 @@ void QQuickItemLayer::setSize(const QSize &size)
 
 void QQuickItemLayer::setWrapMode(QQuickShaderEffectSource::WrapMode mode)
 {
-    if (mode != m_wrapMode)
+    if (mode == m_wrapMode)
         return;
     m_wrapMode = mode;
 
@@ -5858,7 +6126,7 @@ void QQuickItemLayer::updateGeometry()
 {
     QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
     Q_ASSERT(l);
-    QRectF bounds = m_item->boundingRect();
+    QRectF bounds = m_item->clipRect();
     l->setWidth(bounds.width());
     l->setHeight(bounds.height());
     l->setX(bounds.x() + m_item->x());
@@ -5877,10 +6145,20 @@ void QQuickItemLayer::updateMatrix()
     l->setScale(m_item->scale());
     l->setRotation(m_item->rotation());
     ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
-    ld->origin = QQuickItemPrivate::get(m_item)->origin;
+    if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
+        ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
     ld->dirty(QQuickItemPrivate::Transform);
 }
 
+QQuickItemPrivate::ExtraData::ExtraData()
+: z(0), scale(1), rotation(0), opacity(1),
+  contents(0), screenAttached(0), layoutDirectionAttached(0),
+  keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
+  opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
+  acceptedMouseButtons(0), origin(QQuickItem::Center)
+{
+}
+
 QT_END_NAMESPACE
 
 #include <moc_qquickitem.cpp>