diff options
author | Richard Moe Gustavsen <richard.gustavsen@digia.com> | 2014-03-20 10:22:46 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-03-29 10:39:11 +0100 |
commit | 46acfa5d2ab803d8b5fbfbcdd826650b94624187 (patch) | |
tree | ffa68378f3bd2c31ec6598dca1968f913ddd2995 /src/plugins | |
parent | cd1f44a9fcc2b15af0b08451db93652fa6ffca8f (diff) |
iOS: stop keyboard from reopending after the gesture finishes
On iOS we have set the style hint 'SetFocusOnTouchRelease'. This is in
conflict with the 'hide keyboard' gesture, since a control can
try to regain focus (and open the keyboard) if the gesture ends
on top of it. So we need some extra work-around code to prevent this
from happening.
The correct way would probably be to cancel the touch sequence once
the gesture triggers, but this is not well implemented in Qt yet,
especially in combination with widgets and mouse synthesis.
Since usage of the gesture behaves really bad in some cases (e.g
if using the TextEdit example) we need to apply this for now.
Change-Id: Ib3327c0bd94d722b4c4793bc6d152d6d19810e4b
Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@digia.com>
Diffstat (limited to 'src/plugins')
-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. |