iOS: only clear focus object if it supports IM

We try to keep a on-to-one relationship between UI controls with text input
and keyboard visibility. But if the control does not use text input, then
there is no reason for us to clear focus when the keyboard hides. In fact, we
should avoid doing so, since that will stop e.g buttons from working correctly.

The typical flow is:

- a touch release targeting a button is sendt to QApplication.
- QApplication transfers focus to the button.
- qiosinputcontext gets notified, we refuse, and clear focus again.
- QApplication enters a propagation loop where it tried to
    find out the receiver of the event. Since the button is now
    unfocused, the event will propagate up to a grandparent instead.
- the button will as such not trigger.

Change-Id: I70baa38299f40defc4a77f62790502e2d6ebbba9
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
bb10
Richard Moe Gustavsen 2014-12-04 14:57:53 +01:00
parent 87e9e76d97
commit de04841e19
2 changed files with 9 additions and 4 deletions

View File

@ -514,7 +514,8 @@ void QIOSInputContext::setFocusObject(QObject *focusObject)
qImDebug() << "new focus object =" << focusObject;
if (m_keyboardHideGesture.state == UIGestureRecognizerStateChanged) {
if (QPlatformInputContext::inputMethodAccepted()
&& m_keyboardHideGesture.state == UIGestureRecognizerStateChanged) {
// A new focus object may be set as part of delivering touch events to
// application during the hide-keyboard gesture, but we don't want that
// to result in a new object getting focus and bringing the keyboard up

View File

@ -263,10 +263,14 @@
// will set the new first-responder to our next-responder, and in the latter
// case we'll have an active responder candidate.
if ([UIResponder currentFirstResponder] == [self nextResponder]) {
// We have resigned the keyboard, and transferred back to the parent view, so unset focus object
// We have resigned the keyboard, and transferred first responder back to the parent view
Q_ASSERT(!FirstResponderCandidate::currentCandidate());
qImDebug() << "keyboard was closed, clearing focus object";
m_inputContext->clearCurrentFocusObject();
if ([self imValue:Qt::ImEnabled].toBool()) {
// The current focus object expects text input, but there
// is no keyboard to get input from. So we clear focus.
qImDebug() << "no keyboard available, clearing focus object";
m_inputContext->clearCurrentFocusObject();
}
} else {
// We've lost responder status because another Qt window was made active,
// another QIOSTextResponder was made first-responder, another UIView was