Sisyphus repository
Last update: 1 october 2023 | SRPMs: 18631 | Visits: 37860376
en ru br
ALT Linux repos
S:5.15.10-alt1

Group :: System/Libraries
RPM: qt5-declarative

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs and FR  Repocop 

Patch: kde-5.15.patch
Download


diff --git a/src/qml/common/qqmljsfixedpoolarray_p.h b/src/qml/common/qqmljsfixedpoolarray_p.h
index b65b994d6c..15a8cd6878 100644
--- a/src/qml/common/qqmljsfixedpoolarray_p.h
+++ b/src/qml/common/qqmljsfixedpoolarray_p.h
@@ -86,7 +86,7 @@ public:
         if (QTypeInfo<T>::isComplex) {
             for (int i = 0; i < count; ++i)
                 new (data + i) T(vector.at(i));
-        } else {
+        } else if (count) {
             memcpy(data, static_cast<const void*>(vector.constData()), count * sizeof(T));
         }
     }
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index e57cdd8278..94613598af 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -1145,8 +1145,7 @@ void Heap::QObjectWrapper::markObjects(Heap::Base *that, QV4::MarkStack *markSta
 void QObjectWrapper::destroyObject(bool lastCall)
 {
     Heap::QObjectWrapper *h = d();
-    if (!h->internalClass)
-        return; // destroyObject already got called
+    Q_ASSERT(h->internalClass);
 
     if (h->object()) {
         QQmlData *ddata = QQmlData::get(h->object(), false);
@@ -1176,7 +1175,7 @@ void QObjectWrapper::destroyObject(bool lastCall)
         }
     }
 
-    h->~Data();
+    h->destroy();
 }
 
 
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index 06caf04e5a..da149a67c4 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -981,7 +981,7 @@ void MemoryManager::sweep(bool lastSweep, ClassDestroyStatsCallback classCountPt
 
     if (MultiplyWrappedQObjectMap *multiplyWrappedQObjects = engine->m_multiplyWrappedQObjects) {
         for (MultiplyWrappedQObjectMap::Iterator it = multiplyWrappedQObjects->begin(); it != multiplyWrappedQObjects->end();) {
-            if (!it.value().isNullOrUndefined())
+            if (it.value().isNullOrUndefined())
                 it = multiplyWrappedQObjects->erase(it);
             else
                 ++it;
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index 175de8b936..a6ba4b8cb3 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -419,8 +419,10 @@ ReturnedValue QQmlTypeWrapper::virtualInstanceOf(const Object *typeObject, const
             return Encode(false);
 
         QQmlRefPointer<QQmlTypeData> td = qenginepriv->typeLoader.getType(typeWrapper->d()->type().sourceUrl());
-        ExecutableCompilationUnit *cu = td->compilationUnit();
-        myQmlType = qenginepriv->metaObjectForType(cu->metaTypeId);
+        if (ExecutableCompilationUnit *cu = td->compilationUnit())
+            myQmlType = qenginepriv->metaObjectForType(cu->metaTypeId);
+        else
+            return Encode(false); // It seems myQmlType has some errors, so we could not compile it.
     } else {
         myQmlType = qenginepriv->metaObjectForType(myTypeId);
     }
diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp
index 29ed62cd39..aba930dfe1 100644
--- a/src/qml/types/qqmlconnections.cpp
+++ b/src/qml/types/qqmlconnections.cpp
@@ -338,7 +338,7 @@ void QQmlConnections::connectSignalsToMethods()
                    && propName.at(2).isUpper()) {
             qmlWarning(this) << tr("Detected function \"%1\" in Connections element. "
                                    "This is probably intended to be a signal handler but no "
-                                   "signal of the target matches the name.").arg(propName);
+                                   "signal of the \"%2\" target matches the name.").arg(propName).arg(target->metaObject()->className());
         }
     }
 }
diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp
index 2079a8ed04..a577cb2351 100644
--- a/src/qmlmodels/qqmldelegatemodel.cpp
+++ b/src/qmlmodels/qqmldelegatemodel.cpp
@@ -389,6 +389,12 @@ void QQmlDelegateModelPrivate::connectToAbstractItemModel()
                       q,  QQmlDelegateModel, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
     qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
                       q,  QQmlDelegateModel, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
+    qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsInserted(QModelIndex,int,int)),
+                      q, QQmlDelegateModel, SLOT(_q_columnsInserted(QModelIndex,int,int)));
+    qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsRemoved(QModelIndex,int,int)),
+                      q, QQmlDelegateModel, SLOT(_q_columnsRemoved(QModelIndex,int,int)));
+    qmlobject_connect(aim, QAbstractItemModel, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
+                      q, QQmlDelegateModel, SLOT(_q_columnsMoved(QModelIndex,int,int,QModelIndex,int)));
     qmlobject_connect(aim, QAbstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
                       q, QQmlDelegateModel, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
     qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
@@ -413,6 +419,12 @@ void QQmlDelegateModelPrivate::disconnectFromAbstractItemModel()
                         q, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int)));
     QObject::disconnect(aim, SIGNAL(rowsRemoved(QModelIndex,int,int)),
                         q, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
+    QObject::disconnect(aim, SIGNAL(columnsInserted(QModelIndex,int,int)), q,
+                        SLOT(_q_columnsInserted(QModelIndex,int,int)));
+    QObject::disconnect(aim, SIGNAL(columnsRemoved(QModelIndex,int,int)), q,
+                        SLOT(_q_columnsRemoved(QModelIndex,int,int)));
+    QObject::disconnect(aim, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)), q,
+                        SLOT(_q_columnsMoved(QModelIndex,int,int,QModelIndex,int)));
     QObject::disconnect(aim, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
                         q, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>)));
     QObject::disconnect(aim, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
@@ -1973,6 +1985,38 @@ void QQmlDelegateModel::_q_rowsMoved(
     }
 }
 
+void QQmlDelegateModel::_q_columnsInserted(const QModelIndex &parent, int begin, int end)
+{
+    Q_D(QQmlDelegateModel);
+    Q_UNUSED(end);
+    if (parent == d->m_adaptorModel.rootIndex && begin == 0) {
+        // mark all items as changed
+        _q_itemsChanged(0, d->m_count, QVector<int>());
+    }
+}
+
+void QQmlDelegateModel::_q_columnsRemoved(const QModelIndex &parent, int begin, int end)
+{
+    Q_D(QQmlDelegateModel);
+    Q_UNUSED(end);
+    if (parent == d->m_adaptorModel.rootIndex && begin == 0) {
+        // mark all items as changed
+        _q_itemsChanged(0, d->m_count, QVector<int>());
+    }
+}
+
+void QQmlDelegateModel::_q_columnsMoved(const QModelIndex &parent, int start, int end,
+                                        const QModelIndex &destination, int column)
+{
+    Q_D(QQmlDelegateModel);
+    Q_UNUSED(end);
+    if ((parent == d->m_adaptorModel.rootIndex && start == 0)
+        || (destination == d->m_adaptorModel.rootIndex && column == 0)) {
+        // mark all items as changed
+        _q_itemsChanged(0, d->m_count, QVector<int>());
+    }
+}
+
 void QQmlDelegateModel::_q_dataChanged(const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles)
 {
     Q_D(QQmlDelegateModel);
diff --git a/src/qmlmodels/qqmldelegatemodel_p.h b/src/qmlmodels/qqmldelegatemodel_p.h
index 8aab4badca..d140bfbaaf 100644
--- a/src/qmlmodels/qqmldelegatemodel_p.h
+++ b/src/qmlmodels/qqmldelegatemodel_p.h
@@ -152,6 +152,9 @@ private Q_SLOTS:
     void _q_itemsMoved(int from, int to, int count);
     void _q_modelReset();
     void _q_rowsInserted(const QModelIndex &,int,int);
+    void _q_columnsInserted(const QModelIndex &, int, int);
+    void _q_columnsRemoved(const QModelIndex &, int, int);
+    void _q_columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
     void _q_rowsAboutToBeRemoved(const QModelIndex &parent, int begin, int end);
     void _q_rowsRemoved(const QModelIndex &,int,int);
     void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp
index 85719fdc80..78e2ab302c 100644
--- a/src/quick/accessible/qaccessiblequickitem.cpp
+++ b/src/quick/accessible/qaccessiblequickitem.cpp
@@ -46,6 +46,7 @@
 #include "QtQuick/private/qquicktextinput_p.h"
 #include "QtQuick/private/qquickaccessibleattached_p.h"
 #include "QtQuick/qquicktextdocument.h"
+#include "QtQuick/qquickrendercontrol.h"
 QT_BEGIN_NAMESPACE
 
 #if QT_CONFIG(accessibility)
@@ -57,7 +58,19 @@ QAccessibleQuickItem::QAccessibleQuickItem(QQuickItem *item)
 
 QWindow *QAccessibleQuickItem::window() const
 {
-    return item()->window();
+    QQuickWindow *window = item()->window();
+
+    // For QQuickWidget the above window will be the offscreen QQuickWindow,
+    // which is not a part of the accessibility tree. Detect this case and
+    // return the window for the QQuickWidget instead.
+    if (window && !window->handle()) {
+        if (QQuickRenderControl *renderControl = QQuickWindowPrivate::get(window)->renderControl) {
+            if (QWindow *renderWindow = renderControl->renderWindow(nullptr))
+                return renderWindow;
+        }
+    }
+
+    return window;
 }
 
 int QAccessibleQuickItem::childCount() const
@@ -113,19 +126,15 @@ QAccessibleInterface *QAccessibleQuickItem::childAt(int x, int y) const
 QAccessibleInterface *QAccessibleQuickItem::parent() const
 {
     QQuickItem *parent = item()->parentItem();
-    QQuickWindow *window = item()->window();
-    QQuickItem *ci = window ? window->contentItem() : nullptr;
+    QQuickWindow *itemWindow = item()->window();
+    QQuickItem *ci = itemWindow ? itemWindow->contentItem() : nullptr;
     while (parent && !QQuickItemPrivate::get(parent)->isAccessible && parent != ci)
         parent = parent->parentItem();
 
     if (parent) {
         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);
+            // Jump out to the window if the parent is the root item
+            return QAccessible::queryAccessibleInterface(window());
         } else {
             while (parent && !parent->d_func()->isAccessible)
                 parent = parent->parentItem();
@@ -188,7 +197,7 @@ QAccessible::State QAccessibleQuickItem::state() const
     QRect viewRect_ = viewRect();
     QRect itemRect = rect();
 
-    if (viewRect_.isNull() || itemRect.isNull() || !item()->window() || !item()->window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity()))
+    if (viewRect_.isNull() || itemRect.isNull() || !window() || !window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity()))
         state.invisible = true;
     if (!viewRect_.intersects(itemRect))
         state.offscreen = true;
@@ -201,6 +210,10 @@ QAccessible::State QAccessibleQuickItem::state() const
     if (role() == QAccessible::EditableText)
         if (auto ti = qobject_cast<QQuickTextInput *>(item()))
             state.passwordEdit = ti->echoMode() != QQuickTextInput::Normal;
+    if (!item()->isEnabled()) {
+        state.focusable = false;
+        state.disabled = true;
+    }
     return state;
 }
 
diff --git a/src/quick/accessible/qaccessiblequickview_p.h b/src/quick/accessible/qaccessiblequickview_p.h
index 39ffcaf39c..8baa01330c 100644
--- a/src/quick/accessible/qaccessiblequickview_p.h
+++ b/src/quick/accessible/qaccessiblequickview_p.h
@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
 
 #if QT_CONFIG(accessibility)
 
-class QAccessibleQuickWindow : public QAccessibleObject
+class Q_QUICK_EXPORT QAccessibleQuickWindow : public QAccessibleObject
 {
 public:
     QAccessibleQuickWindow(QQuickWindow *object);
diff --git a/src/quick/items/qquickdrag.cpp b/src/quick/items/qquickdrag.cpp
index 8321fcfeed..383078b3b9 100644
--- a/src/quick/items/qquickdrag.cpp
+++ b/src/quick/items/qquickdrag.cpp
@@ -481,7 +481,9 @@ void QQuickDragAttached::setKeys(const QStringList &keys)
     \qmlattachedproperty stringlist QtQuick::Drag::mimeData
     \since 5.2
 
-    This property holds a map of mimeData that is used during startDrag.
+    This property holds a map from mime type to data that is used during startDrag.
+    The mime data needs to be a \c string, or an \c ArrayBuffer with the data encoded
+    according to the mime type.
 */
 
 QVariantMap QQuickDragAttached::mimeData() const
@@ -766,8 +768,12 @@ Qt::DropAction QQuickDragAttachedPrivate::startDrag(Qt::DropActions supportedAct
     QDrag *drag = new QDrag(source ? source : q);
     QMimeData *mimeData = new QMimeData();
 
-    for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it)
-        mimeData->setData(it.key(), it.value().toString().toUtf8());
+    for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it) {
+        if (static_cast<QMetaType::Type>(it.value().type()) == QMetaType::QByteArray)
+            mimeData->setData(it.key(), it.value().toByteArray());
+        else
+            mimeData->setData(it.key(), it.value().toString().toUtf8());
+    }
 
     drag->setMimeData(mimeData);
     if (pixmapLoader.isReady()) {
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 75f1457816..dec0ae19ae 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -59,6 +59,7 @@
 #include <QtCore/private/qnumeric_p.h>
 #include <QtGui/qpa/qplatformtheme.h>
 #include <QtCore/qloggingcategory.h>
+#include <QtCore/private/qduplicatetracker_p.h>
 
 #include <private/qqmlglobal_p.h>
 #include <private/qqmlengine_p.h>
@@ -2326,6 +2327,7 @@ QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
 QQuickItem::~QQuickItem()
 {
     Q_D(QQuickItem);
+    d->inDestructor = true;
 
     if (d->windowRefCount > 1)
         d->windowRefCount = 1; // Make sure window is set to null in next call to derefWindow().
@@ -2526,6 +2528,7 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
     QQuickItem *current = item;
     qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: startItem:" << startItem;
     qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: firstFromItem:" << firstFromItem;
+    QDuplicateTracker<QQuickItem *> cycleDetector;
     do {
         qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: current:" << current;
         qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: from:" << from;
@@ -2592,7 +2595,10 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
         // traversed all of the chain (by compare the [current] item with [startItem])
         // Since the [startItem] might be promoted to its parent if it is invisible,
         // we still have to check [current] item with original start item
-        if ((current == startItem || current == originalStartItem) && from == firstFromItem) {
+        // We might also run into a cycle before we reach firstFromItem again
+        // but note that we have to ignore current if we are meant to skip it
+        if (((current == startItem || current == originalStartItem) && from == firstFromItem) ||
+                (!skip && cycleDetector.hasSeen(current))) {
             // wrapped around, avoid endless loops
             if (item == contentItem) {
                 qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return contentItem";
@@ -2689,9 +2695,8 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
 
         const bool wasVisible = isVisible();
         op->removeChild(this);
-        if (wasVisible) {
+        if (wasVisible && !op->inDestructor)
             emit oldParentItem->visibleChildrenChanged();
-        }
     } else if (d->window) {
         QQuickWindowPrivate::get(d->window)->parentlessItems.remove(this);
     }
@@ -2768,8 +2773,9 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
 
     d->itemChange(ItemParentHasChanged, d->parentItem);
 
-    emit parentChanged(d->parentItem);
-    if (isVisible() && d->parentItem)
+    if (!d->inDestructor)
+        emit parentChanged(d->parentItem);
+    if (isVisible() && d->parentItem && !QQuickItemPrivate::get(d->parentItem)->inDestructor)
         emit d->parentItem->visibleChildrenChanged();
 }
 
@@ -2965,7 +2971,8 @@ void QQuickItemPrivate::removeChild(QQuickItem *child)
 
     itemChange(QQuickItem::ItemChildRemovedChange, child);
 
-    emit q->childrenChanged();
+    if (!inDestructor)
+        emit q->childrenChanged();
 }
 
 void QQuickItemPrivate::refWindow(QQuickWindow *c)
@@ -3194,6 +3201,7 @@ QQuickItemPrivate::QQuickItemPrivate()
     , touchEnabled(false)
 #endif
     , hasCursorHandler(false)
+    , inDestructor(false)
     , dirtyAttributes(0)
     , nextDirtyItem(nullptr)
     , prevDirtyItem(nullptr)
@@ -5120,6 +5128,13 @@ void QQuickItem::componentComplete()
         d->addToDirtyList();
         QQuickWindowPrivate::get(d->window)->dirtyItem(this);
     }
+
+#if QT_CONFIG(accessibility)
+    if (d->isAccessible && d->effectiveVisible) {
+        QAccessibleEvent ev(this, QAccessible::ObjectShow);
+        QAccessible::updateAccessibility(&ev);
+    }
+#endif
 }
 
 QQuickStateGroup *QQuickItemPrivate::_states()
@@ -6106,9 +6121,11 @@ bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
         QAccessible::updateAccessibility(&ev);
     }
 #endif
-    emit q->visibleChanged();
-    if (childVisibilityChanged)
-        emit q->visibleChildrenChanged();
+    if (!inDestructor) {
+        emit q->visibleChanged();
+        if (childVisibilityChanged)
+            emit q->visibleChildrenChanged();
+    }
 
     return true;    // effective visibility DID change
 }
@@ -6157,6 +6174,15 @@ void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffec
     }
 
     itemChange(QQuickItem::ItemEnabledHasChanged, effectiveEnable);
+#if QT_CONFIG(accessibility)
+    if (isAccessible) {
+        QAccessible::State changedState;
+        changedState.disabled = true;
+        changedState.focusable = true;
+        QAccessibleStateChangeEvent ev(q, changedState);
+        QAccessible::updateAccessibility(&ev);
+    }
+#endif
     emit q->enabledChanged();
 }
 
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 841d91bb40..ade8fb61f2 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -472,6 +472,7 @@ public:
     bool replayingPressEvent:1;
     bool touchEnabled:1;
     bool hasCursorHandler:1;
+    quint32 inDestructor:1; // has entered ~QQuickItem
 
     enum DirtyType {
         TransformOrigin         = 0x00000001,
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 010a0152e1..f8ad168a17 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -1785,7 +1785,7 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to)
 
     do {
         bufferPause.stop();
-        if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges()) {
+        if (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges() || currentChanges.active) {
             currentChanges.reset();
             bufferedChanges.reset();
             releaseVisibleItems(reusableFlag);
diff --git a/src/quick/items/qquickmousearea_p_p.h b/src/quick/items/qquickmousearea_p_p.h
index fba383e268..0d63618622 100644
--- a/src/quick/items/qquickmousearea_p_p.h
+++ b/src/quick/items/qquickmousearea_p_p.h
@@ -61,7 +61,6 @@ QT_BEGIN_NAMESPACE
 
 class QQuickMouseEvent;
 class QQuickMouseArea;
-class QQuickPointerMask;
 class QQuickMouseAreaPrivate : public QQuickItemPrivate
 {
     Q_DECLARE_PUBLIC(QQuickMouseArea)
@@ -100,7 +99,6 @@ public:
 #if QT_CONFIG(quick_draganddrop)
     QQuickDrag *drag;
 #endif
-    QPointer<QQuickPointerMask> mask;
     QPointF startScene;
     QPointF targetStartPos;
     QPointF lastPos;
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 6230186933..e823ca1095 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -2168,7 +2168,7 @@ void QQuickText::resetMaximumLineCount()
     <img src="" align="top,middle,bottom" width="" height=""> - inline images
     <ol type="">, <ul type=""> and <li> - ordered and unordered lists
     <pre></pre> - preformatted
-    &gt; &lt; &amp;
+    &gt; &lt; &amp; &quot; &nbsp; &apos;
     \endcode
 
     \c Text.StyledText parser is strict, requiring tags to be correctly nested.
diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
index eb4db0f85e..2325a2665b 100644
--- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
+++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
@@ -446,7 +446,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
 
         const char *textureRecord = allocatorData;
         for (int i = 0; i < textureCount; ++i, textureRecord += Qtdf::TextureRecordSize) {
-            if (textureRecord + Qtdf::TextureRecordSize > qtdfTableEnd) {
+            if (qtdfTableEnd - textureRecord < Qtdf::TextureRecordSize) {
                 qWarning("qtdf table too small in font '%s'.",
                          qPrintable(font.familyName()));
                 return false;
@@ -462,7 +462,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
 
         const char *glyphRecord = textureRecord;
         for (quint32 i = 0; i < glyphCount; ++i, glyphRecord += Qtdf::GlyphRecordSize) {
-            if (glyphRecord + Qtdf::GlyphRecordSize > qtdfTableEnd) {
+            if (qtdfTableEnd - glyphRecord < Qtdf:: GlyphRecordSize) {
                 qWarning("qtdf table too small in font '%s'.",
                          qPrintable(font.familyName()));
                 return false;
@@ -512,8 +512,8 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
 
             int width = texInfo->allocatedArea.width();
             int height = texInfo->allocatedArea.height();
-            qint64 size = width * height;
-            if (reinterpret_cast<const char *>(textureData + size) > qtdfTableEnd) {
+            qint64 size = qint64(width) * height;
+            if (qtdfTableEnd - reinterpret_cast<const char *>(textureData) < size) {
                 qWarning("qtdf table too small in font '%s'.",
                          qPrintable(font.familyName()));
                 return false;
diff --git a/src/quick/util/qquickstyledtext.cpp b/src/quick/util/qquickstyledtext.cpp
index d531fc9205..a25af90414 100644
--- a/src/quick/util/qquickstyledtext.cpp
+++ b/src/quick/util/qquickstyledtext.cpp
@@ -564,6 +564,8 @@ void QQuickStyledTextPrivate::parseEntity(const QChar *&ch, const QString &textI
                 textOut += QChar(60);
             else if (entity == QLatin1String("amp"))
                 textOut += QChar(38);
+            else if (entity == QLatin1String("apos"))
+                textOut += QChar(39);
             else if (entity == QLatin1String("quot"))
                 textOut += QChar(34);
             else if (entity == QLatin1String("nbsp"))
diff --git a/src/quickwidgets/qaccessiblequickwidget.cpp b/src/quickwidgets/qaccessiblequickwidget.cpp
new file mode 100644
index 0000000000..8a1c901880
--- /dev/null
+++ b/src/quickwidgets/qaccessiblequickwidget.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaccessiblequickwidget_p.h"
+
+#include "qquickwidget_p.h"
+
+QT_BEGIN_NAMESPACE
+
+#if QT_CONFIG(accessibility)
+
+QAccessibleQuickWidget::QAccessibleQuickWidget(QQuickWidget* widget)
+: QAccessibleWidget(widget)
+, m_accessibleWindow(QQuickWidgetPrivate::get(widget)->offscreenWindow)
+{
+    // NOTE: m_accessibleWindow is a QAccessibleQuickWindow, and not a
+    // QAccessibleQuickWidgetOffscreenWindow (defined below). This means
+    // it will return the Quick item child interfaces, which is what's needed here
+    // (unlike QAccessibleQuickWidgetOffscreenWindow, which will report 0 children).
+}
+
+QAccessibleInterface *QAccessibleQuickWidget::child(int index) const
+{
+    return m_accessibleWindow.child(index);
+}
+
+int QAccessibleQuickWidget::childCount() const
+{
+    return m_accessibleWindow.childCount();
+}
+
+int QAccessibleQuickWidget::indexOfChild(const QAccessibleInterface *iface) const
+{
+    return m_accessibleWindow.indexOfChild(iface);
+}
+
+QAccessibleInterface *QAccessibleQuickWidget::childAt(int x, int y) const
+{
+    return m_accessibleWindow.childAt(x, y);
+}
+
+QAccessibleQuickWidgetOffscreenWindow::QAccessibleQuickWidgetOffscreenWindow(QQuickWindow *window)
+:QAccessibleQuickWindow(window)
+{
+
+}
+
+QAccessibleInterface *QAccessibleQuickWidgetOffscreenWindow::child(int index) const
+{
+    Q_UNUSED(index);
+    return nullptr;
+}
+
+int QAccessibleQuickWidgetOffscreenWindow::childCount() const
+{
+    return 0;
+}
+
+int QAccessibleQuickWidgetOffscreenWindow::indexOfChild(const QAccessibleInterface *iface) const
+{
+    Q_UNUSED(iface);
+    return -1;
+}
+
+QAccessibleInterface *QAccessibleQuickWidgetOffscreenWindow::QAccessibleQuickWidgetOffscreenWindow::childAt(int x, int y) const
+{
+    Q_UNUSED(x);
+    Q_UNUSED(y);
+    return nullptr;
+}
+
+#endif // accessibility
+
+QT_END_NAMESPACE
diff --git a/src/quickwidgets/qaccessiblequickwidget_p.h b/src/quickwidgets/qaccessiblequickwidget_p.h
new file mode 100644
index 0000000000..7c2ab930e0
--- /dev/null
+++ b/src/quickwidgets/qaccessiblequickwidget_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QACCESSIBLEQUICKWIDGET_H
+#define QACCESSIBLEQUICKWIDGET_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 "qquickwidget.h"
+#include <QtWidgets/qaccessiblewidget.h>
+
+#include <private/qaccessiblequickview_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#if QT_CONFIG(accessibility)
+
+// These classes implement the QQuickWiget accessibility switcharoo,
+// where the child items of the QQuickWidgetOffscreenWindow are reported
+// as child accessible interfaces of the QAccessibleQuickWidget.
+class QAccessibleQuickWidget: public QAccessibleWidget
+{
+public:
+    QAccessibleQuickWidget(QQuickWidget* widget);
+
+    QAccessibleInterface *child(int index) const override;
+    int childCount() const override;
+    int indexOfChild(const QAccessibleInterface *iface) const override;
+    QAccessibleInterface *childAt(int x, int y) const override;
+
+private:
+    QAccessibleQuickWindow m_accessibleWindow;
+    Q_DISABLE_COPY(QAccessibleQuickWidget)
+};
+
+class QAccessibleQuickWidgetOffscreenWindow: public QAccessibleQuickWindow
+{
+public:
+    QAccessibleQuickWidgetOffscreenWindow(QQuickWindow *window);
+    QAccessibleInterface *child(int index) const override;
+    int childCount() const override;
+    int indexOfChild(const QAccessibleInterface *iface) const override;
+    QAccessibleInterface *childAt(int x, int y) const override;
+};
+
+#endif // accessibility
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/quickwidgets/qaccessiblequickwidgetfactory.cpp b/src/quickwidgets/qaccessiblequickwidgetfactory.cpp
new file mode 100644
index 0000000000..7ba88a1769
--- /dev/null
+++ b/src/quickwidgets/qaccessiblequickwidgetfactory.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaccessiblequickwidgetfactory_p.h"
+#include "qaccessiblequickwidget_p.h"
+
+QT_BEGIN_NAMESPACE
+
+#if QT_CONFIG(accessibility)
+
+QAccessibleInterface *qAccessibleQuickWidgetFactory(const QString &classname, QObject *object)
+{
+    if (classname == QLatin1String("QQuickWidget")) {
+        return new QAccessibleQuickWidget(qobject_cast<QQuickWidget *>(object));
+    } else if (classname == QLatin1String("QQuickWidgetOffscreenWindow")) {
+        return new QAccessibleQuickWidgetOffscreenWindow(qobject_cast<QQuickWindow *>(object));
+    }
+    return 0;
+}
+
+#endif // accessibility
+
+QT_END_NAMESPACE
+
diff --git a/src/quickwidgets/qaccessiblequickwidgetfactory_p.h b/src/quickwidgets/qaccessiblequickwidgetfactory_p.h
new file mode 100644
index 0000000000..8c63b09f81
--- /dev/null
+++ b/src/quickwidgets/qaccessiblequickwidgetfactory_p.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qaccessible.h>
+
+#ifndef QACCESSIBLEQUICKWIDGETFACTORY_H
+#define QACCESSIBLEQUICKWIDGETFACTORY_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.
+//
+
+QT_BEGIN_NAMESPACE
+
+#if QT_CONFIG(accessibility)
+
+QAccessibleInterface *qAccessibleQuickWidgetFactory(const QString &classname, QObject *object);
+
+#endif
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp
index 39780f8de3..9c97b43518 100644
--- a/src/quickwidgets/qquickwidget.cpp
+++ b/src/quickwidgets/qquickwidget.cpp
@@ -39,6 +39,7 @@
 
 #include "qquickwidget.h"
 #include "qquickwidget_p.h"
+#include "qaccessiblequickwidgetfactory_p.h"
 
 #include "private/qquickwindow_p.h"
 #include "private/qquickitem_p.h"
@@ -75,9 +76,16 @@
 
 QT_BEGIN_NAMESPACE
 
+QQuickWidgetOffscreenWindow::QQuickWidgetOffscreenWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control)
+:QQuickWindow(dd, control)
+{
+    setTitle(QString::fromLatin1("Offscreen"));
+    setObjectName(QString::fromLatin1("QQuickOffScreenWindow"));
+}
+
 // override setVisble to prevent accidental offscreen window being created
 // by base class.
-class QQuickOffcreenWindowPrivate: public QQuickWindowPrivate {
+class QQuickWidgetOffscreenWindowPrivate: public QQuickWindowPrivate {
 public:
     void setVisible(bool visible) override {
         Q_Q(QWindow);
@@ -105,9 +113,8 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
     Q_Q(QQuickWidget);
 
     renderControl = new QQuickWidgetRenderControl(q);
-    offscreenWindow = new QQuickWindow(*new QQuickOffcreenWindowPrivate(),renderControl);
-    offscreenWindow->setTitle(QString::fromLatin1("Offscreen"));
-    offscreenWindow->setObjectName(QString::fromLatin1("QQuickOffScreenWindow"));
+    offscreenWindow = new QQuickWidgetOffscreenWindow(*new QQuickWidgetOffscreenWindowPrivate(), renderControl);
+    offscreenWindow->setScreen(q->screen());
     // Do not call create() on offscreenWindow.
 
     // Check if the Software Adaptation is being used
@@ -138,6 +145,10 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
     QWidget::connect(offscreenWindow, &QQuickWindow::focusObjectChanged, q, &QQuickWidget::propagateFocusObjectChanged);
     QObject::connect(renderControl, SIGNAL(renderRequested()), q, SLOT(triggerUpdate()));
     QObject::connect(renderControl, SIGNAL(sceneChanged()), q, SLOT(triggerUpdate()));
+
+#if QT_CONFIG(accessibility)
+    QAccessible::installFactory(&qAccessibleQuickWidgetFactory);
+#endif
 }
 
 void QQuickWidgetPrivate::ensureEngine() const
@@ -901,9 +912,7 @@ void QQuickWidgetPrivate::createContext()
 
         context = new QOpenGLContext;
         context->setFormat(offscreenWindow->requestedFormat());
-        const QWindow *win = q->window()->windowHandle();
-        if (win && win->screen())
-            context->setScreen(win->screen());
+        context->setScreen(q->screen());
         QOpenGLContext *shareContext = qt_gl_global_share_context();
         if (!shareContext)
             shareContext = QWidgetPrivate::get(q->window())->shareContext();
@@ -1520,19 +1529,16 @@ bool QQuickWidget::event(QEvent *e)
         d->handleWindowChange();
         break;
 
-    case QEvent::ScreenChangeInternal:
-        if (QWindow *window = this->window()->windowHandle()) {
-            QScreen *newScreen = window->screen();
-
-            if (d->offscreenWindow)
-                d->offscreenWindow->setScreen(newScreen);
-            if (d->offscreenSurface)
-                d->offscreenSurface->setScreen(newScreen);
+    case QEvent::ScreenChangeInternal: {
+        QScreen *newScreen = screen();
+        if (d->offscreenWindow)
+            d->offscreenWindow->setScreen(newScreen);
+        if (d->offscreenSurface)
+            d->offscreenSurface->setScreen(newScreen);
 #if QT_CONFIG(opengl)
-            if (d->context)
-                d->context->setScreen(newScreen);
+        if (d->context)
+            d->context->setScreen(newScreen);
 #endif
-        }
 
         if (d->useSoftwareRenderer
 #if QT_CONFIG(opengl)
@@ -1545,7 +1551,7 @@ bool QQuickWidget::event(QEvent *e)
             d->render(true);
         }
         break;
-
+    }
     case QEvent::Show:
     case QEvent::Move:
         d->updatePosition();
diff --git a/src/quickwidgets/qquickwidget_p.h b/src/quickwidgets/qquickwidget_p.h
index 881f7f9220..1a946bcc71 100644
--- a/src/quickwidgets/qquickwidget_p.h
+++ b/src/quickwidgets/qquickwidget_p.h
@@ -148,6 +148,14 @@ public:
     bool forceFullUpdate;
 };
 
+class QQuickWidgetOffscreenWindow: public QQuickWindow
+{
+    Q_OBJECT
+
+public:
+    QQuickWidgetOffscreenWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control);
+};
+
 QT_END_NAMESPACE
 
 #endif // QQuickWidget_P_H
diff --git a/src/quickwidgets/quickwidgets.pro b/src/quickwidgets/quickwidgets.pro
index 2438e577ae..85d156b8a3 100644
--- a/src/quickwidgets/quickwidgets.pro
+++ b/src/quickwidgets/quickwidgets.pro
@@ -7,9 +7,13 @@ DEFINES   += QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES QT_NO_FO
 HEADERS += \
     qquickwidget.h \
     qquickwidget_p.h \
-    qtquickwidgetsglobal.h
+    qtquickwidgetsglobal.h \
+    qaccessiblequickwidget_p.h \
+    qaccessiblequickwidgetfactory_p.h
 
 SOURCES += \
-    qquickwidget.cpp
+    qquickwidget.cpp \
+    qaccessiblequickwidget.cpp \
+    qaccessiblequickwidgetfactory.cpp
 
 load(qt_module)
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index 3b7d74df63..b75bf820d5 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -102,6 +102,7 @@ private slots:
     void valueConversion_RegularExpression();
     void castWithMultipleInheritance();
     void collectGarbage();
+    void collectGarbageNestedWrappersTwoEngines();
     void gcWithNestedDataStructure();
     void stacktrace();
     void numberParsing_data();
@@ -1809,6 +1810,44 @@ void tst_QJSEngine::collectGarbage()
     QVERIFY(ptr.isNull());
 }
 
+class TestObjectContainer : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(QObject *dummy MEMBER m_dummy CONSTANT)
+
+public:
+    TestObjectContainer() : m_dummy(new QObject(this)) {}
+
+private:
+    QObject *m_dummy;
+};
+
+void tst_QJSEngine::collectGarbageNestedWrappersTwoEngines()
+{
+    QJSEngine engine1;
+    QJSEngine engine2;
+
+    TestObjectContainer container;
+    QQmlEngine::setObjectOwnership(&container, QQmlEngine::CppOwnership);
+
+    engine1.globalObject().setProperty("foobar", engine1.newQObject(&container));
+    engine2.globalObject().setProperty("foobar", engine2.newQObject(&container));
+
+    engine1.evaluate("foobar.dummy.baz = 42");
+    engine2.evaluate("foobar.dummy.baz = 43");
+
+    QCOMPARE(engine1.evaluate("foobar.dummy.baz").toInt(), 42);
+    QCOMPARE(engine2.evaluate("foobar.dummy.baz").toInt(), 43);
+
+    engine1.collectGarbage();
+    engine2.collectGarbage();
+
+    // The GC should not collect dummy object wrappers neither in engine1 nor engine2, we
+    // verify that by checking whether the baz property still has its previous value.
+    QCOMPARE(engine1.evaluate("foobar.dummy.baz").toInt(), 42);
+    QCOMPARE(engine2.evaluate("foobar.dummy.baz").toInt(), 43);
+}
+
 void tst_QJSEngine::gcWithNestedDataStructure()
 {
     // The GC must be able to traverse deeply nested objects, otherwise this
diff --git a/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml b/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml
new file mode 100644
index 0000000000..206133bb39
--- /dev/null
+++ b/tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.8
+
+ListView {
+    id: root
+    width: 200
+    height: 200
+
+    delegate: Text {
+        text: display
+    }
+}
diff --git a/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp b/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
index 35f1e2c94d..1722447830 100644
--- a/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
+++ b/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
@@ -27,6 +27,8 @@
 ****************************************************************************/
 
 #include <QtTest/qtest.h>
+#include <QtCore/QConcatenateTablesProxyModel>
+#include <QtGui/QStandardItemModel>
 #include <QtQml/qqmlcomponent.h>
 #include <QtQmlModels/private/qqmldelegatemodel_p.h>
 #include <QtQuick/qquickview.h>
@@ -47,6 +49,7 @@ private slots:
     void filterOnGroup_removeWhenCompleted();
     void qtbug_86017();
     void contextAccessedByHandler();
+    void redrawUponColumnChange();
 };
 
 class AbstractItemModel : public QAbstractItemModel
@@ -186,6 +189,30 @@ void tst_QQmlDelegateModel::contextAccessedByHandler()
     QVERIFY(root->property("works").toBool());
 }
 
+void tst_QQmlDelegateModel::redrawUponColumnChange()
+{
+    QStandardItemModel m1;
+    m1.appendRow({
+            new QStandardItem("Banana"),
+            new QStandardItem("Coconut"),
+    });
+
+    QQuickView view(testFileUrl("redrawUponColumnChange.qml"));
+    QCOMPARE(view.status(), QQuickView::Ready);
+    view.show();
+    QQuickItem *root = view.rootObject();
+    root->setProperty("model", QVariant::fromValue<QObject *>(&m1));
+
+    QObject *item = root->property("currentItem").value<QObject *>();
+    QVERIFY(item);
+    QCOMPARE(item->property("text").toString(), "Banana");
+
+    QVERIFY(root);
+    m1.removeColumn(0);
+
+    QCOMPARE(item->property("text").toString(), "Coconut");
+}
+
 QTEST_MAIN(tst_QQmlDelegateModel)
 
 #include "tst_qqmldelegatemodel.moc"
diff --git a/tests/auto/qml/qqmllanguage/data/Broken.qml b/tests/auto/qml/qqmllanguage/data/Broken.qml
new file mode 100644
index 0000000000..e24d9112a8
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/Broken.qml
@@ -0,0 +1,5 @@
+import QtQml 2.15
+
+QtObject {
+    notThere: 5
+}
diff --git a/tests/auto/qml/qqmllanguage/data/asBroken.qml b/tests/auto/qml/qqmllanguage/data/asBroken.qml
new file mode 100644
index 0000000000..bd88d14c76
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/asBroken.qml
@@ -0,0 +1,6 @@
+import QtQml 2.15
+
+QtObject {
+    id: self
+    property var selfAsBroken: self as Broken
+}
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index bffb62c59e..97cc64991f 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -336,6 +336,7 @@ private slots:
     void bareInlineComponent();
 
     void hangOnWarning();
+    void objectAsBroken();
 
     void ambiguousContainingType();
 
@@ -5876,6 +5877,21 @@ void tst_qqmllanguage::ambiguousContainingType()
     }
 }
 
+void tst_qqmllanguage::objectAsBroken()
+{
+    QQmlEngine engine;
+    QQmlComponent c(&engine, testFileUrl("asBroken.qml"));
+    QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+    QScopedPointer<QObject> o(c.create());
+    QVERIFY(!o.isNull());
+    QVariant selfAsBroken = o->property("selfAsBroken");
+    QVERIFY(selfAsBroken.isValid());
+    // QCOMPARE(selfAsBroken.metaType(), QMetaType::fromType<std::nullptr_t>());
+
+    QQmlComponent b(&engine, testFileUrl("Broken.qml"));
+    QVERIFY(b.isError());
+}
+
 QTEST_MAIN(tst_qqmllanguage)
 
 #include "tst_qqmllanguage.moc"
diff --git a/tests/auto/qml/qv4mm/tst_qv4mm.cpp b/tests/auto/qml/qv4mm/tst_qv4mm.cpp
index 5d635aa63b..824fd89e5b 100644
--- a/tests/auto/qml/qv4mm/tst_qv4mm.cpp
+++ b/tests/auto/qml/qv4mm/tst_qv4mm.cpp
@@ -76,10 +76,10 @@ void tst_qv4mm::multiWrappedQObjects()
         QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 1);
         QCOMPARE(engine2.memoryManager->m_pendingFreedObjectWrapperValue.size(), 0);
 
-        // Moves the additional WeakValue from m_multiplyWrappedQObjects to
-        // m_pendingFreedObjectWrapperValue. It's still alive after all.
+        // The additional WeakValue from m_multiplyWrappedQObjects hasn't been moved
+        // to m_pendingFreedObjectWrapperValue yet. It's still alive after all.
         engine1.memoryManager->runGC();
-        QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 2);
+        QCOMPARE(engine1.memoryManager->m_pendingFreedObjectWrapperValue.size(), 1);
 
         // engine2 doesn't own the object as engine1 was the first to wrap it above.
         // Therefore, no effect here.
diff --git a/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml b/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml
new file mode 100644
index 0000000000..889e480f3b
--- /dev/null
+++ b/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.6
+
+Item {
+    visible: true
+    Item {
+        visible: false
+        Item {
+            objectName: "hiddenChild"
+            activeFocusOnTab: true
+            focus: true
+        }
+    }
+}
diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
index c8f251dbe1..c8ef36ee68 100644
--- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
@@ -67,6 +67,7 @@ private slots:
     void activeFocusOnTab10();
     void activeFocusOnTab_infiniteLoop_data();
     void activeFocusOnTab_infiniteLoop();
+    void activeFocusOnTab_infiniteLoopControls();
 
     void nextItemInFocusChain();
     void nextItemInFocusChain2();
@@ -1057,6 +1058,17 @@ void tst_QQuickItem::activeFocusOnTab_infiniteLoop()
     QCOMPARE(item, window->rootObject());
 }
 
+
+void tst_QQuickItem::activeFocusOnTab_infiniteLoopControls()
+{
+    auto source = testFileUrl("activeFocusOnTab_infiniteLoop3.qml");
+    QScopedPointer<QQuickView>window(new QQuickView());
+    window->setSource(source);
+    window->show();
+    QVERIFY(window->errors().isEmpty());
+    QTest::keyClick(window.get(), Qt::Key_Tab); // should not hang
+}
+
 void tst_QQuickItem::nextItemInFocusChain()
 {
     if (!qt_tab_all_widgets())
 
design & coding: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
current maintainer: Michael Shigorin