summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIonen Wolkens <ionen@gentoo.org>2024-11-15 02:45:10 -0500
committerIonen Wolkens <ionen@gentoo.org>2024-11-15 03:02:45 -0500
commit07424846a2e87d58e386a16f3d3d279ed5ed7385 (patch)
tree21a8ac0807b30c1b73b36c4d76ae38c435a003bf /dev-qt/qtdeclarative/files
parentsci-libs/caffe2: drop cpu_flags from USE (diff)
downloadgentoo-07424846a2e87d58e386a16f3d3d279ed5ed7385.tar.gz
gentoo-07424846a2e87d58e386a16f3d3d279ed5ed7385.tar.bz2
gentoo-07424846a2e87d58e386a16f3d3d279ed5ed7385.zip
dev-qt/qtdeclarative: fix 6.8.0's QTBUG-125053 patch
The version for 6.7.3 seems correct but sharing it with 6.8.0 was not, thankfully 6.8.0 is masked so this didn't affect many people. Closes: https://bugs.gentoo.org/943527 Signed-off-by: Ionen Wolkens <ionen@gentoo.org>
Diffstat (limited to 'dev-qt/qtdeclarative/files')
-rw-r--r--dev-qt/qtdeclarative/files/qtdeclarative-6.8.0-QTBUG-125053.patch258
1 files changed, 258 insertions, 0 deletions
diff --git a/dev-qt/qtdeclarative/files/qtdeclarative-6.8.0-QTBUG-125053.patch b/dev-qt/qtdeclarative/files/qtdeclarative-6.8.0-QTBUG-125053.patch
new file mode 100644
index 000000000000..250a33f7b166
--- /dev/null
+++ b/dev-qt/qtdeclarative/files/qtdeclarative-6.8.0-QTBUG-125053.patch
@@ -0,0 +1,258 @@
+https://bugreports.qt.io/browse/QTBUG-125053
+https://bugreports.qt.io/browse/QTBUG-127340
+https://codereview.qt-project.org/c/qt/qtdeclarative/+/593122
+https://bugs.gentoo.org/943527 (see also)
+--- a/src/qmlmodels/qqmldelegatemodel.cpp
++++ b/src/qmlmodels/qqmldelegatemodel.cpp
+@@ -4,4 +4,6 @@
+ #include "qqmldelegatemodel_p_p.h"
+
++#include <QtCore/private/qabstractitemmodel_p.h>
++
+ #include <QtQml/qqmlinfo.h>
+
+@@ -172,5 +174,4 @@
+ , m_incubatorCleanupScheduled(false)
+ , m_waitingToFetchMore(false)
+- , m_maybeResetRoleNames(false)
+ , m_cacheItems(nullptr)
+ , m_items(nullptr)
+@@ -366,5 +367,4 @@
+ QObject::connect(aim, &QAbstractItemModel::rowsMoved, q, &QQmlDelegateModel::_q_rowsMoved);
+ QObject::connect(aim, &QAbstractItemModel::modelAboutToBeReset, q, &QQmlDelegateModel::_q_modelAboutToBeReset);
+- QObject::connect(aim, &QAbstractItemModel::modelReset, q, &QQmlDelegateModel::handleModelReset);
+ QObject::connect(aim, &QAbstractItemModel::layoutChanged, q, &QQmlDelegateModel::_q_layoutChanged);
+ }
+@@ -387,5 +387,4 @@
+ QObject::disconnect(aim, &QAbstractItemModel::rowsMoved, q, &QQmlDelegateModel::_q_rowsMoved);
+ QObject::disconnect(aim, &QAbstractItemModel::modelAboutToBeReset, q, &QQmlDelegateModel::_q_modelAboutToBeReset);
+- QObject::disconnect(aim, &QAbstractItemModel::modelReset, q, &QQmlDelegateModel::handleModelReset);
+ QObject::disconnect(aim, &QAbstractItemModel::layoutChanged, q, &QQmlDelegateModel::_q_layoutChanged);
+ }
+@@ -412,4 +411,19 @@
+ d->requestMoreIfNecessary();
+ }
++
++ // Since 837c2f18cd223707e7cedb213257b0158ea07146, we connect to modelAboutToBeReset
++ // rather than modelReset so that we can handle role name changes. _q_modelAboutToBeReset
++ // now connects modelReset to handleModelReset with a single shot connection instead.
++ // However, it's possible for user code to begin the reset before connectToAbstractItemModel is called
++ // (QTBUG-125053), in which case we connect to modelReset too late and handleModelReset is never called,
++ // resulting in delegates not being created in certain cases.
++ // So, we check at the earliest point we can if the model is in the process of being reset,
++ // and if so, connect modelReset to handleModelReset.
++ if (d->m_adaptorModel.adaptsAim()) {
++ auto *aim = d->m_adaptorModel.aim();
++ auto *aimPrivate = QAbstractItemModelPrivate::get(aim);
++ if (aimPrivate->resetting)
++ QObject::connect(aim, &QAbstractItemModel::modelReset, this, &QQmlDelegateModel::handleModelReset, Qt::SingleShotConnection);
++ }
+ }
+
+@@ -1898,26 +1912,23 @@
+ if (!d->m_adaptorModel.adaptsAim())
+ return;
+-
+- /*
+- roleNames are generally guaranteed to be stable (given that QAIM has no
+- change signal for them), except that resetting the model is allowed to
+- invalidate them (QTBUG-32132). DelegateModel must take this into account by
+- snapshotting the current roleNames before the model is reset.
+- Afterwards, if we detect that roleNames has changed, we throw the
+- current model set up away and rebuild everything from scratch – it is
+- unlikely that a more efficient implementation would be worth it.
+-
+- If we detect no changes, we simply use the existing logic to handle the
+- model reset.
+-
+- This (role name resetting) logic relies on the fact that
+- modelAboutToBeReset must be followed by a modelReset signal before any
+- further modelAboutToBeReset can occur. However, it's possible for user
+- code to begin the reset before connectToAbstractItemModel is called
+- (QTBUG-125053), in which case we don't attempt to reset the role names.
+- */
+- Q_ASSERT(!d->m_maybeResetRoleNames);
+- d->m_maybeResetRoleNames = true;
+- d->m_roleNamesBeforeReset = d->m_adaptorModel.aim()->roleNames();
++ auto aim = d->m_adaptorModel.aim();
++ auto oldRoleNames = aim->roleNames();
++ // this relies on the fact that modelAboutToBeReset must be followed
++ // by a modelReset signal before any further modelAboutToBeReset can occur
++ QObject::connect(aim, &QAbstractItemModel::modelReset, this, [this, d, oldRoleNames, aim](){
++ if (!d->m_adaptorModel.adaptsAim() || d->m_adaptorModel.aim() != aim)
++ return;
++ if (oldRoleNames == aim->roleNames()) {
++ // if the rolenames stayed the same (most common case), then we don't have
++ // to throw away all the setup that we did
++ handleModelReset();
++ } else {
++ // If they did change, we give up and just start from scratch via setMode
++ setModel(QVariant::fromValue(model()));
++ // but we still have to call handleModelReset, otherwise views will
++ // not refresh
++ handleModelReset();
++ }
++ }, Qt::SingleShotConnection);
+ }
+
+@@ -1929,21 +1940,4 @@
+
+ int oldCount = d->m_count;
+-
+- if (d->m_maybeResetRoleNames) {
+- auto aim = d->m_adaptorModel.aim();
+- if (!d->m_adaptorModel.adaptsAim() || d->m_adaptorModel.aim() != aim)
+- return;
+-
+- // If the role names stayed the same (most common case), then we don't have
+- // to throw away all the setup that we did.
+- // If they did change, we give up and just start from scratch via setModel.
+- // We do this before handling the reset to ensure that views refresh.
+- if (aim->roleNames() != d->m_roleNamesBeforeReset)
+- setModel(QVariant::fromValue(model()));
+-
+- d->m_maybeResetRoleNames = false;
+- d->m_roleNamesBeforeReset.clear();
+- }
+-
+ d->m_adaptorModel.rootIndex = QModelIndex();
+
+--- a/src/qmlmodels/qqmldelegatemodel_p_p.h
++++ b/src/qmlmodels/qqmldelegatemodel_p_p.h
+@@ -335,5 +335,4 @@
+ QList<QQDMIncubationTask *> m_finishedIncubating;
+ QList<QByteArray> m_watchedRoles;
+- QHash<int, QByteArray> m_roleNamesBeforeReset;
+
+ QString m_filterGroup;
+@@ -349,5 +348,4 @@
+ bool m_incubatorCleanupScheduled : 1;
+ bool m_waitingToFetchMore : 1;
+- bool m_maybeResetRoleNames : 1;
+
+ union {
+--- a/tests/auto/qml/qqmldelegatemodel/data/proxyModelWithDelayedSourceModelInListView.qml
++++ b/tests/auto/qml/qqmldelegatemodel/data/proxyModelWithDelayedSourceModelInListView.qml
+@@ -0,0 +1,30 @@
++import QtQuick
++import Test
++
++Window {
++ id: root
++ title: listView.count
++
++ property alias listView: listView
++ property ProxySourceModel connectionModel: null
++
++ Component {
++ id: modelComponent
++ ProxySourceModel {}
++ }
++
++ ListView {
++ id: listView
++ anchors.fill: parent
++
++ delegate: Text {
++ text: model.Name
++ }
++
++ model: ProxyModel {
++ sourceModel: root.connectionModel
++ }
++ }
++
++ Component.onCompleted: root.connectionModel = modelComponent.createObject(root)
++}
+--- a/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
++++ b/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
+@@ -4,4 +4,5 @@
+ #include <QtTest/qtest.h>
+ #include <QtCore/qjsonobject.h>
++#include <QtCore/qsortfilterproxymodel.h>
+ #include <QtCore/QConcatenateTablesProxyModel>
+ #include <QtCore/qtimer.h>
+@@ -52,4 +53,5 @@
+ void clearCacheDuringInsertion();
+ void viewUpdatedOnDelegateChoiceAffectingRoleChange();
++ void proxyModelWithDelayedSourceModelInListView();
+ };
+
+@@ -732,4 +734,77 @@
+ }
+
++class ProxySourceModel : public QAbstractListModel
++{
++ Q_OBJECT
++ QML_ELEMENT
++public:
++ explicit ProxySourceModel(QObject *parent = nullptr)
++ : QAbstractListModel(parent)
++ {
++ for (int i = 0; i < rows; ++i) {
++ beginInsertRows(QModelIndex(), i, i);
++ endInsertRows();
++ }
++ }
++
++ ~ProxySourceModel() override = default;
++
++ int rowCount(const QModelIndex &) const override
++ {
++ return rows;
++ }
++
++ QVariant data(const QModelIndex &, int ) const override
++ {
++ return "Hello";
++ }
++
++ QHash<int, QByteArray> roleNames() const override
++ {
++ QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
++ roles[Qt::UserRole + 1] = "Name";
++
++ return roles;
++ }
++
++ static const int rows = 1;
++};
++
++class ProxyModel : public QSortFilterProxyModel
++{
++ Q_OBJECT
++ QML_ELEMENT
++ Q_PROPERTY(QAbstractItemModel *sourceModel READ sourceModel WRITE setSourceModel)
++
++public:
++ explicit ProxyModel(QObject *parent = nullptr)
++ : QSortFilterProxyModel(parent)
++ {
++ }
++
++ ~ProxyModel() override = default;
++};
++
++// Checks that the correct amount of delegates are created when using a proxy
++// model whose source model is set after a delay.
++void tst_QQmlDelegateModel::proxyModelWithDelayedSourceModelInListView()
++{
++ QTest::failOnWarning();
++
++ qmlRegisterTypesAndRevisions<ProxySourceModel>("Test", 1);
++ qmlRegisterTypesAndRevisions<ProxyModel>("Test", 1);
++
++ QQuickApplicationHelper helper(this, "proxyModelWithDelayedSourceModelInListView.qml");
++ QVERIFY2(helper.ready, helper.failureMessage());
++ QQuickWindow *window = helper.window;
++ window->show();
++ QVERIFY(QTest::qWaitForWindowExposed(window));
++
++ auto *listView = window->property("listView").value<QQuickListView *>();
++ QVERIFY(listView);
++ const auto delegateModel = QQuickItemViewPrivate::get(listView)->model;
++ QTRY_COMPARE(listView->count(), 1);
++}
++
+ QTEST_MAIN(tst_QQmlDelegateModel)
+