summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPiotr WierciƄski <piotr.wiercinski@qt.io>2023-04-20 13:32:53 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2023-05-12 10:13:24 +0000
commitf3b1d6135222e9ce41845a00831a3eb24cd36449 (patch)
treeb977bdb2a52881d9d05d3a8d924c8871523196f7
parente0c13e1138a1730047e627f4cb2087f6217b8d42 (diff)
downloadqtdeclarative-f3b1d6135222e9ce41845a00831a3eb24cd36449.tar.gz
QQuickText: Mark as a dirty node when its ClipRect changes
Make sure that any changes to ClipRect of QQuickText are properly propagated. Fixes: QTBUG-106164 Fixes: QTBUG-106205 Pick-to: 6.5 Change-Id: Id37099811cf8e10dd510dc5f8086d1323f92af9e Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
-rw-r--r--src/quick/items/qquicktext.cpp5
-rw-r--r--src/quick/items/qquickwindow.cpp28
-rw-r--r--tests/auto/quick/qquicktext/data/qtbug_106205.qml28
-rw-r--r--tests/auto/quick/qquicktext/tst_qquicktext.cpp23
4 files changed, 72 insertions, 12 deletions
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 02ae80b0b8..3a2fbfef0d 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -2538,6 +2538,11 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
void QQuickText::updatePolish()
{
Q_D(QQuickText);
+ const bool clipNodeChanged =
+ d->componentComplete && d->clipNode() && d->clipNode()->rect() != clipRect();
+ if (clipNodeChanged)
+ d->dirty(QQuickItemPrivate::Clip);
+
// If the fonts used for rendering are different from the ones used in the GUI thread,
// it means we will get warnings and corrupted text. If this case is detected, we need
// to update the text layout before creating the scenegraph nodes.
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index a9813d5187..68f3e6f8e0 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -1954,19 +1954,14 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item)
itemPriv->itemNode()->setMatrix(matrix);
}
- bool clipEffectivelyChanged = (dirty & (QQuickItemPrivate::Clip | QQuickItemPrivate::Window)) &&
- ((item->clip() == false) != (itemPriv->clipNode() == nullptr));
- int effectRefCount = itemPriv->extra.isAllocated()?itemPriv->extra->effectRefCount:0;
- bool effectRefEffectivelyChanged = (dirty & (QQuickItemPrivate::EffectReference | QQuickItemPrivate::Window)) &&
- ((effectRefCount == 0) != (itemPriv->rootNode() == nullptr));
-
+ const bool clipEffectivelyChanged = dirty & (QQuickItemPrivate::Clip | QQuickItemPrivate::Window);
if (clipEffectivelyChanged) {
- QSGNode *parent = itemPriv->opacityNode() ? (QSGNode *) itemPriv->opacityNode() :
- (QSGNode *) itemPriv->itemNode();
+ QSGNode *parent = itemPriv->opacityNode() ? (QSGNode *)itemPriv->opacityNode()
+ : (QSGNode *)itemPriv->itemNode();
QSGNode *child = itemPriv->rootNode();
- if (item->clip()) {
- Q_ASSERT(itemPriv->clipNode() == nullptr);
+ if (bool initializeClipNode = item->clip() && itemPriv->clipNode() == nullptr;
+ initializeClipNode) {
QQuickDefaultClipNode *clip = new QQuickDefaultClipNode(item->clipRect());
itemPriv->extra.value().clipNode = clip;
clip->update();
@@ -1980,9 +1975,14 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item)
parent->appendChildNode(clip);
}
- } else {
+ } else if (bool updateClipNode = item->clip() && itemPriv->clipNode() != nullptr;
+ updateClipNode) {
+ QQuickDefaultClipNode *clip = itemPriv->clipNode();
+ clip->setClipRect(item->clipRect());
+ clip->update();
+ } else if (bool removeClipNode = !item->clip() && itemPriv->clipNode() != nullptr;
+ removeClipNode) {
QQuickDefaultClipNode *clip = itemPriv->clipNode();
- Q_ASSERT(clip);
parent->removeChildNode(clip);
if (child) {
clip->removeChildNode(child);
@@ -1996,6 +1996,10 @@ void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item)
}
}
+ const int effectRefCount = itemPriv->extra.isAllocated() ? itemPriv->extra->effectRefCount : 0;
+ const bool effectRefEffectivelyChanged =
+ (dirty & (QQuickItemPrivate::EffectReference | QQuickItemPrivate::Window))
+ && ((effectRefCount == 0) != (itemPriv->rootNode() == nullptr));
if (effectRefEffectivelyChanged) {
if (dirty & QQuickItemPrivate::ChildrenUpdateMask)
itemPriv->childContainerNode()->removeAllChildNodes();
diff --git a/tests/auto/quick/qquicktext/data/qtbug_106205.qml b/tests/auto/quick/qquicktext/data/qtbug_106205.qml
new file mode 100644
index 0000000000..e4db73557a
--- /dev/null
+++ b/tests/auto/quick/qquicktext/data/qtbug_106205.qml
@@ -0,0 +1,28 @@
+import QtQuick
+import QtQuick.Controls
+
+Item {
+ id: root
+ objectName: "root"
+ visible: true
+
+ anchors.fill: parent
+ property string text: ""
+
+ ScrollView {
+ anchors.fill: parent
+ Rectangle {
+ x: 100
+ width: 100
+ height: 30
+ color: "lightgray"
+
+ Text {
+ objectName: "textOutsideViewport"
+ text: root.text
+ width: 50
+ clip: true
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
index c8d9561803..8faace86c1 100644
--- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
@@ -53,6 +53,7 @@ private slots:
void implicitElide_data();
void implicitElide();
void textFormat();
+ void clipRectOutsideViewportDynamicallyChanged();
void baseUrl();
void embeddedImages_data();
@@ -827,6 +828,28 @@ void tst_qquicktext::textFormat()
}
}
+void tst_qquicktext::clipRectOutsideViewportDynamicallyChanged()
+{
+ // QTBUG-106205
+ QScopedPointer<QQuickView> view(createView(testFile("qtbug_106205.qml")));
+ view->setWidth(100);
+ view->setHeight(200);
+ view->showNormal();
+ QQuickItem *root = view->rootObject();
+ QVERIFY(root);
+ QVERIFY(QTest::qWaitForWindowExposed(view.get()));
+
+ auto clipRectMatches = [&]() -> bool {
+ auto *textOutsideInitialViewport = root->findChild<QQuickText *>("textOutsideViewport");
+ if (!textOutsideInitialViewport)
+ return false;
+ auto *clipNode = QQuickItemPrivate::get(textOutsideInitialViewport)->clipNode();
+
+ return textOutsideInitialViewport->clipRect() == clipNode->clipRect();
+ };
+ QTRY_VERIFY(clipRectMatches());
+}
+
//the alignment tests may be trivial o.oa
void tst_qquicktext::horizontalAlignment()
{