From bf817782e6dfeb8455febe3e481bcdb4c383ed05 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Thu, 3 May 2012 13:03:29 +1000 Subject: [PATCH] Ensure the cursor rectangle is updated when preedit text changes. Updating only when the cursor position changes isn't enough because changing pre-edit text changes the width of the pre-edit area and the x offset of all cursor positions within it. Change-Id: I3c0a5e4ad4714a903ca84c1a25374491f34d95a0 Reviewed-by: Yann Bodson --- src/quick/items/qquicktextcontrol.cpp | 2 +- src/quick/items/qquicktextinput.cpp | 4 ++-- .../quick/qquicktextedit/data/inputMethodEvent.qml | 1 + .../quick/qquicktextedit/tst_qquicktextedit.cpp | 19 +++++++++++++++--- .../qquicktextinput/data/inputMethodEvent.qml | 1 + .../quick/qquicktextinput/tst_qquicktextinput.cpp | 23 +++++++++++++++++----- 6 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp index 8bc94b9..751706d 100644 --- a/src/quick/items/qquicktextcontrol.cpp +++ b/src/quick/items/qquicktextcontrol.cpp @@ -1479,7 +1479,7 @@ void QQuickTextControlPrivate::inputMethodEvent(QInputMethodEvent *e) QTextCursorPrivate *cursor_d = QTextCursorPrivate::getPrivate(&cursor); if (cursor_d) cursor_d->setX(); - q->updateCursorRectangle(oldPreeditCursor != preeditCursor || forceSelectionChanged); + q->updateCursorRectangle(oldPreeditCursor != preeditCursor || forceSelectionChanged || isGettingInput); selectionChanged(forceSelectionChanged); } diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index 9cf187e..e219934 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -3217,7 +3217,7 @@ void QQuickTextInputPrivate::processInputMethodEvent(QInputMethodEvent *event) updateDisplayText(/*force*/ true); if (cursorPositionChanged) { emitCursorPositionChanged(); - } else if (m_preeditCursor != oldPreeditCursor) { + } else if (m_preeditCursor != oldPreeditCursor || isGettingInput) { q->updateCursorRectangle(); } @@ -3332,7 +3332,7 @@ bool QQuickTextInputPrivate::finishChange(int validateFromState, bool update, bo emit q->selectionChanged(); } - inputMethodAttributesChanged |= (m_cursor == m_lastCursorPos); + inputMethodAttributesChanged |= (m_cursor != m_lastCursorPos); if (inputMethodAttributesChanged) q->updateInputMethod(); emitUndoRedoChanged(); diff --git a/tests/auto/quick/qquicktextedit/data/inputMethodEvent.qml b/tests/auto/quick/qquicktextedit/data/inputMethodEvent.qml index ab47368..7df7a55 100644 --- a/tests/auto/quick/qquicktextedit/data/inputMethodEvent.qml +++ b/tests/auto/quick/qquicktextedit/data/inputMethodEvent.qml @@ -1,6 +1,7 @@ import QtQuick 2.0 TextEdit { + width: 300 focus: true cursorDelegate: Item { diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp index 51b04cf..1b21fcc 100644 --- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp +++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp @@ -2858,11 +2858,11 @@ void tst_qquicktextedit::preeditCursorRectangle() QCOMPARE(edit->cursorRectangle(), currentRect); QCOMPARE(cursor->pos(), currentRect.topLeft()); QCOMPARE(currentRect, previousRect); - QCOMPARE(editSpy.count(), 0); editSpy.clear(); - QCOMPARE(panelSpy.count(), 0); panelSpy.clear(); // Verify that the micro focus rect moves to the left as the cursor position // is incremented. + editSpy.clear(); + panelSpy.clear(); for (int i = 1; i <= 5; ++i) { QInputMethodEvent imEvent(preeditText, QList() << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, i, preeditText.length(), QVariant())); @@ -2877,9 +2877,22 @@ void tst_qquicktextedit::preeditCursorRectangle() previousRect = currentRect; } + // Verify that if the cursor rectangle is updated if the pre-edit text changes + // but the (non-zero) cursor position is the same. + editSpy.clear(); + panelSpy.clear(); + { QInputMethodEvent imEvent("wwwww", QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 5, 1, QVariant())); + QCoreApplication::sendEvent(qGuiApp->focusObject(), &imEvent); } + QCoreApplication::sendEvent(qGuiApp->focusObject(), &query); + currentRect = query.value(Qt::ImCursorRectangle).toRectF(); + QCOMPARE(edit->cursorRectangle(), currentRect); + QCOMPARE(cursor->pos(), currentRect.topLeft()); + QCOMPARE(editSpy.count(), 1); + QCOMPARE(panelSpy.count(), 1); + // Verify that if there is no preedit cursor then the micro focus rect is the // same as it would be if it were positioned at the end of the preedit text. - QCoreApplication::sendEvent(qGuiApp->focusObject(), &imEvent); editSpy.clear(); panelSpy.clear(); { QInputMethodEvent imEvent(preeditText, QList()); diff --git a/tests/auto/quick/qquicktextinput/data/inputMethodEvent.qml b/tests/auto/quick/qquicktextinput/data/inputMethodEvent.qml index 907ea68..9e04620 100644 --- a/tests/auto/quick/qquicktextinput/data/inputMethodEvent.qml +++ b/tests/auto/quick/qquicktextinput/data/inputMethodEvent.qml @@ -1,6 +1,7 @@ import QtQuick 2.0 TextInput { + width: 300 focus: true autoScroll: false diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp index 2ea2486..e80808b 100644 --- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp @@ -3437,18 +3437,31 @@ void tst_qquicktextinput::preeditCursorRectangle() previousRect = currentRect; } + // Verify that if the cursor rectangle is updated if the pre-edit text changes + // but the (non-zero) cursor position is the same. + inputSpy.clear(); + panelSpy.clear(); + sendPreeditText("wwwww", 5); + QCoreApplication::sendEvent(qGuiApp->focusObject(), &query); + currentRect = query.value(Qt::ImCursorRectangle).toRectF(); + QCOMPARE(input->cursorRectangle(), currentRect); + QCOMPARE(cursor->pos(), currentRect.topLeft()); + QCOMPARE(inputSpy.count(), 1); + QCOMPARE(panelSpy.count(), 1); + // Verify that if there is no preedit cursor then the micro focus rect is the // same as it would be if it were positioned at the end of the preedit text. - sendPreeditText(preeditText, 0); - QInputMethodEvent imEvent(preeditText, QList()); - QCoreApplication::sendEvent(qGuiApp->focusObject(), &imEvent); + inputSpy.clear(); + panelSpy.clear(); + { QInputMethodEvent imEvent(preeditText, QList()); + QCoreApplication::sendEvent(qGuiApp->focusObject(), &imEvent); } QCoreApplication::sendEvent(qGuiApp->focusObject(), &query); currentRect = query.value(Qt::ImCursorRectangle).toRectF(); QCOMPARE(currentRect, previousRect); QCOMPARE(input->cursorRectangle(), currentRect); QCOMPARE(cursor->pos(), currentRect.topLeft()); - QVERIFY(inputSpy.count() > 0); - QVERIFY(panelSpy.count() > 0); + QCOMPARE(inputSpy.count(), 1); + QCOMPARE(panelSpy.count(), 1); } void tst_qquicktextinput::inputContextMouseHandler() -- 2.7.4