diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2018-04-09 15:27:00 +0200 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2018-04-10 13:28:57 +0000 |
commit | 5414d372d42278b146ce1cdf1096c4e91e7039ad (patch) | |
tree | 9bfa13b7c1b8c407b92a44e5dc297c699ae3775c /src | |
parent | fdc28956c91f385ed1d049a62f99d0b714fd9eff (diff) | |
download | qtbase-5414d372d42278b146ce1cdf1096c4e91e7039ad.tar.gz |
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 <richard.gustavsen@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/platforms/ios/qioseventdispatcher.h | 15 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qioseventdispatcher.mm | 64 | ||||
-rw-r--r-- | 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<QIOSEventDispatcher> m_runLoopExitObserver; + RunLoopObserver<QIOSJumpingEventDispatcher> 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<QIOSEventDispatcher *>(qApp->eventDispatcher())->interruptEventLoopExec(); + static_cast<QIOSJumpingEventDispatcher *>(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 |