visionOS: Add support for immersive spaces
The QNativeInterface::QVisionOSApplication interface allows opening and dismissing an immersive space, as well as registering a compositor layer implementation that can be used to configure the compositor layer and render to it with Metal. The compositor layer implementation is consulted both for immersive spaces triggered explicitly, and when the default scene of the app is set to CPSceneSessionRoleImmersiveSpaceApplication via the UIApplicationPreferredDefaultSceneSessionRole in the Info.plist. All of this requires that the application follows the SwiftUI app lifecyle, so our application entrypoint is now a SwiftUI app. The existing qt_main_wrapper used for the QIOSEventDispatcher handles this transparently, so there is no change for the user, who will still receive a callback to main() when the Swift app is ready to build its UI hierarchy. Change-Id: Ic295010d714e90cd4d3f66bd90f321438659f3a6 Reviewed-by: Christian Strømme <christian.stromme@qt.io>
This commit is contained in:
parent
ed71387d1c
commit
1f667ba70e
@ -38,5 +38,13 @@
|
||||
<array>
|
||||
<string>XROS</string>
|
||||
</array>
|
||||
|
||||
<key>UIApplicationSceneManifest</key>
|
||||
<dict>
|
||||
<key>UIApplicationSupportsMultipleScenes</key>
|
||||
<true/>
|
||||
<key>UISceneConfigurations</key>
|
||||
<dict/>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -376,6 +376,11 @@ qt_internal_extend_target(Gui CONDITION MACOS
|
||||
${FWAppKit}
|
||||
)
|
||||
|
||||
qt_internal_extend_target(Gui CONDITION UIKIT
|
||||
SOURCES
|
||||
platform/ios/qiosnativeinterface.cpp
|
||||
)
|
||||
|
||||
qt_internal_extend_target(Gui CONDITION WASM
|
||||
SOURCES
|
||||
platform/wasm/qwasmnativeinterface.cpp
|
||||
|
@ -4401,6 +4401,9 @@ void *QGuiApplication::resolveInterface(const char *name, int revision) const
|
||||
#if QT_CONFIG(wayland)
|
||||
QT_NATIVE_INTERFACE_RETURN_IF(QWaylandApplication, platformNativeInterface());
|
||||
#endif
|
||||
#if defined(Q_OS_VISIONOS)
|
||||
QT_NATIVE_INTERFACE_RETURN_IF(QVisionOSApplication, platformIntegration);
|
||||
#endif
|
||||
|
||||
return QCoreApplication::resolveInterface(name, revision);
|
||||
}
|
||||
|
@ -32,6 +32,22 @@ struct wl_pointer;
|
||||
struct wl_touch;
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_VISIONOS) || defined(Q_QDOC)
|
||||
# ifdef __OBJC__
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(CP_OBJECT_cp_layer_renderer_capabilities);
|
||||
typedef CP_OBJECT_cp_layer_renderer_capabilities *cp_layer_renderer_capabilities_t;
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(CP_OBJECT_cp_layer_renderer_configuration);
|
||||
typedef CP_OBJECT_cp_layer_renderer_configuration *cp_layer_renderer_configuration_t;
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(CP_OBJECT_cp_layer_renderer);
|
||||
typedef CP_OBJECT_cp_layer_renderer *cp_layer_renderer_t;
|
||||
# else
|
||||
typedef struct cp_layer_renderer_capabilities_s *cp_layer_renderer_capabilities_t;
|
||||
typedef struct cp_layer_renderer_configuration_s *cp_layer_renderer_configuration_t;
|
||||
typedef struct cp_layer_renderer_s *cp_layer_renderer_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QNativeInterface
|
||||
@ -61,6 +77,20 @@ struct Q_GUI_EXPORT QWaylandApplication
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_VISIONOS) || defined(Q_QDOC)
|
||||
struct Q_GUI_EXPORT QVisionOSApplication
|
||||
{
|
||||
QT_DECLARE_NATIVE_INTERFACE(QVisionOSApplication, 1, QGuiApplication)
|
||||
struct ImmersiveSpaceCompositorLayer {
|
||||
virtual void configure(cp_layer_renderer_capabilities_t, cp_layer_renderer_configuration_t) const {}
|
||||
virtual void render(cp_layer_renderer_t) = 0;
|
||||
};
|
||||
virtual void setImmersiveSpaceCompositorLayer(ImmersiveSpaceCompositorLayer *layer) = 0;
|
||||
virtual void openImmersiveSpace() = 0;
|
||||
virtual void dismissImmersiveSpace() = 0;
|
||||
};
|
||||
#endif
|
||||
|
||||
} // QNativeInterface
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
26
src/gui/platform/ios/qiosnativeinterface.cpp
Normal file
26
src/gui/platform/ios/qiosnativeinterface.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright (C) 2024 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 <QtGui/private/qguiapplication_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QNativeInterface::Private;
|
||||
|
||||
#if defined(Q_OS_VISIONOS)
|
||||
|
||||
/*!
|
||||
\class QNativeInterface::QVisionOSApplication
|
||||
\since 6.8
|
||||
\internal
|
||||
\preliminary
|
||||
\brief Native interface to QGuiApplication, to be retrieved from QPlatformIntegration.
|
||||
\inmodule QtGui
|
||||
\ingroup native-interfaces
|
||||
*/
|
||||
|
||||
QT_DEFINE_NATIVE_INTERFACE(QVisionOSApplication);
|
||||
|
||||
#endif // Q_OS_VISIONOS
|
||||
|
||||
QT_END_NAMESPACE
|
@ -5,6 +5,19 @@
|
||||
## QIOSIntegrationPlugin Plugin:
|
||||
#####################################################################
|
||||
|
||||
if(VISIONOS)
|
||||
include(SwiftIntegration.cmake)
|
||||
|
||||
qt_install(TARGETS QIOSIntegrationPluginSwift
|
||||
EXPORT "${INSTALL_CMAKE_NAMESPACE}QIOSIntegrationPluginTargets"
|
||||
DESTINATION "${INSTALL_LIBDIR}"
|
||||
)
|
||||
qt_internal_add_targets_to_additional_targets_export_file(
|
||||
TARGETS QIOSIntegrationPluginSwift
|
||||
EXPORT_NAME_PREFIX "${INSTALL_CMAKE_NAMESPACE}QIOSIntegrationPlugin"
|
||||
)
|
||||
endif()
|
||||
|
||||
qt_internal_add_plugin(QIOSIntegrationPlugin
|
||||
OUTPUT_NAME qios
|
||||
STATIC # Force static, even in shared builds
|
||||
@ -86,3 +99,7 @@ qt_internal_extend_target(QIOSIntegrationPlugin CONDITION NOT (TVOS OR VISIONOS)
|
||||
)
|
||||
|
||||
add_subdirectory(optional)
|
||||
|
||||
if(VISIONOS)
|
||||
target_link_libraries(QIOSIntegrationPlugin PRIVATE QIOSIntegrationPluginSwift)
|
||||
endif()
|
||||
|
78
src/plugins/platforms/ios/SwiftIntegration.cmake
Normal file
78
src/plugins/platforms/ios/SwiftIntegration.cmake
Normal file
@ -0,0 +1,78 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
set(CMAKE_Swift_COMPILER_TARGET arm64-apple-xros)
|
||||
if($CACHE{CMAKE_OSX_SYSROOT} MATCHES "^[a-z]+simulator$")
|
||||
set(CMAKE_Swift_COMPILER_TARGET "${CMAKE_Swift_COMPILER_TARGET}-simulator")
|
||||
endif()
|
||||
|
||||
cmake_policy(SET CMP0157 NEW)
|
||||
enable_language(Swift)
|
||||
|
||||
# Verify that we have a new enough compiler
|
||||
if("${CMAKE_Swift_COMPILER_VERSION}" VERSION_LESS 5.9)
|
||||
message(FATAL_ERROR "Swift 5.9 required for C++ interoperability")
|
||||
endif()
|
||||
|
||||
get_target_property(QT_CORE_INCLUDES Qt6::Core INTERFACE_INCLUDE_DIRECTORIES)
|
||||
get_target_property(QT_GUI_INCLUDES Qt6::Gui INTERFACE_INCLUDE_DIRECTORIES)
|
||||
get_target_property(QT_CORE_PRIVATE_INCLUDES Qt6::CorePrivate INTERFACE_INCLUDE_DIRECTORIES)
|
||||
get_target_property(QT_GUI_PRIVATE_INCLUDES Qt6::GuiPrivate INTERFACE_INCLUDE_DIRECTORIES)
|
||||
|
||||
set(target QIOSIntegrationPluginSwift)
|
||||
# Swift library
|
||||
set(SWIFT_SOURCES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/qiosapplication.swift"
|
||||
)
|
||||
add_library(${target} STATIC ${SWIFT_SOURCES})
|
||||
set_target_properties(${target} PROPERTIES
|
||||
Swift_MODULE_NAME ${target})
|
||||
target_include_directories(${target} PUBLIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
"${QT_CORE_INCLUDES}"
|
||||
"${QT_GUI_INCLUDES}"
|
||||
"${QT_CORE_PRIVATE_INCLUDES}"
|
||||
"${QT_GUI_PRIVATE_INCLUDES}"
|
||||
|
||||
)
|
||||
target_compile_options(${target} PUBLIC
|
||||
$<$<COMPILE_LANGUAGE:Swift>:-cxx-interoperability-mode=default>
|
||||
$<$<COMPILE_LANGUAGE:Swift>:-Xcc -std=c++17>)
|
||||
|
||||
# Swift to C++ bridging header
|
||||
set(SWIFT_BRIDGING_HEADER "${CMAKE_CURRENT_BINARY_DIR}/qiosswiftintegration.h")
|
||||
list(TRANSFORM QT_CORE_INCLUDES PREPEND "-I")
|
||||
list(TRANSFORM QT_GUI_INCLUDES PREPEND "-I")
|
||||
list(TRANSFORM QT_CORE_PRIVATE_INCLUDES PREPEND "-I")
|
||||
list(TRANSFORM QT_GUI_PRIVATE_INCLUDES PREPEND "-I")
|
||||
add_custom_command(
|
||||
COMMAND
|
||||
${CMAKE_Swift_COMPILER} -frontend -typecheck
|
||||
${SWIFT_SOURCES}
|
||||
-I ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${QT_CORE_INCLUDES}
|
||||
${QT_GUI_INCLUDES}
|
||||
${QT_CORE_PRIVATE_INCLUDES}
|
||||
${QT_GUI_PRIVATE_INCLUDES}
|
||||
-sdk ${CMAKE_OSX_SYSROOT}
|
||||
-module-name ${target}
|
||||
-cxx-interoperability-mode=default
|
||||
-Xcc -std=c++17
|
||||
-emit-clang-header-path "${SWIFT_BRIDGING_HEADER}"
|
||||
-target ${CMAKE_Swift_COMPILER_TARGET}
|
||||
OUTPUT
|
||||
"${SWIFT_BRIDGING_HEADER}"
|
||||
DEPENDS
|
||||
${SWIFT_SOURCES}
|
||||
)
|
||||
|
||||
set(header_target "${target}Header")
|
||||
add_custom_target(${header_target}
|
||||
DEPENDS "${SWIFT_BRIDGING_HEADER}"
|
||||
)
|
||||
# Make sure the "'__bridge_transfer' casts have no effect when not using ARC"
|
||||
# warning doesn't break warnings-are-error builds.
|
||||
target_compile_options(${target} INTERFACE
|
||||
-Wno-error=arc-bridge-casts-disallowed-in-nonarc)
|
||||
|
||||
add_dependencies(${target} ${header_target})
|
4
src/plugins/platforms/ios/module.modulemap
Normal file
4
src/plugins/platforms/ios/module.modulemap
Normal file
@ -0,0 +1,4 @@
|
||||
module QIOSIntegrationPlugin {
|
||||
header "qiosapplicationdelegate.h"
|
||||
header "qiosintegration.h"
|
||||
}
|
82
src/plugins/platforms/ios/qiosapplication.swift
Normal file
82
src/plugins/platforms/ios/qiosapplication.swift
Normal file
@ -0,0 +1,82 @@
|
||||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
import SwiftUI
|
||||
import CompositorServices
|
||||
import QIOSIntegrationPlugin
|
||||
import RealityKit
|
||||
|
||||
struct QIOSSwiftApplication: App {
|
||||
@UIApplicationDelegateAdaptor private var appDelegate: QIOSApplicationDelegate
|
||||
|
||||
var body: some SwiftUI.Scene {
|
||||
WindowGroup() {
|
||||
ImmersiveSpaceControlView()
|
||||
}
|
||||
|
||||
ImmersiveSpace(id: "QIOSImmersiveSpace") {
|
||||
CompositorLayer(configuration: QIOSLayerConfiguration()) { layerRenderer in
|
||||
QIOSIntegration.instance().renderCompositorLayer(layerRenderer)
|
||||
}
|
||||
}
|
||||
// CompositorLayer immersive spaces are always full, and should not need
|
||||
// to set the immersion style, but lacking this we get a warning in the
|
||||
// console about not being able to "configure an immersive space with
|
||||
// selected style 'AutomaticImmersionStyle' since it is not in the list
|
||||
// of supported styles for this type of content: 'FullImmersionStyle'."
|
||||
.immersionStyle(selection: .constant(.full), in: .full)
|
||||
}
|
||||
}
|
||||
|
||||
public struct QIOSLayerConfiguration: CompositorLayerConfiguration {
|
||||
public func makeConfiguration(capabilities: LayerRenderer.Capabilities,
|
||||
configuration: inout LayerRenderer.Configuration) {
|
||||
// Use reflection to pull out underlying C handles
|
||||
// FIXME: Use proper bridging APIs when available
|
||||
let capabilitiesMirror = Mirror(reflecting: capabilities)
|
||||
let configurationMirror = Mirror(reflecting: configuration)
|
||||
QIOSIntegration.instance().configureCompositorLayer(
|
||||
capabilitiesMirror.descendant("c_capabilities") as? cp_layer_renderer_capabilities_t,
|
||||
configurationMirror.descendant("box", "value") as? cp_layer_renderer_configuration_t
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
public func runSwiftAppMain() {
|
||||
QIOSSwiftApplication.main()
|
||||
}
|
||||
|
||||
public class ImmersiveState: ObservableObject {
|
||||
static let shared = ImmersiveState()
|
||||
@Published var showImmersiveSpace: Bool = false
|
||||
}
|
||||
|
||||
struct ImmersiveSpaceControlView: View {
|
||||
@ObservedObject private var immersiveState = ImmersiveState.shared
|
||||
|
||||
@Environment(\.openImmersiveSpace) var openImmersiveSpace
|
||||
@Environment(\.dismissImmersiveSpace) var dismissImmersiveSpace
|
||||
|
||||
var body: some View {
|
||||
VStack {}
|
||||
.onChange(of: immersiveState.showImmersiveSpace) { _, newValue in
|
||||
Task {
|
||||
if newValue {
|
||||
await openImmersiveSpace(id: "QIOSImmersiveSpace")
|
||||
} else {
|
||||
await dismissImmersiveSpace()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ImmersiveSpaceManager : NSObject {
|
||||
@objc public static func openImmersiveSpace() {
|
||||
ImmersiveState.shared.showImmersiveSpace = true
|
||||
}
|
||||
|
||||
@objc public static func dismissImmersiveSpace() {
|
||||
ImmersiveState.shared.showImmersiveSpace = false
|
||||
}
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
// 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
|
||||
|
||||
#ifndef QIOSAPPLICATIONDELEGATE_H
|
||||
#define QIOSAPPLICATIONDELEGATE_H
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <QtGui/QtGui>
|
||||
|
||||
@ -8,3 +11,5 @@
|
||||
|
||||
@interface QIOSApplicationDelegate : UIResponder <UIApplicationDelegate>
|
||||
@end
|
||||
|
||||
#endif // QIOSAPPLICATIONDELEGATE_H
|
||||
|
@ -16,6 +16,8 @@ public:
|
||||
static QIOSEventDispatcher* create();
|
||||
bool processPostedEvents() override;
|
||||
|
||||
static bool isQtApplication();
|
||||
|
||||
protected:
|
||||
explicit QIOSEventDispatcher(QObject *parent = nullptr);
|
||||
};
|
||||
|
@ -5,6 +5,10 @@
|
||||
#include "qiosapplicationdelegate.h"
|
||||
#include "qiosglobal.h"
|
||||
|
||||
#if defined(Q_OS_VISIONOS)
|
||||
#include "qiosswiftintegration.h"
|
||||
#endif
|
||||
|
||||
#include <QtCore/qprocessordetection.h>
|
||||
#include <QtCore/private/qcoreapplication_p.h>
|
||||
#include <QtCore/private/qthread_p.h>
|
||||
@ -173,12 +177,16 @@ namespace
|
||||
QAppleLogActivity UIApplicationMain;
|
||||
QAppleLogActivity applicationDidFinishLaunching;
|
||||
} logActivity;
|
||||
|
||||
static bool s_isQtApplication = false;
|
||||
}
|
||||
|
||||
using namespace QT_PREPEND_NAMESPACE(QtPrivate);
|
||||
|
||||
extern "C" int qt_main_wrapper(int argc, char *argv[])
|
||||
{
|
||||
s_isQtApplication = true;
|
||||
|
||||
@autoreleasepool {
|
||||
size_t defaultStackSize = 512 * kBytesPerKiloByte; // Same as secondary threads
|
||||
|
||||
@ -202,8 +210,16 @@ extern "C" int qt_main_wrapper(int argc, char *argv[])
|
||||
logActivity.UIApplicationMain = QT_APPLE_LOG_ACTIVITY(
|
||||
lcEventDispatcher().isDebugEnabled(), "UIApplicationMain").enter();
|
||||
|
||||
#if defined(Q_OS_VISIONOS)
|
||||
Q_UNUSED(argc);
|
||||
Q_UNUSED(argv);
|
||||
qCDebug(lcEventDispatcher) << "Starting Swift app";
|
||||
QIOSIntegrationPluginSwift::runSwiftAppMain();
|
||||
Q_UNREACHABLE();
|
||||
#else
|
||||
qCDebug(lcEventDispatcher) << "Running UIApplicationMain";
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([QIOSApplicationDelegate class]));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -424,6 +440,11 @@ QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent)
|
||||
QWindowSystemInterface::setSynchronousWindowSystemEvents(true);
|
||||
}
|
||||
|
||||
bool QIOSEventDispatcher::isQtApplication()
|
||||
{
|
||||
return s_isQtApplication;
|
||||
}
|
||||
|
||||
/*!
|
||||
Override of the CoreFoundation posted events runloop source callback
|
||||
so that we can send window system (QPA) events in addition to sending
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include "qiosapplicationdelegate.h"
|
||||
#include "qiosviewcontroller.h"
|
||||
#include "qiosscreen.h"
|
||||
#include "quiwindow.h"
|
||||
#include "qioseventdispatcher.h"
|
||||
|
||||
#include <QtCore/private/qcore_mac_p.h>
|
||||
|
||||
@ -17,17 +19,13 @@ Q_LOGGING_CATEGORY(lcQpaWindowScene, "qt.qpa.window.scene");
|
||||
|
||||
bool isQtApplication()
|
||||
{
|
||||
if (qt_apple_isApplicationExtension())
|
||||
return false;
|
||||
|
||||
// Returns \c true if the plugin is in full control of the whole application. This means
|
||||
// that we control the application delegate and the top view controller, and can take
|
||||
// actions that impacts all parts of the application. The opposite means that we are
|
||||
// embedded inside a native iOS application, and should be more focused on playing along
|
||||
// with native UIControls, and less inclined to change structures that lies outside the
|
||||
// scope of our QWindows/UIViews.
|
||||
static bool isQt = ([qt_apple_sharedApplication().delegate isKindOfClass:[QIOSApplicationDelegate class]]);
|
||||
return isQt;
|
||||
return QIOSEventDispatcher::isQtApplication();
|
||||
}
|
||||
|
||||
bool isRunningOnVisionOS()
|
||||
@ -126,9 +124,15 @@ UIView *rootViewForScreen(QScreen *screen)
|
||||
Q_UNUSED(iosScreen);
|
||||
#endif
|
||||
|
||||
UIWindow *uiWindow = windowScene.keyWindow;
|
||||
if (!uiWindow && windowScene.windows.count)
|
||||
uiWindow = windowScene.windows[0];
|
||||
UIWindow *uiWindow = qt_objc_cast<QUIWindow*>(windowScene.keyWindow);
|
||||
if (!uiWindow) {
|
||||
for (UIWindow *win in windowScene.windows) {
|
||||
if (qt_objc_cast<QUIWindow*>(win)) {
|
||||
uiWindow = win;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return uiWindow.rootViewController.view;
|
||||
}
|
||||
|
@ -16,11 +16,24 @@
|
||||
#include "qiostextinputoverlay.h"
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_VISIONOS)
|
||||
#include <swift/bridging>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QNativeInterface;
|
||||
|
||||
class QIOSServices;
|
||||
|
||||
class QIOSIntegration : public QPlatformNativeInterface, public QPlatformIntegration
|
||||
class
|
||||
#if defined(Q_OS_VISIONOS)
|
||||
SWIFT_IMMORTAL_REFERENCE
|
||||
#endif
|
||||
QIOSIntegration : public QPlatformNativeInterface, public QPlatformIntegration
|
||||
#if defined(Q_OS_VISIONOS)
|
||||
, public QVisionOSApplication
|
||||
#endif
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@ -77,6 +90,17 @@ public:
|
||||
|
||||
QIOSApplicationState applicationState;
|
||||
|
||||
#if defined(Q_OS_VISIONOS)
|
||||
void openImmersiveSpace() override;
|
||||
void dismissImmersiveSpace() override;
|
||||
|
||||
using CompositorLayer = QVisionOSApplication::ImmersiveSpaceCompositorLayer;
|
||||
void setImmersiveSpaceCompositorLayer(CompositorLayer *layer) override;
|
||||
|
||||
void configureCompositorLayer(cp_layer_renderer_capabilities_t, cp_layer_renderer_configuration_t);
|
||||
void renderCompositorLayer(cp_layer_renderer_t);
|
||||
#endif
|
||||
|
||||
private:
|
||||
QPlatformFontDatabase *m_fontDatabase;
|
||||
#if QT_CONFIG(clipboard)
|
||||
@ -90,6 +114,10 @@ private:
|
||||
#if !defined(Q_OS_TVOS) && !defined(Q_OS_VISIONOS)
|
||||
QIOSTextInputOverlay m_textInputOverlay;
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_VISIONOS)
|
||||
CompositorLayer *m_immersiveSpaceCompositorLayer = nullptr;
|
||||
#endif
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -17,6 +17,10 @@
|
||||
#include "qiosservices.h"
|
||||
#include "qiosoptionalplugininterface.h"
|
||||
|
||||
#if defined(Q_OS_VISIONOS)
|
||||
#include "qiosswiftintegration.h"
|
||||
#endif
|
||||
|
||||
#include <QtGui/qpointingdevice.h>
|
||||
#include <QtGui/private/qguiapplication_p.h>
|
||||
#include <QtGui/private/qrhibackingstore_p.h>
|
||||
@ -296,6 +300,39 @@ void QIOSIntegration::setApplicationBadge(qint64 number)
|
||||
|
||||
// ---------------------------------------------------------
|
||||
|
||||
#if defined(Q_OS_VISIONOS)
|
||||
void QIOSIntegration::openImmersiveSpace()
|
||||
{
|
||||
[ImmersiveSpaceManager openImmersiveSpace];
|
||||
}
|
||||
|
||||
void QIOSIntegration::dismissImmersiveSpace()
|
||||
{
|
||||
[ImmersiveSpaceManager dismissImmersiveSpace];
|
||||
}
|
||||
|
||||
void QIOSIntegration::setImmersiveSpaceCompositorLayer(CompositorLayer *layer)
|
||||
{
|
||||
m_immersiveSpaceCompositorLayer = layer;
|
||||
}
|
||||
|
||||
void QIOSIntegration::configureCompositorLayer(cp_layer_renderer_capabilities_t capabilities,
|
||||
cp_layer_renderer_configuration_t configuration)
|
||||
{
|
||||
if (m_immersiveSpaceCompositorLayer)
|
||||
m_immersiveSpaceCompositorLayer->configure(capabilities, configuration);
|
||||
}
|
||||
|
||||
void QIOSIntegration::renderCompositorLayer(cp_layer_renderer_t renderer)
|
||||
{
|
||||
if (m_immersiveSpaceCompositorLayer)
|
||||
m_immersiveSpaceCompositorLayer->render(renderer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------
|
||||
|
||||
void *QIOSIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
|
||||
{
|
||||
if (!window || !window->handle())
|
||||
|
Loading…
x
Reference in New Issue
Block a user