diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp
index c201076199d5e0f43127792ce8b3efb8a8f43c21..fe01326bbc2751d271cbdf609680b974da2ec0e6 100644
--- a/src/quick/accessible/qaccessiblequickitem.cpp
+++ b/src/quick/accessible/qaccessiblequickitem.cpp
@@ -82,17 +82,42 @@ bool QAccessibleQuickItem::clipsChildren() const
     return static_cast<QQuickItem *>(item())->clip();
 }
 
+QAccessibleInterface *QAccessibleQuickItem::childAt(int x, int y) const
+{
+    if (item()->clip()) {
+        if (!rect().contains(x, y))
+            return 0;
+    }
+
+    const QList<QQuickItem*> kids = accessibleUnignoredChildren(item(), true);
+    for (int i = kids.count() - 1; i >= 0; --i) {
+        QAccessibleInterface *childIface = QAccessible::queryAccessibleInterface(kids.at(i));
+        if (QAccessibleInterface *childChild = childIface->childAt(x, y))
+            return childChild;
+        if (childIface && !childIface->state().invisible) {
+            if (childIface->rect().contains(x, y))
+                return childIface;
+        }
+    }
+
+    return 0;
+}
+
 QAccessibleInterface *QAccessibleQuickItem::parent() const
 {
     QQuickItem *parent = item()->parentItem();
+    QQuickWindow *window = item()->window();
+    QQuickItem *ci = window ? window->contentItem() : 0;
+    while (parent && parent != ci)
+        parent = parent->parentItem();
+
     if (parent) {
-        QQuickWindow *window = item()->window();
-        // Jump out to the scene widget if the parent is the root item.
-        // There are two root items, QQuickWindow::rootItem and
-        // QQuickView::declarativeRoot. The former is the true root item,
-        // but is not a part of the accessibility tree. Check if we hit
-        // it here and return an interface for the scene instead.
-        if (window && (parent == window->contentItem())) {
+        if (parent == ci) {
+            // Jump out to the scene widget if the parent is the root item.
+            // There are two root items, QQuickWindow::rootItem and
+            // QQuickView::declarativeRoot. The former is the true root item,
+            // but is not a part of the accessibility tree. Check if we hit
+            // it here and return an interface for the scene instead.
             return QAccessible::queryAccessibleInterface(window);
         } else {
             return QAccessible::queryAccessibleInterface(parent);
@@ -121,6 +146,19 @@ int QAccessibleQuickItem::indexOfChild(const QAccessibleInterface *iface) const
     return kids.indexOf(static_cast<QQuickItem*>(iface->object()));
 }
 
+QList<QQuickItem *> accessibleUnignoredChildren(QQuickItem *item, bool paintOrder)
+{
+    QList<QQuickItem *> items;
+    QList<QQuickItem*> childItems = paintOrder ? QQuickItemPrivate::get(item)->paintOrderChildItems()
+                                               : item->childItems();
+    Q_FOREACH (QQuickItem *child, childItems) {
+        QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(child);
+        if (itemPrivate->isAccessible)
+            items.append(child);
+    }
+    return items;
+}
+
 QList<QQuickItem *> QAccessibleQuickItem::childItems() const
 {
     if (    role() == QAccessible::Button ||
@@ -133,13 +171,7 @@ QList<QQuickItem *> QAccessibleQuickItem::childItems() const
             role() == QAccessible::ProgressBar)
         return QList<QQuickItem *>();
 
-    QList<QQuickItem *> items;
-    Q_FOREACH (QQuickItem *child, item()->childItems()) {
-        QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(child);
-        if (itemPrivate->isAccessible)
-            items.append(child);
-    }
-    return items;
+    return accessibleUnignoredChildren(item());
 }
 
 QAccessible::State QAccessibleQuickItem::state() const
diff --git a/src/quick/accessible/qaccessiblequickitem_p.h b/src/quick/accessible/qaccessiblequickitem_p.h
index 5cf120a802bc377d6e2a503fa7bd39c61c1f7ea3..84e82fff8668f76beb954770b9a05f1d180fb786 100644
--- a/src/quick/accessible/qaccessiblequickitem_p.h
+++ b/src/quick/accessible/qaccessiblequickitem_p.h
@@ -53,6 +53,7 @@ public:
     QRect viewRect() const;
 
     bool clipsChildren() const;
+    QAccessibleInterface *childAt(int x, int y) const;
 
     QAccessibleInterface *parent() const;
     QAccessibleInterface *child(int index) const;
@@ -118,6 +119,7 @@ private:
 };
 
 QRect itemScreenRect(QQuickItem *item);
+QList<QQuickItem *> accessibleUnignoredChildren(QQuickItem *item, bool paintOrder = false);
 
 
 #endif // QT_NO_ACCESSIBILITY
diff --git a/src/quick/accessible/qaccessiblequickview.cpp b/src/quick/accessible/qaccessiblequickview.cpp
index cfd62b877d850fb6c05511d254891ce5ce65bbb0..db0b042d3b5f7dcb806efcae3fbc8b1e24433935 100644
--- a/src/quick/accessible/qaccessiblequickview.cpp
+++ b/src/quick/accessible/qaccessiblequickview.cpp
@@ -53,7 +53,7 @@ QAccessibleQuickWindow::QAccessibleQuickWindow(QQuickWindow *object)
 QQuickItem *QAccessibleQuickWindow::rootItem() const
 {
     if (QQuickItem *ci = window()->contentItem()) {
-        const QList<QQuickItem *> &childItems = ci->childItems();
+        const QList<QQuickItem *> &childItems = accessibleUnignoredChildren(ci);
         if (!childItems.isEmpty())
             return childItems.first();
     }
@@ -110,56 +110,17 @@ QString QAccessibleQuickWindow::text(QAccessible::Text text) const
     return window()->title();
 }
 
-
-/*!
-  \internal
-
-  Can also return \a item itself
-  */
-static QQuickItem *childAt_helper(QQuickItem *item, int x, int y)
-{
-    if (!item->isVisible() || !item->isEnabled())
-        return 0;
-
-    if (item->flags() & QQuickItem::ItemClipsChildrenToShape) {
-        if (!itemScreenRect(item).contains(x, y))
-            return 0;
-    }
-
-    QAccessibleInterface *accessibleInterface = QAccessible::queryAccessibleInterface(item);
-    // this item has no Accessible attached property
-    if (!accessibleInterface)
-        return 0;
-
-    if (accessibleInterface->childCount() == 0) {
-        return (itemScreenRect(item).contains(x, y)) ? item : 0;
-    }
-
-    QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
-
-    QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
-    for (int i = children.count() - 1; i >= 0; --i) {
-        QQuickItem *child = children.at(i);
-        if (QQuickItem *childChild = childAt_helper(child, x, y))
-            return childChild;
-    }
-
-    QRect screenRect = itemScreenRect(item);
-
-    if (screenRect.contains(x, y))
-        return item;
-
-    return 0;
-}
-
 QAccessibleInterface *QAccessibleQuickWindow::childAt(int x, int y) const
 {
     Q_ASSERT(window());
-    QQuickItem *root = rootItem();
-    if (root) {
-        if (QQuickItem *item = childAt_helper(root, x, y))
-            return QAccessible::queryAccessibleInterface(item);
-        return QAccessible::queryAccessibleInterface(root);
+    for (int i = childCount() - 1; i >= 0; --i) {
+        QAccessibleInterface *childIface = child(i);
+        if (childIface && !childIface->state().invisible) {
+            if (QAccessibleInterface *iface = childIface->childAt(x, y))
+                return iface;
+            if (childIface->rect().contains(x, y))
+                return childIface;
+        }
     }
     return 0;
 }
diff --git a/src/quick/accessible/qqmlaccessible.cpp b/src/quick/accessible/qqmlaccessible.cpp
index 65d321d0a1a1a1ae817dee4ff6e4545d17f9e1ca..53eb6a7a0d671eb3f9496a981eff4f7f32bbcb00 100644
--- a/src/quick/accessible/qqmlaccessible.cpp
+++ b/src/quick/accessible/qqmlaccessible.cpp
@@ -54,27 +54,6 @@ QQmlAccessible::~QQmlAccessible()
 {
 }
 
-QAccessibleInterface *QQmlAccessible::childAt(int x, int y) const
-{
-    // Note that this function will disregard stacking order.
-    // (QAccessibleQuickView::childAt() does this correctly and more efficient)
-
-    // If the item clips its children, we can return early if the coordinate is outside its rect
-    if (clipsChildren()) {
-        if (!rect().contains(x, y))
-            return 0;
-    }
-
-    for (int i = childCount() - 1; i >= 0; --i) {
-        QAccessibleInterface *childIface = child(i);
-        if (childIface && !childIface->state().invisible) {
-            if (childIface->rect().contains(x, y))
-                return childIface;
-        }
-    }
-    return 0;
-}
-
 QAccessible::State QQmlAccessible::state() const
 {
     QAccessible::State state;
diff --git a/src/quick/accessible/qqmlaccessible_p.h b/src/quick/accessible/qqmlaccessible_p.h
index 38e3dcff5947083e14ccf6847be77731f5c05d0b..5948f06cb592bc7964a409a00feffadb8acafc09 100644
--- a/src/quick/accessible/qqmlaccessible_p.h
+++ b/src/quick/accessible/qqmlaccessible_p.h
@@ -64,7 +64,6 @@ public:
     void *interface_cast(QAccessible::InterfaceType t);
 
     virtual QRect viewRect() const = 0;
-    QAccessibleInterface *childAt(int, int) const;
     QAccessible::State state() const;
 
     QStringList actionNames() const;
@@ -72,7 +71,6 @@ public:
     QStringList keyBindingsForAction(const QString &actionName) const;
 
 protected:
-    virtual bool clipsChildren() const = 0;
     // For subclasses, use instantiateObject factory method outside the class.
     QQmlAccessible(QObject *object);
 };