summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@digia.com>2014-10-16 15:37:48 +0200
committerTor Arne Vestbø <tor.arne.vestbo@digia.com>2014-10-28 13:05:05 +0100
commit50cadb87e8f7f8a9e064c86753f348a1e0f9c485 (patch)
tree3c9fc5dcdc6797bcff97919f860e0dd107ccd001 /src
parent5a4fad14797d7cb0f7a65d5c546a0006475757e1 (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')
-rw-r--r--src/plugins/platforms/ios/qiosglobal.h10
-rw-r--r--src/plugins/platforms/ios/qiosglobal.mm7
-rw-r--r--src/plugins/platforms/ios/quiview.mm58
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;
}
// -------------------------------------------------------------------------