iOS: Don't apply UIWindow safeAreInsets to available geometry on visionOS

There is no concept of a screen on visionOS, and hence no concept of
screen-relative system UI that we should keep top level windows away
from.

As UIWindow and UIScreen on visionOS report the exact same bounds, we
can't use the same code path we use for iOS/iPadOS to detect whether
to apply the safe area insets, so skip the logic entirely.

We still report the safe area insets on a QWindow level, so applications
can avoid rendering content close to UI elements such as the window
move and window close buttons.

Task-number: QTBUG-121781
Change-Id: I20ad02390564972a3715c27f351689b79ad579d8
Reviewed-by: Amr Elsayed <amr.elsayed@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
This commit is contained in:
Tor Arne Vestbø 2024-03-16 13:24:13 +01:00
parent 17f6c62d97
commit b7eb73b1f0

View File

@ -296,6 +296,15 @@ QString QIOSScreen::name() const
return "External display"_L1;
}
static bool isRunningOnVisionOS()
{
static bool result = []{
// This class is documented to only be available on visionOS
return NSClassFromString(@"UIWindowSceneGeometryPreferencesVision");
}();
return result;
}
void QIOSScreen::updateProperties()
{
QRect previousGeometry = m_geometry;
@ -308,11 +317,17 @@ void QIOSScreen::updateProperties()
// For convenience, we reflect the safe area margins of the screen's UIWindow
// by reducing the available geometry of the screen. But we only do this if
// the UIWindow bounds is representative of the UIScreen.
UIEdgeInsets safeAreaInsets = m_uiWindow.safeAreaInsets;
if (m_uiWindow.bounds.size.width == m_uiScreen.bounds.size.width)
m_availableGeometry.adjust(safeAreaInsets.left, 0, -safeAreaInsets.right, 0);
if (m_uiWindow.bounds.size.height == m_uiScreen.bounds.size.height)
m_availableGeometry.adjust(0, safeAreaInsets.top, 0, -safeAreaInsets.bottom);
if (isRunningOnVisionOS()) {
// On visionOS there is no concept of a screen, and hence no concept of
// screen-relative system UI that we should keep top level windows away
// from, so don't apply the UIWindow safe area insets to the screen.
} else {
UIEdgeInsets safeAreaInsets = m_uiWindow.safeAreaInsets;
if (m_uiWindow.bounds.size.width == m_uiScreen.bounds.size.width)
m_availableGeometry.adjust(safeAreaInsets.left, 0, -safeAreaInsets.right, 0);
if (m_uiWindow.bounds.size.height == m_uiScreen.bounds.size.height)
m_availableGeometry.adjust(0, safeAreaInsets.top, 0, -safeAreaInsets.bottom);
}
#ifndef Q_OS_TVOS
if (m_uiScreen == [UIScreen mainScreen]) {