diff options
author | Tor Arne Vestbø <tor.arne.vestbo@digia.com> | 2013-06-06 15:42:16 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-13 14:08:44 +0200 |
commit | 59601e06d96edb5661a3dd91341d74e16dc6b229 (patch) | |
tree | 3d914cc9b0645aeeda135403cadb17c7d2546533 /src/plugins/platforms/qnx/qqnxservices.cpp | |
parent | 52b827d11b501511b0ec5c2ee9a395e2adcaf0d8 (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 <simon.hausmann@digia.com>
Diffstat (limited to 'src/plugins/platforms/qnx/qqnxservices.cpp')
0 files changed, 0 insertions, 0 deletions