Fix polish issue in quick text edit

The text edit didn't polish even after there is change in position
offset, leading to alignment issues.

During geometry change, the QQuickTextEdit calculates implicit size
and base position offset, and then further requests a polish
immediately afterwards. This sequence of update happens only if we have
valid width or height set for text edit control. But in case we set
width or height to undefined, there is a chance that this update
would be missed.

This patch removes the checking of widthValid() in
QQuickTextEdit::geometryChange(), to allow those updates.
The validation of width or height is already handled internally
within updateSize(), so it shouldn't create an issue; and we still
try to avoid emitting cursorRectangleChanged() too often.

Amends 1770fa632f

Task-number: QTBUG-117667
Task-number: QTBUG-25489
Pick-to: 6.6 6.5
Change-Id: Ia20cd06e78842f5edb0c395d6322a660f86f6b5e
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
(cherry picked from commit d84c130411)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Santhosh Kumar 2023-11-09 14:05:22 +01:00 committed by Qt Cherry-pick Bot
parent a2bfdb1f4d
commit 3bff953242
3 changed files with 77 additions and 4 deletions

View File

@ -1555,14 +1555,14 @@ void QQuickTextEdit::setInputMethodHints(Qt::InputMethodHints hints)
void QQuickTextEdit::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickTextEdit);
if (!d->inLayout && ((newGeometry.width() != oldGeometry.width() && widthValid())
|| (newGeometry.height() != oldGeometry.height() && heightValid()))) {
if (!d->inLayout && ((newGeometry.width() != oldGeometry.width())
|| (newGeometry.height() != oldGeometry.height()))) {
updateSize();
updateWholeDocument();
moveCursorDelegate();
if (widthValid() || heightValid())
moveCursorDelegate();
}
QQuickImplicitSizeItem::geometryChange(newGeometry, oldGeometry);
}
/*!

View File

@ -0,0 +1,42 @@
import QtQuick
import QtQuick.Controls
Item {
width: 400
height: 150
TextEdit {
id: textEdit
anchors {
top: parent.top
left: parent.left
right: parent.right
}
readOnly: true
wrapMode: Text.WordWrap
verticalAlignment: Text.AlignVCenter
text: "Lorem ipsum dolor sit amet, consectetur adipisicing"
states: [
State {
name: "multi-line"
when: textEdit.lineCount > 1
AnchorChanges {
target: textEdit
anchors.bottom: undefined
}
PropertyChanges {
target: textEdit
height: undefined
}
},
State {
name: "single-line"
when: true
AnchorChanges {
target: textEdit
anchors.bottom: { return textEdit.parent.bottom }
}
}
]
}
}

View File

@ -6,6 +6,7 @@
#include <math.h>
#include <QFile>
#include <QtQuick/QQuickTextDocument>
#include <QtQuickTest/QtQuickTest>
#include <QTextDocument>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlcontext.h>
@ -227,6 +228,7 @@ private slots:
void rtlAlignmentInColumnLayout_QTBUG_112858();
void fontManipulationWithCursorSelection();
void resizeTextEditPolish();
private:
void simulateKeys(QWindow *window, const QList<Key> &keys);
@ -6665,6 +6667,35 @@ void tst_qquicktextedit::fontManipulationWithCursorSelection()
QCOMPARE(block.charFormat().font(), font);
}
void tst_qquicktextedit::resizeTextEditPolish()
{
QQuickView window(testFileUrl("resizeTextEditPolish.qml"));
QVERIFY(window.rootObject() != nullptr);
window.show();
QVERIFY(QTest::qWaitForWindowExposed(&window));
auto *edit = window.rootObject()->findChild<QQuickTextEdit *>();
QVERIFY(edit != nullptr);
QCOMPARE(edit->lineCount(), 1);
QSignalSpy spy(edit, SIGNAL(lineCountChanged()));
// Resize item and check for item polished
auto *item = edit->parentItem();
item->setWidth(item->width() - (item->width() / 2));
QVERIFY(QQuickTest::qIsPolishScheduled(edit));
QVERIFY(QQuickTest::qWaitForPolish(edit));
QTRY_COMPARE(spy.size(), 1);
QVERIFY(edit->lineCount() > 1);
QCOMPARE(edit->state(), QString("multi-line"));
auto *editPriv = QQuickTextEditPrivate::get(edit);
QCOMPARE(editPriv->xoff, 0);
QCOMPARE(editPriv->yoff, 0);
}
QT_END_NAMESPACE
QTEST_MAIN(tst_qquicktextedit)