From 177214d913d3db4ee827b45c43ce8ea2bd120399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=27=C3=A9lectron=20rare?= <108685187+electron-rare@users.noreply.github.com> Date: Mon, 18 May 2026 21:43:03 +0200 Subject: [PATCH] fix(avlivebody): orbit gesture + setUp guard Filter NSPanGestureRecognizer state in OrbitTarget.handlePan to dispatch only on .changed, replacing the Task wrapper with MainActor.assumeIsolated. Guard SceneController.setUp() with a didSetUp flag so duplicate makeNSView calls do not re-install gestures or re-add anchors. --- .../Sources/AVLiveBody/SceneController.swift | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/avlivebody-mac/Sources/AVLiveBody/SceneController.swift b/avlivebody-mac/Sources/AVLiveBody/SceneController.swift index 571601d..1e684a3 100644 --- a/avlivebody-mac/Sources/AVLiveBody/SceneController.swift +++ b/avlivebody-mac/Sources/AVLiveBody/SceneController.swift @@ -24,7 +24,11 @@ final class SceneController { private var orbitPitch: Float = 0 private var orbitRadius: Float = 3.0 + private var didSetUp = false + func setUp() { + guard !didSetUp else { return } + didSetUp = true arView.environment.background = .color(.black) arView.scene.addAnchor(worldAnchor) @@ -94,13 +98,19 @@ final class OrbitTarget: NSObject { private var last: CGPoint = .zero @objc func handlePan(_ g: NSPanGestureRecognizer) { - let p = g.translation(in: g.view) - if g.state == .began { last = p } - let dx = Float(p.x - last.x) - let dy = Float(p.y - last.y) - last = p - Task { @MainActor in - self.controller?.orbit(dx: dx, dy: -dy) + switch g.state { + case .began: + last = g.translation(in: g.view) + case .changed: + let p = g.translation(in: g.view) + let dx = Float(p.x - last.x) + let dy = Float(p.y - last.y) + last = p + MainActor.assumeIsolated { + self.controller?.orbit(dx: dx, dy: -dy) + } + default: + break } } }