diff options
-rw-r--r-- | src/plugins/platforms/ios/qiosinputcontext.mm | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index f5d1b8f220..ab4e3f38e7 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -47,6 +47,7 @@ #include "qioswindow.h" #include "quiview.h" #include <QGuiApplication> +#include <QtGui/private/qwindow_p.h> @interface QIOSKeyboardListener : UIGestureRecognizer { @public @@ -54,6 +55,7 @@ BOOL m_keyboardVisible; BOOL m_keyboardVisibleAndDocked; BOOL m_ignoreKeyboardChanges; + BOOL m_keyboardHiddenByGesture; QRectF m_keyboardRect; QRectF m_keyboardEndRect; NSTimeInterval m_duration; @@ -72,6 +74,7 @@ m_keyboardVisible = NO; m_keyboardVisibleAndDocked = NO; m_ignoreKeyboardChanges = NO; + m_keyboardHiddenByGesture = NO; m_duration = 0; m_curve = UIViewAnimationCurveEaseOut; m_viewController = 0; @@ -175,7 +178,11 @@ // Note that UIKeyboardWillHideNotification is also sendt when the keyboard is undocked. m_keyboardVisibleAndDocked = NO; m_keyboardEndRect = [self getKeyboardRect:notification]; - self.enabled = NO; + if (!m_keyboardHiddenByGesture) { + // Only disable the gesture if the hiding of the keyboard was not caused by it. + // Otherwise we need to await the final touchEnd callback for doing some clean-up. + self.enabled = NO; + } m_context->scroll(0); } @@ -198,12 +205,35 @@ - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { QPointF p = fromCGPoint([[touches anyObject] locationInView:m_viewController.view]); - if (m_keyboardRect.contains(p)) + if (m_keyboardRect.contains(p)) { + m_keyboardHiddenByGesture = YES; m_context->hideInputPanel(); + } [super touchesMoved:touches withEvent:event]; } +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + [self performSelectorOnMainThread:@selector(touchesEndedPostDelivery) withObject:nil waitUntilDone:NO]; + [super touchesEnded:touches withEvent:event]; +} + +- (void)touchesEndedPostDelivery +{ + // Do some clean-up _after_ touchEnd has been delivered to QUIView + m_keyboardHiddenByGesture = NO; + if (!m_keyboardVisibleAndDocked) { + self.enabled = NO; + if (qApp->focusObject()) { + // UI Controls are told to gain focus on touch release. So when the 'hide keyboard' gesture + // finishes, the final touch end can trigger a control to gain focus. This is in conflict with + // the gesture, so we clear focus once more as a work-around. + static_cast<QWindowPrivate *>(QObjectPrivate::get(qApp->focusWindow()))->clearFocusObject(); + } + } +} + @end QIOSInputContext::QIOSInputContext() @@ -230,6 +260,12 @@ QRectF QIOSInputContext::keyboardRect() const void QIOSInputContext::showInputPanel() { + if (m_keyboardListener->m_keyboardHiddenByGesture) { + // We refuse to re-show the keyboard until the touch + // sequence that triggered the gesture has ended. + 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 let the active QIOSWindow tell us which view to use. |