From 5414d372d42278b146ce1cdf1096c4e91e7039ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 9 Apr 2018 15:27:00 +0200 Subject: iOS: Send window-system event also when embedded in native iOS app The iOS event dispatcher has been split into two; one dealing with the QPA event processing, which we should always do, and one dealing with the longjumping that we do when running the user's main on a separate stack. Change-Id: I1f819db33c608aad130ff23cbbadcf84363a32d2 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioseventdispatcher.h | 15 +++++- src/plugins/platforms/ios/qioseventdispatcher.mm | 64 ++++++++++++++---------- src/plugins/platforms/ios/qiosintegration.mm | 5 +- 3 files changed, 51 insertions(+), 33 deletions(-) diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index 62133b9510..1f4c78dc74 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -49,18 +49,29 @@ class QIOSEventDispatcher : public QEventDispatcherCoreFoundation Q_OBJECT public: + static QIOSEventDispatcher* create(); + bool processPostedEvents() override; + +protected: explicit QIOSEventDispatcher(QObject *parent = 0); +}; + +class QIOSJumpingEventDispatcher : public QIOSEventDispatcher +{ + Q_OBJECT +public: + QIOSJumpingEventDispatcher(QObject *parent = 0); bool processEvents(QEventLoop::ProcessEventsFlags flags) override; - bool processPostedEvents() override; + // Public since we can't friend Objective-C methods void handleRunLoopExit(CFRunLoopActivity activity); void interruptEventLoopExec(); private: uint m_processEventLevel; - RunLoopObserver m_runLoopExitObserver; + RunLoopObserver m_runLoopExitObserver; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index d5f74881ab..6a6e1bd618 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -425,7 +425,7 @@ static const char kApplicationWillTerminateExitCode = char(SIGTERM | 0x80); // QEventLoop::exec(). We initiate the return manually as a workaround. qCDebug(lcEventDispatcher) << "Manually triggering return from event loop exec"; applicationWillTerminateActivity.leave(); - static_cast(qApp->eventDispatcher())->interruptEventLoopExec(); + static_cast(qApp->eventDispatcher())->interruptEventLoopExec(); break; case kJumpedFromUserMainTrampoline: applicationWillTerminateActivity.enter(); @@ -443,20 +443,49 @@ static const char kApplicationWillTerminateExitCode = char(SIGTERM | 0x80); QT_BEGIN_NAMESPACE QT_USE_NAMESPACE +QIOSEventDispatcher *QIOSEventDispatcher::create() +{ + if (isQtApplication() && rootLevelRunLoopIntegration()) + return new QIOSJumpingEventDispatcher; + + return new QIOSEventDispatcher; +} + QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent) : QEventDispatcherCoreFoundation(parent) - , m_processEventLevel(0) - , m_runLoopExitObserver(this, &QIOSEventDispatcher::handleRunLoopExit, kCFRunLoopExit) { // We want all delivery of events from the system to be handled synchronously QWindowSystemInterface::setSynchronousWindowSystemEvents(true); } -bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) +/*! + Override of the CoreFoundation posted events runloop source callback + so that we can send window system (QPA) events in addition to sending + normal Qt events. +*/ +bool QIOSEventDispatcher::processPostedEvents() { - if (!rootLevelRunLoopIntegration()) - return QEventDispatcherCoreFoundation::processEvents(flags); + // Don't send window system events if the base CF dispatcher has determined + // that events should not be sent for this pass of the runloop source. + if (!QEventDispatcherCoreFoundation::processPostedEvents()) + return false; + + QT_APPLE_SCOPED_LOG_ACTIVITY(lcEventDispatcher().isDebugEnabled(), "sendWindowSystemEvents"); + qCDebug(lcEventDispatcher) << "Sending window system events for" << m_processEvents.flags; + QWindowSystemInterface::sendWindowSystemEvents(m_processEvents.flags); + + return true; +} +QIOSJumpingEventDispatcher::QIOSJumpingEventDispatcher(QObject *parent) + : QIOSEventDispatcher(parent) + , m_processEventLevel(0) + , m_runLoopExitObserver(this, &QIOSJumpingEventDispatcher::handleRunLoopExit, kCFRunLoopExit) +{ +} + +bool __attribute__((returns_twice)) QIOSJumpingEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) +{ if (applicationAboutToTerminate) { qCDebug(lcEventDispatcher) << "Detected QEventLoop exec after application termination"; // Re-issue exit, and return immediately @@ -500,26 +529,7 @@ bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoo return processedEvents; } -/*! - Override of the CoreFoundation posted events runloop source callback - so that we can send window system (QPA) events in addition to sending - normal Qt events. -*/ -bool QIOSEventDispatcher::processPostedEvents() -{ - // Don't send window system events if the base CF dispatcher has determined - // that events should not be sent for this pass of the runloop source. - if (!QEventDispatcherCoreFoundation::processPostedEvents()) - return false; - - QT_APPLE_SCOPED_LOG_ACTIVITY(lcEventDispatcher().isDebugEnabled(), "sendWindowSystemEvents"); - qCDebug(lcEventDispatcher) << "Sending window system events for" << m_processEvents.flags; - QWindowSystemInterface::sendWindowSystemEvents(m_processEvents.flags); - - return true; -} - -void QIOSEventDispatcher::handleRunLoopExit(CFRunLoopActivity activity) +void QIOSJumpingEventDispatcher::handleRunLoopExit(CFRunLoopActivity activity) { Q_UNUSED(activity); Q_ASSERT(activity == kCFRunLoopExit); @@ -528,7 +538,7 @@ void QIOSEventDispatcher::handleRunLoopExit(CFRunLoopActivity activity) interruptEventLoopExec(); } -void QIOSEventDispatcher::interruptEventLoopExec() +void QIOSJumpingEventDispatcher::interruptEventLoopExec() { Q_ASSERT(m_processEventLevel == 1); diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 5f9f7ad96d..73ae72c87a 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -214,10 +214,7 @@ QPlatformOffscreenSurface *QIOSIntegration::createPlatformOffscreenSurface(QOffs QAbstractEventDispatcher *QIOSIntegration::createEventDispatcher() const { - if (isQtApplication()) - return new QIOSEventDispatcher; - else - return new QEventDispatcherCoreFoundation; + return QIOSEventDispatcher::create(); } QPlatformFontDatabase * QIOSIntegration::fontDatabase() const -- cgit v1.2.3