summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.mm40
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.