Doc: Sanitized QML types
[profile/ivi/qtdeclarative.git] / src / quick / items / qquickitem.cpp
index cb41add..47bfc98 100644 (file)
@@ -52,8 +52,8 @@
 #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>
 
 QT_BEGIN_NAMESPACE
 
+#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));
@@ -110,7 +130,7 @@ 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:
@@ -132,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.
 
@@ -174,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
@@ -216,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.
@@ -234,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/qml/rotation.qml 0
+    \snippet doc/snippets/qml/rotation.qml 0
 
     \image axisrotation.png
 
@@ -484,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
@@ -492,7 +512,7 @@ void QQuickItemKeyFilter::componentComplete()
 
     The following example provides key navigation for a 2x2 grid of items:
 
-    \snippet doc/src/snippets/qml/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
@@ -546,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;
 }
@@ -887,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
@@ -913,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/qml/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/qml/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.
 
@@ -1281,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()
@@ -1349,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);
@@ -1442,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)
@@ -1461,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/qml/layoutmirroring.qml 0
+    \snippet doc/snippets/qml/layoutmirroring.qml 0
 
     \image layoutmirroring.png
 
@@ -1580,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);
         }
@@ -1613,9 +1637,6 @@ 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;
     }
@@ -1632,7 +1653,7 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
     // Correct focus chain in scope
     if (oldSubFocusItem) {
         QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
-        while (sfi != scope) {
+        while (sfi && sfi != scope) {
             QQuickItemPrivate::get(sfi)->subFocusItem = 0;
             sfi = sfi->parentItem();
         }
@@ -1641,7 +1662,7 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
     if (focus) {
         scopePrivate->subFocusItem = q;
         QQuickItem *sfi = scopePrivate->subFocusItem->parentItem();
-        while (sfi != scope) {
+        while (sfi && sfi != scope) {
             QQuickItemPrivate::get(sfi)->subFocusItem = q;
             sfi = sfi->parentItem();
         }
@@ -1653,7 +1674,7 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
 
 /*!
     \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
 
@@ -1662,11 +1683,40 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
     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
 */
 
 /*!
@@ -1674,7 +1724,7 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
     \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 Quick inherit from Item.  Although Item
     has no visual appearance, it defines all the properties that are
@@ -1824,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);
@@ -1924,17 +1977,23 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
 
         QQuickItem *scopeItem = 0;
 
-        if (d->canvas && hasFocus()) {
+        if (hasFocus())
             scopeFocusedItem = this;
-        } else if (d->canvas && !isFocusScope() && d->subFocusItem) {
+        else if (!isFocusScope() && d->subFocusItem)
             scopeFocusedItem = d->subFocusItem;
-        }
 
         if (scopeFocusedItem) {
             scopeItem = oldParentItem;
-            while (!scopeItem->isFocusScope()) scopeItem = scopeItem->parentItem();
-            QQuickCanvasPrivate::get(d->canvas)->clearFocusInScope(scopeItem, scopeFocusedItem,
+            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();
@@ -1946,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);
+                }
+            }
         }
     }
 
@@ -2063,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);
@@ -2158,30 +2234,82 @@ QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *it
     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);
 
+    InitializationState _dummy;
+    InitializationState *childState = state;
+
+    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)->refCanvas(childState, c);
+    }
+
+    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()) {
@@ -2194,39 +2322,19 @@ void QQuickItemPrivate::initCanvas(InitializationState *state, QQuickCanvas *c)
     groupNode = 0;
     paintNode = 0;
 
-    InitializationState _dummy;
-    InitializationState *childState = state;
-
-    if (c && q->isFocusScope()) {
-        _dummy.clear(q);
-        childState = &_dummy;
-    }
-
-    if (!parentItem && canvas)
-        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);
-    }
-
-    if (c && focus) {
-        // Fixup
-        if (state->getFocusScope(q)->scopedFocusItem()) {
-            focus = false;
-            emit q->focusChanged(false);
-        } else {
-            QQuickCanvasPrivate::get(canvas)->setFocusInScope(state->getFocusScope(q), q);
-        }
+        QQuickItemPrivate::get(child)->derefCanvas();
     }
 
     dirty(Canvas);
 
     if (extra.isAllocated() && extra->screenAttached)
-        extra->screenAttached->canvasChanged(c);
-    itemChange(QQuickItem::ItemSceneChange, c);
+        extra->screenAttached->canvasChanged(0);
+    itemChange(QQuickItem::ItemSceneChange, (QQuickCanvas *)0);
 }
 
+
 /*!
 Returns a transform that maps points from canvas space into item space.
 */
@@ -2329,7 +2437,7 @@ bool QQuickItem::isComponentComplete() const
 QQuickItemPrivate::QQuickItemPrivate()
 : _anchors(0), _stateGroup(0),
   flags(0), widthValid(false), heightValid(false), baselineOffsetValid(false), componentComplete(true),
-  keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(false), focus(false), activeFocus(false), notifiedFocus(false),
+  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),
@@ -2339,7 +2447,7 @@ QQuickItemPrivate::QQuickItemPrivate()
 
   dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
 
-  canvas(0), parentItem(0), sortedChildItems(&childItems),
+  canvas(0), canvasRefCount(0), parentItem(0), sortedChildItems(&childItems),
 
   subFocusItem(0),
 
@@ -2388,14 +2496,7 @@ void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
 
     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"))
@@ -2641,7 +2742,7 @@ void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
 
 /*!
     \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.
 */
@@ -2785,6 +2886,7 @@ void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
   \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.
@@ -2845,6 +2947,13 @@ void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
 
   \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}.
@@ -2852,7 +2961,7 @@ void QQuickItemPrivate::transform_clear(QQmlListProperty<QQuickTransform> *prop)
 
 /*!
   \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
@@ -2965,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 *)
@@ -2983,16 +3121,29 @@ QSGNode *QQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
     return 0;
 }
 
-QSGTransformNode *QQuickItemPrivate::createTransformNode()
+/*!
+    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()
 {
-    return new QSGTransformNode;
 }
 
-void QQuickItem::updatePolish()
+QSGTransformNode *QQuickItemPrivate::createTransformNode()
 {
+    return new QSGTransformNode;
 }
 
-void QQuickItem::sendAccessibilityUpdate()
+void QQuickItem::updatePolish()
 {
 }
 
@@ -3047,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 *)
@@ -3237,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);
@@ -3261,6 +3430,17 @@ void QQuickItem::polish()
     }
 }
 
+/*!
+    \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) {
@@ -3283,10 +3463,22 @@ void QQuickItem::mapFromItem(QQmlV8Function *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(p.x()));
-        rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
+            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()));
+        }
     }
 }
 
@@ -3304,6 +3496,17 @@ QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const
     return t;
 }
 
+/*!
+    \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) {
@@ -3326,10 +3529,22 @@ void QQuickItem::mapToItem(QQmlV8Function *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;
 
-        rv->Set(v8::String::New("x"), v8::Number::New(p.x()));
-        rv->Set(v8::String::New("y"), v8::Number::New(p.y()));
+            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()));
+        }
     }
 }
 
@@ -3474,8 +3689,8 @@ QQuickStateGroup *QQuickItemPrivate::_states()
         _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;
@@ -3676,13 +3891,20 @@ 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);
@@ -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)
@@ -4010,7 +4234,12 @@ bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
         childVisibilityChanged |= QQuickItemPrivate::get(childItems.at(ii))->setEffectiveVisibleRecur(newEffectiveVisible);
 
     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();
@@ -4054,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) {
@@ -4239,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.
 */
 
 /*!
@@ -4416,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();
 }
 
@@ -4479,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;
@@ -4538,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();
 }
 
@@ -4568,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;
@@ -4597,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;
@@ -4672,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);
@@ -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
@@ -4910,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);
@@ -5558,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;
     }
@@ -5572,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()
@@ -5860,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());