aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanthosh Kumar <santhosh.kumar.selvaraj@qt.io>2023-12-21 13:46:52 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2024-02-21 13:04:11 +0000
commitf18e147640363fad51f49bff75b43152b0418c81 (patch)
tree2e3b502c7167e5ea67ec8ae099ad8e721704bca7
parente38e96aec910aee82a502369c15f6b856175767c (diff)
Force text layout update in the thread where its created
The text layout gets updated while invalidating font data. This creates an issue when quick text instance was created and invalidated across different threads. It mainly affects QQuickText::lineLaidOut() signal as QQuickTextLine is designed to provide information only about current line and its to be noted that the current line provided by QQuickTextPrivate was from stack. Thus, triggering this signal across thread provide invalid line information. Its possible to keep line in heap but that doesn't help as the ultimate purpose of QQuickText::lineLaidOut() signal is to provide current line information which user can hook to modify its geometry. This patch makes updateLayout() to be happening in same thread where the quick text object was created. Fixes: QTBUG-113039 Pick-to: 6.5 Change-Id: Ic0737cb514f663f87ac1cf21506ad76fee03643e Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> (cherry picked from commit d548077d205d22610ceeb623006f7fa54d4c72c7) Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> (cherry picked from commit 1faaefe3bf59ca609e3729c183b6b5f3fab937fe)
-rw-r--r--src/quick/items/qquicktext.cpp2
-rw-r--r--tests/auto/quick/qquicktext/data/lineLayoutFontUpdate.qml25
-rw-r--r--tests/auto/quick/qquicktext/data/tarzeau_ocr_a.ttfbin0 -> 24544 bytes
-rw-r--r--tests/auto/quick/qquicktext/tst_qquicktext.cpp24
4 files changed, 50 insertions, 1 deletions
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 85c4c54b27..0ee8a86986 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -3074,7 +3074,7 @@ void QQuickText::invalidate()
{
Q_D(QQuickText);
d->textHasChanged = true;
- d->updateLayout();
+ QMetaObject::invokeMethod(this,[&]{q_updateLayout();});
}
bool QQuickTextPrivate::transformChanged(QQuickItem *transformedItem)
diff --git a/tests/auto/quick/qquicktext/data/lineLayoutFontUpdate.qml b/tests/auto/quick/qquicktext/data/lineLayoutFontUpdate.qml
new file mode 100644
index 0000000000..d018e31d29
--- /dev/null
+++ b/tests/auto/quick/qquicktext/data/lineLayoutFontUpdate.qml
@@ -0,0 +1,25 @@
+import QtQuick
+
+Item {
+ width: 640
+ height: 480
+
+ FontLoader {
+ id: fontIcons
+ source: "tarzeau_ocr_a.ttf"
+ }
+
+ Text {
+ id: exampleText
+ objectName: "exampleText"
+ text: "Example multiline text"
+ wrapMode: Text.WordWrap
+ width: 100
+ onLineLaidOut: (line) => {
+ if (line.number < 1) {
+ line.x += 40;
+ line.width -= 40;
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicktext/data/tarzeau_ocr_a.ttf b/tests/auto/quick/qquicktext/data/tarzeau_ocr_a.ttf
new file mode 100644
index 0000000000..cf93f9651f
--- /dev/null
+++ b/tests/auto/quick/qquicktext/data/tarzeau_ocr_a.ttf
Binary files differ
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
index 3cdfeeb0e6..39fcc68476 100644
--- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
@@ -105,6 +105,7 @@ private slots:
void largeTextInDelayedLoader();
void lineLaidOut();
void lineLaidOutRelayout();
+ void lineLaidOutFontUpdate();
void lineLaidOutHAlign();
void lineLaidOutImplicitWidth();
@@ -3140,6 +3141,29 @@ void tst_qquicktext::lineLaidOutRelayout()
}
}
+void tst_qquicktext::lineLaidOutFontUpdate()
+{
+ QScopedPointer<QQuickView> window(createView(testFile("lineLayoutFontUpdate.qml")));
+
+ window->show();
+ window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
+
+ auto *myText = window->rootObject()->findChild<QQuickText*>("exampleText");
+ QVERIFY(myText != nullptr);
+
+ QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(myText);
+ QVERIFY(textPrivate != nullptr);
+
+ QCOMPARE(textPrivate->layout.lineCount(), 2);
+
+ QTextLine firstLine = textPrivate->layout.lineAt(0);
+ QTextLine secondLine = textPrivate->layout.lineAt(1);
+
+ QCOMPARE(firstLine.rect().x(), secondLine.rect().x() + 40);
+ QCOMPARE(firstLine.rect().width(), secondLine.rect().width() - 40);
+}
+
void tst_qquicktext::lineLaidOutHAlign()
{
QScopedPointer<QQuickView> window(createView(testFile("lineLayoutHAlign.qml")));