summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/ios
diff options
context:
space:
mode:
authorRichard Moe Gustavsen <richard.gustavsen@digia.com>2013-01-25 11:49:34 +0100
committerTor Arne Vestbø <tor.arne.vestbo@digia.com>2013-02-27 23:56:06 +0100
commit38e6d5a91588bfe823ff6bcb19bd356965d328f7 (patch)
tree3e1ff8e2b766ecf3693b25d7cbcbe1ddc3408818 /src/plugins/platforms/ios
parentf2c52d65608d238ad35ca91099a8751e0c37ef52 (diff)
iOS: add QIOSWindow::windowLevel() to simplify window stacking
When adding modal windows into the mix, raiseOrLower became even more messy to write. So do it the usual way instead, and add a windowLevel variable to each QIOSWindow that we can sort on. The code becomes more readable, and we can handle more window types correctly. Change-Id: I348352473a7d8cf9909c17c1b074b2fe3fab9819 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@digia.com>
Diffstat (limited to 'src/plugins/platforms/ios')
-rw-r--r--src/plugins/platforms/ios/qioswindow.h3
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm42
2 files changed, 34 insertions, 11 deletions
diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h
index b3a94a8d0e..2d7c4c9103 100644
--- a/src/plugins/platforms/ios/qioswindow.h
+++ b/src/plugins/platforms/ios/qioswindow.h
@@ -89,10 +89,11 @@ private:
int m_touchId;
QRect m_requestedGeometry;
-
+ int m_windowLevel;
qreal m_devicePixelRatio;
void raiseOrLower(bool raise);
+ void updateWindowLevel();
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index 91e75bc660..4aa6b8a24e 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -321,6 +321,7 @@ QIOSWindow::QIOSWindow(QWindow *window)
, m_view([[EAGLView alloc] initWithQIOSWindow:this])
, m_touchId(0)
, m_requestedGeometry(QPlatformWindow::geometry())
+ , m_windowLevel(0)
, m_devicePixelRatio(1.0)
{
if (isQtApplication())
@@ -355,6 +356,7 @@ void QIOSWindow::setVisible(bool visible)
// Since iOS doesn't do window management the way a Qt application
// expects, we need to raise and activate windows ourselves:
if (visible) {
+ updateWindowLevel();
requestActivateWindow();
} else {
// Activate top-most visible QWindow:
@@ -421,10 +423,8 @@ void QIOSWindow::requestActivateWindow()
void QIOSWindow::raiseOrLower(bool raise)
{
- // Re-insert m_view at the correct index among its sibling views (QWindows), and ensure
- // that window flags (staysOnTop, popup) are respected. This function assumes that all
- // sibling views are sorted correctly. Note: We sort popup and staysOnTop windows at
- // the same level:
+ // Re-insert m_view at the correct index among its sibling views
+ // (QWindows) according to their current m_windowLevel:
if (!isQtApplication())
return;
@@ -432,14 +432,12 @@ void QIOSWindow::raiseOrLower(bool raise)
if (subviews.count == 1)
return;
- const Qt::WindowFlags topFlag = (Qt::Popup | Qt::WindowStaysOnTopHint) & ~Qt::Dialog;
- bool thisWindowIsTop = topFlag & window()->flags();
-
for (int i = int(subviews.count) - 1; i >= 0; --i) {
UIView *view = static_cast<UIView *>([subviews objectAtIndex:i]);
- bool otherWindowIsTop = topFlag & view.qwindow->flags();
- if ((raise && (thisWindowIsTop || !otherWindowIsTop))
- || (!raise && (thisWindowIsTop && !otherWindowIsTop))) {
+ if (view.hidden || view == m_view)
+ continue;
+ int level = static_cast<QIOSWindow *>(view.qwindow->handle())->m_windowLevel;
+ if (m_windowLevel > level || (raise && m_windowLevel == level)) {
[m_view.superview insertSubview:m_view aboveSubview:view];
return;
}
@@ -447,6 +445,30 @@ void QIOSWindow::raiseOrLower(bool raise)
[m_view.superview insertSubview:m_view atIndex:0];
}
+void QIOSWindow::updateWindowLevel()
+{
+ Qt::WindowType type = static_cast<Qt::WindowType>(int(window()->flags() & Qt::WindowType_Mask));
+
+ if (type == Qt::ToolTip)
+ m_windowLevel = 120;
+ else if (window()->flags() & Qt::WindowStaysOnTopHint)
+ m_windowLevel = 100;
+ else if (window()->isModal())
+ m_windowLevel = 30;
+ else if (type & Qt::Popup & ~Qt::Window)
+ m_windowLevel = 20;
+ else if (type == Qt::Tool)
+ m_windowLevel = 10;
+ else
+ m_windowLevel = 0;
+
+ // A window should be in at least the same m_windowLevel as its parent:
+ QWindow *transientParent = window()->transientParent();
+ QIOSWindow *transientParentWindow = transientParent ? static_cast<QIOSWindow *>(transientParent->handle()) : 0;
+ if (transientParentWindow)
+ m_windowLevel = qMax(transientParentWindow->m_windowLevel, m_windowLevel);
+}
+
void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation)
{
// Keep the status bar in sync with content orientation. This will ensure