iOS: Compute screen available geometry without UIScreen.applicationFrame
The API has been deprecated for a long time, and doesn't have the same semantics as we want for modern iOS apps that may run in windowed mode on iPad, macOS, or visionOS. Instead we base the availableGeometry exclusively on the safeAreaInsets of the screen's UIWindow. But we only do so if the UIWindow bounds match the bounds of the UIScreen in each dimension. This means that iOS apps that take up the entire screen, or run in Split View on iPad, will get a smaller availableGeometry, but apps that run in Slide Over on iPad, or windowed in Stage Manager on iPad, will get an availableGeometry that matches the entire screen. It's then up to the QWindow to take the safeAreaMargins into account when rendering, to stay out of any UI elements that the OS may add. We do this for QWidgets with layouts automatically, and the plan is to do this for Qt Quick Controls as well. As the current situation is quite broken anyways, we take the first step now, and then follow up with the Quick changes later on. Task-number: QTBUG-121781 Change-Id: I7728e117969474654fcccdb19a6c954bb0eea3f9 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
This commit is contained in:
parent
dc9c67c260
commit
17f6c62d97
@ -149,21 +149,6 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen)
|
||||
|
||||
@end
|
||||
|
||||
@interface UIScreen (Compatibility)
|
||||
@property (nonatomic, readonly) CGRect qt_applicationFrame;
|
||||
@end
|
||||
|
||||
@implementation UIScreen (Compatibility)
|
||||
- (CGRect)qt_applicationFrame
|
||||
{
|
||||
#ifdef Q_OS_IOS
|
||||
return self.applicationFrame;
|
||||
#else
|
||||
return self.bounds;
|
||||
#endif
|
||||
}
|
||||
@end
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@implementation QUIWindow
|
||||
@ -318,14 +303,16 @@ void QIOSScreen::updateProperties()
|
||||
|
||||
m_geometry = QRectF::fromCGRect(m_uiScreen.bounds).toRect();
|
||||
|
||||
// The application frame doesn't take safe area insets into account, and
|
||||
// the safe area insets are not available before the UIWindow is shown,
|
||||
// and do not take split-view constraints into account, so we have to
|
||||
// combine the two to get the correct available geometry.
|
||||
QRect applicationFrame = QRectF::fromCGRect(m_uiScreen.qt_applicationFrame).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.
|
||||
UIEdgeInsets safeAreaInsets = m_uiWindow.safeAreaInsets;
|
||||
m_availableGeometry = m_geometry.adjusted(safeAreaInsets.left, safeAreaInsets.top,
|
||||
-safeAreaInsets.right, -safeAreaInsets.bottom).intersected(applicationFrame);
|
||||
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]) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user