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>
This commit is contained in:
parent
5a4fad1479
commit
50cadb87e8
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -191,33 +191,57 @@
|
||||
|
||||
- (BOOL)becomeFirstResponder
|
||||
{
|
||||
if ([super becomeFirstResponder]) {
|
||||
QWindowSystemInterface::handleWindowActivated(m_qioswindow->window());
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
FirstResponderCandidate firstResponderCandidate(self);
|
||||
|
||||
return YES;
|
||||
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;
|
||||
}
|
||||
|
||||
return NO;
|
||||
qImDebug() << m_qioswindow->window() << "became first responder";
|
||||
|
||||
if (qGuiApp->focusWindow() != m_qioswindow->window()) {
|
||||
QWindowSystemInterface::handleWindowActivated(m_qioswindow->window());
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
} else {
|
||||
qImDebug() << m_qioswindow->window()
|
||||
<< "already active, not sending window activation";
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
});
|
||||
qImDebug() << "win:" << m_qioswindow->window() << "self:" << self
|
||||
<< "first:" << [UIResponder currentFirstResponder];
|
||||
|
||||
return YES;
|
||||
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;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user