SDL: Added VisionOS as a supported target to the Xcode project

From b9ea2dde443f35a18c065f10665a0b1f7820f3ab Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 27 Jan 2024 11:04:06 -0800
Subject: [PATCH] Added VisionOS as a supported target to the Xcode project

Also added SDL_PLATFORM_VISIONOS to the platform definitions and generally switched from TARGET_OS_* macros to SDL_PLATFORM_* macros.
---
 Xcode/SDL/SDL.xcodeproj/project.pbxproj     |  6 ++-
 include/SDL3/SDL_platform_defines.h         |  7 +++-
 include/build_config/SDL_build_config_ios.h |  2 +-
 src/audio/coreaudio/SDL_coreaudio.m         |  6 +--
 src/filesystem/cocoa/SDL_sysfilesystem.m    |  8 ++--
 src/joystick/apple/SDL_mfijoystick.m        | 28 ++++++-------
 src/misc/ios/SDL_sysurl.m                   |  2 +-
 src/power/uikit/SDL_syspower.m              | 10 ++---
 src/video/SDL_video_capture_apple.m         |  2 +-
 src/video/uikit/SDL_uikitappdelegate.m      | 32 +++++++--------
 src/video/uikit/SDL_uikitclipboard.m        |  8 ++--
 src/video/uikit/SDL_uikitevents.m           |  4 +-
 src/video/uikit/SDL_uikitmessagebox.m       |  2 +-
 src/video/uikit/SDL_uikitmetalview.m        |  2 +-
 src/video/uikit/SDL_uikitmodes.h            | 10 ++---
 src/video/uikit/SDL_uikitmodes.m            | 44 ++++++++++-----------
 src/video/uikit/SDL_uikitvideo.h            |  2 +-
 src/video/uikit/SDL_uikitvideo.m            | 10 ++---
 src/video/uikit/SDL_uikitview.h             |  4 +-
 src/video/uikit/SDL_uikitview.m             | 24 +++++------
 src/video/uikit/SDL_uikitviewcontroller.h   |  4 +-
 src/video/uikit/SDL_uikitviewcontroller.m   | 26 ++++++------
 src/video/uikit/SDL_uikitwindow.m           | 34 ++++++++--------
 23 files changed, 141 insertions(+), 136 deletions(-)

diff --git a/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Xcode/SDL/SDL.xcodeproj/project.pbxproj
index a846955a6bea..1cfb27f26fe1 100644
--- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj
+++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj
@@ -2784,9 +2784,10 @@
 				PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL3;
 				PRODUCT_NAME = SDL3;
 				STRIP_STYLE = "non-global";
-				SUPPORTED_PLATFORMS = "watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos";
+				SUPPORTED_PLATFORMS = "xrsimulator xros macosx iphonesimulator iphoneos appletvsimulator appletvos";
 				SUPPORTS_MACCATALYST = YES;
 				TVOS_DEPLOYMENT_TARGET = 9.0;
+				XROS_DEPLOYMENT_TARGET = 1.0;
 			};
 			name = Release;
 		};
@@ -2841,9 +2842,10 @@
 				PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL3;
 				PRODUCT_NAME = SDL3;
 				STRIP_INSTALLED_PRODUCT = NO;
-				SUPPORTED_PLATFORMS = "watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos";
+				SUPPORTED_PLATFORMS = "xrsimulator xros macosx iphonesimulator iphoneos appletvsimulator appletvos";
 				SUPPORTS_MACCATALYST = YES;
 				TVOS_DEPLOYMENT_TARGET = 9.0;
+				XROS_DEPLOYMENT_TARGET = 1.0;
 			};
 			name = Debug;
 		};
diff --git a/include/SDL3/SDL_platform_defines.h b/include/SDL3/SDL_platform_defines.h
index 9a2154a8ec79..8083619d89a1 100644
--- a/include/SDL3/SDL_platform_defines.h
+++ b/include/SDL3/SDL_platform_defines.h
@@ -86,13 +86,16 @@
 #ifndef TARGET_OS_SIMULATOR
 #define TARGET_OS_SIMULATOR 0
 #endif
-#ifndef TARGET_OS_XR
-#define TARGET_OS_XR 0
+#ifndef TARGET_OS_VISION
+#define TARGET_OS_VISION 0
 #endif
 
 #if TARGET_OS_TV
 #define SDL_PLATFORM_TVOS   1
 #endif
+#if TARGET_OS_VISION
+#define SDL_PLATFORM_VISIONOS 1
+#endif
 #if TARGET_OS_IPHONE
 #define SDL_PLATFORM_IOS    1
 #else
diff --git a/include/build_config/SDL_build_config_ios.h b/include/build_config/SDL_build_config_ios.h
index fe5dea8afc91..e79ca4ce2058 100644
--- a/include/build_config/SDL_build_config_ios.h
+++ b/include/build_config/SDL_build_config_ios.h
@@ -170,7 +170,7 @@
 #define SDL_VIDEO_DRIVER_DUMMY  1
 
 /* Enable OpenGL ES */
-#if !TARGET_OS_MACCATALYST
+#if !TARGET_OS_MACCATALYST && !TARGET_OS_VISION
 #define SDL_VIDEO_OPENGL_ES2 1
 #define SDL_VIDEO_OPENGL_ES 1
 #define SDL_VIDEO_RENDER_OGL_ES2    1
diff --git a/src/audio/coreaudio/SDL_coreaudio.m b/src/audio/coreaudio/SDL_coreaudio.m
index 73762acf4cd3..e376e82bd5b1 100644
--- a/src/audio/coreaudio/SDL_coreaudio.m
+++ b/src/audio/coreaudio/SDL_coreaudio.m
@@ -417,7 +417,7 @@ static SDL_bool UpdateAudioSession(SDL_AudioDevice *device, SDL_bool open, SDL_b
             category = AVAudioSessionCategoryRecord;
         }
 
-        #if !TARGET_OS_TV
+        #ifndef SDL_PLATFORM_TVOS
         if (category == AVAudioSessionCategoryPlayAndRecord) {
             options |= AVAudioSessionCategoryOptionDefaultToSpeaker;
         }
@@ -846,7 +846,7 @@ static int COREAUDIO_OpenDevice(SDL_AudioDevice *device)
         AVAudioSession *session = [AVAudioSession sharedInstance];
         [session setPreferredSampleRate:device->spec.freq error:nil];
         device->spec.freq = (int)session.sampleRate;
-        #if TARGET_OS_TV
+        #ifdef SDL_PLATFORM_TVOS
         if (device->iscapture) {
             [session setPreferredInputNumberOfChannels:device->spec.channels error:nil];
             device->spec.channels = session.preferredInputNumberOfChannels;
@@ -856,7 +856,7 @@ static int COREAUDIO_OpenDevice(SDL_AudioDevice *device)
         }
         #else
         // Calling setPreferredOutputNumberOfChannels seems to break audio output on iOS
-        #endif // TARGET_OS_TV
+        #endif /* SDL_PLATFORM_TVOS */
     }
     #endif
 
diff --git a/src/filesystem/cocoa/SDL_sysfilesystem.m b/src/filesystem/cocoa/SDL_sysfilesystem.m
index 71f674fae3f9..aef0217d2aca 100644
--- a/src/filesystem/cocoa/SDL_sysfilesystem.m
+++ b/src/filesystem/cocoa/SDL_sysfilesystem.m
@@ -75,7 +75,7 @@
             org = "";
         }
 
-#if !TARGET_OS_TV
+#ifndef SDL_PLATFORM_TVOS
         array = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
 #else
         /* tvOS does not have persistent local storage!
@@ -95,7 +95,7 @@
         }
 
         array = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
-#endif /* !TARGET_OS_TV */
+#endif /* !SDL_PLATFORM_TVOS */
 
         if ([array count] > 0) { /* we only want the first item in the list. */
             NSString *str = [array objectAtIndex:0];
@@ -129,7 +129,7 @@
 char *SDL_GetUserFolder(SDL_Folder folder)
 {
     @autoreleasepool {
-#if TARGET_OS_TV
+#ifdef SDL_PLATFORM_TVOS
         SDL_SetError("tvOS does not have persistent storage");
         return NULL;
 #else
@@ -224,7 +224,7 @@
         mkdir(retval, 0700);
 
         return retval;
-#endif /* TARGET_OS_TV */
+#endif /* SDL_PLATFORM_TVOS */
     }
 }
 
diff --git a/src/joystick/apple/SDL_mfijoystick.m b/src/joystick/apple/SDL_mfijoystick.m
index eae3ef415193..3accd8b300e3 100644
--- a/src/joystick/apple/SDL_mfijoystick.m
+++ b/src/joystick/apple/SDL_mfijoystick.m
@@ -30,7 +30,7 @@
 #include "SDL_mfijoystick_c.h"
 
 
-#if TARGET_OS_IOS
+#if defined(SDL_PLATFORM_IOS) && !defined(SDL_PLATFORM_TVOS)
 #define SDL_JOYSTICK_iOS_ACCELEROMETER
 #import <CoreMotion/CoreMotion.h>
 #endif
@@ -325,7 +325,7 @@ static BOOL ElementAlreadyHandled(SDL_JoystickDeviceItem *device, NSString *elem
             /* The Nintendo Switch JoyCon home button doesn't ever show as being held down */
             return TRUE;
         }
-#if TARGET_OS_TV
+#ifdef SDL_PLATFORM_TVOS
         /* The OS uses the home button, it's not available to apps */
         return TRUE;
 #endif
@@ -484,7 +484,7 @@ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle
         vendor = USB_VENDOR_APPLE;
         product = 2;
         subtype = 2;
-#if TARGET_OS_TV
+#ifdef SDL_PLATFORM_TVOS
     } else if (controller.microGamepad) {
         vendor = USB_VENDOR_APPLE;
         product = 3;
@@ -541,7 +541,7 @@ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle
         }
 #endif /* DEBUG_CONTROLLER_PROFILE */
 
-#if TARGET_OS_TV
+#ifdef SDL_PLATFORM_TVOS
         /* tvOS turns the menu button into a system gesture, so we grab it here instead */
         if (elements[GCInputButtonMenu] && !elements[@"Button Home"]) {
             device->pause_button_index = [device->buttons indexOfObject:GCInputButtonMenu];
@@ -588,7 +588,7 @@ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle
                 has_direct_menu = TRUE;
             }
         }
-#if TARGET_OS_TV
+#ifdef SDL_PLATFORM_TVOS
         /* The single menu button isn't very reliable, at least as of tvOS 16.1 */
         if ((device->button_mask & (1 << SDL_GAMEPAD_BUTTON_BACK)) == 0) {
             has_direct_menu = FALSE;
@@ -620,7 +620,7 @@ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle
         device->nhats = 1; /* d-pad */
         device->nbuttons = nbuttons;
     }
-#if TARGET_OS_TV
+#ifdef SDL_PLATFORM_TVOS
     else if (controller.microGamepad) {
         int nbuttons = 0;
 
@@ -786,7 +786,7 @@ static void IOS_AddJoystickDevice(GCController *controller, SDL_bool acceleromet
     return next;
 }
 
-#if TARGET_OS_TV
+#ifdef SDL_PLATFORM_TVOS
 static void SDLCALL SDL_AppleTVRemoteRotationHintChanged(void *udata, const char *name, const char *oldValue, const char *newValue)
 {
     BOOL allowRotation = newValue != NULL && *newValue != '0';
@@ -799,7 +799,7 @@ static void SDLCALL SDL_AppleTVRemoteRotationHintChanged(void *udata, const char
         }
     }
 }
-#endif /* TARGET_OS_TV */
+#endif /* SDL_PLATFORM_TVOS */
 
 static int IOS_JoystickInit(void)
 {
@@ -843,10 +843,10 @@ static int IOS_JoystickInit(void)
             IOS_AddJoystickDevice(controller, SDL_FALSE);
         }
 
-#if TARGET_OS_TV
+#ifdef SDL_PLATFORM_TVOS
         SDL_AddHintCallback(SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION,
                             SDL_AppleTVRemoteRotationHintChanged, NULL);
-#endif /* TARGET_OS_TV */
+#endif /* SDL_PLATFORM_TVOS */
 
         center = [NSNotificationCenter defaultCenter];
 
@@ -1248,7 +1248,7 @@ static void IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
 
             SDL_small_free(buttons, isstack);
         }
-#if TARGET_OS_TV
+#ifdef SDL_PLATFORM_TVOS
         else if (controller.microGamepad) {
             GCMicroGamepad *gamepad = controller.microGamepad;
 
@@ -1271,7 +1271,7 @@ static void IOS_MFIJoystickUpdate(SDL_Joystick *joystick)
                 SDL_SendJoystickButton(timestamp, joystick, i, buttons[i]);
             }
         }
-#endif /* TARGET_OS_TV */
+#endif /* SDL_PLATFORM_TVOS */
 
         if (joystick->nhats > 0) {
             SDL_SendJoystickHat(timestamp, joystick, 0, hatstate);
@@ -1799,10 +1799,10 @@ static void IOS_JoystickQuit(void)
             disconnectObserver = nil;
         }
 
-#if TARGET_OS_TV
+#ifdef SDL_PLATFORM_TVOS
         SDL_DelHintCallback(SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION,
                             SDL_AppleTVRemoteRotationHintChanged, NULL);
-#endif /* TARGET_OS_TV */
+#endif /* SDL_PLATFORM_TVOS */
 #endif /* SDL_JOYSTICK_MFI */
 
         while (deviceList != NULL) {
diff --git a/src/misc/ios/SDL_sysurl.m b/src/misc/ios/SDL_sysurl.m
index 7ec00c858574..8038bc732f9c 100644
--- a/src/misc/ios/SDL_sysurl.m
+++ b/src/misc/ios/SDL_sysurl.m
@@ -30,7 +30,7 @@ int SDL_SYS_OpenURL(const char *url)
 {
     @autoreleasepool {
 
-#if TARGET_OS_XR
+#ifdef SDL_PLATFORM_VISIONOS
         return SDL_Unsupported();  // openURL is not suported on visionOS
 #else
         NSString *nsstr = [NSString stringWithUTF8String:url];
diff --git a/src/power/uikit/SDL_syspower.m b/src/power/uikit/SDL_syspower.m
index 3049c1e0c14d..bca259f3277b 100644
--- a/src/power/uikit/SDL_syspower.m
+++ b/src/power/uikit/SDL_syspower.m
@@ -27,7 +27,7 @@
 
 #include "SDL_syspower.h"
 
-#if !TARGET_OS_TV
+#ifndef SDL_PLATFORM_TVOS
 /* turn off the battery monitor if it's been more than X ms since last check. */
 static const int BATTERY_MONITORING_TIMEOUT = 3000;
 static Uint64 SDL_UIKitLastPowerInfoQuery = 0;
@@ -48,15 +48,15 @@ void SDL_UIKit_UpdateBatteryMonitoring(void)
 {
     /* Do nothing. */
 }
-#endif /* !TARGET_OS_TV */
+#endif /* !SDL_PLATFORM_TVOS */
 
 SDL_bool SDL_GetPowerInfo_UIKit(SDL_PowerState *state, int *seconds, int *percent)
 {
-#if TARGET_OS_TV
+#ifdef SDL_PLATFORM_TVOS
     *state = SDL_POWERSTATE_NO_BATTERY;
     *seconds = -1;
     *percent = -1;
-#else  /* TARGET_OS_TV */
+#else  /* SDL_PLATFORM_TVOS */
     @autoreleasepool {
         UIDevice *uidev = [UIDevice currentDevice];
 
@@ -96,7 +96,7 @@ SDL_bool SDL_GetPowerInfo_UIKit(SDL_PowerState *state, int *seconds, int *percen
         const float level = uidev.batteryLevel;
         *percent = ((level < 0.0f) ? -1 : ((int)((level * 100) + 0.5f)));
     }
-#endif /* TARGET_OS_TV */
+#endif /* SDL_PLATFORM_TVOS */
 
     return SDL_TRUE; /* always the definitive answer on iOS. */
 }
diff --git a/src/video/SDL_video_capture_apple.m b/src/video/SDL_video_capture_apple.m
index e63ce3099430..40561263b943 100644
--- a/src/video/SDL_video_capture_apple.m
+++ b/src/video/SDL_video_capture_apple.m
@@ -33,7 +33,7 @@
 #undef HAVE_COREMEDIA
 #endif
 
-#if TARGET_OS_TV
+#ifdef SDL_PLATFORM_TVOS
 #undef HAVE_COREMEDIA
 #endif
 
diff --git a/src/video/uikit/SDL_uikitappdelegate.m b/src/video/uikit/SDL_uikitappdelegate.m
index d8c3a9e0c208..0ab30234ccb2 100644
--- a/src/video/uikit/SDL_uikitappdelegate.m
+++ b/src/video/uikit/SDL_uikitappdelegate.m
@@ -30,7 +30,7 @@
 
 #include "../../events/SDL_events_c.h"
 
-#if !TARGET_OS_TV
+#ifndef SDL_PLATFORM_TVOS
 #include <AvailabilityVersions.h>
 
 #ifndef __IPHONE_13_0
@@ -79,7 +79,7 @@ int SDL_RunApp(int argc, char* argv[], SDL_main_func mainFunction, void * reserv
     return exit_status;
 }
 
-#if !TARGET_OS_TV && !TARGET_OS_XR
+#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS)
 /* Load a launch image using the old UILaunchImageFile-era naming rules. */
 static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh)
 {
@@ -142,7 +142,7 @@ - (void)viewDidLoad
     self.storyboardViewController.view.frame = self.view.bounds;
     [self.storyboardViewController didMoveToParentViewController:self];
 
-#if !TARGET_OS_XR
+#ifndef SDL_PLATFORM_VISIONOS
     UIApplication.sharedApplication.statusBarHidden = self.prefersStatusBarHidden;
     UIApplication.sharedApplication.statusBarStyle = self.preferredStatusBarStyle;
 #endif
@@ -170,11 +170,11 @@ - (UIStatusBarStyle)preferredStatusBarStyle
 }
 
 @end
-#endif /* !TARGET_OS_TV */
+#endif /* !SDL_PLATFORM_TVOS */
 
 @interface SDLLaunchScreenController ()
 
-#if !TARGET_OS_TV
+#ifndef SDL_PLATFORM_TVOS
 - (NSUInteger)supportedInterfaceOrientations;
 #endif
 
@@ -213,7 +213,7 @@ - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibB
         NSString *imagename = nil;
         UIImage *image = nil;
 
-#if TARGET_OS_XR
+#ifdef SDL_PLATFORM_VISIONOS
         int screenw = SDL_XR_SCREENWIDTH;
         int screenh = SDL_XR_SCREENHEIGHT;
 #else
@@ -223,7 +223,7 @@ - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibB
 
 
 
-#if !TARGET_OS_TV && !TARGET_OS_XR
+#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS)
         UIInterfaceOrientation curorient = [UIApplication sharedApplication].statusBarOrientation;
 
         /* We always want portrait-oriented size, to match UILaunchImageSize. */
@@ -253,7 +253,7 @@ - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibB
                     }
                 }
 
-#if !TARGET_OS_TV && !TARGET_OS_XR
+#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS)
                 UIInterfaceOrientationMask orientmask = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
                 NSString *orientstring = dict[@"UILaunchImageOrientation"];
 
@@ -282,7 +282,7 @@ - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibB
                 image = [UIImage imageNamed:imagename];
             }
         }
-#if !TARGET_OS_TV && !TARGET_OS_XR
+#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS)
         else {
             imagename = [bundle objectForInfoDictionaryKey:@"UILaunchImageFile"];
 
@@ -297,7 +297,7 @@ - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibB
 #endif
 
         if (image) {
-#if TARGET_OS_XR
+#ifdef SDL_PLATFORM_VISIONOS
             CGRect viewFrame = CGRectMake(0, 0, screenw, screenh);
 #else
             CGRect viewFrame = [UIScreen mainScreen].bounds;
@@ -305,7 +305,7 @@ - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibB
             UIImageView *view = [[UIImageView alloc] initWithFrame:viewFrame];
             UIImageOrientation imageorient = UIImageOrientationUp;
 
-#if !TARGET_OS_TV && !TARGET_OS_XR
+#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS)
             /* Bugs observed / workaround tested in iOS 8.3. */
             if (UIInterfaceOrientationIsLandscape(curorient)) {
                 if (image.size.width < image.size.height) {
@@ -337,7 +337,7 @@ - (void)loadView
     /* Do nothing. */
 }
 
-#if !TARGET_OS_TV
+#ifndef SDL_PLATFORM_TVOS
 - (BOOL)shouldAutorotate
 {
     /* If YES, the launch image will be incorrectly rotated in some cases. */
@@ -351,7 +351,7 @@ - (NSUInteger)supportedInterfaceOrientations
      * the ones set here (it will cause an exception in that case.) */
     return UIInterfaceOrientationMaskAll;
 }
-#endif /* !TARGET_OS_TV */
+#endif /* !SDL_PLATFORM_TVOS */
 
 @end
 
@@ -434,7 +434,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
     NSString *screenname = nil;
 
     /* tvOS only uses a plain launch image. */
-#if !TARGET_OS_TV && !TARGET_OS_XR
+#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS)
     screenname = [bundle objectForInfoDictionaryKey:@"UILaunchStoryboardName"];
 
     if (screenname) {
@@ -457,7 +457,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
     }
 
     if (vc.view) {
-#if TARGET_OS_XR
+#ifdef SDL_PLATFORM_VISIONOS
         CGRect viewFrame = CGRectMake(0, 0, SDL_XR_SCREENWIDTH, SDL_XR_SCREENHEIGHT);
 #else
         CGRect viewFrame = [UIScreen mainScreen].bounds;
@@ -517,7 +517,7 @@ - (void)sendDropFileForURL:(NSURL *)url fromSourceApplication:(NSString *)source
     SDL_SendDropComplete(NULL);
 }
 
-#if TARGET_OS_TV || (defined(__IPHONE_9_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_9_0)
+#if defined(SDL_PLATFORM_TVOS) || (defined(__IPHONE_9_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_9_0)
 
 - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
 {
diff --git a/src/video/uikit/SDL_uikitclipboard.m b/src/video/uikit/SDL_uikitclipboard.m
index cc5a757c4326..e53e72c84f2c 100644
--- a/src/video/uikit/SDL_uikitclipboard.m
+++ b/src/video/uikit/SDL_uikitclipboard.m
@@ -29,7 +29,7 @@
 
 int UIKit_SetClipboardText(SDL_VideoDevice *_this, const char *text)
 {
-#if TARGET_OS_TV
+#ifdef SDL_PLATFORM_TVOS
     return SDL_SetError("The clipboard is not available on tvOS");
 #else
     @autoreleasepool {
@@ -41,7 +41,7 @@ int UIKit_SetClipboardText(SDL_VideoDevice *_this, const char *text)
 
 char *UIKit_GetClipboardText(SDL_VideoDevice *_this)
 {
-#if TARGET_OS_TV
+#ifdef SDL_PLATFORM_TVOS
     return SDL_strdup(""); // Unsupported.
 #else
     @autoreleasepool {
@@ -60,7 +60,7 @@ int UIKit_SetClipboardText(SDL_VideoDevice *_this, const char *text)
 SDL_bool UIKit_HasClipboardText(SDL_VideoDevice *_this)
 {
     @autoreleasepool {
-#if !TARGET_OS_TV
+#ifndef SDL_PLATFORM_TVOS
         if ([UIPasteboard generalPasteboard].string != nil) {
             return SDL_TRUE;
         }
@@ -71,7 +71,7 @@ SDL_bool UIKit_HasClipboardText(SDL_VideoDevice *_this)
 
 void UIKit_InitClipboard(SDL_VideoDevice *_this)
 {
-#if !TARGET_OS_TV
+#ifndef SDL_PLATFORM_TVOS
     @autoreleasepool {
         SDL_UIKitVideoData *data = (__bridge SDL_UIKitVideoData *)_this->driverdata;
         NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
diff --git a/src/video/uikit/SDL_uikitevents.m b/src/video/uikit/SDL_uikitevents.m
index 00af2cc42251..223f5565ef63 100644
--- a/src/video/uikit/SDL_uikitevents.m
+++ b/src/video/uikit/SDL_uikitevents.m
@@ -57,7 +57,7 @@ - (void)eventPumpChanged
         [notificationCenter addObserver:self selector:@selector(applicationWillEnterForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
         [notificationCenter addObserver:self selector:@selector(applicationWillTerminate) name:UIApplicationWillTerminateNotification object:nil];
         [notificationCenter addObserver:self selector:@selector(applicationDidReceiveMemoryWarning) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
-#if !TARGET_OS_TV && !TARGET_OS_XR
+#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS)
         [notificationCenter addObserver:self
                                selector:@selector(applicationDidChangeStatusBarOrientation)
                                    name:UIApplicationDidChangeStatusBarOrientationNotification
@@ -99,7 +99,7 @@ - (void)applicationDidReceiveMemoryWarning
     SDL_OnApplicationDidReceiveMemoryWarning();
 }
 
-#if !TARGET_OS_TV && !TARGET_OS_XR
+#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS)
 - (void)applicationDidChangeStatusBarOrientation
 {
     SDL_OnApplicationDidChangeStatusBarOrientation();
diff --git a/src/video/uikit/SDL_uikitmessagebox.m b/src/video/uikit/SDL_uikitmessagebox.m
index 55b69b31ce9f..cc977695be6c 100644
--- a/src/video/uikit/SDL_uikitmessagebox.m
+++ b/src/video/uikit/SDL_uikitmessagebox.m
@@ -98,7 +98,7 @@ static BOOL UIKit_ShowMessageBoxAlertController(const SDL_MessageBoxData *messag
     }
 
     if (window == nil || window.rootViewController == nil) {
-#if TARGET_OS_XR
+#ifdef SDL_PLATFORM_VISIONOS
         alertwindow = [[UIWindow alloc] init];
 #else
         alertwindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
diff --git a/src/video/uikit/SDL_uikitmetalview.m b/src/video/uikit/SDL_uikitmetalview.m
index a8d34d49f608..71be59e49c77 100644
--- a/src/video/uikit/SDL_uikitmetalview.m
+++ b/src/video/uikit/SDL_uikitmetalview.m
@@ -79,7 +79,7 @@ SDL_MetalView UIKit_Metal_CreateView(SDL_VideoDevice *_this, SDL_Window *window)
         CGFloat scale = 1.0;
         SDL_uikitmetalview *metalview;
 
-#if !TARGET_OS_XR
+#ifndef SDL_PLATFORM_VISIONOS
         if (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) {
             /* Set the scale to the natural scale factor of the screen - then
              * the backing dimensions of the Metal view will match the pixel
diff --git a/src/video/uikit/SDL_uikitmodes.h b/src/video/uikit/SDL_uikitmodes.h
index a71713972cd3..e8f4b0371c6b 100644
--- a/src/video/uikit/SDL_uikitmodes.h
+++ b/src/video/uikit/SDL_uikitmodes.h
@@ -27,7 +27,7 @@
 
 @interface SDL_UIKitDisplayData : NSObject
 
-#if !TARGET_OS_XR
+#ifndef SDL_PLATFORM_VISIONOS
 - (instancetype)initWithScreen:(UIScreen *)screen;
 @property(nonatomic, strong) UIScreen *uiscreen;
 #endif
@@ -35,18 +35,18 @@
 @end
 
 @interface SDL_UIKitDisplayModeData : NSObject
-#if !TARGET_OS_XR
+#ifndef SDL_PLATFORM_VISIONOS
 @property(nonatomic, strong) UIScreenMode *uiscreenmode;
 #endif
 
 @end
 
-#if !TARGET_OS_XR
+#ifndef SDL_PLATFORM_VISIONOS
 extern SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen);
 #endif
 
 extern int UIKit_InitModes(SDL_VideoDevice *_this);
-#if !TARGET_OS_XR
+#ifndef SDL_PLATFORM_VISIONOS
 extern int UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event);
 extern void UIKit_DelDisplay(UIScreen *uiscreen);
 #endif
@@ -57,7 +57,7 @@ extern int UIKit_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay
 
 // because visionOS does not have a screen
 // we create a fake 1080p display to maintain compatibility.
-#if TARGET_OS_XR
+#ifdef SDL_PLATFORM_VISIONOS
 #define SDL_XR_SCREENWIDTH 1920
 #define SDL_XR_SCREENHEIGHT 1080
 #endif
diff --git a/src/video/uikit/SDL_uikitmodes.m b/src/video/uikit/SDL_uikitmodes.m
index 9d0f479c317e..90e6be16d4a1 100644
--- a/src/video/uikit/SDL_uikitmodes.m
+++ b/src/video/uikit/SDL_uikitmodes.m
@@ -30,7 +30,7 @@
 
 @implementation SDL_UIKitDisplayData
 
-#if !TARGET_OS_XR
+#ifndef SDL_PLATFORM_VISIONOS
 - (instancetype)initWithScreen:(UIScreen *)screen
 {
     if (self = [super init]) {
@@ -45,7 +45,7 @@ - (instancetype)initWithScreen:(UIScreen *)screen
 
 @implementation SDL_UIKitDisplayModeData
 
-#if !TARGET_OS_XR
+#ifndef SDL_PLATFORM_VISIONOS
 @synthesize uiscreenmode;
 #endif
 
@@ -54,7 +54,7 @@ @implementation SDL_UIKitDisplayModeData
 @interface SDL_DisplayWatch : NSObject
 @end
 
-#if !TARGET_OS_XR
+#ifndef SDL_PLATFORM_VISIONOS
 @implementation SDL_DisplayWatch
 
 + (void)start
@@ -98,7 +98,7 @@ + (void)screenDisconnected:(NSNotification *)notification
 @end
 #endif
 
-#if !TARGET_OS_XR
+#ifndef SDL_PLATFORM_VISIONOS
 static int UIKit_AllocateDisplayModeData(SDL_DisplayMode *mode,
                                          UIScreenMode *uiscreenmode)
 {
@@ -128,7 +128,7 @@ static void UIKit_FreeDisplayModeData(SDL_DisplayMode *mode)
     }
 }
 
-#if !TARGET_OS_XR
+#ifndef SDL_PLATFORM_VISIONOS
 static float UIKit_GetDisplayModeRefreshRate(UIScreen *uiscreen)
 {
 #ifdef __IPHONE_10_3
@@ -229,7 +229,7 @@ int UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event)
     }
 
     SDL_zero(display);
-#if !TARGET_OS_TV
+#ifndef SDL_PLATFORM_TVOS
     if (uiscreen == [UIScreen mainScreen]) {
         /* The natural orientation (used by sensors) is portrait */
         display.natural_orientation = SDL_ORIENTATION_PORTRAIT;
@@ -243,7 +243,7 @@ int UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event)
     display.desktop_mode = mode;
 
     /* Allocate the display data */
-#if TARGET_OS_XR
+#ifdef SDL_PLATFORM_VISIONOS
     SDL_UIKitDisplayData *data = [[SDL_UIKitDisplayData alloc] init];
 #else
     SDL_UIKitDisplayData *data = [[SDL_UIKitDisplayData alloc] initWithScreen:uiscreen];
@@ -261,7 +261,7 @@ int UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event)
 }
 #endif
 
-#if TARGET_OS_XR
+#ifdef SDL_PLATFORM_VISIONOS
 int UIKit_AddDisplay(SDL_bool send_event){
     CGSize size = CGSizeMake(SDL_XR_SCREENWIDTH, SDL_XR_SCREENHEIGHT);
     SDL_VideoDisplay display;
@@ -293,7 +293,7 @@ int UIKit_AddDisplay(SDL_bool send_event){
 }
 #endif
 
-#if !TARGET_OS_XR
+#ifndef SDL_PLATFORM_VISIONOS
 
 void UIKit_DelDisplay(UIScreen *uiscreen)
 {
@@ -318,11 +318,11 @@ void UIKit_DelDisplay(UIScreen *uiscreen)
 
 SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen)
 {
-#if !TARGET_OS_TV
+#ifndef SDL_PLATFORM_TVOS
     if (uiscreen == [UIScreen mainScreen]) {
         return UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
     } else
-#endif /* !TARGET_OS_TV */
+#endif /* !SDL_PLATFORM_TVOS */
     {
         CGSize size = uiscreen.bounds.size;
         return (size.width > size.height);
@@ -332,7 +332,7 @@ SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen)
 int UIKit_InitModes(SDL_VideoDevice *_this)
 {
     @autoreleasepool {
-#if TARGET_OS_XR
+#ifdef SDL_PLATFORM_VISIONOS
         UIKit_AddDisplay(SDL_FALSE);
 #else
         for (UIScreen *uiscreen in [UIScreen screens]) {
@@ -342,11 +342,11 @@ int UIKit_InitModes(SDL_VideoDevice *_this)
         }
 #endif
         
-#if !TARGET_OS_TV && !TARGET_OS_XR
+#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS)
         SDL_OnApplicationDidChangeStatusBarOrientation();
 #endif
 
-#if !TARGET_OS_XR
+#ifndef SDL_PLATFORM_VISIONOS
         [SDL_DisplayWatch start];
 #endif
     }
@@ -356,7 +356,7 @@ int UIKit_InitModes(SDL_VideoDevice *_this)
 
 int UIKit_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display)
 {
-#if !TARGET_OS_XR
+#ifndef SDL_PLATFORM_VISIONOS
     @autoreleasepool {
         SDL_UIKitDisplayData *data = (__bridge SDL_UIKitDisplayData *)display->driverdata;
 
@@ -364,7 +364,7 @@ int UIKit_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display)
         SDL_bool addRotation = (data.uiscreen == [UIScreen mainScreen]);
         NSArray *availableModes = nil;
 
-#if TARGET_OS_TV
+#ifdef SDL_PLATFORM_TVOS
         addRotation = SDL_FALSE;
         availableModes = @[ data.uiscreen.currentMode ];
 #else
@@ -392,11 +392,11 @@ int UIKit_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display)
 
 int UIKit_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
 {
-#if !TARGET_OS_XR
+#ifndef SDL_PLATFORM_VISIONOS
     @autoreleasepool {
         SDL_UIKitDisplayData *data = (__bridge SDL_UIKitDisplayData *)display->driverdata;
 
-#if !TARGET_OS_TV
+#ifndef SDL_PLATFORM_TVOS
         SDL_UIKitDisplayModeData *modedata = (__bridge SDL_UIKitDisplayModeData *)mode->driverdata;
         [data.uiscreen setCurrentMode:modedata.uiscreenmode];
 #endif
@@ -424,7 +424,7 @@ int UIKit_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *displ
 {
     @autoreleasepool {
         SDL_UIKitDisplayData *data = (__bridge SDL_UIKitDisplayData *)display->driverdata;
-#if TARGET_OS_XR
+#ifdef SDL_PLATFORM_VISIONOS
         CGRect frame = CGRectMake(0, 0, SDL_XR_SCREENWIDTH, SDL_XR_SCREENHEIGHT);
 #else
         CGRect frame = data.uiscreen.bounds;
@@ -447,7 +447,7 @@ int UIKit_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *displ
 
 void UIKit_QuitModes(SDL_VideoDevice *_this)
 {
-#if !TARGET_OS_XR
+#ifndef SDL_PLATFORM_VISIONOS
     [SDL_DisplayWatch stop];
 #endif
 
@@ -471,7 +471,7 @@ void UIKit_QuitModes(SDL_VideoDevice *_this)
     }
 }
 
-#if !TARGET_OS_TV && !TARGET_OS_XR
+#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS)
 void SDL_OnApplicationDidChangeStatusBarOrientation(void)
 {
     BOOL isLandscape = UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
@@ -523,6 +523,6 @@ void SDL_OnApplicationDidChangeStatusBarOrientation(void)
         SDL_SendDisplayEvent(display, SDL_EVENT_DISPLAY_ORIENTATION, orientation);
     }
 }
-#endif /* !TARGET_OS_TV */
+#endif /* !SDL_PLATFORM_TVOS */
 
 #endif /* SDL_VIDEO_DRIVER_UIKIT */
diff --git a/src/video/uikit/SDL_uikitvideo.h b/src/video/uikit/SDL_uikitvideo.h
index 4022cfbb1321..b57e0a6f6081 100644
--- a/src/video/uikit/SDL_uikitvideo.h
+++ b/src/video/uikit/SDL_uikitvideo.h
@@ -33,7 +33,7 @@
 
 @end
 
-#if TARGET_OS_XR
+#ifdef SDL_PLATFORM_VISIONOS
 CGRect UIKit_ComputeViewFrame(SDL_Window *window);
 #else
 CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen);
diff --git a/src/video/uikit/SDL_uikitvideo.m b/src/video/uikit/SDL_uikitvideo.m
index 5551312f21bf..151611194024 100644
--- a/src/video/uikit/SDL_uikitvideo.m
+++ b/src/video/uikit/SDL_uikitvideo.m
@@ -186,7 +186,7 @@ SDL_bool UIKit_IsSystemVersionAtLeast(double version)
 
 SDL_SystemTheme UIKit_GetSystemTheme(void)
 {
-#if !TARGET_OS_XR
+#ifndef SDL_PLATFORM_VISIONOS
     if (@available(iOS 12.0, tvOS 10.0, *)) {
         switch ([UIScreen mainScreen].traitCollection.userInterfaceStyle) {
         case UIUserInterfaceStyleDark:
@@ -201,7 +201,7 @@ SDL_SystemTheme UIKit_GetSystemTheme(void)
     return SDL_SYSTEM_THEME_UNKNOWN;
 }
 
-#if TARGET_OS_XR
+#ifdef SDL_PLATFORM_VISIONOS
 CGRect UIKit_ComputeViewFrame(SDL_Window *window){
     return CGRectMake(window->x, window->y, window->w, window->h);
 }
@@ -218,7 +218,7 @@ CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen)
         frame = data.uiwindow.bounds;
     }
 
-#if !TARGET_OS_TV
+#ifndef SDL_PLATFORM_TVOS
     /* iOS 10 seems to have a bug where, in certain conditions, putting the
 

(Patch may be truncated, please check the link at the top of this post.)