diff options
Diffstat (limited to 'src/plugins/platforms/ios/qiosscreen.mm')
-rw-r--r-- | src/plugins/platforms/ios/qiosscreen.mm | 138 |
1 files changed, 62 insertions, 76 deletions
diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 80636ab9c6..e48592aa24 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -1,41 +1,7 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses #include "qiosglobal.h" #include "qiosintegration.h" @@ -51,6 +17,7 @@ #include <QtGui/qpointingdevice.h> #include <QtGui/private/qwindow_p.h> +#include <QtGui/private/qguiapplication_p.h> #include <private/qcoregraphics_p.h> #include <qpa/qwindowsysteminterface.h> @@ -108,14 +75,17 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen) + (void)screenConnected:(NSNotification*)notification { - Q_ASSERT_X(QIOSIntegration::instance(), Q_FUNC_INFO, - "Screen connected before QIOSIntegration creation"); + if (!QIOSIntegration::instance()) + return; // Will be added when QIOSIntegration is created QWindowSystemInterface::handleScreenAdded(new QIOSScreen([notification object])); } + (void)screenDisconnected:(NSNotification*)notification { + if (!QIOSIntegration::instance()) + return; + QIOSScreen *screen = qtPlatformScreenFor([notification object]); Q_ASSERT_X(screen, Q_FUNC_INFO, "Screen disconnected that we didn't know about"); @@ -124,6 +94,9 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen) + (void)screenModeChanged:(NSNotification*)notification { + if (!QIOSIntegration::instance()) + return; + QIOSScreen *screen = qtPlatformScreenFor([notification object]); Q_ASSERT_X(screen, Q_FUNC_INFO, "Screen changed that we didn't know about"); @@ -176,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 @@ -213,10 +171,21 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen) { [super traitCollectionDidChange:previousTraitCollection]; + if (!qGuiApp) + return; + + Qt::ColorScheme colorScheme = self.traitCollection.userInterfaceStyle + == UIUserInterfaceStyleDark + ? Qt::ColorScheme::Dark + : Qt::ColorScheme::Light; + if (self.screen == UIScreen.mainScreen) { - if (previousTraitCollection.userInterfaceStyle != self.traitCollection.userInterfaceStyle) { + // Check if the current userInterfaceStyle reports a different appearance than + // the platformTheme's appearance. We might have set that one based on the UIScreen + if (previousTraitCollection.userInterfaceStyle != self.traitCollection.userInterfaceStyle + || QGuiApplicationPrivate::platformTheme()->colorScheme() != colorScheme) { QIOSTheme::initializeSystemPalette(); - QWindowSystemInterface::handleThemeChange<QWindowSystemInterface::SynchronousDelivery>(nullptr); + QWindowSystemInterface::handleThemeChange<QWindowSystemInterface::SynchronousDelivery>(); } } } @@ -227,6 +196,8 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen) QT_BEGIN_NAMESPACE +using namespace Qt::StringLiterals; + /*! Returns the model identifier of the device. */ @@ -243,7 +214,7 @@ static QString deviceModelIdentifier() char value[size]; sysctlbyname(key, &value, &size, NULL, 0); - return QString::fromLatin1(value); + return QString::fromLatin1(QByteArrayView(value, qsizetype(size))); #endif } @@ -288,7 +259,7 @@ QIOSScreen::QIOSScreen(UIScreen *screen) if (!qt_apple_isApplicationExtension()) { for (UIWindow *existingWindow in qt_apple_sharedApplication().windows) { if (existingWindow.screen == m_uiScreen) { - m_uiWindow = [m_uiWindow retain]; + m_uiWindow = [existingWindow retain]; break; } } @@ -319,12 +290,19 @@ QIOSScreen::~QIOSScreen() QString QIOSScreen::name() const { - if (m_uiScreen == [UIScreen mainScreen]) { - return QString::fromNSString([UIDevice currentDevice].model) - + QLatin1String(" built-in display"); - } else { - return QLatin1String("External display"); - } + if (m_uiScreen == [UIScreen mainScreen]) + return QString::fromNSString([UIDevice currentDevice].model) + " built-in display"_L1; + else + 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() @@ -334,14 +312,22 @@ 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(); - UIEdgeInsets safeAreaInsets = m_uiWindow.qt_safeAreaInsets; - m_availableGeometry = m_geometry.adjusted(safeAreaInsets.left, safeAreaInsets.top, - -safeAreaInsets.right, -safeAreaInsets.bottom).intersected(applicationFrame); + 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]) { @@ -460,7 +446,7 @@ QSizeF QIOSScreen::physicalSize() const return m_physicalSize; } -QDpi QIOSScreen::logicalDpi() const +QDpi QIOSScreen::logicalBaseDpi() const { return QDpi(72, 72); } @@ -564,6 +550,6 @@ UIWindow *QIOSScreen::uiWindow() const return m_uiWindow; } -#include "moc_qiosscreen.cpp" - QT_END_NAMESPACE + +#include "moc_qiosscreen.cpp" |