summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKari Oikarinen <kari.oikarinen@qt.io>2020-01-15 19:08:34 +0200
committerKari Oikarinen <kari.oikarinen@qt.io>2020-01-15 19:08:34 +0200
commit51a158929b55dffbdfb757da8bd6a2cd181906c6 (patch)
treed887ef986f357614624d65277f94d740c410be21
parent3a06d02197179240b8ea589534dc3416c75fc0f2 (diff)
parent3f8bcced6790059c279430ff34903c16bea25a98 (diff)
Merge 5.14 into 5.14.1v5.14.15.14.1
-rw-r--r--src/imports/qtquick2/plugins.qmltypes1
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.cpp17
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.h4
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp4
-rw-r--r--src/qml/qml/qqmlengine.cpp4
-rw-r--r--src/quick/handlers/qquickmultipointhandler_p.h1
-rw-r--r--src/quick/handlers/qquickwheelhandler.cpp9
-rw-r--r--src/quick/items/qquickevents.cpp133
-rw-r--r--src/quick/items/qquickitemsmodule.cpp4
-rw-r--r--src/quick/items/qquickitemview.cpp36
-rw-r--r--src/quick/items/qquickitemview_p_p.h1
-rw-r--r--src/quick/scenegraph/qsgrhitextureglyphcache.cpp2
-rw-r--r--tests/auto/qml/qqmlengine/data/evilSingletonInstantiation.qml6
-rw-r--r--tests/auto/qml/qqmlengine/tst_qqmlengine.cpp31
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST1
-rw-r--r--tests/auto/quick/qquicklistview/data/changeModelAndDestroyTheOldOne.qml34
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp16
-rw-r--r--tests/auto/quick/touchmouse/BLACKLIST4
18 files changed, 277 insertions, 31 deletions
diff --git a/src/imports/qtquick2/plugins.qmltypes b/src/imports/qtquick2/plugins.qmltypes
index 0ba918e34e..fffe03ad73 100644
--- a/src/imports/qtquick2/plugins.qmltypes
+++ b/src/imports/qtquick2/plugins.qmltypes
@@ -3340,7 +3340,6 @@ Module {
Property { name: "minimumPointCount"; type: "int" }
Property { name: "maximumPointCount"; type: "int" }
Property { name: "centroid"; type: "QQuickHandlerPoint"; isReadonly: true }
- Signal { name: "marginChanged" }
}
Component {
name: "QQuickMultiPointTouchArea"
diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.cpp b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.cpp
index d4acd24da5..52e197b1ed 100644
--- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.cpp
+++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.cpp
@@ -51,7 +51,7 @@ static QVector<QQmlPreviewPosition::ScreenData> initScreensData()
QVector<QQmlPreviewPosition::ScreenData> screensData;
for (QScreen *screen : QGuiApplication::screens()) {
- QQmlPreviewPosition::ScreenData sd{screen->name(), screen->size()};
+ QQmlPreviewPosition::ScreenData sd{screen->name(), screen->geometry()};
screensData.append(sd);
}
return screensData;
@@ -69,20 +69,20 @@ static QScreen *findScreen(const QString &nameOfScreen)
static QDataStream &operator<<(QDataStream &out, const QQmlPreviewPosition::ScreenData &screenData)
{
out << screenData.name;
- out << screenData.size;
+ out << screenData.rect;
return out;
}
static QDataStream &operator>>(QDataStream &in, QQmlPreviewPosition::ScreenData &screenData)
{
in >> screenData.name;
- in >> screenData.size;
+ in >> screenData.rect;
return in;
}
bool QQmlPreviewPosition::ScreenData::operator==(const QQmlPreviewPosition::ScreenData &other) const
{
- return other.size == size && other.name == name;
+ return other.rect == rect && other.name == name;
}
QQmlPreviewPosition::QQmlPreviewPosition()
@@ -211,8 +211,13 @@ void QQmlPreviewPosition::setPosition(const QQmlPreviewPosition::Position &posit
return;
if (QScreen *screen = findScreen(position.screenName)) {
window->setScreen(screen);
- window->setFramePosition(QHighDpiScaling::mapPositionFromNative(position.nativePosition,
- screen->handle()));
+ const auto point = QHighDpiScaling::mapPositionFromNative(position.nativePosition,
+ screen->handle());
+ const QRect geometry(point, window->size());
+ if (screen->virtualGeometry().contains(geometry))
+ window->setFramePosition(point);
+ else
+ qWarning("preview position is out of screen");
}
}
diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.h b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.h
index f403917f8c..9d84170948 100644
--- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.h
+++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.h
@@ -56,7 +56,7 @@
#include <QtCore/qurl.h>
#include <QtCore/qtimer.h>
#include <QtCore/qsettings.h>
-#include <QtCore/qsize.h>
+#include <QtCore/qrect.h>
#include <QtCore/qdatastream.h>
QT_BEGIN_NAMESPACE
@@ -70,7 +70,7 @@ public:
public:
bool operator==(const QQmlPreviewPosition::ScreenData &other) const;
QString name;
- QSize size;
+ QRect rect;
};
class Position {
public:
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index 5055e13223..5a1b27fda6 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -310,8 +310,10 @@ public:
return false;
}
- if (d()->isReadOnly)
+ if (d()->isReadOnly) {
+ engine()->throwTypeError(QLatin1String("Cannot insert into a readonly container"));
return false;
+ }
if (d()->isReference) {
if (!d()->object)
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 2f4abca4b2..93964ac76f 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -1034,8 +1034,6 @@ QQmlEngine::~QQmlEngine()
Q_D(QQmlEngine);
QJSEnginePrivate::removeFromDebugServer(this);
- d->typeLoader.invalidate();
-
// Emit onDestruction signals for the root context before
// we destroy the contexts, engine, Singleton Types etc. that
// may be required to handle the destruction signal.
@@ -1051,6 +1049,8 @@ QQmlEngine::~QQmlEngine()
delete d->rootContext;
d->rootContext = nullptr;
+
+ d->typeLoader.invalidate();
}
/*! \fn void QQmlEngine::quit()
diff --git a/src/quick/handlers/qquickmultipointhandler_p.h b/src/quick/handlers/qquickmultipointhandler_p.h
index 480f69035b..c0751aa5c5 100644
--- a/src/quick/handlers/qquickmultipointhandler_p.h
+++ b/src/quick/handlers/qquickmultipointhandler_p.h
@@ -81,7 +81,6 @@ public:
signals:
void minimumPointCountChanged();
void maximumPointCountChanged();
- void marginChanged();
void centroidChanged();
protected:
diff --git a/src/quick/handlers/qquickwheelhandler.cpp b/src/quick/handlers/qquickwheelhandler.cpp
index aef2e8ebfb..16f38af962 100644
--- a/src/quick/handlers/qquickwheelhandler.cpp
+++ b/src/quick/handlers/qquickwheelhandler.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -500,6 +500,13 @@ void QQuickWheelHandler::timerEvent(QTimerEvent *event)
}
}
+/*!
+ \qmlsignal QtQuick::WheelHandler::wheel(PointerScrollEvent event)
+
+ This signal is emitted every time this handler receives a \l QWheelEvent:
+ that is, every time the wheel is moved or the scrolling gesture is updated.
+*/
+
QQuickWheelHandlerPrivate::QQuickWheelHandlerPrivate()
: QQuickSinglePointHandlerPrivate()
{
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index 0c697739fa..b5644d55e6 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -448,7 +448,7 @@ Item {
*/
/*!
- \qmlproperty int QtQuick::WheelEvent::inverted
+ \qmlproperty bool QtQuick::WheelEvent::inverted
Returns whether the delta values delivered with the event are inverted.
@@ -1431,6 +1431,135 @@ QQuickEventPoint *QQuickSinglePointEvent::point(int i) const
return nullptr;
}
+
+/*!
+ \qmltype PointerScrollEvent
+ \instantiates QQuickPointerScrollEvent
+ \inqmlmodule QtQuick
+ \ingroup qtquick-input-events
+ \brief Provides information about a scrolling event, such as from a mouse wheel.
+
+ \sa WheelHandler
+*/
+
+/*!
+ \internal
+ \class QQuickPointerScrollEvent
+*/
+
+/*!
+ \readonly
+ \qmlproperty PointerDevice QtQuick::PointerScrollEvent::device
+
+ This property holds the device that generated the event.
+*/
+
+/*!
+ \qmlproperty int QtQuick::PointerScrollEvent::buttons
+
+ This property holds the mouse buttons pressed when the wheel event was generated.
+
+ It contains a bitwise combination of:
+ \list
+ \li \l {Qt::LeftButton} {Qt.LeftButton}
+ \li \l {Qt::RightButton} {Qt.RightButton}
+ \li \l {Qt::MiddleButton} {Qt.MiddleButton}
+ \endlist
+*/
+
+/*!
+ \readonly
+ \qmlproperty int QtQuick::PointerScrollEvent::modifiers
+
+ This property holds the \l {Qt::KeyboardModifier}{keyboard modifier} keys
+ that were pressed immediately before the event occurred.
+
+ It contains a bitwise combination of the following flags:
+ \value Qt.NoModifier
+ No modifier key is pressed.
+ \value Qt.ShiftModifier
+ A Shift key on the keyboard is pressed.
+ \value Qt.ControlModifier
+ A Ctrl key on the keyboard is pressed.
+ \value Qt.AltModifier
+ An Alt key on the keyboard is pressed.
+ \value Qt.MetaModifier
+ A Meta key on the keyboard is pressed.
+ \value Qt.KeypadModifier
+ A keypad button is pressed.
+
+ For example, to react to a Shift key + Left mouse button click:
+ \qml
+ Item {
+ TapHandler {
+ onTapped: {
+ if ((event.button == Qt.LeftButton) && (event.modifiers & Qt.ShiftModifier))
+ doSomething();
+ }
+ }
+ }
+ \endqml
+*/
+
+/*!
+ \qmlproperty point QtQuick::PointerScrollEvent::angleDelta
+
+ This property holds the distance that the wheel is rotated in wheel degrees.
+ The x and y cordinate of this property holds the delta in horizontal and
+ vertical orientation.
+
+ A positive value indicates that the wheel was rotated up/right;
+ a negative value indicates that the wheel was rotated down/left.
+
+ Most mouse types work in steps of 15 degrees, in which case the delta value is a
+ multiple of 120; i.e., 120 units * 1/8 = 15 degrees.
+*/
+
+/*!
+ \qmlproperty point QtQuick::PointerScrollEvent::pixelDelta
+
+ This property holds the delta in screen pixels and is available in platforms that
+ have high-resolution trackpads, such as \macos.
+ The x and y coordinates of this property hold the delta in horizontal and
+ vertical orientation. The value should be used directly to scroll content on screen.
+
+ For platforms without high-resolution touchpad support, pixelDelta will
+ always be (0,0), and angleDelta should be used instead.
+*/
+
+/*!
+ \qmlproperty bool QtQuick::PointerScrollEvent::hasAngleDelta
+
+ Returns whether the \l angleDelta property has a non-null value.
+*/
+
+/*!
+ \qmlproperty bool QtQuick::PointerScrollEvent::hasPixelDelta
+
+ Returns whether the \l pixelDelta property has a non-null value.
+*/
+
+/*!
+ \qmlproperty bool QtQuick::PointerScrollEvent::inverted
+
+ Returns whether the delta values delivered with the event are inverted.
+
+ Normally, a vertical wheel will produce a PointerScrollEvent with positive delta
+ values if the top of the wheel is rotating away from the hand operating it.
+ Similarly, a horizontal wheel movement will produce a PointerScrollEvent with
+ positive delta values if the top of the wheel is moved to the left.
+
+ However, on some platforms this is configurable, so that the same
+ operations described above will produce negative delta values (but with the
+ same magnitude). In a QML component (such as a tumbler or a slider) where
+ it is appropriate to synchronize the movement or rotation of an item with
+ the direction of the wheel, regardless of the system settings, the wheel
+ event handler can use the inverted property to decide whether to negate the
+ \l angleDelta or \l pixelDelta values.
+
+ \note Many platforms provide no such information. On such platforms,
+ \c inverted always returns false.
+*/
QQuickPointerEvent *QQuickPointerScrollEvent::reset(QEvent *event)
{
m_event = static_cast<QInputEvent*>(event);
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index 7bc6eefe0a..86253e770f 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -494,6 +494,8 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
#endif
#if QT_CONFIG(wheelevent)
qmlRegisterType<QQuickWheelHandler>(uri, 2, 14, "WheelHandler");
+ qmlRegisterUncreatableType<QQuickPointerScrollEvent>(uri, 2, 14, "PointerScrollEvent",
+ QQuickPointerHandler::tr("PointerScrollEvent is only available via the WheelHandler::wheel signal"));
#endif
qmlRegisterUncreatableType<QQuickImageBase, 14>(uri, 2, 14, "ImageBase",
QQuickPointerHandler::tr("ImageBase is an abstract base class"));
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 66be3c79f8..a931abca58 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -1505,7 +1505,7 @@ QQuickItemViewPrivate::QQuickItemViewPrivate()
, inLayout(false), inViewportMoved(false), forceLayout(false), currentIndexCleared(false)
, haveHighlightRange(false), autoHighlight(true), highlightRangeStartValid(false), highlightRangeEndValid(false)
, fillCacheBuffer(false), inRequest(false)
- , runDelayedRemoveTransition(false), delegateValidated(false)
+ , runDelayedRemoveTransition(false), delegateValidated(false), isClearing(false)
{
bufferPause.addAnimationChangeListener(this, QAbstractAnimationJob::Completion);
bufferPause.setLoopCount(1);
@@ -1681,6 +1681,10 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex)
void QQuickItemViewPrivate::clear(bool onDestruction)
{
Q_Q(QQuickItemView);
+
+ isClearing = true;
+ auto cleanup = qScopeGuard([this] { isClearing = false; });
+
currentChanges.reset();
bufferedChanges.reset();
timeline.clear();
@@ -1908,21 +1912,25 @@ void QQuickItemViewPrivate::layout()
prepareVisibleItemTransitions();
- for (auto it = releasePendingTransition.begin(); it != releasePendingTransition.end(); ) {
- auto old_count = releasePendingTransition.count();
- auto success = prepareNonVisibleItemTransition(*it, viewBounds);
- // prepareNonVisibleItemTransition() may invalidate iterators while in fast flicking
- // invisible animating items are kicked in or out the viewPort
- // use old_count to test if the abrupt erasure occurs
- if (old_count > releasePendingTransition.count()) {
+ // We cannot use iterators here as erasing from a container invalidates them.
+ for (int i = 0, count = releasePendingTransition.count(); i < count;) {
+ auto success = prepareNonVisibleItemTransition(releasePendingTransition[i], viewBounds);
+ // prepareNonVisibleItemTransition() may remove items while in fast flicking.
+ // Invisible animating items are kicked in or out the viewPort.
+ // Recheck count to test if the item got removed. In that case the same index points
+ // to a different item now.
+ const int old_count = count;
+ count = releasePendingTransition.count();
+ if (old_count > count)
continue;
- }
+
if (!success) {
- releaseItem(*it);
- it = releasePendingTransition.erase(it);
- continue;
+ releaseItem(releasePendingTransition[i]);
+ releasePendingTransition.remove(i);
+ --count;
+ } else {
+ ++i;
}
- ++it;
}
for (int i=0; i<visibleItems.count(); i++)
@@ -2399,7 +2407,7 @@ bool QQuickItemViewPrivate::releaseItem(FxViewItem *item)
QQmlInstanceModel::ReleaseFlags flags = {};
if (model && item->item) {
flags = model->release(item->item);
- if (!flags) {
+ if (!flags && !isClearing) {
// item was not destroyed, and we no longer reference it.
if (item->item->parentItem() == contentItem) {
// Only cull the item if its parent item is still our contentItem.
diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h
index b31f53b2c0..a448cf9a38 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -316,6 +316,7 @@ public:
bool inRequest : 1;
bool runDelayedRemoveTransition : 1;
bool delegateValidated : 1;
+ bool isClearing : 1;
protected:
virtual Qt::Orientation layoutOrientation() const = 0;
diff --git a/src/quick/scenegraph/qsgrhitextureglyphcache.cpp b/src/quick/scenegraph/qsgrhitextureglyphcache.cpp
index d0108bc56e..89c9ea4d5b 100644
--- a/src/quick/scenegraph/qsgrhitextureglyphcache.cpp
+++ b/src/quick/scenegraph/qsgrhitextureglyphcache.cpp
@@ -145,7 +145,9 @@ void QSGRhiTextureGlyphCache::prepareGlyphImage(QImage *img)
{
const int maskWidth = img->width();
const int maskHeight = img->height();
+#if Q_BYTE_ORDER != Q_BIG_ENDIAN
const bool supportsBgra = m_rhi->isTextureFormatSupported(QRhiTexture::BGRA8);
+#endif
m_bgra = false;
if (img->format() == QImage::Format_Mono) {
diff --git a/tests/auto/qml/qqmlengine/data/evilSingletonInstantiation.qml b/tests/auto/qml/qqmlengine/data/evilSingletonInstantiation.qml
new file mode 100644
index 0000000000..757b0c90bb
--- /dev/null
+++ b/tests/auto/qml/qqmlengine/data/evilSingletonInstantiation.qml
@@ -0,0 +1,6 @@
+import QtQml 2.12
+import foo.foo 1.0
+
+QtObject {
+ objectName: Singleton.objectName
+}
diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
index 64f167b47e..613616ab71 100644
--- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
+++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
@@ -83,6 +83,7 @@ private slots:
void singletonInstance();
void aggressiveGc();
void cachedGetterLookup_qtbug_75335();
+ void createComponentOnSingletonDestruction();
public slots:
QObject *createAQObjectForOwnershipTest ()
@@ -1141,6 +1142,36 @@ void tst_qqmlengine::cachedGetterLookup_qtbug_75335()
QVERIFY(object != nullptr);
}
+class EvilSingleton : public QObject
+{
+ Q_OBJECT
+public:
+ QPointer<QQmlEngine> m_engine;
+ EvilSingleton(QQmlEngine *engine) : m_engine(engine) {
+ connect(this, &QObject::destroyed, this, [this]() {
+ QQmlComponent component(m_engine);
+ component.setData("import QtQml 2.0\nQtObject {}", QUrl("file://Stuff.qml"));
+ QVERIFY(component.isReady());
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(obj);
+ });
+ }
+};
+
+void tst_qqmlengine::createComponentOnSingletonDestruction()
+{
+ qmlRegisterSingletonType<EvilSingleton>("foo.foo", 1, 0, "Singleton",
+ [](QQmlEngine *engine, QJSEngine *) {
+ return new EvilSingleton(engine);
+ });
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("evilSingletonInstantiation.qml"));
+ QVERIFY(component.isReady());
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(obj);
+}
+
QTEST_MAIN(tst_qqmlengine)
#include "tst_qqmlengine.moc"
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST b/tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST
index 20f989fc50..92903955ac 100644
--- a/tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/BLACKLIST
@@ -1,5 +1,6 @@
[touchAndDragHandlerOnFlickable]
windows gcc
+opensuse-leap
[touchDragFlickableBehindSlider]
windows gcc
[touchDragFlickableBehindButton]
diff --git a/tests/auto/quick/qquicklistview/data/changeModelAndDestroyTheOldOne.qml b/tests/auto/quick/qquicklistview/data/changeModelAndDestroyTheOldOne.qml
new file mode 100644
index 0000000000..6a33decde6
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/data/changeModelAndDestroyTheOldOne.qml
@@ -0,0 +1,34 @@
+import QtQuick 2.13
+import QtQml 2.13
+import QtQml.Models 2.13
+
+Rectangle {
+ width: 640
+ height: 480
+ property var model1: null
+ property var model2: null
+ Component {
+ id: m1
+ ObjectModel {
+ Rectangle { height: 30; width: 80; color: "red" }
+ Rectangle { height: 30; width: 80; color: "green" }
+ Rectangle { height: 30; width: 80; color: "blue" }
+ }
+ }
+ Component {
+ id: m2
+ ObjectModel {
+ Rectangle { height: 30; width: 80; color: "red" }
+ }
+ }
+ ListView {
+ anchors.fill: parent
+ Component.onCompleted: {
+ model1 = m1.createObject()
+ model = model1
+ model2 = m2.createObject()
+ model = model2
+ model1.destroy()
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index 3976dbc0f0..3687c9416e 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -281,6 +281,7 @@ private slots:
void touchCancel();
void resizeAfterComponentComplete();
void moveObjectModelItemToAnotherObjectModel();
+ void changeModelAndDestroyTheOldOne();
private:
template <class T> void items(const QUrl &source);
@@ -9158,6 +9159,21 @@ void tst_QQuickListView::moveObjectModelItemToAnotherObjectModel()
QVERIFY(!QQuickItemPrivate::get(redRect)->culled);
}
+void tst_QQuickListView::changeModelAndDestroyTheOldOne() // QTBUG-80203
+{
+ QScopedPointer<QQuickView> window(createView());
+ window->setSource(testFileUrl("changeModelAndDestroyTheOldOne.qml"));
+ window->resize(640, 480);
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QQuickItem *root = window->rootObject();
+ QVERIFY(root);
+
+ QVERIFY(QQuickTest::qWaitForItemPolished(root));
+ // no crash
+}
+
QTEST_MAIN(tst_QQuickListView)
#include "tst_qquicklistview.moc"
diff --git a/tests/auto/quick/touchmouse/BLACKLIST b/tests/auto/quick/touchmouse/BLACKLIST
index 0dfe28087a..9afc86c2fe 100644
--- a/tests/auto/quick/touchmouse/BLACKLIST
+++ b/tests/auto/quick/touchmouse/BLACKLIST
@@ -4,3 +4,7 @@ windows gcc developer-build
# QTBUG-74517
[buttonOnFlickable]
windows gcc developer-build
+
+# QTBUG-74517
+[touchButtonOnFlickable]
+windows gcc developer-build