How it works
WindowManagerRole describes how the windows a scene produces participate in full screen and Stage Manager on macOS. Each scene has one of three roles: a principal window anchors a full-screen or Stage Manager grouping, an associated window may join a principal window's grouping but never forms one on its own, and the automatic role lets SwiftUI infer the right behavior from the scene's type and position. Reach for it through the windowManagerRole(_:) scene modifier when the default inference doesn't match how you want a secondary window to behave, such as promoting an auxiliary Window to be a full-screen anchor.
Choose a role with the static members
WindowManagerRole is a value type whose meaningful values come from three static properties rather than an initializer:
.automatic,.principal, and.associated. The example binds one directly withlet role: WindowManagerRole = .principal, which is the role that lets a scene's windows appear in full screen or Stage Manager as the anchor of their grouping.Let .automatic defer to the scene
WindowManagerRole.automaticis the default and asks SwiftUI to pick a role from the scene's type and configuration. On macOS aWindowGrouporDocumentGroupresolves toprincipal, while aWindowisprincipalonly when it is the first scene declared andassociatedotherwise;Settingsresolves toassociated.Distinguish .principal from .associated
.principalmakes the scene's windows able to enter full screen or Stage Manager and lead that grouping, whereas.associatedwindows can ride alongside a principal window in those modes but cannot trigger them by themselves. Picking between these two is the whole point of the type: in the example, choosing.principalover.associatedis what changes whetherrolerepresents an anchor or a companion window.Apply it with windowManagerRole(_:)
You attach a WindowManagerRole to a scene, not a view, using the
Scene/windowManagerRole(_:)modifier to override the inferred behavior. A secondaryWindow("Organizer", id: "organizer")declared after aWindowGroupwould normally beassociated, but.windowManagerRole(.principal)promotes it so its windows can anchor full screen and Stage Manager.Inspect the chosen value
Because the type conforms to nothing beyond
Sendable, the example surfaces the selected role for display by funneling it throughString(describing: role)inside aText, turning the stored.principalvalue into readable text. This is illustrative only -- the role's effect is on scene window management, which surfaces in a real app's scene definition rather than in a view's body.
let role: WindowManagerRole = .principal to .associated (or .automatic) and watch the displayed String(describing: role) text update to the role that would govern the scene's full-screen and Stage Manager participation.Example & preview
Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.
struct WindowManagerRoleDemo: View {
let role: WindowManagerRole = .principal
var body: some View {
VStack(spacing: 8) {
Image(systemName: "macwindow")
.font(.largeTitle)
Text("Window Manager Role")
.font(.headline)
Text("\(String(describing: role))")
.font(.subheadline)
.foregroundStyle(.secondary)
}
.padding()
}
}