Short answer: there is a private Info.plist key that Safari uses for this, but as far as I can tell it is not honored for third-party apps (especially SwiftUI-lifecycle ones). It looks first-party gated. Here is what I found reverse-engineering the visionOS 27 SDK and the simulator runtime.
MobileSafari.app/Info.plist on visionOS 27 contains a PreferredWindowCurvature entry, nested inside UILaunchPlacementParameters (the same dict that holds PreferredLaunchSize). This key is new in 27 - it does not exist in the 26.5 Safari Info.plist.
<key>UILaunchPlacementParameters</key>
<dict>
<key>PreferredLaunchSize</key>
<dict>
<key>Width</key><integer>940</integer>
<key>Height</key><integer>916</integer>
</dict>
<key>PreferredWindowCurvature</key>
<string>Enabled</string>
</dict>
The accepted string values (from the MRUIWindowCurvature enum in MRUIKit) are:
Default | Automatic | Enabled | Disabled
Practical note: UILaunchPlacementParameters is a nested dictionary, so you cannot express it via INFOPLIST_KEY_* build settings. With GENERATE_INFOPLIST_FILE = YES you have to point INFOPLIST_FILE at a small partial plist containing just this dict (Xcode merges the generated keys on top). Also, if your sources live in a synchronized folder group, keep that plist outside it or it gets added to "Copy Bundle Resources" and you get a duplicate Info.plist build error.
The window shell process (SurfBoard, class SFBSceneManager) decides curvature per scene and logs it. For my SwiftUI app the launch preference is always Default, even with the key set:
SurfBoard SFBSceneManager: Applying initial curvature for scene de.example.myapp:
clientCurvaturePreference: Default
launchCurvaturePreference: Default
chosenCurvature: Default
...
effectiveCurvature: NO
Setting a deliberately invalid value did not produce the "Received invalid curvature preference" log that SurfBoard emits for bad values - i.e. the key is never read at all for my app. Safari, by contrast, is a UIKit app with its own scene delegate (BrowserSceneDelegateRouter); SwiftUI-lifecycle apps do not get this honored. Adding a UISceneDelegate via UIApplicationDelegateAdaptor + configurationForConnecting did not change it.
Crucially, SurfBoard establishes launchCurvaturePreference before the app process loads (its scene-setup log is timestamped about 1s before my image's +load runs), so this is a host-side decision made from the app bundle's Info.plist - not something app code can influence after launch.
MRUIKit exposes a per-scene client setting:
// MRUIWindowCurvatureSceneClientSettings (protocol)
@property (nonatomic) NSInteger preferredWindowCurvature; // setPreferredWindowCurvature:
You reach the scene's mutable client settings via:
FBSScene *fbs = [windowScene _FBSScene];
[fbs updateClientSettingsWithBlock:^(FBSMutableSceneClientSettings *s) {
// ...
}];
...but the settings object that comes back (MRUIMutableSharedApplicationSceneClientSettings) does not respond to setPreferredWindowCurvature:. That accessor is a Swift-only FBS settings extension (no @objc entry point), so it is unreachable from the Obj-C runtime / KVC. The only Obj-C-reachable carrier of the value is MRUILaunchPlacementParameters (it has -setPreferredWindowCurvature: and -initWithInfoPlistDictionary), but that is consumed only at scene-request time, host-side. Method-swizzling -[MRUILaunchPlacementParameters preferredWindowCurvature] did nothing - the getter is never invoked in the app process.
On visionOS 27 the curvature decision is made by the system shell from the app bundle's Info.plist before your process runs, and the key is only honored for first-party / UIKit-shell apps. I could not enable it from a third-party SwiftUI app through any reachable path (Info.plist, runtime client settings, or swizzling). The "larger windows naturally curve" behavior shown for Safari in the WWDC session did not trigger for my own wide windows either.
If anyone has found a supported (or even unsupported-but-working) way to opt a third-party window into curvature, I would love to know.