path: root/src/plugins/platforms/ios/qioseventdispatcher.h
diff options
authorTor Arne Vestbø <>2013-06-06 15:42:16 +0200
committerThe Qt Project <>2013-09-13 14:08:44 +0200
commit59601e06d96edb5661a3dd91341d74e16dc6b229 (patch)
tree3d914cc9b0645aeeda135403cadb17c7d2546533 /src/plugins/platforms/ios/qioseventdispatcher.h
parent52b827d11b501511b0ec5c2ee9a395e2adcaf0d8 (diff)
iOS: Interleave Qt application main() with iOS startup sequence
Our previous event loop integration had two unfortunate flaws: 1. We would call qt_user_main() from a timer, after returning from didFinishLaunchingWithOptions. This had the effect of showing the iOS application window long before the Qt application UI had been set up, resulting in a 1-2 second flash of black/pink between the launch image disappearing and the actual application showing. 2. We spun a nested event loop, where our implementation of the different event loop modes did not perfectly match the Apple implementation. This resulted in scrolling being busted in some cases such as when showing the virtual keyboard for Emoji characters. These two issues have now been solved by calling the user's main() from didFinishLaunchingWithOptions. Normally this would not work, as the user's main would call QApplication::exec() at the end of their main(), which would block and we would never return back from the didFinishLaunchingWithOptions callback, resulting in no UI on screen. We work around this by longjmp'ing out of QApplication::exec(), back into didFinishLaunchingWithOptions, so that it can return. Again, this would normally not work, as the call stack where QApplication and friends would live would get smashed as the application continued executing. We work around this by allocating a block of stack space at the start of main(), which we then redirect the stack pointer to before calling the user's main. This results in the whole stack of the user's main() and below being preserved, even if we longjmp out of the call stack (which then restores the stack pointer). This approach should work fine together with garbage-collection as well, since the mark-and-sweep phase will walk the stack from the stack pointer to the stack base, including sections of the stack that were part of qt_user_main() and live in the reserved area. One case where GC will fail though is if it happens as part of the qt_user_main() call, where the GC will not mark anything in the 'real' callstack below UIApplicationMain(), but this is not expected to happen. The size of the reserved stack can be controlled through the Info.plist key 'QtRunLoopIntegrationStackSize', as well as the 'QtRunLoopIntegrationDisableSeparateStack' key to disable the separate stack approach completely. This will fall back to the old approach. The amount of stack space used by the user's main can be determined by enabling a special debugging mode, using the 'QtRunLoopIntegrationDebugStackUsage' key. Change-Id: I2af7a6cfe1a006a80fd220ed83d8a66d4c45b523 Reviewed-by: Simon Hausmann <>
Diffstat (limited to 'src/plugins/platforms/ios/qioseventdispatcher.h')
1 files changed, 71 insertions, 0 deletions
diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h
new file mode 100644
index 0000000000..83267e80ea
--- /dev/null
+++ b/src/plugins/platforms/ios/qioseventdispatcher.h
@@ -0,0 +1,71 @@
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact:
+** This file is part of the plugins of the Qt Toolkit.
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see For further information
+** use the contact form at
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met:
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met:
+#include <QtPlatformSupport/private/qeventdispatcher_cf_p.h>
+class QIOSEventDispatcher : public QEventDispatcherCoreFoundation
+ explicit QIOSEventDispatcher(QObject *parent = 0);
+ bool processEvents(QEventLoop::ProcessEventsFlags flags) Q_DECL_OVERRIDE;
+ void interrupt() Q_DECL_OVERRIDE;
+ void handleRunLoopExit(CFRunLoopActivity activity);
+ void checkIfApplicationShouldQuit();
+ void interruptQApplicationExec();
+ uint m_processEventCallsAfterAppExec;
+ RunLoopObserver<QIOSEventDispatcher> m_runLoopExitObserver;
+#endif // QIOSEVENTDISPATCHER_H \ No newline at end of file