diff options
author | Tor Arne Vestbø <tor.arne.vestbo@digia.com> | 2014-04-24 15:33:20 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-04-28 19:52:25 +0200 |
commit | a3634e4b2b39fb7895a3c5795498d1a176e528b1 (patch) | |
tree | ab0ef139efafe6a85975b6c3491f284d499b35dc | |
parent | b619c35d8507eee3ad9b456128f811b561513727 (diff) |
iOS: Send updated expose events on application background/foregrounding
When an application has background processing enabled, for example for
communicating with an external accessory or getting location updates,
it might trigger code that does UI updates, which will kill the app as
doing UI in the background is not allowed on iOS.
We guard against this by propagating the backgrounding as updated expose
events with a non-exposed region and isExposed() returning false. This
means clients who correctly use QWindow::isExposed() to guard their
drawing code (including the scene-graph), will live to see another day.
Task-number: QTBUG-36956
Change-Id: Ib708394d33093affe68c9f2c7abde7e54be5ec74
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@digia.com>
-rw-r--r-- | src/plugins/platforms/ios/qioswindow.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qioswindow.mm | 32 |
2 files changed, 28 insertions, 5 deletions
diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index fc99543aa6..6b6892e6e4 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -88,6 +88,7 @@ public: WId winId() const { return WId(m_view); }; private: + void applicationStateChanged(Qt::ApplicationState state); void applyGeometry(const QRect &rect); QUIView *m_view; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 7d5c507972..ebff2c25a1 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -192,12 +192,25 @@ - (void)displayLayer:(CALayer *)layer { - QSize bounds = fromCGRect(layer.bounds).toRect().size(); + Q_UNUSED(layer); + Q_ASSERT(layer == self.layer); - Q_ASSERT(m_qioswindow->geometry().size() == bounds); - Q_ASSERT(self.hidden == !m_qioswindow->window()->isVisible()); + [self sendUpdatedExposeEvent]; +} + +- (void)sendUpdatedExposeEvent +{ + QRegion region; + + if (m_qioswindow->isExposed()) { + QSize bounds = fromCGRect(self.layer.bounds).toRect().size(); + + Q_ASSERT(m_qioswindow->geometry().size() == bounds); + Q_ASSERT(self.hidden == !m_qioswindow->window()->isVisible()); + + region = QRect(QPoint(), bounds); + } - QRegion region = self.hidden ? QRegion() : QRect(QPoint(), bounds); QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), region); QWindowSystemInterface::flushWindowSystemEvents(); } @@ -334,6 +347,8 @@ QIOSWindow::QIOSWindow(QWindow *window) , m_view([[QUIView alloc] initWithQIOSWindow:this]) , m_windowLevel(0) { + connect(qGuiApp, &QGuiApplication::applicationStateChanged, this, &QIOSWindow::applicationStateChanged); + setParent(QPlatformWindow::parent()); // Resolve default window geometry in case it was not set before creating the @@ -471,7 +486,8 @@ void QIOSWindow::applyGeometry(const QRect &rect) bool QIOSWindow::isExposed() const { - return window()->isVisible() && !window()->geometry().isEmpty(); + return qApp->applicationState() > Qt::ApplicationHidden + && window()->isVisible() && !window()->geometry().isEmpty(); } void QIOSWindow::setWindowState(Qt::WindowState state) @@ -593,6 +609,12 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio [[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO]; } +void QIOSWindow::applicationStateChanged(Qt::ApplicationState) +{ + if (window()->isExposed() != isExposed()) + [m_view sendUpdatedExposeEvent]; +} + qreal QIOSWindow::devicePixelRatio() const { return m_view.contentScaleFactor; |