diff options
-rw-r--r-- | src/gui/kernel/qinputmethod.cpp | 6 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 14 | ||||
-rw-r--r-- | tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 31 |
3 files changed, 48 insertions, 3 deletions
diff --git a/src/gui/kernel/qinputmethod.cpp b/src/gui/kernel/qinputmethod.cpp index ea1978b5fb..e37e85e246 100644 --- a/src/gui/kernel/qinputmethod.cpp +++ b/src/gui/kernel/qinputmethod.cpp @@ -399,7 +399,11 @@ QVariant QInputMethod::queryFocusObject(Qt::InputMethodQuery query, const QVaria Q_ARG(Qt::InputMethodQuery, query), Q_ARG(QVariant, argument)); Q_ASSERT(ok); - return retval; + if (retval.isValid()) + return retval; + + // If the new API didn't have an answer to the query, we fall + // back to use the old event-based API. } QInputMethodQueryEvent queryEvent(query); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index cf32ff6c93..1160471194 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -8896,8 +8896,18 @@ bool QWidget::event(QEvent *event) Qt::InputMethodQuery q = (Qt::InputMethodQuery)(int)(queries & (1<<i)); if (q) { QVariant v = inputMethodQuery(q); - if (q == Qt::ImEnabled && !v.isValid() && isEnabled()) - v = QVariant(true); // special case for Qt4 compatibility + if (q == Qt::ImEnabled && !v.isValid() && isEnabled()) { + // Qt:ImEnabled was added in Qt 5.3. So not all widgets support it, even + // if they implement IM otherwise (and override inputMethodQuery()). + // So for legacy reasons, we need to check by other means if IM is supported when + // Qt::ImEnabled is not implemented (the query returns an invalid QVariant). + // Since QWidget implements inputMethodQuery(), and return valid values for + // some of the IM properties, we cannot just query for Qt::ImQueryAll. + // Instead we assume that if a widget supports IM, it will implement + // Qt::ImSurroundingText (which is not implemented by QWidget). + const bool imEnabledFallback = inputMethodQuery(Qt::ImSurroundingText).isValid(); + v = QVariant(imEnabledFallback); + } query->setValue(q, v); } } diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index f65882611b..397a1cf8df 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -369,6 +369,8 @@ private slots: void focusProxy(); void focusProxyAndInputMethods(); + void imEnabledNotImplemented(); + #ifdef QT_BUILD_INTERNAL void scrollWithoutBackingStore(); #endif @@ -10982,6 +10984,35 @@ void tst_QWidget::focusProxyAndInputMethods() QCOMPARE(qApp->focusObject(), toplevel.data()); } +void tst_QWidget::imEnabledNotImplemented() +{ + // Check that a plain widget doesn't report that it supports IM. Only + // widgets that implements either Qt::ImEnabled, or the Qt4 backup + // solution, Qt::ImSurroundingText, should do so. + QWidget topLevel; + QWidget plain(&topLevel); + QLineEdit edit(&topLevel); + topLevel.show(); + + QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); + QApplication::setActiveWindow(&topLevel); + QVERIFY(QTest::qWaitForWindowActive(&topLevel)); + + // A plain widget should return false for ImEnabled + plain.setFocus(Qt::OtherFocusReason); + QCOMPARE(QApplication::focusWidget(), &plain); + QVariant imEnabled = QApplication::inputMethod()->queryFocusObject(Qt::ImEnabled, QVariant()); + QVERIFY(imEnabled.isValid()); + QVERIFY(!imEnabled.toBool()); + + // But a lineedit should return true + edit.setFocus(Qt::OtherFocusReason); + QCOMPARE(QApplication::focusWidget(), &edit); + imEnabled = QApplication::inputMethod()->queryFocusObject(Qt::ImEnabled, QVariant()); + QVERIFY(imEnabled.isValid()); + QVERIFY(imEnabled.toBool()); +} + #ifdef QT_BUILD_INTERNAL class scrollWidgetWBS : public QWidget { |