diff --git a/src/declarative/items/qquickborderimage.cpp b/src/declarative/items/qquickborderimage.cpp
index 4e713c02d41bc79b285197f67ae3bb2598ab17c0..fac7543fce7d8e5bff7829fc458765003528e626 100644
--- a/src/declarative/items/qquickborderimage.cpp
+++ b/src/declarative/items/qquickborderimage.cpp
@@ -299,8 +299,7 @@ void QQuickBorderImage::load()
     if (d->url.isEmpty()) {
         d->pix.clear(this);
         d->status = Null;
-        setImplicitWidth(0);
-        setImplicitHeight(0);
+        setImplicitSize(0, 0);
         emit statusChanged(d->status);
         update();
     } else {
@@ -331,8 +330,7 @@ void QQuickBorderImage::load()
                 d->pix.connectDownloadProgress(this, SLOT(requestProgress(qint64,qint64)));
             } else {
                 QSize impsize = d->pix.implicitSize();
-                setImplicitWidth(impsize.width());
-                setImplicitHeight(impsize.height());
+                setImplicitSize(impsize.width(), impsize.height());
 
                 if (d->pix.isReady()) {
                     d->status = Ready;
@@ -474,8 +472,7 @@ void QQuickBorderImage::setGridScaledImage(const QQuickGridScaledImage& sci)
         } else {
 
             QSize impsize = d->pix.implicitSize();
-            setImplicitWidth(impsize.width());
-            setImplicitHeight(impsize.height());
+            setImplicitSize(impsize.width(), impsize.height());
 
             if (d->pix.isReady()) {
                 d->status = Ready;
@@ -505,8 +502,7 @@ void QQuickBorderImage::requestFinished()
         d->status = Ready;
     }
 
-    setImplicitWidth(impsize.width());
-    setImplicitHeight(impsize.height());
+    setImplicitSize(impsize.width(), impsize.height());
 
     if (d->sourcesize.width() != d->pix.width() || d->sourcesize.height() != d->pix.height())
         emit sourceSizeChanged();
diff --git a/src/declarative/items/qquickimage.cpp b/src/declarative/items/qquickimage.cpp
index 598d6bef483c2d4d465fc2bfabffe26f8932c592..6d2e1b3187a9ddc84511475cee1ba3efd261bebd 100644
--- a/src/declarative/items/qquickimage.cpp
+++ b/src/declarative/items/qquickimage.cpp
@@ -478,8 +478,7 @@ void QQuickImage::updatePaintedGeometry()
 
     if (d->fillMode == PreserveAspectFit) {
         if (!d->pix.width() || !d->pix.height()) {
-            setImplicitWidth(0);
-            setImplicitHeight(0);
+            setImplicitSize(0, 0);
             return;
         }
         qreal w = widthValid() ? width() : d->pix.width();
@@ -493,16 +492,10 @@ void QQuickImage::updatePaintedGeometry()
             d->paintedWidth = heightScale * qreal(d->pix.width());
             d->paintedHeight = h;
         }
-        if (widthValid() && !heightValid()) {
-            setImplicitHeight(d->paintedHeight);
-        } else {
-            setImplicitHeight(d->pix.height());
-        }
-        if (heightValid() && !widthValid()) {
-            setImplicitWidth(d->paintedWidth);
-        } else {
-            setImplicitWidth(d->pix.width());
-        }
+        qreal iHeight = (widthValid() && !heightValid()) ? d->paintedHeight : d->pix.height();
+        qreal iWidth = (heightValid() && !widthValid()) ? d->paintedWidth : d->pix.width();
+        setImplicitSize(iWidth, iHeight);
+
     } else if (d->fillMode == PreserveAspectCrop) {
         if (!d->pix.width() || !d->pix.height())
             return;
diff --git a/src/declarative/items/qquickimagebase.cpp b/src/declarative/items/qquickimagebase.cpp
index 3eb196d15297327f64cc73e2fe9d555e98a271af..e5030c5e09153b56bb9ccf081dd1d66cd30e9b4f 100644
--- a/src/declarative/items/qquickimagebase.cpp
+++ b/src/declarative/items/qquickimagebase.cpp
@@ -284,8 +284,7 @@ void QQuickImageBase::componentComplete()
 void QQuickImageBase::pixmapChange()
 {
     Q_D(QQuickImageBase);
-    setImplicitWidth(d->pix.width());
-    setImplicitHeight(d->pix.height());
+    setImplicitSize(d->pix.width(), d->pix.height());
 }
 
 QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickitem.cpp b/src/declarative/items/qquickitem.cpp
index a4a5ab4d0ed3c8e693e83062ba43a2f524dec2e3..3978cf8133e96c067853151d4fc26055ef49fb05 100644
--- a/src/declarative/items/qquickitem.cpp
+++ b/src/declarative/items/qquickitem.cpp
@@ -4412,6 +4412,48 @@ void QQuickItem::setImplicitHeight(qreal h)
         d->implicitHeightChanged();
 }
 
+void QQuickItem::setImplicitSize(qreal w, qreal h)
+{
+    Q_D(QQuickItem);
+    bool wChanged = w != d->implicitWidth;
+    bool hChanged = h != d->implicitHeight;
+
+    d->implicitWidth = w;
+    d->implicitHeight = h;
+
+    bool wDone = false;
+    bool hDone = false;
+    if (d->width == w || widthValid()) {
+        if (wChanged)
+            d->implicitWidthChanged();
+        wDone = true;
+    }
+    if (d->height == h || heightValid()) {
+        if (hChanged)
+            d->implicitHeightChanged();
+        hDone = true;
+    }
+    if (wDone && hDone)
+        return;
+
+    qreal oldWidth = d->width;
+    qreal oldHeight = d->height;
+    if (!wDone)
+        d->width = w;
+    if (!hDone)
+        d->height = h;
+
+    d->dirty(QQuickItemPrivate::Size);
+
+    geometryChanged(QRectF(x(), y(), width(), height()),
+                    QRectF(x(), y(), oldWidth, oldHeight));
+
+    if (!wDone && wChanged)
+        d->implicitWidthChanged();
+    if (!hDone && hChanged)
+        d->implicitHeightChanged();
+}
+
 /*!
     Returns whether the height property has been set explicitly.
 */
diff --git a/src/declarative/items/qquickitem.h b/src/declarative/items/qquickitem.h
index 0cbcfb890d256242b6707fd55e5c597751a29b24..a3baecb9ead7dac349eab925ba372846e1ba015e 100644
--- a/src/declarative/items/qquickitem.h
+++ b/src/declarative/items/qquickitem.h
@@ -359,6 +359,7 @@ protected:
     bool widthValid() const; // ### better name?
     void setImplicitHeight(qreal);
     bool heightValid() const; // ### better name?
+    void setImplicitSize(qreal, qreal);
 
     virtual void classBegin();
     virtual void componentComplete();
diff --git a/src/declarative/items/qquickloader.cpp b/src/declarative/items/qquickloader.cpp
index 73f57073d21c0f607c062218514b49ecd1747455..242d9f3d7f8b62c87d753684fbeb94f68cde30f5 100644
--- a/src/declarative/items/qquickloader.cpp
+++ b/src/declarative/items/qquickloader.cpp
@@ -783,17 +783,12 @@ void QQuickLoaderPrivate::_q_updateSize(bool loaderGeometryChanged)
 
     updatingSize = true;
 
-    if (!itemWidthValid)
-        q->setImplicitWidth(item->implicitWidth());
-    else
-        q->setImplicitWidth(item->width());
+    qreal iWidth = !itemWidthValid ? item->implicitWidth() : item->width();
+    qreal iHeight = !itemHeightValid ? item->implicitHeight() : item->height();
+    q->setImplicitSize(iWidth, iHeight);
+
     if (loaderGeometryChanged && q->widthValid())
         item->setWidth(q->width());
-
-    if (!itemHeightValid)
-        q->setImplicitHeight(item->implicitHeight());
-    else
-        q->setImplicitHeight(item->height());
     if (loaderGeometryChanged && q->heightValid())
         item->setHeight(q->height());
 
diff --git a/src/declarative/items/qquickpositioners.cpp b/src/declarative/items/qquickpositioners.cpp
index 8d204931ef0a2c00da64d7ef6ef54edebd510f63..08fa4b1724dc8e6a70160310558a562485e3c4d8 100644
--- a/src/declarative/items/qquickpositioners.cpp
+++ b/src/declarative/items/qquickpositioners.cpp
@@ -245,8 +245,7 @@ void QQuickBasePositioner::prePositioning()
         finishApplyTransitions();
     d->doingPositioning = false;
     //Set implicit size to the size of its children
-    setImplicitHeight(contentSize.height());
-    setImplicitWidth(contentSize.width());
+    setImplicitSize(contentSize.width(), contentSize.height());
 }
 
 void QQuickBasePositioner::positionX(int x, const PositionedItem &target)
diff --git a/src/declarative/items/qquicktext.cpp b/src/declarative/items/qquicktext.cpp
index e3286f0b6b8e0de301ae824636fca78da1e1c354..22f29cb135942303070b8b41e38e8d06e1d3bfc7 100644
--- a/src/declarative/items/qquicktext.cpp
+++ b/src/declarative/items/qquicktext.cpp
@@ -293,8 +293,7 @@ void QQuickTextPrivate::updateSize()
 
     QFontMetrics fm(font);
     if (text.isEmpty()) {
-        q->setImplicitWidth(0);
-        q->setImplicitHeight(fm.height());
+        q->setImplicitSize(0, fm.height());
         paintedSize = QSize(0, fm.height());
         emit q->paintedSizeChanged();
         q->update();
@@ -356,13 +355,17 @@ void QQuickTextPrivate::updateSize()
 
     //### need to comfirm cost of always setting these for richText
     internalWidthUpdate = true;
+    qreal iWidth = -1;
     if (!q->widthValid())
-        q->setImplicitWidth(size.width());
+        iWidth = size.width();
     else if (requireImplicitWidth)
-        q->setImplicitWidth(naturalWidth);
+        iWidth = naturalWidth;
+    if (iWidth > -1)
+        q->setImplicitSize(iWidth, size.height());
     internalWidthUpdate = false;
 
-    q->setImplicitHeight(size.height());
+    if (iWidth == -1)
+        q->setImplicitHeight(size.height());
     if (paintedSize != size) {
         paintedSize = size;
         emit q->paintedSizeChanged();
diff --git a/src/declarative/items/qquicktextedit.cpp b/src/declarative/items/qquicktextedit.cpp
index 51231e17de5226be7bfffab2879a35c553c9deb9..b40b5c09a1874324db6691f6af44db7075f2fce3 100644
--- a/src/declarative/items/qquicktextedit.cpp
+++ b/src/declarative/items/qquicktextedit.cpp
@@ -1804,12 +1804,16 @@ void QQuickTextEdit::updateSize()
         if (!widthValid() && d->document->textWidth() != newWidth)
             d->document->setTextWidth(newWidth); // ### Text does not align if width is not set (QTextDoc bug)
         // ### Setting the implicitWidth triggers another updateSize(), and unless there are bindings nothing has changed.
+        qreal iWidth = -1;
         if (!widthValid())
-            setImplicitWidth(newWidth);
+            iWidth = newWidth;
         else if (d->requireImplicitWidth)
-            setImplicitWidth(naturalWidth);
+            iWidth = naturalWidth;
         qreal newHeight = d->document->isEmpty() ? fm.height() : (int)d->document->size().height();
-        setImplicitHeight(newHeight);
+        if (iWidth > -1)
+            setImplicitSize(iWidth, newHeight);
+        else
+            setImplicitHeight(newHeight);
 
         d->paintedSize = QSize(newWidth, newHeight);
         emit paintedSizeChanged();
diff --git a/src/declarative/items/qquicktextinput.cpp b/src/declarative/items/qquicktextinput.cpp
index c9469babdbcdfe8db1e0597c883beab53278aff1..c46eba1b9f259f9e1d90b74add2ca93be112fd01 100644
--- a/src/declarative/items/qquicktextinput.cpp
+++ b/src/declarative/items/qquicktextinput.cpp
@@ -1971,8 +1971,7 @@ void QQuickTextInput::updateSize(bool needsRedraw)
     Q_D(QQuickTextInput);
     int w = width();
     int h = height();
-    setImplicitHeight(d->control->height()-1); // -1 to counter QLineControl's +1 which is not consistent with Text.
-    setImplicitWidth(d->calculateTextWidth());
+    setImplicitSize(d->calculateTextWidth(), d->control->height()-1); // -1 to counter QLineControl's +1 which is not consistent with Text.
     if (w==width() && h==height() && needsRedraw)
         update();
 }
diff --git a/tests/auto/declarative/qquickanchors/tst_qquickanchors.cpp b/tests/auto/declarative/qquickanchors/tst_qquickanchors.cpp
index cfdab7f14ccdc41fc40f96c24d0a2d3d22a40b55..00b52ebc50b26e6455617cfcbd17c4fcb3bb6535 100644
--- a/tests/auto/declarative/qquickanchors/tst_qquickanchors.cpp
+++ b/tests/auto/declarative/qquickanchors/tst_qquickanchors.cpp
@@ -283,7 +283,6 @@ void tst_qquickanchors::loops()
         QString expect = source.toString() + ":6:5: QML Text: Possible anchor loop detected on horizontal anchor.";
         QTest::ignoreMessage(QtWarningMsg, expect.toLatin1());
         QTest::ignoreMessage(QtWarningMsg, expect.toLatin1());
-        QTest::ignoreMessage(QtWarningMsg, expect.toLatin1());
 
         QQuickView *view = new QQuickView;
         view->setSource(source);