summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@digia.com>2014-04-24 15:33:20 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-04-28 19:52:25 +0200
commita3634e4b2b39fb7895a3c5795498d1a176e528b1 (patch)
treeab0ef139efafe6a85975b6c3491f284d499b35dc
parentb619c35d8507eee3ad9b456128f811b561513727 (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.h1
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm32
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;