From bc014d5fc705e95bb34b7729b2c3bb5f9539d777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 8 Apr 2024 20:25:46 +0200 Subject: iOS: Don't report UIDevice.currentDevice.orientation through QScreen As of Qt 6 (3e12951c0b35041920989d6089ddb6c2f5c2d3d1, the QScreen's orientation() property is supposed to represent the orientation of the screen from a window management perspective, and not the orientation of the actual device, as in Qt 5 times. For iOS, when the orientation of the app is locked to a orientation via the Info.plist or [UIViewController supportedInterfaceOrientations], the UIDevice API will keep reporting the actual orientation of the device, which is wrong for the Qt 6 definition of the API. We currently don't have an API in QScreen to represent the always updating physical rotation of the device. For this use-case the supported API is QOrientationReading in Qt Sensors. [ChangeLog][iOS] QScreen::orientation() will no longer report the device's physical orientation when orientation has been locked to a subset of the available orientations, but will instead match the primary orientation. Task-number: QTBUG-38576 Task-number: QTBUG-121781 Change-Id: I251a039a618656466cbfd1d836a5b49a6be8e736 Reviewed-by: Volker Hilsheimer Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/ios/qiosscreen.h | 1 - src/plugins/platforms/ios/qiosscreen.mm | 82 +++------------------------------ 2 files changed, 7 insertions(+), 76 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index f05a5456b3..005ea8b2ee 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -63,7 +63,6 @@ private: uint m_physicalDpi; #endif QSizeF m_physicalSize; - QIOSOrientationListener *m_orientationListener = nullptr; CADisplayLink *m_displayLink = nullptr; }; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 19f66d783c..e41a6ab46f 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -107,50 +107,6 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen) @end -// ------------------------------------------------------------------------- - -@interface QIOSOrientationListener : NSObject -@end - -@implementation QIOSOrientationListener { - QIOSScreen *m_screen; -} - -- (instancetype)initWithQIOSScreen:(QIOSScreen *)screen -{ - self = [super init]; - if (self) { - m_screen = screen; -#ifndef Q_OS_TVOS - [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(orientationChanged:) - name:@"UIDeviceOrientationDidChangeNotification" object:nil]; -#endif - } - return self; -} - -- (void)dealloc -{ -#ifndef Q_OS_TVOS - [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; - [[NSNotificationCenter defaultCenter] - removeObserver:self - name:@"UIDeviceOrientationDidChangeNotification" object:nil]; -#endif - [super dealloc]; -} - -- (void)orientationChanged:(NSNotification *)notification -{ - Q_UNUSED(notification); - m_screen->updateProperties(); -} - -@end - #endif // !defined(Q_OS_VISIONOS) // ------------------------------------------------------------------------- @@ -235,8 +191,6 @@ QIOSScreen::QIOSScreen(UIScreen *screen) } } - m_orientationListener = [[QIOSOrientationListener alloc] initWithQIOSScreen:this]; - m_displayLink = [m_uiScreen displayLinkWithBlock:^(CADisplayLink *) { deliverUpdateRequests(); }]; m_displayLink.paused = YES; // Enabled when clients call QWindow::requestUpdate() [m_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; @@ -250,7 +204,6 @@ QIOSScreen::~QIOSScreen() { [m_displayLink invalidate]; - [m_orientationListener release]; [m_uiWindow release]; } @@ -423,34 +376,13 @@ Qt::ScreenOrientation QIOSScreen::nativeOrientation() const Qt::ScreenOrientation QIOSScreen::orientation() const { -#if defined(Q_OS_TVOS) || defined(Q_OS_VISIONOS) - return Qt::PrimaryOrientation; -#else - // Auxiliary screens are always the same orientation as their primary orientation - if (m_uiScreen != [UIScreen mainScreen]) - return Qt::PrimaryOrientation; - - UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation; - - // At startup, iOS will report an unknown orientation for the device, even - // if we've asked it to begin generating device orientation notifications. - // In this case we fall back to the status bar orientation, which reflects - // the orientation the application was started up in (which may not match - // the physical orientation of the device, but typically does unless the - // application has been locked to a subset of the available orientations). - if (deviceOrientation == UIDeviceOrientationUnknown && !qt_apple_isApplicationExtension()) - deviceOrientation = UIDeviceOrientation(qt_apple_sharedApplication().statusBarOrientation); - - // If the device reports face up or face down orientations, we can't map - // them to Qt orientations, so we pretend we're in the same orientation - // as before. - if (deviceOrientation == UIDeviceOrientationFaceUp || deviceOrientation == UIDeviceOrientationFaceDown) { - Q_ASSERT(screen()); - return screen()->orientation(); - } - - return toQtScreenOrientation(deviceOrientation); -#endif + // We don't report UIDevice.currentDevice.orientation here, + // as that would report the actual orientation of the device, + // even if the orientation of the UI was locked to a subset + // of the possible orientations via the app's Info.plist or + // via [UIViewController supportedInterfaceOrientations]. + return m_geometry.width() >= m_geometry.height() ? + Qt::LandscapeOrientation : Qt::PortraitOrientation; } QPixmap QIOSScreen::grabWindow(WId window, int x, int y, int width, int height) const -- cgit v1.2.3