path: root/src/plugins/platforms/ios/
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/
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/')
1 files changed, 0 insertions, 23 deletions
diff --git a/src/plugins/platforms/ios/ b/src/plugins/platforms/ios/
index d4fd613ae3..e06d2b8840 100644
--- a/src/plugins/platforms/ios/
+++ b/src/plugins/platforms/ios/
@@ -46,8 +46,6 @@
#include <QtCore/QtCore>
-extern "C" int main(int argc, char *argv[]);
@implementation QIOSApplicationDelegate
@synthesize window;
@@ -68,30 +66,9 @@ extern "C" int main(int argc, char *argv[]);
[self.window makeKeyAndVisible];
- // We schedule the main-redirection for the next eventloop pass so that we
- // can return from this function and let UIApplicationMain finish its job.
- [NSTimer scheduledTimerWithTimeInterval:.01f target:self
- selector:@selector(runUserMain) userInfo:nil repeats:NO];
return YES;
-- (void)runUserMain
- NSArray *arguments = [[NSProcessInfo processInfo] arguments];
- int argc = arguments.count;
- char **argv = new char*[argc];
- for (int i = 0; i < argc; ++i) {
- NSString *arg = [arguments objectAtIndex:i];
- argv[i] = reinterpret_cast<char *>(malloc([arg lengthOfBytesUsingEncoding:[NSString defaultCStringEncoding]]));
- strcpy(argv[i], [arg cStringUsingEncoding:[NSString defaultCStringEncoding]]);
- }
- main(argc, argv);
- delete[] argv;
- (void)dealloc
[qiosViewController release];