Fixed initial window size and placement on visionOS

This commit is contained in:
Sam Lantinga
2026-03-17 12:25:13 -07:00
parent 3d21b3bc68
commit c717a20ec8
3 changed files with 25 additions and 5 deletions

View File

@@ -69,6 +69,11 @@
size.width *= self.layer.contentsScale; size.width *= self.layer.contentsScale;
size.height *= self.layer.contentsScale; size.height *= self.layer.contentsScale;
// Skip invalid sizes (can happen on visionOS before scene geometry is applied)
if (size.width <= 0 || size.height <= 0) {
return;
}
CAMetalLayer *metallayer = ((CAMetalLayer *)self.layer); CAMetalLayer *metallayer = ((CAMetalLayer *)self.layer);
if (metallayer.drawableSize.width != size.width || if (metallayer.drawableSize.width != size.width ||
metallayer.drawableSize.height != size.height) { metallayer.drawableSize.height != size.height) {

View File

@@ -213,7 +213,9 @@ SDL_SystemTheme UIKit_GetSystemTheme(void)
#ifdef SDL_PLATFORM_VISIONOS #ifdef SDL_PLATFORM_VISIONOS
CGRect UIKit_ComputeViewFrame(SDL_Window *window) CGRect UIKit_ComputeViewFrame(SDL_Window *window)
{ {
return CGRectMake(window->x, window->y, window->w, window->h); // View origin is always (0,0) relative to the UIWindow.
// window->x/y are screen-level positions (often SDL_WINDOWPOS_UNDEFINED).
return CGRectMake(0, 0, window->w, window->h);
} }
#else #else
CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen) CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen)

View File

@@ -186,6 +186,23 @@ bool UIKit_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Properti
} }
if (scene) { if (scene) {
uiwindow = [[UIWindow alloc] initWithWindowScene:scene]; uiwindow = [[UIWindow alloc] initWithWindowScene:scene];
#ifdef SDL_PLATFORM_VISIONOS
/* On visionOS, the window scene may not have its final geometry yet
* when the UIWindow is first created. Request the desired size now
* and set the UIWindow frame to match so views have valid initial
* dimensions before the async geometry update completes. */
CGSize desiredSize = CGSizeMake(window->w, window->h);
uiwindow.frame = CGRectMake(0, 0, desiredSize.width, desiredSize.height);
UIWindowSceneGeometryPreferences *preferences =
[[UIWindowSceneGeometryPreferencesVision alloc] initWithSize:desiredSize];
[scene requestGeometryUpdateWithPreferences:preferences errorHandler:^(NSError * _Nonnull error) {
SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO,
"Initial geometry request failed: %s",
[[error localizedDescription] UTF8String]);
}];
#endif
} }
} }
if (!uiwindow) { if (!uiwindow) {
@@ -214,10 +231,6 @@ bool UIKit_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Properti
if (!SetupWindowData(_this, window, uiwindow, true)) { if (!SetupWindowData(_this, window, uiwindow, true)) {
return false; return false;
} }
#ifdef SDL_PLATFORM_VISIONOS
SDL_SetWindowSize(window, window->w, window->h);
#endif
} }
return true; return true;