Преглед изворни кода

visionOS: re-enable dimming mode

Sam Lantinga пре 1 дан
родитељ
комит
0e480bee30

+ 26 - 22
src/video/uikit/SDL_CurvedContentHosting.swift

@@ -151,6 +151,16 @@ internal class SDL_CurvedContentHosting: NSObject {
         //NSLog("SDL_CurvedContentHosting: Bootstrapping RealityView as hidden child")
         //NSLog("SDL_CurvedContentHosting: Bootstrapping RealityView as hidden child")
     }
     }
 
 
+    @objc public func dismiss() {
+        guard let hc = self.hostingController else { return }
+
+        settings.dimmingReady = false
+
+        hc.dismiss(animated: false)
+
+        hostingController = nil
+    }
+
     private func updateOrnaments() {
     private func updateOrnaments() {
         guard let hostingController else { return }
         guard let hostingController else { return }
         let settings = self.settings
         let settings = self.settings
@@ -263,8 +273,8 @@ internal class SDL_CurvedContentSettings {
 
 
     var inputType: InputType = .eyes
     var inputType: InputType = .eyes
     var showHover: Bool = true
     var showHover: Bool = true
-    var enableDimming: Bool = false // Doesn't seem to be reliable at the moment
     var isDimmed: Bool = false
     var isDimmed: Bool = false
+    var dimmingReady: Bool = false
     var curvatureRadius: Float = 0.0
     var curvatureRadius: Float = 0.0
     var sceneState: SceneState = .interactive
     var sceneState: SceneState = .interactive
     var isSnapped: Bool = false
     var isSnapped: Bool = false
@@ -320,10 +330,8 @@ struct SDL_SettingsPanelView: View {
                 HStack(spacing: 12) {
                 HStack(spacing: 12) {
                     Image(systemName: settings.showHover ? "eye" : "eye.slash")
                     Image(systemName: settings.showHover ? "eye" : "eye.slash")
 
 
-                    if settings.enableDimming {
-                        Image(systemName: settings.isDimmed ? "moon.fill" : "sun.max")
-                            .foregroundStyle(settings.isDimmed ? .primary : .secondary)
-                    }
+                    Image(systemName: settings.isDimmed ? "moon.fill" : "sun.max")
+                        .foregroundStyle(settings.isDimmed ? .primary : .secondary)
 
 
                     Divider().frame(height: 8)
                     Divider().frame(height: 8)
 
 
@@ -344,10 +352,8 @@ struct SDL_SettingsPanelView: View {
                 VStack(spacing: 12) {
                 VStack(spacing: 12) {
                     Image(systemName: settings.showHover ? "eye" : "eye.slash")
                     Image(systemName: settings.showHover ? "eye" : "eye.slash")
 
 
-                    if settings.enableDimming {
-                        Image(systemName: settings.isDimmed ? "moon.fill" : "sun.max")
-                            .foregroundStyle(settings.isDimmed ? .primary : .secondary)
-                    }
+                    Image(systemName: settings.isDimmed ? "moon.fill" : "sun.max")
+                        .foregroundStyle(settings.isDimmed ? .primary : .secondary)
 
 
                     Divider().frame(height: 8)
                     Divider().frame(height: 8)
 
 
@@ -394,21 +400,19 @@ struct SDL_SettingsPanelView: View {
                 Image(systemName: "eye")
                 Image(systemName: "eye")
                 Spacer()
                 Spacer()
 
 
-                if settings.enableDimming {
-                    Spacer()
-                    Image(systemName: "sun.max")
-
-                    Toggle(isOn: $settings.isDimmed) {
-                    }
-                    .onChange(of: settings.isDimmed) {
-                        settings.save()
-                    }
-                    .labelsHidden()
-                    .tint(.secondary)
+                Spacer()
+                Image(systemName: "sun.max")
 
 
-                    Image(systemName: "moon.fill")
-                    Spacer()
+                Toggle(isOn: $settings.isDimmed) {
+                }
+                .onChange(of: settings.isDimmed) {
+                    settings.save()
                 }
                 }
+                .labelsHidden()
+                .tint(.secondary)
+
+                Image(systemName: "moon.fill")
+                Spacer()
             }
             }
 
 
             // Curvature slider
             // Curvature slider

+ 12 - 1
src/video/uikit/SDL_CurvedContentView.swift

@@ -71,6 +71,10 @@ internal struct SDL_CurvedContentView: View {
         return curvedUIEntity != nil && helper.collisionShape != nil && !mouseInputEnabled
         return curvedUIEntity != nil && helper.collisionShape != nil && !mouseInputEnabled
     }
     }
 
 
+    private var shouldEnableDimming: Bool {
+        return settings.isDimmed && settings.dimmingReady
+    }
+
     /// Value use to animate the screen radius
     /// Value use to animate the screen radius
     @State private var animatedScreenRadius: Float = 1010
     @State private var animatedScreenRadius: Float = 1010
 
 
@@ -265,6 +269,13 @@ internal struct SDL_CurvedContentView: View {
             guard let curvedUIEntity else { return }
             guard let curvedUIEntity else { return }
             if let shape = helper.collisionShape, shouldPopulateCollisionShape {
             if let shape = helper.collisionShape, shouldPopulateCollisionShape {
                 curvedUIEntity.components.set(CollisionComponent(shapes: [shape]))
                 curvedUIEntity.components.set(CollisionComponent(shapes: [shape]))
+
+                // Dimming is possible now that we have a collision component
+                Task {
+                    try await Task.sleep(nanoseconds: 1_000_000_000 / 4)
+
+                    settings.dimmingReady = true
+                }
             } else {
             } else {
                 curvedUIEntity.components.set(CollisionComponent(shapes: []))
                 curvedUIEntity.components.set(CollisionComponent(shapes: []))
             }
             }
@@ -273,7 +284,7 @@ internal struct SDL_CurvedContentView: View {
             settings.isSnapped = snappedStatus.isSnapped
             settings.isSnapped = snappedStatus.isSnapped
             helper.updateSnappedStatus(snapped: snappedStatus.isSnapped)
             helper.updateSnappedStatus(snapped: snappedStatus.isSnapped)
         }
         }
-        .preferredSurroundingsEffect(settings.enableDimming && settings.isDimmed ? .dark : nil)
+        .preferredSurroundingsEffect(shouldEnableDimming ? .dark : nil)
         .frame(depth: 0)
         .frame(depth: 0)
         .ignoresSafeArea()
         .ignoresSafeArea()
         .persistentSystemOverlays(settings.sceneState == .cinematic ? .hidden : .automatic)
         .persistentSystemOverlays(settings.sceneState == .cinematic ? .hidden : .automatic)

+ 5 - 0
src/video/uikit/SDL_UIKitBridge-objc.h

@@ -42,6 +42,11 @@ bool SDL_UIKit_HasCurvedWindow();
  */
  */
 bool SDL_UIKit_IsCurvedWindow(SDL_Window *window);
 bool SDL_UIKit_IsCurvedWindow(SDL_Window *window);
 
 
+/**
+ * Dismiss the curved content view
+ */
+void SDL_UIKit_HideCurvedWindow(SDL_Window *window);
+
 /**
 /**
  * Get the curved content display texture.
  * Get the curved content display texture.
  */
  */

+ 22 - 0
src/video/uikit/SDL_UIKitBridge.m

@@ -152,6 +152,28 @@ bool SDL_UIKit_IsCurvedWindow(SDL_Window *window)
     return data && data.curvedContentHosting;
     return data && data.curvedContentHosting;
 }
 }
 
 
+void SDL_UIKit_HideCurvedWindow(SDL_Window *window)
+{
+    SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal;
+    if (!data || !data.curvedContentHosting) {
+        return nil;
+    }
+
+    id hosting = data.curvedContentHosting;
+    SEL dismissSelector = NSSelectorFromString(@"dismiss");
+    if (![hosting respondsToSelector:dismissSelector]) {
+        return nil;
+    }
+
+    NSMethodSignature *signature = [hosting methodSignatureForSelector:dismissSelector];
+    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
+    [invocation setSelector:dismissSelector];
+    [invocation setTarget:hosting];
+    [invocation invoke];
+
+    data.curvedContentHosting = nil;
+}
+
 id<MTLTexture> SDL_UIKit_GetCurvedDisplayTexture(SDL_Window *window, id<MTLCommandBuffer> commandBuffer, int width, int height, MTLPixelFormat pixelFormat)
 id<MTLTexture> SDL_UIKit_GetCurvedDisplayTexture(SDL_Window *window, id<MTLCommandBuffer> commandBuffer, int width, int height, MTLPixelFormat pixelFormat)
 {
 {
     SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal;
     SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal;

+ 4 - 0
src/video/uikit/SDL_uikitwindow.m

@@ -33,6 +33,7 @@
 #include "SDL_uikitappdelegate.h"
 #include "SDL_uikitappdelegate.h"
 #include "SDL_uikitview.h"
 #include "SDL_uikitview.h"
 #include "SDL_uikitopenglview.h"
 #include "SDL_uikitopenglview.h"
+#include "SDL_UIKitBridge-objc.h"
 
 
 #include <Foundation/Foundation.h>
 #include <Foundation/Foundation.h>
 
 
@@ -386,6 +387,9 @@ void UIKit_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window)
 
 
             [data.viewcontroller stopAnimation];
             [data.viewcontroller stopAnimation];
 
 
+#ifdef SDL_PLATFORM_VISIONOS
+            SDL_UIKit_HideCurvedWindow(window);
+#endif
             /* Detach all views from this window. We use a copy of the array
             /* Detach all views from this window. We use a copy of the array
              * because setSDLWindow will remove the object from the original
              * because setSDLWindow will remove the object from the original
              * array, which would be undesirable if we were iterating over it. */
              * array, which would be undesirable if we were iterating over it. */