This was created by checking out qtdeclarative and checking out the
kf5 patches from kde.  For more details of those, see
https://dot.kde.org/2021/04/06/announcing-kdes-qt-5-patch-collection

 from kde:
 git clone https://invent.kde.org/qt/qt/qtdeclarative
 cd qtdeclarative
 git checkout -t origin/5.15
 git format-patch origin/5.15.2..origin/kde/5.15

To update for new patches, git pull and then rerun git format-patch.

Last updated: 2021-01-25

 Following patches commented:
 patch 01 would change the version to 5.15.3
 patches 02, 03, 04 already applied in 5.15.2.

#From 568763928a78b52373932b01be17e040f7c3fa50 Mon Sep 17 00:00:00 2001
#From: Jani Heikkinen <jani.heikkinen@qt.io>
#Date: Tue, 27 Oct 2020 07:48:21 +0200
#Subject: [PATCH 01/41] Bump version
#
#Change-Id: I58fee19a72cda6a19ba168f55caf764c73ffd1c8
#---
# .qmake.conf | 2 +-
# 1 file changed, 1 insertion(+), 1 deletion(-)
#
#diff --git a/.qmake.conf b/.qmake.conf
#index 85b893856b..4e82106546 100644
#--- a/.qmake.conf
#+++ b/.qmake.conf
#@@ -4,4 +4,4 @@ CONFIG += warning_clean
# DEFINES += QT_NO_LINKED_LIST
# DEFINES += QT_NO_JAVA_STYLE_ITERATORS
# 
#-MODULE_VERSION = 5.15.2
#+MODULE_VERSION = 5.15.3
#-- 
#2.33.0
#
#From 5652923d99166e942385eb35b778d26b55ab4b0a Mon Sep 17 00:00:00 2001
#From: Fabian Kosmale <fabian.kosmale@qt.io>
#Date: Tue, 27 Oct 2020 16:54:01 +0100
#Subject: [PATCH 02/41] Inline components: Fix custom parser support
#
#Fixes: QTBUG-85713
#Fixes: QTBUG-87464
#Change-Id: I5c190ad2d02190de90260042cc06e51c1da01c63
#Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io>
#Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
#(cherry picked from commit 2425cd478138c52694aaa20b7f7eb4a91d97b51c)
#Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
#---
# src/qml/qml/qqmltypecompiler.cpp                    |  6 ++++++
# .../qml/qqmllanguage/data/customParserTypeInIC.qml  | 13 +++++++++++++
# tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp    | 11 +++++++++++
# 3 files changed, 30 insertions(+)
# create mode 100644 tests/auto/qml/qqmllanguage/data/customParserTypeInIC.qml
#
#diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp
#index 058bf8848c..f1a6b3bff2 100644
#--- a/src/qml/qml/qqmltypecompiler.cpp
#+++ b/src/qml/qml/qqmltypecompiler.cpp
#@@ -683,6 +683,9 @@ QQmlCustomParserScriptIndexer::QQmlCustomParserScriptIndexer(QQmlTypeCompiler *t
# void QQmlCustomParserScriptIndexer::annotateBindingsWithScriptStrings()
# {
#     scanObjectRecursively(/*root object*/0);
#+    for (int i = 0; i < qmlObjects.size(); ++i)
#+        if (qmlObjects.at(i)->isInlineComponent)
#+            scanObjectRecursively(i);
# }
# 
# void QQmlCustomParserScriptIndexer::scanObjectRecursively(int objectIndex, bool annotateScriptBindings)
#@@ -1223,6 +1226,9 @@ QQmlDeferredAndCustomParserBindingScanner::QQmlDeferredAndCustomParserBindingSca
# 
# bool QQmlDeferredAndCustomParserBindingScanner::scanObject()
# {
#+    for (int i = 0; i < qmlObjects->size(); ++i)
#+        if (qmlObjects->at(i)->isInlineComponent)
#+            scanObject(i);
#     return scanObject(/*root object*/0);
# }
# 
#diff --git a/tests/auto/qml/qqmllanguage/data/customParserTypeInIC.qml b/tests/auto/qml/qqmllanguage/data/customParserTypeInIC.qml
#new file mode 100644
#index 0000000000..a29d87caa0
#--- /dev/null
#+++ b/tests/auto/qml/qqmllanguage/data/customParserTypeInIC.qml
#@@ -0,0 +1,13 @@
#+import QtQuick 2.15
#+
#+Item {
#+    property int count: myModel.count
#+    component MyModel : ListModel {
#+        ListElement { a: 10 }
#+        ListElement { a: 12 }
#+    }
#+
#+    MyModel {
#+        id: myModel
#+    }
#+}
#diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
#index e32fa884a2..8adcbc1837 100644
#--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
#+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
#@@ -111,6 +111,7 @@ private slots:
#     void bindJSValueToType();
#     void bindTypeToJSValue();
#     void customParserTypes();
#+    void customParserTypeInInlineComponent();
#     void rootAsQmlComponent();
#     void rootItemIsComponent();
#     void inlineQmlComponents();
#@@ -1313,6 +1314,16 @@ void tst_qqmllanguage::customParserTypes()
#     QCOMPARE(object->property("count"), QVariant(2));
# }
# 
#+// Tests that custom pursor types can be instantiated in ICs
#+void tst_qqmllanguage::customParserTypeInInlineComponent()
#+{
#+    QQmlComponent component(&engine, testFileUrl("customParserTypeInIC.qml"));
#+    VERIFY_ERRORS(0);
#+    QScopedPointer<QObject> object(component.create());
#+    QVERIFY(object != nullptr);
#+    QCOMPARE(object->property("count"), 2);
#+}
#+
# // Tests that the root item can be a custom component
# void tst_qqmllanguage::rootAsQmlComponent()
# {
#-- 
#2.33.0
#
#From be3a57263b7e9e03e01fa9dfe637f03ba557950b Mon Sep 17 00:00:00 2001
#From: Maximilian Goldstein <max.goldstein@qt.io>
#Date: Thu, 29 Oct 2020 16:25:23 +0100
#Subject: [PATCH 03/41] Revert "qquickloader: Free memory of loaded components
# after source change"
#
#This reverts commit c5085eb8905f1a3c070f866746110980e84be271.
#It can cause crashes and only fixes an edge case that can't
#be encountered during normal usage.
#
#Change-Id: Ia265f0d6716b59a0f483e5a114b3f3b1a76fe898
#Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
#(cherry picked from commit 0fa6091b1076bc3cc58303ff00d43efdad32b8ad)
#Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
#---
# src/quick/items/qquickloader.cpp | 13 -------------
# 1 file changed, 13 deletions(-)
#
#diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
#index 9a8eca871c..8cd63a4236 100644
#--- a/src/quick/items/qquickloader.cpp
#+++ b/src/quick/items/qquickloader.cpp
#@@ -412,19 +412,6 @@ void QQuickLoader::setSource(const QUrl &url)
# void QQuickLoader::setSource(const QUrl &url, bool needsClear)
# {
#     Q_D(QQuickLoader);
#-
#-    // The source has been changed at this point, and we assume that (after
#-    // notifying potential listeners with sourceChanged) that it is now
#-    // safe to actually delete the old component. We have to do this here
#-    // in case the component referenced expensive resources (like uncached
#-    // images), as it might take too long until we return to the event loop.
#-    // We need to explicitly pass QEvent::DeferredDelete to sendPostedEvents,
#-    // else the allowDeferredDelete check in qcoreapplication.cpp will not
#-    // allow the event to pass. This will not affect anything deleted by this
#-    // call, only the previous one. This has to be done as otherwise there
#-    // might be signal handlers that are still in progress.
#-    QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
#-
#     if (d->source == url)
#         return;
# 
#-- 
#2.33.0
#
#From d27e0cc2a41c229c5b4085b2d78c4328a82baecd Mon Sep 17 00:00:00 2001
#From: Antti Kokko <antti.kokko@qt.io>
#Date: Tue, 27 Oct 2020 10:02:12 +0200
#Subject: [PATCH 04/41] Add changes file for Qt 5.15.2
#
#Change-Id: I5bf32a9ba9f5e3f10f23ffe78bceecdfaa23fbc2
#Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
#Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
#(cherry picked from commit eaa6459984b723cb48b2617fcabab844109c16fa)
#Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
#---
# dist/changes-5.15.2 | 91 +++++++++++++++++++++++++++++++++++++++++++++
# 1 file changed, 91 insertions(+)
# create mode 100644 dist/changes-5.15.2
#
#diff --git a/dist/changes-5.15.2 b/dist/changes-5.15.2
#new file mode 100644
#index 0000000000..39b743a932
#--- /dev/null
#+++ b/dist/changes-5.15.2
#@@ -0,0 +1,91 @@
#+Qt 5.15.2 is a bug-fix release. It maintains both forward and backward
#+compatibility (source and binary) with Qt 5.15.1.
#+
#+For more details, refer to the online documentation included in this
#+distribution. The documentation is also available online:
#+
#+  https://doc.qt.io/qt-5.15/index.html
#+
#+The Qt version 5.15 series is binary compatible with the 5.14.x series.
#+Applications compiled for 5.14 will continue to run with 5.15.
#+
#+Some of the changes listed in this file include issue tracking numbers
#+corresponding to tasks in the Qt Bug Tracker:
#+
#+  https://bugreports.qt.io/
#+
#+Each of these identifiers can be entered in the bug tracker to obtain more
#+information about a particular change.
#+
#+****************************************************************************
#+*                          QtQuick                                         *
#+****************************************************************************
#+
#+ - Animations:
#+   * [QTBUG-82890] alwaysRunToEnd==true does not prevent complex Animations
#+     from stopping anymore.
#+
#+ - Drag and drop:
#+   * [QTBUG-82157] Fixed a crash when changing supportedActions in Drag.
#+
#+ - Item Views:
#+   * [QTBUG-87821] TableView: The sync view is rebuilt even when flicking on
#+     a sync view child now.
#+   * [QTBUG-87680] TableView: The content size is always updated upon model
#+     changes now.
#+   * [QTBUG-74046][QTBUG-85302] ListView: Floating headers and footers
#+     containing mouse-handling items work again when the listview is clipped.
#+
#+ - Layouts:
#+   * [QTBUG-62989] We follow layoutMirroring in Layout margins now.
#+
#+ - Loader:
#+   * [QTBUG-85938] QQuickLoader: The status property changes properly now when
#+     setSource() is called.
#+
#+ - RHI / scene graph:
#+   * [QTBUG-86402] Fixed a crash in QQuickShaderEffect when hiding a parent.
#+   * [QTBUG-86524] We don't leak memory from QQuickView's QOpenGLContextGroup
#+     object anymore.
#+
#+ - Text:
#+   * [QTBUG-61475] You can use different input methods on TextEdit in
#+     QQuickWidget now.
#+
#+****************************************************************************
#+*                          Tooling                                         *
#+****************************************************************************
#+
#+ - [QTBUG-87222] qmlformat: Computed property names work correctly now.
#+ - [QTBUG-86980] qmlformat: for...of loops using array variables are
#+   formatted correctly now.
#+ - [QTBUG-86979] qmlformat: Inline components are formatted correctly now.
#+ - [QTBUG-85317] qmlformat: Template literals are correctly formatted now.
#+
#+****************************************************************************
#+*                          Examples                                        *
#+****************************************************************************
#+
#+ - [QTBUG-87150] The lineedit example uses the correct QML_NAMED_ELEMENT
#+   macro now.
#+ - [QTBUG-85724] The Screen example does not attempt to shadow final
#+   properties with required properties anymore.
#+
#+****************************************************************************
#+*                          QtQml                                           *
#+****************************************************************************
#+
#+ - [QTBUG-87721] qtquick_compiler_add_resources now takes OPTIONS into
#+   account.
#+ - [QTBUG-86989] You can define more than one inline component in a QML file
#+   now.
#+ - [QTBUG-75777] The QML Engine does not deadlock in its destructor anymore
#+   under some conditions when asynchronous loaders are used.
#+
#+****************************************************************************
#+*                        Platform Specific Changes                         *
#+****************************************************************************
#+
#+ - WebOS:
#+   * [QTBUG-83361] You can have activeFocus on multiple windows,
#+     if there is a single window per screen on eglfs.
#-- 
#2.33.0
#
From 4ee1462686dc12eb463f5ba6b378d43a39aed074 Mon Sep 17 00:00:00 2001
From: Fabian Kosmale <fabian.kosmale@qt.io>
Date: Thu, 12 Nov 2020 12:11:29 +0100
Subject: [PATCH 05/41] QQuickView docs: show correct usage of
 setInitialProperties

Change-Id: If63f4c59f18bc0754ce2e68e424f6efd0f512d30
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
(cherry picked from commit 54d4f8f526f9c9a1af702b14925e1d34ee8b2134)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/quick/doc/snippets/qquickview-ex.cpp | 9 +++++++++
 src/quick/items/qquickview.cpp           | 4 ++++
 2 files changed, 13 insertions(+)

diff --git a/src/quick/doc/snippets/qquickview-ex.cpp b/src/quick/doc/snippets/qquickview-ex.cpp
index 32406f8f2f..5f93dfdbe8 100644
--- a/src/quick/doc/snippets/qquickview-ex.cpp
+++ b/src/quick/doc/snippets/qquickview-ex.cpp
@@ -59,3 +59,12 @@ int main(int argc, char *argv[])
     return app.exec();
 }
 //![0]
+
+void makeDocTeamHappyByKeepingExampleCompilable() {
+//![1]
+    QScopedPointer<QQuickView> view { new QQuickView };
+    view->setInitialProperties({"x, 100"}, {"width", 50});
+    view->setSource(QUrl::fromLocalFile("myqmlfile.qml"));
+    view->show();
+//![1]
+}
diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp
index 97f6689d8a..b3a5270e9b 100644
--- a/src/quick/items/qquickview.cpp
+++ b/src/quick/items/qquickview.cpp
@@ -240,7 +240,11 @@ void QQuickView::setSource(const QUrl& url)
    Sets the initial properties \a initialProperties with which the QML
    component gets initialized after calling \l QQuickView::setSource().
 
+   \snippet qquickview-ex.cpp 1
+
    \note You can only use this function to initialize top-level properties.
+   \note This function should always be called before setSource, as it has
+   no effect once the component has become \c Ready.
 
    \sa QQmlComponent::createWithInitialProperties()
    \since 5.14
-- 
2.33.0

From 81238e0ff8453f4fb78436ac9bec8452584680ae Mon Sep 17 00:00:00 2001
From: Bartlomiej Moskal <bartlomiej.moskal@siili.com>
Date: Thu, 5 Nov 2020 10:12:29 +0100
Subject: [PATCH 06/41] QQuickWindow: Check if QQuickItem was not deleted

Added check into deliverMatchingPointsToItem method for Android device.

In QT_VERSION below 6.0.0 touchEnabled for QtQuickItems is set by default to true
It causes delivering touch events to Items which are not interested
In some cases it may cause a crash. For example using Material Style in Android.
QQuickShaderEffectSource may be deleted and then try to handle touch

Fixes: QTBUG-85379
Change-Id: Ia2c4e016db57ef9c86fcc31d4cfba6154068a546
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
(cherry picked from commit a14e4fcdf94d26774490b26a4ef77981594f583f)
Reviewed-by: Bartlomiej Moskal <bartlomiej.moskal@siili.com>
---
 src/quick/items/qquickwindow.cpp | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index d0c9ad5454..9ff91eb9a0 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -2864,6 +2864,14 @@ void QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, QQuickPo
 {
     Q_Q(QQuickWindow);
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+#if defined(Q_OS_ANDROID) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+    // QTBUG-85379
+    // In QT_VERSION below 6.0.0 touchEnabled for QtQuickItems is set by default to true
+    // It causes delivering touch events to Items which are not interested
+    // In some cases (like using Material Style in Android) it may cause a crash
+    if (itemPrivate->wasDeleted)
+        return;
+#endif
     pointerEvent->localize(item);
 
     // Let the Item's handlers (if any) have the event first.
-- 
2.33.0

From e749605ecbe76c392552d0e3a75f47b31bed9ba1 Mon Sep 17 00:00:00 2001
From: Kimmo Ollila <kimmo.ollila@qt.io>
Date: Wed, 11 Nov 2020 12:23:53 +0200
Subject: [PATCH 07/41] Avoid GHS linker to optimize away QML type
 registrations

GHS linker optimizes away QML type registrations despite volatile.
To prevent this we add #pragma ghs reference(s) to avoid such linker
optimization.

Fixes: QTBUG-88033
Change-Id: I7c8983506360710185c37028873234b1464847d5
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
---
 src/imports/folderlistmodel/plugin.cpp          | 1 +
 src/imports/labsanimation/plugin.cpp            | 1 +
 src/imports/labsmodels/plugin.cpp               | 1 +
 src/imports/layouts/plugin.cpp                  | 1 +
 src/imports/localstorage/plugin.cpp             | 1 +
 src/imports/settings/plugin.cpp                 | 1 +
 src/imports/sharedimage/plugin.cpp              | 1 +
 src/imports/statemachine/plugin.cpp             | 1 +
 src/imports/testlib/main.cpp                    | 1 +
 src/imports/wavefrontmesh/plugin.cpp            | 1 +
 src/imports/window/plugin.cpp                   | 1 +
 src/particles/qtquickparticlesglobal_p.h        | 1 +
 src/qml/qml/qqmlextensionplugin.h               | 7 +++++++
 src/qml/qtqmlglobal_p.h                         | 2 ++
 src/qmlmodels/qtqmlmodelsglobal_p.h             | 1 +
 src/qmlworkerscript/qtqmlworkerscriptglobal_p.h | 1 +
 src/quick/qtquickglobal_p.h                     | 1 +
 src/quickshapes/qquickshapesglobal_p.h          | 2 ++
 18 files changed, 26 insertions(+)

diff --git a/src/imports/folderlistmodel/plugin.cpp b/src/imports/folderlistmodel/plugin.cpp
index 7a38769b77..7206df6664 100644
--- a/src/imports/folderlistmodel/plugin.cpp
+++ b/src/imports/folderlistmodel/plugin.cpp
@@ -43,6 +43,7 @@
 #include "qquickfolderlistmodel.h"
 
 extern void qml_register_types_Qt_labs_folderlistmodel();
+GHS_KEEP_REFERENCE(qml_register_types_Qt_labs_folderlistmodel);
 
 QT_BEGIN_NAMESPACE
 
diff --git a/src/imports/labsanimation/plugin.cpp b/src/imports/labsanimation/plugin.cpp
index 9c985f0dcf..c35be764f9 100644
--- a/src/imports/labsanimation/plugin.cpp
+++ b/src/imports/labsanimation/plugin.cpp
@@ -43,6 +43,7 @@
 #include "qquickboundaryrule_p.h"
 
 extern void qml_register_types_Qt_labs_animation();
+GHS_KEEP_REFERENCE(qml_register_types_Qt_labs_animation);
 
 QT_BEGIN_NAMESPACE
 
diff --git a/src/imports/labsmodels/plugin.cpp b/src/imports/labsmodels/plugin.cpp
index ab5e0023a6..b06491e663 100644
--- a/src/imports/labsmodels/plugin.cpp
+++ b/src/imports/labsmodels/plugin.cpp
@@ -51,6 +51,7 @@
 #endif
 
 extern void qml_register_types_Qt_labs_qmlmodels();
+GHS_KEEP_REFERENCE(qml_register_types_Qt_labs_qmlmodels);
 
 QT_BEGIN_NAMESPACE
 
diff --git a/src/imports/layouts/plugin.cpp b/src/imports/layouts/plugin.cpp
index af270c1732..b6ae516eee 100644
--- a/src/imports/layouts/plugin.cpp
+++ b/src/imports/layouts/plugin.cpp
@@ -43,6 +43,7 @@
 #include "qquickstacklayout_p.h"
 
 extern void qml_register_types_QtQuick_Layouts();
+GHS_KEEP_REFERENCE(qml_register_types_QtQuick_Layouts);
 
 QT_BEGIN_NAMESPACE
 
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp
index e488b3d43c..0291ed4715 100644
--- a/src/imports/localstorage/plugin.cpp
+++ b/src/imports/localstorage/plugin.cpp
@@ -43,6 +43,7 @@
 #include <QtQml/qqml.h>
 
 extern void qml_register_types_QtQuick_LocalStorage();
+GHS_KEEP_REFERENCE(qml_register_types_QtQuick_LocalStorage);
 
 QT_BEGIN_NAMESPACE
 
diff --git a/src/imports/settings/plugin.cpp b/src/imports/settings/plugin.cpp
index e8e640412b..e83147f612 100644
--- a/src/imports/settings/plugin.cpp
+++ b/src/imports/settings/plugin.cpp
@@ -43,6 +43,7 @@
 #include "qqmlsettings_p.h"
 
 extern void qml_register_types_Qt_labs_settings();
+GHS_KEEP_REFERENCE(qml_register_types_Qt_labs_settings);
 
 QT_BEGIN_NAMESPACE
 
diff --git a/src/imports/sharedimage/plugin.cpp b/src/imports/sharedimage/plugin.cpp
index d7c2ef8d17..79168d933b 100644
--- a/src/imports/sharedimage/plugin.cpp
+++ b/src/imports/sharedimage/plugin.cpp
@@ -100,6 +100,7 @@
 */
 
 extern void qml_register_types_Qt_labs_sharedimage();
+GHS_KEEP_REFERENCE(qml_register_types_Qt_labs_sharedimage);
 
 QT_BEGIN_NAMESPACE
 
diff --git a/src/imports/statemachine/plugin.cpp b/src/imports/statemachine/plugin.cpp
index c370504029..abb238965e 100644
--- a/src/imports/statemachine/plugin.cpp
+++ b/src/imports/statemachine/plugin.cpp
@@ -49,6 +49,7 @@
 #include <qqml.h>
 
 extern void qml_register_types_QtQml_StateMachine();
+GHS_KEEP_REFERENCE(qml_register_types_QtQml_StateMachine);
 
 QT_BEGIN_NAMESPACE
 
diff --git a/src/imports/testlib/main.cpp b/src/imports/testlib/main.cpp
index 83fc150e6c..1da251c49b 100644
--- a/src/imports/testlib/main.cpp
+++ b/src/imports/testlib/main.cpp
@@ -51,6 +51,7 @@ QML_DECLARE_TYPE(QuickTestEvent)
 QML_DECLARE_TYPE(QuickTestUtil)
 
 extern void qml_register_types_QtTest();
+GHS_KEEP_REFERENCE(qml_register_types_QtTest);
 
 QT_BEGIN_NAMESPACE
 
diff --git a/src/imports/wavefrontmesh/plugin.cpp b/src/imports/wavefrontmesh/plugin.cpp
index eea0db19db..edd4d1dba5 100644
--- a/src/imports/wavefrontmesh/plugin.cpp
+++ b/src/imports/wavefrontmesh/plugin.cpp
@@ -43,6 +43,7 @@
 #include "qwavefrontmesh.h"
 
 extern void qml_register_types_Qt_labs_wavefrontmesh();
+GHS_KEEP_REFERENCE(qml_register_types_Qt_labs_wavefrontmesh);
 
 QT_BEGIN_NAMESPACE
 
diff --git a/src/imports/window/plugin.cpp b/src/imports/window/plugin.cpp
index 5152fa02ec..ff2f10fde3 100644
--- a/src/imports/window/plugin.cpp
+++ b/src/imports/window/plugin.cpp
@@ -42,6 +42,7 @@
 #include "plugin.h"
 
 extern void qml_register_types_QtQuick_Window();
+GHS_KEEP_REFERENCE(qml_register_types_QtQuick_Window);
 
 QT_BEGIN_NAMESPACE
 
diff --git a/src/particles/qtquickparticlesglobal_p.h b/src/particles/qtquickparticlesglobal_p.h
index 927bc29050..91c2764060 100644
--- a/src/particles/qtquickparticlesglobal_p.h
+++ b/src/particles/qtquickparticlesglobal_p.h
@@ -66,5 +66,6 @@
 #endif
 
 void Q_QUICKPARTICLES_PRIVATE_EXPORT qml_register_types_QtQuick_Particles();
+GHS_KEEP_REFERENCE(qml_register_types_QtQuick_Particles);
 
 #endif // QTQUICKPARTICLESGLOBAL_P_H
diff --git a/src/qml/qml/qqmlextensionplugin.h b/src/qml/qml/qqmlextensionplugin.h
index ef7ff422cd..afb3f99c4a 100644
--- a/src/qml/qml/qqmlextensionplugin.h
+++ b/src/qml/qml/qqmlextensionplugin.h
@@ -44,6 +44,13 @@
 #include <QtCore/QUrl>
 #include <QtQml/qqmlextensioninterface.h>
 
+#if defined(Q_CC_GHS)
+#  define GHS_PRAGMA(S) _Pragma(#S)
+#  define GHS_KEEP_REFERENCE(S) GHS_PRAGMA(ghs reference S ##__Fv)
+#else
+#  define GHS_KEEP_REFERENCE(S)
+#endif
+
 QT_BEGIN_NAMESPACE
 
 class QQmlEngine;
diff --git a/src/qml/qtqmlglobal_p.h b/src/qml/qtqmlglobal_p.h
index a729729b67..7b0910fa13 100644
--- a/src/qml/qtqmlglobal_p.h
+++ b/src/qml/qtqmlglobal_p.h
@@ -53,6 +53,7 @@
 
 #include <QtCore/private/qglobal_p.h>
 #include <QtQml/qtqmlglobal.h>
+#include <QtQml/qqmlextensionplugin.h>
 #ifndef QT_QML_BOOTSTRAPPED
 #  include <QtQml/private/qtqml-config_p.h>
 #endif
@@ -61,6 +62,7 @@
 #define Q_QML_PRIVATE_EXPORT Q_QML_EXPORT
 
 void Q_QML_PRIVATE_EXPORT qml_register_types_QtQml();
+GHS_KEEP_REFERENCE(qml_register_types_QtQml);
 
 #if !defined(QT_QMLDEVTOOLS_LIB) && !defined(QT_BUILD_QMLDEVTOOLS_LIB)
 #  define Q_QML_AUTOTEST_EXPORT Q_AUTOTEST_EXPORT
diff --git a/src/qmlmodels/qtqmlmodelsglobal_p.h b/src/qmlmodels/qtqmlmodelsglobal_p.h
index 1a1157138d..24df6ef7b3 100644
--- a/src/qmlmodels/qtqmlmodelsglobal_p.h
+++ b/src/qmlmodels/qtqmlmodelsglobal_p.h
@@ -59,5 +59,6 @@
 #define Q_QMLMODELS_AUTOTEST_EXPORT Q_AUTOTEST_EXPORT
 
 void Q_QMLMODELS_PRIVATE_EXPORT qml_register_types_QtQml_Models();
+GHS_KEEP_REFERENCE(qml_register_types_QtQml_Models);
 
 #endif // QTQMLMODELSGLOBAL_P_H
diff --git a/src/qmlworkerscript/qtqmlworkerscriptglobal_p.h b/src/qmlworkerscript/qtqmlworkerscriptglobal_p.h
index c75d5f3129..6452567f6b 100644
--- a/src/qmlworkerscript/qtqmlworkerscriptglobal_p.h
+++ b/src/qmlworkerscript/qtqmlworkerscriptglobal_p.h
@@ -58,5 +58,6 @@
 #define Q_QMLWORKERSCRIPT_AUTOTEST_EXPORT Q_AUTOTEST_EXPORT
 
 void Q_QMLWORKERSCRIPT_PRIVATE_EXPORT qml_register_types_QtQml_WorkerScript();
+GHS_KEEP_REFERENCE(qml_register_types_QtQml_WorkerScript);
 
 #endif // QTQMLWORKERSCRIPTGLOBAL_P_H
diff --git a/src/quick/qtquickglobal_p.h b/src/quick/qtquickglobal_p.h
index 80e59563c7..97680569e7 100644
--- a/src/quick/qtquickglobal_p.h
+++ b/src/quick/qtquickglobal_p.h
@@ -62,6 +62,7 @@
 #define Q_QUICK_PRIVATE_EXPORT Q_QUICK_EXPORT
 
 void Q_QUICK_PRIVATE_EXPORT qml_register_types_QtQuick();
+GHS_KEEP_REFERENCE(qml_register_types_QtQuick);
 
 QT_BEGIN_NAMESPACE
 
diff --git a/src/quickshapes/qquickshapesglobal_p.h b/src/quickshapes/qquickshapesglobal_p.h
index 40f6cfbdcf..37386c23b2 100644
--- a/src/quickshapes/qquickshapesglobal_p.h
+++ b/src/quickshapes/qquickshapesglobal_p.h
@@ -51,6 +51,7 @@
 // We mean it.
 //
 
+#include <QtQml/qqmlextensionplugin.h>
 #include "qquickshapesglobal.h"
 
 QT_BEGIN_NAMESPACE
@@ -60,5 +61,6 @@ QT_BEGIN_NAMESPACE
 QT_END_NAMESPACE
 
 void Q_QUICKSHAPES_PRIVATE_EXPORT qml_register_types_QtQuick_Shapes();
+GHS_KEEP_REFERENCE(qml_register_types_QtQuick_Shapes);
 
 #endif // QQUICKSHAPESGLOBAL_P_H
-- 
2.33.0

From f4afe4934819a7f0fb9754b9bb08fb1acb818058 Mon Sep 17 00:00:00 2001
From: Shinichi Okada <shinichi.okada@qt.io>
Date: Tue, 17 Nov 2020 14:15:50 +0900
Subject: [PATCH 08/41] QML Text doesn't reset lineCount when text is empty

lineCount is not reset when replacing a multi-line QML Text 'text'
property with an "" empty string. Also, the lineCountChanged signal is
not emitted

Task-number: QTBUG-84458
Change-Id: Ic3c02e6a90e6675eadbaafc6af6ab0356ee98123
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit ae1b9c6d94001411efeef600e22638906e0fa990)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/quick/items/qquicktext.cpp                |  2 +
 .../auto/quick/qquicktext/tst_qquicktext.cpp  | 37 +++++++++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 90469ee82b..581ab9f76a 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -398,6 +398,8 @@ void QQuickTextPrivate::updateSize()
         layedOutTextRect = QRectF(0, 0, 0, fontHeight);
         advance = QSizeF();
         signalSizeChange(previousSize);
+        lineCount = 1;
+        emit q->lineCountChanged();
         updateType = UpdatePaintNode;
         q->update();
         return;
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
index 42fdbea58d..308c6b5091 100644
--- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
@@ -2243,6 +2243,43 @@ void tst_qquicktext::lineCount()
     QCOMPARE(myText->lineCount(), 2);
     QCOMPARE(myText->truncated(), true);
     QCOMPARE(myText->maximumLineCount(), 2);
+
+    // QTBUG-84458
+    myText->resetMaximumLineCount();
+    myText->setText("qqqqq\nqqqqq");
+    QCOMPARE(myText->lineCount(), 2);
+    myText->setText("qqqqq\nqqqqq\nqqqqq");
+    QCOMPARE(myText->lineCount(), 3);
+    myText->setText("");
+    QCOMPARE(myText->lineCount(), 1);
+
+    myText->setText("qqqqq\nqqqqq\nqqqqq");
+    QCOMPARE(myText->lineCount(), 3);
+    myText->setFontSizeMode(QQuickText::HorizontalFit);
+    myText->setText("");
+    QCOMPARE(myText->lineCount(), 1);
+
+    myText->setText("qqqqq\nqqqqq\nqqqqq");
+    QCOMPARE(myText->lineCount(), 3);
+    myText->setFontSizeMode(QQuickText::VerticalFit);
+    myText->setText("");
+    QCOMPARE(myText->lineCount(), 1);
+
+    myText->setText("qqqqq\nqqqqq\nqqqqq");
+    QCOMPARE(myText->lineCount(), 3);
+    myText->setFontSizeMode(QQuickText::Fit);
+    myText->setText("");
+    QCOMPARE(myText->lineCount(), 1);
+
+    QScopedPointer<QQuickView> layoutWindow(createView(testFile("lineLayoutHAlign.qml")));
+    QQuickText *lineLaidOut = layoutWindow->rootObject()->findChild<QQuickText*>("myText");
+    QVERIFY(lineLaidOut != nullptr);
+
+    lineLaidOut->setText("qqqqq\nqqqqq\nqqqqq");
+    QCOMPARE(lineLaidOut->lineCount(), 3);
+    lineLaidOut->setFontSizeMode(QQuickText::FixedSize);
+    lineLaidOut->setText("");
+    QCOMPARE(lineLaidOut->lineCount(), 1);
 }
 
 void tst_qquicktext::lineHeight()
-- 
2.33.0

From 4d6078e4b556e83f55ffed55f14203c3ed880c62 Mon Sep 17 00:00:00 2001
From: Mitch Curtis <mitch.curtis@qt.io>
Date: Thu, 19 Nov 2020 16:39:23 +0100
Subject: [PATCH 09/41] Doc: mention that INCLUDEPATH must be set in some cases

Otherwise the generated type registrations .cpp file will not be able
to include the sources.

Change-Id: I7821c7674b4341546da2fc49e584bf10cc60b46f
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit 06c31f386f8664343debd219a522a8897df0f3ec)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/qml/doc/src/cppintegration/definetypes.qdoc | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/qml/doc/src/cppintegration/definetypes.qdoc b/src/qml/doc/src/cppintegration/definetypes.qdoc
index cbbbd9ba58..ece2fd5fd7 100644
--- a/src/qml/doc/src/cppintegration/definetypes.qdoc
+++ b/src/qml/doc/src/cppintegration/definetypes.qdoc
@@ -117,6 +117,14 @@ QML_IMPORT_NAME = com.mycompany.messaging
 QML_IMPORT_MAJOR_VERSION = 1
 \endcode
 
+If the header the class is declared in is not accessible from your project's
+include path, you may have to amend the include path so that the generated
+registration code can be compiled:
+
+\code
+INCLUDEPATH += com/mycompany/messaging
+\endcode
+
 The type can be used in an \l{qtqml-syntax-basics.html#object-declarations}
 {object declaration} from QML, and its properties can be read and written to,
 as per the example below:
-- 
2.33.0

From 65851a450926befad65d9cffcaa217875d1936c6 Mon Sep 17 00:00:00 2001
From: Maximilian Goldstein <max.goldstein@qt.io>
Date: Mon, 23 Nov 2020 13:17:40 +0100
Subject: [PATCH 10/41] qmlfunctions.qdoc: Add clarification to QML_FOREIGN

Fixes: QTBUG-87150
Change-Id: If99a06a07892bdfef7b6b1e8fa737480750992fe
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 56f428c360191230b571969a2651e85380030afa)
---
 examples/qml/doc/src/qml-extending.qdoc | 4 ++++
 src/qml/doc/src/qmlfunctions.qdoc       | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/examples/qml/doc/src/qml-extending.qdoc b/examples/qml/doc/src/qml-extending.qdoc
index 723e470d45..c9922ebd45 100644
--- a/examples/qml/doc/src/qml-extending.qdoc
+++ b/examples/qml/doc/src/qml-extending.qdoc
@@ -79,6 +79,10 @@ Qt's internal QLineEdit class.
 
 \snippet referenceexamples/extended/lineedit.h 0
 
+Note the usage of \l QML_NAMED_ELEMENT() instead of \l QML_ELEMENT.
+QML_ELEMENT uses the name of the containing type by default, "LineEditExtension" in this case.
+As the class being an extension class is an implementation detail, we choose the more natural name "LineEdit" instead
+
 The QML engine then instantiates a \l QLineEdit:
 
 \snippet referenceexamples/extended/main.cpp 1
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc
index 12b7efb159..4e531ceb61 100644
--- a/src/qml/doc/src/qmlfunctions.qdoc
+++ b/src/qml/doc/src/qmlfunctions.qdoc
@@ -250,6 +250,10 @@
   This is useful for registering types that cannot be amended to add the macros,
   for example because they belong to 3rdparty libraries.
 
+  \b{NOTE:} You may want to use \l QML_NAMED_ELEMENT() instead of \l QML_ELEMENT due to the fact that
+  the element will be named like the struct it is contained in, not the foreign type.
+  See \l {Extending QML - Extension Objects Example} for an example.
+
   \sa QML_ELEMENT, QML_NAMED_ELEMENT()
 */
 
-- 
2.33.0

From b2862e2bd84d651c1f4fb2ced96ee6f40ea1f3e4 Mon Sep 17 00:00:00 2001
From: Andrei Golubev <andrei.golubev@qt.io>
Date: Fri, 20 Nov 2020 10:44:44 +0100
Subject: [PATCH 11/41] Fix QML property cache leaks of delegate items

The delegate items are destroyed through an event loop by a call to a
deleteLater(). This, however, doesn't work when the application is
in the process of exiting and the event loop is already closed (i.e.
we're in a stack unwinding part that starts after app.exec())

Combat this situation by setting a parent of the to-be-deleted object
to some QObject that will be destroyed e.g. QCoreApplication::instance()
before the program finishes. As QObjects clean their children on
destruction, this will make sure that we cleanup the previously leaking
thing regardless of the event loop

Added a test to check that delegates are destroyed (as a separate binary
due to differences in main() function)

Fixes: QTBUG-87228
Change-Id: I59066603b77497fe4fd8d051798c3e4b47c119f0
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 3a5617dc45e281552b9c1f7a04f0561b8fa14d94)
---
 src/qmlmodels/qqmldelegatemodel.cpp           | 11 ++-
 .../qquickview_extra/data/qtbug_87228.qml     | 30 ++++++++
 .../qquickview_extra/qquickview_extra.pro     | 12 +++
 .../qquickview_extra/tst_qquickview_extra.cpp | 77 +++++++++++++++++++
 tests/auto/quick/quick.pro                    |  1 +
 5 files changed, 130 insertions(+), 1 deletion(-)
 create mode 100644 tests/auto/quick/qquickview_extra/data/qtbug_87228.qml
 create mode 100644 tests/auto/quick/qquickview_extra/qquickview_extra.pro
 create mode 100644 tests/auto/quick/qquickview_extra/tst_qquickview_extra.cpp

diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp
index 725b9e8bc3..12c3d11937 100644
--- a/src/qmlmodels/qqmldelegatemodel.cpp
+++ b/src/qmlmodels/qqmldelegatemodel.cpp
@@ -1,6 +1,6 @@
 /****************************************************************************
 **
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
 ** Contact: https://www.qt.io/licensing/
 **
 ** This file is part of the QtQml module of the Qt Toolkit.
@@ -2379,6 +2379,15 @@ void QQmlDelegateModelItem::destroyObject()
         data->ownContext = nullptr;
         data->context = nullptr;
     }
+    /* QTBUG-87228: when destroying object at the application exit, the deferred
+     * parent by setting it to QCoreApplication instance if it's nullptr, so
+     * deletion won't work. Not to leak memory, make sure our object has a that
+     * the parent claims the object at the end of the lifetime. When not at the
+     * application exit, normal event loop will handle the deferred deletion
+     * earlier.
+     */
+    if (object->parent() == nullptr)
+        object->setParent(QCoreApplication::instance());
     object->deleteLater();
 
     if (attached) {
diff --git a/tests/auto/quick/qquickview_extra/data/qtbug_87228.qml b/tests/auto/quick/qquickview_extra/data/qtbug_87228.qml
new file mode 100644
index 0000000000..ff10eba23d
--- /dev/null
+++ b/tests/auto/quick/qquickview_extra/data/qtbug_87228.qml
@@ -0,0 +1,30 @@
+import QtQml 2.12
+import QtQml.Models 2.12
+import QtQuick 2.12
+
+Item {
+    height: 480
+    width: 320
+    Rectangle {
+        id: rootRect
+
+        function addItem(desc) {
+            myModel.append({"desc": desc});
+        }
+
+        Rectangle {
+            ListView {
+                objectName: "listView"
+                delegate: Text {
+                    required property string desc
+                    text: desc
+                }
+                model: ListModel { id: myModel }
+            }
+        }
+
+        Component.onCompleted: {
+            addItem("Test creation of a delegate with a property");
+        }
+    }
+}
diff --git a/tests/auto/quick/qquickview_extra/qquickview_extra.pro b/tests/auto/quick/qquickview_extra/qquickview_extra.pro
new file mode 100644
index 0000000000..b40af0ce19
--- /dev/null
+++ b/tests/auto/quick/qquickview_extra/qquickview_extra.pro
@@ -0,0 +1,12 @@
+CONFIG += testcase
+TARGET = tst_qquickview_extra
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qquickview_extra.cpp
+
+include (../../shared/util.pri)
+include (../shared/util.pri)
+
+TESTDATA = data/*
+
+QT += core-private gui-private qml-private quick-private testlib
diff --git a/tests/auto/quick/qquickview_extra/tst_qquickview_extra.cpp b/tests/auto/quick/qquickview_extra/tst_qquickview_extra.cpp
new file mode 100644
index 0000000000..f697a438bd
--- /dev/null
+++ b/tests/auto/quick/qquickview_extra/tst_qquickview_extra.cpp
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qtest.h>
+#include <QtTest/QSignalSpy>
+#include <QtQuick/qquickview.h>
+#include <QtQuick/qquickitem.h>
+#include <QtQml/qqmlengine.h>
+#include "../../shared/util.h"
+#include <QtCore/QDebug>
+#include <QtCore/QTimer>
+
+// Extra app-less tests
+class tst_QQuickViewExtra : public QQmlDataTest
+{
+    Q_OBJECT
+public:
+    tst_QQuickViewExtra();
+
+private slots:
+    void qtbug_87228();
+};
+
+tst_QQuickViewExtra::tst_QQuickViewExtra() { }
+
+void tst_QQuickViewExtra::qtbug_87228()
+{
+    QScopedPointer<QSignalSpy> deletionSpy;
+    {
+        int argc = 0;
+        QGuiApplication app(argc, nullptr);
+        QQuickView view;
+
+        view.setSource(testFileUrl("qtbug_87228.qml"));
+        view.show();
+        QTimer::singleShot(500, &app, QCoreApplication::quit);
+        app.exec();
+
+        QObject *listView = view.findChild<QObject *>("listView");
+        QVERIFY(listView);
+        QQuickItem *contentItem = listView->property("contentItem").value<QQuickItem *>();
+        QVERIFY(contentItem);
+        auto children = contentItem->childItems();
+        QVERIFY(children.size() > 0);
+        // for the sake of this test, any child would be suitable, so pick first
+        deletionSpy.reset(new QSignalSpy(children[0], SIGNAL(destroyed(QObject *))));
+    }
+    QCOMPARE(deletionSpy->count(), 1);
+}
+
+QTEST_APPLESS_MAIN(tst_QQuickViewExtra)
+
+#include "tst_qquickview_extra.moc"
diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro
index 541bfdd527..45bcf8a9ce 100644
--- a/tests/auto/quick/quick.pro
+++ b/tests/auto/quick/quick.pro
@@ -85,6 +85,7 @@ QUICKTESTS += \
     qquicktextinput \
     qquickvisualdatamodel \
     qquickview \
+    qquickview_extra \
     qquickcanvasitem \
     qquickdesignersupport \
     qquickscreen \
-- 
2.33.0

From 89ea9f1f9468aa47718cbb398317c63a9479adf2 Mon Sep 17 00:00:00 2001
From: Fabian Kosmale <fabian.kosmale@qt.io>
Date: Tue, 24 Nov 2020 13:23:23 +0100
Subject: [PATCH 12/41] QQuickTextInput: Store mask data in std::unique_ptr

This ensures that the memory is freed reliably

Fixes: QTBUG-88807
Change-Id: I841a5a2b226a69ce50975d95702a948857d1b54f
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
(cherry picked from commit d2d8e90e9f218103d60737e1273ab5322834d9ec)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/quick/items/qquicktextinput.cpp   | 6 ++----
 src/quick/items/qquicktextinput_p_p.h | 4 +++-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index 6275b298ed..bb78ead0e8 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -3831,8 +3831,7 @@ void QQuickTextInputPrivate::parseInputMask(const QString &maskFields)
     int delimiter = maskFields.indexOf(QLatin1Char(';'));
     if (maskFields.isEmpty() || delimiter == 0) {
         if (m_maskData) {
-            delete [] m_maskData;
-            m_maskData = nullptr;
+            m_maskData.reset(nullptr);
             m_maxLength = 32767;
             internalSetText(QString());
         }
@@ -3863,8 +3862,7 @@ void QQuickTextInputPrivate::parseInputMask(const QString &maskFields)
             m_maxLength++;
     }
 
-    delete [] m_maskData;
-    m_maskData = new MaskInputData[m_maxLength];
+    m_maskData.reset(new MaskInputData[m_maxLength]);
 
     MaskInputData::Casemode m = MaskInputData::NoCaseMode;
     c = 0;
diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h
index 7965f3d3f4..7fbba49405 100644
--- a/src/quick/items/qquicktextinput_p_p.h
+++ b/src/quick/items/qquicktextinput_p_p.h
@@ -58,6 +58,8 @@
 
 #include "qplatformdefs.h"
 
+#include <memory>
+
 //
 //  W A R N I N G
 //  -------------
@@ -230,7 +232,7 @@ public:
 
     QQuickItem *cursorItem;
     QQuickTextNode *textNode;
-    MaskInputData *m_maskData;
+    std::unique_ptr<MaskInputData[]> m_maskData;
     QInputControl *m_inputControl;
 
     QList<int> m_transactions;
-- 
2.33.0

From 810a0afe1e9bd14e4393a73bf6c299b25745dbc5 Mon Sep 17 00:00:00 2001
From: Richard Weickelt <richard@weickelt.de>
Date: Tue, 24 Nov 2020 01:14:28 +0100
Subject: [PATCH 13/41] Fix crash when calling hasOwnProperty() on proxy object

Property pointer p needs to be checked for nullptr value in
QV4::ProxyObject::virtualGetOwnProperty(). This can happen when calling
hasOwnProperty() or propertyIsEnumerable().

Fixes: QTBUG-88786
Change-Id: I43da58fed4d8656f9187213f7317f17398739e34
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit 9b321a34490cd17c0eb043b69bd7c9d8d8f513d5)
Reviewed-by: Richard Weickelt <richard@weickelt.de>
---
 src/qml/jsruntime/qv4proxy.cpp                | 10 +++---
 .../qml/qqmlecmascript/tst_qqmlecmascript.cpp | 31 ++++++++++++++++++-
 2 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/src/qml/jsruntime/qv4proxy.cpp b/src/qml/jsruntime/qv4proxy.cpp
index 24676ffd00..1505eae426 100644
--- a/src/qml/jsruntime/qv4proxy.cpp
+++ b/src/qml/jsruntime/qv4proxy.cpp
@@ -265,9 +265,9 @@ PropertyAttributes ProxyObject::virtualGetOwnProperty(const Managed *m, Property
     ScopedProperty targetDesc(scope);
     PropertyAttributes targetAttributes = target->getOwnProperty(id, targetDesc);
     if (trapResult->isUndefined()) {
-        p->value = Encode::undefined();
-        if (targetAttributes == Attr_Invalid) {
+        if (p)
             p->value = Encode::undefined();
+        if (targetAttributes == Attr_Invalid) {
             return Attr_Invalid;
         }
         if (!targetAttributes.isConfigurable() || !target->isExtensible()) {
@@ -295,8 +295,10 @@ PropertyAttributes ProxyObject::virtualGetOwnProperty(const Managed *m, Property
         }
     }
 
-    p->value = resultDesc->value;
-    p->set = resultDesc->set;
+    if (p) {
+        p->value = resultDesc->value;
+        p->set = resultDesc->set;
+    }
     return resultAttributes;
 }
 
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 1e10841430..3a9d1bfb4c 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -382,7 +382,7 @@ private slots:
     void semicolonAfterProperty();
     void hugeStack();
     void variantConversionMethod();
-
+    void proxyHandlerTraps();
     void gcCrashRegressionTest();
 
 private:
@@ -9306,6 +9306,35 @@ void tst_qqmlecmascript::variantConversionMethod()
     QCOMPARE(obj.funcCalled, QLatin1String("QModelIndex"));
 }
 
+void tst_qqmlecmascript::proxyHandlerTraps()
+{
+    const QString expression = QStringLiteral(R"SNIPPET(
+        (function(){
+            const target = {
+                prop: 47
+            };
+            const handler = {
+                getOwnPropertyDescriptor(target, prop) {
+                    return { configurable: true, enumerable: true, value: 47 };
+                }
+            };
+            const proxy = new Proxy(target, handler);
+
+            // QTBUG-88786
+            if (!proxy.propertyIsEnumerable("prop"))
+                throw Error("FAIL: propertyisEnumerable");
+            if (!proxy.hasOwnProperty("prop"))
+                throw Error("FAIL: hasOwnProperty");
+
+            return "SUCCESS";
+        })()
+    )SNIPPET");
+
+    QJSEngine engine;
+    QJSValue value = engine.evaluate(expression);
+    QVERIFY(value.isString() && value.toString() == QStringLiteral("SUCCESS"));
+}
+
 QTEST_MAIN(tst_qqmlecmascript)
 
 #include "tst_qqmlecmascript.moc"
-- 
2.33.0

From 514a69659a56fda410f4ab955f03c0d2a38b52f9 Mon Sep 17 00:00:00 2001
From: Piotr Mikolajczyk <piotr.mikolajczyk@qt.io>
Date: Tue, 10 Nov 2020 14:58:12 +0100
Subject: [PATCH 14/41] Accessibility event is sent on item's geometry change
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

In case of enabled accessibility, whenever the geometry
of a QQuickItem changes, accessibility module is notified
by a LocationChange event. This enables responding to this
by for example moving the accessibility frame on the screen.

Task-number: QTBUG-79611
Change-Id: I808e835384ef42bba2e9aabecf4be3cda07859fe
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
(cherry picked from commit def81070668f101e1e2cbb46d586bbab64c8e00f)
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
---
 src/quick/items/qquickitem.cpp | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 67c4611d9e..ddd67522b9 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -3753,6 +3753,14 @@ void QQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeo
         emit widthChanged();
     if (change.heightChange())
         emit heightChanged();
+#if QT_CONFIG(accessibility)
+    if (QAccessible::isActive()) {
+        if (QObject *acc = QQuickAccessibleAttached::findAccessible(this)) {
+            QAccessibleEvent ev(acc, QAccessible::LocationChanged);
+            QAccessible::updateAccessibility(&ev);
+        }
+    }
+#endif
 }
 
 /*!
-- 
2.33.0

From 3c075bfd348306cd553caddb9f8bf3f596666636 Mon Sep 17 00:00:00 2001
From: Alessandro Portale <alessandro.portale@qt.io>
Date: Wed, 25 Nov 2020 23:43:03 +0100
Subject: [PATCH 15/41] qmltypes.prf: Take abi into account for
 *_metatypes.json file names

The lib/metatypes/*_metatypes.json file names contain the ABI. When
constructing the qmltyperegistrar command, the right file names
with that ABI part need to be passed as "foreign-types".

Fixes: QTBUG-85888
Fixes: QTBUG-87117
Change-Id: I20daac1b6b9a27c5ac48b3c2c685e2fed301e213
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
(cherry picked from commit acc5e48a90d0daeccb28175b80ab6b52cac5d84a)
---
 src/qmltyperegistrar/qmltypes.prf | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/qmltyperegistrar/qmltypes.prf b/src/qmltyperegistrar/qmltypes.prf
index 354fa1736f..2cc0027b7e 100644
--- a/src/qmltyperegistrar/qmltypes.prf
+++ b/src/qmltyperegistrar/qmltypes.prf
@@ -44,7 +44,8 @@ qt_module_deps = $$replace(qt_module_deps, _private$, '')
 qt_module_deps = $$unique(qt_module_deps)
 
 for(dep, qt_module_deps) {
-    METATYPES_FILENAME = $$lower($$eval(QT.$${dep}.module))_metatypes.json
+    android:ABI = _$${ANDROID_TARGET_ARCH}
+    METATYPES_FILENAME = $$lower($$eval(QT.$${dep}.module))$${ABI}_metatypes.json
     INSTALLED_METATYPES = $$[QT_INSTALL_LIBS]/metatypes/$$METATYPES_FILENAME
     isEmpty(MODULE_BASE_OUTDIR) {
         QML_FOREIGN_METATYPES += $$INSTALLED_METATYPES
-- 
2.33.0

From 37c290c5b8659256ff574a06a3df2c363ae446b5 Mon Sep 17 00:00:00 2001
From: Maximilian Goldstein <max.goldstein@qt.io>
Date: Wed, 2 Dec 2020 13:08:57 +0100
Subject: [PATCH 16/41] qv4qmlcontext: Fix bounded signal expressions when
 debugging

Fixes: QTBUG-83599
Change-Id: I8909f0b2d3eca909512b99c172c8dc5e93e48482
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit bad85119bf35468292cfd80ecc934b66515f0c68)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/qml/jsruntime/qv4qmlcontext.cpp                  |  4 ++--
 .../qml/debugger/qv4debugger/tst_qv4debugger.cpp     | 12 +++++++++---
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp
index e2d3b98ff6..6eece147a6 100644
--- a/src/qml/jsruntime/qv4qmlcontext.cpp
+++ b/src/qml/jsruntime/qv4qmlcontext.cpp
@@ -466,9 +466,9 @@ ReturnedValue QQmlContextWrapper::resolveQmlContextPropertyLookupGetter(Lookup *
                 return static_cast<Heap::CallContext *>(ctx)->locals[index].asReturnedValue();
         }
 
-        // Skip only block contexts within the current call context.
+        // Skip only block and call contexts.
         // Other contexts need a regular QML property lookup. See below.
-        if (ctx->type != Heap::ExecutionContext::Type_BlockContext)
+        if (ctx->type != Heap::ExecutionContext::Type_BlockContext && ctx->type != Heap::ExecutionContext::Type_CallContext)
             break;
     }
 
diff --git a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
index 84f5eebd10..e3cbeb9891 100644
--- a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
+++ b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
@@ -910,19 +910,25 @@ void tst_qv4debugger::signalParameters()
     component.setData("import QtQml 2.12\n"
                       "QtObject {\n"
                       "    id: root\n"
-                      "    property string result\n"
+                      "    property string result: 'unset'\n"
+                      "    property string resultCallbackInternal: 'unset'\n"
+                      "    property string resultCallbackExternal: 'unset'\n"
                       "    signal signalWithArg(string textArg)\n"
+                      "    function call(callback) { callback(); }\n"
+                      "    function externalCallback() { root.resultCallbackExternal = textArg; }\n"
                       "    property Connections connections : Connections {\n"
                       "        target: root\n"
-                      "        onSignalWithArg: { root.result = textArg; }\n"
+                      "        onSignalWithArg: { root.result = textArg; call(function() { root.resultCallbackInternal = textArg; }); call(externalCallback); }\n"
                       "    }\n"
                       "    Component.onCompleted: signalWithArg('something')\n"
                       "}", QUrl("test.qml"));
 
-    QVERIFY(component.isReady());
+    QVERIFY2(component.isReady(), qPrintable(component.errorString()));
     QScopedPointer<QObject> obj(component.create());
     QVERIFY(obj);
     QCOMPARE(obj->property("result").toString(), QLatin1String("something"));
+    QCOMPARE(obj->property("resultCallbackInternal").toString(), QLatin1String("something"));
+    QCOMPARE(obj->property("resultCallbackExternal").toString(), QLatin1String("unset"));
 }
 
 QTEST_MAIN(tst_qv4debugger)
-- 
2.33.0

From 30c7a6c6a874264800d398df8c3ec65f30707c92 Mon Sep 17 00:00:00 2001
From: Li Xinwei <1326710505@qq.com>
Date: Tue, 8 Dec 2020 15:36:01 +0800
Subject: [PATCH 17/41] Use load(qt_tool) for qmltime

The qmltime should be a tool, not a normal executable or an app.

Change-Id: I64c76877907297a6a817ba5903786bcc7fba8fdd
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
(cherry picked from commit e6e262da1423bcb7cfe3db9f83fe0df54483c8d4)
---
 tools/qmltime/qmltime.pro | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/qmltime/qmltime.pro b/tools/qmltime/qmltime.pro
index c915f6e8c1..366d90f75b 100644
--- a/tools/qmltime/qmltime.pro
+++ b/tools/qmltime/qmltime.pro
@@ -1,4 +1,3 @@
-TEMPLATE = app
 TARGET = qmltime
 QT += qml quick
 QT += quick-private
@@ -12,3 +11,5 @@ QMAKE_TARGET_DESCRIPTION = QML Time
 
 SOURCES += qmltime.cpp
 HEADERS += qmltime.h
+
+load(qt_tool)
-- 
2.33.0

From 83100a84f2b0068b4cf725896bbb810415908334 Mon Sep 17 00:00:00 2001
From: Maximilian Goldstein <max.goldstein@qt.io>
Date: Tue, 8 Dec 2020 09:26:36 +0100
Subject: [PATCH 18/41] qqmlistmodel: Fix crash when modelCache is null

Fixes: QTBUG-89173
Change-Id: Ife82518808fc5504ec42407e80ed3de89ed4adeb
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit c3860cd04bbc089ef95bc441a1f8f1e46f9606f8)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/qmlmodels/qqmllistmodel.cpp               |  2 +-
 .../qml/qqmllistmodel/tst_qqmllistmodel.cpp   | 22 +++++++++++++++++++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/src/qmlmodels/qqmllistmodel.cpp b/src/qmlmodels/qqmllistmodel.cpp
index e07951cab3..8830e08097 100644
--- a/src/qmlmodels/qqmllistmodel.cpp
+++ b/src/qmlmodels/qqmllistmodel.cpp
@@ -703,7 +703,7 @@ void ListModel::set(int elementIndex, QV4::Object *object, ListModel::SetElement
         } else if (propertyValue->isNullOrUndefined()) {
             if (reason == SetElement::WasJustInserted) {
                 QQmlError err;
-                auto memberName = propertyName->toString(m_modelCache->engine())->toQString();
+                auto memberName = propertyName->toString(v4)->toQString();
                 err.setDescription(QString::fromLatin1("%1 is %2. Adding an object with a %2 member does not create a role for it.").arg(memberName, propertyValue->isNull() ? QLatin1String("null") : QLatin1String("undefined")));
                 qmlWarning(nullptr, err);
             } else {
diff --git a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
index d54e3467b7..1953798a15 100644
--- a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
+++ b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
@@ -130,6 +130,7 @@ private slots:
     void dynamic_roles_crash_QTBUG_38907();
     void nestedListModelIteration();
     void undefinedAppendShouldCauseError();
+    void nullPropertyCrash();
 };
 
 bool tst_qqmllistmodel::compareVariantList(const QVariantList &testList, QVariant object)
@@ -1723,6 +1724,27 @@ void tst_qqmllistmodel::undefinedAppendShouldCauseError()
     QScopedPointer<QObject>(component.create());
 }
 
+// QTBUG-89173
+void tst_qqmllistmodel::nullPropertyCrash()
+{
+    QQmlEngine engine;
+    QQmlComponent component(&engine);
+    component.setData(
+            R"(import QtQuick 2.15
+            ListView {
+                model: ListModel { id: listModel }
+
+                delegate: Item {}
+
+                Component.onCompleted: {
+                    listModel.append({"a": "value1", "b":[{"c":"value2"}]})
+                    listModel.append({"a": "value2", "b":[{"c":null}]})
+                }
+            })",
+            QUrl());
+    QTest::ignoreMessage(QtMsgType::QtWarningMsg, "<Unknown File>: c is null. Adding an object with a null member does not create a role for it.");
+    QScopedPointer<QObject>(component.create());
+}
 
 QTEST_MAIN(tst_qqmllistmodel)
 
-- 
2.33.0

From 1241e4f3c3ec010ae121f5d56c3e9405ec43231f Mon Sep 17 00:00:00 2001
From: Andy Shaw <andy.shaw@qt.io>
Date: Fri, 6 Nov 2020 13:30:12 +0100
Subject: [PATCH 19/41] Show a tableview even if the syncView has an empty
 model

By showing the tableview, we can be sure that headerviews will be
visible even in the syncView has an empty model.

Fixes: QTBUG-87526
Change-Id: I68c8b119122a2d2f88c2afbeb2d6c71a83a3ce33
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
(cherry picked from commit 27c254203b3e7dd6d3a4445feb205fbe98c32d30)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/quick/items/qquicktableview.cpp           |  7 +--
 .../qquicktableview/tst_qquicktableview.cpp   | 43 +++++++++++++++++++
 2 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp
index 7b73fcb393..1349d308d7 100644
--- a/src/quick/items/qquicktableview.cpp
+++ b/src/quick/items/qquicktableview.cpp
@@ -1760,11 +1760,8 @@ void QQuickTableViewPrivate::calculateTopLeft(QPoint &topLeftCell, QPointF &topL
         const auto syncView_d = syncView->d_func();
 
         if (syncView_d->loadedItems.isEmpty()) {
-            // The sync view contains no loaded items. This probably means
-            // that it has not been rebuilt yet. Which also means that
-            // we cannot rebuild anything before this happens.
-            topLeftCell.rx() = kEdgeIndexNotSet;
-            topLeftCell.ry() = kEdgeIndexNotSet;
+            topLeftCell.rx() = 0;
+            topLeftCell.ry() = 0;
             return;
         }
 
diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
index 54f73c6e0c..d489a873e4 100644
--- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
+++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
@@ -176,6 +176,7 @@ private slots:
     void checkSyncView_connect_late_data();
     void checkSyncView_connect_late();
     void checkSyncView_pageFlicking();
+    void checkSyncView_emptyModel();
     void delegateWithRequiredProperties();
     void checkThatFetchMoreIsCalledWhenScrolledToTheEndOfTable();
     void replaceModel();
@@ -2731,6 +2732,48 @@ void tst_QQuickTableView::checkSyncView_pageFlicking()
     QVERIFY(tableViewPrivate->scheduledRebuildOptions & QQuickTableViewPrivate::RebuildOption::CalculateNewTopLeftRow);
 }
 
+void tst_QQuickTableView::checkSyncView_emptyModel()
+{
+    // When a tableview has a syncview with an empty model then it should still be
+    // showing the tableview without depending on the syncview. This is particularly
+    // important for headerviews for example
+    LOAD_TABLEVIEW("syncviewsimple.qml");
+    GET_QML_TABLEVIEW(tableViewH);
+    GET_QML_TABLEVIEW(tableViewV);
+    GET_QML_TABLEVIEW(tableViewHV);
+    QQuickTableView *views[] = {tableViewH, tableViewV, tableViewHV};
+
+    auto model = TestModelAsVariant(100, 100);
+
+    for (auto view : views)
+        view->setModel(model);
+
+    WAIT_UNTIL_POLISHED_ARG(tableViewHV);
+
+    // Check that geometry properties are mirrored
+    QCOMPARE(tableViewH->columnSpacing(), tableView->columnSpacing());
+    QCOMPARE(tableViewH->rowSpacing(), 0);
+    QCOMPARE(tableViewH->contentWidth(), tableView->contentWidth());
+    QVERIFY(tableViewH->contentHeight() > 0);
+    QCOMPARE(tableViewV->columnSpacing(), 0);
+    QCOMPARE(tableViewV->rowSpacing(), tableView->rowSpacing());
+    QCOMPARE(tableViewV->contentHeight(), tableView->contentHeight());
+    QVERIFY(tableViewV->contentWidth() > 0);
+
+    QCOMPARE(tableViewH->contentX(), tableView->contentX());
+    QCOMPARE(tableViewH->contentY(), 0);
+    QCOMPARE(tableViewV->contentX(), 0);
+    QCOMPARE(tableViewV->contentY(), tableView->contentY());
+    QCOMPARE(tableViewHV->contentX(), tableView->contentX());
+    QCOMPARE(tableViewHV->contentY(), tableView->contentY());
+
+    QCOMPARE(tableViewHPrivate->loadedTableOuterRect.left(), tableViewPrivate->loadedTableOuterRect.left());
+    QCOMPARE(tableViewHPrivate->loadedTableOuterRect.top(), 0);
+
+    QCOMPARE(tableViewVPrivate->loadedTableOuterRect.top(), tableViewPrivate->loadedTableOuterRect.top());
+    QCOMPARE(tableViewVPrivate->loadedTableOuterRect.left(), 0);
+}
+
 void tst_QQuickTableView::checkThatFetchMoreIsCalledWhenScrolledToTheEndOfTable()
 {
     LOAD_TABLEVIEW("plaintableview.qml");
-- 
2.33.0

From 5e0ba6b797ca7843609fc19d8c4c96f6f26aacd2 Mon Sep 17 00:00:00 2001
From: Miikka Heikkinen <miikka.heikkinen@qt.io>
Date: Tue, 15 Dec 2020 12:43:40 +0200
Subject: [PATCH 20/41] DesignerSupport: Don't skip already inspected objects

Already inspected objects should not be skipped when determining their
properties, as recursive call will always have different base name for
the properties.

Internally we don't need inspectedObjects list at all anymore, but
it's kept to avoid changing API and in case the caller is interested
in inspected objects.

Fixes: QDS-3301
Change-Id: I76198b96d420e2a5ae6b13cfee65df4bce22d8f5
Pick-to: dev
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
---
 .../designer/qquickdesignersupportproperties.cpp  | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/src/quick/designer/qquickdesignersupportproperties.cpp b/src/quick/designer/qquickdesignersupportproperties.cpp
index 335795acf1..fb6a5fb324 100644
--- a/src/quick/designer/qquickdesignersupportproperties.cpp
+++ b/src/quick/designer/qquickdesignersupportproperties.cpp
@@ -137,11 +137,8 @@ QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::propert
     if (inspectedObjects == nullptr)
         inspectedObjects = &localObjectList;
 
-
-    if (inspectedObjects->contains(object))
-        return propertyNameList;
-
-    inspectedObjects->append(object);
+    if (!inspectedObjects->contains(object))
+        inspectedObjects->append(object);
 
     const QMetaObject *metaObject = object->metaObject();
     for (int index = 0; index < metaObject->propertyCount(); ++index) {
@@ -194,12 +191,8 @@ QQuickDesignerSupport::PropertyNameList QQuickDesignerSupportProperties::allProp
     if (inspectedObjects == nullptr)
         inspectedObjects = &localObjectList;
 
-
-    if (inspectedObjects->contains(object))
-        return propertyNameList;
-
-    inspectedObjects->append(object);
-
+    if (!inspectedObjects->contains(object))
+        inspectedObjects->append(object);
 
     const QMetaObject *metaObject = object->metaObject();
 
-- 
2.33.0

From 5a7aa7881fa2c7abffb3d34a6b642fe4efcadbf4 Mon Sep 17 00:00:00 2001
From: Fabian Kosmale <fabian.kosmale@qt.io>
Date: Thu, 17 Dec 2020 11:22:34 +0100
Subject: [PATCH 21/41] QML: Fix proxy iteration

If the target of a proxy was extensible, we did not set the
iteratorTarget to its correct value, and thus the ForInIteratorObject
would not be usable.

Fixes: QTBUG-86323
Change-Id: Id1924ac4087bab38c006b8eba92b619b79d36b7a
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit dd740d6b3469448dc1fd31c1742781e923e9f274)
---
 src/qml/jsruntime/qv4proxy.cpp                |  8 +++--
 .../qqmlecmascript/data/proxyIteration.qml    | 29 +++++++++++++++++++
 .../qml/qqmlecmascript/tst_qqmlecmascript.cpp | 10 +++++++
 3 files changed, 45 insertions(+), 2 deletions(-)
 create mode 100644 tests/auto/qml/qqmlecmascript/data/proxyIteration.qml

diff --git a/src/qml/jsruntime/qv4proxy.cpp b/src/qml/jsruntime/qv4proxy.cpp
index 1505eae426..8bfc9fc3ba 100644
--- a/src/qml/jsruntime/qv4proxy.cpp
+++ b/src/qml/jsruntime/qv4proxy.cpp
@@ -624,8 +624,10 @@ OwnPropertyKeyIterator *ProxyObject::virtualOwnPropertyKeys(const Object *m, Val
         else
             targetNonConfigurableKeys->push_back(keyAsValue);
     }
-    if (target->isExtensible() && targetNonConfigurableKeys->getLength() == 0)
+    if (target->isExtensible() && targetNonConfigurableKeys->getLength() == 0) {
+        *iteratorTarget = *m;
         return new ProxyObjectOwnPropertyKeyIterator(trapKeys);
+    }
 
     ScopedArrayObject uncheckedResultKeys(scope, scope.engine->newArrayObject());
     uncheckedResultKeys->copyArrayData(trapKeys);
@@ -639,8 +641,10 @@ OwnPropertyKeyIterator *ProxyObject::virtualOwnPropertyKeys(const Object *m, Val
         }
     }
 
-    if (target->isExtensible())
+    if (target->isExtensible()) {
+        *iteratorTarget = *m;
         return new ProxyObjectOwnPropertyKeyIterator(trapKeys);
+    }
 
     len = targetConfigurableKeys->getLength();
     for (uint i = 0; i < len; ++i) {
diff --git a/tests/auto/qml/qqmlecmascript/data/proxyIteration.qml b/tests/auto/qml/qqmlecmascript/data/proxyIteration.qml
new file mode 100644
index 0000000000..affba7d9f1
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/proxyIteration.qml
@@ -0,0 +1,29 @@
+import QtQml 2
+
+QtObject {
+  id: root
+  property int sum
+  Component.onCompleted: {
+    const target = { prop1: 1, prop2: 2, prop3: 3 };
+    const handler = {
+      get: function(target, key) {
+        return target[key]+1;
+      },
+      ownKeys: function() {
+        return ["prop1", "prop3"];
+      },
+      getOwnPropertyDescriptor: function(target, key) {
+        return {
+          value: this.get(target, key),
+          enumerable: true,
+          configurable: true
+        };
+      }
+    };
+    const proxy = new Proxy(target, handler);
+    for (var prop in proxy) {
+      root.sum += proxy[prop] // prop2 gets skipped, the values of 1 and 3 get incremented
+    }
+    // so root.sum should be 6 now
+  }
+}
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 3a9d1bfb4c..9198d3bebf 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -382,6 +382,7 @@ private slots:
     void semicolonAfterProperty();
     void hugeStack();
     void variantConversionMethod();
+    void proxyIteration();
     void proxyHandlerTraps();
     void gcCrashRegressionTest();
 
@@ -9306,6 +9307,15 @@ void tst_qqmlecmascript::variantConversionMethod()
     QCOMPARE(obj.funcCalled, QLatin1String("QModelIndex"));
 }
 
+void tst_qqmlecmascript::proxyIteration()
+{
+    QQmlEngine engine;
+    QQmlComponent component(&engine, testFileUrl("proxyIteration.qml"));
+    QScopedPointer<QObject> root(component.create());
+    QVERIFY2(root != nullptr, qPrintable(component.errorString()));
+    QCOMPARE(root->property("sum").toInt(), 6);
+}
+
 void tst_qqmlecmascript::proxyHandlerTraps()
 {
     const QString expression = QStringLiteral(R"SNIPPET(
-- 
2.33.0

From bb0ce1ffd48aa69da03dc43bd314351519ebf0d7 Mon Sep 17 00:00:00 2001
From: Fabian Kosmale <fabian.kosmale@qt.io>
Date: Tue, 8 Dec 2020 14:12:47 +0100
Subject: [PATCH 22/41] Fix IC properties in same file

Also fixes typename and metatype registration for inline components.

Done-with: Fabian Kosmale <fabian.kosmale@qt.io>
Fixes: QTBUG-89173
Change-Id: I97d65d5539b577a8828d5711e5f2e79c8568b441
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit c2ca14ce22551ea72544b6e2b3a19823b6dc3050)
---
 src/qml/qml/qqmlpropertycachecreator.cpp      |  9 +++++++
 src/qml/qml/qqmlpropertycachecreator_p.h      |  2 ++
 src/qml/qml/qqmlpropertyvalidator.cpp         | 25 +++++++++++++++++++
 src/qml/qml/qqmltypedata.cpp                  |  4 +--
 .../data/inlineComponentsSameFile.qml         | 11 ++++++++
 .../qml/qqmllanguage/tst_qqmllanguage.cpp     |  1 +
 6 files changed, 49 insertions(+), 3 deletions(-)
 create mode 100644 tests/auto/qml/qqmllanguage/data/inlineComponentsSameFile.qml

diff --git a/src/qml/qml/qqmlpropertycachecreator.cpp b/src/qml/qml/qqmlpropertycachecreator.cpp
index 36581bda4e..88d80d88ab 100644
--- a/src/qml/qml/qqmlpropertycachecreator.cpp
+++ b/src/qml/qml/qqmlpropertycachecreator.cpp
@@ -90,6 +90,15 @@ QByteArray QQmlPropertyCacheCreatorBase::createClassNameTypeByUrl(const QUrl &ur
             QByteArray::number(classIndexCounter.fetchAndAddRelaxed(1));
 }
 
+QByteArray QQmlPropertyCacheCreatorBase::createClassNameForInlineComponent(const QUrl &baseUrl, int icId)
+{
+    QByteArray baseName = createClassNameTypeByUrl(baseUrl);
+    if (baseName.isEmpty())
+        baseName = QByteArray("ANON_QML_IC_") + QByteArray::number(classIndexCounter.fetchAndAddRelaxed(1));
+    baseName += "_" + QByteArray::number(icId);
+    return baseName;
+}
+
 QQmlBindingInstantiationContext::QQmlBindingInstantiationContext(int referencingObjectIndex, const QV4::CompiledData::Binding *instantiatingBinding,
                                                                  const QString &instantiatingPropertyName, QQmlPropertyCache *referencingObjectPropertyCache)
     : referencingObjectIndex(referencingObjectIndex)
diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h
index 6b02d6fb98..77e3763a49 100644
--- a/src/qml/qml/qqmlpropertycachecreator_p.h
+++ b/src/qml/qml/qqmlpropertycachecreator_p.h
@@ -104,6 +104,8 @@ public:
     static int metaTypeForPropertyType(QV4::CompiledData::BuiltinType type);
 
     static QByteArray createClassNameTypeByUrl(const QUrl &url);
+
+    static QByteArray createClassNameForInlineComponent(const QUrl &baseUrl, int icId);
 };
 
 template <typename ObjectContainer>
diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp
index 3587609301..3a1f33113f 100644
--- a/src/qml/qml/qqmlpropertyvalidator.cpp
+++ b/src/qml/qml/qqmlpropertyvalidator.cpp
@@ -651,6 +651,19 @@ bool QQmlPropertyValidator::canCoerce(int to, QQmlPropertyCache *fromMo) const
 {
     QQmlPropertyCache *toMo = enginePrivate->rawPropertyCacheForType(to);
 
+    if (toMo == nullptr) {
+        // if we have an inline component from the current file,
+        // it is not properly registered at this point, as registration
+        // only occurs after the whole file has been validated
+        // Therefore we need to check the ICs here
+        for (const auto& icDatum : compilationUnit->inlineComponentData) {
+            if (icDatum.typeIds.id == to) {
+                toMo = compilationUnit->propertyCaches.at(icDatum.objectIndex);
+                break;
+            }
+        }
+    }
+
     while (fromMo) {
         if (fromMo == toMo)
             return true;
@@ -746,6 +759,18 @@ QQmlError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *propert
         // effect the properties on the type, but don't effect assignability
         // Using -1 for the minor version ensures that we get the raw metaObject.
         QQmlPropertyCache *propertyMetaObject = enginePrivate->rawPropertyCacheForType(propType, -1);
+        if (!propertyMetaObject) {
+            // if we have an inline component from the current file,
+            // it is not properly registered at this point, as registration
+            // only occurs after the whole file has been validated
+            // Therefore we need to check the ICs here
+            for (const auto& icDatum: compilationUnit->inlineComponentData) {
+                if (icDatum.typeIds.id == property->propType()) {
+                    propertyMetaObject = compilationUnit->propertyCaches.at(icDatum.objectIndex);
+                    break;
+                }
+            }
+        }
 
         if (propertyMetaObject) {
             // Will be true if the assigned type inherits propertyMetaObject
diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp
index fc1d0cfbcf..92a90ea677 100644
--- a/src/qml/qml/qqmltypedata.cpp
+++ b/src/qml/qml/qqmltypedata.cpp
@@ -283,9 +283,7 @@ void setupICs(const ObjectContainer &container, QHash<int, InlineComponentData>
     for (int i = 0; i != container->objectCount(); ++i) {
         auto root = container->objectAt(i);
         for (auto it = root->inlineComponentsBegin(); it != root->inlineComponentsEnd(); ++it) {
-            auto url = finalUrl;
-            url.setFragment(QString::number(it->objectIndex));
-            const QByteArray &className = QQmlPropertyCacheCreatorBase::createClassNameTypeByUrl(url);
+            const QByteArray &className = QQmlPropertyCacheCreatorBase::createClassNameForInlineComponent(finalUrl, it->objectIndex);
             InlineComponentData icDatum(QQmlMetaType::registerInternalCompositeType(className), int(it->objectIndex), int(it->nameIndex), 0, 0, 0);
             icData->insert(it->objectIndex, icDatum);
         }
diff --git a/tests/auto/qml/qqmllanguage/data/inlineComponentsSameFile.qml b/tests/auto/qml/qqmllanguage/data/inlineComponentsSameFile.qml
new file mode 100644
index 0000000000..87cac10200
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/inlineComponentsSameFile.qml
@@ -0,0 +1,11 @@
+import QtQml 2.15
+
+QtObject {
+    component IC : QtObject {
+        property string name
+        property int age
+    }
+
+    property IC other: IC { name: "Toby"; age: 30 }
+    property list<IC> listProp: [IC { name: "Alfred Ill"; age: 65 }, IC { name: "Claire Zachanassian"; age: 62}]
+}
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index 8adcbc1837..e247a139ec 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -5604,6 +5604,7 @@ void tst_qqmllanguage::inlineComponent_data()
     QTest::newRow("Alias resolves correctly") << testFileUrl("inlineComponentWithAlias.qml") << QColorConstants::Svg::lime << 42 << true;
 
     QTest::newRow("Two inline components in same do not crash (QTBUG-86989)") << testFileUrl("twoInlineComponents.qml") << QColor() << 0 << false;
+    QTest::newRow("Inline components used in same file (QTBUG-89173)") << testFileUrl("inlineComponentsSameFile.qml") << QColor() << 0 << false;
 }
 
 void tst_qqmllanguage::inlineComponentReferenceCycle_data()
-- 
2.33.0

From 35614462443c100b6753b335b58a134fed4b5c35 Mon Sep 17 00:00:00 2001
From: Ulf Hermann <ulf.hermann@qt.io>
Date: Wed, 16 Dec 2020 16:45:36 +0100
Subject: [PATCH 23/41] JIT: When making memory writable, include the exception
 handler

makeWritable() rounds the memory down to the next page boundary. Usually
we include the exception handler this way, unless the offset from the
page boundary is less than the exception handler size. Make it explicit
that we do want the exception handler to be writable, too.

Fixes: QTBUG-89513
Change-Id: I2fb8fb0e1dcc3450b036924463dc1b40d2020c46
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 86a595b126bc6794380dc00af80ec4802f7d058c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/3rdparty/masm/assembler/AssemblerBuffer.h      |  4 ++--
 src/3rdparty/masm/assembler/LinkBuffer.h           |  9 +++++----
 .../masm/assembler/MacroAssemblerCodeRef.h         |  6 +++---
 src/3rdparty/masm/stubs/ExecutableAllocator.h      | 11 ++++++++---
 src/qml/jsruntime/qv4executableallocator.cpp       | 14 ++++++++++++--
 src/qml/jsruntime/qv4executableallocator_p.h       | 10 ++++++++--
 src/qml/jsruntime/qv4functiontable_win64.cpp       |  4 ++--
 7 files changed, 40 insertions(+), 18 deletions(-)

diff --git a/src/3rdparty/masm/assembler/AssemblerBuffer.h b/src/3rdparty/masm/assembler/AssemblerBuffer.h
index 45874235b6..2292a4c244 100644
--- a/src/3rdparty/masm/assembler/AssemblerBuffer.h
+++ b/src/3rdparty/masm/assembler/AssemblerBuffer.h
@@ -140,9 +140,9 @@ namespace JSC {
             if (!result)
                 return 0;
 
-            ExecutableAllocator::makeWritable(result->start(), result->sizeInBytes());
+            ExecutableAllocator::makeWritable(result->memoryStart(), result->memorySize());
 
-            memcpy(result->start(), m_buffer, m_index);
+            memcpy(result->codeStart(), m_buffer, m_index);
             
             return result.release();
         }
diff --git a/src/3rdparty/masm/assembler/LinkBuffer.h b/src/3rdparty/masm/assembler/LinkBuffer.h
index ba57564a1d..fa669deaf9 100644
--- a/src/3rdparty/masm/assembler/LinkBuffer.h
+++ b/src/3rdparty/masm/assembler/LinkBuffer.h
@@ -333,7 +333,7 @@ inline void LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::linkCode
     m_executableMemory = m_assembler->m_assembler.executableCopy(*m_globalData, ownerUID, effort);
     if (!m_executableMemory)
         return;
-    m_code = m_executableMemory->start();
+    m_code = m_executableMemory->codeStart();
     m_size = m_assembler->m_assembler.codeSize();
     ASSERT(m_code);
 }
@@ -355,7 +355,8 @@ void LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::performFinaliza
 template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator>
 inline void LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::makeExecutable()
 {
-    ExecutableAllocator::makeExecutable(code(), static_cast<int>(m_size));
+    ExecutableAllocator::makeExecutable(m_executableMemory->memoryStart(),
+                                        m_executableMemory->memorySize());
 }
 
 template <typename MacroAssembler>
@@ -442,9 +443,9 @@ inline void BranchCompactingLinkBuffer<MacroAssembler>::linkCode(void* ownerUID,
     m_executableMemory = m_globalData->executableAllocator.allocate(*m_globalData, m_initialSize, ownerUID, effort);
     if (!m_executableMemory)
         return;
-    m_code = (uint8_t*)m_executableMemory->start();
+    m_code = (uint8_t*)m_executableMemory->codeStart();
     ASSERT(m_code);
-    ExecutableAllocator::makeWritable(m_code, m_initialSize);
+    ExecutableAllocator::makeWritable(m_executableMemory->memoryStart(), m_executableMemory->memorySize());
     uint8_t* inData = (uint8_t*)m_assembler->unlinkedCode();
     uint8_t* outData = reinterpret_cast<uint8_t*>(m_code);
     int readPtr = 0;
diff --git a/src/3rdparty/masm/assembler/MacroAssemblerCodeRef.h b/src/3rdparty/masm/assembler/MacroAssemblerCodeRef.h
index a7e78ad78f..cde9751108 100644
--- a/src/3rdparty/masm/assembler/MacroAssemblerCodeRef.h
+++ b/src/3rdparty/masm/assembler/MacroAssemblerCodeRef.h
@@ -357,11 +357,11 @@ public:
     }
 
     MacroAssemblerCodeRef(PassRefPtr<ExecutableMemoryHandle> executableMemory)
-        : m_codePtr(executableMemory->start())
+        : m_codePtr(executableMemory->codeStart())
         , m_executableMemory(executableMemory)
     {
         ASSERT(m_executableMemory->isManaged());
-        ASSERT(m_executableMemory->start());
+        ASSERT(m_executableMemory->codeStart());
         ASSERT(m_codePtr);
     }
     
@@ -395,7 +395,7 @@ public:
     {
         if (!m_executableMemory)
             return 0;
-        return m_executableMemory->sizeInBytes();
+        return m_executableMemory->codeSize();
     }
     
     bool tryToDisassemble(const char* prefix) const
diff --git a/src/3rdparty/masm/stubs/ExecutableAllocator.h b/src/3rdparty/masm/stubs/ExecutableAllocator.h
index a439c53827..f984704023 100644
--- a/src/3rdparty/masm/stubs/ExecutableAllocator.h
+++ b/src/3rdparty/masm/stubs/ExecutableAllocator.h
@@ -82,9 +82,14 @@ struct ExecutableMemoryHandle : public RefCounted<ExecutableMemoryHandle> {
 
     inline bool isManaged() const { return true; }
 
-    void *exceptionHandler() { return m_allocation->exceptionHandler(); }
-    void *start() { return m_allocation->start(); }
-    size_t sizeInBytes() { return m_size; }
+    void *memoryStart() { return m_allocation->memoryStart(); }
+    size_t memorySize() { return m_allocation->memorySize(); }
+
+    void *exceptionHandlerStart() { return m_allocation->exceptionHandlerStart(); }
+    size_t exceptionHandlerSize() { return m_allocation->exceptionHandlerSize(); }
+
+    void *codeStart() { return m_allocation->codeStart(); }
+    size_t codeSize() { return m_size; }
 
     QV4::ExecutableAllocator::ChunkOfPages *chunk() const
     { return m_allocator->chunkForAllocation(m_allocation); }
diff --git a/src/qml/jsruntime/qv4executableallocator.cpp b/src/qml/jsruntime/qv4executableallocator.cpp
index 7ee6f39aa2..c06773d3c5 100644
--- a/src/qml/jsruntime/qv4executableallocator.cpp
+++ b/src/qml/jsruntime/qv4executableallocator.cpp
@@ -45,12 +45,22 @@
 
 using namespace QV4;
 
-void *ExecutableAllocator::Allocation::exceptionHandler() const
+void *ExecutableAllocator::Allocation::exceptionHandlerStart() const
 {
     return reinterpret_cast<void*>(addr);
 }
 
-void *ExecutableAllocator::Allocation::start() const
+size_t ExecutableAllocator::Allocation::exceptionHandlerSize() const
+{
+    return QV4::exceptionHandlerSize();
+}
+
+void *ExecutableAllocator::Allocation::memoryStart() const
+{
+    return reinterpret_cast<void*>(addr);
+}
+
+void *ExecutableAllocator::Allocation::codeStart() const
 {
     return reinterpret_cast<void*>(addr + exceptionHandlerSize());
 }
diff --git a/src/qml/jsruntime/qv4executableallocator_p.h b/src/qml/jsruntime/qv4executableallocator_p.h
index f98f2c7d33..4735fb151f 100644
--- a/src/qml/jsruntime/qv4executableallocator_p.h
+++ b/src/qml/jsruntime/qv4executableallocator_p.h
@@ -86,8 +86,14 @@ public:
             , free(true)
         {}
 
-        void *exceptionHandler() const;
-        void *start() const;
+        void *memoryStart() const;
+        size_t memorySize() const { return size; }
+
+        void *exceptionHandlerStart() const;
+        size_t exceptionHandlerSize() const;
+
+        void *codeStart() const;
+
         void invalidate() { addr = 0; }
         bool isValid() const { return addr != 0; }
         void deallocate(ExecutableAllocator *allocator);
diff --git a/src/qml/jsruntime/qv4functiontable_win64.cpp b/src/qml/jsruntime/qv4functiontable_win64.cpp
index fc13dc2602..0cb98641cd 100644
--- a/src/qml/jsruntime/qv4functiontable_win64.cpp
+++ b/src/qml/jsruntime/qv4functiontable_win64.cpp
@@ -106,7 +106,7 @@ struct ExceptionHandlerRecord
 void generateFunctionTable(Function *, JSC::MacroAssemblerCodeRef *codeRef)
 {
     ExceptionHandlerRecord *record = reinterpret_cast<ExceptionHandlerRecord *>(
-                codeRef->executableMemory()->exceptionHandler());
+                codeRef->executableMemory()->exceptionHandlerStart());
 
     record->info.Version             = 1;
     record->info.Flags               = 0;
@@ -136,7 +136,7 @@ void generateFunctionTable(Function *, JSC::MacroAssemblerCodeRef *codeRef)
 void destroyFunctionTable(Function *, JSC::MacroAssemblerCodeRef *codeRef)
 {
     ExceptionHandlerRecord *record = reinterpret_cast<ExceptionHandlerRecord *>(
-                codeRef->executableMemory()->exceptionHandler());
+                codeRef->executableMemory()->exceptionHandlerStart());
     if (!RtlDeleteFunctionTable(&record->handler)) {
         const unsigned int errorCode = GetLastError();
         qWarning() << "Failed to remove win64 unwind hook. Error code:" << errorCode;
-- 
2.33.0

From e203a185cfab199a89a33b903096d6d0023a8a88 Mon Sep 17 00:00:00 2001
From: Shawn Rutledge <shawn.rutledge@qt.io>
Date: Wed, 30 Sep 2020 13:51:59 +0200
Subject: [PATCH 24/41] doc: explain QQItem event delivery, handlers,
 setAcceptTouchEvents()

We quietly recommended calling setAcceptTouchEvents() in the Qt 5.10
release notes in any Item subclass that wants to receive touch events,
and in the docs for setAcceptTouchEvents() itself; but the message about
the impending behavior change might not have been obvious enough.
In Qt 6 it becomes mandatory, so clearer docs will hopefully help to
stave off bogus bug reports.

We also never had a great overview of event handling from an Item's
perspective; now it's a little better.

Followup to ab91e7fa02a562d80fd0747f28a60e00c3b45a01 and
a97759a336c597327cb82eebc9f45c793aec32c9

[ChangeLog][QtQuick][QQuickItem] When subclassing QQuickItem, you
should call setAcceptTouchEvents(true) if you need the item to receive
touch events. It will be required in Qt 6.

Task-number: QTBUG-87018
Task-number: QTBUG-87082
Change-Id: I1c7a43979e3665778d61949c9d37c1d085ed594b
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 7c648280bb53c4276ba4ae2abf26d070fedde71a)
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
---
 src/quick/items/qquickitem.cpp | 34 +++++++++++++++++++++++++++++-----
 1 file changed, 29 insertions(+), 5 deletions(-)

diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index ddd67522b9..e02df00595 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -1,9 +1,9 @@
 /****************************************************************************
 **
-** Copyright (C) 2016 The Qt Company Ltd.
+** 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.
+** This file is part of the QtQuick module of the Qt Toolkit.fset
 **
 ** $QT_BEGIN_LICENSE:LGPL$
 ** Commercial License Usage
@@ -1883,7 +1883,23 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
     \endqml
 
 
-    \section2 Key Handling
+    \section2 Event Handling
+
+    All Item-based visual types can use \l {Qt Quick Input Handlers}{Input Handlers}
+    to handle incoming input events (subclasses of QInputEvent), such as mouse,
+    touch and key events. This is the preferred declarative way to handle events.
+
+    An alternative way to handle touch events is to subclass QQuickItem, call
+    setAcceptTouchEvents() in the constructor, and override touchEvent().
+    \l {QEvent::setAccepted()}{Accept} the entire event to stop delivery to
+    items underneath, and to exclusively grab all the event's touch points.
+
+    Likewise, a QQuickItem subclass can call setAcceptedMouseButtons()
+    to register to receive mouse button events, setAcceptHoverEvents()
+    to receive hover events (mouse movements while no button is pressed),
+    and override the virtual functions mousePressEvent(), mouseMoveEvent(), and
+    mouseReleaseEvent(). Those can also accept the event to prevent further
+    delivery and get an implicit grab at the same time.
 
     Key handling is available to all Item-based visual types via the \l Keys
     attached property.  The \e Keys attached property provides basic signals
@@ -7301,7 +7317,9 @@ bool QQuickItem::isAncestorOf(const QQuickItem *child) const
     If an item does not accept the mouse button for a particular mouse event,
     the mouse event will not be delivered to the item and will be delivered
     to the next item in the item hierarchy instead.
-  */
+
+    \sa acceptTouchEvents()
+*/
 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
 {
     Q_D(const QQuickItem);
@@ -7310,7 +7328,13 @@ Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
 
 /*!
     Sets the mouse buttons accepted by this item to \a buttons.
-  */
+
+    \note In Qt 5, calling setAcceptedMouseButtons() implicitly caused
+    an item to receive touch events as well as mouse events; but it was
+    recommended to call setAcceptTouchEvents() to subscribe for them.
+    In Qt 6, it is necessary to call setAcceptTouchEvents() to continue
+    to receive them.
+*/
 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
 {
     Q_D(QQuickItem);
-- 
2.33.0

From 6d7dfed857ab9e83ab2a917a929ce3b25342d90a Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <albert.astals.cid@kdab.com>
Date: Fri, 21 May 2021 13:30:41 +0200
Subject: [PATCH 25/41] Give a warning when StyledText encounters a non
 supported entity

Pick-to: 6.1 5.15
Change-Id: Iea8bdf25542cd404ee71141467ac1f1398a7d0df
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 8cd43e370040e23fcbd03ad64969e683055bd7d0)
---
 src/quick/util/qquickstyledtext.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/quick/util/qquickstyledtext.cpp b/src/quick/util/qquickstyledtext.cpp
index 660852ba83..d531fc9205 100644
--- a/src/quick/util/qquickstyledtext.cpp
+++ b/src/quick/util/qquickstyledtext.cpp
@@ -46,6 +46,8 @@
 #include "qquickstyledtext_p.h"
 #include <QQmlContext>
 
+Q_LOGGING_CATEGORY(lcStyledText, "qt.quick.styledtext")
+
 /*
     QQuickStyledText supports few tags:
 
@@ -566,6 +568,8 @@ void QQuickStyledTextPrivate::parseEntity(const QChar *&ch, const QString &textI
                 textOut += QChar(34);
             else if (entity == QLatin1String("nbsp"))
                 textOut += QChar(QChar::Nbsp);
+            else
+                qCWarning(lcStyledText) << "StyledText doesn't support entity" << entity;
             return;
         } else if (*ch == QLatin1Char(' ')) {
             QStringRef entity(&textIn, entityStart - 1, entityLength + 1);
-- 
2.33.0

From 4f08a2da5b0da675cf6a75683a43a106f5a1e7b8 Mon Sep 17 00:00:00 2001
From: Antonio Rojas <arojas@archlinux.org>
Date: Sun, 23 May 2021 14:32:46 +0200
Subject: [PATCH 26/41] Add missing limits include to fix build with GCC 11

This is not required for Qt 6, since it is indirectly pulled via
qanystrigview.h, but it is for Qt 5 (where qanystrigview does
not exist) and, in any case, it is good to declare all used headers
and not rely on them being implicitly pulled.

Pick-to: 6.1 5.15
Change-Id: I97606ea493e723006759608b7d4c4f00632f340c
Reviewed-by: Albert Astals Cid <albert.astals.cid@kdab.com>
(cherry picked from commit 367293b18ab0d0a0432c1c8ce445fee052e5eee5)
---
 src/qmldebug/qqmlprofilerevent_p.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/qmldebug/qqmlprofilerevent_p.h b/src/qmldebug/qqmlprofilerevent_p.h
index a7e37d1964..01b2f58f16 100644
--- a/src/qmldebug/qqmlprofilerevent_p.h
+++ b/src/qmldebug/qqmlprofilerevent_p.h
@@ -48,6 +48,7 @@
 #include <QtCore/qmetatype.h>
 
 #include <initializer_list>
+#include <limits>
 #include <type_traits>
 
 //
-- 
2.33.0

From ebc0daeea59af400601e6207cd9939c746fccdc7 Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <albert.astals.cid@kdab.com>
Date: Fri, 21 May 2021 13:17:15 +0200
Subject: [PATCH 27/41] Document that StyledText also supports &nbsp; and
 &quot;

Change-Id: I1715f8ae8ec8d0fbaf6dbe2b8663cc169da663cd
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 5848c081c094a66e024493fc1e5c2569e06f73b6)
---
 src/quick/items/qquicktext.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 581ab9f76a..26840b99e3 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;
     \endcode
 
     \c Text.StyledText parser is strict, requiring tags to be correctly nested.
-- 
2.33.0

From 0dda47d9f1a22567ad8f1266be2f0cd8a9226c7f Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <albert.astals.cid@kdab.com>
Date: Fri, 21 May 2021 13:42:35 +0200
Subject: [PATCH 28/41] Support &apos; in styled text

Pick-to: 6.1 5.15
Change-Id: I4a8db963e52a7899ab1796f9a560e8029cc1c929
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
(cherry picked from commit 96b528efcba1226d2980828d1255160bdceae4cf)
---
 src/quick/items/qquicktext.cpp      | 2 +-
 src/quick/util/qquickstyledtext.cpp | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 26840b99e3..4ddd2a41bc 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; &quot; &nbsp;
+    &gt; &lt; &amp; &quot; &nbsp; &apos;
     \endcode
 
     \c Text.StyledText parser is strict, requiring tags to be correctly nested.
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"))
-- 
2.33.0

From 6683c414c5cc6ab46197c41bb1361c518ca84d3e Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <albert.astals.cid@kdab.com>
Date: Thu, 17 Jun 2021 16:32:28 +0200
Subject: [PATCH 29/41] Remove unused QPointer<QQuickPointerMask>

Change-Id: I009fa6bbd8599dc3bb2e810176fe20e70ed50851
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
(cherry picked from commit ac03b4b8ee9cc8d4522e0c8cf1018ff086f80c1b)
---
 src/quick/items/qquickmousearea_p_p.h | 2 --
 1 file changed, 2 deletions(-)

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;
-- 
2.33.0

From 92225b72b9ca6b1efc9bc7bb0c12dd7487e900a7 Mon Sep 17 00:00:00 2001
From: Dmitry Shachnev <mitya57@gmail.com>
Date: Wed, 18 Aug 2021 22:50:29 +0300
Subject: [PATCH 30/41] Include <limits> in Yarr.h to fix build with GCC 11
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- <limits.h> (aka <climits>) is needed for UINT_MAX macro constant.
- <limits> is needed for std::numeric_limits.

Without this fix, qtdeclarative failed to build on some platforms:

 In file included from jsruntime/qv4regexp_p.h:62,
                  from jsruntime/qv4regexp.cpp:40:
 ../3rdparty/masm/yarr/Yarr.h:46:44: error: ‘numeric_limits’ is not a member of ‘std’
    46 | static const unsigned offsetNoMatch = std::numeric_limits<unsigned>::max();
       |                                            ^~~~~~~~~~~~~~

Pick-to: 5.15 6.2
Change-Id: I7cc9f7bc6624a52c8659f09034ab16064da5fd2f
Reviewed-by: Albert Astals Cid <albert.astals.cid@kdab.com>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit db58b8518e157b765bf2e01e6382a9eed4751f27)
---
 src/3rdparty/masm/yarr/Yarr.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/3rdparty/masm/yarr/Yarr.h b/src/3rdparty/masm/yarr/Yarr.h
index ccf78f9880..2955ea7e72 100644
--- a/src/3rdparty/masm/yarr/Yarr.h
+++ b/src/3rdparty/masm/yarr/Yarr.h
@@ -28,6 +28,7 @@
 #pragma once
 
 #include <limits.h>
+#include <limits>
 #include "YarrErrorCode.h"
 
 namespace JSC { namespace Yarr {
-- 
2.33.0

From 1c33a9d045897ce755a818ebff7ddecae97885d3 Mon Sep 17 00:00:00 2001
From: Aleix Pol <aleixpol@kde.org>
Date: Tue, 21 Sep 2021 00:10:26 +0200
Subject: [PATCH 31/41] QQuickLoader: Do not incubate if the source arrives
 after setActive(false)

Otherwise we end up in the crazy place of active being false but item
being non-null and forces us to workaround within the apps.

Change-Id: I88c27c4b00ccec8b8e0c05a8e10b44fcabfc2e30
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit e78c068700fa74ab3aca6a23ab2450563b1c3a5c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
---
 src/quick/items/qquickloader.cpp              |  3 +++
 .../data/loader-async-race-rect.qml           | 10 ++++++++++
 .../qquickloader/data/loader-async-race.qml   | 14 ++++++++++++++
 .../quick/qquickloader/tst_qquickloader.cpp   | 19 +++++++++++++++++++
 4 files changed, 46 insertions(+)
 create mode 100644 tests/auto/quick/qquickloader/data/loader-async-race-rect.qml
 create mode 100644 tests/auto/quick/qquickloader/data/loader-async-race.qml

diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index 8cd63a4236..a6f7009946 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -738,6 +738,9 @@ void QQuickLoaderPrivate::_q_sourceLoaded()
         return;
     }
 
+    if (!active)
+        return;
+
     QQmlContext *creationContext = component->creationContext();
     if (!creationContext) creationContext = qmlContext(q);
     itemContext = new QQmlContext(creationContext);
diff --git a/tests/auto/quick/qquickloader/data/loader-async-race-rect.qml b/tests/auto/quick/qquickloader/data/loader-async-race-rect.qml
new file mode 100644
index 0000000000..a56dcea5ad
--- /dev/null
+++ b/tests/auto/quick/qquickloader/data/loader-async-race-rect.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.15
+
+Rectangle {
+    anchors.fill: parent
+    color: "blue"
+    Item {
+        Item {
+        }
+    }
+}
diff --git a/tests/auto/quick/qquickloader/data/loader-async-race.qml b/tests/auto/quick/qquickloader/data/loader-async-race.qml
new file mode 100644
index 0000000000..8ba625c5c1
--- /dev/null
+++ b/tests/auto/quick/qquickloader/data/loader-async-race.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.15
+
+Item {
+    id: root
+    Component.onCompleted: {
+        myloader.active = false
+    }
+    Loader {
+        id: myloader
+        anchors.fill: parent
+        asynchronous: true
+        source: "loader-async-race-rect.qml"
+    }
+}
diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
index f4b682f3f4..fe2d71b037 100644
--- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp
+++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
@@ -132,6 +132,7 @@ private slots:
     void statusChangeOnlyEmittedOnce();
 
     void setSourceAndCheckStatus();
+    void asyncLoaderRace();
 };
 
 Q_DECLARE_METATYPE(QList<QQmlError>)
@@ -1491,6 +1492,24 @@ void tst_QQuickLoader::setSourceAndCheckStatus()
     QCOMPARE(loader->status(), QQuickLoader::Null);
 }
 
+void tst_QQuickLoader::asyncLoaderRace()
+{
+    QQmlApplicationEngine engine;
+    auto url = testFileUrl("loader-async-race.qml");
+    engine.load(url);
+    auto root = engine.rootObjects().at(0);
+    QVERIFY(root);
+
+    QQuickLoader *loader = root->findChild<QQuickLoader *>();
+    QCOMPARE(loader->active(), false);
+    QCOMPARE(loader->status(), QQuickLoader::Null);
+    QCOMPARE(loader->item(), nullptr);
+
+    QSignalSpy spy(loader, &QQuickLoader::itemChanged);
+    QVERIFY(!spy.wait(100));
+    QCOMPARE(loader->item(), nullptr);
+}
+
 QTEST_MAIN(tst_QQuickLoader)
 
 #include "tst_qquickloader.moc"
-- 
2.33.0

From e0271324f05fee2c8670a73d1e7e89aef51532a3 Mon Sep 17 00:00:00 2001
From: Aleix Pol <aleixpol@kde.org>
Date: Thu, 23 Sep 2021 03:43:04 +0200
Subject: [PATCH 32/41] QQmlDelegateModel: Refresh the view when a column is
 added at 0

It can happen that a model reports n>0 rows but columns=0 (See
QConcatenateTablesProxyModel). In those cases we would render glitchy
items until the elements are marked as dirty.

Change-Id: I615c9cacbb1b6f9dee3898b03476605e5ac39d0a
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit ec9251efb918f37971aeefa1f687d137d037ff12)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Signed-off-by: Aleix Pol <aleixpol@kde.org>
---
 src/qmlmodels/qqmldelegatemodel.cpp           | 44 +++++++++++++++++++
 src/qmlmodels/qqmldelegatemodel_p.h           |  3 ++
 .../data/redrawUponColumnChange.qml           | 11 +++++
 .../qqmldelegatemodel/qqmldelegatemodel.pro   |  2 +-
 .../tst_qqmldelegatemodel.cpp                 | 29 ++++++++++++
 5 files changed, 88 insertions(+), 1 deletion(-)
 create mode 100644 tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml

diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp
index 12c3d11937..8ce3da1cf1 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)),
@@ -1953,6 +1965,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/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/qqmldelegatemodel.pro b/tests/auto/qml/qqmldelegatemodel/qqmldelegatemodel.pro
index 7fdd3ab5f1..fbd72f6a44 100644
--- a/tests/auto/qml/qqmldelegatemodel/qqmldelegatemodel.pro
+++ b/tests/auto/qml/qqmldelegatemodel/qqmldelegatemodel.pro
@@ -2,7 +2,7 @@ CONFIG += testcase
 TARGET = tst_qqmldelegatemodel
 macos:CONFIG -= app_bundle
 
-QT += qml testlib core-private qml-private qmlmodels-private
+QT += qml quick testlib core-private qml-private qmlmodels-private
 
 SOURCES += tst_qqmldelegatemodel.cpp
 
diff --git a/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp b/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
index 87f42c0c8a..1d338ac330 100644
--- a/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
+++ b/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
@@ -27,8 +27,12 @@
 ****************************************************************************/
 
 #include <QtTest/qtest.h>
+#include <QtCore/QConcatenateTablesProxyModel>
+#include <QtGui/QStandardItemModel>
 #include <QtQml/qqmlcomponent.h>
 #include <QtQmlModels/private/qqmldelegatemodel_p.h>
+#include <QtQuick/qquickview.h>
+#include <QtQuick/qquickitem.h>
 
 #include "../../shared/util.h"
 
@@ -42,6 +46,7 @@ public:
 private slots:
     void valueWithoutCallingObjectFirst_data();
     void valueWithoutCallingObjectFirst();
+    void redrawUponColumnChange();
 };
 
 class AbstractItemModel : public QAbstractItemModel
@@ -134,6 +139,30 @@ void tst_QQmlDelegateModel::valueWithoutCallingObjectFirst()
     QCOMPARE(model->variantValue(index, role), expectedValue);
 }
 
+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"
-- 
2.33.0

From 9c0030bc8e828ecfbd8a4c8dd6bbfcbd3655b71c Mon Sep 17 00:00:00 2001
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
Date: Sun, 10 Oct 2021 21:04:21 +0300
Subject: [PATCH 33/41] Fix sweep step for tainted QObject JavaScript wrappers

Currently, whenever the garbage collector runs, it will destroy all
valid tainted wrappers.

Only null or undefined wrappers will be preserved in the
m_multiplyWrappedQObjects map.

It seems like "!" was overlooked in
3b5d37ce3841c4bfdf1c629d33f0e33b881b47fb. Prior to that change, it
was "!it.value()->markBit()", so calling erase() in the then branch
did make sense. But with "!it.value().isNullOrUndefined()", erase()
will be called for every valid wrapper, which is the opposite what we
want.

Pick-to: 5.15 6.2
Change-Id: I2bf2630f538af8cbd4bfffcff29d67be6c278265
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit e6b2f88d892dcf396580a61662f569bf69d6d9d1)
---
 src/qml/memory/qv4mm.cpp                   |  2 +-
 tests/auto/qml/qjsengine/tst_qjsengine.cpp | 39 ++++++++++++++++++++++
 tests/auto/qml/qv4mm/tst_qv4mm.cpp         |  6 ++--
 3 files changed, 43 insertions(+), 4 deletions(-)

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/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/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.
-- 
2.33.0

From c1ddd97c87c729c7d05c7a74f82d41cfc5bd9cf8 Mon Sep 17 00:00:00 2001
From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
Date: Tue, 12 Oct 2021 13:13:01 +0200
Subject: [PATCH 34/41] Fix distorted text with subpixel matrix translation

We would pixel-align native text *before* applying the
model-view matrix, which would cause GL_NEAREST artifacts to
show up when the text was positioned at a subpixel offset in
some cases. Instead, we pixel-align the coordinates after mapping
them to the view frustum, but before applying the projection to the
screen.

To make it easier to modify the buffer layout for the shaders the
next time, this also adds some constants for offsets.

[ChangeLog][Text] Fixed an issue where text using NativeRendering
would look slightly skewed if it was inside a parent that had
been positioned at a subpixel offset.

Pick-to: 5.15 6.2
Fixes: QTBUG-96112
Fixes: QTBUG-83626
Task-number: QTBUG-55638
Change-Id: Ifb785ad5830093df94afc75a7bc288e24ca7aa38
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
(cherry picked from commit b21948f5e811ce1b7abf065bc48af61a231e86f4)
---
 .../scenegraph/qsgdefaultglyphnode_p.cpp      | 46 ++++++----
 .../scenegraph/shaders_ng/24bittextmask.frag  |  5 +-
 .../scenegraph/shaders_ng/32bitcolortext.frag |  5 +-
 .../scenegraph/shaders_ng/8bittextmask.frag   |  3 +-
 .../scenegraph/shaders_ng/8bittextmask_a.frag |  3 +-
 .../scenegraph/shaders_ng/outlinedtext.frag   |  5 +-
 .../scenegraph/shaders_ng/outlinedtext.vert   |  9 +-
 .../scenegraph/shaders_ng/outlinedtext_a.frag |  5 +-
 .../scenegraph/shaders_ng/styledtext.frag     |  3 +-
 .../scenegraph/shaders_ng/styledtext.vert     |  7 +-
 .../scenegraph/shaders_ng/styledtext_a.frag   |  3 +-
 src/quick/scenegraph/shaders_ng/textmask.frag |  3 +-
 src/quick/scenegraph/shaders_ng/textmask.vert |  7 +-
 ...text_nativerendering_subpixelpositions.qml | 91 +++++++++++++++++++
 14 files changed, 155 insertions(+), 40 deletions(-)
 create mode 100644 tests/manual/scenegraph_lancelot/data/text/text_nativerendering_subpixelpositions.qml

diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
index 3c60f830de..0fd6581dc4 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
@@ -428,6 +428,18 @@ QSGTextMaskRhiShader::QSGTextMaskRhiShader(QFontEngine::GlyphFormat glyphFormat)
                       QStringLiteral(":/qt-project.org/scenegraph/shaders_ng/textmask.frag.qsb"));
 }
 
+enum UbufOffset {
+    ModelViewMatrixOffset = 0,
+    ProjectionMatrixOffset = ModelViewMatrixOffset + 64,
+    ColorOffset = ProjectionMatrixOffset + 64,
+    TextureScaleOffset = ColorOffset + 16,
+    DprOffset = TextureScaleOffset + 8,
+
+    // + 1 float padding (vec4 must be aligned to 16)
+    StyleColorOffset = DprOffset + 4 + 4,
+    ShiftOffset = StyleColorOffset + 16
+};
+
 bool QSGTextMaskRhiShader::updateUniformData(RenderState &state,
                                              QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
 {
@@ -443,11 +455,14 @@ bool QSGTextMaskRhiShader::updateUniformData(RenderState &state,
 
     bool changed = false;
     QByteArray *buf = state.uniformData();
-    Q_ASSERT(buf->size() >= 92);
+    Q_ASSERT(buf->size() >= DprOffset + 4);
 
     if (state.isMatrixDirty()) {
-        const QMatrix4x4 m = state.combinedMatrix();
-        memcpy(buf->data(), m.constData(), 64);
+        const QMatrix4x4 mv = state.modelViewMatrix();
+        memcpy(buf->data() + ModelViewMatrixOffset, mv.constData(), 64);
+        const QMatrix4x4 p = state.projectionMatrix();
+        memcpy(buf->data() + ProjectionMatrixOffset, p.constData(), 64);
+
         changed = true;
     }
 
@@ -456,13 +471,13 @@ bool QSGTextMaskRhiShader::updateUniformData(RenderState &state,
     if (updated || !oldMat || oldRtex != newRtex) {
         const QVector2D textureScale = QVector2D(1.0f / mat->rhiGlyphCache()->width(),
                                                  1.0f / mat->rhiGlyphCache()->height());
-        memcpy(buf->data() + 64 + 16, &textureScale, 8);
+        memcpy(buf->data() + TextureScaleOffset, &textureScale, 8);
         changed = true;
     }
 
     if (!oldMat) {
         float dpr = state.devicePixelRatio();
-        memcpy(buf->data() + 64 + 16 + 8, &dpr, 4);
+        memcpy(buf->data() + DprOffset, &dpr, 4);
     }
 
     // move texture uploads/copies onto the renderer's soon-to-be-committed list
@@ -510,11 +525,11 @@ bool QSG8BitTextMaskRhiShader::updateUniformData(RenderState &state,
     QSGTextMaskMaterial *oldMat = static_cast<QSGTextMaskMaterial *>(oldMaterial);
 
     QByteArray *buf = state.uniformData();
-    Q_ASSERT(buf->size() >= 80);
+    Q_ASSERT(buf->size() >= ColorOffset + 16);
 
     if (oldMat == nullptr || mat->color() != oldMat->color() || state.isOpacityDirty()) {
         const QVector4D color = qsg_premultiply(mat->color(), state.opacity());
-        memcpy(buf->data() + 64, &color, 16);
+        memcpy(buf->data() + ColorOffset, &color, 16);
         changed = true;
     }
 
@@ -553,12 +568,12 @@ bool QSG24BitTextMaskRhiShader::updateUniformData(RenderState &state,
     QSGTextMaskMaterial *oldMat = static_cast<QSGTextMaskMaterial *>(oldMaterial);
 
     QByteArray *buf = state.uniformData();
-    Q_ASSERT(buf->size() >= 92);
+    Q_ASSERT(buf->size() >= ColorOffset + 16);
 
     if (oldMat == nullptr || mat->color() != oldMat->color() || state.isOpacityDirty()) {
         // shader takes vec4 but uses alpha only; coloring happens via the blend constant
         const QVector4D color = qsg_premultiply(mat->color(), state.opacity());
-        memcpy(buf->data() + 64, &color, 16);
+        memcpy(buf->data() + ColorOffset, &color, 16);
         changed = true;
     }
 
@@ -608,12 +623,12 @@ bool QSG32BitColorTextRhiShader::updateUniformData(RenderState &state,
     QSGTextMaskMaterial *oldMat = static_cast<QSGTextMaskMaterial *>(oldMaterial);
 
     QByteArray *buf = state.uniformData();
-    Q_ASSERT(buf->size() >= 92);
+    Q_ASSERT(buf->size() >= ColorOffset + 16);
 
     if (oldMat == nullptr || mat->color() != oldMat->color() || state.isOpacityDirty()) {
         // shader takes vec4 but uses alpha only
         const QVector4D color(0, 0, 0, mat->color().w() * state.opacity());
-        memcpy(buf->data() + 64, &color, 16);
+        memcpy(buf->data() + ColorOffset, &color, 16);
         changed = true;
     }
 
@@ -649,20 +664,17 @@ bool QSGStyledTextRhiShader::updateUniformData(RenderState &state,
     QSGStyledTextMaterial *oldMat = static_cast<QSGStyledTextMaterial *>(oldMaterial);
 
     QByteArray *buf = state.uniformData();
-    Q_ASSERT(buf->size() >= 120);
-
-    // matrix..dpr + 1 float padding (vec4 must be aligned to 16)
-    const int startOffset = 64 + 16 + 8 + 4 + 4;
+    Q_ASSERT(buf->size() >= ShiftOffset + 8);
 
     if (oldMat == nullptr || mat->styleColor() != oldMat->styleColor() || state.isOpacityDirty()) {
         const QVector4D styleColor = qsg_premultiply(mat->styleColor(), state.opacity());
-        memcpy(buf->data() + startOffset, &styleColor, 16);
+        memcpy(buf->data() + StyleColorOffset, &styleColor, 16);
         changed = true;
     }
 
     if (oldMat == nullptr || oldMat->styleShift() != mat->styleShift()) {
         const QVector2D v = mat->styleShift();
-        memcpy(buf->data() + startOffset + 16, &v, 8);
+        memcpy(buf->data() + ShiftOffset, &v, 8);
         changed = true;
     }
 
diff --git a/src/quick/scenegraph/shaders_ng/24bittextmask.frag b/src/quick/scenegraph/shaders_ng/24bittextmask.frag
index bc3826a924..ed8da4cd30 100644
--- a/src/quick/scenegraph/shaders_ng/24bittextmask.frag
+++ b/src/quick/scenegraph/shaders_ng/24bittextmask.frag
@@ -6,8 +6,9 @@ layout(location = 0) out vec4 fragColor;
 layout(binding = 1) uniform sampler2D _qt_texture;
 
 layout(std140, binding = 0) uniform buf {
-    mat4 matrix;
-    vec4 color; // only alpha is used, but must be vec4 due to layout compat
+    mat4 modelViewMatrix;
+    mat4 projectionMatrix;
+    vec4 color;
     vec2 textureScale;
     float dpr;
 } ubuf;
diff --git a/src/quick/scenegraph/shaders_ng/32bitcolortext.frag b/src/quick/scenegraph/shaders_ng/32bitcolortext.frag
index 63e445f90b..4198a4d339 100644
--- a/src/quick/scenegraph/shaders_ng/32bitcolortext.frag
+++ b/src/quick/scenegraph/shaders_ng/32bitcolortext.frag
@@ -6,8 +6,9 @@ layout(location = 0) out vec4 fragColor;
 layout(binding = 1) uniform sampler2D _qt_texture;
 
 layout(std140, binding = 0) uniform buf {
-    mat4 matrix;
-    vec4 color; // only alpha is used, but must be vec4 due to layout compat
+    mat4 modelViewMatrix;
+    mat4 projectionMatrix;
+    vec4 color;
     vec2 textureScale;
     float dpr;
 } ubuf;
diff --git a/src/quick/scenegraph/shaders_ng/8bittextmask.frag b/src/quick/scenegraph/shaders_ng/8bittextmask.frag
index 6304e821ff..a06743876d 100644
--- a/src/quick/scenegraph/shaders_ng/8bittextmask.frag
+++ b/src/quick/scenegraph/shaders_ng/8bittextmask.frag
@@ -6,7 +6,8 @@ layout(location = 0) out vec4 fragColor;
 layout(binding = 1) uniform sampler2D _qt_texture;
 
 layout(std140, binding = 0) uniform buf {
-    mat4 matrix;
+    mat4 modelViewMatrix;
+    mat4 projectionMatrix;
     vec4 color;
     vec2 textureScale;
     float dpr;
diff --git a/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag b/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag
index 0d0fa1cd3a..f725cbc5e7 100644
--- a/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag
+++ b/src/quick/scenegraph/shaders_ng/8bittextmask_a.frag
@@ -6,7 +6,8 @@ layout(location = 0) out vec4 fragColor;
 layout(binding = 1) uniform sampler2D _qt_texture;
 
 layout(std140, binding = 0) uniform buf {
-    mat4 matrix;
+    mat4 modelViewMatrix;
+    mat4 projectionMatrix;
     vec4 color;
     vec2 textureScale;
     float dpr;
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext.frag b/src/quick/scenegraph/shaders_ng/outlinedtext.frag
index 947d161a50..e2f82d3845 100644
--- a/src/quick/scenegraph/shaders_ng/outlinedtext.frag
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext.frag
@@ -11,11 +11,12 @@ layout(location = 0) out vec4 fragColor;
 layout(binding = 1) uniform sampler2D _qt_texture;
 
 layout(std140, binding = 0) uniform buf {
-    // must match styledtext
-    mat4 matrix;
+    mat4 modelViewMatrix;
+    mat4 projectionMatrix;
     vec4 color;
     vec2 textureScale;
     float dpr;
+    // the above must stay compatible with textmask/8bittextmask
     vec4 styleColor;
     vec2 shift;
 } ubuf;
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext.vert b/src/quick/scenegraph/shaders_ng/outlinedtext.vert
index 023f9dfdc2..4068e42f28 100644
--- a/src/quick/scenegraph/shaders_ng/outlinedtext.vert
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext.vert
@@ -10,11 +10,12 @@ layout(location = 3) out vec2 sCoordLeft;
 layout(location = 4) out vec2 sCoordRight;
 
 layout(std140, binding = 0) uniform buf {
-    // must match styledtext
-    mat4 matrix;
+    mat4 modelViewMatrix;
+    mat4 projectionMatrix;
     vec4 color;
     vec2 textureScale;
     float dpr;
+    // the above must stay compatible with textmask/8bittextmask
     vec4 styleColor;
     vec2 shift;
 } ubuf;
@@ -28,6 +29,6 @@ void main()
      sCoordDown = (tCoord - vec2(0.0, 1.0)) * ubuf.textureScale;
      sCoordLeft = (tCoord - vec2(-1.0, 0.0)) * ubuf.textureScale;
      sCoordRight = (tCoord - vec2(1.0, 0.0)) * ubuf.textureScale;
-     vec3 dprSnapPos = floor(vCoord.xyz * ubuf.dpr + 0.5) / ubuf.dpr;
-     gl_Position = ubuf.matrix * vec4(dprSnapPos, vCoord.w);
+     vec4 xformed = ubuf.modelViewMatrix * vCoord;
+     gl_Position = ubuf.projectionMatrix * vec4(floor(xformed.xyz * ubuf.dpr + 0.5) / ubuf.dpr, xformed.w);
 }
diff --git a/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag b/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag
index 5b7bd9ca82..274d891a3c 100644
--- a/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag
+++ b/src/quick/scenegraph/shaders_ng/outlinedtext_a.frag
@@ -11,11 +11,12 @@ layout(location = 0) out vec4 fragColor;
 layout(binding = 1) uniform sampler2D _qt_texture;
 
 layout(std140, binding = 0) uniform buf {
-    // must match styledtext
-    mat4 matrix;
+    mat4 modelViewMatrix;
+    mat4 projectionMatrix;
     vec4 color;
     vec2 textureScale;
     float dpr;
+    // the above must stay compatible with textmask/8bittextmask
     vec4 styleColor;
     vec2 shift;
 } ubuf;
diff --git a/src/quick/scenegraph/shaders_ng/styledtext.frag b/src/quick/scenegraph/shaders_ng/styledtext.frag
index 0b16396037..2e380dfeae 100644
--- a/src/quick/scenegraph/shaders_ng/styledtext.frag
+++ b/src/quick/scenegraph/shaders_ng/styledtext.frag
@@ -8,7 +8,8 @@ layout(location = 0) out vec4 fragColor;
 layout(binding = 1) uniform sampler2D _qt_texture;
 
 layout(std140, binding = 0) uniform buf {
-    mat4 matrix;
+    mat4 modelViewMatrix;
+    mat4 projectionMatrix;
     vec4 color;
     vec2 textureScale;
     float dpr;
diff --git a/src/quick/scenegraph/shaders_ng/styledtext.vert b/src/quick/scenegraph/shaders_ng/styledtext.vert
index beadf07c79..271dae8d8a 100644
--- a/src/quick/scenegraph/shaders_ng/styledtext.vert
+++ b/src/quick/scenegraph/shaders_ng/styledtext.vert
@@ -7,7 +7,8 @@ layout(location = 0) out vec2 sampleCoord;
 layout(location = 1) out vec2 shiftedSampleCoord;
 
 layout(std140, binding = 0) uniform buf {
-    mat4 matrix;
+    mat4 modelViewMatrix;
+    mat4 projectionMatrix;
     vec4 color;
     vec2 textureScale;
     float dpr;
@@ -22,6 +23,6 @@ void main()
 {
      sampleCoord = tCoord * ubuf.textureScale;
      shiftedSampleCoord = (tCoord - ubuf.shift) * ubuf.textureScale;
-     vec3 dprSnapPos = floor(vCoord.xyz * ubuf.dpr + 0.5) / ubuf.dpr;
-     gl_Position = ubuf.matrix * vec4(dprSnapPos, vCoord.w);
+     vec4 xformed = ubuf.modelViewMatrix * vCoord;
+     gl_Position = ubuf.projectionMatrix * vec4(floor(xformed.xyz * ubuf.dpr + 0.5) / ubuf.dpr, xformed.w);
 }
diff --git a/src/quick/scenegraph/shaders_ng/styledtext_a.frag b/src/quick/scenegraph/shaders_ng/styledtext_a.frag
index b673137895..62e162c851 100644
--- a/src/quick/scenegraph/shaders_ng/styledtext_a.frag
+++ b/src/quick/scenegraph/shaders_ng/styledtext_a.frag
@@ -8,7 +8,8 @@ layout(location = 0) out vec4 fragColor;
 layout(binding = 1) uniform sampler2D _qt_texture;
 
 layout(std140, binding = 0) uniform buf {
-    mat4 matrix;
+    mat4 modelViewMatrix;
+    mat4 projectionMatrix;
     vec4 color;
     vec2 textureScale;
     float dpr;
diff --git a/src/quick/scenegraph/shaders_ng/textmask.frag b/src/quick/scenegraph/shaders_ng/textmask.frag
index 518d5c965f..ed8da4cd30 100644
--- a/src/quick/scenegraph/shaders_ng/textmask.frag
+++ b/src/quick/scenegraph/shaders_ng/textmask.frag
@@ -6,7 +6,8 @@ layout(location = 0) out vec4 fragColor;
 layout(binding = 1) uniform sampler2D _qt_texture;
 
 layout(std140, binding = 0) uniform buf {
-    mat4 matrix;
+    mat4 modelViewMatrix;
+    mat4 projectionMatrix;
     vec4 color;
     vec2 textureScale;
     float dpr;
diff --git a/src/quick/scenegraph/shaders_ng/textmask.vert b/src/quick/scenegraph/shaders_ng/textmask.vert
index 9d80d5dadb..e0b3c01bce 100644
--- a/src/quick/scenegraph/shaders_ng/textmask.vert
+++ b/src/quick/scenegraph/shaders_ng/textmask.vert
@@ -6,7 +6,8 @@ layout(location = 1) in vec2 tCoord;
 layout(location = 0) out vec2 sampleCoord;
 
 layout(std140, binding = 0) uniform buf {
-    mat4 matrix;
+    mat4 modelViewMatrix;
+    mat4 projectionMatrix;
     vec4 color;
     vec2 textureScale;
     float dpr;
@@ -17,6 +18,6 @@ out gl_PerVertex { vec4 gl_Position; };
 void main()
 {
      sampleCoord = tCoord * ubuf.textureScale;
-     vec3 dprSnapPos = floor(vCoord.xyz * ubuf.dpr + 0.5) / ubuf.dpr;
-     gl_Position = ubuf.matrix * vec4(dprSnapPos, vCoord.w);
+     vec4 xformed = ubuf.modelViewMatrix * vCoord;
+     gl_Position = ubuf.projectionMatrix * vec4(floor(xformed.xyz * ubuf.dpr + 0.5) / ubuf.dpr, xformed.w);
 }
diff --git a/tests/manual/scenegraph_lancelot/data/text/text_nativerendering_subpixelpositions.qml b/tests/manual/scenegraph_lancelot/data/text/text_nativerendering_subpixelpositions.qml
new file mode 100644
index 0000000000..c60fc4d8b0
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/text/text_nativerendering_subpixelpositions.qml
@@ -0,0 +1,91 @@
+import QtQuick 2.0
+
+//vary font style, native rendering at non-integer offsets
+
+Item {
+    id: topLevel
+    width: 320
+    height: 580
+
+    Repeater {
+        model: [Text.Normal, Text.Outline, Text.Raised, Text.Sunken]
+        Text {
+            y: 20 * index
+            clip: true
+            renderType: Text.NativeRendering
+            width: parent.width
+            wrapMode: Text.Wrap
+            font.pointSize: 10
+            style: modelData
+            styleColor: "green"
+            text: "The quick fox jumps in style " + modelData
+        }
+    }
+
+    Repeater {
+        model: [Text.Normal, Text.Outline, Text.Raised, Text.Sunken]
+        Text {
+            y: 100.5 + 20 * index
+            clip: true
+            renderType: Text.NativeRendering
+            width: parent.width
+            wrapMode: Text.Wrap
+            font.pointSize: 10
+            style: modelData
+            styleColor: "green"
+            text: "The quick fox jumps in style " + modelData
+        }
+    }
+
+    Repeater {
+        model: [Text.Normal, Text.Outline, Text.Raised, Text.Sunken]
+        Text {
+            y: 200.5 + 20 * index
+            x: 0.5
+            clip: true
+            renderType: Text.NativeRendering
+            width: parent.width
+            wrapMode: Text.Wrap
+            font.pointSize: 10
+            style: modelData
+            styleColor: "green"
+            text: "The quick fox jumps in style " + modelData
+        }
+    }
+
+    Repeater {
+        model: [Text.Normal, Text.Outline, Text.Raised, Text.Sunken]
+        Text {
+            y: 300.5 + 20 * index
+            x: 0.5
+            clip: true
+            renderType: Text.NativeRendering
+            width: parent.width
+            wrapMode: Text.Wrap
+            font.pointSize: 10
+            style: modelData
+            styleColor: "green"
+            text: "The quick fox jumps in style " + modelData
+        }
+    }
+
+    Repeater {
+        model: [Text.Normal, Text.Outline, Text.Raised, Text.Sunken]
+        Rectangle {
+            y: 400.5 + 20 * index
+            x: 0.5
+            width: topLevel.width
+            height: topLevel.height
+            clip: true
+            Text {
+                renderType: Text.NativeRendering
+                width: parent.width
+                wrapMode: Text.Wrap
+                font.pointSize: 10
+                style: modelData
+                styleColor: "green"
+                text: "The quick fox jumps in style " + modelData
+            }
+        }
+    }
+}
-- 
2.33.0

From 9dde7b66a30a33074fc2c2c682b53b18791dba0d Mon Sep 17 00:00:00 2001
From: Laszlo Agocs <laszlo.agocs@qt.io>
Date: Mon, 11 Oct 2021 15:37:33 +0200
Subject: [PATCH 35/41] Revert "Fix for possible crash in
 QSGDefaultLayer::grab"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This reverts commit 1c5de027d0c31d1d6697bd0557128d92207763d8.

The fix here is not correct. Calling a QSGRhiLayer function from the gui
thread is very wrong and can cause a set of unexpected issues. The
Address Sanitizer catches this by recognizing that the render thread is
trying to do something with an object destroyed in the meantime on the
main thread in the layer->setItem(null) call.

The issue the original fix is trying to address needs to be addressed in
some different form.

Fixes: QTBUG-94975
Pick-to: 6.2 6.1 5.15
Change-Id: I46f904026281201fc6d233ed7d3bdc7080934afe
Reviewed-by: Christian Strømme <christian.stromme@qt.io>
(cherry picked from commit a5f0361622eb08eab6c3474d5fc249d1962e3d1e)
---
 src/quick/items/qquickshadereffectsource.cpp | 8 --------
 src/quick/items/qquickshadereffectsource_p.h | 1 -
 2 files changed, 9 deletions(-)

diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp
index 4f61d61309..b298ed74da 100644
--- a/src/quick/items/qquickshadereffectsource.cpp
+++ b/src/quick/items/qquickshadereffectsource.cpp
@@ -344,7 +344,6 @@ void QQuickShaderEffectSource::setSourceItem(QQuickItem *item)
             d->refFromEffectItem(m_hideSource);
             d->addItemChangeListener(this, QQuickItemPrivate::Geometry);
             connect(m_sourceItem, SIGNAL(destroyed(QObject*)), this, SLOT(sourceItemDestroyed(QObject*)));
-            connect(m_sourceItem, SIGNAL(parentChanged(QQuickItem*)), this, SLOT(sourceItemParentChanged(QQuickItem*)));
         } else {
             qWarning("ShaderEffectSource: sourceItem and ShaderEffectSource must both be children of the same window.");
             m_sourceItem = nullptr;
@@ -364,13 +363,6 @@ void QQuickShaderEffectSource::sourceItemDestroyed(QObject *item)
 }
 
 
-void QQuickShaderEffectSource::sourceItemParentChanged(QQuickItem *parent)
-{
-    if (!parent && m_texture)
-        m_texture->setItem(0);
-}
-
-
 /*!
     \qmlproperty rect QtQuick::ShaderEffectSource::sourceRect
 
diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h
index 4deb6c70a3..c0a1ccab78 100644
--- a/src/quick/items/qquickshadereffectsource_p.h
+++ b/src/quick/items/qquickshadereffectsource_p.h
@@ -173,7 +173,6 @@ Q_SIGNALS:
 private Q_SLOTS:
     void sourceItemDestroyed(QObject *item);
     void invalidateSceneGraph();
-    void sourceItemParentChanged(QQuickItem *parent);
 
 protected:
     void releaseResources() override;
-- 
2.33.0

From 55324650f9e759a43dce927f823c9858574106c3 Mon Sep 17 00:00:00 2001
From: Alexey Edelev <alexey.edelev@qt.io>
Date: Tue, 12 Jan 2021 16:37:09 +0100
Subject: [PATCH 36/41] Do not revert properties of deleted objects

If state contains revert action of properties of deleted objects,
we should avoid adding them to apply list

Fixes: QTBUG-85106
Pick-to: 5.15
Change-Id: Iff57eb9958a054476096f6d951ab7390277a2b39
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit 96763dbb105fde20431a264789ac27abfdab841c)
---
 src/quick/util/qquickstate.cpp                |  5 ++
 .../data/revertNullObjectBinding.qml          | 48 +++++++++++++
 .../quick/qquickstates/tst_qquickstates.cpp   | 68 +++++++++++++++++++
 3 files changed, 121 insertions(+)
 create mode 100644 tests/auto/quick/qquickstates/data/revertNullObjectBinding.qml

diff --git a/src/quick/util/qquickstate.cpp b/src/quick/util/qquickstate.cpp
index 71ab1f4d62..6a72754bde 100644
--- a/src/quick/util/qquickstate.cpp
+++ b/src/quick/util/qquickstate.cpp
@@ -635,6 +635,11 @@ void QQuickState::apply(QQuickTransition *trans, QQuickState *revert)
             }
         }
         if (!found) {
+            // If revert list contains bindings assigned to deleted objects, we need to
+            // prevent reverting properties of those objects.
+            if (d->revertList.at(ii).binding() && !d->revertList.at(ii).property().object()) {
+                continue;
+            }
             QVariant cur = d->revertList.at(ii).property().read();
             QQmlPropertyPrivate::removeBinding(d->revertList.at(ii).property());
 
diff --git a/tests/auto/quick/qquickstates/data/revertNullObjectBinding.qml b/tests/auto/quick/qquickstates/data/revertNullObjectBinding.qml
new file mode 100644
index 0000000000..dee82f52ed
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/revertNullObjectBinding.qml
@@ -0,0 +1,48 @@
+import QtQuick 2.12
+import Qt.test 1.0
+
+Item {
+    id: root
+    readonly property int someProp: 1234
+
+    property bool state1Active: false
+    property bool state2Active: false
+    StateGroup {
+        states: [
+            State {
+                id: state1
+                name: "state1"
+                when: state1Active
+                changes: [
+                    PropertyChanges {
+                        objectName: "propertyChanges1"
+                        target: ContainingObj.obj
+                        prop: root.someProp
+                    }
+                ]
+            }
+    ]}
+    StateGroup {
+        states: [
+            State {
+                id: state2
+                name: "state2"
+                when: state2Active
+                changes: [
+                    PropertyChanges {
+                        objectName: "propertyChanges2"
+                        target: ContainingObj.obj
+                        prop: 11111
+                    }
+                ]
+            }
+        ]
+    }
+
+    Component.onCompleted: {
+        state1Active = true;
+        state2Active = true;
+
+        ContainingObj.reset()
+    }
+}
diff --git a/tests/auto/quick/qquickstates/tst_qquickstates.cpp b/tests/auto/quick/qquickstates/tst_qquickstates.cpp
index d5fea3cb28..849522454f 100644
--- a/tests/auto/quick/qquickstates/tst_qquickstates.cpp
+++ b/tests/auto/quick/qquickstates/tst_qquickstates.cpp
@@ -79,6 +79,55 @@ private:
 QML_DECLARE_TYPE(MyRect)
 QML_DECLARE_TYPEINFO(MyRect, QML_HAS_ATTACHED_PROPERTIES)
 
+class RemovableObj : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(int prop READ prop WRITE setProp NOTIFY propChanged)
+
+public:
+    RemovableObj(QObject *parent) : QObject(parent), m_prop(4321) { }
+    int prop() const { return m_prop; }
+
+public slots:
+    void setProp(int prop)
+    {
+        if (m_prop == prop)
+            return;
+
+        m_prop = prop;
+        emit propChanged(m_prop);
+    }
+
+signals:
+    void propChanged(int prop);
+
+private:
+    int m_prop;
+};
+
+class ContainingObj : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(RemovableObj *obj READ obj NOTIFY objChanged)
+    RemovableObj *m_obj;
+
+public:
+    ContainingObj() : m_obj(new RemovableObj(this)) { }
+    RemovableObj *obj() const { return m_obj; }
+
+    Q_INVOKABLE void reset()
+    {
+        if (m_obj) {
+            m_obj->deleteLater();
+        }
+
+        m_obj = new RemovableObj(this);
+        emit objChanged();
+    }
+signals:
+    void objChanged();
+};
+
 class tst_qquickstates : public QQmlDataTest
 {
     Q_OBJECT
@@ -140,12 +189,20 @@ private slots:
     void duplicateStateName();
     void trivialWhen();
     void parentChangeCorrectReversal();
+    void revertNullObjectBinding();
 };
 
 void tst_qquickstates::initTestCase()
 {
     QQmlDataTest::initTestCase();
     qmlRegisterType<MyRect>("Qt.test", 1, 0, "MyRectangle");
+    qmlRegisterSingletonType<ContainingObj>(
+            "Qt.test", 1, 0, "ContainingObj", [](QQmlEngine *engine, QJSEngine *) {
+                static ContainingObj instance;
+                engine->setObjectOwnership(&instance, QQmlEngine::CppOwnership);
+                return &instance;
+            });
+    qmlRegisterUncreatableType<RemovableObj>("Qt.test", 1, 0, "RemovableObj", "Uncreatable");
 }
 
 QByteArray tst_qquickstates::fullDataPath(const QString &path) const
@@ -1692,6 +1749,17 @@ void tst_qquickstates::parentChangeCorrectReversal()
     QCOMPARE(oldX, stayingRectX.read().toDouble());
 }
 
+void tst_qquickstates::revertNullObjectBinding()
+{
+    QQmlEngine engine;
+
+    QQmlComponent c(&engine, testFileUrl("revertNullObjectBinding.qml"));
+    QScopedPointer<QObject> root { c.create() };
+    QVERIFY(root);
+    QTest::qWait(10);
+    QQmlProperty state2Active(root.get(), "state2Active");
+    state2Active.write(false);
+}
 
 QTEST_MAIN(tst_qquickstates)
 
-- 
2.33.0

From 8e85afd011ea25eec0aa710481e2474dbaaee869 Mon Sep 17 00:00:00 2001
From: Volker Hilsheimer <volker.hilsheimer@qt.io>
Date: Wed, 17 Mar 2021 16:52:21 +0100
Subject: [PATCH 37/41] QQuickItemAnimation: close potential memory leak

Fix static analyzer warning bff6cb4333f531d5a72f7bf6dc1485f6.

If ownership of viaData is not passed to the viaAction, then the object
might be leaked. Use std::unique_ptr to make ownership transfer explicit
and implicitly delete unowned objects.

Pick-to: 6.1 5.15
Change-Id: I89f2a6b630941a98a74db302bc1ab08055c71974
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit 78aea267209c34abeb4895712dc76c923aa46165)
---
 src/quick/items/qquickitemanimation.cpp | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/src/quick/items/qquickitemanimation.cpp b/src/quick/items/qquickitemanimation.cpp
index 23694e2de3..dfb56ccc00 100644
--- a/src/quick/items/qquickitemanimation.cpp
+++ b/src/quick/items/qquickitemanimation.cpp
@@ -230,8 +230,8 @@ QAbstractAnimationJob* QQuickParentAnimation::transition(QQuickStateActions &act
 {
     Q_D(QQuickParentAnimation);
 
-    QQuickParentAnimationData *data = new QQuickParentAnimationData;
-    QQuickParentAnimationData *viaData = new QQuickParentAnimationData;
+    std::unique_ptr<QQuickParentAnimationData> data(new QQuickParentAnimationData);
+    std::unique_ptr<QQuickParentAnimationData> viaData(new QQuickParentAnimationData);
 
     bool hasExplicit = false;
     if (d->target && d->newParent) {
@@ -377,8 +377,8 @@ QAbstractAnimationJob* QQuickParentAnimation::transition(QQuickStateActions &act
         QParallelAnimationGroupJob *ag = new QParallelAnimationGroupJob;
 
         if (d->via)
-            viaAction->setAnimAction(viaData);
-        targetAction->setAnimAction(data);
+            viaAction->setAnimAction(viaData.release());
+        targetAction->setAnimAction(data.release());
 
         //take care of any child animations
         bool valid = d->defaultProperty.isValid();
@@ -405,9 +405,6 @@ QAbstractAnimationJob* QQuickParentAnimation::transition(QQuickStateActions &act
             topLevelGroup->appendAnimation(d->via ? viaAction : targetAction);
         }
         return initInstance(topLevelGroup);
-    } else {
-        delete data;
-        delete viaData;
     }
     return nullptr;
 }
-- 
2.33.0

From fe8c06d78a1b2f261806797c6f15f313cc3fc490 Mon Sep 17 00:00:00 2001
From: Maximilian Goldstein <max.goldstein@qt.io>
Date: Tue, 23 Feb 2021 16:10:44 +0100
Subject: [PATCH 38/41] qqmldelegatemodel: Fix out of bounds cache removal

Pick-to: 5.15 6.0 6.1
Task-number: QTBUG-91276
Change-Id: I1ddbb4a3326d61ff94e3881beb64a14dade11c46
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit 31ad81d81e623a34cd71567b9507f16601f1c1d4)
---
 src/qmlmodels/qqmldelegatemodel.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp
index 8ce3da1cf1..8a74a854f4 100644
--- a/src/qmlmodels/qqmldelegatemodel.cpp
+++ b/src/qmlmodels/qqmldelegatemodel.cpp
@@ -1621,7 +1621,7 @@ void QQmlDelegateModelPrivate::itemsRemoved(
         removed[i] = 0;
 
     for (const Compositor::Remove &remove : removes) {
-        for (; cacheIndex < remove.cacheIndex; ++cacheIndex)
+        for (; cacheIndex < remove.cacheIndex && cacheIndex < m_cache.size(); ++cacheIndex)
             incrementIndexes(m_cache.at(cacheIndex), m_groupCount, removed);
 
         for (int i = 1; i < m_groupCount; ++i) {
-- 
2.33.0

From d7ede3462d7e12e4fa60a6efa1b83e2157be4b00 Mon Sep 17 00:00:00 2001
From: Andreas Hartmetz <andreas@ixgreen.de>
Date: Fri, 5 Mar 2021 12:41:06 +0100
Subject: [PATCH 39/41] QQuickWindow: don't leak old screenChanged connections

Connections could accumulate. Because the newest one was invoked
last due to how signal-slot invocations are ordered, rendering
was correct, but the stale connections caused unnecessary updates
(and wasted a small amount of memory).
This comes from a misunderstanding I had at the time about how
QMetaObject::Connection works. Destroying or overwriting one does
not affect the actual connection.

While at it, also modernize the connect().

Pick-to: 5.15 6.0 6.1
Change-Id: Idde81bdbff8947ed517bf2740d623a395c0acb74
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
(cherry picked from commit 9f8292d48913c5bc50377749c2b3e030cf16d703)
---
 src/quick/items/qquickwindow.cpp | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 9ff91eb9a0..fbb807ca96 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -450,15 +450,14 @@ void QQuickWindow::physicalDpiChanged()
 void QQuickWindow::handleScreenChanged(QScreen *screen)
 {
     Q_D(QQuickWindow);
+    disconnect(d->physicalDpiChangedConnection);
     if (screen) {
         physicalDpiChanged();
         // When physical DPI changes on the same screen, either the resolution or the device pixel
         // ratio changed. We must check what it is. Device pixel ratio does not have its own
         // ...Changed() signal.
-        d->physicalDpiChangedConnection = connect(screen, SIGNAL(physicalDotsPerInchChanged(qreal)),
-                                                  this, SLOT(physicalDpiChanged()));
-    } else {
-        disconnect(d->physicalDpiChangedConnection);
+        d->physicalDpiChangedConnection = connect(screen, &QScreen::physicalDotsPerInchChanged,
+                                                  this, &QQuickWindow::physicalDpiChanged);
     }
 
     d->forcePolish();
-- 
2.33.0

From 36e8ccd434f948e4f11a8f9d59139ec072e41ff5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Arve=20S=C3=A6ther?= <jan-arve.saether@qt.io>
Date: Thu, 3 Sep 2020 10:51:01 +0200
Subject: [PATCH 40/41] Fix TapHandler so that it actually registers a tap

This bug caused all quick examples that used the
shared\LauncherList.qml to be broken.

In QtGui, QSinglePointEvent will construct itself with a point id of 0
if there is a valid point, and with a point id of -1 if the point is
invalid (the default constructor does the latter).
However, QQuickSinglePointHandler::wantsPointerEvent() did not agree
with that, because it assumed that a point id of 0 meant
uninitialized/invalid point.
The fix is to change QQuickSinglePointHandler::wantsPointerEvent() and
QQuickHandlerPoint so that it assumes that the id -1 is now an invalid
point, (instead of 0)

Change-Id: I8c9683dfe06ebb77c5342a26f08174b67e7cbd90
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
(cherry picked from commit 8d3a91016506fd0afedb0be535f7c34a4ca762f6)
---
 src/quick/handlers/qquickhandlerpoint.cpp       | 4 ++--
 src/quick/handlers/qquicksinglepointhandler.cpp | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/quick/handlers/qquickhandlerpoint.cpp b/src/quick/handlers/qquickhandlerpoint.cpp
index 72efdfd0f4..6aef3545dd 100644
--- a/src/quick/handlers/qquickhandlerpoint.cpp
+++ b/src/quick/handlers/qquickhandlerpoint.cpp
@@ -82,7 +82,7 @@ void QQuickHandlerPoint::localize(QQuickItem *item)
 
 void QQuickHandlerPoint::reset()
 {
-    m_id = 0;
+    m_id = -1;
     m_uniqueId = QPointingDeviceUniqueId();
     m_position = QPointF();
     m_scenePosition = QPointF();
@@ -165,7 +165,7 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points)
         pressureSum += point.pressure();
         ellipseDiameterSum += point.ellipseDiameters();
     }
-    m_id = 0;
+    m_id = -1;
     m_uniqueId = QPointingDeviceUniqueId();
     // all points are required to be from the same event, so pressed buttons and modifiers should be the same
     m_pressedButtons = points.first().pressedButtons();
diff --git a/src/quick/handlers/qquicksinglepointhandler.cpp b/src/quick/handlers/qquicksinglepointhandler.cpp
index b51f53b74f..89081b4e84 100644
--- a/src/quick/handlers/qquicksinglepointhandler.cpp
+++ b/src/quick/handlers/qquicksinglepointhandler.cpp
@@ -75,7 +75,7 @@ bool QQuickSinglePointHandler::wantsPointerEvent(QQuickPointerEvent *event)
     if (!QQuickPointerDeviceHandler::wantsPointerEvent(event))
         return false;
 
-    if (d->pointInfo.id()) {
+    if (d->pointInfo.id() != -1) {
         // We already know which one we want, so check whether it's there.
         // It's expected to be an update or a release.
         // If we no longer want it, cancel the grab.
@@ -125,7 +125,7 @@ bool QQuickSinglePointHandler::wantsPointerEvent(QQuickPointerEvent *event)
             chosen->setAccepted();
         }
     }
-    return d->pointInfo.id();
+    return d->pointInfo.id() != -1;
 }
 
 void QQuickSinglePointHandler::handlePointerEventImpl(QQuickPointerEvent *event)
-- 
2.33.0

From 7024ac8358f9e576dff013ce2452c1daa0d34506 Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <aacid@kde.org>
Date: Tue, 16 Nov 2021 22:43:37 +0100
Subject: [PATCH 41/41] Revert "Fix TapHandler so that it actually registers a
 tap"

This reverts commit 36e8ccd434f948e4f11a8f9d59139ec072e41ff5.

It's causing regresions
---
 src/quick/handlers/qquickhandlerpoint.cpp       | 4 ++--
 src/quick/handlers/qquicksinglepointhandler.cpp | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/quick/handlers/qquickhandlerpoint.cpp b/src/quick/handlers/qquickhandlerpoint.cpp
index 6aef3545dd..72efdfd0f4 100644
--- a/src/quick/handlers/qquickhandlerpoint.cpp
+++ b/src/quick/handlers/qquickhandlerpoint.cpp
@@ -82,7 +82,7 @@ void QQuickHandlerPoint::localize(QQuickItem *item)
 
 void QQuickHandlerPoint::reset()
 {
-    m_id = -1;
+    m_id = 0;
     m_uniqueId = QPointingDeviceUniqueId();
     m_position = QPointF();
     m_scenePosition = QPointF();
@@ -165,7 +165,7 @@ void QQuickHandlerPoint::reset(const QVector<QQuickHandlerPoint> &points)
         pressureSum += point.pressure();
         ellipseDiameterSum += point.ellipseDiameters();
     }
-    m_id = -1;
+    m_id = 0;
     m_uniqueId = QPointingDeviceUniqueId();
     // all points are required to be from the same event, so pressed buttons and modifiers should be the same
     m_pressedButtons = points.first().pressedButtons();
diff --git a/src/quick/handlers/qquicksinglepointhandler.cpp b/src/quick/handlers/qquicksinglepointhandler.cpp
index 89081b4e84..b51f53b74f 100644
--- a/src/quick/handlers/qquicksinglepointhandler.cpp
+++ b/src/quick/handlers/qquicksinglepointhandler.cpp
@@ -75,7 +75,7 @@ bool QQuickSinglePointHandler::wantsPointerEvent(QQuickPointerEvent *event)
     if (!QQuickPointerDeviceHandler::wantsPointerEvent(event))
         return false;
 
-    if (d->pointInfo.id() != -1) {
+    if (d->pointInfo.id()) {
         // We already know which one we want, so check whether it's there.
         // It's expected to be an update or a release.
         // If we no longer want it, cancel the grab.
@@ -125,7 +125,7 @@ bool QQuickSinglePointHandler::wantsPointerEvent(QQuickPointerEvent *event)
             chosen->setAccepted();
         }
     }
-    return d->pointInfo.id() != -1;
+    return d->pointInfo.id();
 }
 
 void QQuickSinglePointHandler::handlePointerEventImpl(QQuickPointerEvent *event)
-- 
2.33.0

From 8aa1164f1bb6a5dfb5527bcfbf128ab6f2c73ed4 Mon Sep 17 00:00:00 2001
From: Joni Poikelin <joni.poikelin@qt.io>
Date: Mon, 14 Dec 2020 09:18:58 +0200
Subject: [PATCH 42/43] Fix crash during model reset

Commit 37fcffa035d55ac00f85f57ce1390fff3be213c6 fixed the issue for
remove rows, but it can also happen with model reset.

Fixes: QTBUG-83352
Pick-to: 6.0 5.15
Change-Id: I0ec1a67e822e4f8fe5b8f87f38dfae1f26b3fab5
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit d99d192884608408759492bd656ab99a2f4f23ed)
---
 src/qmlmodels/qqmldelegatemodel.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp
index 8a74a854f4..53e511303e 100644
--- a/src/qmlmodels/qqmldelegatemodel.cpp
+++ b/src/qmlmodels/qqmldelegatemodel.cpp
@@ -1887,6 +1887,9 @@ void QQmlDelegateModel::_q_modelReset()
         d->m_count = d->adaptorModelCount();
 
         const QList<QQmlDelegateModelItem *> cache = d->m_cache;
+        for (QQmlDelegateModelItem *item : cache)
+            item->referenceObject();
+
         for (int i = 0, c = cache.count();  i < c; ++i) {
             QQmlDelegateModelItem *item = cache.at(i);
             // layout change triggered by changing the modelIndex might have
@@ -1898,6 +1901,8 @@ void QQmlDelegateModel::_q_modelReset()
                 item->setModelIndex(-1, -1, -1);
         }
 
+        for (QQmlDelegateModelItem *item : cache)
+            item->releaseObject();
         QVector<Compositor::Remove> removes;
         QVector<Compositor::Insert> inserts;
         if (oldCount)
-- 
2.33.0

From c691908c54ed7815f513f8511005dbf1f13ad40d Mon Sep 17 00:00:00 2001
From: Marc Mutz <marc.mutz@qt.io>
Date: Tue, 21 Dec 2021 09:20:17 +0100
Subject: [PATCH 43/43] QQmlJs::FixedPoolArray: fix UB (precondition violation)
 in allocate()

Says ubsan:

  qqmljsfixedpoolarray_p.h:90:19: runtime error: null pointer passed as argument 2, which is declared to never be null

Fix, like in so many other places, by a size check.

Pick-to: 6.3 6.2 5.15
Change-Id: I9181d6ecb467c2dc726978ce7f93b35a6bf2f944
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
(cherry picked from commit d74e931f3fc2587ac6d1e2930acbbe54ea5be2b5)
---
 src/qml/common/qqmljsfixedpoolarray_p.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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));
         }
     }
-- 
2.33.0

