Position of volumetric and 2D windows on visionOS

Hi,

I would like to create an app that has a volumetric window in the middle and two 2D windows on the sides. When I tried that, the 2D windows are positioned slightly below the volumetric window for some reason (image1).

Looks like the base (hadle, close button, etc.) of the volumetric window is aligned with the center of the whole 2D window. I would like all the window bases to be aligned (image2). (I can of course do this manually by dragging the window down a bit with my hand, but that’s an inconvenience for my usecase.)

I tried making the whole volumetric window content higher, but that did not help and the content actually went far above the 2D windows (image3).

I suppose this was some design choice when creating the whole window positioning behavior on VisionOS.

Am I doing something wrong? Is there a way to achieve what I want or a better way to customize the position of windows, not just 5 predefined positions in defaultWindowPlacement?

Image1 - current:

Image2 - what I want:

Image3 - current, larger content:

Code:

import SwiftUI

@main
struct placementTestApp: App {
    @Environment(\.openWindow) var openWindowAction
    
    var body: some Scene {
        WindowGroup(id: "volume") {
            VolumetricWindowView()
                .onAppear {
                    openWindowAction(id: "first")
                    openWindowAction(id: "second")
                }
        }
        .windowStyle(.volumetric)
        .volumeWorldAlignment(.gravityAligned)
        
        WindowGroup(id: "first") {
            NormalWindowView()
        }
        .defaultWindowPlacement { _, context in
            if let mainWindow = context.windows.first(where: { $0.id == "volume" }) {
                WindowPlacement(.leading(mainWindow))
            } else {
                WindowPlacement()
            }
        }
        
        WindowGroup(id: "second") {
            NormalWindowView()
        }
        .defaultWindowPlacement { _, context in
            if let mainWindow = context.windows.first(where: { $0.id == "volume" }) {
                WindowPlacement(.trailing(mainWindow))
            } else {
                WindowPlacement()
            }
        }
    }
}

Hey @elukasino,

Based on what you are describing it seems like you should consider using ornaments instead of separate window groups. You can use ornament(visibility:attachmentAnchor:contentAlignment:ornament:) to control the placement and content of the ornaments. This has the added advantage of being attached to your volume such that when the volume is dragged or closed so are the ornaments. The default window placement API only controls the initial placement of the windows. Once positioned the windows can be independently dragged. Here's an example of this in practice:

WindowGroup(id: "volume") {
    VolumetricWindowView()
        .ornament(attachmentAnchor: .scene(.leadingFront), ornament: {
            Text("Left").padding(200).glassBackgroundEffect()
                        .rotation3DEffect(.degrees(30), axis: .y)
        })
        .ornament(attachmentAnchor: .scene(.trailingFront), ornament: {
            Text("Right").padding(200).glassBackgroundEffect()
                        .rotation3DEffect(.degrees(-30), axis: .y)
        })
}
.windowStyle(.volumetric)

Let me know what you think,
Michael

Position of volumetric and 2D windows on visionOS
 
 
Q