iOS: Compute window level when needed instead of up front in member var

When a popup widget is shown, it's first raised(), and then made visible.
In this scenario, the logic in QIOSWindow::setVisible() to compute the
window level was too late, and we ended up showing the popup below other
popups.

Instead of moving the window level computation earlier, we remove the
member variable and just compute the level when needed, as we do in
the Cocoa platform plugin.

Fixes: QTBUG-126052
Fixes: QTBUG-126044
Pick-to: 6.7
Change-Id: If5dbcdcf0500aed57b725bb8eb636fe076459130
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
(cherry picked from commit 0e656164e640ff2aca00e82b51b0f1019fd7802f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Tor Arne Vestbø 2024-06-05 13:28:26 +02:00 committed by Qt Cherry-pick Bot
parent 0ad536d65c
commit 9bd3752029
2 changed files with 24 additions and 27 deletions

View File

@ -71,10 +71,9 @@ private:
UIView *m_view;
QRect m_normalGeometry;
int m_windowLevel;
void raiseOrLower(bool raise);
void updateWindowLevel();
int windowLevel() const;
bool blockedByModal();
friend class QIOSScreen;

View File

@ -36,7 +36,6 @@ enum {
QIOSWindow::QIOSWindow(QWindow *window, WId nativeHandle)
: QPlatformWindow(window)
, m_windowLevel(0)
{
if (nativeHandle) {
m_view = reinterpret_cast<UIView *>(nativeHandle);
@ -127,11 +126,6 @@ void QIOSWindow::setVisible(bool visible)
if (!isQtApplication() || !window()->isTopLevel())
return;
// Since iOS doesn't do window management the way a Qt application
// expects, we need to raise and activate windows ourselves:
if (visible)
updateWindowLevel();
if (blockedByModal()) {
if (visible)
raise();
@ -343,8 +337,8 @@ void QIOSWindow::raiseOrLower(bool raise)
UIView *view = static_cast<UIView *>([subviews objectAtIndex:i]);
if (view.hidden || view == m_view || !view.qwindow)
continue;
int level = static_cast<QIOSWindow *>(view.qwindow->handle())->m_windowLevel;
if (m_windowLevel > level || (raise && m_windowLevel == level)) {
int level = static_cast<QIOSWindow *>(view.qwindow->handle())->windowLevel();
if (windowLevel() > level || (raise && windowLevel() == level)) {
[m_view.superview insertSubview:m_view aboveSubview:view];
return;
}
@ -359,30 +353,34 @@ void QIOSWindow::raiseOrLower(bool raise)
}
}
void QIOSWindow::updateWindowLevel()
int QIOSWindow::windowLevel() const
{
Qt::WindowType type = window()->type();
if (type == Qt::ToolTip)
m_windowLevel = 120;
else if (window()->flags() & Qt::WindowStaysOnTopHint)
m_windowLevel = 100;
else if (window()->isModal())
m_windowLevel = 40;
else if (type == Qt::Popup)
m_windowLevel = 30;
else if (type == Qt::SplashScreen)
m_windowLevel = 20;
else if (type == Qt::Tool)
m_windowLevel = 10;
else
m_windowLevel = 0;
int level = 0;
// A window should be in at least the same m_windowLevel as its parent:
if (type == Qt::ToolTip)
level = 120;
else if (window()->flags() & Qt::WindowStaysOnTopHint)
level = 100;
else if (window()->isModal())
level = 40;
else if (type == Qt::Popup)
level = 30;
else if (type == Qt::SplashScreen)
level = 20;
else if (type == Qt::Tool)
level = 10;
else
level = 0;
// A window should be in at least the same window level 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);
level = qMax(transientParentWindow->windowLevel(), level);
return level;
}
void QIOSWindow::applicationStateChanged(Qt::ApplicationState)