How to use default placement to position new windows
In visionOS we can provide a default window placement. This placement will be used when an instance of a window is opened. When nothing is provided, a new window will appear slightly in front of the window. It will be positioned in front of the volume from which it was opened.
Note: The default placement value is only used when opening a new instance of a window. As of visionOS 2, there is no way for developers to move or position existing windows.
There are five placements supported so far in visionOS 2.
- Relative to an existing window or volume
- Above
- Below
- Trailing
- Leading
- Relative to the user
- Utility
Relative to an existing window
If we wanted to open a window to the left of our main window we could do something like this.
// Main window
WindowGroup {
ContentView()
}
.defaultSize(width: 500, height: 500)
WindowGroup(id: "YellowFlower") {
Text("🌼")
.font(.system(size: 128))
}
.defaultSize(CGSize(width: 300, height: 200))
.defaultWindowPlacement { _, context in
if let mainWindow = context.windows.first {
return WindowPlacement(.leading(mainWindow))
}
return WindowPlacement(.none)
}We use the defaultWindowPlacement scene modifier and extract the main window from the context provided to the closure. Then we can specify the placement relative to the main window like this: WindowPlacement(.leading(mainWindow)).

We can repeat that process for each of the other relative placements.

Relative to the user
A very useful option is .utilityPlacement. This will open a window closer to the user. I often use this placement for tool panels and menus for volumes and immersive spaces. This one is easier to use since we don’t need to get a proxy to another window.
WindowGroup(id: "Rocks") {
Text("🪨🪨🪨")
.font(.system(size: 48))
}
.defaultSize(CGSize(width: 300, height: 100))
.defaultWindowPlacement { _, context in
return WindowPlacement(.utilityPanel)
}WindowPlacement(.utilityPanel) is doing all the work here. When seen head-on in the simulator, you may assume this is just a lower version of the “below” placement. But when we rotate the camera a bit, you can see this window was placed much closer to the user.
visionOS simulator demo of multiple windows opening relative to a main window.
Sample code for this post is available in Garden03 in Step Into Examples on GitHub
Download the Xcode project with this and many more examples from Step Into Vision.
Some examples are provided as standalone Xcode projects. You can find those here.

Follow Step Into Vision