aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/items/qquickitem.cpp16
-rw-r--r--src/quick/items/qquickitem.h3
-rw-r--r--src/quick/items/qquicktextedit.cpp4
-rw-r--r--src/quick/items/qquicktextinput.cpp23
-rw-r--r--tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp99
-rw-r--r--tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp30
6 files changed, 151 insertions, 24 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 49084639d5..844d1ede6b 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -3081,13 +3081,6 @@ void QQuickItem::setInputMethodHints(Qt::InputMethodHints hints)
qApp->inputPanel()->update(Qt::ImHints);
}
-void QQuickItem::updateMicroFocus()
-{
- QInputPanel *p = qApp->inputPanel();
- if (p->inputItem() == this)
- qApp->inputPanel()->update(Qt::ImQueryInput);
-}
-
QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
{
Q_D(const QQuickItem);
@@ -3608,6 +3601,15 @@ void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
Q_UNUSED(value);
}
+/*!
+ Notify input method on updated query values if needed. \a indicates changed attributes.
+*/
+void QQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
+{
+ if (hasActiveFocus())
+ qApp->inputPanel()->update(queries);
+}
+
/*! \internal */
// XXX todo - do we want/need this anymore?
// Note that it's now used for varying clip rect
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index 0dd896af3d..684910a112 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -324,7 +324,6 @@ public:
public Q_SLOTS:
void update();
- void updateMicroFocus();
Q_SIGNALS:
void childrenRectChanged(const QRectF &);
@@ -359,6 +358,8 @@ protected:
bool isComponentComplete() const;
virtual void itemChange(ItemChange, const ItemChangeData &);
+ void updateInputMethod(Qt::InputMethodQueries queries = Qt::ImQueryInput);
+
void setImplicitWidth(qreal);
bool widthValid() const; // ### better name?
void setImplicitHeight(qreal);
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index 37c76c09a3..126003906e 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -373,6 +373,7 @@ void QQuickTextEdit::setFont(const QFont &font)
}
updateSize();
updateDocument();
+ updateInputMethod(Qt::ImCursorRectangle | Qt::ImFont);
}
emit fontChanged(d->sourceFont);
}
@@ -1248,6 +1249,7 @@ void QQuickTextEdit::setReadOnly(bool r)
if (!r)
d->control->moveCursor(QTextCursor::End);
+ updateInputMethod(Qt::ImEnabled);
q_canPasteChanged();
emit readOnlyChanged(r);
}
@@ -1853,7 +1855,7 @@ void QQuickTextEdit::moveCursorDelegate()
{
Q_D(QQuickTextEdit);
d->determineHorizontalAlignment();
- updateMicroFocus();
+ updateInputMethod();
emit cursorRectangleChanged();
if (!d->cursor)
return;
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index 08892e1922..9d36ded9cc 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -306,7 +306,7 @@ void QQuickTextInput::setFont(const QFont &font)
if (oldFont != d->font) {
d->updateLayout();
updateCursorRectangle();
- qApp->inputPanel()->update(Qt::ImCursorRectangle | Qt::ImFont);
+ updateInputMethod(Qt::ImCursorRectangle | Qt::ImFont);
}
emit fontChanged(d->sourceFont);
}
@@ -575,6 +575,7 @@ void QQuickTextInput::setReadOnly(bool ro)
d->m_readOnly = ro;
if (!ro)
d->setCursorPosition(d->end());
+ updateInputMethod(Qt::ImEnabled);
q_canPasteChanged();
d->emitUndoRedoChanged();
emit readOnlyChanged(ro);
@@ -2508,6 +2509,7 @@ void QQuickTextInput::updateCursorRectangle()
d->cursorItem->setPos(r.topLeft());
d->cursorItem->setHeight(r.height());
}
+ updateInputMethod(Qt::ImCursorRectangle);
}
void QQuickTextInput::selectionChanged()
@@ -2873,8 +2875,8 @@ void QQuickTextInputPrivate::setSelection(int start, int length)
}
emit q->selectionChanged();
emitCursorPositionChanged();
- qApp->inputPanel()->update(Qt::ImCursorRectangle | Qt::ImAnchorPosition
- | Qt::ImCursorPosition | Qt::ImCurrentSelection);
+ q->updateInputMethod(Qt::ImCursorRectangle | Qt::ImAnchorPosition
+ | Qt::ImCursorPosition | Qt::ImCurrentSelection);
}
/*!
@@ -2964,7 +2966,7 @@ void QQuickTextInputPrivate::moveCursor(int pos, bool mark)
emit q->selectionChanged();
}
emitCursorPositionChanged();
- q->updateMicroFocus();
+ q->updateInputMethod();
}
/*!
@@ -3065,7 +3067,6 @@ void QQuickTextInputPrivate::processInputMethodEvent(QInputMethodEvent *event)
emitCursorPositionChanged();
} else if (m_preeditCursor != oldPreeditCursor) {
q->updateCursorRectangle();
- qApp->inputPanel()->update(Qt::ImCursorRectangle);
}
bool tentativeCommitChanged = m_tentativeCommit != event->tentativeCommitString();
@@ -3080,8 +3081,8 @@ void QQuickTextInputPrivate::processInputMethodEvent(QInputMethodEvent *event)
if (selectionChange) {
emit q->selectionChanged();
- qApp->inputPanel()->update(Qt::ImCursorRectangle | Qt::ImAnchorPosition
- | Qt::ImCursorPosition | Qt::ImCurrentSelection);
+ q->updateInputMethod(Qt::ImCursorRectangle | Qt::ImAnchorPosition
+ | Qt::ImCursorPosition | Qt::ImCurrentSelection);
}
}
@@ -3123,7 +3124,7 @@ bool QQuickTextInputPrivate::finishChange(int validateFromState, bool update, bo
Q_Q(QQuickTextInput);
Q_UNUSED(update)
- bool notifyInputPanel = m_textDirty || m_selDirty;
+ bool inputMethodAttributesChanged = m_textDirty || m_selDirty;
bool alignmentChanged = false;
if (m_textDirty) {
@@ -3194,9 +3195,9 @@ bool QQuickTextInputPrivate::finishChange(int validateFromState, bool update, bo
emit q->selectionChanged();
}
- notifyInputPanel |= (m_cursor == m_lastCursorPos);
- if (notifyInputPanel)
- q->updateMicroFocus();
+ inputMethodAttributesChanged |= (m_cursor == m_lastCursorPos);
+ if (inputMethodAttributesChanged)
+ q->updateInputMethod();
emitUndoRedoChanged();
if (!emitCursorPositionChanged() && alignmentChanged)
diff --git a/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp
index 1d63145b2f..861f7a9efc 100644
--- a/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp
+++ b/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp
@@ -144,6 +144,7 @@ private slots:
void canPaste();
void canPasteEmpty();
void textInput();
+ void inputPanelUpdate();
void openInputPanel();
void geometrySignals();
void pastingRichText_QTBUG_14003();
@@ -226,7 +227,7 @@ void tst_qquicktextedit::simulateKeys(QWindow *window, const QList<Key> &keys)
void tst_qquicktextedit::simulateKeys(QWindow *window, const QKeySequence &sequence)
{
- for (uint i = 0; i < sequence.count(); ++i) {
+ for (int i = 0; i < sequence.count(); ++i) {
const int key = sequence[i];
const int modifiers = key & Qt::KeyboardModifierMask;
@@ -236,7 +237,7 @@ void tst_qquicktextedit::simulateKeys(QWindow *window, const QKeySequence &seque
QList<Key> &operator <<(QList<Key> &keys, const QKeySequence &sequence)
{
- for (uint i = 0; i < sequence.count(); ++i)
+ for (int i = 0; i < sequence.count(); ++i)
keys << Key(sequence[i], QChar());
return keys;
}
@@ -2131,6 +2132,100 @@ void tst_qquicktextedit::textInput()
QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event2);
QCOMPARE(spy.count(), 1);
QCOMPARE(edit->text(), QString("string"));
+
+ QInputMethodQueryEvent queryEvent(Qt::ImEnabled);
+ QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &queryEvent);
+ QCOMPARE(queryEvent.value(Qt::ImEnabled).toBool(), true);
+
+ edit->setReadOnly(true);
+ QGuiApplication::sendEvent(edit, &queryEvent);
+ QCOMPARE(queryEvent.value(Qt::ImEnabled).toBool(), false);
+}
+
+void tst_qquicktextedit::inputPanelUpdate()
+{
+ PlatformInputContext platformInputContext;
+ QInputPanelPrivate *inputPanelPrivate = QInputPanelPrivate::get(qApp->inputPanel());
+ inputPanelPrivate->testContext = &platformInputContext;
+
+ QQuickView view(testFileUrl("inputMethodEvent.qml"));
+ view.show();
+ view.requestActivateWindow();
+ QTest::qWaitForWindowShown(&view);
+ QTRY_COMPARE(&view, qGuiApp->focusWindow());
+ QQuickTextEdit *edit = qobject_cast<QQuickTextEdit *>(view.rootObject());
+ QVERIFY(edit);
+ QVERIFY(edit->hasActiveFocus() == true);
+
+ // text change even without cursor position change needs to trigger update
+ edit->setText("test");
+ platformInputContext.clear();
+ edit->setText("xxxx");
+ QVERIFY(platformInputContext.m_updateCallCount > 0);
+
+ // input method event replacing text
+ platformInputContext.clear();
+ {
+ QInputMethodEvent inputMethodEvent;
+ inputMethodEvent.setCommitString("y", -1, 1);
+ QGuiApplication::sendEvent(edit, &inputMethodEvent);
+ }
+ QVERIFY(platformInputContext.m_updateCallCount > 0);
+
+ // input method changing selection
+ platformInputContext.clear();
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 0, 2, QVariant());
+ QInputMethodEvent inputMethodEvent("", attributes);
+ QGuiApplication::sendEvent(edit, &inputMethodEvent);
+ }
+ QVERIFY(edit->selectionStart() != edit->selectionEnd());
+ QVERIFY(platformInputContext.m_updateCallCount > 0);
+
+ // font changes
+ platformInputContext.clear();
+ QFont font = edit->font();
+ font.setBold(!font.bold());
+ edit->setFont(font);
+ QVERIFY(platformInputContext.m_updateCallCount > 0);
+
+ // normal input
+ platformInputContext.clear();
+ {
+ QInputMethodEvent inputMethodEvent;
+ inputMethodEvent.setCommitString("y");
+ QGuiApplication::sendEvent(edit, &inputMethodEvent);
+ }
+ QVERIFY(platformInputContext.m_updateCallCount > 0);
+
+ // changing cursor position
+ platformInputContext.clear();
+ edit->setCursorPosition(0);
+ QVERIFY(platformInputContext.m_updateCallCount > 0);
+
+ // continuing with selection
+ platformInputContext.clear();
+ edit->moveCursorSelection(1);
+ QVERIFY(platformInputContext.m_updateCallCount > 0);
+
+ // read only disabled input method
+ platformInputContext.clear();
+ edit->setReadOnly(true);
+ QVERIFY(platformInputContext.m_updateCallCount > 0);
+ edit->setReadOnly(false);
+
+ // no updates while no focus
+ edit->setFocus(false);
+ platformInputContext.clear();
+ edit->setText("Foo");
+ QCOMPARE(platformInputContext.m_updateCallCount, 0);
+ edit->setCursorPosition(1);
+ QCOMPARE(platformInputContext.m_updateCallCount, 0);
+ edit->selectAll();
+ QCOMPARE(platformInputContext.m_updateCallCount, 0);
+ edit->setReadOnly(true);
+ QCOMPARE(platformInputContext.m_updateCallCount, 0);
}
void tst_qquicktextedit::openInputPanel()
diff --git a/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp
index cae38bcd73..8fc768f2ab 100644
--- a/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp
+++ b/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp
@@ -222,7 +222,7 @@ void tst_qquicktextinput::simulateKeys(QWindow *window, const QList<Key> &keys)
void tst_qquicktextinput::simulateKeys(QWindow *window, const QKeySequence &sequence)
{
- for (uint i = 0; i < sequence.count(); ++i) {
+ for (int i = 0; i < sequence.count(); ++i) {
const int key = sequence[i];
const int modifiers = key & Qt::KeyboardModifierMask;
@@ -232,7 +232,7 @@ void tst_qquicktextinput::simulateKeys(QWindow *window, const QKeySequence &sequ
QList<Key> &operator <<(QList<Key> &keys, const QKeySequence &sequence)
{
- for (uint i = 0; i < sequence.count(); ++i)
+ for (int i = 0; i < sequence.count(); ++i)
keys << Key(sequence[i], QChar());
return keys;
}
@@ -1951,6 +1951,14 @@ void tst_qquicktextinput::inputMethods()
event.setCommitString("replacement", -input->text().length(), input->text().length());
QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event);
QCOMPARE(input->selectionStart(), input->selectionEnd());
+
+ QInputMethodQueryEvent enabledQueryEvent(Qt::ImEnabled);
+ QGuiApplication::sendEvent(input, &enabledQueryEvent);
+ QCOMPARE(enabledQueryEvent.value(Qt::ImEnabled).toBool(), true);
+
+ input->setReadOnly(true);
+ QGuiApplication::sendEvent(input, &enabledQueryEvent);
+ QCOMPARE(enabledQueryEvent.value(Qt::ImEnabled).toBool(), false);
}
/*
@@ -3081,6 +3089,24 @@ void tst_qquicktextinput::inputPanelUpdate()
platformInputContext.clear();
input->setCursorPosition(0);
QVERIFY(platformInputContext.m_updateCallCount > 0);
+
+ // read only disabled input method
+ platformInputContext.clear();
+ input->setReadOnly(true);
+ QVERIFY(platformInputContext.m_updateCallCount > 0);
+ input->setReadOnly(false);
+
+ // no updates while no focus
+ input->setFocus(false);
+ platformInputContext.clear();
+ input->setText("Foo");
+ QCOMPARE(platformInputContext.m_updateCallCount, 0);
+ input->setCursorPosition(1);
+ QCOMPARE(platformInputContext.m_updateCallCount, 0);
+ input->selectAll();
+ QCOMPARE(platformInputContext.m_updateCallCount, 0);
+ input->setReadOnly(true);
+ QCOMPARE(platformInputContext.m_updateCallCount, 0);
}
void tst_qquicktextinput::cursorRectangleSize()