This commit is contained in:
Jan Grulich 2023-01-05 13:09:21 +01:00
parent 66e09911dc
commit dc0953b5e1
28 changed files with 1031 additions and 682 deletions

1
.gitignore vendored
View File

@ -12,3 +12,4 @@
/qtdeclarative-everywhere-opensource-src-5.15.5.tar.xz
/qtdeclarative-everywhere-opensource-src-5.15.6.tar.xz
/qtdeclarative-everywhere-opensource-src-5.15.7.tar.xz
/qtdeclarative-everywhere-opensource-src-5.15.8.tar.xz

View File

@ -1,7 +1,7 @@
From 43b6267d024afd655a8c0c8c833f71850d7a8bb9 Mon Sep 17 00:00:00 2001
From 3f272e04492cd884deb4e7948e39b749809d5256 Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <albert.astals.cid@kdab.com>
Date: Fri, 21 May 2021 13:17:15 +0200
Subject: [PATCH 01/18] Document that StyledText also supports &nbsp; and
Subject: [PATCH 01/21] Document that StyledText also supports &nbsp; and
&quot;
Change-Id: I1715f8ae8ec8d0fbaf6dbe2b8663cc169da663cd
@ -25,5 +25,5 @@ index 6230186933..c1571fc6f5 100644
\c Text.StyledText parser is strict, requiring tags to be correctly nested.
--
2.37.3
2.39.0

View File

@ -1,7 +1,7 @@
From 8e28af8076873503bbf036487aaf7310407a2f11 Mon Sep 17 00:00:00 2001
From bf4b4f3dfb3534e7919c50faa60a0fe7fbcdacf5 Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <albert.astals.cid@kdab.com>
Date: Fri, 21 May 2021 13:42:35 +0200
Subject: [PATCH 02/18] Support &apos; in styled text
Subject: [PATCH 02/21] Support &apos; in styled text
Pick-to: 6.1 5.15
Change-Id: I4a8db963e52a7899ab1796f9a560e8029cc1c929
@ -40,5 +40,5 @@ index d531fc9205..a25af90414 100644
textOut += QChar(34);
else if (entity == QLatin1String("nbsp"))
--
2.37.3
2.39.0

View File

@ -1,7 +1,7 @@
From 0f3b328766038c1161f4f613a0bf3a4fcbdb4cef Mon Sep 17 00:00:00 2001
From da206ac99b58218a1e51a2e75032647d24cd0fdb 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 03/18] Remove unused QPointer<QQuickPointerMask>
Subject: [PATCH 03/21] Remove unused QPointer<QQuickPointerMask>
Change-Id: I009fa6bbd8599dc3bb2e810176fe20e70ed50851
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
@ -31,5 +31,5 @@ index fba383e268..0d63618622 100644
QPointF targetStartPos;
QPointF lastPos;
--
2.37.3
2.39.0

View File

@ -1,7 +1,7 @@
From ad09b853a3a137127de847d4d6d55f73ab09899d Mon Sep 17 00:00:00 2001
From e61200ff7222c31e73dbc779ba4a70073775cc0c Mon Sep 17 00:00:00 2001
From: Aleix Pol <aleixpol@kde.org>
Date: Thu, 23 Sep 2021 03:43:04 +0200
Subject: [PATCH 04/18] QQmlDelegateModel: Refresh the view when a column is
Subject: [PATCH 04/21] 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
@ -174,5 +174,5 @@ index 35f1e2c94d..1722447830 100644
#include "tst_qqmldelegatemodel.moc"
--
2.37.3
2.39.0

View File

@ -1,7 +1,7 @@
From 55caf921033dc1f310c1d370a046908cb0a6bc57 Mon Sep 17 00:00:00 2001
From ab781c9f5364ddfab0bfe9626a9dd01bd6bc046e Mon Sep 17 00:00:00 2001
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
Date: Sun, 10 Oct 2021 21:04:21 +0300
Subject: [PATCH 05/18] Fix sweep step for tainted QObject JavaScript wrappers
Subject: [PATCH 05/21] Fix sweep step for tainted QObject JavaScript wrappers
Currently, whenever the garbage collector runs, it will destroy all
valid tainted wrappers.
@ -115,5 +115,5 @@ index 5d635aa63b..824fd89e5b 100644
// engine2 doesn't own the object as engine1 was the first to wrap it above.
// Therefore, no effect here.
--
2.37.3
2.39.0

View File

@ -1,7 +1,7 @@
From 7dd0d9f9ce9bbd5e21f017069256d52b397a6195 Mon Sep 17 00:00:00 2001
From b8f474a4dd5fa58edfba73e565499bcdad679291 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 07/18] Fix TapHandler so that it actually registers a tap
Subject: [PATCH 06/21] Fix TapHandler so that it actually registers a tap
This bug caused all quick examples that used the
shared\LauncherList.qml to be broken.
@ -69,5 +69,5 @@ index b51f53b74f..89081b4e84 100644
void QQuickSinglePointHandler::handlePointerEventImpl(QQuickPointerEvent *event)
--
2.37.3
2.39.0

View File

@ -1,71 +0,0 @@
From 1cb0de43684c7f23cd121d48ebd84a9da688c8ef Mon Sep 17 00:00:00 2001
From: Laszlo Agocs <laszlo.agocs@qt.io>
Date: Mon, 11 Oct 2021 15:37:33 +0200
Subject: [PATCH 06/18] Revert "Fix for possible crash in
QSGDefaultLayer::grab"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This reverts commit 1c5de027d0c31d1d6697bd0557128d92207763d8.
The fix here is not correct. Calling a QSGRhiLayer function from the gui
thread is very wrong and can cause a set of unexpected issues. The
Address Sanitizer catches this by recognizing that the render thread is
trying to do something with an object destroyed in the meantime on the
main thread in the layer->setItem(null) call.
The issue the original fix is trying to address needs to be addressed in
some different form.
Fixes: QTBUG-94975
Pick-to: 6.2 6.1 5.15
Change-Id: I46f904026281201fc6d233ed7d3bdc7080934afe
Reviewed-by: Christian Strømme <christian.stromme@qt.io>
(cherry picked from commit a5f0361622eb08eab6c3474d5fc249d1962e3d1e)
---
src/quick/items/qquickshadereffectsource.cpp | 8 --------
src/quick/items/qquickshadereffectsource_p.h | 1 -
2 files changed, 9 deletions(-)
diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp
index 4f61d61309..b298ed74da 100644
--- a/src/quick/items/qquickshadereffectsource.cpp
+++ b/src/quick/items/qquickshadereffectsource.cpp
@@ -344,7 +344,6 @@ void QQuickShaderEffectSource::setSourceItem(QQuickItem *item)
d->refFromEffectItem(m_hideSource);
d->addItemChangeListener(this, QQuickItemPrivate::Geometry);
connect(m_sourceItem, SIGNAL(destroyed(QObject*)), this, SLOT(sourceItemDestroyed(QObject*)));
- connect(m_sourceItem, SIGNAL(parentChanged(QQuickItem*)), this, SLOT(sourceItemParentChanged(QQuickItem*)));
} else {
qWarning("ShaderEffectSource: sourceItem and ShaderEffectSource must both be children of the same window.");
m_sourceItem = nullptr;
@@ -364,13 +363,6 @@ void QQuickShaderEffectSource::sourceItemDestroyed(QObject *item)
}
-void QQuickShaderEffectSource::sourceItemParentChanged(QQuickItem *parent)
-{
- if (!parent && m_texture)
- m_texture->setItem(0);
-}
-
-
/*!
\qmlproperty rect QtQuick::ShaderEffectSource::sourceRect
diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h
index 4deb6c70a3..c0a1ccab78 100644
--- a/src/quick/items/qquickshadereffectsource_p.h
+++ b/src/quick/items/qquickshadereffectsource_p.h
@@ -173,7 +173,6 @@ Q_SIGNALS:
private Q_SLOTS:
void sourceItemDestroyed(QObject *item);
void invalidateSceneGraph();
- void sourceItemParentChanged(QQuickItem *parent);
protected:
void releaseResources() override;
--
2.37.3

View File

@ -1,7 +1,7 @@
From ad102f786a12d0cc139bfbebea8edbab3dd8206d Mon Sep 17 00:00:00 2001
From de04cfb654a09fe7d0f8454b8a8de9243284e1d2 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 08/18] Revert "Fix TapHandler so that it actually registers a
Subject: [PATCH 07/21] Revert "Fix TapHandler so that it actually registers a
tap"
This reverts commit 36e8ccd434f948e4f11a8f9d59139ec072e41ff5.
@ -57,5 +57,5 @@ index 89081b4e84..b51f53b74f 100644
void QQuickSinglePointHandler::handlePointerEventImpl(QQuickPointerEvent *event)
--
2.37.3
2.39.0

View File

@ -1,7 +1,7 @@
From 2d11778ce9348716ce936ce11c89ced58d8ec188 Mon Sep 17 00:00:00 2001
From 99ada3c3d329b6d7136b0425841dcaa654c9c05b Mon Sep 17 00:00:00 2001
From: Marc Mutz <marc.mutz@qt.io>
Date: Tue, 21 Dec 2021 09:20:17 +0100
Subject: [PATCH 09/18] QQmlJs::FixedPoolArray: fix UB (precondition violation)
Subject: [PATCH 08/21] QQmlJs::FixedPoolArray: fix UB (precondition violation)
in allocate()
Says ubsan:
@ -32,5 +32,5 @@ index b65b994d6c..15a8cd6878 100644
}
}
--
2.37.3
2.39.0

View File

@ -1,7 +1,7 @@
From eb04ee7e02c5e7a2b84b129c09f13025242688d6 Mon Sep 17 00:00:00 2001
From b964ba12bf118afbbf42cd9e4e7b4903ad107060 Mon Sep 17 00:00:00 2001
From: Ulf Hermann <ulf.hermann@qt.io>
Date: Thu, 3 Feb 2022 10:02:06 +0100
Subject: [PATCH 10/18] V4: Do not call dtor of an object we continue to use
Subject: [PATCH 09/21] V4: Do not call dtor of an object we continue to use
After destroyObject(), the QObjectWrapper is still alive. We might use
its heap object again. Furthermore, the Heap::QObjectWrapper dtor does
@ -24,10 +24,10 @@ Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 9899c9274e..272b85069f 100644
index e57cdd8278..94613598af 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -1160,8 +1160,7 @@ void Heap::QObjectWrapper::markObjects(Heap::Base *that, QV4::MarkStack *markSta
@@ -1145,8 +1145,7 @@ void Heap::QObjectWrapper::markObjects(Heap::Base *that, QV4::MarkStack *markSta
void QObjectWrapper::destroyObject(bool lastCall)
{
Heap::QObjectWrapper *h = d();
@ -37,7 +37,7 @@ index 9899c9274e..272b85069f 100644
if (h->object()) {
QQmlData *ddata = QQmlData::get(h->object(), false);
@@ -1191,7 +1190,7 @@ void QObjectWrapper::destroyObject(bool lastCall)
@@ -1176,7 +1175,7 @@ void QObjectWrapper::destroyObject(bool lastCall)
}
}
@ -47,5 +47,5 @@ index 9899c9274e..272b85069f 100644
--
2.37.3
2.39.0

View File

@ -1,7 +1,7 @@
From 436f3c0550f64b4cb629480a6b7ceb1381f30501 Mon Sep 17 00:00:00 2001
From d8808a609a81660e9de9abc6b1b71ea01f0d6f40 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 11/18] Make sure QQuickWidget and its offscreen window's
Subject: [PATCH 10/21] Make sure QQuickWidget and its offscreen window's
screens are always in sync
By default, the offscreen window is placed on the primary screen.
@ -80,5 +80,5 @@ index 39780f8de3..223d91f579 100644
case QEvent::Move:
d->updatePosition();
--
2.37.3
2.39.0

View File

@ -1,7 +1,7 @@
From 74c8c421763597f778313ea976fffdc03183226b Mon Sep 17 00:00:00 2001
From 052dba54ae335b42fdcd1c0c68c9fce0031ffe9e 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 12/18] QQuickItem: Guard against cycles in
Subject: [PATCH 11/21] QQuickItem: Guard against cycles in
nextPrevItemInTabFocusChain
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
@ -118,5 +118,5 @@ index c8f251dbe1..c8ef36ee68 100644
{
if (!qt_tab_all_widgets())
--
2.37.3
2.39.0

View File

@ -1,7 +1,7 @@
From 76113c63af23d516f488f5e6b9062ca97e062e9e Mon Sep 17 00:00:00 2001
From f9faa4cfa0dbbac12cdf79e56a02b9aa0022018c Mon Sep 17 00:00:00 2001
From: Marc Mutz <marc.mutz@kdab.com>
Date: Tue, 16 Jul 2019 11:23:37 +0200
Subject: [PATCH 13/18] QSGOpenGLDistanceFieldGlyphCache: fix multiplication
Subject: [PATCH 12/21] QSGOpenGLDistanceFieldGlyphCache: fix multiplication
result truncation
The type of the expression int * int is int, so truncation has already
@ -26,7 +26,7 @@ Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
index 53b6fe117f..f7cb8bede3 100644
index eb4db0f85e..2c9868b335 100644
--- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
+++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
@@ -512,7 +512,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
@ -39,5 +39,5 @@ index 53b6fe117f..f7cb8bede3 100644
qWarning("qtdf table too small in font '%s'.",
qPrintable(font.familyName()));
--
2.37.3
2.39.0

View File

@ -1,7 +1,7 @@
From 985358efb1e60a8ff493da4d6ca9056f63dc9982 Mon Sep 17 00:00:00 2001
From 6d844f0250d97acdf66fd0d9cdabd26588e72333 Mon Sep 17 00:00:00 2001
From: Marc Mutz <marc.mutz@kdab.com>
Date: Tue, 16 Jul 2019 11:31:01 +0200
Subject: [PATCH 14/18] QSGOpenGLDistanceFieldGlyphCache: fix UB (ordering of
Subject: [PATCH 13/21] QSGOpenGLDistanceFieldGlyphCache: fix UB (ordering of
pointers not from the same array)
The code performed out of bounds checks by adding the size of the
@ -33,7 +33,7 @@ Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
index f7cb8bede3..219cdd5966 100644
index 2c9868b335..2325a2665b 100644
--- a/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
+++ b/src/quick/scenegraph/qsgrhidistancefieldglyphcache.cpp
@@ -446,7 +446,7 @@ bool QSGRhiDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
@ -64,5 +64,5 @@ index f7cb8bede3..219cdd5966 100644
qPrintable(font.familyName()));
return false;
--
2.37.3
2.39.0

View File

@ -1,7 +1,7 @@
From 10d77845723f1e7fa60bbb0f60f708949f3a538c Mon Sep 17 00:00:00 2001
From 5f183c1a7b2afbe50b4071e6a862c1a6d53de7fb Mon Sep 17 00:00:00 2001
From: Tony Leinonen <tony.leinonen@qt.io>
Date: Thu, 21 Oct 2021 14:44:02 +0300
Subject: [PATCH 17/18] Reset currentChanges if currentChanges is active when
Subject: [PATCH 14/21] Reset currentChanges if currentChanges is active when
refilling listView
currentIndex was not getting updated because itemViewChangeSet was left
@ -21,7 +21,7 @@ Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 13e7b87049..c8ea286d3e 100644
index 010a0152e1..f8ad168a17 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -1785,7 +1785,7 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to)
@ -34,5 +34,5 @@ index 13e7b87049..c8ea286d3e 100644
bufferedChanges.reset();
releaseVisibleItems(reusableFlag);
--
2.37.3
2.39.0

View File

@ -0,0 +1,60 @@
From 4884d7f5a3dbfddd865b594db51eeb4272565f76 Mon Sep 17 00:00:00 2001
From: Fushan Wen <qydwhotmail@gmail.com>
Date: Tue, 1 Nov 2022 22:35:24 +0800
Subject: [PATCH 15/21] 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.39.0

View File

@ -1,423 +0,0 @@
From 8dbc2a0a112752ab85c688ba66e86e5598896aae Mon Sep 17 00:00:00 2001
From: Shawn Rutledge <shawn.rutledge@qt.io>
Date: Tue, 4 May 2021 10:12:39 +0200
Subject: [PATCH 15/18] Fix Flickable wheel velocity calculation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Angular velocity is defined as angle rotated divided by time elapsed.
But the historical problem with Flickable is that the calculation
ignored time, as if there was a maximum frequency of events and we
only needed to know the rotation angle per fixed unit of time.
With "clicky" mouse wheels perhaps it was a reasonable approximation.
With touchpads that provide pixel deltas, we've been doing the velocity
calculation the right way since a6ed830f4779e218b8e8f8d82dc4aa9b4b4528a1
Now we divide by dt also in the wheel rotation case.
That gives instantaneous velocity. Next question: how to do smoothing?
AxisData::velocityBuffer is basically a Kalman filter, but until now
it was used only when dragging ends and we animate the deceleration from
the velocity at that time. It seems to work well for smoothing the
velocity that comes from wheel events, too. So now we use that instead
of smoothVelocity, and it stays in control better.
Next question: when a series of wheel events occurs, we have valid
dt for the dy / dt velocity calculation (or dx / dt horizontally),
but what about the initial flick? What if first thing the user does
is rotate a physical mouse wheel by one "click", how far should
Flickable move before it comes to rest? QStyleHints::wheelScrollLines()
tells us how far to move for one wheel event... in "lines", whatever
that is. Flickable doesn't know about its contents. But it "feels"
reasonable if we define a "line" as 24 pixels. At least the setting
will do something now: applications can adjust it, and some system
control panels can adjust it. A subclass of QQuickFlickable (such as
TableView) could even change QQFlickablePrivate::initialWheelFlickDistance
to be the actual number of pixels per "line", to scroll exactly by rows.
(But when the events occur faster, it moves further and faster, like it
always did.)
OK so we know how far we want to move when the Flickable is at rest
and receives a QWheelEvent with angleDelta of 120. I.e. when isMoving()
is false. So I tried an experiment: set dt to 0.25. How far did it move?
77 pixels. Why? We're making it move via QQuickFlickablePrivate::flick()
which does some math and drives the timeline. The key formula is
qreal dist = v2 / (accel * 2.0)
which agrees with the testing: if the wheel turns by 120 units,
(120 / 0.25)^2 / (1500 * 2) =~ 77
So it's possible to do the algebra to reverse-engineer what dt should be
so that we will move the right distance with a single wheel event,
despite the complexity of the animation itself. That's what is now
done. When the user rotates the wheel very slowly, it moves by discrete
amounts but with smooth animation. A little faster, and it speeds up,
somewhat like it did before, but with more control. If it has sped
up to a high speed and then the user rotates the wheel backwards,
it reverses instantly: we clear the Kalman filter and insert instantaneous
velocity (so it will go from there at the next event).
On a touchpad, it also feels quite in-control because the velocity
is calculated properly as distance-delta / time-delta. Smoothing
it out doesn't hurt, and animating after release doesn't hurt.
It longer goes "zing" out of control when the wheel events come in too
frequently from a touchpad or a free-spinning wheel.
None of this affects trackpads on macOS, because then the wheel events
have phases and pixel deltas, and we don't use this animation. We still
should try to get that working on as many OSes as possible, eventually.
Clarify the meaning of the flickDeceleration property.
[ChangeLog][QtQuick][Flickable] Flickable no longer tries to detect
whether you're using a "clicky" wheel or a touchpad, but rather does the
velocity calculation more correctly with elapsed time (dθ / dt).
A single rotation of a "clicky" wheel also moves a fixed distance,
which is now adjustable via QStyleHints::wheelScrollLines().
Animation is restored, but should now stay in control on touchpads;
and it will once again transition the "moving" properties correctly
when scrolling ends.
Fixes: QTBUG-56075
Pick-to: 6.2
Change-Id: I5166ca31c86335641cf407a922a3a970fced653d
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
(cherry picked from commit a8fbd865140d4dd165723c7e3d4168514d4b1d0c)
---
src/quick/items/qquickflickable.cpp | 95 +++++++++++++------
src/quick/items/qquickflickable_p_p.h | 1 +
src/quick/util/qquicktimeline.cpp | 3 +
.../qquickflickable/tst_qquickflickable.cpp | 9 +-
tests/manual/touch/flicktext.qml | 30 ++++++
5 files changed, 107 insertions(+), 31 deletions(-)
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index e12e85db64..9eea0e1487 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -263,7 +263,8 @@ QQuickFlickablePrivate::QQuickFlickablePrivate()
, deceleration(QML_FLICK_DEFAULTDECELERATION)
, maxVelocity(QML_FLICK_DEFAULTMAXVELOCITY), reportedVelocitySmoothing(100)
, delayedPressEvent(nullptr), pressDelay(0), fixupDuration(400)
- , flickBoost(1.0), fixupMode(Normal), vTime(0), visibleArea(nullptr)
+ , flickBoost(1.0), initialWheelFlickDistance(qApp->styleHints()->wheelScrollLines() * 24)
+ , fixupMode(Normal), vTime(0), visibleArea(nullptr)
, flickableDirection(QQuickFlickable::AutoFlickDirection)
, boundsBehavior(QQuickFlickable::DragAndOvershootBounds)
, boundsMovement(QQuickFlickable::FollowBoundsBehavior)
@@ -531,10 +532,14 @@ void QQuickFlickablePrivate::updateBeginningEnd()
if (atBeginning != vData.atBeginning) {
vData.atBeginning = atBeginning;
atYBeginningChange = true;
+ if (!vData.moving && atBeginning)
+ vData.smoothVelocity.setValue(0);
}
if (atEnd != vData.atEnd) {
vData.atEnd = atEnd;
atYEndChange = true;
+ if (!vData.moving && atEnd)
+ vData.smoothVelocity.setValue(0);
}
// Horizontal
@@ -547,10 +552,14 @@ void QQuickFlickablePrivate::updateBeginningEnd()
if (atBeginning != hData.atBeginning) {
hData.atBeginning = atBeginning;
atXBeginningChange = true;
+ if (!hData.moving && atBeginning)
+ hData.smoothVelocity.setValue(0);
}
if (atEnd != hData.atEnd) {
hData.atEnd = atEnd;
atXEndChange = true;
+ if (!hData.moving && atEnd)
+ hData.smoothVelocity.setValue(0);
}
if (vData.extentsChanged) {
@@ -1489,6 +1498,7 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event)
d->hData.velocity = 0;
d->timer.start();
d->maybeBeginDrag(currentTimestamp, event->position());
+ d->lastPosTime = -1;
break;
case Qt::NoScrollPhase: // default phase with an ordinary wheel mouse
case Qt::ScrollUpdate:
@@ -1515,20 +1525,34 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event)
return;
}
+ qreal elapsed = qreal(currentTimestamp - d->lastPosTime) / qreal(1000);
+ if (elapsed <= 0) {
+ d->lastPosTime = currentTimestamp;
+ qCDebug(lcWheel) << "insufficient elapsed time: can't calculate velocity" << elapsed;
+ return;
+ }
+
if (event->source() == Qt::MouseEventNotSynthesized || event->pixelDelta().isNull()) {
- // physical mouse wheel, so use angleDelta
+ // no pixel delta (physical mouse wheel, or "dumb" touchpad), so use angleDelta
int xDelta = event->angleDelta().x();
int yDelta = event->angleDelta().y();
+ // For a single "clicky" wheel event (angleDelta +/- 120),
+ // we want flick() to end up moving a distance proportional to QStyleHints::wheelScrollLines().
+ // The decel algo from there is
+ // qreal dist = v2 / (accel * 2.0);
+ // i.e. initialWheelFlickDistance = (120 / dt)^2 / (deceleration * 2)
+ // now solve for dt:
+ // dt = 120 / sqrt(deceleration * 2 * initialWheelFlickDistance)
+ if (!isMoving())
+ elapsed = 120 / qSqrt(d->deceleration * 2 * d->initialWheelFlickDistance);
if (yflick() && yDelta != 0) {
- bool valid = false;
- if (yDelta > 0 && contentY() > -minYExtent()) {
- d->vData.velocity = qMax(yDelta*2 - d->vData.smoothVelocity.value(), qreal(d->maxVelocity/4));
- valid = true;
- } else if (yDelta < 0 && contentY() < -maxYExtent()) {
- d->vData.velocity = qMin(yDelta*2 - d->vData.smoothVelocity.value(), qreal(-d->maxVelocity/4));
- valid = true;
- }
- if (valid) {
+ qreal instVelocity = yDelta / elapsed;
+ // if the direction has changed, start over with filtering, to allow instant movement in the opposite direction
+ if ((instVelocity < 0 && d->vData.velocity > 0) || (instVelocity > 0 && d->vData.velocity < 0))
+ d->vData.velocityBuffer.clear();
+ d->vData.addVelocitySample(instVelocity, d->maxVelocity);
+ d->vData.updateVelocity();
+ if ((yDelta > 0 && contentY() > -minYExtent()) || (yDelta < 0 && contentY() < -maxYExtent())) {
d->flickY(d->vData.velocity);
d->flickingStarted(false, true);
if (d->vData.flicking) {
@@ -1539,15 +1563,13 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event)
}
}
if (xflick() && xDelta != 0) {
- bool valid = false;
- if (xDelta > 0 && contentX() > -minXExtent()) {
- d->hData.velocity = qMax(xDelta*2 - d->hData.smoothVelocity.value(), qreal(d->maxVelocity/4));
- valid = true;
- } else if (xDelta < 0 && contentX() < -maxXExtent()) {
- d->hData.velocity = qMin(xDelta*2 - d->hData.smoothVelocity.value(), qreal(-d->maxVelocity/4));
- valid = true;
- }
- if (valid) {
+ qreal instVelocity = xDelta / elapsed;
+ // if the direction has changed, start over with filtering, to allow instant movement in the opposite direction
+ if ((instVelocity < 0 && d->hData.velocity > 0) || (instVelocity > 0 && d->hData.velocity < 0))
+ d->hData.velocityBuffer.clear();
+ d->hData.addVelocitySample(instVelocity, d->maxVelocity);
+ d->hData.updateVelocity();
+ if ((xDelta > 0 && contentX() > -minXExtent()) || (xDelta < 0 && contentX() < -maxXExtent())) {
d->flickX(d->hData.velocity);
d->flickingStarted(true, false);
if (d->hData.flicking) {
@@ -1562,18 +1584,13 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event)
int xDelta = event->pixelDelta().x();
int yDelta = event->pixelDelta().y();
- qreal elapsed = qreal(currentTimestamp - d->lastPosTime) / 1000.;
- if (elapsed <= 0) {
- d->lastPosTime = currentTimestamp;
- return;
- }
QVector2D velocity(xDelta / elapsed, yDelta / elapsed);
- d->lastPosTime = currentTimestamp;
d->accumulatedWheelPixelDelta += QVector2D(event->pixelDelta());
d->drag(currentTimestamp, event->type(), event->position(), d->accumulatedWheelPixelDelta,
true, !d->scrollingPhase, true, velocity);
event->accept();
}
+ d->lastPosTime = currentTimestamp;
if (!event->isAccepted())
QQuickItem::wheelEvent(event);
@@ -1744,6 +1761,10 @@ void QQuickFlickable::componentComplete()
setContentX(-minXExtent());
if (!d->vData.explicitValue && d->vData.startMargin != 0.)
setContentY(-minYExtent());
+ if (lcWheel().isDebugEnabled() || lcVel().isDebugEnabled()) {
+ d->timeline.setObjectName(QLatin1String("timeline for Flickable ") + objectName());
+ d->velocityTimeline.setObjectName(QLatin1String("velocity timeline for Flickable ") + objectName());
+ }
}
void QQuickFlickable::viewportMoved(Qt::Orientations orient)
@@ -2504,9 +2525,23 @@ void QQuickFlickable::setMaximumFlickVelocity(qreal v)
/*!
\qmlproperty real QtQuick::Flickable::flickDeceleration
- This property holds the rate at which a flick will decelerate.
-
- The default value is platform dependent.
+ This property holds the rate at which a flick will decelerate:
+ the higher the number, the faster it slows down when the user stops
+ flicking via touch, touchpad or mouse wheel. For example 0.0001 is nearly
+ "frictionless", and 10000 feels quite "sticky".
+
+ The default value is platform dependent. Values of zero or less are not allowed.
+
+ \note For touchpad flicking, some platforms drive Flickable directly by
+ sending QWheelEvents with QWheelEvent::phase() being \c Qt::ScrollMomentum,
+ after the user has released all fingers from the touchpad. In that case,
+ the operating system is controlling the deceleration, and this property has
+ no effect.
+
+ \note For mouse wheel scrolling, and for gesture scrolling on touchpads
+ that do not have a momentum phase, extremely large values of
+ flickDeceleration can make Flickable very resistant to scrolling,
+ especially if \l maximumFlickVelocity is too small.
*/
qreal QQuickFlickable::flickDeceleration() const
{
@@ -2519,7 +2554,7 @@ void QQuickFlickable::setFlickDeceleration(qreal deceleration)
Q_D(QQuickFlickable);
if (deceleration == d->deceleration)
return;
- d->deceleration = deceleration;
+ d->deceleration = qMax(0.001, deceleration);
emit flickDecelerationChanged();
}
diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
index 414c9c33d6..6163613493 100644
--- a/src/quick/items/qquickflickable_p_p.h
+++ b/src/quick/items/qquickflickable_p_p.h
@@ -241,6 +241,7 @@ public:
int pressDelay;
int fixupDuration;
qreal flickBoost;
+ qreal initialWheelFlickDistance;
enum FixupMode { Normal, Immediate, ExtentChanged };
FixupMode fixupMode;
diff --git a/src/quick/util/qquicktimeline.cpp b/src/quick/util/qquicktimeline.cpp
index 7ec7c827eb..abe6eb7261 100644
--- a/src/quick/util/qquicktimeline.cpp
+++ b/src/quick/util/qquicktimeline.cpp
@@ -53,6 +53,8 @@
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcTl, "qt.quick.timeline")
+
struct Update {
Update(QQuickTimeLineValue *_g, qreal _v)
: g(_g), v(_v) {}
@@ -513,6 +515,7 @@ void QQuickTimeLine::reset(QQuickTimeLineValue &timeLineValue)
qWarning() << "QQuickTimeLine: Cannot reset a QQuickTimeLineValue owned by another timeline.";
return;
}
+ qCDebug(lcTl) << static_cast<QObject*>(this) << timeLineValue.value();
remove(&timeLineValue);
timeLineValue._t = nullptr;
}
diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
index f3659290eb..9fa51da6f8 100644
--- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
+++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
@@ -870,6 +870,7 @@ void tst_qquickflickable::wheel()
QVERIFY(flick != nullptr);
QQuickFlickablePrivate *fp = QQuickFlickablePrivate::get(flick);
QSignalSpy moveEndSpy(flick, SIGNAL(movementEnded()));
+ quint64 timestamp = 10;
// test a vertical flick
{
@@ -877,6 +878,7 @@ void tst_qquickflickable::wheel()
QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(), QPoint(0,-120),
Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false);
event.setAccepted(false);
+ event.setTimestamp(timestamp);
QGuiApplication::sendEvent(window.data(), &event);
}
@@ -887,6 +889,7 @@ void tst_qquickflickable::wheel()
QCOMPARE(fp->velocityTimeline.isActive(), false);
QCOMPARE(fp->timeline.isActive(), false);
QTest::qWait(50); // make sure that onContentYChanged won't sneak in again
+ timestamp += 50;
QCOMPARE(flick->property("movementsAfterEnd").value<int>(), 0); // QTBUG-55886
// get ready to test horizontal flick
@@ -900,8 +903,8 @@ void tst_qquickflickable::wheel()
QPoint pos(200, 200);
QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(), QPoint(-120,0),
Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false);
-
event.setAccepted(false);
+ event.setTimestamp(timestamp);
QGuiApplication::sendEvent(window.data(), &event);
}
@@ -926,11 +929,13 @@ void tst_qquickflickable::trackpad()
QVERIFY(flick != nullptr);
QSignalSpy moveEndSpy(flick, SIGNAL(movementEnded()));
QPoint pos(200, 200);
+ quint64 timestamp = 10;
{
QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(0,-100), QPoint(0,-120),
Qt::NoButton, Qt::NoModifier, Qt::ScrollBegin, false);
event.setAccepted(false);
+ event.setTimestamp(timestamp++);
QGuiApplication::sendEvent(window.data(), &event);
}
@@ -944,6 +949,7 @@ void tst_qquickflickable::trackpad()
QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(-100,0), QPoint(-120,0),
Qt::NoButton, Qt::NoModifier, Qt::ScrollUpdate, false);
event.setAccepted(false);
+ event.setTimestamp(timestamp++);
QGuiApplication::sendEvent(window.data(), &event);
}
@@ -954,6 +960,7 @@ void tst_qquickflickable::trackpad()
QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(0,0), QPoint(0,0),
Qt::NoButton, Qt::NoModifier, Qt::ScrollEnd, false);
event.setAccepted(false);
+ event.setTimestamp(timestamp++);
QGuiApplication::sendEvent(window.data(), &event);
}
diff --git a/tests/manual/touch/flicktext.qml b/tests/manual/touch/flicktext.qml
index 9e84261687..e69d6207a9 100644
--- a/tests/manual/touch/flicktext.qml
+++ b/tests/manual/touch/flicktext.qml
@@ -380,6 +380,36 @@ Rectangle {
text: "content X " + flick.contentX.toFixed(2) + " Y " + flick.contentY.toFixed(2)
}
}
+
+ Column {
+ Row {
+ spacing: 2
+ Examples.Button {
+ id: decrButton
+ text: "-"
+ onClicked: flick.flickDeceleration -= 100
+ Timer {
+ running: decrButton.pressed
+ interval: 100; repeat: true
+ onTriggered: flick.flickDeceleration -= 100
+ }
+ }
+ Text {
+ horizontalAlignment: Text.AlignHCenter
+ text: "decel:\n" + flick.flickDeceleration.toFixed(4)
+ }
+ Examples.Button {
+ id: incrButton
+ text: "+"
+ onClicked: flick.flickDeceleration += 100
+ }
+ Timer {
+ running: incrButton.pressed
+ interval: 100; repeat: true
+ onTriggered: flick.flickDeceleration += 100
+ }
+ }
+ }
}
Component.onCompleted: {
--
2.37.3

View File

@ -1,25 +0,0 @@
From 46e932d87ffd6b2437b0411dd792112f5d4380fa Mon Sep 17 00:00:00 2001
From: Wolfgang Frisch <wfrisch@riseup.net>
Date: Thu, 19 May 2022 00:55:50 +0200
Subject: [PATCH 16/18] Fix Flickable with QTBUG-56075 patch applied
---
src/quick/items/qquickflickable.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 9eea0e1487..2fa3b7142c 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -62,6 +62,8 @@
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcHandlerParent)
+Q_LOGGING_CATEGORY(lcWheel, "qt.quick.flickable.wheel")
+Q_LOGGING_CATEGORY(lcVel, "qt.quick.flickable.velocity")
// FlickThreshold determines how far the "mouse" must have moved
// before we perform a flick.
--
2.37.3

View File

@ -0,0 +1,26 @@
From 2574ff9d5c6e72d01dca283e66436cd90a64324d 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 16/21] 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.39.0

View File

@ -0,0 +1,565 @@
From 6d1dd8925f160d6ad02ea646eac638675bdf9f1c 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 17/21] 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 85719fdc80..eb3df4d4cd 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();
@@ -188,7 +197,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.39.0

View File

@ -1,94 +0,0 @@
From 45d43c04088efb8346979f633f72bb1f23183461 Mon Sep 17 00:00:00 2001
From: Mitch Curtis <mitch.curtis@qt.io>
Date: Thu, 4 Nov 2021 10:41:28 +0100
Subject: [PATCH 18/18] Revert "Fix ListView.isCurrentItem when used with
DelegateModel"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This reverts commit d9f9d773e92940786f159897623618f3bf6bcf0f.
It causes a heap-use-after-free in tst_swipeview.qml.
Task-number: QTBUG-97423
Pick-to: 5.15 6.1 6.2
Change-Id: I42e9831ae1399a010df28c39496a7778121f5e35
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
Reviewed-by: Oliver Eftevaag <oliver.eftevaag@qt.io>
(cherry picked from commit 5d656b31eb371c9e0bb97c558f9193b08471f1d7)
---
src/quick/items/qquickitemview.cpp | 2 --
.../quick/qquicklistview/data/qtbug86744.qml | 21 -------------------
.../qquicklistview/tst_qquicklistview.cpp | 14 -------------
3 files changed, 37 deletions(-)
delete mode 100644 tests/auto/quick/qquicklistview/data/qtbug86744.qml
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index c8ea286d3e..f8ad168a17 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -2402,8 +2402,6 @@ void QQuickItemView::createdItem(int index, QObject* object)
d->repositionPackageItemAt(item, index);
else if (index == d->currentIndex)
d->updateCurrent(index);
- } else if (index == d->currentIndex) {
- d->updateCurrent(index);
}
}
diff --git a/tests/auto/quick/qquicklistview/data/qtbug86744.qml b/tests/auto/quick/qquicklistview/data/qtbug86744.qml
deleted file mode 100644
index 6dc82d57eb..0000000000
--- a/tests/auto/quick/qquicklistview/data/qtbug86744.qml
+++ /dev/null
@@ -1,21 +0,0 @@
-import QtQuick 2.15
-import QtQml.Models 2.15
-
-Item {
- height: 200
- width: 100
- DelegateModel {
- id: dm
- model: 2
- delegate: Item {
- width: 100; height: 20
- property bool isCurrent: ListView.isCurrentItem
- }
- }
- ListView {
- objectName: "listView"
- model: dm
- currentIndex: 1
- anchors.fill: parent
- }
-}
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index df329f8318..b564fd3ba5 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -10201,20 +10201,6 @@ void tst_QQuickListView::dragDelegateWithMouseArea_data()
}
}
-void tst_QQuickListView::isCurrentItem_DelegateModel()
-{
- QScopedPointer<QQuickView> window(createView());
- window->setSource(testFileUrl("qtbug86744.qml"));
- window->resize(640, 480);
- window->show();
- QVERIFY(QTest::qWaitForWindowExposed(window.data()));
-
- QQuickListView* listView = window->rootObject()->findChild<QQuickListView*>("listView");
- QVERIFY(listView);
- QVariant value = listView->itemAtIndex(1)->property("isCurrent");
- QVERIFY(value.toBool() == true);
-}
-
QTEST_MAIN(tst_QQuickListView)
#include "tst_qquicklistview.moc"
--
2.37.3

View File

@ -0,0 +1,46 @@
From 99c990d55802c1ea782ca609ccd2bcdf39fb786f Mon Sep 17 00:00:00 2001
From: Fushan Wen <qydwhotmail@gmail.com>
Date: Sat, 5 Nov 2022 01:44:30 +0800
Subject: [PATCH 18/21] 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 9de244ed9e..462147adbd 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.39.0

View File

@ -0,0 +1,113 @@
From b91f07532b02f68161ec525bd44501d91ad19b38 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 19/21] 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 462147adbd..4cf73ff73d 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.39.0

View File

@ -0,0 +1,57 @@
From 1fb12800a8907680b821a8e8e29c5b428cbb64b6 Mon Sep 17 00:00:00 2001
From: Harald Sitter <sitter@kde.org>
Date: Mon, 28 Nov 2022 14:59:33 +0100
Subject: [PATCH 20/21] 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 eb3df4d4cd..78e2ab302c 100644
--- a/src/quick/accessible/qaccessiblequickitem.cpp
+++ b/src/quick/accessible/qaccessiblequickitem.cpp
@@ -210,6 +210,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 4cf73ff73d..dec0ae19ae 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.39.0

View File

@ -0,0 +1,87 @@
From 8defe7bfcae2ac5cb6dc25bfe3678124b09cf6f9 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 21/21] 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.39.0

View File

@ -11,7 +11,7 @@
Summary: Qt5 - QtDeclarative component
Name: qt5-%{qt_module}
Version: 5.15.7
Version: 5.15.8
Release: 1%{?dist}
# See LICENSE.GPL LICENSE.LGPL LGPL_EXCEPTION.txt, for details
@ -27,25 +27,28 @@ Source5: qv4global_p-multilib.h
## upstream patches
## repo: https://invent.kde.org/qt/qt/qtdeclarative
## branch: kde/5.15
## git format-patch v5.15.7-lts-lgpl
Patch01: 0001-Document-that-StyledText-also-supports-nbsp-and-quot.patch
Patch02: 0002-Support-apos-in-styled-text.patch
Patch03: 0003-Remove-unused-QPointer-QQuickPointerMask.patch
Patch04: 0004-QQmlDelegateModel-Refresh-the-view-when-a-column-is-.patch
Patch05: 0005-Fix-sweep-step-for-tainted-QObject-JavaScript-wrappe.patch
Patch06: 0006-Revert-Fix-for-possible-crash-in-QSGDefaultLayer-gra.patch
Patch07: 0007-Fix-TapHandler-so-that-it-actually-registers-a-tap.patch
Patch08: 0008-Revert-Fix-TapHandler-so-that-it-actually-registers-.patch
Patch09: 0009-QQmlJs-FixedPoolArray-fix-UB-precondition-violation-.patch
Patch10: 0010-V4-Do-not-call-dtor-of-an-object-we-continue-to-use.patch
Patch11: 0011-Make-sure-QQuickWidget-and-its-offscreen-window-s-sc.patch
Patch12: 0012-QQuickItem-Guard-against-cycles-in-nextPrevItemInTab.patch
Patch13: 0013-QSGOpenGLDistanceFieldGlyphCache-fix-multiplication-.patch
Patch14: 0014-QSGOpenGLDistanceFieldGlyphCache-fix-UB-ordering-of-.patch
Patch15: 0015-Fix-Flickable-wheel-velocity-calculation.patch
Patch16: 0016-Fix-Flickable-with-QTBUG-56075-patch-applied.patch
Patch17: 0017-Reset-currentChanges-if-currentChanges-is-active-whe.patch
Patch18: 0018-Revert-Fix-ListView.isCurrentItem-when-used-with-Del.patch
## git format-patch v5.15.8-lts-lgpl
Patch1: 0001-Document-that-StyledText-also-supports-nbsp-and-quot.patch
Patch2: 0002-Support-apos-in-styled-text.patch
Patch3: 0003-Remove-unused-QPointer-QQuickPointerMask.patch
Patch4: 0004-QQmlDelegateModel-Refresh-the-view-when-a-column-is-.patch
Patch5: 0005-Fix-sweep-step-for-tainted-QObject-JavaScript-wrappe.patch
Patch6: 0006-Fix-TapHandler-so-that-it-actually-registers-a-tap.patch
Patch7: 0007-Revert-Fix-TapHandler-so-that-it-actually-registers-.patch
Patch8: 0008-QQmlJs-FixedPoolArray-fix-UB-precondition-violation-.patch
Patch9: 0009-V4-Do-not-call-dtor-of-an-object-we-continue-to-use.patch
Patch10: 0010-Make-sure-QQuickWidget-and-its-offscreen-window-s-sc.patch
Patch11: 0011-QQuickItem-Guard-against-cycles-in-nextPrevItemInTab.patch
Patch12: 0012-QSGOpenGLDistanceFieldGlyphCache-fix-multiplication-.patch
Patch13: 0013-QSGOpenGLDistanceFieldGlyphCache-fix-UB-ordering-of-.patch
Patch14: 0014-Reset-currentChanges-if-currentChanges-is-active-whe.patch
Patch15: 0015-Don-t-convert-QByteArray-in-startDrag.patch
Patch16: 0016-Fix-build-after-95290f66b806a307b8da1f72f8fc2c698019.patch
Patch17: 0017-Implement-accessibility-for-QQuickWidget.patch
Patch18: 0018-Send-ObjectShow-event-for-visible-components-after-i.patch
Patch19: 0019-QQuickItem-avoid-emitting-signals-during-destruction.patch
Patch20: 0020-a11y-track-item-enabled-state.patch
Patch21: 0021-Make-QaccessibleQuickWidget-private-API.patch
## upstreamable patches
@ -229,6 +232,9 @@ make check -k -C tests ||:
%changelog
* Thu Jan 05 2023 Jan Grulich <jgrulich@redhat.com> - 5.15.8-1
- 5.15.8
* Mon Oct 31 2022 Jan Grulich <jgrulich@redhat.com> - 5.15.7-1
- 5.15.7

View File

@ -1 +1,2 @@
SHA512 (qtdeclarative-everywhere-opensource-src-5.15.7.tar.xz) = 909721a7c756ad3f55fa30b539ddd7f459449edc599883a4e04acbe6f1cecaf44b3a5f2b3b17adb83adaf8cd3e1e5e7e09829b30b0df3dacb1e203892b996508
SHA512 (qtdeclarative-everywhere-opensource-src-5.15.6.tar.xz) = a4824b6ec2de5e78819b726850767db6d4280208d6cc985219f4c33b6b0dcd6194557f32b577df97b0596d157190aa9c00e99bf6879554936a356fa7afe8a7d5
SHA512 (qtdeclarative-everywhere-opensource-src-5.15.8.tar.xz) = c611cc1d25b7eea1da3e5932d253d024459044d8fff6a31066033ea5867dd20aeb183b2d2ba8a2ca71cf263fc1921126509212dd43ab680134e7a9df8d937d73