diff options
author | Tor Arne Vestbø <tor.arne.vestbo@digia.com> | 2014-10-16 15:37:48 +0200 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@digia.com> | 2014-10-28 13:05:05 +0100 |
commit | 50cadb87e8f7f8a9e064c86753f348a1e0f9c485 (patch) | |
tree | 3c9fc5dcdc6797bcff97919f860e0dd107ccd001 /src/plugins/platforms/ios | |
parent | 5a4fad14797d7cb0f7a65d5c546a0006475757e1 (diff) |
iOS: Detect window deactivation without waiting for next runloop iteration
Since we know and control whether or not we are making a new QUIView first
responder, we can take not of this at that point, and use that information
when another view is resigning first responder.
Change-Id: I508720d418c92dc8a8011b489cc5cace8fc82633
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@digia.com>
Diffstat (limited to 'src/plugins/platforms/ios')
-rw-r--r-- | src/plugins/platforms/ios/qiosglobal.h | 10 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qiosglobal.mm | 7 | ||||
-rw-r--r-- | src/plugins/platforms/ios/quiview.mm | 58 |
3 files changed, 58 insertions, 17 deletions
diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index fccb051645..dbedba7e85 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -71,4 +71,14 @@ QT_END_NAMESPACE +(id)currentFirstResponder; @end +class FirstResponderCandidate : public QScopedValueRollback<UIResponder *> +{ +public: + FirstResponderCandidate(UIResponder *); + static UIResponder *currentCandidate() { return s_firstResponderCandidate; } + +private: + static UIResponder *s_firstResponderCandidate; +}; + #endif // QIOSGLOBAL_H diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index e6d52f1850..bc16a7997d 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -168,5 +168,12 @@ int infoPlistValue(NSString* key, int defaultValue) } @end +FirstResponderCandidate::FirstResponderCandidate(UIResponder *responder) + : QScopedValueRollback<UIResponder *>(s_firstResponderCandidate, responder) +{ +} + +UIResponder *FirstResponderCandidate::s_firstResponderCandidate = 0; + QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index c46ed4c0b1..33e5b955e3 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -191,33 +191,57 @@ - (BOOL)becomeFirstResponder { - if ([super becomeFirstResponder]) { + FirstResponderCandidate firstResponderCandidate(self); + + qImDebug() << "win:" << m_qioswindow->window() << "self:" << self + << "first:" << [UIResponder currentFirstResponder]; + + if (![super becomeFirstResponder]) { + qImDebug() << m_qioswindow->window() + << "was not allowed to become first responder"; + return NO; + } + + qImDebug() << m_qioswindow->window() << "became first responder"; + + if (qGuiApp->focusWindow() != m_qioswindow->window()) { QWindowSystemInterface::handleWindowActivated(m_qioswindow->window()); QWindowSystemInterface::flushWindowSystemEvents(); - - return YES; + } else { + qImDebug() << m_qioswindow->window() + << "already active, not sending window activation"; } - return NO; + return YES; +} + +- (BOOL)responderShouldTriggerWindowDeactivation:(UIResponder *)responder +{ + // We don't want to send window deactivation in case the resign + // was a result of another Qt window becoming first responder. + if ([responder isKindOfClass:[QUIView class]]) + return NO; + + return YES; } - (BOOL)resignFirstResponder { - if ([super resignFirstResponder]) { - // We don't want to send window deactivation in case we're in the process - // of activating another window. The handleWindowActivated of the activation - // will take care of both. - dispatch_async(dispatch_get_main_queue (), ^{ - if (![[UIResponder currentFirstResponder] isKindOfClass:[QUIView class]]) { - QWindowSystemInterface::handleWindowActivated(0); - QWindowSystemInterface::flushWindowSystemEvents(); - } - }); - - return YES; + qImDebug() << "win:" << m_qioswindow->window() << "self:" << self + << "first:" << [UIResponder currentFirstResponder]; + + if (![super resignFirstResponder]) + return NO; + + qImDebug() << m_qioswindow->window() << "resigned first responder"; + + UIResponder *newResponder = FirstResponderCandidate::currentCandidate(); + if ([self responderShouldTriggerWindowDeactivation:newResponder]) { + QWindowSystemInterface::handleWindowActivated(0); + QWindowSystemInterface::flushWindowSystemEvents(); } - return NO; + return YES; } // ------------------------------------------------------------------------- |