diff options
author | Santhosh Kumar <santhosh.kumar.selvaraj@qt.io> | 2023-12-21 13:46:52 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2024-02-21 13:04:11 +0000 |
commit | f18e147640363fad51f49bff75b43152b0418c81 (patch) | |
tree | 2e3b502c7167e5ea67ec8ae099ad8e721704bca7 | |
parent | e38e96aec910aee82a502369c15f6b856175767c (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.cpp | 2 | ||||
-rw-r--r-- | tests/auto/quick/qquicktext/data/lineLayoutFontUpdate.qml | 25 | ||||
-rw-r--r-- | tests/auto/quick/qquicktext/data/tarzeau_ocr_a.ttf | bin | 0 -> 24544 bytes | |||
-rw-r--r-- | tests/auto/quick/qquicktext/tst_qquicktext.cpp | 24 |
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 Binary files differnew file mode 100644 index 0000000000..cf93f9651f --- /dev/null +++ b/tests/auto/quick/qquicktext/data/tarzeau_ocr_a.ttf 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"))); |