aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qml/jsruntime/qv4engine.cpp6
-rw-r--r--src/qmlmodels/qqmltableinstancemodel.cpp19
-rw-r--r--src/qmlmodels/qqmltableinstancemodel_p.h1
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp5
-rw-r--r--src/quick/items/qquickitem.cpp8
-rw-r--r--src/quick/items/qquicktableview.cpp11
6 files changed, 45 insertions, 5 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 76fefb767d..df2c46b64a 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -1516,7 +1516,11 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
return retn;
#endif
if (typeHint != -1) {
- retn = QVariant(typeHint, QMetaType::create(typeHint));
+ // the QVariant constructor will create a copy, so we have manually
+ // destroy the value returned by QMetaType::create
+ auto temp = QMetaType::create(typeHint);
+ retn = QVariant(typeHint, temp);
+ QMetaType::destroy(typeHint, temp);
auto retnAsIterable = retn.value<QtMetaTypePrivate::QSequentialIterableImpl>();
if (retnAsIterable._iteratorCapabilities & QtMetaTypePrivate::ContainerIsAppendable) {
auto const length = a->getLength();
diff --git a/src/qmlmodels/qqmltableinstancemodel.cpp b/src/qmlmodels/qqmltableinstancemodel.cpp
index 9800eb8c72..e2cecfef79 100644
--- a/src/qmlmodels/qqmltableinstancemodel.cpp
+++ b/src/qmlmodels/qqmltableinstancemodel.cpp
@@ -240,6 +240,25 @@ QQmlInstanceModel::ReleaseFlags QQmlTableInstanceModel::release(QObject *object,
return QQmlInstanceModel::Destroyed;
}
+void QQmlTableInstanceModel::dispose(QObject *object)
+{
+ Q_ASSERT(object);
+ auto modelItem = qvariant_cast<QQmlDelegateModelItem *>(object->property(kModelItemTag));
+ Q_ASSERT(modelItem);
+
+ modelItem->releaseObject();
+
+ // The item is not referenced by anyone
+ Q_ASSERT(!modelItem->isObjectReferenced());
+ Q_ASSERT(!modelItem->isReferenced());
+
+ m_modelItems.remove(modelItem->index);
+
+ emit destroyingItem(object);
+ delete object;
+ delete modelItem;
+}
+
void QQmlTableInstanceModel::cancel(int index)
{
auto modelItem = m_modelItems.value(index);
diff --git a/src/qmlmodels/qqmltableinstancemodel_p.h b/src/qmlmodels/qqmltableinstancemodel_p.h
index fd5968d872..4ea1d85d16 100644
--- a/src/qmlmodels/qqmltableinstancemodel_p.h
+++ b/src/qmlmodels/qqmltableinstancemodel_p.h
@@ -117,6 +117,7 @@ public:
QObject *object(int index, QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested) override;
ReleaseFlags release(QObject *object) override { return release(object, NotReusable); }
ReleaseFlags release(QObject *object, ReusableFlag reusable);
+ void dispose(QObject *object);
void cancel(int) override;
void insertIntoReusableItemsPool(QQmlDelegateModelItem *modelItem);
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index 54cda72a36..14fa07099f 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -986,10 +986,11 @@ static QV4::ReturnedValue qt_create_image_data(qreal w, qreal h, QV4::ExecutionE
pixelData->setPrototypeOf(p);
if (image.isNull()) {
- *pixelData->d()->image = QImage(w, h, QImage::Format_ARGB32);
+ *pixelData->d()->image = QImage(qRound(w), qRound(h), QImage::Format_ARGB32);
pixelData->d()->image->fill(0x00000000);
} else {
- Q_ASSERT(image.width()== qRound(w * image.devicePixelRatioF()) && image.height() == qRound(h * image.devicePixelRatioF()));
+ // After qtbase 88e56d0932a3615231adf40d5ae033e742d72c33, the image size can be off by one.
+ Q_ASSERT(qAbs(image.width() - qRound(w * image.devicePixelRatioF())) <= 1 && qAbs(image.height() - qRound(h * image.devicePixelRatioF())) <= 1);
*pixelData->d()->image = image.format() == QImage::Format_ARGB32 ? image : image.convertToFormat(QImage::Format_ARGB32);
}
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 3785abc450..11c1f12e75 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -2568,6 +2568,7 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
bool skip = false;
QQuickItem *startItem = item;
+ QQuickItem *originalStartItem = startItem;
// Protect from endless loop:
// If we start on an invisible item we will not find it again.
// If there is no other item which can become the focus item, we have a forever loop,
@@ -2643,7 +2644,12 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
}
}
from = last;
- if (current == startItem && from == firstFromItem) {
+ // if [from] item is equal to [firstFromItem], means we have traversed one path and
+ // jump back to parent of the chain, and then we have to check whether we have
+ // traversed all of the chain (by compare the [current] item with [startItem])
+ // Since the [startItem] might be promoted to its parent if it is invisible,
+ // we still have to check [current] item with original start item
+ if ((current == startItem || current == originalStartItem) && from == firstFromItem) {
// wrapped around, avoid endless loops
if (item == contentItem) {
qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return contentItem";
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp
index 4b34e3b2c1..4105996b31 100644
--- a/src/quick/items/qquicktableview.cpp
+++ b/src/quick/items/qquicktableview.cpp
@@ -441,7 +441,16 @@ QQuickTableViewPrivate::QQuickTableViewPrivate()
QQuickTableViewPrivate::~QQuickTableViewPrivate()
{
- releaseLoadedItems(QQmlTableInstanceModel::NotReusable);
+ for (auto *fxTableItem : loadedItems) {
+ if (auto item = fxTableItem->item) {
+ if (fxTableItem->ownItem)
+ delete item;
+ else if (tableModel)
+ tableModel->dispose(item);
+ }
+ delete fxTableItem;
+ }
+
if (tableModel)
delete tableModel;
}