Post

Replies

Boosts

Views

Activity

Reply to visionOS 26: is there any way yet to distinguish a user-initiated window close from system out-of-FoV backgrounding
Thanks Michael — enhancement request filed as FB24076974, and a focused test project is here: https://www.icloud.com/iclouddrive/0fcptDNbtKk0CCcs-EYMS_2bA#WindowCloseRepro Building it produced results worth reporting, including a correction to my original post. Complete flow: Launch opens the primary window (the editor menu) which immediately opens a fully immersive space — the space IS the product: users build and animate 3D scenes inside it in .full immersion. They open and close secondary tool windows (materials, timeline, lighting, …) around the space as they work, and park any window — including the primary — beside or behind them. There is also a player flow: tapping a scene file in Files launches straight into the immersive space with a single compact transport-bar window. Correction first: in the focused repro (visionOS 26.5, on-device), the session-identifier mismatch I reported does NOT reproduce. While another regular window is open, closing a window delivers didDisconnect + didDiscardSceneSessions within ~30 ms, carrying an identifier that matches the closed window's view-reachable windowScene.session.persistentIdentifier, plus root-view onDisappear — attribution works, exactly as your window-life-cycle article describes. My earlier in-app observations of unmatched identifiers were evidently stale-session discards misattributed to the close. I'm happy to be wrong about that half. The gap that DOES reproduce, cleanly: closing the LAST regular window while the fully immersive space remains open. On-device, that close produces didEnterBackground + scenePhase → background and then nothing — no disconnect, no discard, no onDisappear, session still in openSessions — for the entire time the user remains in the immersive space. That signature is identical to the ~61 s out-of-view backgrounding, so the app cannot distinguish "the user closed my last window and is now standing inside my environment with no chrome at all" from "my window is parked behind the user". Your doc states this case directly ("The last closed nonimmersive scene enters the ScenePhase.background phase but doesn't immediately receive the onDisappear() callback") — for a fully-immersive app it is the one lifecycle moment we most need to observe (dismiss the space, save state, end the session), and the one close that produces no signal. On your concern — the app never dismisses its own last scene. The problem is the reverse direction: after the USER closes the last window, they're still inside our fully immersive environment, which has no close affordance of its own. From the user's perspective that close should end the session; the app just has nothing to act on. The enhancement filed: deliver onDisappear/disconnect (or a dismissal callback with a reason) to the last nonimmersive scene when an immersive space remains open — or extend the association model from your "Associating a window with an immersive space" sample (which pairs a pushed window with a space) to a primary window. One question meanwhile: is there a recommended pattern today for a fully-immersive app whose last window closes — is "Embedding controls in an immersive space" (persistent in-space chrome) the intended fallback?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
2d
Reply to visionOS 26: is there any way yet to distinguish a user-initiated window close from system out-of-FoV backgrounding
Thanks Michael — enhancement request filed as FB24076974, and a focused test project is here: https://www.icloud.com/iclouddrive/0fcptDNbtKk0CCcs-EYMS_2bA#WindowCloseRepro Building it produced results worth reporting, including a correction to my original post. Complete flow: Launch opens the primary window (the editor menu) which immediately opens a fully immersive space — the space IS the product: users build and animate 3D scenes inside it in .full immersion. They open and close secondary tool windows (materials, timeline, lighting, …) around the space as they work, and park any window — including the primary — beside or behind them. There is also a player flow: tapping a scene file in Files launches straight into the immersive space with a single compact transport-bar window. Correction first: in the focused repro (visionOS 26.5, on-device), the session-identifier mismatch I reported does NOT reproduce. While another regular window is open, closing a window delivers didDisconnect + didDiscardSceneSessions within ~30 ms, carrying an identifier that matches the closed window's view-reachable windowScene.session.persistentIdentifier, plus root-view onDisappear — attribution works, exactly as your window-life-cycle article describes. My earlier in-app observations of unmatched identifiers were evidently stale-session discards misattributed to the close. I'm happy to be wrong about that half. The gap that DOES reproduce, cleanly: closing the LAST regular window while the fully immersive space remains open. On-device, that close produces didEnterBackground + scenePhase → background and then nothing — no disconnect, no discard, no onDisappear, session still in openSessions — for the entire time the user remains in the immersive space. That signature is identical to the ~61 s out-of-view backgrounding, so the app cannot distinguish "the user closed my last window and is now standing inside my environment with no chrome at all" from "my window is parked behind the user". Your doc states this case directly ("The last closed nonimmersive scene enters the ScenePhase.background phase but doesn't immediately receive the onDisappear() callback") — for a fully-immersive app it is the one lifecycle moment we most need to observe (dismiss the space, save state, end the session), and the one close that produces no signal. On your concern — the app never dismisses its own last scene. The problem is the reverse direction: after the USER closes the last window, they're still inside our fully immersive environment, which has no close affordance of its own. From the user's perspective that close should end the session; the app just has nothing to act on. The enhancement filed: deliver onDisappear/disconnect (or a dismissal callback with a reason) to the last nonimmersive scene when an immersive space remains open — or extend the association model from your "Associating a window with an immersive space" sample (which pairs a pushed window with a space) to a primary window. One question meanwhile: is there a recommended pattern today for a fully-immersive app whose last window closes — is "Embedding controls in an immersive space" (persistent in-space chrome) the intended fallback?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
2d