aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquicktextedit.cpp
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2022-08-17 21:57:52 +0200
committerShawn Rutledge <shawn.rutledge@qt.io>2022-08-25 19:34:08 +0200
commitb271755e6c9a5a939c3ad6dfca8da573779e06ee (patch)
treea0ac0ca69835f3a0a9632d1114058e1a58e0bb96 /src/quick/items/qquicktextedit.cpp
parent47490648b14938049ddf84c3f665619c1117241c (diff)
Fix bad rendering after text selection
In 9db23e0e04906cf9ea33e23fa41f34955e5e6fe0 we added a new call to createTextNode(), but it turns out that it could be called again for the same block, a few lines below (in code that was originally added in dfdc4ce825e814b30449cfa1c85d3d2f47f8a845), if we have not reached the "last node that needed replacing or last block of the frame". This resulted in a memory leak: TransformNodes were created without parents, which b616028dae933e7ff6142d41bdafee8ad445a8ec tried to fix by calling addCurrentTextNodeToRoot(). That change made the code in "Update the position of the subsequent text blocks" re-add offsets that had already been added, which had the effect of moving down the blocks below the selected ones by the height of one line; but the new call to addCurrentTextNodeToRoot() was anyway just adding empty TransformNode instances to the scene graph. Afterwards we can see that any TransformNode that does not have a GeometryNode as a child is not actually rendering any text, it's just wasting memory. Having a debug operator for QQuickTextEditPrivate::Node, and using a QQuickTextEdit subclass in the autotest that checks the nodes corresponding to blocks rendered at the end of updatePaintNode(), makes this easier to see and verify. So now, if createTextNode() has already been called, we avoid calling it again a few lines below; but we keep the checks in place to make sure that every node which does not have a parent will get added to the scene graph (regardless of which line of code it was created on), so that there's no leak. It remains to be seen if this could be cleaned up further. Amends 9db23e0e04906cf9ea33e23fa41f34955e5e6fe0 and b616028dae933e7ff6142d41bdafee8ad445a8ec Pick-to: 6.3.2 6.3 6.4 Task-number: QTBUG-103819 Fixes: QTBUG-105208 Fixes: QTBUG-105555 Fixes: QTBUG-105728 Change-Id: I321980c705887bfdb37825f7e6ed8da3d200654e Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
Diffstat (limited to 'src/quick/items/qquicktextedit.cpp')
-rw-r--r--src/quick/items/qquicktextedit.cpp16
1 files changed, 14 insertions, 2 deletions
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index 8ce622d176..ba8d8a1fc4 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -2271,11 +2271,13 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
}
}
+ bool createdNodeInView = false;
if (inView) {
if (!engine.hasContents()) {
if (node && !node->parent())
d->addCurrentTextNodeToRoot(&engine, rootNode, node, nodeIterator, nodeStart);
node = d->createTextNode();
+ createdNodeInView = true;
updateNodeTransform(node, nodeOffset);
nodeStart = block.position();
}
@@ -2285,13 +2287,13 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
if ((it.atEnd()) || block.next().position() >= firstCleanNode.startPos())
break; // last node that needed replacing or last block of the frame
-
QList<int>::const_iterator lowerBound = std::lower_bound(frameBoundaries.constBegin(), frameBoundaries.constEnd(), block.next().position());
if (node && (currentNodeSize > nodeBreakingSize || lowerBound == frameBoundaries.constEnd() || *lowerBound > nodeStart)) {
currentNodeSize = 0;
if (!node->parent())
d->addCurrentTextNodeToRoot(&engine, rootNode, node, nodeIterator, nodeStart);
- node = d->createTextNode();
+ if (!createdNodeInView)
+ node = d->createTextNode();
resetEngine(&engine, d->color, d->selectedTextColor, d->selectionColor);
nodeStart = block.next().position();
}
@@ -3357,6 +3359,16 @@ void QQuickTextEdit::clear()
d->control->clear();
}
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug debug, const QQuickTextEditPrivate::Node &n)
+{
+ QDebugStateSaver saver(debug);
+ debug.space();
+ debug << "Node(startPos:" << n.m_startPos << "dirty:" << n.m_dirty << n.m_node << ')';
+ return debug;
+}
+#endif
+
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
void QQuickTextEdit::setOldSelectionDefault()
{