diff options
58 files changed, 468 insertions, 125 deletions
diff --git a/.cmake.conf b/.cmake.conf index 87091cdd646..d3738283b9f 100644 --- a/.cmake.conf +++ b/.cmake.conf @@ -45,3 +45,8 @@ set(QT_SUPPORTED_MIN_MACOS_XCODE_VERSION "14") set(QT_SUPPORTED_MIN_IOS_SDK_VERSION "16") set(QT_SUPPORTED_MAX_IOS_SDK_VERSION "17") set(QT_SUPPORTED_MIN_IOS_XCODE_VERSION "14") + +set(QT_SUPPORTED_MIN_VISIONOS_SDK_VERSION "1") +set(QT_SUPPORTED_MAX_VISIONOS_SDK_VERSION "1") +set(QT_SUPPORTED_MIN_VISIONOS_XCODE_VERSION "15") + diff --git a/cmake/QtAutoDetectHelpers.cmake b/cmake/QtAutoDetectHelpers.cmake index 9120e3cf621..ad0764b804b 100644 --- a/cmake/QtAutoDetectHelpers.cmake +++ b/cmake/QtAutoDetectHelpers.cmake @@ -184,6 +184,8 @@ function(qt_auto_detect_apple) if("${QT_QMAKE_TARGET_MKSPEC}" STREQUAL "macx-ios-clang") set(CMAKE_SYSTEM_NAME "iOS" CACHE STRING "") + elseif("${QT_QMAKE_TARGET_MKSPEC}" STREQUAL "macx-visionos-clang") + set(CMAKE_SYSTEM_NAME "visionOS" CACHE STRING "") endif() if(CMAKE_SYSTEM_NAME STREQUAL iOS) @@ -226,13 +228,14 @@ function(qt_auto_detect_apple) endif() endif() - # For non simulator_and_device builds, we need to explicitly set the SYSROOT aka the sdk - # value. - if(QT_APPLE_SDK) - set(CMAKE_OSX_SYSROOT "${QT_APPLE_SDK}" CACHE STRING "") - endif() set(CMAKE_OSX_ARCHITECTURES "${osx_architectures}" CACHE STRING "") + endif() + + if(QT_APPLE_SDK) + set(CMAKE_OSX_SYSROOT "${QT_APPLE_SDK}" CACHE STRING "") + endif() + if(CMAKE_SYSTEM_NAME STREQUAL iOS OR CMAKE_SYSTEM_NAME STREQUAL visionOS) if(NOT DEFINED BUILD_SHARED_LIBS) qt_internal_ensure_static_qt_config() endif() diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake index e561701deff..1e604559ed7 100644 --- a/cmake/QtBaseGlobalTargets.cmake +++ b/cmake/QtBaseGlobalTargets.cmake @@ -321,6 +321,7 @@ qt_copy_or_install(DIRECTORY cmake/ PATTERN "3rdparty" EXCLUDE PATTERN "macos" EXCLUDE PATTERN "ios" EXCLUDE + PATTERN "visionos" EXCLUDE PATTERN "platforms" EXCLUDE PATTERN "QtBuildInternals" EXCLUDE ) @@ -335,6 +336,7 @@ if(QT_WILL_INSTALL) PATTERN "3rdparty" EXCLUDE PATTERN "macos" EXCLUDE PATTERN "ios" EXCLUDE + PATTERN "visionos" EXCLUDE PATTERN "platforms" EXCLUDE PATTERN "QtBuildInternals" EXCLUDE ) @@ -345,6 +347,8 @@ if(APPLE) set(platform_shortname "macos") elseif(IOS) set(platform_shortname "ios") + elseif(VISIONOS) + set(platform_shortname "visionos") endif() # Info.plist diff --git a/cmake/QtBuildPathsHelpers.cmake b/cmake/QtBuildPathsHelpers.cmake index ad4b7a1365a..6431fa19375 100644 --- a/cmake/QtBuildPathsHelpers.cmake +++ b/cmake/QtBuildPathsHelpers.cmake @@ -214,6 +214,8 @@ macro(qt_internal_set_qt_apple_support_files_path) set(__qt_internal_cmake_apple_support_files_path "${QT_CMAKE_DIR}/macos") elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS") set(__qt_internal_cmake_apple_support_files_path "${QT_CMAKE_DIR}/ios") + elseif(CMAKE_SYSTEM_NAME STREQUAL "visionOS") + set(__qt_internal_cmake_apple_support_files_path "${QT_CMAKE_DIR}/visionos") endif() endif() endmacro() diff --git a/cmake/QtConfig.cmake.in b/cmake/QtConfig.cmake.in index c2a5d381d96..b5a21e391d1 100644 --- a/cmake/QtConfig.cmake.in +++ b/cmake/QtConfig.cmake.in @@ -44,6 +44,8 @@ if(APPLE) set(__qt_internal_cmake_apple_support_files_path "${_qt_import_prefix}/macos") elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS") set(__qt_internal_cmake_apple_support_files_path "${_qt_import_prefix}/ios") + elseif(CMAKE_SYSTEM_NAME STREQUAL "visionOS") + set(__qt_internal_cmake_apple_support_files_path "${_qt_import_prefix}/visionos") endif() endif() diff --git a/cmake/QtPlatformSupport.cmake b/cmake/QtPlatformSupport.cmake index e20a5e153d4..9f8498e42c8 100644 --- a/cmake/QtPlatformSupport.cmake +++ b/cmake/QtPlatformSupport.cmake @@ -32,7 +32,8 @@ qt_set01(BSD APPLE OR OPENBSD OR FREEBSD OR NETBSD) qt_set01(IOS APPLE AND CMAKE_SYSTEM_NAME STREQUAL "iOS") qt_set01(TVOS APPLE AND CMAKE_SYSTEM_NAME STREQUAL "tvOS") qt_set01(WATCHOS APPLE AND CMAKE_SYSTEM_NAME STREQUAL "watchOS") -qt_set01(UIKIT APPLE AND (IOS OR TVOS OR WATCHOS)) +qt_set01(VISIONOS APPLE AND CMAKE_SYSTEM_NAME STREQUAL "visionOS") +qt_set01(UIKIT APPLE AND (IOS OR TVOS OR WATCHOS OR VISIONOS)) qt_set01(MACOS APPLE AND NOT UIKIT) qt_set01(GCC CMAKE_CXX_COMPILER_ID STREQUAL "GNU") diff --git a/cmake/QtPublicAppleHelpers.cmake b/cmake/QtPublicAppleHelpers.cmake index 294412d2e74..5f7a7719b54 100644 --- a/cmake/QtPublicAppleHelpers.cmake +++ b/cmake/QtPublicAppleHelpers.cmake @@ -681,6 +681,12 @@ function(_qt_internal_export_apple_sdk_and_xcode_version_requirements out_var) QT_SUPPORTED_MAX_IOS_SDK_VERSION QT_SUPPORTED_MIN_IOS_XCODE_VERSION ) + elseif(VISIONOS) + set(vars_to_assign + QT_SUPPORTED_MIN_VISIONOS_SDK_VERSION + QT_SUPPORTED_MAX_VISIONOS_SDK_VERSION + QT_SUPPORTED_MIN_VISIONOS_XCODE_VERSION + ) else() set(vars_to_assign QT_SUPPORTED_MIN_MACOS_SDK_VERSION @@ -707,6 +713,8 @@ function(_qt_internal_get_apple_sdk_version out_var) if(APPLE) if(CMAKE_SYSTEM_NAME STREQUAL iOS) set(sdk_name "iphoneos") + elseif(CMAKE_SYSTEM_NAME STREQUAL visionOS) + set(sdk_name "xros") else() # Default to macOS set(sdk_name "macosx") @@ -804,6 +812,10 @@ function(_qt_internal_check_apple_sdk_and_xcode_versions) set(min_sdk_version "${QT_SUPPORTED_MIN_IOS_SDK_VERSION}") set(max_sdk_version "${QT_SUPPORTED_MAX_IOS_SDK_VERSION}") set(min_xcode_version "${QT_SUPPORTED_MIN_IOS_XCODE_VERSION}") + elseif(VISIONOS) + set(min_sdk_version "${QT_SUPPORTED_MIN_VISIONOS_SDK_VERSION}") + set(max_sdk_version "${QT_SUPPORTED_MAX_VISIONOS_SDK_VERSION}") + set(min_xcode_version "${QT_SUPPORTED_MIN_VISIONOS_XCODE_VERSION}") else() set(min_sdk_version "${QT_SUPPORTED_MIN_MACOS_SDK_VERSION}") set(max_sdk_version "${QT_SUPPORTED_MAX_MACOS_SDK_VERSION}") @@ -885,7 +897,7 @@ function(_qt_internal_check_apple_sdk_and_xcode_versions) endfunction() function(_qt_internal_finalize_apple_app target) - # Shared between macOS and iOS apps + # Shared between macOS and UIKit apps _qt_internal_copy_info_plist("${target}") _qt_internal_set_apple_localizations("${target}") @@ -905,6 +917,14 @@ function(_qt_internal_finalize_apple_app target) _qt_internal_set_placeholder_apple_bundle_version("${target}") endfunction() +function(_qt_internal_finalize_uikit_app target) + if(CMAKE_SYSTEM_NAME STREQUAL iOS) + _qt_internal_finalize_ios_app("${target}") + else() + _qt_internal_finalize_apple_app("${target}") + endif() +endfunction() + function(_qt_internal_finalize_ios_app target) # Must be called before we generate the Info.plist _qt_internal_handle_ios_launch_screen("${target}") diff --git a/cmake/QtWrapperScriptHelpers.cmake b/cmake/QtWrapperScriptHelpers.cmake index 9ba8e4017be..8eb4416e6d0 100644 --- a/cmake/QtWrapperScriptHelpers.cmake +++ b/cmake/QtWrapperScriptHelpers.cmake @@ -22,7 +22,7 @@ function(qt_internal_create_wrapper_scripts) set(extra_qt_cmake_code "") if(generate_unix) - if(IOS) + if(UIKIT) set(extra_qt_cmake_code [=[ # Specify Xcode as the default generator by assigning it to the CMAKE_GENERATOR env var. # An explicit -G or -D CMAKE_GENERATOR given on the command line will still take precedence. diff --git a/cmake/visionos/Info.plist.app.in b/cmake/visionos/Info.plist.app.in new file mode 100644 index 00000000000..7aa46986492 --- /dev/null +++ b/cmake/visionos/Info.plist.app.in @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + + <key>CFBundlePackageType</key> + <string>APPL</string> + + <key>CFBundleName</key> + <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string> + + <key>CFBundleDisplayName</key> + <string>${QT_INTERNAL_DOLLAR_VAR}{PRODUCT_NAME}</string> + + <key>CFBundleIdentifier</key> + <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string> + + <key>CFBundleExecutable</key> + <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string> + + <key>CFBundleVersion</key> + <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string> + + <key>CFBundleShortVersionString</key> + <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> + + <key>CFBundleIconFile</key> + <string>${MACOSX_BUNDLE_ICON_FILE}</string> + + <key>CFBundleDevelopmentRegion</key> + <string>$(DEVELOPMENT_LANGUAGE)</string> + <key>CFBundleAllowMixedLocalizations</key> + <true/> + + <key>CFBundleSupportedPlatforms</key> + <array> + <string>XROS</string> + </array> +</dict> +</plist> diff --git a/cmake/visionos/PrivacyInfo.xcprivacy b/cmake/visionos/PrivacyInfo.xcprivacy new file mode 100644 index 00000000000..d75908da058 --- /dev/null +++ b/cmake/visionos/PrivacyInfo.xcprivacy @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>NSPrivacyTracking</key> + <false/> + <key>NSPrivacyCollectedDataTypes</key> + <array/> + <key>NSPrivacyTrackingDomains</key> + <array/> + <key>NSPrivacyAccessedAPITypes</key> + <array/> +</dict> +</plist> diff --git a/configure.cmake b/configure.cmake index 01ee4fa3936..4cf9ad6741a 100644 --- a/configure.cmake +++ b/configure.cmake @@ -605,7 +605,7 @@ if(APPLE) endif() qt_feature("simulator_and_device" PUBLIC LABEL "Build for both simulator and device" - CONDITION UIKIT AND NOT QT_APPLE_SDK + CONDITION IOS AND NOT QT_APPLE_SDK ) qt_feature_config("simulator_and_device" QMAKE_PUBLIC_QT_CONFIG) qt_feature("rpath" PUBLIC diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf index 0b64a586b93..22c84d6473e 100644 --- a/mkspecs/features/mac/default_post.prf +++ b/mkspecs/features/mac/default_post.prf @@ -120,10 +120,12 @@ macx-xcode { QMAKE_XCODE_ARCHS = - arch_device.name = "ARCHS[sdk=$${device.sdk}*]" - arch_device.value = $$QMAKE_APPLE_DEVICE_ARCHS - QMAKE_XCODE_ARCHS += $$QMAKE_APPLE_DEVICE_ARCHS - QMAKE_MAC_XCODE_SETTINGS += arch_device + !isEmpty(QMAKE_APPLE_DEVICE_ARCHS) { + arch_device.name = "ARCHS[sdk=$${device.sdk}*]" + arch_device.value = $$QMAKE_APPLE_DEVICE_ARCHS + QMAKE_XCODE_ARCHS += $$QMAKE_APPLE_DEVICE_ARCHS + QMAKE_MAC_XCODE_SETTINGS += arch_device + } ios:simulator { arch_simulator.name = "ARCHS[sdk=$${simulator.sdk}*]" @@ -224,10 +226,16 @@ macx-xcode { platform_identifier = $$device.sdk sysroot_path = $$xcodeSDKInfo(Path, $$device.sdk) } - version_min_flag = -m$${version_identifier}-version-min=$$deployment_target - QMAKE_CFLAGS += -isysroot $$sysroot_path $$version_min_flag - QMAKE_CXXFLAGS += -isysroot $$sysroot_path $$version_min_flag - QMAKE_LFLAGS += -isysroot $$sysroot_path $$version_min_flag + QMAKE_CFLAGS += -isysroot $$sysroot_path + QMAKE_CXXFLAGS += -isysroot $$sysroot_path + QMAKE_LFLAGS += -isysroot $$sysroot_path + + !isEmpty(version_identifier):!isEmpty(deployment_target) { + version_min_flag = -m$${version_identifier}-version-min=$$deployment_target + QMAKE_CFLAGS += $$version_min_flag + QMAKE_CXXFLAGS += $$version_min_flag + QMAKE_LFLAGS += $$version_min_flag + } } # Enable precompiled headers for multiple architectures diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf index bfad10d35bc..13bf7f12aca 100644 --- a/mkspecs/features/toolchain.prf +++ b/mkspecs/features/toolchain.prf @@ -182,7 +182,7 @@ isEmpty($${target_prefix}.INCDIRS) { # UIKit simulator platforms will see the device SDK's sysroot in # QMAKE_DEFAULT_*DIRS, because they're handled in a single build pass. darwin { - uikit { + uikit:!isEmpty(QMAKE_APPLE_DEVICE_ARCHS) { # Clang doesn't automatically pick up the architecture, just because # we're passing the iOS sysroot below, and we will end up building the # test for the host architecture, resulting in linker errors when diff --git a/mkspecs/macx-visionos-clang/Info.plist.app b/mkspecs/macx-visionos-clang/Info.plist.app new file mode 100644 index 00000000000..df76305bde1 --- /dev/null +++ b/mkspecs/macx-visionos-clang/Info.plist.app @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDisplayName</key> + <string>${PRODUCT_NAME}</string> + + <key>CFBundleExecutable</key> + <string>${EXECUTABLE_NAME}</string> + + <key>CFBundleIconFile</key> + <string>${ASSETCATALOG_COMPILER_APPICON_NAME}</string> + + <key>CFBundleIdentifier</key> + <string>${PRODUCT_BUNDLE_IDENTIFIER}</string> + + <key>CFBundleName</key> + <string>${PRODUCT_NAME}</string> + + <key>CFBundlePackageType</key> + <string>APPL</string> + + <key>CFBundleShortVersionString</key> + <string>${QMAKE_SHORT_VERSION}</string> + + <key>CFBundleVersion</key> + <string>${QMAKE_FULL_VERSION}</string> + + <key>CFBundleDevelopmentRegion</key> + <string>$(DEVELOPMENT_LANGUAGE)</string> + <key>CFBundleAllowMixedLocalizations</key> + <true/> + + <key>CFBundleSupportedPlatforms</key> + <array> + <string>XROS</string> + </array> +</dict> +</plist> diff --git a/mkspecs/macx-visionos-clang/Info.plist.dSYM.in b/mkspecs/macx-visionos-clang/Info.plist.dSYM.in new file mode 100644 index 00000000000..a8c8d0d4fb5 --- /dev/null +++ b/mkspecs/macx-visionos-clang/Info.plist.dSYM.in @@ -0,0 +1,18 @@ +<?xml version=\"1.0\" encoding=\"UTF-8\"?> +<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"> +<plist version=\"1.0\"> + <dict> + <key>CFBundleIdentifier</key> + <string>com.apple.xcode.dsym.$${BUNDLEIDENTIFIER}</string> + <key>CFBundlePackageType</key> + <string>dSYM</string> + <key>CFBundleSignature</key> + <string>????</string> +!!IF !isEmpty(VERSION) + <key>CFBundleShortVersionString</key> + <string>$${VER_MAJ}.$${VER_MIN}</string> + <key>CFBundleVersion</key> + <string>$${VER_MAJ}.$${VER_MIN}.$${VER_PAT}</string> +!!ENDIF + </dict> +</plist> diff --git a/mkspecs/macx-visionos-clang/Info.plist.lib b/mkspecs/macx-visionos-clang/Info.plist.lib new file mode 100644 index 00000000000..34752ec40d9 --- /dev/null +++ b/mkspecs/macx-visionos-clang/Info.plist.lib @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleExecutable</key> + <string>${EXECUTABLE_NAME}</string> + <key>CFBundleIdentifier</key> + <string>${PRODUCT_BUNDLE_IDENTIFIER}</string> + <key>CFBundlePackageType</key> + <string>FMWK</string> + <key>CFBundleShortVersionString</key> + <string>${QMAKE_SHORT_VERSION}</string> + <key>CFBundleSignature</key> + <string>${QMAKE_PKGINFO_TYPEINFO}</string> + <key>CFBundleVersion</key> + <string>${QMAKE_FULL_VERSION}</string> + <key>NOTE</key> + <string>Please, do NOT change this file -- It was generated by Qt/QMake.</string> +</dict> +</plist> diff --git a/mkspecs/macx-visionos-clang/qmake.conf b/mkspecs/macx-visionos-clang/qmake.conf new file mode 100644 index 00000000000..35d92685733 --- /dev/null +++ b/mkspecs/macx-visionos-clang/qmake.conf @@ -0,0 +1,29 @@ +# +# qmake configuration for visionOS +# + +QMAKE_PLATFORM += visionos +QMAKE_MAC_SDK = xros + +device.sdk = xros +device.target = device +device.dir_affix = $${device.sdk} +device.CONFIG = $${device.sdk} +device.deployment_identifier = + +simulator.sdk = xrsimulator +simulator.target = simulator +simulator.dir_affix = $${simulator.sdk} +simulator.CONFIG = $${simulator.sdk} +simulator.deployment_identifier = + +QMAKE_APPLE_TARGETED_DEVICE_FAMILY = 7 + +include(../common/uikit.conf) +include(../common/gcc-base-mac.conf) +include(../common/clang.conf) +include(../common/clang-mac.conf) +include(../common/uikit/clang.conf) +include(../common/uikit/qmake.conf) + +load(qt_config) diff --git a/mkspecs/macx-visionos-clang/qplatformdefs.h b/mkspecs/macx-visionos-clang/qplatformdefs.h new file mode 100644 index 00000000000..3c0fa239cb5 --- /dev/null +++ b/mkspecs/macx-visionos-clang/qplatformdefs.h @@ -0,0 +1,4 @@ +// 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 + +#include "../common/mac/qplatformdefs.h" diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt index a785a31ee3e..e1fb0d7e393 100644 --- a/src/corelib/CMakeLists.txt +++ b/src/corelib/CMakeLists.txt @@ -1124,7 +1124,7 @@ qt_internal_extend_target(Core CONDITION QT_FEATURE_dlopen ${CMAKE_DL_LIBS} ) -qt_internal_extend_target(Core CONDITION APPLE AND (IOS OR TVOS) +qt_internal_extend_target(Core CONDITION APPLE AND UIKIT LIBRARIES ${FWUIKit} ) @@ -1382,7 +1382,7 @@ qt_internal_apply_gc_binaries_conditional(Core PUBLIC) # Add entry-point on platforms that need it. A project can opt-out of using the # entrypoint by setting the qt_no_entrypoint property to TRUE on a target. -if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "iOS") +if(WIN32 OR UIKIT) # find_package(Qt6Core) should call find_package(Qt6EntryPointPrivate) so that we can # link against EntryPointPrivate. Normally this is handled automatically for deps, but # for some reason it doesn't work for the EntryPointPrivate, so we need to add it manually. diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake index 3bcf7900064..9e8ce544cca 100644 --- a/src/corelib/Qt6CoreMacros.cmake +++ b/src/corelib/Qt6CoreMacros.cmake @@ -732,10 +732,14 @@ function(_qt_internal_finalize_executable target) _qt_internal_add_wasm_extra_exported_methods("${target}") _qt_internal_set_wasm_export_name("${target}") endif() - if(IOS) - _qt_internal_finalize_ios_app("${target}") - elseif(APPLE) - _qt_internal_finalize_macos_app("${target}") + + if(APPLE) + if(NOT CMAKE_SYSTEM_NAME OR CMAKE_SYSTEM_NAME STREQUAL "Darwin") + # macOS + _qt_internal_finalize_macos_app("${target}") + else() + _qt_internal_finalize_uikit_app("${target}") + endif() endif() # For finalizer mode of plugin importing to work safely, we need to know the list of Qt diff --git a/src/corelib/global/qoperatingsystemversion.cpp b/src/corelib/global/qoperatingsystemversion.cpp index d25a626b8d3..cf6063fca05 100644 --- a/src/corelib/global/qoperatingsystemversion.cpp +++ b/src/corelib/global/qoperatingsystemversion.cpp @@ -34,7 +34,7 @@ QT_BEGIN_NAMESPACE operating system version (as opposed to the kernel version number or marketing version). - Presently, Android, Apple Platforms (iOS, macOS, tvOS, and watchOS), + Presently, Android, Apple Platforms (iOS, macOS, tvOS, watchOS, and visionOS), and Windows are supported. The \a majorVersion(), \a minorVersion(), and \a microVersion() functions @@ -98,6 +98,7 @@ QT_BEGIN_NAMESPACE \value MacOS The Apple macOS operating system. \value TvOS The Apple tvOS operating system. \value WatchOS The Apple watchOS operating system. + \value VisionOS The Apple visionOS operating system. \value Windows The Microsoft Windows operating system. \value Unknown An unknown or unsupported operating system. @@ -325,6 +326,8 @@ QString QOperatingSystemVersionBase::name(QOperatingSystemVersionBase osversion) return QStringLiteral("tvOS"); case QOperatingSystemVersionBase::WatchOS: return QStringLiteral("watchOS"); + case QOperatingSystemVersionBase::VisionOS: + return QStringLiteral("visionOS"); case QOperatingSystemVersionBase::Android: return QStringLiteral("Android"); case QOperatingSystemVersionBase::Unknown: diff --git a/src/corelib/global/qoperatingsystemversion.h b/src/corelib/global/qoperatingsystemversion.h index 6aecdef3411..a9f30dc2752 100644 --- a/src/corelib/global/qoperatingsystemversion.h +++ b/src/corelib/global/qoperatingsystemversion.h @@ -30,7 +30,8 @@ public: IOS, TvOS, WatchOS, - Android + Android, + VisionOS }; constexpr QOperatingSystemVersionBase(OSType osType, @@ -57,6 +58,8 @@ public: return TvOS; #elif defined(Q_OS_WATCHOS) return WatchOS; +#elif defined(Q_OS_VISIONOS) + return VisionOS; #elif defined(Q_OS_ANDROID) return Android; #else @@ -158,7 +161,8 @@ public: IOS, TvOS, WatchOS, - Android + Android, + VisionOS }; #endif diff --git a/src/corelib/global/qsysinfo.cpp b/src/corelib/global/qsysinfo.cpp index 803d447d2c4..79cb76b2366 100644 --- a/src/corelib/global/qsysinfo.cpp +++ b/src/corelib/global/qsysinfo.cpp @@ -784,6 +784,8 @@ QString QSysInfo::productType() return QStringLiteral("tvos"); #elif defined(Q_OS_WATCHOS) return QStringLiteral("watchos"); +#elif defined(Q_OS_VISIONOS) + return QStringLiteral("visionos"); #elif defined(Q_OS_MACOS) return QStringLiteral("macos"); #elif defined(Q_OS_DARWIN) diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h index d797a196008..b29f2e94964 100644 --- a/src/corelib/global/qsystemdetection.h +++ b/src/corelib/global/qsystemdetection.h @@ -19,6 +19,7 @@ IOS - iOS WATCHOS - watchOS TVOS - tvOS + VISIONOS - visionOS WIN32 - Win32 (Windows 2000/XP/Vista/7 and Windows Server 2003/2008) CYGWIN - Cygwin SOLARIS - Sun Solaris @@ -61,6 +62,8 @@ # define Q_OS_WATCHOS # elif defined(TARGET_OS_TV) && TARGET_OS_TV # define Q_OS_TVOS +# elif defined(TARGET_OS_VISION) && TARGET_OS_VISION +# define Q_OS_VISIONOS # else # // TARGET_OS_IOS is only available in newer SDKs, # // so assume any other iOS-based platform is iOS for now diff --git a/src/corelib/global/qsystemdetection.qdoc b/src/corelib/global/qsystemdetection.qdoc index 11750e8cf73..a48a79bbb24 100644 --- a/src/corelib/global/qsystemdetection.qdoc +++ b/src/corelib/global/qsystemdetection.qdoc @@ -78,6 +78,13 @@ */ /*! + \macro Q_OS_VISIONOS + \relates <QtSystemDetection> + + Defined on visionOS. +*/ + +/*! \macro Q_OS_WIN \relates <QtSystemDetection> diff --git a/src/corelib/kernel/qcore_mac.mm b/src/corelib/kernel/qcore_mac.mm index d3c57e44f5d..54c4373aeda 100644 --- a/src/corelib/kernel/qcore_mac.mm +++ b/src/corelib/kernel/qcore_mac.mm @@ -567,6 +567,9 @@ void qt_apple_check_os_version() #elif defined(__TV_OS_VERSION_MIN_REQUIRED) const char *os = "tvOS"; const int version = __TV_OS_VERSION_MIN_REQUIRED; +#elif defined(__VISION_OS_VERSION_MIN_REQUIRED) + const char *os = "visionOS"; + const int version = __VISION_OS_VERSION_MIN_REQUIRED; #elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) const char *os = "iOS"; const int version = __IPHONE_OS_VERSION_MIN_REQUIRED; diff --git a/src/corelib/platform/darwin/qdarwinpermissionplugin_location.mm b/src/corelib/platform/darwin/qdarwinpermissionplugin_location.mm index 3676ba09634..1d32c0fcacb 100644 --- a/src/corelib/platform/darwin/qdarwinpermissionplugin_location.mm +++ b/src/corelib/platform/darwin/qdarwinpermissionplugin_location.mm @@ -73,6 +73,11 @@ struct PermissionRequest return Qt::PermissionStatus::Denied; } +#if defined(Q_OS_VISIONOS) + if (permission.availability() == QLocationPermission::Always) + return Qt::PermissionStatus::Denied; +#endif + auto status = [self authorizationStatus]; switch (status) { case kCLAuthorizationStatusRestricted: @@ -80,9 +85,11 @@ struct PermissionRequest return Qt::PermissionStatus::Denied; case kCLAuthorizationStatusNotDetermined: return Qt::PermissionStatus::Undetermined; +#if !defined(Q_OS_VISIONOS) case kCLAuthorizationStatusAuthorizedAlways: return Qt::PermissionStatus::Granted; -#ifdef Q_OS_IOS +#endif +#if defined(Q_OS_IOS) || defined(Q_OS_VISIONOS) case kCLAuthorizationStatusAuthorizedWhenInUse: if (permission.availability() == QLocationPermission::Always) return Qt::PermissionStatus::Denied; @@ -177,6 +184,9 @@ struct PermissionRequest } break; case QLocationPermission::Always: +#if defined(Q_OS_VISIONOS) + [self deliverResult]; // Not supported +#else // The documentation specifies that requestAlwaysAuthorization can only // be called when the current authorization status is either undetermined, // or authorized when in use. @@ -199,6 +209,7 @@ struct PermissionRequest default: [self deliverResult]; } +#endif break; } } diff --git a/src/entrypoint/CMakeLists.txt b/src/entrypoint/CMakeLists.txt index 21385eaba09..ba8342e41a9 100644 --- a/src/entrypoint/CMakeLists.txt +++ b/src/entrypoint/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: BSD-3-Clause -if (NOT WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "iOS") +if (NOT (WIN32 OR UIKIT)) return() endif() @@ -111,7 +111,7 @@ if(WIN32) qt_internal_add_sync_header_dependencies(EntryPointImplementation Core) endif() -if(CMAKE_SYSTEM_NAME STREQUAL "iOS") +if(UIKIT) set_target_properties(EntryPointPrivate PROPERTIES INTERFACE_LINK_OPTIONS "-Wl,-e,_qt_main_wrapper" ) diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 87621e4c680..cef71318d85 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -13,7 +13,7 @@ if (QT_FEATURE_gui) set(_default_platform "android") elseif(MACOS) set(_default_platform "cocoa") - elseif(TVOS OR IOS) + elseif(UIKIT) set(_default_platform "ios") elseif(WATCHOS) set(_default_platform "minimal") diff --git a/src/gui/configure.cmake b/src/gui/configure.cmake index ddb0af35b61..e1d8efb2928 100644 --- a/src/gui/configure.cmake +++ b/src/gui/configure.cmake @@ -813,7 +813,7 @@ qt_feature("vulkan" PUBLIC ) qt_feature("metal" PUBLIC LABEL "Metal" - CONDITION MACOS OR IOS + CONDITION MACOS OR IOS OR VISIONOS ) qt_feature("vkkhrdisplay" PRIVATE SECTION "Platform plugins" @@ -1255,6 +1255,7 @@ qt_feature("wayland" PUBLIC LABEL "Wayland" CONDITION TARGET Wayland::Client ) + qt_configure_add_summary_section(NAME "Qt Gui") qt_configure_add_summary_entry(ARGS "accessibility") qt_configure_add_summary_entry(ARGS "freetype") @@ -1371,7 +1372,7 @@ qt_configure_add_report_entry( qt_configure_add_report_entry( TYPE ERROR MESSAGE "The OpenGL functionality tests failed! You might need to modify the OpenGL package search path by setting the OpenGL_DIR CMake variable to the OpenGL library's installation directory." - CONDITION QT_FEATURE_gui AND NOT WATCHOS AND ( NOT INPUT_opengl STREQUAL 'no' ) AND NOT QT_FEATURE_opengl_desktop AND NOT QT_FEATURE_opengles2 AND NOT QT_FEATURE_opengl_dynamic + CONDITION QT_FEATURE_gui AND NOT WATCHOS AND NOT VISIONOS AND ( NOT INPUT_opengl STREQUAL 'no' ) AND NOT QT_FEATURE_opengl_desktop AND NOT QT_FEATURE_opengles2 AND NOT QT_FEATURE_opengl_dynamic ) qt_configure_add_report_entry( TYPE WARNING diff --git a/src/gui/painting/qcoregraphics.mm b/src/gui/painting/qcoregraphics.mm index 7b641063238..27b46202f50 100644 --- a/src/gui/painting/qcoregraphics.mm +++ b/src/gui/painting/qcoregraphics.mm @@ -185,7 +185,7 @@ QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size) #endif // Q_OS_MACOS -#ifdef Q_OS_IOS +#ifdef QT_PLATFORM_UIKIT QImage qt_mac_toQImage(const UIImage *image, QSizeF size) { @@ -202,7 +202,7 @@ QImage qt_mac_toQImage(const UIImage *image, QSizeF size) return ret; } -#endif // Q_OS_IOS +#endif // QT_PLATFORM_UIKIT // ---------------------- Colors and Brushes ---------------------- diff --git a/src/gui/painting/qcoregraphics_p.h b/src/gui/painting/qcoregraphics_p.h index f2c2ba1db14..a35f27a7304 100644 --- a/src/gui/painting/qcoregraphics_p.h +++ b/src/gui/painting/qcoregraphics_p.h @@ -26,10 +26,8 @@ #if defined(__OBJC__) # if defined(Q_OS_MACOS) # include <AppKit/AppKit.h> -# define HAVE_APPKIT -# elif defined(Q_OS_IOS) +# elif defined(QT_PLATFORM_UIKIT) # include <UIKit/UIKit.h> -# define HAVE_UIKIT # endif #endif @@ -37,11 +35,11 @@ QT_BEGIN_NAMESPACE Q_GUI_EXPORT CGBitmapInfo qt_mac_bitmapInfoForImage(const QImage &image); -#ifdef HAVE_UIKIT +#ifdef QT_PLATFORM_UIKIT Q_GUI_EXPORT QImage qt_mac_toQImage(const UIImage *image, QSizeF size); #endif -#ifdef HAVE_APPKIT +#ifdef Q_OS_MACOS Q_GUI_EXPORT QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size); QT_END_NAMESPACE @@ -66,7 +64,7 @@ Q_GUI_EXPORT void qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBou Q_GUI_EXPORT void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform); -#ifdef HAVE_APPKIT +#ifdef Q_OS_MACOS Q_GUI_EXPORT QColor qt_mac_toQColor(const NSColor *color); Q_GUI_EXPORT QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup = QPalette::Normal); #endif @@ -90,6 +88,4 @@ private: QT_END_NAMESPACE -#undef HAVE_APPKIT - #endif // QCOREGRAPHICS_P_H diff --git a/src/gui/platform/darwin/qappleiconengine.mm b/src/gui/platform/darwin/qappleiconengine.mm index 8300222dea4..7e0ed184dca 100644 --- a/src/gui/platform/darwin/qappleiconengine.mm +++ b/src/gui/platform/darwin/qappleiconengine.mm @@ -5,7 +5,7 @@ #if defined(Q_OS_MACOS) # include <AppKit/AppKit.h> -#elif defined (Q_OS_IOS) +#elif defined(QT_PLATFORM_UIKIT) # include <UIKit/UIKit.h> #endif @@ -280,7 +280,7 @@ auto *loadImage(const QString &iconName) NSString *systemIconName = it != std::end(iconMap) ? it->second : iconName.toNSString(); #if defined(Q_OS_MACOS) return [NSImage imageWithSystemSymbolName:systemIconName accessibilityDescription:nil]; -#elif defined(Q_OS_IOS) +#elif defined(QT_PLATFORM_UIKIT) return [UIImage systemImageNamed:systemIconName]; #endif } @@ -374,7 +374,7 @@ auto *configuredImage(const NSImage *image, const QColor &color) return [image imageWithSymbolConfiguration:config]; } -#elif defined(Q_OS_IOS) +#elif defined(QT_PLATFORM_UIKIT) auto *configuredImage(const UIImage *image, const QColor &color) { auto *config = [UIImageSymbolConfiguration configurationWithPointSize:48 @@ -453,7 +453,7 @@ void QAppleIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode m [image drawInRect:iconRect fromRect:sourceRect operation:NSCompositingOperationSourceOver fraction:1.0 respectFlipped:YES hints:nil]; [NSGraphicsContext restoreGraphicsState]; -#elif defined(Q_OS_IOS) +#elif defined(QT_PLATFORM_UIKIT) UIGraphicsPushContext(ctx); const CGRect cgrect = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); [image drawInRect:cgrect]; diff --git a/src/gui/platform/darwin/qappleiconengine_p.h b/src/gui/platform/darwin/qappleiconengine_p.h index 8f48e8e6fcf..2a4ff7fc649 100644 --- a/src/gui/platform/darwin/qappleiconengine_p.h +++ b/src/gui/platform/darwin/qappleiconengine_p.h @@ -51,7 +51,7 @@ private: const QString m_iconName; #if defined(Q_OS_MACOS) const NSImage *m_image; -#elif defined(Q_OS_IOS) +#elif defined(QT_PLATFORM_UIKIT) const UIImage *m_image; #endif mutable QPixmap m_pixmap; diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index e10da4ca0e6..1c7b3971938 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -567,9 +567,7 @@ bool QRhiMetal::create(QRhi::Flags flags) // suitable as deviceId because it does not seem stable on macOS and can // apparently change when the system is rebooted. -#ifdef Q_OS_IOS - driverInfoStruct.deviceType = QRhiDriverInfo::IntegratedDevice; -#else +#ifdef Q_OS_MACOS if (@available(macOS 10.15, *)) { const MTLDeviceLocation deviceLocation = [d->dev location]; switch (deviceLocation) { @@ -586,6 +584,8 @@ bool QRhiMetal::create(QRhi::Flags flags) break; } } +#else + driverInfoStruct.deviceType = QRhiDriverInfo::IntegratedDevice; #endif const QOperatingSystemVersion ver = QOperatingSystemVersion::current(); @@ -6465,12 +6465,12 @@ QRhiSwapChainHdrInfo QMetalSwapChain::hdrInfo() if (m_window) { // Must use m_window, not window, given this may be called before createOrResize(). -#ifdef Q_OS_MACOS +#if defined(Q_OS_MACOS) NSView *view = reinterpret_cast<NSView *>(m_window->winId()); NSScreen *screen = view.window.screen; info.limits.colorComponentValue.maxColorComponentValue = screen.maximumExtendedDynamicRangeColorComponentValue; info.limits.colorComponentValue.maxPotentialColorComponentValue = screen.maximumPotentialExtendedDynamicRangeColorComponentValue; -#else +#elif defined(Q_OS_IOS) if (@available(iOS 16.0, *)) { UIView *view = reinterpret_cast<UIView *>(m_window->winId()); UIScreen *screen = view.window.windowScene.screen; diff --git a/src/gui/text/coretext/qcoretextfontdatabase.mm b/src/gui/text/coretext/qcoretextfontdatabase.mm index 3e058ec25ff..19f3a2b3352 100644 --- a/src/gui/text/coretext/qcoretextfontdatabase.mm +++ b/src/gui/text/coretext/qcoretextfontdatabase.mm @@ -896,7 +896,7 @@ static CTFontDescriptorRef fontDescriptorFromTheme(QPlatformTheme::Font f) UIFontDescriptor *desc = [UIFontDescriptor preferredFontDescriptorWithTextStyle:textStyle]; return static_cast<CTFontDescriptorRef>(CFBridgingRetain(desc)); } -#endif // Q_OS_IOS, Q_OS_TVOS, Q_OS_WATCHOS +#endif // QT_PLATFORM_UIKIT // macOS default case and iOS fallback case return descriptorForFontType(fontTypeFromTheme(f)); diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index f68198df588..4d5c6412472 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -244,7 +244,7 @@ qt_internal_extend_target(Network CONDITION QT_FEATURE_dnslookup AND NOT QT_FEAT kernel/qdnslookup_dummy.cpp ) -qt_internal_extend_target(Network CONDITION IOS OR MACOS +qt_internal_extend_target(Network CONDITION APPLE SOURCES kernel/qnetconmonitor_darwin.mm LIBRARIES @@ -256,7 +256,7 @@ qt_internal_extend_target(Network CONDITION QT_FEATURE_networklistmanager AND NO kernel/qnetconmonitor_win.cpp ) -qt_internal_extend_target(Network CONDITION NOT IOS AND NOT MACOS AND NOT QT_FEATURE_networklistmanager +qt_internal_extend_target(Network CONDITION NOT APPLE AND NOT QT_FEATURE_networklistmanager SOURCES kernel/qnetconmonitor_stub.cpp ) @@ -271,7 +271,7 @@ qt_internal_extend_target(Network CONDITION UIKIT kernel/qnetworkinterface_uikit_p.h ) -qt_internal_extend_target(Network CONDITION APPLE +qt_internal_extend_target(Network CONDITION APPLE AND NOT VISIONOS SOURCES kernel/qnetworkproxy_darwin.cpp ) @@ -289,7 +289,7 @@ qt_internal_extend_target(Network CONDITION ANDROID kernel/qnetworkproxy_android.cpp ) -qt_internal_extend_target(Network CONDITION UNIX AND NOT ANDROID AND NOT APPLE AND NOT QT_FEATURE_libproxy AND (UNIX OR WINRT) +qt_internal_extend_target(Network CONDITION UNIX AND NOT ANDROID AND NOT (APPLE AND NOT VISIONOS) AND NOT QT_FEATURE_libproxy AND (UNIX OR WINRT) SOURCES kernel/qnetworkproxy_generic.cpp ) diff --git a/src/plugins/platforms/ios/CMakeLists.txt b/src/plugins/platforms/ios/CMakeLists.txt index 1c99103a49a..32e4eb8051a 100644 --- a/src/plugins/platforms/ios/CMakeLists.txt +++ b/src/plugins/platforms/ios/CMakeLists.txt @@ -57,20 +57,31 @@ qt_internal_extend_target(QIOSIntegrationPlugin CONDITION QT_FEATURE_opengl Qt::OpenGLPrivate ) -qt_internal_extend_target(QIOSIntegrationPlugin CONDITION NOT TVOS +qt_internal_extend_target(QIOSIntegrationPlugin CONDITION QT_FEATURE_clipboard SOURCES qiosclipboard.h qiosclipboard.mm - qiosdocumentpickercontroller.h qiosdocumentpickercontroller.mm +) + +qt_internal_extend_target(QIOSIntegrationPlugin CONDITION NOT TVOS + SOURCES qiosfiledialog.h qiosfiledialog.mm + qiosdocumentpickercontroller.h qiosdocumentpickercontroller.mm + LIBRARIES + ${FWUniformTypeIdentifiers} + ${FWPhotos} +) + +qt_internal_extend_target(QIOSIntegrationPlugin CONDITION NOT TVOS + SOURCES qioscolordialog.h qioscolordialog.mm qiosfontdialog.h qiosfontdialog.mm - qiosmenu.h qiosmenu.mm qiosmessagedialog.h qiosmessagedialog.mm +) + +qt_internal_extend_target(QIOSIntegrationPlugin CONDITION NOT (TVOS OR VISIONOS) + SOURCES + qiosmenu.h qiosmenu.mm qiostextinputoverlay.h qiostextinputoverlay.mm - LIBRARIES - ${FWAssetsLibrary} - ${FWUniformTypeIdentifiers} - ${FWPhotos} ) add_subdirectory(optional) diff --git a/src/plugins/platforms/ios/qioscolordialog.mm b/src/plugins/platforms/ios/qioscolordialog.mm index 92c0f3e46c8..6651b1791df 100644 --- a/src/plugins/platforms/ios/qioscolordialog.mm +++ b/src/plugins/platforms/ios/qioscolordialog.mm @@ -8,6 +8,7 @@ #include <QtCore/private/qcore_mac_p.h> +#include "qiosglobal.h" #include "qioscolordialog.h" #include "qiosintegration.h" @@ -117,8 +118,7 @@ bool QIOSColorDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality windo if (windowModality == Qt::ApplicationModal || windowModality == Qt::WindowModal) m_viewController.modalInPresentation = YES; - UIWindow *window = parent ? reinterpret_cast<UIView *>(parent->winId()).window - : qt_apple_sharedApplication().keyWindow; + UIWindow *window = presentationWindow(parent); if (!window) return false; diff --git a/src/plugins/platforms/ios/qiosfiledialog.mm b/src/plugins/platforms/ios/qiosfiledialog.mm index 63d180220b4..cf9580c17e9 100644 --- a/src/plugins/platforms/ios/qiosfiledialog.mm +++ b/src/plugins/platforms/ios/qiosfiledialog.mm @@ -11,6 +11,7 @@ #include <QtCore/private/qcore_mac_p.h> +#include "qiosglobal.h" #include "qiosfiledialog.h" #include "qiosintegration.h" #include "qiosoptionalplugininterface.h" @@ -59,8 +60,7 @@ bool QIOSFileDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality window void QIOSFileDialog::showImagePickerDialog_helper(QWindow *parent) { - UIWindow *window = parent ? reinterpret_cast<UIView *>(parent->winId()).window - : qt_apple_sharedApplication().keyWindow; + UIWindow *window = presentationWindow(parent); [window.rootViewController presentViewController:m_viewController animated:YES completion:nil]; } @@ -123,8 +123,7 @@ bool QIOSFileDialog::showNativeDocumentPickerDialog(QWindow *parent) #ifndef Q_OS_TVOS m_viewController = [[QIOSDocumentPickerController alloc] initWithQIOSFileDialog:this]; - UIWindow *window = parent ? reinterpret_cast<UIView *>(parent->winId()).window - : qt_apple_sharedApplication().keyWindow; + UIWindow *window = presentationWindow(parent); [window.rootViewController presentViewController:m_viewController animated:YES completion:nil]; return true; diff --git a/src/plugins/platforms/ios/qiosfontdialog.mm b/src/plugins/platforms/ios/qiosfontdialog.mm index 4cea1cb5584..25d0197195e 100644 --- a/src/plugins/platforms/ios/qiosfontdialog.mm +++ b/src/plugins/platforms/ios/qiosfontdialog.mm @@ -11,6 +11,7 @@ #include <QtGui/private/qfont_p.h> #include <QtGui/private/qfontengine_p.h> +#include "qiosglobal.h" #include "qiosfontdialog.h" #include "qiosintegration.h" @@ -144,8 +145,7 @@ bool QIOSFontDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality window if (windowModality == Qt::ApplicationModal || windowModality == Qt::WindowModal) m_viewController.modalInPresentation = YES; - UIWindow *window = parent ? reinterpret_cast<UIView *>(parent->winId()).window - : qt_apple_sharedApplication().keyWindow; + UIWindow *window = presentationWindow(parent); if (!window) return false; diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index a5139a3fdef..e7ca2d1fecc 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -34,6 +34,9 @@ UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation) int infoPlistValue(NSString* key, int defaultValue); +class QWindow; +UIWindow *presentationWindow(QWindow *); + QT_END_NAMESPACE @interface UIResponder (QtFirstResponder) diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index c0faccaf712..169c292a008 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -85,6 +85,16 @@ int infoPlistValue(NSString* key, int defaultValue) return value ? [value intValue] : defaultValue; } +UIWindow *presentationWindow(QWindow *window) +{ + UIWindow *uiWindow = window ? reinterpret_cast<UIView *>(window->winId()).window : nullptr; +#if !defined(Q_OS_VISIONOS) + if (!uiWindow) + uiWindow = qt_apple_sharedApplication().keyWindow; +#endif + return uiWindow; +} + QT_END_NAMESPACE // ------------------------------------------------------------------------- diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index 56322a0f65f..d4f81f22e3d 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -22,11 +22,13 @@ // ------------------------------------------------------------------------- +#if !defined(Q_OS_VISIONOS) static QUIView *focusView() { return qApp->focusWindow() ? reinterpret_cast<QUIView *>(qApp->focusWindow()->winId()) : 0; } +#endif // ------------------------------------------------------------------------- @@ -352,7 +354,7 @@ void QIOSInputContext::clearCurrentFocusObject() void QIOSInputContext::updateKeyboardState(NSNotification *notification) { -#ifdef Q_OS_TVOS +#if defined(Q_OS_TVOS) || defined(Q_OS_VISIONOS) Q_UNUSED(notification); #else static CGRect currentKeyboardRect = CGRectZero; @@ -442,6 +444,7 @@ UIView *QIOSInputContext::scrollableRootView() void QIOSInputContext::scrollToCursor() { +#if !defined(Q_OS_VISIONOS) if (!isQtApplication()) return; @@ -498,6 +501,7 @@ void QIOSInputContext::scrollToCursor() } else { scroll(0); } +#endif } void QIOSInputContext::scroll(int y) diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index a57a707c7f4..2c7d33cc946 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -11,7 +11,8 @@ #include <QtCore/private/qfactoryloader_p.h> #include "qiosapplicationstate.h" -#ifndef Q_OS_TVOS + +#if !defined(Q_OS_TVOS) && !defined(Q_OS_VISIONOS) #include "qiostextinputoverlay.h" #endif @@ -41,9 +42,11 @@ public: QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override; QPlatformFontDatabase *fontDatabase() const override; -#ifndef QT_NO_CLIPBOARD + +#if QT_CONFIG(clipboard) QPlatformClipboard *clipboard() const override; #endif + QPlatformInputContext *inputContext() const override; QPlatformServices *services() const override; @@ -76,7 +79,7 @@ public: private: QPlatformFontDatabase *m_fontDatabase; -#ifndef Q_OS_TVOS +#if QT_CONFIG(clipboard) QPlatformClipboard *m_clipboard; #endif QPlatformInputContext *m_inputContext; @@ -84,7 +87,7 @@ private: QIOSServices *m_platformServices; mutable QPlatformAccessibility *m_accessibility; QFactoryLoader *m_optionalPlugins; -#ifndef Q_OS_TVOS +#if !defined(Q_OS_TVOS) && !defined(Q_OS_VISIONOS) QIOSTextInputOverlay m_textInputOverlay; #endif }; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index c646042eb26..7cd21f83f66 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -9,7 +9,7 @@ #include "qioswindow.h" #include "qiosscreen.h" #include "qiosplatformaccessibility.h" -#ifndef Q_OS_TVOS +#if QT_CONFIG(clipboard) #include "qiosclipboard.h" #endif #include "qiosinputcontext.h" @@ -51,7 +51,7 @@ QIOSIntegration *QIOSIntegration::instance() QIOSIntegration::QIOSIntegration() : m_fontDatabase(new QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>) -#if !defined(Q_OS_TVOS) && !defined(QT_NO_CLIPBOARD) +#if QT_CONFIG(clipboard) , m_clipboard(new QIOSClipboard) #endif , m_inputContext(0) @@ -72,6 +72,10 @@ QIOSIntegration::QIOSIntegration() void QIOSIntegration::initialize() { +#if defined(Q_OS_VISIONOS) + // Qt requires a screen, so let's give it a dummy one + QWindowSystemInterface::handleScreenAdded(new QIOSScreen); +#else UIScreen *mainScreen = [UIScreen mainScreen]; NSMutableArray<UIScreen *> *screens = [[[UIScreen screens] mutableCopy] autorelease]; if (![screens containsObject:mainScreen]) { @@ -81,6 +85,7 @@ void QIOSIntegration::initialize() for (UIScreen *screen in screens) QWindowSystemInterface::handleScreenAdded(new QIOSScreen(screen)); +#endif // Depends on a primary screen being present m_inputContext = new QIOSInputContext; @@ -88,8 +93,10 @@ void QIOSIntegration::initialize() m_touchDevice = new QPointingDevice; m_touchDevice->setType(QInputDevice::DeviceType::TouchScreen); QPointingDevice::Capabilities touchCapabilities = QPointingDevice::Capability::Position | QPointingDevice::Capability::NormalizedPosition; +#if !defined(Q_OS_VISIONOS) if (mainScreen.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) touchCapabilities |= QPointingDevice::Capability::Pressure; +#endif m_touchDevice->setCapabilities(touchCapabilities); QWindowSystemInterface::registerInputDevice(m_touchDevice); #if QT_CONFIG(tabletevent) @@ -107,7 +114,7 @@ QIOSIntegration::~QIOSIntegration() delete m_fontDatabase; m_fontDatabase = 0; -#if !defined(Q_OS_TVOS) && !defined(QT_NO_CLIPBOARD) +#if QT_CONFIG(clipboard) delete m_clipboard; m_clipboard = 0; #endif @@ -208,14 +215,10 @@ QPlatformFontDatabase * QIOSIntegration::fontDatabase() const return m_fontDatabase; } -#ifndef QT_NO_CLIPBOARD +#if QT_CONFIG(clipboard) QPlatformClipboard *QIOSIntegration::clipboard() const { -#ifndef Q_OS_TVOS return m_clipboard; -#else - return QPlatformIntegration::clipboard(); -#endif } #endif diff --git a/src/plugins/platforms/ios/qiosmessagedialog.mm b/src/plugins/platforms/ios/qiosmessagedialog.mm index 34421bbbd18..979829377a9 100644 --- a/src/plugins/platforms/ios/qiosmessagedialog.mm +++ b/src/plugins/platforms/ios/qiosmessagedialog.mm @@ -116,7 +116,7 @@ bool QIOSMessageDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality win [m_alertController addAction:createAction(NoButton)]; } - UIWindow *window = parent ? reinterpret_cast<UIView *>(parent->winId()).window : qt_apple_sharedApplication().keyWindow; + UIWindow *window = presentationWindow(parent); if (!window) { qCDebug(lcQpaWindow, "Attempting to exec a dialog without any window/widget visible."); diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 21afb90c556..b1fa5cad0d7 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -21,7 +21,11 @@ class QIOSScreen : public QObject, public QPlatformScreen Q_OBJECT public: +#if !defined(Q_OS_VISIONOS) QIOSScreen(UIScreen *screen); +#else + QIOSScreen(); +#endif ~QIOSScreen(); QString name() const override; @@ -40,7 +44,9 @@ public: QPixmap grabWindow(WId window, int x, int y, int width, int height) const override; +#if !defined(Q_OS_VISIONOS) UIScreen *uiScreen() const; +#endif UIWindow *uiWindow() const; void setUpdatesPaused(bool); @@ -50,15 +56,19 @@ public: private: void deliverUpdateRequests() const; - UIScreen *m_uiScreen; - UIWindow *m_uiWindow; +#if !defined(Q_OS_VISIONOS) + UIScreen *m_uiScreen = nullptr; +#endif + UIWindow *m_uiWindow = nullptr; QRect m_geometry; QRect m_availableGeometry; int m_depth; +#if !defined(Q_OS_VISIONOS) uint m_physicalDpi; +#endif QSizeF m_physicalSize; - QIOSOrientationListener *m_orientationListener; - CADisplayLink *m_displayLink; + QIOSOrientationListener *m_orientationListener = nullptr; + CADisplayLink *m_displayLink = nullptr; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index e48592aa245..5c61f6f724e 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -46,6 +46,7 @@ typedef void (^DisplayLinkBlock)(CADisplayLink *displayLink); // ------------------------------------------------------------------------- +#if !defined(Q_OS_VISIONOS) static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen) { foreach (QScreen *screen, QGuiApplication::screens()) { @@ -149,6 +150,8 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen) @end +#endif // !defined(Q_OS_VISIONOS) + // ------------------------------------------------------------------------- @implementation QUIWindow @@ -167,6 +170,7 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen) [super sendEvent:event]; } +#if !defined(Q_OS_VISIONOS) - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { [super traitCollectionDidChange:previousTraitCollection]; @@ -189,6 +193,7 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen) } } } +#endif @end @@ -198,6 +203,7 @@ QT_BEGIN_NAMESPACE using namespace Qt::StringLiterals; +#if !defined(Q_OS_VISIONOS) /*! Returns the model identifier of the device. */ @@ -217,12 +223,14 @@ static QString deviceModelIdentifier() return QString::fromLatin1(QByteArrayView(value, qsizetype(size))); #endif } +#endif // !defined(Q_OS_VISIONOS) +#if defined(Q_OS_VISIONOS) +QIOSScreen::QIOSScreen() +{ +#else QIOSScreen::QIOSScreen(UIScreen *screen) - : QPlatformScreen() - , m_uiScreen(screen) - , m_uiWindow(0) - , m_orientationListener(0) + : m_uiScreen(screen) { QString deviceIdentifier = deviceModelIdentifier(); @@ -273,11 +281,13 @@ QIOSScreen::QIOSScreen(UIScreen *screen) m_orientationListener = [[QIOSOrientationListener alloc] initWithQIOSScreen:this]; - updateProperties(); - m_displayLink = [m_uiScreen displayLinkWithBlock:^(CADisplayLink *) { deliverUpdateRequests(); }]; m_displayLink.paused = YES; // Enabled when clients call QWindow::requestUpdate() [m_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; + +#endif // !defined(Q_OS_VISIONOS)) + + updateProperties(); } QIOSScreen::~QIOSScreen() @@ -290,13 +300,17 @@ QIOSScreen::~QIOSScreen() QString QIOSScreen::name() const { +#if defined(Q_OS_VISIONOS) + return {}; +#else if (m_uiScreen == [UIScreen mainScreen]) return QString::fromNSString([UIDevice currentDevice].model) + " built-in display"_L1; else return "External display"_L1; +#endif } -static bool isRunningOnVisionOS() +[[maybe_unused]] static bool isRunningOnVisionOS() { static bool result = []{ // This class is documented to only be available on visionOS @@ -310,8 +324,13 @@ void QIOSScreen::updateProperties() QRect previousGeometry = m_geometry; QRect previousAvailableGeometry = m_availableGeometry; +#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 @@ -369,6 +388,8 @@ void QIOSScreen::updateProperties() m_physicalSize = physicalGeometry.size() / m_physicalDpi * millimetersPerInch; } +#endif // defined(Q_OS_VISIONOS) + // 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 @@ -453,16 +474,28 @@ QDpi QIOSScreen::logicalBaseDpi() const qreal QIOSScreen::devicePixelRatio() const { +#if defined(Q_OS_VISIONOS) + return 2.0; // Based on what iPad app reports +#else return [m_uiScreen scale]; +#endif } qreal QIOSScreen::refreshRate() const { +#if defined(Q_OS_VISIONOS) + return 120.0; // Based on what iPad app reports +#else return m_uiScreen.maximumFramesPerSecond; +#endif } Qt::ScreenOrientation QIOSScreen::nativeOrientation() const { +#if defined(Q_OS_VISIONOS) + // Based on iPad app reporting native bounds 1668x2388 + return Qt::PortraitOrientation; +#else CGRect nativeBounds = #if defined(Q_OS_IOS) m_uiScreen.nativeBounds; @@ -474,11 +507,12 @@ Qt::ScreenOrientation QIOSScreen::nativeOrientation() const // be on the safe side we compare the width and height of the bounds. return nativeBounds.size.width >= nativeBounds.size.height ? Qt::LandscapeOrientation : Qt::PortraitOrientation; +#endif } Qt::ScreenOrientation QIOSScreen::orientation() const { -#ifdef Q_OS_TVOS +#if defined(Q_OS_TVOS) || defined(Q_OS_VISIONOS) return Qt::PrimaryOrientation; #else // Auxiliary screens are always the same orientation as their primary orientation @@ -540,10 +574,12 @@ QPixmap QIOSScreen::grabWindow(WId window, int x, int y, int width, int height) return QPixmap::fromImage(qt_mac_toQImage(screenshot.CGImage)); } +#if !defined(Q_OS_VISIONOS) UIScreen *QIOSScreen::uiScreen() const { return m_uiScreen; } +#endif UIWindow *QIOSScreen::uiWindow() const { diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index b7377cc5e79..5231a3addef 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -401,7 +401,7 @@ if (UIView *accessoryView = static_cast<UIView *>(platformData.value(kImePlatformDataInputAccessoryView).value<void *>())) self.inputAccessoryView = [[[WrapperView alloc] initWithView:accessoryView] autorelease]; -#ifndef Q_OS_TVOS +#if !defined(Q_OS_TVOS) && !defined(Q_OS_VISIONOS) if (platformData.value(kImePlatformDataHideShortcutsBar).toBool()) { // According to the docs, leadingBarButtonGroups/trailingBarButtonGroups should be set to nil to hide the shortcuts bar. // However, starting with iOS 10, the API has been surrounded with NS_ASSUME_NONNULL, which contradicts this and causes diff --git a/src/plugins/platforms/ios/qiostheme.h b/src/plugins/platforms/ios/qiostheme.h index 0f12ce099c6..f0a404a61a2 100644 --- a/src/plugins/platforms/ios/qiostheme.h +++ b/src/plugins/platforms/ios/qiostheme.h @@ -23,8 +23,10 @@ public: Qt::ColorScheme colorScheme() const override; +#if !defined(Q_OS_TVOS) && !defined(Q_OS_VISIONOS) QPlatformMenuItem* createPlatformMenuItem() const override; QPlatformMenu* createPlatformMenu() const override; +#endif bool usePlatformNativeDialog(DialogType type) const override; QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const override; diff --git a/src/plugins/platforms/ios/qiostheme.mm b/src/plugins/platforms/ios/qiostheme.mm index 3d6d60f9717..251d0434cb5 100644 --- a/src/plugins/platforms/ios/qiostheme.mm +++ b/src/plugins/platforms/ios/qiostheme.mm @@ -18,12 +18,15 @@ #include <UIKit/UIFont.h> #include <UIKit/UIInterface.h> -#ifndef Q_OS_TVOS +#if !defined(Q_OS_TVOS) && !defined(Q_OS_VISIONOS) #include "qiosmenu.h" +#endif + +#if !defined(Q_OS_TVOS) #include "qiosfiledialog.h" -#include "qiosmessagedialog.h" #include "qioscolordialog.h" #include "qiosfontdialog.h" +#include "qiosmessagedialog.h" #include "qiosscreen.h" #endif @@ -82,23 +85,17 @@ const QPalette *QIOSTheme::palette(QPlatformTheme::Palette type) const return 0; } +#if !defined(Q_OS_TVOS) && !defined(Q_OS_VISIONOS) QPlatformMenuItem* QIOSTheme::createPlatformMenuItem() const { -#ifdef Q_OS_TVOS - return 0; -#else - return new QIOSMenuItem(); -#endif + return new QIOSMenuItem; } QPlatformMenu* QIOSTheme::createPlatformMenu() const { -#ifdef Q_OS_TVOS - return 0; -#else - return new QIOSMenu(); -#endif + return new QIOSMenu; } +#endif bool QIOSTheme::usePlatformNativeDialog(QPlatformTheme::DialogType type) const { @@ -149,6 +146,13 @@ QVariant QIOSTheme::themeHint(ThemeHint hint) const Qt::ColorScheme QIOSTheme::colorScheme() const { +#if defined(Q_OS_VISIONOS) + // On visionOS the concept of light or dark mode does not + // apply, as the UI is constantly changing based on what + // the lighting conditions are outside the headset, but + // the OS reports itself as always being in dark mode. + return Qt::ColorScheme::Dark; +#else // Set the appearance based on the QUIWindow // Fallback to the UIScreen if no window is created yet UIUserInterfaceStyle appearance = UIScreen.mainScreen.traitCollection.userInterfaceStyle; @@ -163,6 +167,7 @@ Qt::ColorScheme QIOSTheme::colorScheme() const return appearance == UIUserInterfaceStyleDark ? Qt::ColorScheme::Dark : Qt::ColorScheme::Light; +#endif } const QFont *QIOSTheme::font(Font type) const diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 01a8a0d9b26..fa3fef26b68 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -88,6 +88,7 @@ - (void)didAddSubview:(UIView *)subview { +#if !defined(Q_OS_VISIONOS) Q_UNUSED(subview); QT_PREPEND_NAMESPACE(QIOSScreen) *screen = self.qtViewController.platformScreen; @@ -103,10 +104,12 @@ uiWindow.screen = screen->uiScreen(); uiWindow.hidden = NO; } +#endif } - (void)willRemoveSubview:(UIView *)subview { +#if !defined(Q_OS_VISIONOS) Q_UNUSED(subview); UIWindow *uiWindow = self.window; @@ -124,6 +127,7 @@ uiWindow.screen = [UIScreen mainScreen]; }); } +#endif } - (void)layoutSubviews @@ -285,7 +289,7 @@ Q_ASSERT(!qt_apple_isApplicationExtension()); -#ifndef Q_OS_TVOS +#if !defined(Q_OS_TVOS) && !defined(Q_OS_VISIONOS) NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center addObserver:self selector:@selector(willChangeStatusBarFrame:) name:UIApplicationWillChangeStatusBarFrameNotification @@ -307,7 +311,7 @@ - (BOOL)shouldAutorotate { -#ifndef Q_OS_TVOS +#if !defined(Q_OS_TVOS) && !defined(Q_OS_VISIONOS) return self.platformScreen && self.platformScreen->uiScreen() == [UIScreen mainScreen] && !self.lockedOrientation; #else return NO; @@ -339,6 +343,7 @@ [super didRotateFromInterfaceOrientation:orientation]; } +#if !defined(Q_OS_VISIONOS) - (void)willChangeStatusBarFrame:(NSNotification*)notification { Q_UNUSED(notification); @@ -382,6 +387,7 @@ [self.view setNeedsLayout]; } +#endif - (void)viewWillLayoutSubviews { @@ -402,10 +408,12 @@ if (!self.platformScreen || !self.platformScreen->screen()) return; +#if !defined(Q_OS_VISIONOS) // For now we only care about the main screen, as both the statusbar // visibility and orientation is only appropriate for the main screen. if (self.platformScreen->uiScreen() != [UIScreen mainScreen]) return; +#endif // Prevent recursion caused by updating the status bar appearance (position // or visibility), which in turn may cause a layout of our subviews, and @@ -432,7 +440,7 @@ // All decisions are based on the top level window focusWindow = qt_window_private(focusWindow)->topLevelWindow(); -#ifndef Q_OS_TVOS +#if !defined(Q_OS_TVOS) && !defined(Q_OS_VISIONOS) // -------------- Status bar style and visbility --------------- diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 3631d6be70b..398f8c4a6f9 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -21,7 +21,7 @@ #import <QuartzCore/CAEAGLLayer.h> #endif -#ifdef Q_OS_IOS +#if QT_CONFIG(metal) #import <QuartzCore/CAMetalLayer.h> #endif @@ -42,7 +42,7 @@ QIOSWindow::QIOSWindow(QWindow *window, WId nativeHandle) m_view = reinterpret_cast<UIView *>(nativeHandle); [m_view retain]; } else { -#ifdef Q_OS_IOS +#if QT_CONFIG(metal) if (window->surfaceType() == QSurface::RasterSurface) window->setSurfaceType(QSurface::MetalSurface); @@ -304,7 +304,6 @@ void QIOSWindow::requestActivateWindow() if (blockedByModal()) return; - Q_ASSERT(m_view.window); [m_view.window makeKeyWindow]; [m_view becomeFirstResponder]; diff --git a/src/plugins/platforms/ios/quiview.h b/src/plugins/platforms/ios/quiview.h index 51725851729..7899ec6e0e4 100644 --- a/src/plugins/platforms/ios/quiview.h +++ b/src/plugins/platforms/ios/quiview.h @@ -34,7 +34,7 @@ QT_END_NAMESPACE - (QIOSViewController*)qtViewController; @end -#ifdef Q_OS_IOS +#if QT_CONFIG(metal) @interface QUIMetalView : QUIView @end #endif diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index f1103dae9c3..58071eed376 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -61,7 +61,7 @@ inline ulong getTimeStamp(UIEvent *event) + (void)load { -#ifndef Q_OS_TVOS +#if !defined(Q_OS_TVOS) && !defined(Q_OS_VISIONOS) if (QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::IOS, 11)) { // iOS 11 handles this though [UIView safeAreaInsetsDidChange], but there's no signal for // the corresponding top and bottom layout guides that we use on earlier versions. Note @@ -197,6 +197,7 @@ inline ulong getTimeStamp(UIEvent *event) return description; } +#if !defined(Q_OS_VISIONOS) - (void)willMoveToWindow:(UIWindow *)newWindow { // UIKIt will normally set the scale factor of a view to match the corresponding @@ -206,6 +207,7 @@ inline ulong getTimeStamp(UIEvent *event) // FIXME: Allow the scale factor to be customized through QSurfaceFormat. } +#endif - (void)didAddSubview:(UIView *)subview { @@ -700,7 +702,7 @@ inline ulong getTimeStamp(UIEvent *event) - (BOOL)canPerformAction:(SEL)action withSender:(id)sender { -#ifndef Q_OS_TVOS +#if !defined(Q_OS_TVOS) && !defined(Q_OS_VISIONOS) // Check first if QIOSMenu should handle the action before continuing up the responder chain return [QIOSMenu::menuActionTarget() targetForAction:action withSender:sender] != 0; #else @@ -713,7 +715,7 @@ inline ulong getTimeStamp(UIEvent *event) - (id)forwardingTargetForSelector:(SEL)selector { Q_UNUSED(selector); -#ifndef Q_OS_TVOS +#if !defined(Q_OS_TVOS) && !defined(Q_OS_VISIONOS) return QIOSMenu::menuActionTarget(); #else return nil; @@ -831,7 +833,7 @@ inline ulong getTimeStamp(UIEvent *event) @end -#ifdef Q_OS_IOS +#if QT_CONFIG(metal) @implementation QUIMetalView + (Class)layerClass diff --git a/src/testlib/qtestblacklist.cpp b/src/testlib/qtestblacklist.cpp index 064a59f0128..4154f8f2a60 100644 --- a/src/testlib/qtestblacklist.cpp +++ b/src/testlib/qtestblacklist.cpp @@ -118,6 +118,9 @@ static QSet<QByteArray> keywords() #ifdef Q_OS_WATCHOS << "watchos" #endif +#ifdef Q_OS_VISIONOS + << "visionos" +#endif #ifdef Q_OS_ANDROID << "android" #endif diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index b6502284e27..2cc40fc7ad6 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1289,7 +1289,7 @@ void QWidgetPrivate::create() Qt::WindowFlags &flags = data.window_flags; -#if defined(Q_OS_IOS) || defined(Q_OS_TVOS) +#if defined(QT_PLATFORM_UIKIT) if (q->testAttribute(Qt::WA_ContentsMarginsRespectsSafeArea)) flags |= Qt::MaximizeUsingFullscreenGeometryHint; #endif |