Compare commits

...

10 Commits

Author SHA1 Message Date
openeuler-ci-bot
66743a3316
!20 [sync] PR-19: update to version 5.15.10-1
From: @openeuler-sync-bot 
Reviewed-by: @peijiankang 
Signed-off-by: @peijiankang
2023-08-30 09:03:24 +00:00
huayadong
0eaee0887c update to version 5.15.10-1
(cherry picked from commit 7470737daf88b77b41bdabc178519bc4ba7a27f1)
2023-08-24 19:20:19 +08:00
openeuler-ci-bot
2204a7588b
!16 modify changlog error
From: @peijiankang 
Reviewed-by: @licihua 
Signed-off-by: @licihua
2022-06-14 11:15:43 +00:00
peijiankang
c62415eebb modify changlog error 2022-06-08 14:19:18 +08:00
openeuler-ci-bot
4fae4e8527
!14 rm qt5-qtdeclarative-5.15.2-7.eln112.src.rpm
Merge pull request !14 from pei-jiankang/master
2022-01-11 06:27:11 +00:00
pei-jiankang
a8e40edc31 rm qt5-qtdeclarative-5.15.2-7.eln112.src.rpm 2022-01-07 16:58:15 +08:00
openeuler-ci-bot
4a304b43cb
!13 update to upstream version 5.15.2
Merge pull request !13 from pei-jiankang/master
2022-01-07 03:04:44 +00:00
pei-jiankang
ad1efaf16a update to upstream version 5.15.2 2022-01-05 09:15:17 +08:00
openeuler-ci-bot
369deb5ea6 !12 drop python2 subpackage
From: @wangxiao65
Reviewed-by: @small_leek
Signed-off-by: @small_leek
2020-10-30 10:18:45 +08:00
wangxiao65
617d5fa17e drop python2 subpackage 2020-10-29 11:59:04 +08:00
33 changed files with 2913 additions and 94 deletions

View File

@ -0,0 +1,35 @@
From 7a8bd4c2b3213919343359d5933914ffe1d535e0 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 01/26] 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.40.1

View File

@ -0,0 +1,178 @@
From 28c1d895c5220d7f5c49d18ae839feaac0f6e69f Mon Sep 17 00:00:00 2001
From: Aleix Pol <aleixpol@kde.org>
Date: Thu, 23 Sep 2021 03:43:04 +0200
Subject: [PATCH 02/26] 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 +++++
.../tst_qqmldelegatemodel.cpp | 27 ++++++++++++
4 files changed, 85 insertions(+)
create mode 100644 tests/auto/qml/qqmldelegatemodel/data/redrawUponColumnChange.qml
diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp
index 4fcff70de6..4157899aa6 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)),
@@ -1974,6 +1986,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/tst_qqmldelegatemodel.cpp b/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
index 35f1e2c94d..1722447830 100644
--- a/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
+++ b/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
@@ -27,6 +27,8 @@
****************************************************************************/
#include <QtTest/qtest.h>
+#include <QtCore/QConcatenateTablesProxyModel>
+#include <QtGui/QStandardItemModel>
#include <QtQml/qqmlcomponent.h>
#include <QtQmlModels/private/qqmldelegatemodel_p.h>
#include <QtQuick/qquickview.h>
@@ -47,6 +49,7 @@ private slots:
void filterOnGroup_removeWhenCompleted();
void qtbug_86017();
void contextAccessedByHandler();
+ void redrawUponColumnChange();
};
class AbstractItemModel : public QAbstractItemModel
@@ -186,6 +189,30 @@ void tst_QQmlDelegateModel::contextAccessedByHandler()
QVERIFY(root->property("works").toBool());
}
+void tst_QQmlDelegateModel::redrawUponColumnChange()
+{
+ QStandardItemModel m1;
+ m1.appendRow({
+ new QStandardItem("Banana"),
+ new QStandardItem("Coconut"),
+ });
+
+ QQuickView view(testFileUrl("redrawUponColumnChange.qml"));
+ QCOMPARE(view.status(), QQuickView::Ready);
+ view.show();
+ QQuickItem *root = view.rootObject();
+ root->setProperty("model", QVariant::fromValue<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.40.1

View File

@ -0,0 +1,73 @@
From ac46066b113c8c8b93277f717dd2f90207ed0e85 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 03/26] 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 7103206470..02141b9a9e 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 d785d8c0ca..a508de455d 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.40.1

View File

@ -0,0 +1,61 @@
From d6514d71fe897493e76bd5e38bccf9b9159c4880 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 04/26] 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 02141b9a9e..7103206470 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 a508de455d..d785d8c0ca 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.40.1

View File

@ -0,0 +1,84 @@
From b02c8610176e1d1ceb65ac5d832d3a21c5a79d47 Mon Sep 17 00:00:00 2001
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
Date: Sat, 29 Jan 2022 21:59:33 +0200
Subject: [PATCH 05/26] Make sure QQuickWidget and its offscreen window's
screens are always in sync
By default, the offscreen window is placed on the primary screen.
However, if the parent widget argument is passed to the QQuickWidget's
constructor, then QQuickWidget's and the offscreen window's screens can
be different and that can create rendering issues, e.g. blurry text if
the primary screen and QQuickWidget's screen have different scale
factors.
Change-Id: I10c62b5635664f943b11828773f14017f198a770
Reviewed-by: David Edmundson <davidedmundson@kde.org>
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
(cherry picked from commit a2a2734bffa1459639b31fb3f4f83873ba44ab5c)
---
src/quickwidgets/qquickwidget.cpp | 26 +++++++++++---------------
1 file changed, 11 insertions(+), 15 deletions(-)
diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp
index 39780f8de3..223d91f579 100644
--- a/src/quickwidgets/qquickwidget.cpp
+++ b/src/quickwidgets/qquickwidget.cpp
@@ -106,6 +106,7 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
renderControl = new QQuickWidgetRenderControl(q);
offscreenWindow = new QQuickWindow(*new QQuickOffcreenWindowPrivate(),renderControl);
+ offscreenWindow->setScreen(q->screen());
offscreenWindow->setTitle(QString::fromLatin1("Offscreen"));
offscreenWindow->setObjectName(QString::fromLatin1("QQuickOffScreenWindow"));
// Do not call create() on offscreenWindow.
@@ -901,9 +902,7 @@ void QQuickWidgetPrivate::createContext()
context = new QOpenGLContext;
context->setFormat(offscreenWindow->requestedFormat());
- const QWindow *win = q->window()->windowHandle();
- if (win && win->screen())
- context->setScreen(win->screen());
+ context->setScreen(q->screen());
QOpenGLContext *shareContext = qt_gl_global_share_context();
if (!shareContext)
shareContext = QWidgetPrivate::get(q->window())->shareContext();
@@ -1520,19 +1519,16 @@ bool QQuickWidget::event(QEvent *e)
d->handleWindowChange();
break;
- case QEvent::ScreenChangeInternal:
- if (QWindow *window = this->window()->windowHandle()) {
- QScreen *newScreen = window->screen();
-
- if (d->offscreenWindow)
- d->offscreenWindow->setScreen(newScreen);
- if (d->offscreenSurface)
- d->offscreenSurface->setScreen(newScreen);
+ case QEvent::ScreenChangeInternal: {
+ QScreen *newScreen = screen();
+ if (d->offscreenWindow)
+ d->offscreenWindow->setScreen(newScreen);
+ if (d->offscreenSurface)
+ d->offscreenSurface->setScreen(newScreen);
#if QT_CONFIG(opengl)
- if (d->context)
- d->context->setScreen(newScreen);
+ if (d->context)
+ d->context->setScreen(newScreen);
#endif
- }
if (d->useSoftwareRenderer
#if QT_CONFIG(opengl)
@@ -1545,7 +1541,7 @@ bool QQuickWidget::event(QEvent *e)
d->render(true);
}
break;
-
+ }
case QEvent::Show:
case QEvent::Move:
d->updatePosition();
--
2.40.1

View File

@ -0,0 +1,122 @@
From d1d910545103549912d1b51383a5ace872dfb1f8 Mon Sep 17 00:00:00 2001
From: Fabian Kosmale <fabian.kosmale@qt.io>
Date: Wed, 4 May 2022 09:10:54 +0200
Subject: [PATCH 06/26] QQuickItem: Guard against cycles in
nextPrevItemInTabFocusChain
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
nextPrevItemInTabFocusChain already had a check to prevent running into
cycles, it would however only detect if we reached the original item. If
our cycle instead would loop between reachable items without ever
returning to the initial one, as in the diagram below, then we would
never terminate the loop.
/-->other item<---next item
initial-item \ ^
\ |
--->different item
To prevent this from happening, we keep track of all items we've seen so
far. One last complications arises due to the fact that we do visit the
parent twice under some cicrcumstances, but we already have the skip
variable to indicate that case we simply skip the duplicate check if
it is set to true.
Pick-to: 6.2 6.3
Fixes: QTBUG-87190
Change-Id: I1449a7ebf8f325f00c296e8a8db4360faf1049e4
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit e74bcf751495d9fe27efd195bc04e2a6ae6732a4)
---
src/quick/items/qquickitem.cpp | 7 ++++++-
.../data/activeFocusOnTab_infiniteLoop3.qml | 13 +++++++++++++
tests/auto/quick/qquickitem2/tst_qquickitem.cpp | 12 ++++++++++++
3 files changed, 31 insertions(+), 1 deletion(-)
create mode 100644 tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 33da9762d3..ec55fb2998 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -59,6 +59,7 @@
#include <QtCore/private/qnumeric_p.h>
#include <QtGui/qpa/qplatformtheme.h>
#include <QtCore/qloggingcategory.h>
+#include <QtCore/private/qduplicatetracker_p.h>
#include <private/qqmlglobal_p.h>
#include <private/qqmlengine_p.h>
@@ -2526,6 +2527,7 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
QQuickItem *current = item;
qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: startItem:" << startItem;
qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: firstFromItem:" << firstFromItem;
+ QDuplicateTracker<QQuickItem *> cycleDetector;
do {
qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: current:" << current;
qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: from:" << from;
@@ -2592,7 +2594,10 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
// traversed all of the chain (by compare the [current] item with [startItem])
// Since the [startItem] might be promoted to its parent if it is invisible,
// we still have to check [current] item with original start item
- if ((current == startItem || current == originalStartItem) && from == firstFromItem) {
+ // We might also run into a cycle before we reach firstFromItem again
+ // but note that we have to ignore current if we are meant to skip it
+ if (((current == startItem || current == originalStartItem) && from == firstFromItem) ||
+ (!skip && cycleDetector.hasSeen(current))) {
// wrapped around, avoid endless loops
if (item == contentItem) {
qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: looped, return contentItem";
diff --git a/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml b/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml
new file mode 100644
index 0000000000..889e480f3b
--- /dev/null
+++ b/tests/auto/quick/qquickitem2/data/activeFocusOnTab_infiniteLoop3.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.6
+
+Item {
+ visible: true
+ Item {
+ visible: false
+ Item {
+ objectName: "hiddenChild"
+ activeFocusOnTab: true
+ focus: true
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
index c8f251dbe1..c8ef36ee68 100644
--- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
@@ -67,6 +67,7 @@ private slots:
void activeFocusOnTab10();
void activeFocusOnTab_infiniteLoop_data();
void activeFocusOnTab_infiniteLoop();
+ void activeFocusOnTab_infiniteLoopControls();
void nextItemInFocusChain();
void nextItemInFocusChain2();
@@ -1057,6 +1058,17 @@ void tst_QQuickItem::activeFocusOnTab_infiniteLoop()
QCOMPARE(item, window->rootObject());
}
+
+void tst_QQuickItem::activeFocusOnTab_infiniteLoopControls()
+{
+ auto source = testFileUrl("activeFocusOnTab_infiniteLoop3.qml");
+ QScopedPointer<QQuickView>window(new QQuickView());
+ window->setSource(source);
+ window->show();
+ QVERIFY(window->errors().isEmpty());
+ QTest::keyClick(window.get(), Qt::Key_Tab); // should not hang
+}
+
void tst_QQuickItem::nextItemInFocusChain()
{
if (!qt_tab_all_widgets())
--
2.40.1

View File

@ -0,0 +1,60 @@
From 70a38e3c897e3ba72b50413d0f994c9f5ebaffd8 Mon Sep 17 00:00:00 2001
From: Fushan Wen <qydwhotmail@gmail.com>
Date: Tue, 1 Nov 2022 22:35:24 +0800
Subject: [PATCH 07/26] Don't convert QByteArray in `startDrag`
QMimeData::setData expects the provided data to contain the correctly
encoded QByteArray, so if the variant contains a QByteArray, then take
it as is to avoid data loss.
If the variant is not already a byte array, then we ideally would make
sure that the mime type (i.e. the key of the map) and the QVariant's
type are compatible (image/png with a QImage works; text/plain with a
QImage does not). This changes behavior and needs to be a follow-up
commit.
Fixes: QTBUG-71922
Change-Id: I9b9f10fd332e1f9568f6835a69a1c359457f823c
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 062f9bf57657b54dc708015ec5fed3c89e5cc3ca)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 22de23c4bb9ac5e2c545e9de3149a7d4f8edd5ee)
---
src/quick/items/qquickdrag.cpp | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/src/quick/items/qquickdrag.cpp b/src/quick/items/qquickdrag.cpp
index 8321fcfeed..3b50370355 100644
--- a/src/quick/items/qquickdrag.cpp
+++ b/src/quick/items/qquickdrag.cpp
@@ -481,7 +481,9 @@ void QQuickDragAttached::setKeys(const QStringList &keys)
\qmlattachedproperty stringlist QtQuick::Drag::mimeData
\since 5.2
- This property holds a map of mimeData that is used during startDrag.
+ This property holds a map from mime type to data that is used during startDrag.
+ The mime data needs to be a \c string, or an \c ArrayBuffer with the data encoded
+ according to the mime type.
*/
QVariantMap QQuickDragAttached::mimeData() const
@@ -766,8 +768,12 @@ Qt::DropAction QQuickDragAttachedPrivate::startDrag(Qt::DropActions supportedAct
QDrag *drag = new QDrag(source ? source : q);
QMimeData *mimeData = new QMimeData();
- for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it)
- mimeData->setData(it.key(), it.value().toString().toUtf8());
+ for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it) {
+ if (it.value().typeId() == QMetaType::QByteArray)
+ mimeData->setData(it.key(), it.value().toByteArray());
+ else
+ mimeData->setData(it.key(), it.value().toString().toUtf8());
+ }
drag->setMimeData(mimeData);
if (pixmapLoader.isReady()) {
--
2.40.1

View File

@ -0,0 +1,26 @@
From 63d011a519c1fee2a0f5dbcc204def9e950a168b Mon Sep 17 00:00:00 2001
From: Hannah von Reth <vonreth@kde.org>
Date: Sat, 5 Nov 2022 18:48:41 +0100
Subject: [PATCH 08/26] Fix build after
95290f66b806a307b8da1f72f8fc2c69801933d0
---
src/quick/items/qquickdrag.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/quick/items/qquickdrag.cpp b/src/quick/items/qquickdrag.cpp
index 3b50370355..383078b3b9 100644
--- a/src/quick/items/qquickdrag.cpp
+++ b/src/quick/items/qquickdrag.cpp
@@ -769,7 +769,7 @@ Qt::DropAction QQuickDragAttachedPrivate::startDrag(Qt::DropActions supportedAct
QMimeData *mimeData = new QMimeData();
for (auto it = externalMimeData.cbegin(), end = externalMimeData.cend(); it != end; ++it) {
- if (it.value().typeId() == QMetaType::QByteArray)
+ if (static_cast<QMetaType::Type>(it.value().type()) == QMetaType::QByteArray)
mimeData->setData(it.key(), it.value().toByteArray());
else
mimeData->setData(it.key(), it.value().toString().toUtf8());
--
2.40.1

View File

@ -0,0 +1,565 @@
From 95f4632430db5668fa022983c76e4f6bde74c33d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= <morten.sorvig@qt.io>
Date: Fri, 7 May 2021 10:07:50 +0200
Subject: [PATCH 09/26] Implement accessibility for QQuickWidget
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The accessibility tree for the Qt Quick content should
be rooted at the QQuickWidget, and not at the offscreen
QQuickWindow.
For this to be the case, several things must happen:
- QQuickWindow must not report the child interfaces
- QQuickWidget must report the child interfaces
- The child interfaces must report the QQuickWidget as the parent
Create accessibility interfaces for QQuickWidget and
and QQuickWigetOffscreenWindow (which now gets a proper
subclass), where the QQuickWidget interface reports
the child interfaces and the QQuickWigetOffscreenWindow
reports no children
Change the code in QAccessibleQuickItem to use the
true (visible) window, where needed.
Fixes: QTBUG-67290
Change-Id: I387d0ef711138d248a8dd16eefc9839499b35eeb
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 41926e08d73ea6c4bbfc87a1dd52d2cdbc435c27)
---
src/quick/accessible/qaccessiblequickitem.cpp | 29 +++--
src/quick/accessible/qaccessiblequickview_p.h | 2 +-
src/quickwidgets/qaccessiblequickwidget.cpp | 110 ++++++++++++++++++
src/quickwidgets/qaccessiblequickwidget.h | 84 +++++++++++++
.../qaccessiblequickwidgetfactory.cpp | 60 ++++++++++
.../qaccessiblequickwidgetfactory_p.h | 66 +++++++++++
src/quickwidgets/qquickwidget.cpp | 18 ++-
src/quickwidgets/qquickwidget_p.h | 8 ++
src/quickwidgets/quickwidgets.pro | 8 +-
9 files changed, 368 insertions(+), 17 deletions(-)
create mode 100644 src/quickwidgets/qaccessiblequickwidget.cpp
create mode 100644 src/quickwidgets/qaccessiblequickwidget.h
create mode 100644 src/quickwidgets/qaccessiblequickwidgetfactory.cpp
create mode 100644 src/quickwidgets/qaccessiblequickwidgetfactory_p.h
diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp
index ae1954ae8d..0692ce634d 100644
--- a/src/quick/accessible/qaccessiblequickitem.cpp
+++ b/src/quick/accessible/qaccessiblequickitem.cpp
@@ -46,6 +46,7 @@
#include "QtQuick/private/qquicktextinput_p.h"
#include "QtQuick/private/qquickaccessibleattached_p.h"
#include "QtQuick/qquicktextdocument.h"
+#include "QtQuick/qquickrendercontrol.h"
QT_BEGIN_NAMESPACE
#if QT_CONFIG(accessibility)
@@ -57,7 +58,19 @@ QAccessibleQuickItem::QAccessibleQuickItem(QQuickItem *item)
QWindow *QAccessibleQuickItem::window() const
{
- return item()->window();
+ QQuickWindow *window = item()->window();
+
+ // For QQuickWidget the above window will be the offscreen QQuickWindow,
+ // which is not a part of the accessibility tree. Detect this case and
+ // return the window for the QQuickWidget instead.
+ if (window && !window->handle()) {
+ if (QQuickRenderControl *renderControl = QQuickWindowPrivate::get(window)->renderControl) {
+ if (QWindow *renderWindow = renderControl->renderWindow(nullptr))
+ return renderWindow;
+ }
+ }
+
+ return window;
}
int QAccessibleQuickItem::childCount() const
@@ -113,19 +126,15 @@ QAccessibleInterface *QAccessibleQuickItem::childAt(int x, int y) const
QAccessibleInterface *QAccessibleQuickItem::parent() const
{
QQuickItem *parent = item()->parentItem();
- QQuickWindow *window = item()->window();
- QQuickItem *ci = window ? window->contentItem() : nullptr;
+ QQuickWindow *itemWindow = item()->window();
+ QQuickItem *ci = itemWindow ? itemWindow->contentItem() : nullptr;
while (parent && !QQuickItemPrivate::get(parent)->isAccessible && parent != ci)
parent = parent->parentItem();
if (parent) {
if (parent == ci) {
- // Jump out to the scene widget if the parent is the root item.
- // There are two root items, QQuickWindow::rootItem and
- // QQuickView::declarativeRoot. The former is the true root item,
- // but is not a part of the accessibility tree. Check if we hit
- // it here and return an interface for the scene instead.
- return QAccessible::queryAccessibleInterface(window);
+ // Jump out to the window if the parent is the root item
+ return QAccessible::queryAccessibleInterface(window());
} else {
while (parent && !parent->d_func()->isAccessible)
parent = parent->parentItem();
@@ -193,7 +202,7 @@ QAccessible::State QAccessibleQuickItem::state() const
QRect viewRect_ = viewRect();
QRect itemRect = rect();
- if (viewRect_.isNull() || itemRect.isNull() || !item()->window() || !item()->window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity()))
+ if (viewRect_.isNull() || itemRect.isNull() || !window() || !window()->isVisible() ||!item()->isVisible() || qFuzzyIsNull(item()->opacity()))
state.invisible = true;
if (!viewRect_.intersects(itemRect))
state.offscreen = true;
diff --git a/src/quick/accessible/qaccessiblequickview_p.h b/src/quick/accessible/qaccessiblequickview_p.h
index 39ffcaf39c..8baa01330c 100644
--- a/src/quick/accessible/qaccessiblequickview_p.h
+++ b/src/quick/accessible/qaccessiblequickview_p.h
@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
#if QT_CONFIG(accessibility)
-class QAccessibleQuickWindow : public QAccessibleObject
+class Q_QUICK_EXPORT QAccessibleQuickWindow : public QAccessibleObject
{
public:
QAccessibleQuickWindow(QQuickWindow *object);
diff --git a/src/quickwidgets/qaccessiblequickwidget.cpp b/src/quickwidgets/qaccessiblequickwidget.cpp
new file mode 100644
index 0000000000..6f04d6693f
--- /dev/null
+++ b/src/quickwidgets/qaccessiblequickwidget.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaccessiblequickwidget.h"
+
+#include "qquickwidget_p.h"
+
+QT_BEGIN_NAMESPACE
+
+#if QT_CONFIG(accessibility)
+
+QAccessibleQuickWidget::QAccessibleQuickWidget(QQuickWidget* widget)
+: QAccessibleWidget(widget)
+, m_accessibleWindow(QQuickWidgetPrivate::get(widget)->offscreenWindow)
+{
+ // NOTE: m_accessibleWindow is a QAccessibleQuickWindow, and not a
+ // QAccessibleQuickWidgetOffscreenWindow (defined below). This means
+ // it will return the Quick item child interfaces, which is what's needed here
+ // (unlike QAccessibleQuickWidgetOffscreenWindow, which will report 0 children).
+}
+
+QAccessibleInterface *QAccessibleQuickWidget::child(int index) const
+{
+ return m_accessibleWindow.child(index);
+}
+
+int QAccessibleQuickWidget::childCount() const
+{
+ return m_accessibleWindow.childCount();
+}
+
+int QAccessibleQuickWidget::indexOfChild(const QAccessibleInterface *iface) const
+{
+ return m_accessibleWindow.indexOfChild(iface);
+}
+
+QAccessibleInterface *QAccessibleQuickWidget::childAt(int x, int y) const
+{
+ return m_accessibleWindow.childAt(x, y);
+}
+
+QAccessibleQuickWidgetOffscreenWindow::QAccessibleQuickWidgetOffscreenWindow(QQuickWindow *window)
+:QAccessibleQuickWindow(window)
+{
+
+}
+
+QAccessibleInterface *QAccessibleQuickWidgetOffscreenWindow::child(int index) const
+{
+ Q_UNUSED(index);
+ return nullptr;
+}
+
+int QAccessibleQuickWidgetOffscreenWindow::childCount() const
+{
+ return 0;
+}
+
+int QAccessibleQuickWidgetOffscreenWindow::indexOfChild(const QAccessibleInterface *iface) const
+{
+ Q_UNUSED(iface);
+ return -1;
+}
+
+QAccessibleInterface *QAccessibleQuickWidgetOffscreenWindow::QAccessibleQuickWidgetOffscreenWindow::childAt(int x, int y) const
+{
+ Q_UNUSED(x);
+ Q_UNUSED(y);
+ return nullptr;
+}
+
+#endif // accessibility
+
+QT_END_NAMESPACE
diff --git a/src/quickwidgets/qaccessiblequickwidget.h b/src/quickwidgets/qaccessiblequickwidget.h
new file mode 100644
index 0000000000..1f52c78c46
--- /dev/null
+++ b/src/quickwidgets/qaccessiblequickwidget.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QACCESSIBLEQUICKWIDGET_H
+#define QACCESSIBLEQUICKWIDGET_H
+
+#include "qquickwidget.h"
+#include <QtWidgets/qaccessiblewidget.h>
+
+#include <private/qaccessiblequickview_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#if QT_CONFIG(accessibility)
+
+// These classes implement the QQuickWiget accessibility switcharoo,
+// where the child items of the QQuickWidgetOffscreenWindow are reported
+// as child accessible interfaces of the QAccessibleQuickWidget.
+class QAccessibleQuickWidget: public QAccessibleWidget
+{
+public:
+ QAccessibleQuickWidget(QQuickWidget* widget);
+
+ QAccessibleInterface *child(int index) const override;
+ int childCount() const override;
+ int indexOfChild(const QAccessibleInterface *iface) const override;
+ QAccessibleInterface *childAt(int x, int y) const override;
+
+private:
+ QAccessibleQuickWindow m_accessibleWindow;
+ Q_DISABLE_COPY(QAccessibleQuickWidget)
+};
+
+class QAccessibleQuickWidgetOffscreenWindow: public QAccessibleQuickWindow
+{
+public:
+ QAccessibleQuickWidgetOffscreenWindow(QQuickWindow *window);
+ QAccessibleInterface *child(int index) const override;
+ int childCount() const override;
+ int indexOfChild(const QAccessibleInterface *iface) const override;
+ QAccessibleInterface *childAt(int x, int y) const override;
+};
+
+#endif // accessibility
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/quickwidgets/qaccessiblequickwidgetfactory.cpp b/src/quickwidgets/qaccessiblequickwidgetfactory.cpp
new file mode 100644
index 0000000000..3756d0c27c
--- /dev/null
+++ b/src/quickwidgets/qaccessiblequickwidgetfactory.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaccessiblequickwidgetfactory_p.h"
+#include "qaccessiblequickwidget.h"
+
+QT_BEGIN_NAMESPACE
+
+#if QT_CONFIG(accessibility)
+
+QAccessibleInterface *qAccessibleQuickWidgetFactory(const QString &classname, QObject *object)
+{
+ if (classname == QLatin1String("QQuickWidget")) {
+ return new QAccessibleQuickWidget(qobject_cast<QQuickWidget *>(object));
+ } else if (classname == QLatin1String("QQuickWidgetOffscreenWindow")) {
+ return new QAccessibleQuickWidgetOffscreenWindow(qobject_cast<QQuickWindow *>(object));
+ }
+ return 0;
+}
+
+#endif // accessibility
+
+QT_END_NAMESPACE
+
diff --git a/src/quickwidgets/qaccessiblequickwidgetfactory_p.h b/src/quickwidgets/qaccessiblequickwidgetfactory_p.h
new file mode 100644
index 0000000000..8c63b09f81
--- /dev/null
+++ b/src/quickwidgets/qaccessiblequickwidgetfactory_p.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qaccessible.h>
+
+#ifndef QACCESSIBLEQUICKWIDGETFACTORY_H
+#define QACCESSIBLEQUICKWIDGETFACTORY_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+#if QT_CONFIG(accessibility)
+
+QAccessibleInterface *qAccessibleQuickWidgetFactory(const QString &classname, QObject *object);
+
+#endif
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp
index 223d91f579..9c97b43518 100644
--- a/src/quickwidgets/qquickwidget.cpp
+++ b/src/quickwidgets/qquickwidget.cpp
@@ -39,6 +39,7 @@
#include "qquickwidget.h"
#include "qquickwidget_p.h"
+#include "qaccessiblequickwidgetfactory_p.h"
#include "private/qquickwindow_p.h"
#include "private/qquickitem_p.h"
@@ -75,9 +76,16 @@
QT_BEGIN_NAMESPACE
+QQuickWidgetOffscreenWindow::QQuickWidgetOffscreenWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control)
+:QQuickWindow(dd, control)
+{
+ setTitle(QString::fromLatin1("Offscreen"));
+ setObjectName(QString::fromLatin1("QQuickOffScreenWindow"));
+}
+
// override setVisble to prevent accidental offscreen window being created
// by base class.
-class QQuickOffcreenWindowPrivate: public QQuickWindowPrivate {
+class QQuickWidgetOffscreenWindowPrivate: public QQuickWindowPrivate {
public:
void setVisible(bool visible) override {
Q_Q(QWindow);
@@ -105,10 +113,8 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
Q_Q(QQuickWidget);
renderControl = new QQuickWidgetRenderControl(q);
- offscreenWindow = new QQuickWindow(*new QQuickOffcreenWindowPrivate(),renderControl);
+ offscreenWindow = new QQuickWidgetOffscreenWindow(*new QQuickWidgetOffscreenWindowPrivate(), renderControl);
offscreenWindow->setScreen(q->screen());
- offscreenWindow->setTitle(QString::fromLatin1("Offscreen"));
- offscreenWindow->setObjectName(QString::fromLatin1("QQuickOffScreenWindow"));
// Do not call create() on offscreenWindow.
// Check if the Software Adaptation is being used
@@ -139,6 +145,10 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
QWidget::connect(offscreenWindow, &QQuickWindow::focusObjectChanged, q, &QQuickWidget::propagateFocusObjectChanged);
QObject::connect(renderControl, SIGNAL(renderRequested()), q, SLOT(triggerUpdate()));
QObject::connect(renderControl, SIGNAL(sceneChanged()), q, SLOT(triggerUpdate()));
+
+#if QT_CONFIG(accessibility)
+ QAccessible::installFactory(&qAccessibleQuickWidgetFactory);
+#endif
}
void QQuickWidgetPrivate::ensureEngine() const
diff --git a/src/quickwidgets/qquickwidget_p.h b/src/quickwidgets/qquickwidget_p.h
index 881f7f9220..1a946bcc71 100644
--- a/src/quickwidgets/qquickwidget_p.h
+++ b/src/quickwidgets/qquickwidget_p.h
@@ -148,6 +148,14 @@ public:
bool forceFullUpdate;
};
+class QQuickWidgetOffscreenWindow: public QQuickWindow
+{
+ Q_OBJECT
+
+public:
+ QQuickWidgetOffscreenWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control);
+};
+
QT_END_NAMESPACE
#endif // QQuickWidget_P_H
diff --git a/src/quickwidgets/quickwidgets.pro b/src/quickwidgets/quickwidgets.pro
index 2438e577ae..f46deb54ac 100644
--- a/src/quickwidgets/quickwidgets.pro
+++ b/src/quickwidgets/quickwidgets.pro
@@ -7,9 +7,13 @@ DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES QT_NO_FO
HEADERS += \
qquickwidget.h \
qquickwidget_p.h \
- qtquickwidgetsglobal.h
+ qtquickwidgetsglobal.h \
+ qaccessiblequickwidget.h \
+ qaccessiblequickwidgetfactory_p.h
SOURCES += \
- qquickwidget.cpp
+ qquickwidget.cpp \
+ qaccessiblequickwidget.cpp \
+ qaccessiblequickwidgetfactory.cpp
load(qt_module)
--
2.40.1

View File

@ -0,0 +1,46 @@
From ffa3c975270c5026be40912451a289492956f01c Mon Sep 17 00:00:00 2001
From: Fushan Wen <qydwhotmail@gmail.com>
Date: Sat, 5 Nov 2022 01:44:30 +0800
Subject: [PATCH 10/26] Send ObjectShow event for visible components after
initialized
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Currently ObjectShow event is only sent when the visible property
changes from false to true, but for items with the notification
accessible role, a screen reader like Orca needs to receive an
ObjectShow event to read the notification, so also send the event after
a component is initialized.
See also: https://gitlab.gnome.org/GNOME/orca/-/merge_requests/134
Pick-to: 6.4
Change-Id: I626594b65ffe4d0582dcee9f489df0c2c63e53b7
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
(cherry picked from commit 9a4f2d23ecec2c7ff19f83cff28df6b97e3fda98)
---
src/quick/items/qquickitem.cpp | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index ec55fb2998..499fb61d1b 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -5125,6 +5125,13 @@ void QQuickItem::componentComplete()
d->addToDirtyList();
QQuickWindowPrivate::get(d->window)->dirtyItem(this);
}
+
+#if QT_CONFIG(accessibility)
+ if (d->isAccessible && d->effectiveVisible) {
+ QAccessibleEvent ev(this, QAccessible::ObjectShow);
+ QAccessible::updateAccessibility(&ev);
+ }
+#endif
}
QQuickStateGroup *QQuickItemPrivate::_states()
--
2.40.1

View File

@ -0,0 +1,113 @@
From 2384b04415045b2203894b24a3743b03eeadbc88 Mon Sep 17 00:00:00 2001
From: Volker Hilsheimer <volker.hilsheimer@qt.io>
Date: Wed, 9 Nov 2022 15:34:11 +0100
Subject: [PATCH 11/26] QQuickItem: avoid emitting signals during destruction
If a QQuickItem is in the QQuickItem destructor, then it is both unsafe
and unnecessary to emit property change notifications. Connected code
can no longer rely on the state of the emitting object - if it was
originally a subclass of QQuickItem, then those subclass destructors
will already have run. And the QQuickItem destructor will also have
partially run, leaving the object in an undefined state.
Add a flag that we set to true at the top of ~QQuickItem, and don't emit
visibleChildrenChanged, parentChanged, visibleChanged, and
childrenChanged for items that are partially destroyed already.
[ChangeLog][Qt Quick][QQuickItem] QQuickItem no longer emits change
notifications for the parent, children, visible, and visibleChildren
properties while it is being destroyed.
Task-number: QTBUG-107850
Change-Id: I36ea98842c89ad89fcc1c4a328d138f66f2a0446
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
(cherry picked from commit 74873324bdf3399753f9fcaf7461c0e00df628b1)
---
src/quick/items/qquickitem.cpp | 21 +++++++++++++--------
src/quick/items/qquickitem_p.h | 1 +
2 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 499fb61d1b..5ee2a440a3 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -2327,6 +2327,7 @@ QQuickItem::QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent)
QQuickItem::~QQuickItem()
{
Q_D(QQuickItem);
+ d->inDestructor = true;
if (d->windowRefCount > 1)
d->windowRefCount = 1; // Make sure window is set to null in next call to derefWindow().
@@ -2694,9 +2695,8 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
const bool wasVisible = isVisible();
op->removeChild(this);
- if (wasVisible) {
+ if (wasVisible && !op->inDestructor)
emit oldParentItem->visibleChildrenChanged();
- }
} else if (d->window) {
QQuickWindowPrivate::get(d->window)->parentlessItems.remove(this);
}
@@ -2773,8 +2773,9 @@ void QQuickItem::setParentItem(QQuickItem *parentItem)
d->itemChange(ItemParentHasChanged, d->parentItem);
- emit parentChanged(d->parentItem);
- if (isVisible() && d->parentItem)
+ if (!d->inDestructor)
+ emit parentChanged(d->parentItem);
+ if (isVisible() && d->parentItem && !QQuickItemPrivate::get(d->parentItem)->inDestructor)
emit d->parentItem->visibleChildrenChanged();
}
@@ -2970,7 +2971,8 @@ void QQuickItemPrivate::removeChild(QQuickItem *child)
itemChange(QQuickItem::ItemChildRemovedChange, child);
- emit q->childrenChanged();
+ if (!inDestructor)
+ emit q->childrenChanged();
}
void QQuickItemPrivate::refWindow(QQuickWindow *c)
@@ -3199,6 +3201,7 @@ QQuickItemPrivate::QQuickItemPrivate()
, touchEnabled(false)
#endif
, hasCursorHandler(false)
+ , inDestructor(false)
, dirtyAttributes(0)
, nextDirtyItem(nullptr)
, prevDirtyItem(nullptr)
@@ -6118,9 +6121,11 @@ bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
QAccessible::updateAccessibility(&ev);
}
#endif
- emit q->visibleChanged();
- if (childVisibilityChanged)
- emit q->visibleChildrenChanged();
+ if (!inDestructor) {
+ emit q->visibleChanged();
+ if (childVisibilityChanged)
+ emit q->visibleChildrenChanged();
+ }
return true; // effective visibility DID change
}
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 841d91bb40..ade8fb61f2 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -472,6 +472,7 @@ public:
bool replayingPressEvent:1;
bool touchEnabled:1;
bool hasCursorHandler:1;
+ quint32 inDestructor:1; // has entered ~QQuickItem
enum DirtyType {
TransformOrigin = 0x00000001,
--
2.40.1

View File

@ -0,0 +1,57 @@
From 5b6faa5cc115d5be8b2300e059592f8dd1a84ac8 Mon Sep 17 00:00:00 2001
From: Harald Sitter <sitter@kde.org>
Date: Mon, 28 Nov 2022 14:59:33 +0100
Subject: [PATCH 12/26] a11y: track item enabled state
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
disabled items are neither enabled nor focusable
Change-Id: I4f286c7b85605d5ad6fa787d1f5cfcce1297d268
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
(cherry picked from commit 20fd2902a6d7bdb4a3306005d2718ca5a8fef96d)
---
src/quick/accessible/qaccessiblequickitem.cpp | 4 ++++
src/quick/items/qquickitem.cpp | 9 +++++++++
2 files changed, 13 insertions(+)
diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp
index 0692ce634d..a8df58d450 100644
--- a/src/quick/accessible/qaccessiblequickitem.cpp
+++ b/src/quick/accessible/qaccessiblequickitem.cpp
@@ -215,6 +215,10 @@ QAccessible::State QAccessibleQuickItem::state() const
if (role() == QAccessible::EditableText)
if (auto ti = qobject_cast<QQuickTextInput *>(item()))
state.passwordEdit = ti->echoMode() != QQuickTextInput::Normal;
+ if (!item()->isEnabled()) {
+ state.focusable = false;
+ state.disabled = true;
+ }
return state;
}
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 5ee2a440a3..c370d6e5c3 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -6174,6 +6174,15 @@ void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffec
}
itemChange(QQuickItem::ItemEnabledHasChanged, effectiveEnable);
+#if QT_CONFIG(accessibility)
+ if (isAccessible) {
+ QAccessible::State changedState;
+ changedState.disabled = true;
+ changedState.focusable = true;
+ QAccessibleStateChangeEvent ev(q, changedState);
+ QAccessible::updateAccessibility(&ev);
+ }
+#endif
emit q->enabledChanged();
}
--
2.40.1

View File

@ -0,0 +1,87 @@
From 3d4ff545a998066f563d03bd0e0da6aee81e811d Mon Sep 17 00:00:00 2001
From: Fabian Kosmale <fabian.kosmale@qt.io>
Date: Tue, 1 Jun 2021 16:40:44 +0200
Subject: [PATCH 13/26] Make QaccessibleQuickWidget private API
Its base class is private API, so it should be private API, too.
Change-Id: Ic80f841fee19ed0305c60ad5f8e9349a05f09e5e
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
(cherry picked from commit a4fa74d3e7581cb5c6bb82223ee17257f66fa41d)
---
src/quickwidgets/qaccessiblequickwidget.cpp | 2 +-
...ssiblequickwidget.h => qaccessiblequickwidget_p.h} | 11 +++++++++++
src/quickwidgets/qaccessiblequickwidgetfactory.cpp | 2 +-
src/quickwidgets/quickwidgets.pro | 2 +-
4 files changed, 14 insertions(+), 3 deletions(-)
rename src/quickwidgets/{qaccessiblequickwidget.h => qaccessiblequickwidget_p.h} (92%)
diff --git a/src/quickwidgets/qaccessiblequickwidget.cpp b/src/quickwidgets/qaccessiblequickwidget.cpp
index 6f04d6693f..8a1c901880 100644
--- a/src/quickwidgets/qaccessiblequickwidget.cpp
+++ b/src/quickwidgets/qaccessiblequickwidget.cpp
@@ -37,7 +37,7 @@
**
****************************************************************************/
-#include "qaccessiblequickwidget.h"
+#include "qaccessiblequickwidget_p.h"
#include "qquickwidget_p.h"
diff --git a/src/quickwidgets/qaccessiblequickwidget.h b/src/quickwidgets/qaccessiblequickwidget_p.h
similarity index 92%
rename from src/quickwidgets/qaccessiblequickwidget.h
rename to src/quickwidgets/qaccessiblequickwidget_p.h
index 1f52c78c46..7c2ab930e0 100644
--- a/src/quickwidgets/qaccessiblequickwidget.h
+++ b/src/quickwidgets/qaccessiblequickwidget_p.h
@@ -40,6 +40,17 @@
#ifndef QACCESSIBLEQUICKWIDGET_H
#define QACCESSIBLEQUICKWIDGET_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include "qquickwidget.h"
#include <QtWidgets/qaccessiblewidget.h>
diff --git a/src/quickwidgets/qaccessiblequickwidgetfactory.cpp b/src/quickwidgets/qaccessiblequickwidgetfactory.cpp
index 3756d0c27c..7ba88a1769 100644
--- a/src/quickwidgets/qaccessiblequickwidgetfactory.cpp
+++ b/src/quickwidgets/qaccessiblequickwidgetfactory.cpp
@@ -38,7 +38,7 @@
****************************************************************************/
#include "qaccessiblequickwidgetfactory_p.h"
-#include "qaccessiblequickwidget.h"
+#include "qaccessiblequickwidget_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/quickwidgets/quickwidgets.pro b/src/quickwidgets/quickwidgets.pro
index f46deb54ac..85d156b8a3 100644
--- a/src/quickwidgets/quickwidgets.pro
+++ b/src/quickwidgets/quickwidgets.pro
@@ -8,7 +8,7 @@ HEADERS += \
qquickwidget.h \
qquickwidget_p.h \
qtquickwidgetsglobal.h \
- qaccessiblequickwidget.h \
+ qaccessiblequickwidget_p.h \
qaccessiblequickwidgetfactory_p.h
SOURCES += \
--
2.40.1

View File

@ -0,0 +1,113 @@
From 0d21fc0cb74c01368107bf2779c34e5734b5e5ae Mon Sep 17 00:00:00 2001
From: Ulf Hermann <ulf.hermann@qt.io>
Date: Tue, 30 Nov 2021 14:39:48 +0100
Subject: [PATCH 14/26] Qml: Don't crash when as-casting to type with errors
Such types don't have a compilation unit, but we still know their names.
Pick-to: 6.2
Fixes: QTBUG-98792
Change-Id: I2db8dea3a5a02ec1492f7f7a054fd3ad4c6ad69a
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
(cherry picked from commit e0cd201e91ae64b9c03e0128cd17656b00611fbb)
---
src/qml/qml/qqmltypewrapper.cpp | 6 ++++--
src/qml/types/qqmlconnections.cpp | 2 +-
tests/auto/qml/qqmllanguage/data/Broken.qml | 5 +++++
tests/auto/qml/qqmllanguage/data/asBroken.qml | 6 ++++++
tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 16 ++++++++++++++++
5 files changed, 32 insertions(+), 3 deletions(-)
create mode 100644 tests/auto/qml/qqmllanguage/data/Broken.qml
create mode 100644 tests/auto/qml/qqmllanguage/data/asBroken.qml
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index 175de8b936..a6ba4b8cb3 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -419,8 +419,10 @@ ReturnedValue QQmlTypeWrapper::virtualInstanceOf(const Object *typeObject, const
return Encode(false);
QQmlRefPointer<QQmlTypeData> td = qenginepriv->typeLoader.getType(typeWrapper->d()->type().sourceUrl());
- ExecutableCompilationUnit *cu = td->compilationUnit();
- myQmlType = qenginepriv->metaObjectForType(cu->metaTypeId);
+ if (ExecutableCompilationUnit *cu = td->compilationUnit())
+ myQmlType = qenginepriv->metaObjectForType(cu->metaTypeId);
+ else
+ return Encode(false); // It seems myQmlType has some errors, so we could not compile it.
} else {
myQmlType = qenginepriv->metaObjectForType(myTypeId);
}
diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp
index 29ed62cd39..aba930dfe1 100644
--- a/src/qml/types/qqmlconnections.cpp
+++ b/src/qml/types/qqmlconnections.cpp
@@ -338,7 +338,7 @@ void QQmlConnections::connectSignalsToMethods()
&& propName.at(2).isUpper()) {
qmlWarning(this) << tr("Detected function \"%1\" in Connections element. "
"This is probably intended to be a signal handler but no "
- "signal of the target matches the name.").arg(propName);
+ "signal of the \"%2\" target matches the name.").arg(propName).arg(target->metaObject()->className());
}
}
}
diff --git a/tests/auto/qml/qqmllanguage/data/Broken.qml b/tests/auto/qml/qqmllanguage/data/Broken.qml
new file mode 100644
index 0000000000..e24d9112a8
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/Broken.qml
@@ -0,0 +1,5 @@
+import QtQml 2.15
+
+QtObject {
+ notThere: 5
+}
diff --git a/tests/auto/qml/qqmllanguage/data/asBroken.qml b/tests/auto/qml/qqmllanguage/data/asBroken.qml
new file mode 100644
index 0000000000..bd88d14c76
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/asBroken.qml
@@ -0,0 +1,6 @@
+import QtQml 2.15
+
+QtObject {
+ id: self
+ property var selfAsBroken: self as Broken
+}
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index bffb62c59e..97cc64991f 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -336,6 +336,7 @@ private slots:
void bareInlineComponent();
void hangOnWarning();
+ void objectAsBroken();
void ambiguousContainingType();
@@ -5876,6 +5877,21 @@ void tst_qqmllanguage::ambiguousContainingType()
}
}
+void tst_qqmllanguage::objectAsBroken()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("asBroken.qml"));
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(!o.isNull());
+ QVariant selfAsBroken = o->property("selfAsBroken");
+ QVERIFY(selfAsBroken.isValid());
+ // QCOMPARE(selfAsBroken.metaType(), QMetaType::fromType<std::nullptr_t>());
+
+ QQmlComponent b(&engine, testFileUrl("Broken.qml"));
+ QVERIFY(b.isError());
+}
+
QTEST_MAIN(tst_qqmllanguage)
#include "tst_qqmllanguage.moc"
--
2.40.1

View File

@ -0,0 +1,54 @@
From 4f645419ab8def41d1bdddddc5976b2ff5620bff Mon Sep 17 00:00:00 2001
From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
Date: Mon, 19 Dec 2022 10:05:33 +0100
Subject: [PATCH 15/26] Fix missing glyphs when using NativeRendering
When we look up glyphs with subpixel positions in the glyph cache,
we use the calculated subpixel position (from a set of predefined
subpixel positions) as key. In some very rare cases, we could end
up with different subpixel positions when looking up an on-screen
position than when we entered it into the cache, due to numerical
differences when doing the calculation.
The reason for this was that when entering the glyph into the
cache, we used the 16.6 fixed point representation, whereas when
looking up, we used the unmodified float. In some cases, the
converted fixed point approximation might snap to a different
predefined subpixel position than the floating point equivalent.
To avoid this, we reuse the converted fixed point positions when
looking up the glyphs in the cache.
[ChangeLog][Text] Fixed an issue where text using NativeRendering
would sometimes be missing glyphs.
Pick-to: 5.15 6.2 6.4 6.5
Fixes: QTBUG-108713
Change-Id: Iecc264eb3d27e875c24257eaefcfb18a1a5fb5be
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
(cherry picked from commit 4bad329985b75090c68a70cceee7edadc172d7ab)
---
src/quick/scenegraph/qsgdefaultglyphnode_p.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
index f912da5799..fd128aa06e 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
@@ -839,9 +839,11 @@ void QSGTextMaskMaterial::populate(const QPointF &p,
bool supportsSubPixelPositions = fontD->fontEngine->supportsSubPixelPositions();
for (int i=0; i<glyphIndexes.size(); ++i) {
QPointF glyphPosition = glyphPositions.at(i) + position;
+ QFixedPoint fixedPointPosition = fixedPointPositions.at(i);
+
QFixed subPixelPosition;
if (supportsSubPixelPositions)
- subPixelPosition = fontD->fontEngine->subPixelPositionForX(QFixed::fromReal(glyphPosition.x()));
+ subPixelPosition = fontD->fontEngine->subPixelPositionForX(QFixed::fromReal(fixedPointPosition.x.toReal() * glyphCacheScaleX));
QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphIndexes.at(i), subPixelPosition);
const QTextureGlyphCache::Coord &c = cache->coords.value(glyph);
--
2.40.1

View File

@ -0,0 +1,32 @@
From 187bb66368921ce4a6522aca78531714485c377c Mon Sep 17 00:00:00 2001
From: Fushan Wen <qydwhotmail@gmail.com>
Date: Tue, 10 Jan 2023 20:42:04 +0800
Subject: [PATCH 16/26] Revert "Fix missing glyphs when using NativeRendering"
This reverts commit da5e53b649f50cd9cdd89dadbba16f05e4070be2.
It breaks fonts on Wayland when global scale > 100%.
---
src/quick/scenegraph/qsgdefaultglyphnode_p.cpp | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
index fd128aa06e..f912da5799 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
@@ -839,11 +839,9 @@ void QSGTextMaskMaterial::populate(const QPointF &p,
bool supportsSubPixelPositions = fontD->fontEngine->supportsSubPixelPositions();
for (int i=0; i<glyphIndexes.size(); ++i) {
QPointF glyphPosition = glyphPositions.at(i) + position;
- QFixedPoint fixedPointPosition = fixedPointPositions.at(i);
-
QFixed subPixelPosition;
if (supportsSubPixelPositions)
- subPixelPosition = fontD->fontEngine->subPixelPositionForX(QFixed::fromReal(fixedPointPosition.x.toReal() * glyphCacheScaleX));
+ subPixelPosition = fontD->fontEngine->subPixelPositionForX(QFixed::fromReal(glyphPosition.x()));
QTextureGlyphCache::GlyphAndSubPixelPosition glyph(glyphIndexes.at(i), subPixelPosition);
const QTextureGlyphCache::Coord &c = cache->coords.value(glyph);
--
2.40.1

View File

@ -0,0 +1,57 @@
From 0d217b88c6bf5673464e350e3a62773e69555f98 Mon Sep 17 00:00:00 2001
From: Jaeyoon Jung <jaeyoon.jung@lge.com>
Date: Fri, 19 Feb 2021 08:11:57 +0900
Subject: [PATCH 17/26] QQmlImportDatabase: Make sure the newly added import
path be first
If it already exists in the import list, move it to the first place.
This is as per the description of QQmlEngine::addImportPath:
| The newly added path will be first in the importPathList().
Change-Id: I782d355c46ada2a46cff72e63326208f39028e01
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit 3e413803c698d21f398daf0450c8f501204eb167)
---
src/qml/qml/qqmlimport.cpp | 9 ++++++---
tests/auto/qml/qqmlimport/tst_qqmlimport.cpp | 5 +++++
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 10c6c41338..39bfcdc999 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -2120,9 +2120,12 @@ void QQmlImportDatabase::addImportPath(const QString& path)
cPath.replace(Backslash, Slash);
}
- if (!cPath.isEmpty()
- && !fileImportPath.contains(cPath))
- fileImportPath.prepend(cPath);
+ if (!cPath.isEmpty()) {
+ if (fileImportPath.contains(cPath))
+ fileImportPath.move(fileImportPath.indexOf(cPath), 0);
+ else
+ fileImportPath.prepend(cPath);
+ }
}
/*!
diff --git a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp
index 9c865b3f73..1f788f7a7f 100644
--- a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp
+++ b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp
@@ -154,6 +154,11 @@ void tst_QQmlImport::importPathOrder()
engine.addImportPath(QT_QMLTEST_DATADIR);
expectedImportPaths.prepend(QT_QMLTEST_DATADIR);
QCOMPARE(expectedImportPaths, engine.importPathList());
+
+ // Add qml2Imports again to make it the first of the list
+ engine.addImportPath(qml2Imports);
+ expectedImportPaths.move(expectedImportPaths.indexOf(qml2Imports), 0);
+ QCOMPARE(expectedImportPaths, engine.importPathList());
}
Q_DECLARE_METATYPE(QQmlImports::ImportVersion)
--
2.40.1

View File

@ -0,0 +1,102 @@
From 35608b36b284000f5871deb6a0d58113110e01e8 Mon Sep 17 00:00:00 2001
From: Fabian Kosmale <fabian.kosmale@qt.io>
Date: Wed, 20 Jul 2022 11:44:43 +0200
Subject: [PATCH 18/26] QQuickState::when: handle QJSValue properties correctly
If one assigns a binding whose evaluation results in a QJSValue, care
must be take to correctly convert it into a bool. Instead of directly
using QVariant::value<bool>, one needs to first extract the QJSValue,
and only convert it to bool afterwards.
This is necessary due to the custom binding evaluation we're doing to
avoid state oscillation.
Amends a8c729d83979fb0b9939044d246e73b1d578e65b.
Fixes: QTBUG-105000
Pick-to: 6.4 6.3 6.2 5.15
Change-Id: I4b093b48edecf9e0f09d2b54d10c2ff527f24ac3
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit 2c31d25a44b1221c151681e1bb68ef78618e0166)
---
src/quick/util/qquickstategroup.cpp | 10 ++++++++--
.../quick/qquickstates/data/jsValueWhen.qml | 18 ++++++++++++++++++
.../quick/qquickstates/tst_qquickstates.cpp | 11 +++++++++++
3 files changed, 37 insertions(+), 2 deletions(-)
create mode 100644 tests/auto/quick/qquickstates/data/jsValueWhen.qml
diff --git a/src/quick/util/qquickstategroup.cpp b/src/quick/util/qquickstategroup.cpp
index 7cb3138618..f732b1eb4a 100644
--- a/src/quick/util/qquickstategroup.cpp
+++ b/src/quick/util/qquickstategroup.cpp
@@ -381,8 +381,14 @@ bool QQuickStateGroupPrivate::updateAutoState()
const auto potentialWhenBinding = QQmlPropertyPrivate::binding(whenProp);
// if there is a binding, the value in when might not be up-to-date at this point
// so we manually reevaluate the binding
- if (auto abstractBinding = dynamic_cast<QQmlBinding *>(potentialWhenBinding))
- whenValue = abstractBinding->evaluate().toBool();
+ if (auto abstractBinding = dynamic_cast<QQmlBinding *>(potentialWhenBinding)) {
+ QVariant evalResult = abstractBinding->evaluate();
+ if (evalResult.userType() == qMetaTypeId<QJSValue>())
+ whenValue = evalResult.value<QJSValue>().toBool();
+ else
+ whenValue = evalResult.toBool();
+ }
+
if (whenValue) {
if (stateChangeDebug())
qWarning() << "Setting auto state due to expression";
diff --git a/tests/auto/quick/qquickstates/data/jsValueWhen.qml b/tests/auto/quick/qquickstates/data/jsValueWhen.qml
new file mode 100644
index 0000000000..6d5eb1600c
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/jsValueWhen.qml
@@ -0,0 +1,18 @@
+import QtQuick 2.15
+
+Item {
+ id: root
+ property var prop: null
+ property bool works: false
+ states: [
+ State {
+ name: "mystate"
+ when: root.prop
+ PropertyChanges {
+ target: root
+ works: "works"
+ }
+ }
+ ]
+ Component.onCompleted: root.prop = new Object
+}
diff --git a/tests/auto/quick/qquickstates/tst_qquickstates.cpp b/tests/auto/quick/qquickstates/tst_qquickstates.cpp
index aa55b42935..26e86672b0 100644
--- a/tests/auto/quick/qquickstates/tst_qquickstates.cpp
+++ b/tests/auto/quick/qquickstates/tst_qquickstates.cpp
@@ -188,6 +188,7 @@ private slots:
void revertListMemoryLeak();
void duplicateStateName();
void trivialWhen();
+ void jsValueWhen();
void noStateOsciallation();
void parentChangeCorrectReversal();
void revertNullObjectBinding();
@@ -1734,6 +1735,16 @@ void tst_qquickstates::trivialWhen()
QVERIFY(c.create());
}
+void tst_qquickstates::jsValueWhen()
+{
+ QQmlEngine engine;
+
+ QQmlComponent c(&engine, testFileUrl("jsValueWhen.qml"));
+ QScopedPointer<QObject> root(c.create());
+ QVERIFY(root);
+ QVERIFY(root->property("works").toBool());
+}
+
void tst_qquickstates::noStateOsciallation()
{
QQmlEngine engine;
--
2.40.1

View File

@ -0,0 +1,162 @@
From 32730dad9adcaab137cf2fe434b03be23bbe9c7d Mon Sep 17 00:00:00 2001
From: Ulf Hermann <ulf.hermann@qt.io>
Date: Wed, 29 Mar 2023 16:36:03 +0200
Subject: [PATCH 19/26] Models: Avoid crashes when deleting cache items
Pick-to: 6.5 6.2 5.15
Fixes: QTBUG-91425
Change-Id: I58cf9ee29922f83fc6621f771b80ed557b31f106
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 0cfdecba54e4f40468c4c9a8a6668cc1bc0eff65)
* asturmlechner 2023-04-08: Resolve conflict with dev branch commit
c2d490a2385ea6f389340a296acaac0fa198c8b9 (qAsConst to std::as_const)
---
src/qmlmodels/qqmldelegatemodel.cpp | 23 ++++++---
.../qml/qqmldelegatemodel/data/deleteRace.qml | 50 +++++++++++++++++++
.../tst_qqmldelegatemodel.cpp | 12 +++++
3 files changed, 78 insertions(+), 7 deletions(-)
create mode 100644 tests/auto/qml/qqmldelegatemodel/data/deleteRace.qml
diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp
index 4157899aa6..5b7e767ae2 100644
--- a/src/qmlmodels/qqmldelegatemodel.cpp
+++ b/src/qmlmodels/qqmldelegatemodel.cpp
@@ -1883,10 +1883,15 @@ void QQmlDelegateModelPrivate::emitChanges()
for (int i = 1; i < m_groupCount; ++i)
QQmlDelegateModelGroupPrivate::get(m_groups[i])->emitModelUpdated(reset);
- auto cacheCopy = m_cache; // deliberate; emitChanges may alter m_cache
- for (QQmlDelegateModelItem *cacheItem : qAsConst(cacheCopy)) {
- if (cacheItem->attached)
- cacheItem->attached->emitChanges();
+ // emitChanges may alter m_cache and delete items
+ QVarLengthArray<QPointer<QQmlDelegateModelAttached>> attachedObjects;
+ attachedObjects.reserve(m_cache.length());
+ for (const QQmlDelegateModelItem *cacheItem : qAsConst(m_cache))
+ attachedObjects.append(cacheItem->attached);
+
+ for (const QPointer<QQmlDelegateModelAttached> &attached : qAsConst(attachedObjects)) {
+ if (attached && attached->m_cacheItem)
+ attached->emitChanges();
}
}
@@ -2707,20 +2712,24 @@ void QQmlDelegateModelAttached::emitChanges()
m_previousGroups = m_cacheItem->groups;
int indexChanges = 0;
- for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i) {
+ const int groupCount = m_cacheItem->metaType->groupCount;
+ for (int i = 1; i < groupCount; ++i) {
if (m_previousIndex[i] != m_currentIndex[i]) {
m_previousIndex[i] = m_currentIndex[i];
indexChanges |= (1 << i);
}
}
+ // Don't access m_cacheItem anymore once we've started sending signals.
+ // We don't own it and someone might delete it.
+
int notifierId = 0;
const QMetaObject *meta = metaObject();
- for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i, ++notifierId) {
+ for (int i = 1; i < groupCount; ++i, ++notifierId) {
if (groupChanges & (1 << i))
QMetaObject::activate(this, meta, notifierId, nullptr);
}
- for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i, ++notifierId) {
+ for (int i = 1; i < groupCount; ++i, ++notifierId) {
if (indexChanges & (1 << i))
QMetaObject::activate(this, meta, notifierId, nullptr);
}
diff --git a/tests/auto/qml/qqmldelegatemodel/data/deleteRace.qml b/tests/auto/qml/qqmldelegatemodel/data/deleteRace.qml
new file mode 100644
index 0000000000..23874970e7
--- /dev/null
+++ b/tests/auto/qml/qqmldelegatemodel/data/deleteRace.qml
@@ -0,0 +1,50 @@
+import QtQuick 2.15
+import QtQml.Models 2.15
+
+Item {
+ DelegateModel {
+ id: delegateModel
+ model: ListModel {
+ id: sourceModel
+
+ ListElement { title: "foo" }
+ ListElement { title: "bar" }
+
+ function clear() {
+ if (count > 0)
+ remove(0, count);
+ }
+ }
+
+ groups: [
+ DelegateModelGroup { name: "selectedItems" }
+ ]
+
+ delegate: Text {
+ height: DelegateModel.inSelectedItems ? implicitHeight * 2 : implicitHeight
+ Component.onCompleted: {
+ if (index === 0)
+ DelegateModel.inSelectedItems = true;
+ }
+ }
+
+ Component.onCompleted: {
+ items.create(0)
+ items.create(1)
+ }
+ }
+
+ ListView {
+ anchors.fill: parent
+ model: delegateModel
+ }
+
+ Timer {
+ running: true
+ interval: 10
+ onTriggered: sourceModel.clear()
+ }
+
+ property int count: delegateModel.items.count
+}
+
diff --git a/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp b/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
index 1722447830..f473cff75f 100644
--- a/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
+++ b/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
@@ -50,6 +50,7 @@ private slots:
void qtbug_86017();
void contextAccessedByHandler();
void redrawUponColumnChange();
+ void deleteRace();
};
class AbstractItemModel : public QAbstractItemModel
@@ -213,6 +214,17 @@ void tst_QQmlDelegateModel::redrawUponColumnChange()
QCOMPARE(item->property("text").toString(), "Coconut");
}
+void tst_QQmlDelegateModel::deleteRace()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("deleteRace.qml"));
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(!o.isNull());
+ QTRY_COMPARE(o->property("count").toInt(), 2);
+ QTRY_COMPARE(o->property("count").toInt(), 0);
+}
+
QTEST_MAIN(tst_QQmlDelegateModel)
#include "tst_qqmldelegatemodel.moc"
--
2.40.1

View File

@ -0,0 +1,35 @@
From adad56c92c633248f0fe467f8e0c32dc461f6716 Mon Sep 17 00:00:00 2001
From: Maximilian Goldstein <max.goldstein@qt.io>
Date: Wed, 9 Jun 2021 15:02:45 +0200
Subject: [PATCH 20/26] qv4function: Fix crash due to reference being
invalidated
Function::updateInternalClass creates a reference to a QStringList that is appended to before being used.
This is unsafe and can leads to a segfault if the append() causes a reallocation.
Fixes: QTBUG-94360
Pick-to: 5.15 6.1 6.2
Change-Id: Iac49e8d816cf440ca2b70e133c88314eb8df6b91
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
(cherry picked from commit 7fa28f98824a94396106eadfc028b329985a0cfc)
---
src/qml/jsruntime/qv4function.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index aeb4835c40..9082628a1a 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -136,7 +136,7 @@ void Function::updateInternalClass(ExecutionEngine *engine, const QList<QByteArr
if (duplicate == -1) {
parameterNames.append(QString::fromUtf8(param));
} else {
- const QString &dup = parameterNames[duplicate];
+ const QString dup = parameterNames[duplicate];
parameterNames.append(dup);
parameterNames[duplicate] =
QString(0xfffe) + QString::number(duplicate) + dup;
--
2.40.1

View File

@ -0,0 +1,141 @@
From cc1b9e7d4aac93d0767e83431be5a5aebcdffb59 Mon Sep 17 00:00:00 2001
From: Fabian Kosmale <fabian.kosmale@qt.io>
Date: Tue, 29 Mar 2022 10:44:04 +0200
Subject: [PATCH 21/26] Quick Animations: Fix crash
SwipeDelegate causes the running animation job to be deleted when
calling swipe.close in swipe.completed. Employ the RETURN_IF_DELETED
check in more places to avoid crashes.
Fixes: QTBUG-100560
Task-number: QTBUG-103223
Pick-to: 6.3 6.2 5.15
Change-Id: I276eeaa9aed1bdb36449b322a24641fa02c4d5e4
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit 0238af0bd48b831d72126f2228d5913eccf67bae)
* asturmlechner 2023-04-09: Resolve conflict with dev branch commit
4938984f9a779192264757a06e6ca555fc8f5e91
---
.../qcontinuinganimationgroupjob.cpp | 4 +-
.../animations/qparallelanimationgroupjob.cpp | 4 +-
.../swipedelegate/CloseOnCompletedWorks.qml | 74 +++++++++++++++++++
3 files changed, 78 insertions(+), 4 deletions(-)
create mode 100644 tests/manual/quickcontrols2/swipedelegate/CloseOnCompletedWorks.qml
diff --git a/src/qml/animations/qcontinuinganimationgroupjob.cpp b/src/qml/animations/qcontinuinganimationgroupjob.cpp
index 88c0e9e60e..61a9dc36f8 100644
--- a/src/qml/animations/qcontinuinganimationgroupjob.cpp
+++ b/src/qml/animations/qcontinuinganimationgroupjob.cpp
@@ -82,9 +82,9 @@ void QContinuingAnimationGroupJob::updateState(QAbstractAnimationJob::State newS
return;
}
for (QAbstractAnimationJob *animation = firstChild(); animation; animation = animation->nextSibling()) {
- resetUncontrolledAnimationFinishTime(animation);
+ RETURN_IF_DELETED(resetUncontrolledAnimationFinishTime(animation));
animation->setDirection(m_direction);
- animation->start();
+ RETURN_IF_DELETED(animation->start());
}
break;
}
diff --git a/src/qml/animations/qparallelanimationgroupjob.cpp b/src/qml/animations/qparallelanimationgroupjob.cpp
index 420a934ba2..a828d0e234 100644
--- a/src/qml/animations/qparallelanimationgroupjob.cpp
+++ b/src/qml/animations/qparallelanimationgroupjob.cpp
@@ -144,10 +144,10 @@ void QParallelAnimationGroupJob::updateState(QAbstractAnimationJob::State newSta
animation->stop();
m_previousLoop = m_direction == Forward ? 0 : m_loopCount - 1;
}
- resetUncontrolledAnimationFinishTime(animation);
+ RETURN_IF_DELETED(resetUncontrolledAnimationFinishTime(animation));
animation->setDirection(m_direction);
if (shouldAnimationStart(animation, oldState == Stopped))
- animation->start();
+ RETURN_IF_DELETED(animation->start());
}
break;
}
diff --git a/tests/manual/quickcontrols2/swipedelegate/CloseOnCompletedWorks.qml b/tests/manual/quickcontrols2/swipedelegate/CloseOnCompletedWorks.qml
new file mode 100644
index 0000000000..38dfde41c3
--- /dev/null
+++ b/tests/manual/quickcontrols2/swipedelegate/CloseOnCompletedWorks.qml
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 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:BSD$
+** 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.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2
+import QtQuick.Controls 2
+ApplicationWindow {
+ visible: true
+ width: 640
+ height: 480
+
+ ListView {
+ anchors.fill: parent
+ model: 2
+
+ delegate: SwipeDelegate {
+ text: "Swipe me left (should not crash)"
+
+ swipe.right: Label {
+ text: "Release (should not crash)"
+ }
+
+ swipe.onCompleted: {
+ swipe.close()
+ }
+ }
+ }
+}
--
2.40.1

View File

@ -0,0 +1,129 @@
From 3366947eb58c0c5ad8a7e714a6b9667e1c3ff7b8 Mon Sep 17 00:00:00 2001
From: Joni Poikelin <joni.poikelin@qt.io>
Date: Thu, 3 Sep 2020 14:22:26 +0300
Subject: [PATCH 22/26] Prevent crash when destroying asynchronous Loader
Fixes: QTBUG-86255
Pick-to: 5.15
Change-Id: I30488b64d910a1409a43e2e98ee7ab084aec33d2
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit 149c1dd07b54ee0c027d94a49d52160dc4f4e2ac)
* asturmlechner 2023-01-06: Resolve conflict with dev branch commits
d51c007ecc8aa6256cb95cf3992e5ac34a70fa3f and
b2a4a61e8cb0839ba293783ac03c72f35c7b1307
---
src/qml/qml/qqmlvmemetaobject.cpp | 2 +-
.../quick/qquickgridview/data/qtbug86255.qml | 55 +++++++++++++++++++
.../qquickgridview/tst_qquickgridview.cpp | 13 +++++
3 files changed, 69 insertions(+), 1 deletion(-)
create mode 100644 tests/auto/quick/qquickgridview/data/qtbug86255.qml
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index aa9f4bc1bd..09503a7e99 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -254,7 +254,7 @@ void QQmlVMEMetaObjectEndpoint::tryConnect()
if (!pd)
return;
- if (pd->notifyIndex() != -1)
+ if (pd->notifyIndex() != -1 && ctxt->engine)
connect(target, pd->notifyIndex(), ctxt->engine);
}
diff --git a/tests/auto/quick/qquickgridview/data/qtbug86255.qml b/tests/auto/quick/qquickgridview/data/qtbug86255.qml
new file mode 100644
index 0000000000..20688b1967
--- /dev/null
+++ b/tests/auto/quick/qquickgridview/data/qtbug86255.qml
@@ -0,0 +1,55 @@
+import QtQuick 2.15
+
+Item {
+ width: 240
+ height: 320
+
+ GridView {
+ id: grid
+ objectName: "view"
+ anchors.fill: parent
+ cellWidth: 64
+ cellHeight: 64
+ model: ListModel {
+ id: listModel
+
+ Component.onCompleted: reload()
+
+ function reload() {
+ clear();
+ for (let i = 0; i < 1000; i++) {
+ let magic = Math.random();
+ append( { magic } );
+ }
+ }
+ }
+ clip: true
+ delegate: Item {
+ id: d
+ property string val: magic
+ Loader {
+ property alias value: d.val
+ asynchronous: true
+ sourceComponent: cmp
+ }
+ }
+ }
+
+ Timer {
+ running: true
+ interval: 1000
+ onTriggered: listModel.reload()
+ }
+ Timer {
+ running: true
+ interval: 500
+ onTriggered: grid.flick(0, -4000)
+ }
+
+ Component {
+ id: cmp
+ Text {
+ text: value
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
index 94ec4f44d5..7d0d9fa7a7 100644
--- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
+++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
@@ -213,6 +213,7 @@ private slots:
void QTBUG_45640();
void QTBUG_49218();
void QTBUG_48870_fastModelUpdates();
+ void QTBUG_86255();
void keyNavigationEnabled();
void resizeDynamicCellWidthRtL();
@@ -6814,6 +6815,18 @@ void tst_QQuickGridView::resizeDynamicCellWidthRtL()
QTRY_COMPARE(gridview->contentX(), 0.f);
}
+void tst_QQuickGridView::QTBUG_86255()
+{
+ QScopedPointer<QQuickView> window(createView());
+ window->setSource(testFileUrl("qtbug86255.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+ QQuickGridView *view = findItem<QQuickGridView>(window->rootObject(), "view");
+ QVERIFY(view != nullptr);
+ QTRY_COMPARE(view->isFlicking(), true);
+ QTRY_COMPARE(view->isFlicking(), false);
+}
+
void tst_QQuickGridView::releaseItems()
{
QScopedPointer<QQuickView> view(createView());
--
2.40.1

View File

@ -0,0 +1,81 @@
From 688795f02ecc163e7cb18dfb6c87273d7e613cbf Mon Sep 17 00:00:00 2001
From: Volker Hilsheimer <volker.hilsheimer@qt.io>
Date: Fri, 18 Nov 2022 14:20:20 +0100
Subject: [PATCH 23/26] QQuickItem: Fix effective visibility for items without
parent
Items are visible if they are children of a visible parent, and not
explicitly hidden. The effectiveVisible member stores the state and is
updated when conditions that impact the item visibility changes.
The old code returned true for items outside a visual hierarchy, which
broke signal emission when items were removed from a parent, e.g.
because the parent got destroyed. With this change, items removed from
a visual hierarchy will emit the visibleChanged signal.
Note: QQuickItem initializes the effectiveVisible member to true, even
if the item was created without parent item. Visual items are required
to be added to a visual hierarchy via setParentItem. For this reason,
newly created items never emit visibleChanged when they are added to
a parent.
Adjust the QQuickItem::visible test - it creates an item hierarchy
without window. Such items are never visible, so add a window and
parent the test item hierarchy to the window's content item.
This fixes the expected failures in the tests. It does introduce an
incompatibility with QGraphicsView and QGraphicsItem, which continue
to return true from QGraphicsItem::isVisible for items that are not
in an item hierarchy.
[ChangeLog][Qt Quick][QQuickItem] The visible property of Items without
a parent now always returns false, and the visibleChanged signal gets
emitted when the parent item of a visible item becomes null.
Fixes: QTBUG-108213
Change-Id: If4b2947cefd1407853f0f29e6c3fdbd49fc9af65
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
(cherry picked from commit d1b9a4cacfb966cf0a37983d8f8044f3aedf5de3)
CCBUG: 467909
CCBUG: 396359
---
src/quick/items/qquickitem.cpp | 6 ++----
tests/auto/quick/qquickitem/tst_qquickitem.cpp | 2 ++
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index c370d6e5c3..0d421349d7 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -6081,10 +6081,8 @@ void QQuickItem::setEnabled(bool e)
bool QQuickItemPrivate::calcEffectiveVisible() const
{
- // XXX todo - Should the effective visible of an element with no parent just be the current
- // effective visible? This would prevent pointless re-processing in the case of an element
- // moving to/from a no-parent situation, but it is different from what graphics view does.
- return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
+ // An item is visible if it is a child of a visible parent, and not explicitly hidden.
+ return explicitVisible && parentItem && QQuickItemPrivate::get(parentItem)->effectiveVisible;
}
bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp
index 42348d8dd1..34eefd85e6 100644
--- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp
@@ -989,7 +989,9 @@ void tst_qquickitem::setParentItem()
void tst_qquickitem::visible()
{
+ QQuickWindow window;
QQuickItem *root = new QQuickItem;
+ root->setParentItem(window.contentItem());
QQuickItem *child1 = new QQuickItem;
child1->setParentItem(root);
--
2.40.1

View File

@ -0,0 +1,51 @@
From 70bc0c03423fe861bb917c67041f71e08ec10343 Mon Sep 17 00:00:00 2001
From: Fushan Wen <qydwhotmail@gmail.com>
Date: Fri, 21 Apr 2023 23:38:04 +0800
Subject: [PATCH 24/26] Revert "QQuickItem: Fix effective visibility for items
without parent"
This breaks applications that use QQmlPropertyList to store QQuickItem
and don't set a parentItem for them.
Ref: https://github.com/musescore/MuseScore/issues/17276
This reverts commit 45c22a0221937682f4496801a495458a00f76d3a.
---
src/quick/items/qquickitem.cpp | 6 ++++--
tests/auto/quick/qquickitem/tst_qquickitem.cpp | 2 --
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 0d421349d7..c370d6e5c3 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -6081,8 +6081,10 @@ void QQuickItem::setEnabled(bool e)
bool QQuickItemPrivate::calcEffectiveVisible() const
{
- // An item is visible if it is a child of a visible parent, and not explicitly hidden.
- return explicitVisible && parentItem && QQuickItemPrivate::get(parentItem)->effectiveVisible;
+ // XXX todo - Should the effective visible of an element with no parent just be the current
+ // effective visible? This would prevent pointless re-processing in the case of an element
+ // moving to/from a no-parent situation, but it is different from what graphics view does.
+ return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible);
}
bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp
index 34eefd85e6..42348d8dd1 100644
--- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp
@@ -989,9 +989,7 @@ void tst_qquickitem::setParentItem()
void tst_qquickitem::visible()
{
- QQuickWindow window;
QQuickItem *root = new QQuickItem;
- root->setParentItem(window.contentItem());
QQuickItem *child1 = new QQuickItem;
child1->setParentItem(root);
--
2.40.1

View File

@ -0,0 +1,111 @@
From a9f99d945e23b915502ddbd56e20a2af9f33296e Mon Sep 17 00:00:00 2001
From: Volker Hilsheimer <volker.hilsheimer@qt.io>
Date: Tue, 18 Apr 2023 22:05:36 +0200
Subject: [PATCH 25/26] Accessibility: respect value in attached Accessible in
controls
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
QQuickItemPrivate::accessibleRole is virtual and called by the framework
to determine the role of an item. The default implementation checks and
respects a possible Accessible attached object. However, subclasses that
override the virtual don't, so the attached properties are ignored, and
the class-specific implementation wins. This makes it impossible to
change the role of e.g. a checkable button.
To fix that, move the code respecting the attached object into a non-
virtual function that the framework calls instead, and only call the
virtual member if there is no attached object, or if that object is not
initialized with a role. Replace calls to the virtual from the
framework with calls to the non-virtual wrapper.
Do this for both QQuickItem and for QQuickPopup, and adjust the logic
in QQuickControl types that create an attached object and initialize
it's role when accessibility becomes active. Use the non-overridable
effective role value for that as well.
Add a test case, and to avoid any new framework calls to the virtual,
make it private.
Fixes: QTBUG-110114
Pick-to: 6.5 6.2
Change-Id: Ia709cecbd181b6d8ee3297a4af60c1e7db9a2c51
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
(cherry picked from commit 3c08d08ae2bbd449cc0579a1b3cb499383c7a60c)
---
src/quick/accessible/qaccessiblequickitem.cpp | 2 +-
src/quick/items/qquickitem.cpp | 17 ++++++++++++-----
src/quick/items/qquickitem_p.h | 3 +++
3 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp
index a8df58d450..99e6eff7c3 100644
--- a/src/quick/accessible/qaccessiblequickitem.cpp
+++ b/src/quick/accessible/qaccessiblequickitem.cpp
@@ -230,7 +230,7 @@ QAccessible::Role QAccessibleQuickItem::role() const
QAccessible::Role role = QAccessible::NoRole;
if (item())
- role = QQuickItemPrivate::get(item())->accessibleRole();
+ role = QQuickItemPrivate::get(item())->effectiveAccessibleRole();
if (role == QAccessible::NoRole) {
if (qobject_cast<QQuickText*>(const_cast<QQuickItem *>(item())))
role = QAccessible::StaticText;
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index c370d6e5c3..9e8b289376 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -2400,7 +2400,7 @@ bool QQuickItemPrivate::canAcceptTabFocus(QQuickItem *item)
return true;
#if QT_CONFIG(accessibility)
- QAccessible::Role role = QQuickItemPrivate::get(item)->accessibleRole();
+ QAccessible::Role role = QQuickItemPrivate::get(item)->effectiveAccessibleRole();
if (role == QAccessible::EditableText || role == QAccessible::Table || role == QAccessible::List) {
return true;
} else if (role == QAccessible::ComboBox || role == QAccessible::SpinBox) {
@@ -9000,13 +9000,20 @@ QQuickItemPrivate::ExtraData::ExtraData()
#if QT_CONFIG(accessibility)
-QAccessible::Role QQuickItemPrivate::accessibleRole() const
+QAccessible::Role QQuickItemPrivate::effectiveAccessibleRole() const
{
Q_Q(const QQuickItem);
- QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(qmlAttachedPropertiesObject<QQuickAccessibleAttached>(q, false));
- if (accessibleAttached)
- return accessibleAttached->role();
+ auto *attached = qmlAttachedPropertiesObject<QQuickAccessibleAttached>(q, false);
+ auto role = QAccessible::NoRole;
+ if (auto *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(attached))
+ role = accessibleAttached->role();
+ if (role == QAccessible::NoRole)
+ role = accessibleRole();
+ return role;
+}
+QAccessible::Role QQuickItemPrivate::accessibleRole() const
+{
return QAccessible::NoRole;
}
#endif
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index ade8fb61f2..6f329bd119 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -575,7 +575,10 @@ public:
virtual void implicitHeightChanged();
#if QT_CONFIG(accessibility)
+ QAccessible::Role effectiveAccessibleRole() const;
+private:
virtual QAccessible::Role accessibleRole() const;
+public:
#endif
void setImplicitAntialiasing(bool antialiasing);
--
2.40.1

View File

@ -0,0 +1,57 @@
From 5352f113b3c7a5af2ad2741d593c6e6a758eb93e Mon Sep 17 00:00:00 2001
From: Shawn Rutledge <shawn.rutledge@qt.io>
Date: Tue, 16 May 2023 07:59:46 +0200
Subject: [PATCH 26/26] qml tool: Use QCommandLineParser::process() rather than
parse()
This handles the --version, --help and --help-all options.
Apparently there's no other way to handle --help-all, because
addHelpOption() adds two options but only returns one of them.
Amends bb6602bca2b20d98f24320b10c7a039e605c9a05
Fixes: QTBUG-100678
Pick-to: 6.2 6.5 5.15
Change-Id: Iddd1ba2dae975d7256935d8d357e2f3ac6c013d6
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit e5007fcc43af6751c72ec970eed11df5fdb8638e)
* asturmlechner 2023-05-18: Resolve conflict with dev branch commit
a15472716dbef63f1e5ad27ee412c2a2408b44e2
---
tools/qml/main.cpp | 13 +++----------
1 file changed, 3 insertions(+), 10 deletions(-)
diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp
index beeec88f07..2cb7653d65 100644
--- a/tools/qml/main.cpp
+++ b/tools/qml/main.cpp
@@ -446,8 +446,8 @@ int main(int argc, char *argv[])
QCommandLineParser parser;
parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
parser.setOptionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsPositionalArguments);
- const QCommandLineOption helpOption = parser.addHelpOption();
- const QCommandLineOption versionOption = parser.addVersionOption();
+ parser.addHelpOption();
+ parser.addVersionOption();
#ifdef QT_GUI_LIB
QCommandLineOption apptypeOption(QStringList() << QStringLiteral("a") << QStringLiteral("apptype"),
QCoreApplication::translate("main", "Select which application class to use. Default is gui."),
@@ -522,14 +522,7 @@ int main(int argc, char *argv[])
parser.addPositionalArgument("args",
QCoreApplication::translate("main", "Arguments after '--' are ignored, but passed through to the application.arguments variable in QML."), "[-- args...]");
- if (!parser.parse(QCoreApplication::arguments())) {
- qWarning() << parser.errorText();
- exit(1);
- }
- if (parser.isSet(versionOption))
- parser.showVersion();
- if (parser.isSet(helpOption))
- parser.showHelp();
+ parser.process(*app);
if (parser.isSet(listConfOption))
listConfFiles();
if (applicationType == QmlApplicationTypeUnknown) {
--
2.40.1

View File

@ -0,0 +1,44 @@
From e2bdde18d9758efdc6a0d7d106aad56995df1271 Mon Sep 17 00:00:00 2001
From: Ulf Hermann <ulf.hermann@qt.io>
Date: Wed, 15 Mar 2023 08:59:43 +0100
Subject: [PATCH] JIT: Add missing {STORE|LOAD}_ACC() to CreateCallContext
We cannot assume anything about the accumulator register after calling
PushCallContext::call(). Also add a note about not needing to re-load
the accumulator on ThrowException.
Pick-to: 6.5 6.2 5.15
Fixes: QTBUG-111935
Change-Id: I7196585e1d2697c215f4fe87d8d7ac9b98b622a3
---
src/qml/jit/qv4baselinejit.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/qml/jit/qv4baselinejit.cpp b/src/qml/jit/qv4baselinejit.cpp
index 14e183adb8..1d65169dce 100644
--- a/src/qml/jit/qv4baselinejit.cpp
+++ b/src/qml/jit/qv4baselinejit.cpp
@@ -506,6 +506,8 @@ void BaselineJIT::generate_ThrowException()
as->passEngineAsArg(0);
BASELINEJIT_GENERATE_RUNTIME_CALL(ThrowException, CallResultDestination::Ignore);
as->gotoCatchException();
+
+ // LOAD_ACC(); <- not needed here since it would be unreachable.
}
void BaselineJIT::generate_GetException() { as->getException(); }
@@ -513,9 +515,11 @@ void BaselineJIT::generate_SetException() { as->setException(); }
void BaselineJIT::generate_CreateCallContext()
{
+ STORE_ACC();
as->prepareCallWithArgCount(1);
as->passCppFrameAsArg(0);
BASELINEJIT_GENERATE_RUNTIME_CALL(PushCallContext, CallResultDestination::Ignore);
+ LOAD_ACC();
}
void BaselineJIT::generate_PushCatchContext(int index, int name) { as->pushCatchContext(index, name); }
--
2.39.2

View File

@ -0,0 +1,25 @@
diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp
index 76daead8..4f707703 100644
--- a/src/qml/jsruntime/qv4regexp.cpp
+++ b/src/qml/jsruntime/qv4regexp.cpp
@@ -37,6 +37,7 @@
**
****************************************************************************/
+#include <limits>
#include "qv4regexp_p.h"
#include "qv4engine_p.h"
#include "qv4scopedvalue_p.h"
diff --git a/src/qmldebug/qqmlprofilerevent_p.h b/src/qmldebug/qqmlprofilerevent_p.h
index a7e37d19..21c3b465 100644
--- a/src/qmldebug/qqmlprofilerevent_p.h
+++ b/src/qmldebug/qqmlprofilerevent_p.h
@@ -40,6 +40,8 @@
#ifndef QQMLPROFILEREVENT_P_H
#define QQMLPROFILEREVENT_P_H
+#include <limits>
+
#include "qqmlprofilerclientdefinitions_p.h"
#include <QtCore/qstring.h>

View File

@ -1,41 +1,108 @@
%global __provides_exclude_from ^%{_qt5_archdatadir}/qml/.*\\.so$
%define _lto_cflags %{nil}
%global qt_module qtdeclarative
%global multilib_archs x86_64 %{ix86} %{?mips} ppc64 ppc s390x s390 sparc64 sparcv9
Name: qt5-qtdeclarative
Version: 5.11.1
Release: 6
License: LGPLv2 with exceptions or GPLv3 with exceptions
Summary: Qt5 module for declarative framework
Name: qt5-%{qt_module}
Version: 5.15.10
Release: 1
Summary: Qt5 - QtDeclarative component
License: LGPL-3.0-only OR GPL-3.0-only WITH Qt-GPL-exception-1.0
Url: http://www.qt.io
Source0: https://download.qt.io/new_archive/qt/5.11/%{version}/submodules/qtdeclarative-everywhere-src-%{version}.tar.xz
Source1: qv4global_p-multilib.h
Patch0001: qtdeclarative-opensource-src-5.11.0-no_sse2.patch
Obsoletes: qt5-qtjsbackend < 5.2.0 qt5-qtdeclarative-render2d < 5.7.1-10
BuildRequires: gcc-c++ qt5-rpm-macros >= %{version} qt5-qtbase-devel >= %{version}
BuildRequires: qt5-qtbase-private-devel qt5-qtxmlpatterns-devel >= %{version} python3 python2
%{?_qt5:Requires: %{_qt5} = %{_qt5_version}}
%global majmin %(echo %{version} | cut -d. -f1-2)
Source0: https://download.qt.io/official_releases/qt/%{majmin}/%{version}/submodules/%{qt_module}-everywhere-opensource-src-%{version}.tar.xz
Source5: qv4global_p-multilib.h
Patch1: 0001-Remove-unused-QPointer-QQuickPointerMask.patch
Patch2: 0002-QQmlDelegateModel-Refresh-the-view-when-a-column-is-.patch
Patch3: 0003-Fix-TapHandler-so-that-it-actually-registers-a-tap.patch
Patch4: 0004-Revert-Fix-TapHandler-so-that-it-actually-registers-.patch
Patch5: 0005-Make-sure-QQuickWidget-and-its-offscreen-window-s-sc.patch
Patch6: 0006-QQuickItem-Guard-against-cycles-in-nextPrevItemInTab.patch
Patch7: 0007-Don-t-convert-QByteArray-in-startDrag.patch
Patch8: 0008-Fix-build-after-95290f66b806a307b8da1f72f8fc2c698019.patch
Patch9: 0009-Implement-accessibility-for-QQuickWidget.patch
Patch10: 0010-Send-ObjectShow-event-for-visible-components-after-i.patch
Patch11: 0011-QQuickItem-avoid-emitting-signals-during-destruction.patch
Patch12: 0012-a11y-track-item-enabled-state.patch
Patch13: 0013-Make-QaccessibleQuickWidget-private-API.patch
Patch14: 0014-Qml-Don-t-crash-when-as-casting-to-type-with-errors.patch
Patch15: 0015-Fix-missing-glyphs-when-using-NativeRendering.patch
Patch16: 0016-Revert-Fix-missing-glyphs-when-using-NativeRendering.patch
Patch17: 0017-QQmlImportDatabase-Make-sure-the-newly-added-import-.patch
Patch18: 0018-QQuickState-when-handle-QJSValue-properties-correctl.patch
Patch19: 0019-Models-Avoid-crashes-when-deleting-cache-items.patch
Patch20: 0020-qv4function-Fix-crash-due-to-reference-being-invalid.patch
Patch21: 0021-Quick-Animations-Fix-crash.patch
Patch22: 0022-Prevent-crash-when-destroying-asynchronous-Loader.patch
Patch23: 0023-QQuickItem-Fix-effective-visibility-for-items-withou.patch
Patch24: 0024-Revert-QQuickItem-Fix-effective-visibility-for-items.patch
Patch25: 0025-Accessibility-respect-value-in-attached-Accessible-i.patch
Patch26: 0026-qml-tool-Use-QCommandLineParser-process-rather-than-.patch
Patch100: %{name}-gcc11.patch
Patch101: qtdeclarative-5.15.0-FixMaxXMaxYExtent.patch
Patch102: qt-QTBUG-111935-fix-V4-jit.patch
# filter qml provides
Obsoletes: qt5-qtjsbackend < 5.2.0
Obsoletes: qt5-qtdeclarative-render2d < 5.7.1-10
BuildRequires: make
BuildRequires: gcc-c++
BuildRequires: qt5-rpm-macros
BuildRequires: qt5-qtbase-devel >= %{version}
BuildRequires: qt5-qtbase-private-devel
%{?_qt5:Requires: %{_qt5}%{?_isa} = %{_qt5_version}}
BuildRequires: python%{python3_pkgversion}
%if 0%{?bootstrap}
Obsoletes: %{name}-examples < %{version}-%{release}
%global no_examples CONFIG-=compile_examples
%endif
%if 0%{?tests}
BuildRequires: dbus-x11 mesa-dri-drivers time xorg-x11-server-Xvfb
BuildRequires: dbus-x11
BuildRequires: mesa-dri-drivers
BuildRequires: time
BuildRequires: xorg-x11-server-Xvfb
%endif
%description
This package contains base tools, like string, xml, and network handling.
%{summary}.
%package devel
Summary: Library and header files of %{name}
Requires: %{name} = %{version}-%{release} qt5-qtbase-devel
Summary: Development files for %{name}
Obsoletes: qt5-qtjsbackend-devel < 5.2.0
Obsoletes: qt5-qtdeclarative-render2d-devel < 5.7.1-10
Provides: %{name}-private-devel = %{version}-%{release}
Provides: %{name}-static = %{version}-%{release} %{name}-examples = %{version}-%{release}
Obsoletes: qt5-qtjsbackend-devel < 5.2.0 qt5-qtdeclarative-render2d-devel < 5.7.1-10
Obsoletes: %{name}-static < %{version}-%{release} %{name}-examples < %{version}-%{release}
Requires: %{name}%{?_isa} = %{version}-%{release}
Requires: qt5-qtbase-devel%{?_isa}
%description devel
%{name}-devel provides libraries and header files for %{name}.
%{summary}.
%package static
Summary: Static library files for %{name}
Requires: %{name}-devel%{?_isa} = %{version}-%{release}
%description static
%{summary}.
%package examples
Summary: Programming examples for %{name}
Requires: %{name}%{?_isa} = %{version}-%{release}
%description examples
%{summary}.
%prep
%setup -q -n qtdeclarative-everywhere-src-%{version}
%autosetup -n qtdeclarative-everywhere-src-%{version} -p1
%build
#HACK so calls to "python" get what we want
ln -s %{__python3} python
export PATH=`pwd`:$PATH
%qmake_qt5
@ -44,58 +111,69 @@ Obsoletes: %{name}-static < %{version}-%{release} %{name}-examples < %{ve
%install
%make_install INSTALL_ROOT=%{buildroot}
%ifarch x86_64
pushd %{buildroot}%{_qt5_headerdir}/QtQml/%{version}/QtQml/private
mv qv4global_p.h qv4global_p-%{__isa_bits}.h
popd
install -p -m644 -D %{SOURCE1} %{buildroot}%{_qt5_headerdir}/QtQml/%{version}/QtQml/private/qv4global_p.h
%ifarch %{multilib_archs}
# multilib: qv4global_p.h
mv %{buildroot}%{_qt5_headerdir}/QtQml/%{version}/QtQml/private/qv4global_p.h \
%{buildroot}%{_qt5_headerdir}/QtQml/%{version}/QtQml/private/qv4global_p-%{__isa_bits}.h
install -p -m644 -D %{SOURCE5} %{buildroot}%{_qt5_headerdir}/QtQml/%{version}/QtQml/private/qv4global_p.h
%endif
install -d %{buildroot}%{_bindir}
# hardlink files to %{_bindir}, add -qt5 postfix to not conflict
mkdir %{buildroot}%{_bindir}
pushd %{buildroot}%{_qt5_bindir}
for file in * ; do
case "${file}" in
for i in * ; do
case "${i}" in
# qt4 conflicts
qmlplugindump|qmlprofiler)
ln -v ${file} %{buildroot}%{_bindir}/${file}-qt5
ln -sv ${file} ${file}-qt5
ln -v ${i} %{buildroot}%{_bindir}/${i}-qt5
ln -sv ${i} ${i}-qt5
;;
qml|qmlbundle|qmlmin|qmlscene)
ln -v ${file} %{buildroot}%{_bindir}/${file}
ln -v ${file} %{buildroot}%{_bindir}/${file}-qt5
ln -sv ${file} ${file}-qt5
ln -v ${i} %{buildroot}%{_bindir}/${i}
ln -v ${i} %{buildroot}%{_bindir}/${i}-qt5
ln -sv ${i} ${i}-qt5
;;
*)
ln -v ${file} %{buildroot}%{_bindir}/${file}
ln -v ${i} %{buildroot}%{_bindir}/${i}
;;
esac
done
popd
pushd %{buildroot}%{_qt5_libdir}
for file in libQt5*.prl ; do
sed -i -e "/^QMAKE_PRL_BUILD_DIR/d" ${file}
rm -fv "$(basename ${file} .prl).la"
sed -i -e "/^QMAKE_PRL_LIBS/d" ${file}
for prl_file in libQt5*.prl ; do
sed -i -e "/^QMAKE_PRL_BUILD_DIR/d" ${prl_file}
rm -fv "$(basename ${prl_file} .prl).la"
sed -i -e "/^QMAKE_PRL_LIBS/d" ${prl_file}
done
popd
%check
%if 0%{?tests}
export CTEST_OUTPUT_ON_FAILURE=1
export PATH=%{buildroot}%{_qt5_bindir}:$PATH
export LD_LIBRARY_PATH=%{buildroot}%{_qt5_libdir}
export CTEST_OUTPUT_ON_FAILURE=1 PATH=%{buildroot}%{_qt5_bindir}:$PATH
make sub-tests-all %{?_smp_mflags}
xvfb-run -a dbus-launch --exit-with-session time \
xvfb-run -a \
dbus-launch --exit-with-session \
time \
make check -k -C tests ||:
%endif
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%ldconfig_scriptlets
%files
%license LICENSE.LGPL*
%{_qt5_libdir}/libQt5Qml.so.5*
%{_qt5_libdir}/libQt5Quick*.so.5*
%{_qt5_libdir}/libQt5QmlModels.so.5*
%{_qt5_libdir}/libQt5QmlWorkerScript.so.5*
%{_qt5_libdir}/libQt5Quick.so.5*
%{_qt5_libdir}/libQt5QuickWidgets.so.5*
%{_qt5_libdir}/libQt5QuickParticles.so.5*
%{_qt5_libdir}/libQt5QuickShapes.so.5*
%{_qt5_libdir}/libQt5QuickTest.so.5*
%{_qt5_plugindir}/qmltooling/
%{_qt5_archdatadir}/qml/
@ -103,18 +181,51 @@ make check -k -C tests ||:
%{_bindir}/qml*
%{_qt5_bindir}/qml*
%{_qt5_headerdir}/Qt*/
%{_qt5_libdir}/pkgconfig/Qt5*.pc
%{_qt5_libdir}/libQt5Qml*.{a,so,prl}
%{_qt5_libdir}/libQt5Quick*.{so,prl}
%{_qt5_libdir}/libQt5Qml.so
%{_qt5_libdir}/libQt5Qml.prl
%{_qt5_libdir}/libQt5QmlModels.so
%{_qt5_libdir}/libQt5QmlModels.prl
%{_qt5_libdir}/libQt5QmlWorkerScript.so
%{_qt5_libdir}/libQt5QmlWorkerScript.prl
%{_qt5_libdir}/libQt5Quick*.so
%{_qt5_libdir}/libQt5Quick*.prl
%dir %{_qt5_libdir}/cmake/Qt5Quick*/
%{_qt5_libdir}/cmake/Qt5*/Qt5*Config*.cmake
%{_qt5_libdir}/libQt5PacketProtocol.{a,prl}
%{_qt5_libdir}/metatypes/qt5*_metatypes.json
%{_qt5_libdir}/pkgconfig/Qt5*.pc
%{_qt5_archdatadir}/mkspecs/modules/*.pri
%{_qt5_archdatadir}/mkspecs/features/*.prf
%dir %{_qt5_libdir}/cmake/Qt5Qml/
%{_qt5_libdir}/cmake/Qt5Qml/Qt5Qml_*Factory.cmake
%{_qt5_archdatadir}/mkspecs/{modules/*.pri,features/*.prf}
%dir %{_qt5_libdir}/cmake/{Qt5Qml/,Qt5Quick*/}
%{_qt5_libdir}/cmake/Qt5QmlImportScanner/
%files static
%{_qt5_libdir}/libQt5QmlDevTools.a
%{_qt5_libdir}/libQt5QmlDevTools.prl
%{_qt5_libdir}/libQt5PacketProtocol.a
%{_qt5_libdir}/libQt5PacketProtocol.prl
%{_qt5_libdir}/libQt5QmlDebug.a
%{_qt5_libdir}/libQt5QmlDebug.prl
%if ! 0%{?no_examples:1}
%files examples
%{_qt5_examplesdir}/
%endif
%changelog
* Mon Aug 21 2023 huayadong <huayadong@kylinos.cn> - 5.15.10-1
- update to version 5.15.10-1
* Fri Jan 7 2022 peijiankang <peijiankang@kylinos.cn> - 5.15.2-2
- rm qt5-qtdeclarative-5.15.2-7.eln112.src.rpm
* Wed Oct 13 2021 peijiankang <peijiankang@kylinos.cn> - 5.15.2-1
- update to upstream version 5.15.2
* Tue Oct 27 2020 wangxiao <wangxiao65@huawei.com> - 5.11.1-7
- delete python2 buildrequires
* Mon Sep 14 2020 liuweibo <liuweibo10@huawei.com> - 5.11.1-6
- Fix Source0

View File

@ -1,4 +1,4 @@
version_control: github
src_repo: qt/qtdeclarative
tag_prefix: ^v
seperator: .
src_repo: https://code.qt.io/qt/qtdeclarative.git
tag_prefix: "^v"
separator: "."

View File

@ -0,0 +1,46 @@
Parent: f5a4e984 (QQuickTextInputPrivate: refactor getImplicitWidth() to calculateImplicitWidth())
Author: David Redondo <qt@david-redondo.de>
AuthorDate: 2020-05-13 11:04:23 +0200
Commit: Mitch Curtis <mitch.curtis@qt.io>
CommitDate: 2020-05-25 10:58:35 +0200
QQuickItemView: Fix max(X/Y)Extent()
QQuickFlickable maxXExtent() and maxYExtent() return the amount of space
that is not shown when inside a ScrollView. QQuickItemView however just
returned width() if vertical and height() if horizontal. In these cases
just defer to the QQuickFlickable base implementation like minXExtent()
and minYExtent() already do.
This change also adds tst_qquicklistview2 to speed up development.
tst_QQuickListView is almost 9000 lines long, and compiling it
is slow. In addition, a similar approach (creating a second test to
avoid the slowness of a massive one) already exists for QQuickItem
tests.
Fixes: QTBUG-83890
Pick-to: 5.15
Change-Id: I7f4060c2f46ae07611bedceca0d322c5f7f6affb
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 2b4ca9e2..f2feba2a 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -1393,7 +1393,7 @@ qreal QQuickItemView::maxYExtent() const
{
Q_D(const QQuickItemView);
if (d->layoutOrientation() == Qt::Horizontal)
- return height();
+ return QQuickFlickable::maxYExtent();
if (d->vData.maxExtentDirty) {
d->maxExtent = d->maxExtentForAxis(d->vData, false);
@@ -1421,7 +1421,7 @@ qreal QQuickItemView::maxXExtent() const
{
Q_D(const QQuickItemView);
if (d->layoutOrientation() == Qt::Vertical)
- return width();
+ return QQuickFlickable::maxXExtent();
if (d->hData.maxExtentDirty) {
d->maxExtent = d->maxExtentForAxis(d->hData, true);

View File

@ -1,39 +0,0 @@
diff -up qtdeclarative-everywhere-src-5.11.0/src/qml/jsruntime/jsruntime.pri.no_sse2 qtdeclarative-everywhere-src-5.11.0/src/qml/jsruntime/jsruntime.pri
--- qtdeclarative-everywhere-src-5.11.0/src/qml/jsruntime/jsruntime.pri.no_sse2 2018-04-30 06:54:03.000000000 -0500
+++ qtdeclarative-everywhere-src-5.11.0/src/qml/jsruntime/jsruntime.pri 2018-05-24 16:15:51.151738531 -0500
@@ -115,6 +115,11 @@ SOURCES += \
$$PWD/qv4value.cpp \
$$PWD/qv4executableallocator.cpp
+linux-g++*:isEqual(QT_ARCH,i386):!no_sse2 {
+ QMAKE_CFLAGS += -msse2 -mfpmath=sse
+ QMAKE_CXXFLAGS += -msse2 -mfpmath=sse
+}
+
valgrind {
DEFINES += V4_USE_VALGRIND
}
diff -up qtdeclarative-everywhere-src-5.11.0/src/qml/jsruntime/qv4global_p.h.no_sse2 qtdeclarative-everywhere-src-5.11.0/src/qml/jsruntime/qv4global_p.h
--- qtdeclarative-everywhere-src-5.11.0/src/qml/jsruntime/qv4global_p.h.no_sse2 2018-04-30 06:54:03.000000000 -0500
+++ qtdeclarative-everywhere-src-5.11.0/src/qml/jsruntime/qv4global_p.h 2018-05-24 20:23:38.642642420 -0500
@@ -88,7 +88,7 @@ inline double trunc(double d) { return d
//
// NOTE: This should match the logic in qv4targetplatform_p.h!
-#if defined(Q_PROCESSOR_X86) && (QT_POINTER_SIZE == 4) \
+#if defined(Q_PROCESSOR_X86) && (QT_POINTER_SIZE == 4) && defined(__SSE2__) \
&& (defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_QNX) || defined(Q_OS_FREEBSD))
# define V4_ENABLE_JIT
#elif defined(Q_PROCESSOR_X86_64) && (QT_POINTER_SIZE == 8) \
diff -up qtdeclarative-everywhere-src-5.11.0/src/qml/qml/v8/qv8engine.cpp.no_sse2 qtdeclarative-everywhere-src-5.11.0/src/qml/qml/v8/qv8engine.cpp
--- qtdeclarative-everywhere-src-5.11.0/src/qml/qml/v8/qv8engine.cpp.no_sse2 2018-05-24 16:15:51.152738550 -0500
+++ qtdeclarative-everywhere-src-5.11.0/src/qml/qml/v8/qv8engine.cpp 2018-05-24 20:21:01.273574503 -0500
@@ -131,7 +131,7 @@ QV8Engine::QV8Engine(QJSEngine *qq, QV4:
{
#ifdef Q_PROCESSOR_X86_32
if (!qCpuHasFeature(SSE2)) {
- qFatal("This program requires an X86 processor that supports SSE2 extension, at least a Pentium 4 or newer");
+ qDebug("This program requires an X86 processor that supports SSE2 extension, at least a Pentium 4 or newer, processors missing the extension are NOT supported to run QML2 code!");
}
#endif