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::isComplex) { for (int i = 0; i < count; ++i) new (data + i) T(vector.at(i)); - } else { + } else if (count) { memcpy(data, static_cast(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 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)), q, QQmlDelegateModel, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector))); 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)), q, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector))); 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()); + } +} + +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()); + } +} + +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()); + } +} + void QQmlDelegateModel::_q_dataChanged(const QModelIndex &begin, const QModelIndex &end, const QVector &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(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(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 #include #include +#include #include #include @@ -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 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 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() - inline images
    ,
      and
    • - ordered and unordered lists
       - preformatted
      -    > < &
      +    > < & "   '
           \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(textureData + size) > qtdfTableEnd) {
      +            qint64 size = qint64(width) * height;
      +            if (qtdfTableEnd - reinterpret_cast(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 
      +
      +#include 
      +
      +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(object));
      +    } else if (classname == QLatin1String("QQuickWidgetOffscreenWindow")) {
      +        return new QAccessibleQuickWidgetOffscreenWindow(qobject_cast(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 
      +
      +#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 
      +#include 
      +#include 
       #include 
       #include 
       #include 
      @@ -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(&m1));
      +
      +    QObject *item = root->property("currentItem").value();
      +    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 o(c.create());
      +    QVERIFY(!o.isNull());
      +    QVariant selfAsBroken = o->property("selfAsBroken");
      +    QVERIFY(selfAsBroken.isValid());
      +    // QCOMPARE(selfAsBroken.metaType(), QMetaType::fromType());
      +
      +    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");
      +    QScopedPointerwindow(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())