diff --git a/src/quick/items/items.pri b/src/quick/items/items.pri
index b8b4e1104c2f6a3e6bd987d75fd312a08cac5527..4f22b32837e6689e29ad8bf2b0884aeb0eeeb0ac 100644
--- a/src/quick/items/items.pri
+++ b/src/quick/items/items.pri
@@ -23,6 +23,7 @@ HEADERS += \
     $$PWD/qquicktextcontrol_p_p.h \
     $$PWD/qquicktextedit_p.h \
     $$PWD/qquicktextedit_p_p.h \
+    $$PWD/qquicktextutil_p.h \
     $$PWD/qquickimagebase_p.h \
     $$PWD/qquickimagebase_p_p.h \
     $$PWD/qquickimage_p.h \
@@ -91,6 +92,7 @@ SOURCES += \
     $$PWD/qquicktextinput.cpp \
     $$PWD/qquicktextcontrol.cpp \
     $$PWD/qquicktextedit.cpp \
+    $$PWD/qquicktextutil.cpp \
     $$PWD/qquickimagebase.cpp \
     $$PWD/qquickimage.cpp \
     $$PWD/qquickborderimage.cpp \
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index de0cf7cceebed0da941e9175444b4e826cc045d3..cfb07f019b35b9cafa9230aa0f31b488f924a711 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -46,6 +46,7 @@
 #include "qquickevents_p_p.h"
 #include "qquickcanvas.h"
 #include "qquicktextnode_p.h"
+#include "qquicktextutil_p.h"
 #include <QtQuick/qsgsimplerectnode.h>
 
 #include <QtQml/qqmlinfo.h>
@@ -60,6 +61,7 @@
 #include <private/qtextengine_p.h>
 #include <private/qsgadaptationlayer_p.h>
 
+
 QT_BEGIN_NAMESPACE
 
 /*!
@@ -360,8 +362,8 @@ void QQuickTextEdit::setFont(const QFont &font)
 
     if (oldFont != d->font) {
         d->document->setDefaultFont(d->font);
-        if (d->cursor) {
-            d->cursor->setHeight(QFontMetrics(d->font).height());
+        if (d->cursorItem) {
+            d->cursorItem->setHeight(QFontMetrics(d->font).height());
             moveCursorDelegate();
         }
         updateSize();
@@ -890,6 +892,8 @@ void QQuickTextEdit::setCursorVisible(bool on)
     if (d->cursorVisible == on)
         return;
     d->cursorVisible = on;
+    if (on && isComponentComplete())
+        QQuickTextUtil::createCursor(d);
     if (!on && !d->persistentSelection)
         d->control->setCursorIsFocusIndicator(true);
     d->control->setCursorVisible(on);
@@ -941,45 +945,14 @@ QQmlComponent* QQuickTextEdit::cursorDelegate() const
 void QQuickTextEdit::setCursorDelegate(QQmlComponent* c)
 {
     Q_D(QQuickTextEdit);
-    if (d->cursorComponent) {
-        if (d->cursor) {
-            d->control->setCursorWidth(-1);
-            updateCursor();
-            delete d->cursor;
-            d->cursor = 0;
-        }
-    }
-    d->cursorComponent = c;
-    if (c && c->isReady()) {
-        loadCursorDelegate();
-    } else {
-        if (c)
-            connect(c, SIGNAL(statusChanged()),
-                    this, SLOT(loadCursorDelegate()));
-    }
-
-    emit cursorDelegateChanged();
+    QQuickTextUtil::setCursorDelegate(d, c);
 }
 
-void QQuickTextEdit::loadCursorDelegate()
+void QQuickTextEdit::createCursor()
 {
     Q_D(QQuickTextEdit);
-    if (d->cursorComponent->isLoading() || !isComponentComplete())
-        return;
-    QQmlContext *creationContext = d->cursorComponent->creationContext();
-    QObject *object = d->cursorComponent->create(creationContext ? creationContext : qmlContext(this));
-    d->cursor = qobject_cast<QQuickItem*>(object);
-    if (d->cursor) {
-        d->control->setCursorWidth(0);
-        updateCursor();
-        QQml_setParent_noEvent(d->cursor, this);
-        d->cursor->setParentItem(this);
-        d->cursor->setHeight(QFontMetrics(d->font).height());
-        moveCursorDelegate();
-    }else{
-        delete object;
-        qmlInfo(this) << "Error loading cursor delegate.";
-    }
+    d->cursorPending = true;
+    QQuickTextUtil::createCursor(d);
 }
 
 /*!
@@ -1187,8 +1160,8 @@ void QQuickTextEdit::componentComplete()
         updateSize();
         d->dirty = false;
     }
-    if (d->cursorComponent && d->cursorComponent->isReady())
-        loadCursorDelegate();
+    if (d->cursorComponent && isCursorVisible())
+        QQuickTextUtil::createCursor(d);
 }
 /*!
     \qmlproperty bool QtQuick2::TextEdit::selectByMouse
@@ -1818,11 +1791,11 @@ void QQuickTextEdit::moveCursorDelegate()
     d->determineHorizontalAlignment();
     updateInputMethod();
     emit cursorRectangleChanged();
-    if (!d->cursor)
+    if (!d->cursorItem)
         return;
     QRectF cursorRect = cursorRectangle();
-    d->cursor->setX(cursorRect.x());
-    d->cursor->setY(cursorRect.y());
+    d->cursorItem->setX(cursorRect.x());
+    d->cursorItem->setY(cursorRect.y());
 }
 
 void QQuickTextEdit::updateSelectionMarkers()
@@ -1843,7 +1816,7 @@ QRectF QQuickTextEdit::boundingRect() const
     Q_D(const QQuickTextEdit);
     QRectF r(0, -d->yoff, d->contentSize.width(), d->contentSize.height());
     int cursorWidth = 1;
-    if (d->cursor)
+    if (d->cursorItem)
         cursorWidth = 0;
     else if (!d->document->isEmpty())
         cursorWidth += 3;// ### Need a better way of accounting for space between char and cursor
@@ -1885,8 +1858,8 @@ QRectF QQuickTextEdit::clipRect() const
     Q_D(const QQuickTextEdit);
     QRectF r = QQuickImplicitSizeItem::clipRect();
     int cursorWidth = 1;
-    if (d->cursor)
-        cursorWidth = d->cursor->width();
+    if (d->cursorItem)
+        cursorWidth = d->cursorItem->width();
     if (!d->document->isEmpty())
         cursorWidth += 3;// ### Need a better way of accounting for space between char and cursor
 
diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h
index 9f904cae67b557a49968cc03595badca1f7f75f9..48954cc7d6bd8c2a01a6b7a47d15e16152e10e3f 100644
--- a/src/quick/items/qquicktextedit_p.h
+++ b/src/quick/items/qquicktextedit_p.h
@@ -290,7 +290,7 @@ private Q_SLOTS:
     void q_textChanged();
     void updateSelectionMarkers();
     void moveCursorDelegate();
-    void loadCursorDelegate();
+    void createCursor();
     void q_canPasteChanged();
     void updateDocument();
     void updateCursor();
@@ -320,6 +320,8 @@ protected:
 
     QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData);
 
+    friend class QQuickTextUtil;
+
 private:
     Q_DISABLE_COPY(QQuickTextEdit)
     Q_DECLARE_PRIVATE(QQuickTextEdit)
diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h
index e556367bcf33686853cb8af06281b37604e38d9c..1fb82110ea73b34aee06b36471ca0fdeca9c47ce 100644
--- a/src/quick/items/qquicktextedit_p_p.h
+++ b/src/quick/items/qquicktextedit_p_p.h
@@ -55,6 +55,7 @@
 
 #include "qquicktextedit_p.h"
 #include "qquickimplicitsizeitem_p_p.h"
+#include "qquicktextcontrol_p.h"
 
 #include <QtQml/qqml.h>
 
@@ -64,19 +65,21 @@ class QQuickTextDocumentWithImageResources;
 class QQuickTextControl;
 class QQuickTextEditPrivate : public QQuickImplicitSizeItemPrivate
 {
+public:
     Q_DECLARE_PUBLIC(QQuickTextEdit)
 
-public:
+    typedef QQuickTextEdit Public;
+
     QQuickTextEditPrivate()
         : color(QRgb(0xFF000000)), selectionColor(QRgb(0xFF000080)), selectedTextColor(QRgb(0xFFFFFFFF))
-        , textMargin(0.0), yoff(0), font(sourceFont), cursorComponent(0), cursor(0), document(0), control(0)
+        , textMargin(0.0), yoff(0), font(sourceFont), cursorComponent(0), cursorItem(0), document(0), control(0)
         , lastSelectionStart(0), lastSelectionEnd(0), lineCount(0)
         , hAlign(QQuickTextEdit::AlignLeft), vAlign(QQuickTextEdit::AlignTop)
         , format(QQuickTextEdit::PlainText), wrapMode(QQuickTextEdit::NoWrap)
         , contentDirection(Qt::LayoutDirectionAuto)
         , mouseSelectionMode(QQuickTextEdit::SelectCharacters), inputMethodHints(Qt::ImhNone)
         , updateType(UpdatePaintNode)
-        , documentDirty(true), dirty(false), richText(false), cursorVisible(false)
+        , documentDirty(true), dirty(false), richText(false), cursorVisible(false), cursorPending(false)
         , focusOnPress(true), persistentSelection(false), requireImplicitWidth(false)
         , selectByMouse(false), canPaste(false), canPasteValid(false), hAlignImplicit(true)
         , textCached(false), inLayout(false)
@@ -96,6 +99,8 @@ public:
     qreal getImplicitWidth() const;
     Qt::LayoutDirection textDirection(const QString &text) const;
 
+    void setNativeCursorEnabled(bool enabled) { control->setCursorWidth(enabled ? 1 : 0); }
+
     QColor color;
     QColor selectionColor;
     QColor selectedTextColor;
@@ -111,7 +116,7 @@ public:
     QFont font;
 
     QQmlComponent* cursorComponent;
-    QQuickItem* cursor;
+    QQuickItem* cursorItem;
     QQuickTextDocumentWithImageResources *document;
     QQuickTextControl *control;
 
@@ -138,6 +143,7 @@ public:
     bool dirty : 1;
     bool richText : 1;
     bool cursorVisible : 1;
+    bool cursorPending : 1;
     bool focusOnPress : 1;
     bool persistentSelection : 1;
     bool requireImplicitWidth:1;
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index e2199347e7295f59d8b1008636b46a9b8f924d93..3e92568db3fdb2d18d793d4e464b97e5ad4f4e9e 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -42,9 +42,11 @@
 #include "qquicktextinput_p.h"
 #include "qquicktextinput_p_p.h"
 #include "qquickcanvas.h"
+#include "qquicktextutil_p.h"
 
 #include <private/qqmlglobal_p.h>
 
+
 #include <QtCore/qcoreapplication.h>
 #include <QtQml/qqmlinfo.h>
 #include <QtGui/qevent.h>
@@ -102,8 +104,8 @@ void QQuickTextInput::componentComplete()
     d->checkIsValid();
     d->updateLayout();
     updateCursorRectangle();
-    if (d->cursorComponent && d->cursorComponent->isReady())
-        createCursor();
+    if (d->cursorComponent && isCursorVisible())
+        QQuickTextUtil::createCursor(d);
 }
 
 /*!
@@ -669,9 +671,13 @@ void QQuickTextInput::setCursorVisible(bool on)
     if (d->cursorVisible == on)
         return;
     d->cursorVisible = on;
-    d->setCursorBlinkPeriod(on ? qApp->styleHints()->cursorFlashTime() : 0);
-    d->updateType = QQuickTextInputPrivate::UpdatePaintNode;
-    update();
+    if (on && isComponentComplete())
+        QQuickTextUtil::createCursor(d);
+    if (!d->cursorItem) {
+        d->setCursorBlinkPeriod(on ? qApp->styleHints()->cursorFlashTime() : 0);
+        d->updateType = QQuickTextInputPrivate::UpdatePaintNode;
+        update();
+    }
     emit cursorVisibleChanged(d->cursorVisible);
 }
 
@@ -1247,65 +1253,14 @@ QQmlComponent* QQuickTextInput::cursorDelegate() const
 void QQuickTextInput::setCursorDelegate(QQmlComponent* c)
 {
     Q_D(QQuickTextInput);
-    if (d->cursorComponent == c)
-        return;
-
-    d->cursorComponent = c;
-    if (!c) {
-        //note that the components are owned by something else
-        delete d->cursorItem;
-        d->cursorItem = 0;
-    } else {
-        d->startCreatingCursor();
-    }
-
-    emit cursorDelegateChanged();
-}
-
-void QQuickTextInputPrivate::startCreatingCursor()
-{
-    Q_Q(QQuickTextInput);
-    if (cursorComponent->isReady()) {
-        q->createCursor();
-    } else if (cursorComponent->isLoading()) {
-        q->connect(cursorComponent, SIGNAL(statusChanged(int)),
-                q, SLOT(createCursor()));
-    } else { // isError
-        qmlInfo(q, cursorComponent->errors()) << QQuickTextInput::tr("Could not load cursor delegate");
-    }
+    QQuickTextUtil::setCursorDelegate(d, c);
 }
 
 void QQuickTextInput::createCursor()
 {
     Q_D(QQuickTextInput);
-    if (!isComponentComplete())
-        return;
-
-    if (d->cursorComponent->isError()) {
-        qmlInfo(this, d->cursorComponent->errors()) << tr("Could not load cursor delegate");
-        return;
-    }
-
-    if (!d->cursorComponent->isReady())
-        return;
-
-    if (d->cursorItem)
-        delete d->cursorItem;
-    QQmlContext *creationContext = d->cursorComponent->creationContext();
-    QObject *object = d->cursorComponent->create(creationContext ? creationContext : qmlContext(this));
-    d->cursorItem = qobject_cast<QQuickItem*>(object);
-    if (!d->cursorItem) {
-        delete object;
-        qmlInfo(this, d->cursorComponent->errors()) << tr("Could not instantiate cursor delegate");
-        return;
-    }
-
-    QRectF r = cursorRectangle();
-
-    QQml_setParent_noEvent(d->cursorItem, this);
-    d->cursorItem->setParentItem(this);
-    d->cursorItem->setPos(r.topLeft());
-    d->cursorItem->setHeight(r.height());
+    d->cursorPending = true;
+    QQuickTextUtil::createCursor(d);
 }
 
 /*!
@@ -3189,10 +3144,9 @@ void QQuickTextInputPrivate::processInputMethodEvent(QInputMethodEvent *event)
     m_textLayout.setPreeditArea(m_cursor, event->preeditString());
 #endif //QT_NO_IM
     const int oldPreeditCursor = m_preeditCursor;
-    const bool oldCursorVisible = cursorVisible;
     m_preeditCursor = event->preeditString().length();
     hasImState = !event->preeditString().isEmpty();
-    cursorVisible = true;
+    bool cursorVisible = true;
     QList<QTextLayout::FormatRange> formats;
     for (int i = 0; i < event->attributes().size(); ++i) {
         const QInputMethodEvent::Attribute &a = event->attributes().at(i);
@@ -3224,8 +3178,7 @@ void QQuickTextInputPrivate::processInputMethodEvent(QInputMethodEvent *event)
     if (isGettingInput)
         finishChange(priorState);
 
-    if (cursorVisible != oldCursorVisible)
-        emit q->cursorVisibleChanged(cursorVisible);
+    q->setCursorVisible(cursorVisible);
 
     if (selectionChange) {
         emit q->selectionChanged();
diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h
index 9a3be0f116ffaabc5151e1972f2e79cee93f8608..a7b07898e86a5afb134f2bbdf345a2c6f77610d4 100644
--- a/src/quick/items/qquicktextinput_p.h
+++ b/src/quick/items/qquicktextinput_p.h
@@ -344,6 +344,8 @@ private Q_SLOTS:
     void triggerPreprocess();
 
 private:
+    friend class QQuickTextUtil;
+
     Q_DECLARE_PRIVATE(QQuickTextInput)
 };
 
diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h
index 34aa0726d32d880ea5e5b7d853a487671a7e6ef8..2648af160d5283b0fac55d59289364baba57727a 100644
--- a/src/quick/items/qquicktextinput_p_p.h
+++ b/src/quick/items/qquicktextinput_p_p.h
@@ -74,8 +74,11 @@ class QQuickTextNode;
 
 class Q_AUTOTEST_EXPORT QQuickTextInputPrivate : public QQuickImplicitSizeItemPrivate
 {
-    Q_DECLARE_PUBLIC(QQuickTextInput)
 public:
+    Q_DECLARE_PUBLIC(QQuickTextInput)
+
+    typedef QQuickTextInput Public;
+
     QQuickTextInputPrivate()
         : hscroll(0)
         , vscroll(0)
@@ -105,6 +108,7 @@ public:
         , m_passwordCharacter(QLatin1Char('*'))
         , focusOnPress(true)
         , cursorVisible(false)
+        , cursorPending(false)
         , autoScroll(true)
         , selectByMouse(false)
         , canPaste(false)
@@ -235,6 +239,7 @@ public:
 
     bool focusOnPress:1;
     bool cursorVisible:1;
+    bool cursorPending:1;
     bool autoScroll:1;
     bool selectByMouse:1;
     bool canPaste:1;
@@ -265,6 +270,8 @@ public:
         return !tripleClickTimer.hasExpired(qApp->styleHints()->mouseDoubleClickInterval());
     }
 
+    void setNativeCursorEnabled(bool enabled) {
+        setCursorBlinkPeriod(enabled && cursorVisible ? qApp->styleHints()->cursorFlashTime() : 0); }
 
     int nextMaskBlank(int pos)
     {
diff --git a/src/quick/items/qquicktextutil.cpp b/src/quick/items/qquicktextutil.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c2c11b3daacc822a265e1db15de6556b6e59c206
--- /dev/null
+++ b/src/quick/items/qquicktextutil.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquicktextutil_p.h"
+
+#include <QtQml/qqmlinfo.h>
+
+#include <private/qqmlglobal_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QQuickItem *QQuickTextUtil::createCursor(
+        QQmlComponent *component, QQuickItem *parent, const QRectF &rectangle, const char *className)
+{
+    QQuickItem *item = 0;
+    if (component->isReady()) {
+        QQmlContext *creationContext = component->creationContext();
+
+        if (QObject *object = component->beginCreate(creationContext
+                ? creationContext
+                : qmlContext(parent))) {
+            if ((item = qobject_cast<QQuickItem *>(object))) {
+                QQml_setParent_noEvent(item, parent);
+                item->setParentItem(parent);
+                item->setPos(rectangle.topLeft());
+                item->setHeight(rectangle.height());
+            } else {
+                qmlInfo(parent) << tr("%1 does not support loading non-visual cursor delegates.")
+                        .arg(QString::fromUtf8(className));
+            }
+            component->completeCreate();
+            return item;
+        }
+    } else if (component->isLoading()) {
+        QObject::connect(component, SIGNAL(statusChanged(QQmlComponent::Status)),
+                parent, SLOT(createCursor()), Qt::UniqueConnection);
+        return item;
+    }
+    qmlInfo(parent, component->errors()) << tr("Could not load cursor delegate");
+    return item;
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktextutil_p.h b/src/quick/items/qquicktextutil_p.h
new file mode 100644
index 0000000000000000000000000000000000000000..91ef40b221c342fa20b2be9eabc0989641961da0
--- /dev/null
+++ b/src/quick/items/qquicktextutil_p.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKTEXTUTIL_P_H
+#define QQUICKTEXTUTIL_P_H
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API.  It exists purely as an
+// implementation detail.  This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtQml/qqml.h>
+#include <QtQml/qqmlincubator.h>
+#include <QtQuick/qquickitem.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickTextUtil : public QObject   // For the benefit of translations.
+{
+    Q_OBJECT
+public:
+    template <typename Private> static void setCursorDelegate(Private *d, QQmlComponent *delegate);
+    template <typename Private> static void createCursor(Private *d);
+
+private:
+    static QQuickItem *createCursor(
+            QQmlComponent *component,
+            QQuickItem *parent,
+            const QRectF &cursorRectangle,
+            const char *className);
+};
+
+template <typename Private>
+void QQuickTextUtil::setCursorDelegate(Private *d, QQmlComponent *delegate)
+{
+    if (d->cursorComponent == delegate)
+        return;
+
+    typename Private::Public *parent = d->q_func();
+
+    if (d->cursorComponent) {
+        disconnect(d->cursorComponent, SIGNAL(statusChanged(QQmlComponent::Status)),
+                parent, SLOT(createCursor()));
+    }
+
+    delete d->cursorItem;
+    d->cursorItem = 0;
+    d->cursorPending = true;
+
+    d->cursorComponent = delegate;
+
+    if (parent->isCursorVisible() && parent->isComponentComplete())
+        createCursor(d);
+
+    emit parent->cursorDelegateChanged();
+}
+
+template <typename Private>
+void QQuickTextUtil::createCursor(Private *d)
+{
+    if (!d->cursorPending)
+        return;
+
+    d->cursorPending = false;
+
+    typename Private::Public *parent = d->q_func();
+    if (d->cursorComponent) {
+        d->cursorItem = createCursor(
+                d->cursorComponent,
+                parent,
+                parent->cursorRectangle(),
+                Private::Public::staticMetaObject.className());
+    }
+
+    d->setNativeCursorEnabled(!d->cursorItem);
+    d->updateType = Private::UpdatePaintNode;
+    parent->update();
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tests/auto/quick/qquicktextedit/data/http/cursorHttpTest.qml b/tests/auto/quick/qquicktextedit/data/http/cursorHttpTest.qml
index be4526e22bec16933aa6a18b12d546aafd24b04d..043304d02783a1f31cc8a35e6dab34395d44aa4c 100644
--- a/tests/auto/quick/qquicktextedit/data/http/cursorHttpTest.qml
+++ b/tests/auto/quick/qquicktextedit/data/http/cursorHttpTest.qml
@@ -9,14 +9,18 @@ Rectangle { width: 300; height: 300; color: "white"
     ] 
     TextEdit {
         cursorDelegate: cursorFail
+        cursorVisible: true
     }
     TextEdit {
         cursorDelegate: cursorWait
+        cursorVisible: true
     }
     TextEdit {
         cursorDelegate: cursorNorm
+        cursorVisible: true
     }
     TextEdit {
         cursorDelegate: cursorErr
+        cursorVisible: true
     }
 }
diff --git a/tests/auto/quick/qquicktextedit/data/http/cursorHttpTestFail1.qml b/tests/auto/quick/qquicktextedit/data/http/cursorHttpTestFail1.qml
index 1d7763f913d8cf4a3ce7635ae56b9c3bdf8cf3ac..a6556454feda6df8a76e6fcdff1f8d3bafd538b3 100644
--- a/tests/auto/quick/qquicktextedit/data/http/cursorHttpTestFail1.qml
+++ b/tests/auto/quick/qquicktextedit/data/http/cursorHttpTestFail1.qml
@@ -8,11 +8,14 @@ Rectangle { width: 300; height: 300; color: "white"
     ] 
     TextEdit {
         cursorDelegate: cursorFail
+        cursorVisible: true
     }
     TextEdit {
         cursorDelegate: cursorWait
+        cursorVisible: true
     }
     TextEdit {
         cursorDelegate: cursorNorm
+        cursorVisible: true
     }
 }
diff --git a/tests/auto/quick/qquicktextedit/data/http/cursorHttpTestFail2.qml b/tests/auto/quick/qquicktextedit/data/http/cursorHttpTestFail2.qml
index c82ec02e68cf12e50b5983390e8e967269c19f3e..9429779a87544143d068ba7a6a957a5c4c11293c 100644
--- a/tests/auto/quick/qquicktextedit/data/http/cursorHttpTestFail2.qml
+++ b/tests/auto/quick/qquicktextedit/data/http/cursorHttpTestFail2.qml
@@ -8,11 +8,14 @@ Rectangle { width: 300; height: 300; color: "white"
     ] 
     TextEdit {
         cursorDelegate: cursorWait
+        cursorVisible: true
     }
     TextEdit {
         cursorDelegate: cursorNorm
+        cursorVisible: true
     }
     TextEdit {
         cursorDelegate: cursorErr
+        cursorVisible: true
     }
 }
diff --git a/tests/auto/quick/qquicktextedit/data/http/cursorHttpTestPass.qml b/tests/auto/quick/qquicktextedit/data/http/cursorHttpTestPass.qml
index 96d582c95d60a187c4bd2691f6779d08e14cb15b..69e498ef8d586f98b675a6e53277e908678360e8 100644
--- a/tests/auto/quick/qquicktextedit/data/http/cursorHttpTestPass.qml
+++ b/tests/auto/quick/qquicktextedit/data/http/cursorHttpTestPass.qml
@@ -8,10 +8,12 @@ Rectangle { width: 300; height: 300; color: "white"
     TextEdit {
         cursorDelegate: cursorWait
         text: "Hello"
+        cursorVisible: true
     }
     TextEdit {
         objectName: "textEditObject"
         cursorDelegate: cursorNorm
+        cursorVisible: true
         focus: true;
         text: "Hello"
     }
diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
index 1b21fcc2b41c71d70402076284e633ebf10de939..c7bf6af6ee7f2690fa41d763e3493e1012f95496 100644
--- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
+++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
@@ -1952,9 +1952,12 @@ void tst_qquicktextedit::cursorDelegate()
     view.requestActivateWindow();
     QQuickTextEdit *textEditObject = view.rootObject()->findChild<QQuickTextEdit*>("textEditObject");
     QVERIFY(textEditObject != 0);
-    QVERIFY(textEditObject->findChild<QQuickItem*>("cursorInstance"));
+    // Delegate creation is deferred until focus in or cursor visiblity is forced.
+    QVERIFY(!textEditObject->findChild<QQuickItem*>("cursorInstance"));
+    QVERIFY(!textEditObject->isCursorVisible());
     //Test Delegate gets created
     textEditObject->setFocus(true);
+    QVERIFY(textEditObject->isCursorVisible());
     QQuickItem* delegateObject = textEditObject->findChild<QQuickItem*>("cursorInstance");
     QVERIFY(delegateObject);
     QCOMPARE(delegateObject->property("localProperty").toString(), QString("Hello"));
@@ -2716,6 +2719,7 @@ void tst_qquicktextedit::clipRect()
     cursorComponent.setData("import QtQuick 2.0\nRectangle { height: 20; width: 8 }", QUrl());
 
     edit->setCursorDelegate(&cursorComponent);
+    edit->setCursorVisible(true);
 
     // If a cursor delegate is used it's size should determine the excess width.
     QCOMPARE(edit->clipRect().x(), qreal(0));
@@ -2797,6 +2801,7 @@ void tst_qquicktextedit::boundingRect()
     cursorComponent.setData("import QtQuick 2.0\nRectangle { height: 20; width: 8 }", QUrl());
 
     edit->setCursorDelegate(&cursorComponent);
+    edit->setCursorVisible(true);
 
     // Don't include the size of a cursor delegate as it has its own bounding rect.
     QCOMPARE(edit->boundingRect().x(), qreal(0));
diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
index e80808badf37f9ba686dc61a8ece7e00ae047b08..5397b6ce9f9c01898557086450a926b220132a88 100644
--- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
+++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
@@ -1509,6 +1509,7 @@ void tst_qquicktextinput::clipRect()
     cursorComponent.setData("import QtQuick 2.0\nRectangle { height: 20; width: 8 }", QUrl());
 
     input->setCursorDelegate(&cursorComponent);
+    input->setCursorVisible(true);
 
     // If a cursor delegate is used it's size should determine the excess width.
     QCOMPARE(input->clipRect().x(), qreal(0));
@@ -1596,6 +1597,7 @@ void tst_qquicktextinput::boundingRect()
     cursorComponent.setData("import QtQuick 2.0\nRectangle { height: 20; width: 8 }", QUrl());
 
     input->setCursorDelegate(&cursorComponent);
+    input->setCursorVisible(true);
 
     // Don't include the size of a cursor delegate as it has its own bounding rect.
     QCOMPARE(input->boundingRect().x(), input->width() - line.naturalTextWidth());
@@ -2481,9 +2483,13 @@ void tst_qquicktextinput::cursorDelegate()
     view.requestActivateWindow();
     QQuickTextInput *textInputObject = view.rootObject()->findChild<QQuickTextInput*>("textInputObject");
     QVERIFY(textInputObject != 0);
-    QVERIFY(textInputObject->findChild<QQuickItem*>("cursorInstance"));
+    // Delegate is created on demand, and so won't be available immediately.  Focus in or
+    // setCursorVisible(true) will trigger creation.
+    QTRY_VERIFY(!textInputObject->findChild<QQuickItem*>("cursorInstance"));
+    QVERIFY(!textInputObject->isCursorVisible());
     //Test Delegate gets created
     textInputObject->setFocus(true);
+    QVERIFY(textInputObject->isCursorVisible());
     QQuickItem* delegateObject = textInputObject->findChild<QQuickItem*>("cursorInstance");
     QVERIFY(delegateObject);
     QCOMPARE(delegateObject->property("localProperty").toString(), QString("Hello"));
@@ -2497,7 +2503,6 @@ void tst_qquicktextinput::cursorDelegate()
     QCOMPARE(textInputObject->cursorRectangle().x(), delegateObject->x());
     QCOMPARE(textInputObject->cursorRectangle().y(), delegateObject->y());
 
-
     // Test delegate gets moved on mouse press.
     textInputObject->setSelectByMouse(true);
     textInputObject->setCursorPosition(0);