From 02f1e72d5a18040832a9dd1426b176e5ba769f2f Mon Sep 17 00:00:00 2001 From: Bartlomiej Moskal Date: Fri, 9 Sep 2022 09:55:56 +0200 Subject: [PATCH] Android: Set EnterKeyNext as default type for QLineEdit Behavior of EnterKey for virtual keyboard need to be changed for QLineEdit. Before this commit, ImeOption was set to IME_ACTION_DONE. Because of that, setting any text in QLineEdit automatically accept QDialogs. That was annoying, when more than one QLineEdit need to be set. [ChangeLog][Widgets][Android] EnterKey type is now changed from EnterKeyDefault to EnterKeyNext for virtual keyboard in QLineEdit. It is done only if the focus can be moved to widget below. Fixes: QTBUG-61652 Change-Id: I98a7686f9f675fccf0112b8d27d48ad8fd7a887f Reviewed-by: Assam Boudjelthia Reviewed-by: Ville Voutilainen --- src/widgets/widgets/qlineedit.cpp | 16 ++++++++++ .../widgets/qlineedit/tst_qlineedit.cpp | 29 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index c38f3db7a19..aad75207a1c 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -1802,6 +1802,22 @@ void QLineEdit::inputMethodEvent(QInputMethodEvent *e) */ QVariant QLineEdit::inputMethodQuery(Qt::InputMethodQuery property) const { +#ifdef Q_OS_ANDROID + // QTBUG-61652 + if (property == Qt::ImEnterKeyType) { + QWidget *next = nextInFocusChain(); + while (next && next != this && next->focusPolicy() == Qt::NoFocus) + next = next->nextInFocusChain(); + if (next) { + const auto nextYPos = next->mapToGlobal(QPoint(0, 0)).y(); + const auto currentYPos = mapToGlobal(QPoint(0, 0)).y(); + if (currentYPos < nextYPos) + // Set EnterKey to KeyNext type only if the next widget + // in the focus chain is below current QLineEdit + return Qt::EnterKeyNext; + } + } +#endif return inputMethodQuery(property, QVariant()); } diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp index 74a011d96dc..efd59059d09 100644 --- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp @@ -267,6 +267,8 @@ private slots: void inputMethodQueryImHints_data(); void inputMethodQueryImHints(); + void inputMethodQueryEnterKeyType(); + void inputMethodUpdate(); void undoRedoAndEchoModes_data(); @@ -4409,6 +4411,33 @@ void tst_QLineEdit::inputMethodQueryImHints() QCOMPARE(static_cast(value.toInt()), hints); } +void tst_QLineEdit::inputMethodQueryEnterKeyType() +{ + QWidget mw; + QVBoxLayout layout(&mw); + QLineEdit le1(&mw); + layout.addWidget(&le1); + mw.show(); + QVariant enterType = le1.inputMethodQuery(Qt::ImEnterKeyType); + QCOMPARE(enterType.value(), Qt::EnterKeyDefault); + + mw.hide(); + QLineEdit le2(&mw); + layout.addWidget(&le2); + mw.show(); + + enterType = le1.inputMethodQuery(Qt::ImEnterKeyType); +#ifdef Q_OS_ANDROID + // QTBUG-61652 + // EnterKey is changed to EnterKeyNext if the focus can be moved to widget below + QCOMPARE(enterType.value(), Qt::EnterKeyNext); +#else + QCOMPARE(enterType.value(), Qt::EnterKeyDefault); +#endif + enterType = le2.inputMethodQuery(Qt::ImEnterKeyType); + QCOMPARE(enterType.value(), Qt::EnterKeyDefault); +} + void tst_QLineEdit::inputMethodUpdate() { if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))