summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Arne Vestbø <[email protected]>2024-03-18 19:35:52 +0100
committerTor Arne Vestbø <[email protected]>2024-04-18 05:00:57 +0200
commitd5bf42f75b0ae35b7f02bb9211787ae1d44a98ba (patch)
tree3aa389137752dbe2bbaa7446e4ef0e2e1b8c55a5
parentbf2ed624091d0239bce91a84df59b7afc843298a (diff)
Add preliminary support for Qt for visionOS
Qt already runs on Vision Pro as "Designed for iPad", using Qt for iOS. This change enables building Qt for visionOS directly, which opens the door to visionOS specific APIs and use-cases such as volumes and immersive spaces. The platform removes some APIs we depend on, notably UIScreen, so some code paths have been disabled or mocked to get something up and running. As our current window management approach on UIKit platforms depends on UIWindow and UIScreen there is currently no way to bring up QWindows. This will improve once we refactor our window management to use window scenes. To configure for visionOS, pass -platform macx-visionos-clang, and optionally add -sdk xrsimulator to build for the simulator. Change-Id: I4eda55fc3fd06e12d30a188928487cf68940ee07 Reviewed-by: Alexey Edelev <[email protected]>
-rw-r--r--.cmake.conf5
-rw-r--r--cmake/QtAutoDetectHelpers.cmake13
-rw-r--r--cmake/QtBaseGlobalTargets.cmake4
-rw-r--r--cmake/QtBuildPathsHelpers.cmake2
-rw-r--r--cmake/QtConfig.cmake.in2
-rw-r--r--cmake/QtPlatformSupport.cmake3
-rw-r--r--cmake/QtPublicAppleHelpers.cmake22
-rw-r--r--cmake/QtWrapperScriptHelpers.cmake2
-rw-r--r--cmake/visionos/Info.plist.app.in42
-rw-r--r--cmake/visionos/PrivacyInfo.xcprivacy14
-rw-r--r--configure.cmake2
-rw-r--r--mkspecs/features/mac/default_post.prf24
-rw-r--r--mkspecs/features/toolchain.prf2
-rw-r--r--mkspecs/macx-visionos-clang/Info.plist.app39
-rw-r--r--mkspecs/macx-visionos-clang/Info.plist.dSYM.in18
-rw-r--r--mkspecs/macx-visionos-clang/Info.plist.lib20
-rw-r--r--mkspecs/macx-visionos-clang/qmake.conf29
-rw-r--r--mkspecs/macx-visionos-clang/qplatformdefs.h4
-rw-r--r--src/corelib/CMakeLists.txt4
-rw-r--r--src/corelib/Qt6CoreMacros.cmake12
-rw-r--r--src/corelib/global/qoperatingsystemversion.cpp5
-rw-r--r--src/corelib/global/qoperatingsystemversion.h8
-rw-r--r--src/corelib/global/qsysinfo.cpp2
-rw-r--r--src/corelib/global/qsystemdetection.h3
-rw-r--r--src/corelib/global/qsystemdetection.qdoc7
-rw-r--r--src/corelib/kernel/qcore_mac.mm3
-rw-r--r--src/corelib/platform/darwin/qdarwinpermissionplugin_location.mm13
-rw-r--r--src/entrypoint/CMakeLists.txt4
-rw-r--r--src/gui/CMakeLists.txt2
-rw-r--r--src/gui/configure.cmake5
-rw-r--r--src/gui/painting/qcoregraphics.mm4
-rw-r--r--src/gui/painting/qcoregraphics_p.h12
-rw-r--r--src/gui/platform/darwin/qappleiconengine.mm8
-rw-r--r--src/gui/platform/darwin/qappleiconengine_p.h2
-rw-r--r--src/gui/rhi/qrhimetal.mm10
-rw-r--r--src/gui/text/coretext/qcoretextfontdatabase.mm2
-rw-r--r--src/network/CMakeLists.txt8
-rw-r--r--src/plugins/platforms/ios/CMakeLists.txt25
-rw-r--r--src/plugins/platforms/ios/qioscolordialog.mm4
-rw-r--r--src/plugins/platforms/ios/qiosfiledialog.mm7
-rw-r--r--src/plugins/platforms/ios/qiosfontdialog.mm4
-rw-r--r--src/plugins/platforms/ios/qiosglobal.h3
-rw-r--r--src/plugins/platforms/ios/qiosglobal.mm10
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.mm6
-rw-r--r--src/plugins/platforms/ios/qiosintegration.h11
-rw-r--r--src/plugins/platforms/ios/qiosintegration.mm19
-rw-r--r--src/plugins/platforms/ios/qiosmessagedialog.mm2
-rw-r--r--src/plugins/platforms/ios/qiosscreen.h18
-rw-r--r--src/plugins/platforms/ios/qiosscreen.mm54
-rw-r--r--src/plugins/platforms/ios/qiostextresponder.mm2
-rw-r--r--src/plugins/platforms/ios/qiostheme.h2
-rw-r--r--src/plugins/platforms/ios/qiostheme.mm29
-rw-r--r--src/plugins/platforms/ios/qiosviewcontroller.mm14
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm5
-rw-r--r--src/plugins/platforms/ios/quiview.h2
-rw-r--r--src/plugins/platforms/ios/quiview.mm10
-rw-r--r--src/testlib/qtestblacklist.cpp3
-rw-r--r--src/widgets/kernel/qwidget.cpp2
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