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> (cherry picked from commit 5414d372d42278b146ce1cdf1096c4e91e7039ad)
This commit is contained in:
parent
dc55000140
commit
0b1342f374
@ -49,18 +49,29 @@ class QIOSEventDispatcher : public QEventDispatcherCoreFoundation
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit QIOSEventDispatcher(QObject *parent = 0);
|
static QIOSEventDispatcher* create();
|
||||||
|
|
||||||
bool processEvents(QEventLoop::ProcessEventsFlags flags) override;
|
|
||||||
bool processPostedEvents() override;
|
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;
|
||||||
|
|
||||||
|
// Public since we can't friend Objective-C methods
|
||||||
void handleRunLoopExit(CFRunLoopActivity activity);
|
void handleRunLoopExit(CFRunLoopActivity activity);
|
||||||
|
|
||||||
void interruptEventLoopExec();
|
void interruptEventLoopExec();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint m_processEventLevel;
|
uint m_processEventLevel;
|
||||||
RunLoopObserver<QIOSEventDispatcher> m_runLoopExitObserver;
|
RunLoopObserver<QIOSJumpingEventDispatcher> m_runLoopExitObserver;
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -403,7 +403,7 @@ static const char kApplicationWillTerminateExitCode = char(SIGTERM | 0x80);
|
|||||||
// so we'll never see the exit activity and have a chance to return from
|
// so we'll never see the exit activity and have a chance to return from
|
||||||
// QEventLoop::exec(). We initiate the return manually as a workaround.
|
// QEventLoop::exec(). We initiate the return manually as a workaround.
|
||||||
qCDebug(lcEventDispatcher) << "Manually triggering return from event loop exec";
|
qCDebug(lcEventDispatcher) << "Manually triggering return from event loop exec";
|
||||||
static_cast<QIOSEventDispatcher *>(qApp->eventDispatcher())->interruptEventLoopExec();
|
static_cast<QIOSJumpingEventDispatcher *>(qApp->eventDispatcher())->interruptEventLoopExec();
|
||||||
break;
|
break;
|
||||||
case kJumpedFromUserMainTrampoline:
|
case kJumpedFromUserMainTrampoline:
|
||||||
// The user's main has returned, so we're ready to let iOS terminate the application
|
// The user's main has returned, so we're ready to let iOS terminate the application
|
||||||
@ -419,20 +419,48 @@ static const char kApplicationWillTerminateExitCode = char(SIGTERM | 0x80);
|
|||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
QT_USE_NAMESPACE
|
QT_USE_NAMESPACE
|
||||||
|
|
||||||
|
QIOSEventDispatcher *QIOSEventDispatcher::create()
|
||||||
|
{
|
||||||
|
if (isQtApplication() && rootLevelRunLoopIntegration())
|
||||||
|
return new QIOSJumpingEventDispatcher;
|
||||||
|
|
||||||
|
return new QIOSEventDispatcher;
|
||||||
|
}
|
||||||
|
|
||||||
QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent)
|
QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent)
|
||||||
: QEventDispatcherCoreFoundation(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
|
// We want all delivery of events from the system to be handled synchronously
|
||||||
QWindowSystemInterface::setSynchronousWindowSystemEvents(true);
|
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())
|
// Don't send window system events if the base CF dispatcher has determined
|
||||||
return QEventDispatcherCoreFoundation::processEvents(flags);
|
// that events should not be sent for this pass of the runloop source.
|
||||||
|
if (!QEventDispatcherCoreFoundation::processPostedEvents())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
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) {
|
if (applicationAboutToTerminate) {
|
||||||
qCDebug(lcEventDispatcher) << "Detected QEventLoop exec after application termination";
|
qCDebug(lcEventDispatcher) << "Detected QEventLoop exec after application termination";
|
||||||
// Re-issue exit, and return immediately
|
// Re-issue exit, and return immediately
|
||||||
@ -475,25 +503,7 @@ bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoo
|
|||||||
return processedEvents;
|
return processedEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
void QIOSJumpingEventDispatcher::handleRunLoopExit(CFRunLoopActivity activity)
|
||||||
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;
|
|
||||||
|
|
||||||
qCDebug(lcEventDispatcher) << "Sending window system events for" << m_processEvents.flags;
|
|
||||||
QWindowSystemInterface::sendWindowSystemEvents(m_processEvents.flags);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QIOSEventDispatcher::handleRunLoopExit(CFRunLoopActivity activity)
|
|
||||||
{
|
{
|
||||||
Q_UNUSED(activity);
|
Q_UNUSED(activity);
|
||||||
Q_ASSERT(activity == kCFRunLoopExit);
|
Q_ASSERT(activity == kCFRunLoopExit);
|
||||||
@ -502,7 +512,7 @@ void QIOSEventDispatcher::handleRunLoopExit(CFRunLoopActivity activity)
|
|||||||
interruptEventLoopExec();
|
interruptEventLoopExec();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QIOSEventDispatcher::interruptEventLoopExec()
|
void QIOSJumpingEventDispatcher::interruptEventLoopExec()
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_processEventLevel == 1);
|
Q_ASSERT(m_processEventLevel == 1);
|
||||||
|
|
||||||
|
@ -217,10 +217,7 @@ QPlatformOffscreenSurface *QIOSIntegration::createPlatformOffscreenSurface(QOffs
|
|||||||
|
|
||||||
QAbstractEventDispatcher *QIOSIntegration::createEventDispatcher() const
|
QAbstractEventDispatcher *QIOSIntegration::createEventDispatcher() const
|
||||||
{
|
{
|
||||||
if (isQtApplication())
|
return QIOSEventDispatcher::create();
|
||||||
return new QIOSEventDispatcher;
|
|
||||||
else
|
|
||||||
return new QEventDispatcherCoreFoundation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPlatformFontDatabase * QIOSIntegration::fontDatabase() const
|
QPlatformFontDatabase * QIOSIntegration::fontDatabase() const
|
||||||
|
Loading…
x
Reference in New Issue
Block a user