iOS: let first responder follow the view of the focus window
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ø <tor.arne.vestbo@digia.com>
This commit is contained in:
parent
73e8796603
commit
0a9a4e826f
@ -61,8 +61,11 @@ public:
|
||||
void hideInputPanel();
|
||||
bool isInputPanelVisible() const;
|
||||
|
||||
void focusViewChanged(UIView *view);
|
||||
|
||||
private:
|
||||
QIOSKeyboardListener *m_keyboardListener;
|
||||
UIView *m_focusView;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -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<QIOSWindow *>(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<QIOSWindow *>(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];
|
||||
}
|
||||
|
@ -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 <QtGui/private/qguiapplication_p.h>
|
||||
#include <qpa/qplatformintegration.h>
|
||||
|
||||
#import <QuartzCore/CAEAGLLayer.h>
|
||||
|
||||
@ -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<QIOSInputContext *>(context)->focusViewChanged(m_view);
|
||||
QPlatformWindow::requestActivateWindow();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user