summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/ios
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2024-04-05 18:05:31 +0200
committerTor Arne Vestbø <tor.arne.vestbo@qt.io>2024-04-18 15:25:22 +0200
commit1a0c113b2ddd59d25145ca7c7b7209d90d9d9dc8 (patch)
treeb3c03c343292e9e9804de5fd74ce8de5b491466a /src/plugins/platforms/ios
parenteb9923c67ed919c4072a22857d4c32419de3d521 (diff)
iOS: Handle geometry of maximized windows outside of QIOSScreen
Ideally we would report the available geometry of our screen in a way that reflects the safe area margins of a potentially full screen window, but doing so requires that we manage UIWindows via QScreen/UIScreen, which is not in line with modern iOS window management. We still apply safe area margins to maximized windows, as before, but do so when applying the maximized state in QIOSWindow::setWindowState Task-number: QTBUG-121781 Change-Id: If7b9855aea47014f01e23dfe197b7057a1305a68 Reviewed-by: Amr Elsayed <amr.elsayed@qt.io> Reviewed-by: Doris Verria <doris.verria@qt.io>
Diffstat (limited to 'src/plugins/platforms/ios')
-rw-r--r--src/plugins/platforms/ios/qiosglobal.h1
-rw-r--r--src/plugins/platforms/ios/qiosglobal.mm9
-rw-r--r--src/plugins/platforms/ios/qiosscreen.mm32
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm35
4 files changed, 40 insertions, 37 deletions
diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h
index e7ca2d1fec..0fafbe1936 100644
--- a/src/plugins/platforms/ios/qiosglobal.h
+++ b/src/plugins/platforms/ios/qiosglobal.h
@@ -26,6 +26,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcQpaWindow);
class QPlatformScreen;
bool isQtApplication();
+bool isRunningOnVisionOS();
#ifndef Q_OS_TVOS
Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation);
diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm
index 8d0df38dbe..eb9e713b0d 100644
--- a/src/plugins/platforms/ios/qiosglobal.mm
+++ b/src/plugins/platforms/ios/qiosglobal.mm
@@ -29,6 +29,15 @@ bool isQtApplication()
return isQt;
}
+bool isRunningOnVisionOS()
+{
+ static bool result = []{
+ // This class is documented to only be available on visionOS
+ return NSClassFromString(@"UIWindowSceneGeometryPreferencesVision");
+ }();
+ return result;
+}
+
#ifndef Q_OS_TVOS
Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation)
{
diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm
index e6f533c466..d96f7686f5 100644
--- a/src/plugins/platforms/ios/qiosscreen.mm
+++ b/src/plugins/platforms/ios/qiosscreen.mm
@@ -310,15 +310,6 @@ QString QIOSScreen::name() const
#endif
}
-[[maybe_unused]] 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;
@@ -327,26 +318,9 @@ void QIOSScreen::updateProperties()
#if defined(Q_OS_VISIONOS)
// Based on what iPad app reports
m_geometry = QRect(0, 0, 1194, 834);
- m_availableGeometry = m_geometry;
m_depth = 24;
#else
m_geometry = QRectF::fromCGRect(m_uiScreen.bounds).toRect();
- m_availableGeometry = m_geometry;
-
- // 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.
- 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]) {
@@ -390,6 +364,12 @@ void QIOSScreen::updateProperties()
#endif // defined(Q_OS_VISIONOS)
+ // UIScreen does not provide a consistent accessor for the safe area margins
+ // of the screen, and on visionOS we won't even have a UIScreen, so we report
+ // the available geometry of the screen to be the same as the full geometry.
+ // Safe area margins and maximized state is handled in QIOSWindow::setWindowState.
+ m_availableGeometry = m_geometry;
+
// At construction time, we don't yet have an associated QScreen, but we still want
// to compute the properties above so they are ready for when the QScreen attaches.
// Also, at destruction time the QScreen has already been torn down, so notifying
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index 398f8c4a6f..0f4a6803b3 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -261,21 +261,34 @@ void QIOSWindow::setWindowState(Qt::WindowStates state)
// it to clamp the window geometry. Instead just use the UIWindow
// directly, which represents our "screen".
applyGeometry(uiWindowBounds);
+ } else 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.
+ applyGeometry(uiWindowBounds);
} else {
- // When an application is in split-view mode, the UIScreen still has the
- // same geometry, but the UIWindow is resized to the area reserved for the
- // application. We use this to constrain the geometry used when applying the
- // fullscreen or maximized window states. Note that we do not do this
- // in applyGeometry(), as we don't want to artificially limit window
- // placement "outside" of the screen bounds if that's what the user wants.
- QRect fullscreenGeometry = screen()->geometry().intersected(uiWindowBounds);
- QRect maximizedGeometry = window()->flags() & Qt::MaximizeUsingFullscreenGeometryHint ?
- fullscreenGeometry : screen()->availableGeometry().intersected(uiWindowBounds);
+ QRect fullscreenGeometry = screen()->geometry();
+ QRect maximizedGeometry = fullscreenGeometry;
+
+#if !defined(Q_OS_VISIONOS)
+ if (!(window()->flags() & Qt::MaximizeUsingFullscreenGeometryHint)) {
+ // If the safe area margins reflect the screen's outer edges,
+ // then reduce the maximized geometry accordingly. Otherwise
+ // leave it as is, and assume the client will take the safe
+ // are margins into account explicitly.
+ UIScreen *uiScreen = m_view.window.windowScene.screen;
+ UIEdgeInsets safeAreaInsets = m_view.window.safeAreaInsets;
+ if (m_view.window.bounds.size.width == uiScreen.bounds.size.width)
+ maximizedGeometry.adjust(safeAreaInsets.left, 0, -safeAreaInsets.right, 0);
+ if (m_view.window.bounds.size.height == uiScreen.bounds.size.height)
+ maximizedGeometry.adjust(0, safeAreaInsets.top, 0, -safeAreaInsets.bottom);
+ }
+#endif
if (state & Qt::WindowFullScreen)
- applyGeometry(fullscreenGeometry);
+ applyGeometry(fullscreenGeometry.intersected(uiWindowBounds));
else
- applyGeometry(maximizedGeometry);
+ applyGeometry(maximizedGeometry.intersected(uiWindowBounds));
}
} else {
applyGeometry(m_normalGeometry);