From 719a6fd50d590e819fa541dc5b31661b38537344 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 28 Oct 2014 12:54:26 +0100 Subject: iOS: Allow virtual keyboard to be hidden by QInputMethod::hide() Calling the function has the same effect as dismissing the keyboard using the native keyboard dismiss button or the hide-keyboard gesture, and will result in the QIOSTextInputResponder losing first-responder status and the current focus object being cleared. QtWidgets and other parts of Qt will try to hide the keyboard during focus changes between widgets, which we already take care of when the focus object changes, so we detect the situation and ignore it, by requiring that the current focus object matches the one we've brought up the text responder for. Showing the virtual keyboard is still a no-op, as there is no way to show the virtual keyboard without a focus-object. Change-Id: Iefcb403c2b6d3da8a4df3fcd53bc1244ba9c4d23 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosinputcontext.h | 3 ++- src/plugins/platforms/ios/qiosinputcontext.mm | 21 ++++++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h index f07408db81..1f1130f932 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.h +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -51,9 +51,10 @@ QT_BEGIN_NAMESPACE struct ImeState { - ImeState() : currentState(0) {} + ImeState() : currentState(0), focusObject(0) {} Qt::InputMethodQueries update(Qt::InputMethodQueries properties); QInputMethodQueryEvent currentState; + QObject *focusObject; }; class QIOSInputContext : public QPlatformInputContext diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index acdf6d9715..072a49c7c5 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -300,8 +300,11 @@ Qt::InputMethodQueries ImeState::update(Qt::InputMethodQueries properties) QInputMethodQueryEvent newState(properties); - if (qApp && qApp->focusObject()) - QCoreApplication::sendEvent(qApp->focusObject(), &newState); + // Update the focus object that the new state is based on + focusObject = qApp ? qApp->focusObject() : 0; + + if (focusObject) + QCoreApplication::sendEvent(focusObject, &newState); Qt::InputMethodQueries updatedProperties; for (uint i = 0; i < (sizeof(Qt::ImQueryAll) * CHAR_BIT); ++i) { @@ -348,11 +351,23 @@ QRectF QIOSInputContext::keyboardRect() const void QIOSInputContext::showInputPanel() { // No-op, keyboard controlled fully by platform based on focus + qImDebug() << "can't show virtual keyboard without a focus object, ignoring"; } void QIOSInputContext::hideInputPanel() { - // No-op, keyboard controlled fully by platform based on focus + if (![m_textResponder isFirstResponder]) { + qImDebug() << "QIOSTextInputResponder is not first responder, ignoring"; + return; + } + + if (qGuiApp->focusObject() != m_imeState.focusObject) { + qImDebug() << "current focus object does not match IM state, likely hiding from focusOut event, so ignoring"; + return; + } + + qImDebug() << "hiding VKB as requested by QInputMethod::hide()"; + [m_textResponder resignFirstResponder]; } void QIOSInputContext::clearCurrentFocusObject() -- cgit v1.2.3