From 0a9a4e826fc0a3909481f40d77708a86be55a345 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 16 Jan 2013 10:42:31 +0100 Subject: iOS: let first responder follow the view of the focus window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This to ensure that the keyboard does not close prematurly. This can happen if the user opens up the keyboard while typing inside one window, then switch window, continue typing while the other window gets deleted. Change-Id: I5cfb1673ccbe4d5aaa14167b7aa53451031089a1 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosinputcontext.h | 3 +++ src/plugins/platforms/ios/qiosinputcontext.mm | 33 ++++++++++++--------------- src/plugins/platforms/ios/qioswindow.mm | 5 ++++ 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h index ceed5ffaf2..176ad05733 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.h +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -61,8 +61,11 @@ public: void hideInputPanel(); bool isInputPanelVisible() const; + void focusViewChanged(UIView *view); + private: QIOSKeyboardListener *m_keyboardListener; + UIView *m_focusView; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index 89d210cb54..c0ff3b2531 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -98,12 +98,14 @@ QIOSInputContext::QIOSInputContext() : QPlatformInputContext() , m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this]) + , m_focusView(0) { } QIOSInputContext::~QIOSInputContext() { [m_keyboardListener release]; + [m_focusView release]; } QRectF QIOSInputContext::keyboardRect() const @@ -113,33 +115,28 @@ QRectF QIOSInputContext::keyboardRect() const void QIOSInputContext::showInputPanel() { - if (isInputPanelVisible()) - return; - // Documentation tells that one should call (and recall, if necessary) becomeFirstResponder/resignFirstResponder // to show/hide the keyboard. This is slightly inconvenient, since there exist no API to get the current first - // responder. Rather than searching for it from the top, we assume that the view backing the focus window in Qt - // is the best candidate as long as there exist no first responder from before (which the isInputPanelVisible - // test on top should catch). Note that Qt will forward keyevents to whichever QObject that needs it, regardless of - // which UIView the input actually came from. So in this respect, we're undermining iOS' responder chain. - if (QWindow *window = QGuiApplication::focusWindow()) { - QIOSWindow *qiosWindow = static_cast(window->handle()); - [qiosWindow->nativeView() becomeFirstResponder]; - } + // responder. Rather than searching for it from the top, we let the active QIOSWindow tell us which view to use. + // Note that Qt will forward keyevents to whichever QObject that needs it, regardless of which UIView the input + // actually came from. So in this respect, we're undermining iOS' responder chain. + [m_focusView becomeFirstResponder]; } void QIOSInputContext::hideInputPanel() { - if (!isInputPanelVisible()) - return; - - if (QWindow *window = QGuiApplication::focusWindow()) { - QIOSWindow *qiosWindow = static_cast(window->handle()); - [qiosWindow->nativeView() resignFirstResponder]; - } + [m_focusView resignFirstResponder]; } bool QIOSInputContext::isInputPanelVisible() const { return m_keyboardListener->m_keyboardVisible; } + +void QIOSInputContext::focusViewChanged(UIView *view) +{ + if ([m_focusView isFirstResponder]) + [view becomeFirstResponder]; + [m_focusView release]; + m_focusView = [view retain]; +} diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 59f82fb64e..c5d9cbe323 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -42,9 +42,12 @@ #include "qiosglobal.h" #include "qioswindow.h" #include "qioscontext.h" +#include "qiosinputcontext.h" #include "qiosscreen.h" #include "qiosapplicationdelegate.h" #include "qiosviewcontroller.h" +#include +#include #import @@ -327,6 +330,8 @@ void QIOSWindow::requestActivateWindow() // hierarchy (transient children). But only one window can be QGuiApplication::focusWindow(). // Dispite the name, 'requestActivateWindow' means raise and transfer focus to the window: raise(); + QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext(); + static_cast(context)->focusViewChanged(m_view); QPlatformWindow::requestActivateWindow(); } -- cgit v1.2.3