SDL: Use bridged pointers to Objective C objects in C structures

From 6c9e199f7303878fc12c738f73bd24c063ecb0d5 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Wed, 22 Feb 2023 21:51:51 -0800
Subject: [PATCH] Use bridged pointers to Objective C objects in C structures

Fixes https://github.com/libsdl-org/SDL/issues/7244
---
 src/video/SDL_sysvideo.h                  | 24 -------
 src/video/cocoa/SDL_cocoaclipboard.h      |  4 +-
 src/video/cocoa/SDL_cocoaclipboard.m      |  4 +-
 src/video/cocoa/SDL_cocoaevents.m         |  6 +-
 src/video/cocoa/SDL_cocoakeyboard.m       | 14 ++--
 src/video/cocoa/SDL_cocoamessagebox.m     |  2 +-
 src/video/cocoa/SDL_cocoametalview.m      |  2 +-
 src/video/cocoa/SDL_cocoamodes.m          |  8 +--
 src/video/cocoa/SDL_cocoamouse.m          |  8 +--
 src/video/cocoa/SDL_cocoaopengl.m         |  8 +--
 src/video/cocoa/SDL_cocoaopengles.m       | 10 +--
 src/video/cocoa/SDL_cocoashape.m          |  4 +-
 src/video/cocoa/SDL_cocoavideo.h          |  2 +-
 src/video/cocoa/SDL_cocoavideo.m          | 14 ++--
 src/video/cocoa/SDL_cocoavulkan.m         |  2 +-
 src/video/cocoa/SDL_cocoawindow.h         | 14 ++--
 src/video/cocoa/SDL_cocoawindow.m         | 88 +++++++++++------------
 src/video/offscreen/SDL_offscreenwindow.h |  4 --
 src/video/uikit/SDL_uikitappdelegate.m    |  2 +-
 src/video/uikit/SDL_uikitclipboard.m      |  4 +-
 src/video/uikit/SDL_uikitmessagebox.m     |  2 +-
 src/video/uikit/SDL_uikitmetalview.m      |  2 +-
 src/video/uikit/SDL_uikitmodes.h          |  4 +-
 src/video/uikit/SDL_uikitmodes.m          | 29 ++++----
 src/video/uikit/SDL_uikitopengles.m       |  2 +-
 src/video/uikit/SDL_uikitvideo.h          |  2 +-
 src/video/uikit/SDL_uikitvideo.m          | 14 ++--
 src/video/uikit/SDL_uikitview.m           |  6 +-
 src/video/uikit/SDL_uikitviewcontroller.m |  4 +-
 src/video/uikit/SDL_uikitwindow.h         |  2 +-
 src/video/uikit/SDL_uikitwindow.m         | 36 +++++-----
 31 files changed, 150 insertions(+), 177 deletions(-)

diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h
index 37af3f999c2c..1a6e4c5ba0cc 100644
--- a/src/video/SDL_sysvideo.h
+++ b/src/video/SDL_sysvideo.h
@@ -31,34 +31,10 @@ typedef struct SDL_WindowShaper SDL_WindowShaper;
 typedef struct SDL_ShapeDriver SDL_ShapeDriver;
 typedef struct SDL_VideoDisplay SDL_VideoDisplay;
 typedef struct SDL_VideoDevice SDL_VideoDevice;
-#if defined(SDL_VIDEO_DRIVER_COCOA)
-#ifdef __OBJC__
-@class SDL_VideoData;
-@class SDL_WindowData;
-#else
-typedef struct _SDL_VideoData SDL_VideoData;
-typedef struct _SDL_WindowData SDL_WindowData;
-#endif
-typedef struct SDL_DisplayData SDL_DisplayData;
-typedef struct SDL_DisplayModeData SDL_DisplayModeData;
-#elif defined(SDL_VIDEO_DRIVER_UIKIT)
-#ifdef __OBJC__
-@class SDL_VideoData;
-@class SDL_WindowData;
-@class SDL_DisplayData;
-@class SDL_DisplayModeData;
-#else
-typedef struct _SDL_VideoData SDL_VideoData;
-typedef struct _SDL_WindowData SDL_WindowData;
-typedef struct _SDL_DisplayData SDL_DisplayData;
-typedef struct _SDL_DisplayModeData SDL_DisplayModeData;
-#endif
-#else
 typedef struct SDL_VideoData SDL_VideoData;
 typedef struct SDL_DisplayData SDL_DisplayData;
 typedef struct SDL_DisplayModeData SDL_DisplayModeData;
 typedef struct SDL_WindowData SDL_WindowData;
-#endif /* SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT */
 
 /* Define the SDL window-shaper structure */
 struct SDL_WindowShaper
diff --git a/src/video/cocoa/SDL_cocoaclipboard.h b/src/video/cocoa/SDL_cocoaclipboard.h
index dd954d55f37f..cd6c71ce5f47 100644
--- a/src/video/cocoa/SDL_cocoaclipboard.h
+++ b/src/video/cocoa/SDL_cocoaclipboard.h
@@ -24,11 +24,11 @@
 #define SDL_cocoaclipboard_h_
 
 /* Forward declaration */
-@class SDL_VideoData;
+@class SDL_CocoaVideoData;
 
 extern int Cocoa_SetClipboardText(_THIS, const char *text);
 extern char *Cocoa_GetClipboardText(_THIS);
 extern SDL_bool Cocoa_HasClipboardText(_THIS);
-extern void Cocoa_CheckClipboardUpdate(SDL_VideoData *data);
+extern void Cocoa_CheckClipboardUpdate(SDL_CocoaVideoData *data);
 
 #endif /* SDL_cocoaclipboard_h_ */
diff --git a/src/video/cocoa/SDL_cocoaclipboard.m b/src/video/cocoa/SDL_cocoaclipboard.m
index 765022750557..c6ea040b98fb 100644
--- a/src/video/cocoa/SDL_cocoaclipboard.m
+++ b/src/video/cocoa/SDL_cocoaclipboard.m
@@ -28,7 +28,7 @@
 int Cocoa_SetClipboardText(_THIS, const char *text)
 {
     @autoreleasepool {
-        SDL_VideoData *data = _this->driverdata;
+        SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->driverdata;
         NSPasteboard *pasteboard;
         NSString *format = NSPasteboardTypeString;
         NSString *nsstr = [NSString stringWithUTF8String:text];
@@ -86,7 +86,7 @@ int Cocoa_SetClipboardText(_THIS, const char *text)
     return result;
 }
 
-void Cocoa_CheckClipboardUpdate(SDL_VideoData *data)
+void Cocoa_CheckClipboardUpdate(SDL_CocoaVideoData *data)
 {
     @autoreleasepool {
         NSPasteboard *pasteboard;
diff --git a/src/video/cocoa/SDL_cocoaevents.m b/src/video/cocoa/SDL_cocoaevents.m
index bf8b58ebc0a6..6cb6da45781d 100644
--- a/src/video/cocoa/SDL_cocoaevents.m
+++ b/src/video/cocoa/SDL_cocoaevents.m
@@ -35,7 +35,7 @@
     SDL_VideoDevice *device = SDL_GetVideoDevice();
     if (device && device->windows) {
         for (sdlwindow = device->windows; sdlwindow; sdlwindow = sdlwindow->next) {
-            NSWindow *nswindow = sdlwindow->driverdata.nswindow;
+            NSWindow *nswindow = ((__bridge SDL_CocoaWindowData *)sdlwindow->driverdata).nswindow;
             if (win == nswindow) {
                 return sdlwindow;
             }
@@ -557,7 +557,7 @@ void Cocoa_SendWakeupEvent(_THIS, SDL_Window *window)
                                             location:NSMakePoint(0, 0)
                                        modifierFlags:0
                                            timestamp:0.0
-                                        windowNumber:window->driverdata.window_number
+                                        windowNumber:((__bridge SDL_CocoaWindowData *)window->driverdata).window_number
                                              context:nil
                                              subtype:0
                                                data1:0
@@ -570,7 +570,7 @@ void Cocoa_SendWakeupEvent(_THIS, SDL_Window *window)
 int Cocoa_SuspendScreenSaver(_THIS)
 {
     @autoreleasepool {
-        SDL_VideoData *data = _this->driverdata;
+        SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->driverdata;
 
         if (data.screensaver_assertion) {
             IOPMAssertionRelease(data.screensaver_assertion);
diff --git a/src/video/cocoa/SDL_cocoakeyboard.m b/src/video/cocoa/SDL_cocoakeyboard.m
index a92c17da2c93..da6afa02043b 100644
--- a/src/video/cocoa/SDL_cocoakeyboard.m
+++ b/src/video/cocoa/SDL_cocoakeyboard.m
@@ -228,7 +228,7 @@ static void HandleModifiers(_THIS, unsigned short scancode, unsigned int modifie
     }
 }
 
-static void UpdateKeymap(SDL_VideoData *data, SDL_bool send_event)
+static void UpdateKeymap(SDL_CocoaVideoData *data, SDL_bool send_event)
 {
     TISInputSourceRef key_layout;
     const void *chr_data;
@@ -294,7 +294,7 @@ static void UpdateKeymap(SDL_VideoData *data, SDL_bool send_event)
 
 void Cocoa_InitKeyboard(_THIS)
 {
-    SDL_VideoData *data = _this->driverdata;
+    SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->driverdata;
 
     UpdateKeymap(data, SDL_FALSE);
 
@@ -314,11 +314,11 @@ void Cocoa_StartTextInput(_THIS)
 {
     @autoreleasepool {
         NSView *parentView;
-        SDL_VideoData *data = _this->driverdata;
+        SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->driverdata;
         SDL_Window *window = SDL_GetKeyboardFocus();
         NSWindow *nswindow = nil;
         if (window) {
-            nswindow = window->driverdata.nswindow;
+            nswindow = ((__bridge SDL_CocoaWindowData *)window->driverdata).nswindow;
         }
 
         parentView = [nswindow contentView];
@@ -345,7 +345,7 @@ void Cocoa_StartTextInput(_THIS)
 void Cocoa_StopTextInput(_THIS)
 {
     @autoreleasepool {
-        SDL_VideoData *data = _this->driverdata;
+        SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->driverdata;
 
         if (data && data.fieldEdit) {
             [data.fieldEdit removeFromSuperview];
@@ -356,7 +356,7 @@ void Cocoa_StopTextInput(_THIS)
 
 int Cocoa_SetTextInputRect(_THIS, const SDL_Rect *rect)
 {
-    SDL_VideoData *data = _this->driverdata;
+    SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->driverdata;
     [data.fieldEdit setInputRect:rect];
     return 0;
 }
@@ -365,7 +365,7 @@ void Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
 {
     unsigned short scancode;
     SDL_Scancode code;
-    SDL_VideoData *data = _this ? _this->driverdata : nil;
+    SDL_CocoaVideoData *data = _this ? ((__bridge SDL_CocoaVideoData *)_this->driverdata) : nil;
     if (!data) {
         return; /* can happen when returning from fullscreen Space on shutdown */
     }
diff --git a/src/video/cocoa/SDL_cocoamessagebox.m b/src/video/cocoa/SDL_cocoamessagebox.m
index 9c4eb8c95baf..e7c8a2cefa54 100644
--- a/src/video/cocoa/SDL_cocoamessagebox.m
+++ b/src/video/cocoa/SDL_cocoamessagebox.m
@@ -42,7 +42,7 @@ - (id)initWithParentWindow:(SDL_Window *)window
 
         /* Retain the NSWindow because we'll show the alert later on the main thread */
         if (window) {
-            nswindow = window->driverdata.nswindow;
+            nswindow = ((__bridge SDL_CocoaWindowData *)window->driverdata).nswindow;
         } else {
             nswindow = nil;
         }
diff --git a/src/video/cocoa/SDL_cocoametalview.m b/src/video/cocoa/SDL_cocoametalview.m
index f87e4fbf3017..71509aec511d 100644
--- a/src/video/cocoa/SDL_cocoametalview.m
+++ b/src/video/cocoa/SDL_cocoametalview.m
@@ -133,7 +133,7 @@ - (NSView *)hitTest:(NSPoint)point
 Cocoa_Metal_CreateView(_THIS, SDL_Window *window)
 {
     @autoreleasepool {
-        SDL_WindowData *data = window->driverdata;
+        SDL_CocoaWindowData *data = (__bridge SDL_CocoaWindowData *)window->driverdata;
         NSView *view = data.nswindow.contentView;
         BOOL highDPI = (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) != 0;
         Uint32 windowID = SDL_GetWindowID(window);
diff --git a/src/video/cocoa/SDL_cocoamodes.m b/src/video/cocoa/SDL_cocoamodes.m
index a43a6ee45f99..0fb5f2c86bd2 100644
--- a/src/video/cocoa/SDL_cocoamodes.m
+++ b/src/video/cocoa/SDL_cocoamodes.m
@@ -363,7 +363,7 @@ void Cocoa_InitModes(_THIS)
 
 int Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect)
 {
-    SDL_DisplayData *displaydata = display->driverdata;
+    SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata;
     CGRect cgrect;
 
     cgrect = CGDisplayBounds(displaydata->display);
@@ -376,7 +376,7 @@ int Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect)
 
 int Cocoa_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect)
 {
-    SDL_DisplayData *displaydata = display->driverdata;
+    SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata;
     const CGDirectDisplayID cgdisplay = displaydata->display;
     NSArray *screens = [NSScreen screens];
     NSScreen *screen = nil;
@@ -408,7 +408,7 @@ int Cocoa_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rec
 
 int Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
 {
-    SDL_DisplayData *data = display->driverdata;
+    SDL_DisplayData *data = (SDL_DisplayData *)display->driverdata;
     CVDisplayLinkRef link = NULL;
     CFArrayRef modes;
     CFDictionaryRef dict = NULL;
@@ -485,7 +485,7 @@ static CGError SetDisplayModeForDisplay(CGDirectDisplayID display, SDL_DisplayMo
 
 int Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
 {
-    SDL_DisplayData *displaydata = display->driverdata;
+    SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata;
     SDL_DisplayModeData *data = (SDL_DisplayModeData *)mode->driverdata;
     CGDisplayFadeReservationToken fade_token = kCGDisplayFadeReservationInvalidToken;
     CGError result;
diff --git a/src/video/cocoa/SDL_cocoamouse.m b/src/video/cocoa/SDL_cocoamouse.m
index 0d3b82331cdc..d77fefbeb467 100644
--- a/src/video/cocoa/SDL_cocoamouse.m
+++ b/src/video/cocoa/SDL_cocoamouse.m
@@ -253,7 +253,7 @@ static int Cocoa_WarpMouseGlobal(float x, float y)
     CGPoint point;
     SDL_Mouse *mouse = SDL_GetMouse();
     if (mouse->focus) {
-        SDL_WindowData *data = mouse->focus->driverdata;
+        SDL_CocoaWindowData *data = (__bridge SDL_CocoaWindowData *)mouse->focus->driverdata;
         if ([data.listener isMovingOrFocusClickPending]) {
             DLog("Postponing warp, window being moved or focused.");
             [data.listener setPendingMoveX:x Y:y];
@@ -298,7 +298,7 @@ static int Cocoa_SetRelativeMouseMode(SDL_bool enabled)
 {
     CGError result;
     SDL_Window *window;
-    SDL_WindowData *data;
+    SDL_CocoaWindowData *data;
     if (enabled) {
         DLog("Turning on.");
         result = CGAssociateMouseAndMouseCursorPosition(NO);
@@ -321,7 +321,7 @@ static int Cocoa_SetRelativeMouseMode(SDL_bool enabled)
     /* We will re-apply the non-relative mode when the window finishes being moved,
      * if it is being moved right now.
      */
-    data = window->driverdata;
+    data = (__bridge SDL_CocoaWindowData *)window->driverdata;
     if ([data.listener isMovingOrFocusClickPending]) {
         return 0;
     }
@@ -402,7 +402,7 @@ static void Cocoa_HandleTitleButtonEvent(_THIS, NSEvent *event)
     }
 
     for (window = _this->windows; window; window = window->next) {
-        SDL_WindowData *data = window->driverdata;
+        SDL_CocoaWindowData *data = (__bridge SDL_CocoaWindowData *)window->driverdata;
         if (data && data.nswindow == nswindow) {
             switch ([event type]) {
             case NSEventTypeLeftMouseDown:
diff --git a/src/video/cocoa/SDL_cocoaopengl.m b/src/video/cocoa/SDL_cocoaopengl.m
index f5b480c3628c..5031f0139121 100644
--- a/src/video/cocoa/SDL_cocoaopengl.m
+++ b/src/video/cocoa/SDL_cocoaopengl.m
@@ -138,7 +138,7 @@ - (void)update
 - (void)setWindow:(SDL_Window *)newWindow
 {
     if (self->window) {
-        SDL_WindowData *oldwindowdata = self->window->driverdata;
+        SDL_CocoaWindowData *oldwindowdata = (__bridge SDL_CocoaWindowData *)self->window->driverdata;
 
         /* Make sure to remove us from the old window's context list, or we'll get scheduled updates from it too. */
         NSMutableArray *contexts = oldwindowdata.nscontexts;
@@ -150,7 +150,7 @@ - (void)setWindow:(SDL_Window *)newWindow
     self->window = newWindow;
 
     if (newWindow) {
-        SDL_WindowData *windowdata = newWindow->driverdata;
+        SDL_CocoaWindowData *windowdata = (__bridge SDL_CocoaWindowData *)newWindow->driverdata;
         NSView *contentview = windowdata.sdlContentView;
 
         /* Now sign up for scheduled updates for the new window. */
@@ -254,7 +254,7 @@ SDL_GLContext Cocoa_GL_CreateContext(_THIS, SDL_Window *window)
 {
     @autoreleasepool {
         SDL_VideoDisplay *display = SDL_GetVideoDisplayForWindow(window);
-        SDL_DisplayData *displaydata = display->driverdata;
+        SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata;
         NSOpenGLPixelFormatAttribute attr[32];
         NSOpenGLPixelFormat *fmt;
         SDLOpenGLContext *context;
@@ -482,7 +482,7 @@ int Cocoa_GL_SwapWindow(_THIS, SDL_Window *window)
 {
     @autoreleasepool {
         SDLOpenGLContext *nscontext = (__bridge SDLOpenGLContext *)SDL_GL_GetCurrentContext();
-        SDL_VideoData *videodata = _this->driverdata;
+        SDL_CocoaVideoData *videodata = (__bridge SDL_CocoaVideoData *)_this->driverdata;
         const int setting = SDL_AtomicGet(&nscontext->swapIntervalSetting);
 
         if (setting == 0) {
diff --git a/src/video/cocoa/SDL_cocoaopengles.m b/src/video/cocoa/SDL_cocoaopengles.m
index c188af3d330b..46c0f66c68ff 100644
--- a/src/video/cocoa/SDL_cocoaopengles.m
+++ b/src/video/cocoa/SDL_cocoaopengles.m
@@ -62,7 +62,7 @@ int Cocoa_GLES_LoadLibrary(_THIS, const char *path)
 {
     @autoreleasepool {
         SDL_GLContext context;
-        SDL_WindowData *data = window->driverdata;
+        SDL_CocoaWindowData *data = (__bridge SDL_CocoaWindowData *)window->driverdata;
 
 #if SDL_VIDEO_OPENGL_CGL
         if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES) {
@@ -103,14 +103,14 @@ int Cocoa_GLES_DeleteContext(_THIS, SDL_GLContext context)
 int Cocoa_GLES_SwapWindow(_THIS, SDL_Window *window)
 {
     @autoreleasepool {
-        return SDL_EGL_SwapBuffers(_this, window->driverdata.egl_surface);
+        return SDL_EGL_SwapBuffers(_this, ((__bridge SDL_CocoaWindowData *)window->driverdata).egl_surface);
     }
 }
 
 int Cocoa_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context)
 {
     @autoreleasepool {
-        return SDL_EGL_MakeCurrent(_this, window ? window->driverdata.egl_surface : EGL_NO_SURFACE, context);
+        return SDL_EGL_MakeCurrent(_this, window ? ((__bridge SDL_CocoaWindowData *)window->driverdata).egl_surface : EGL_NO_SURFACE, context);
     }
 }
 
@@ -119,7 +119,7 @@ int Cocoa_GLES_SetupWindow(_THIS, SDL_Window *window)
     @autoreleasepool {
         NSView *v;
         /* The current context is lost in here; save it and reset it. */
-        SDL_WindowData *windowdata = window->driverdata;
+        SDL_CocoaWindowData *windowdata = (__bridge SDL_CocoaWindowData *)window->driverdata;
         SDL_Window *current_win = SDL_GL_GetCurrentWindow();
         SDL_GLContext current_ctx = SDL_GL_GetCurrentContext();
 
@@ -151,7 +151,7 @@ int Cocoa_GLES_SetupWindow(_THIS, SDL_Window *window)
 Cocoa_GLES_GetEGLSurface(_THIS, SDL_Window *window)
 {
     @autoreleasepool {
-        return window->driverdata.egl_surface;
+        return ((__bridge SDL_CocoaWindowData *)window->driverdata).egl_surface;
     }
 }
 
diff --git a/src/video/cocoa/SDL_cocoashape.m b/src/video/cocoa/SDL_cocoashape.m
index 0bba18783504..c77ef8661f30 100644
--- a/src/video/cocoa/SDL_cocoashape.m
+++ b/src/video/cocoa/SDL_cocoashape.m
@@ -45,7 +45,7 @@ @implementation SDL_CocoaClosure
         SDL_WindowShaper *result;
         SDL_ShapeData *data;
         int resized_properly;
-        SDL_WindowData *windata = window->driverdata;
+        SDL_CocoaWindowData *windata = (__bridge SDL_CocoaWindowData *)window->driverdata;
 
         result = (SDL_WindowShaper *)SDL_malloc(sizeof(SDL_WindowShaper));
         if (!result) {
@@ -90,7 +90,7 @@ int Cocoa_SetWindowShape(SDL_WindowShaper *shaper, SDL_Surface *shape, SDL_Windo
 {
     @autoreleasepool {
         SDL_ShapeData *data = (__bridge SDL_ShapeData *)shaper->driverdata;
-        SDL_WindowData *windata = shaper->window->driverdata;
+        SDL_CocoaWindowData *windata = (__bridge SDL_CocoaWindowData *)shaper->window->driverdata;
         SDL_CocoaClosure *closure;
         if (data.saved == SDL_TRUE) {
             [data.context restoreGraphicsState];
diff --git a/src/video/cocoa/SDL_cocoavideo.h b/src/video/cocoa/SDL_cocoavideo.h
index b236cdb3212a..d88b19a916ea 100644
--- a/src/video/cocoa/SDL_cocoavideo.h
+++ b/src/video/cocoa/SDL_cocoavideo.h
@@ -96,7 +96,7 @@ DECLARE_ALERT_STYLE(Critical);
 
 @class SDLTranslatorResponder;
 
-@interface SDL_VideoData : NSObject
+@interface SDL_CocoaVideoData : NSObject
 @property(nonatomic) int allow_spaces;
 @property(nonatomic) int trackpad_is_touch_only;
 @property(nonatomic) unsigned int modifierFlags;
diff --git a/src/video/cocoa/SDL_cocoavideo.m b/src/video/cocoa/SDL_cocoavideo.m
index f6ba6526aa55..fa9f48320c93 100644
--- a/src/video/cocoa/SDL_cocoavideo.m
+++ b/src/video/cocoa/SDL_cocoavideo.m
@@ -32,7 +32,7 @@
 #include "SDL_cocoametalview.h"
 #include "SDL_cocoaopengles.h"
 
-@implementation SDL_VideoData
+@implementation SDL_CocoaVideoData
 
 @end
 
@@ -48,7 +48,7 @@ static void Cocoa_DeleteDevice(SDL_VideoDevice *device)
         if (device->wakeup_lock) {
             SDL_DestroyMutex(device->wakeup_lock);
         }
-        device->driverdata = nil;
+        CFBridgingRelease(device->driverdata);
         SDL_free(device);
     }
 }
@@ -57,14 +57,14 @@ static void Cocoa_DeleteDevice(SDL_VideoDevice *device)
 {
     @autoreleasepool {
         SDL_VideoDevice *device;
-        SDL_VideoData *data;
+        SDL_CocoaVideoData *data;
 
         Cocoa_RegisterApp();
 
         /* Initialize all variables that we clean on shutdown */
         device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice));
         if (device) {
-            data = [[SDL_VideoData alloc] init];
+            data = [[SDL_CocoaVideoData alloc] init];
         } else {
             data = nil;
         }
@@ -73,7 +73,7 @@ static void Cocoa_DeleteDevice(SDL_VideoDevice *device)
             SDL_free(device);
             return NULL;
         }
-        device->driverdata = data;
+        device->driverdata = (SDL_VideoData *)CFBridgingRetain(data);
         device->wakeup_lock = SDL_CreateMutex();
 
         /* Set the function pointers */
@@ -189,7 +189,7 @@ static void Cocoa_DeleteDevice(SDL_VideoDevice *device)
 int Cocoa_VideoInit(_THIS)
 {
     @autoreleasepool {
-        SDL_VideoData *data = _this->driverdata;
+        SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->driverdata;
 
         Cocoa_InitModes(_this);
         Cocoa_InitKeyboard(_this);
@@ -212,7 +212,7 @@ int Cocoa_VideoInit(_THIS)
 void Cocoa_VideoQuit(_THIS)
 {
     @autoreleasepool {
-        SDL_VideoData *data = _this->driverdata;
+        SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->driverdata;
         Cocoa_QuitModes(_this);
         Cocoa_QuitKeyboard(_this);
         Cocoa_QuitMouse(_this);
diff --git a/src/video/cocoa/SDL_cocoavulkan.m b/src/video/cocoa/SDL_cocoavulkan.m
index bb80b363a612..6e4da43114fe 100644
--- a/src/video/cocoa/SDL_cocoavulkan.m
+++ b/src/video/cocoa/SDL_cocoavulkan.m
@@ -262,7 +262,7 @@ SDL_bool Cocoa_Vulkan_CreateSurface(_THIS,
 
     if (window->flags & SDL_WINDOW_FOREIGN) {
         @autoreleasepool {
-            SDL_WindowData *data = window->driverdata;
+            SDL_CocoaWindowData *data = (__bridge SDL_CocoaWindowData *)window->driverdata;
             if (![data.sdlContentView.layer isKindOfClass:[CAMetalLayer class]]) {
                 [data.sdlContentView setLayer:[CAMetalLayer layer]];
             }
diff --git a/src/video/cocoa/SDL_cocoawindow.h b/src/video/cocoa/SDL_cocoawindow.h
index ebc576ef2193..1a593ce3c363 100644
--- a/src/video/cocoa/SDL_cocoawindow.h
+++ b/src/video/cocoa/SDL_cocoawindow.h
@@ -29,7 +29,7 @@
 #include "../SDL_egl_c.h"
 #endif
 
-@class SDL_WindowData;
+@class SDL_CocoaWindowData;
 
 typedef enum
 {
@@ -41,10 +41,10 @@ typedef enum
 
 @interface Cocoa_WindowListener : NSResponder <NSWindowDelegate>
 {
-    /* SDL_WindowData owns this Listener and has a strong reference to it.
+    /* SDL_CocoaWindowData owns this Listener and has a strong reference to it.
      * To avoid reference cycles, we could have either a weak or an
      * unretained ref to the WindowData. */
-    __weak SDL_WindowData *_data;
+    __weak SDL_CocoaWindowData *_data;
     BOOL observingVisible;
     BOOL wasCtrlLeft;
     BOOL wasVisible;
@@ -58,7 +58,7 @@ typedef enum
 }
 
 - (BOOL)isTouchFromTrackpad:(NSEvent *)theEvent;
-- (void)listen:(SDL_WindowData *)data;
+- (void)listen:(SDL_CocoaWindowData *)data;
 - (void)pauseVisibleObservation;
 - (void)resumeVisibleObservation;
 - (BOOL)setFullscreenSpace:(BOOL)state;
@@ -120,9 +120,9 @@ typedef enum
 /* *INDENT-ON* */
 
 @class SDLOpenGLContext;
-@class SDL_VideoData;
+@class SDL_CocoaVideoData;
 
-@interface SDL_WindowData : NSObject
+@interface SDL_CocoaWindowData : NSObject
 @property(nonatomic) SDL_Window *window;
 @property(nonatomic) NSWindow *nswindow;
 @property(nonatomic) NSView *sdlContentView;
@@ -132,7 +132,7 @@ typedef enum
 @property(nonatomic) NSInteger window_number;
 @property(nonatomic) NSInteger flash_request;
 @property(nonatomic) Cocoa_WindowListener *listener;
-@property(nonatomic) SDL_VideoData *videodata;
+@property(nonatomic) SDL_CocoaVideoData *videodata;
 #if SDL_VIDEO_OPENGL_EGL
 @property(nonatomic) EGLSurface egl_surface;
 #endif
diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m
index 39a24ef84fa5..b14cd3bbf623 100644
--- a/src/video/cocoa/SDL_cocoawindow.m
+++ b/src/video/cocoa/SDL_cocoawindow.m
@@ -63,7 +63,7 @@
 #define NSAppKitVersionNumber10_14 1671
 #endif
 
-@implementation SDL_WindowData
+@implementation SDL_CocoaWindowData
 
 @end
 
@@ -239,7 +239,7 @@ - (SDL_Window *)findSDLWindow
     /* !!! FIXME: is there a better way to do this? */
     if (_this) {
         for (sdlwindow = _this->windows; sdlwindow; sdlwindow = sdlwindow->next) {
-            NSWindow *nswindow = sdlwindow->driverdata.nswindow;
+            NSWindow *nswindow = ((__bridge SDL_CocoaWindowData *)sdlwindow->driverdata).nswindow;
             if (nswindow == self) {
                 break;
             }
@@ -258,7 +258,7 @@ static void ConvertNSRect(NSScreen *screen, BOOL fullscreen, NSRect *r)
     r->origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - r->origin.y - r->size.height;
 }
 
-static void ScheduleContextUpdates(SDL_WindowData *data)
+static void ScheduleContextUpdates(SDL_CocoaWindowData *data)
 {
 /* We still support OpenGL as long as Apple offers it, deprecated or not, so disable deprecation warnings about it. */
 #if SDL_VIDEO_OPENGL
@@ -333,7 +333,7 @@ static NSUInteger GetWindowStyle(SDL_Window *window)
 
 static SDL_bool SetWindowStyle(SDL_Window *window, NSUInteger style)
 {
-    SDL_WindowData *data = window->driverdata;
+    SDL_CocoaWindowData *data = (__bridge SDL_CocoaWindowData *)window->driverdata;
     NSWindow *nswindow = data.nswindow;
 
     /* The view responder chain gets messed with during setStyleMask */
@@ -353,7 +353,7 @@ static SDL_bool SetWindowStyle(SDL_Window *window, NSUInteger style)
 
 static SDL_bool ShouldAdjustCoordinatesForGrab(SDL_Window *window)
 {
-    SDL_WindowData *data = window->driverdata;
+    SDL_CocoaWindowData *data = (__bridge SDL_CocoaWindowData *)window->driverdata;
 
     if (!data || [data.listener isMovingOrFocusClickPending]) {
         return SDL_FALSE;
@@ -410,7 +410,7 @@ static SDL_bool AdjustCoordinatesForGrab(SDL_Window *window, float x, float y, C
 
 static void Cocoa_UpdateClipCursor(SDL_Window *window)
 {
-    SDL_WindowData *data = window->driverdata;
+    SDL_CocoaWindowData *data = (__bridge SDL_CocoaWindowData *)window->driverdata;
 
     if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_13_2) {
         NSWindow *nswindow = data.nswindow;
@@ -463,7 +463,7 @@ static void Cocoa_UpdateClipCursor(SDL_Window *window)
 
 @implementation Cocoa_WindowListener
 
-- (void)listen:(SDL_WindowData *)data
+- (void)listen:(SDL_CocoaWindowData *)data
 {
     NSNotificationCenter *center;
     NSWindow *window = data.nswindow;
@@ -564,7 +564,7 @@ - (BOOL)setFullscreenSpace:(BOOL)state
 {
     SDL_Window *window = _data.window;
     NSWindow *nswindow = _data.nswindow;
-    SDL_VideoData *videodata = window->driverdata.videodata;
+    SDL_CocoaVideoData *videodata = ((__bridge SDL_CocoaWindowData *)window->driverdata).videodata;
 
     if (!videodata.allow_spaces) {
         return NO; /* Spaces are forcibly disabled. */
@@ -1198,7 +1198,7 @@ static int Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL_
     //  the position in the currently-focused window. We don't (currently) send a mousemove
     //  event for the background window, this just makes sure the button is reported at the
     //  correct position in its own event.
-    if (focus && ([theEvent window] == focus->driverdata.nswindow)) {
+    if (focus && ([theEvent window] == ((__bridge SDL_CocoaWindowData *)focus->driverdata).nswindow)) {
         rc = SDL_SendMouseButtonClicks(Cocoa_GetEventTimestamp([theEvent timestamp]), window, mouseID, state, button, clicks);
     } else {
         const int orig_x = mouse->x;
@@ -1384,7 +1384,7 @@ - (void)scrollWheel:(NSEvent *)theEvent
 - (BOOL)isTouchFromTrackpad:(NSEvent *)theEvent
 {
     SDL_Window *window = _data.window;
-    SDL_VideoData *videodata = window->driverdata.videodata;
+    SDL_CocoaVideoData *videodata = ((__bridge SDL_CocoaWindowData *)window->driverdata).videodata;
 
     /* if this a MacBook trackpad, we'll make input look like a synthesized
        event. This is backwards from reality, but better matches user
@@ -1573,7 +1573,7 @@ - (void)updateLayer
        white until the app is ready to draw. In practice on modern macOS, this
        only gets called for window creation and other extraordinary events. */
     self.layer.backgroundColor = CGColorGetConstantColor(kCGColorBlack);
-    ScheduleContextUpdates(_sdlWindow->driverdata);
+    ScheduleContextUpdates((__bridge SDL_CocoaWindowData *)_sdlWindow->driverdata);
     SDL_SendWindowEvent(_sdlWindow, SDL_EVENT_WINDOW_EXPOSED, 0, 0);
 }
 
@@ -1604,11 +1604,11 @@ - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
 static int SetupWindowData(_THIS, SDL_Window *window, NSWindow *nswindow, NSView *nsview, SDL_bool created)
 {
     @autoreleasepool {
-        SDL_VideoData *videodata = _this->driverdata;
-        SDL_WindowData *data;
+        SDL_CocoaVideoData *videodata = (__bridge SDL_CocoaVideoData *)_this->driverdata;
+        SDL_CocoaWindowData *data;
 
         /* Allocate the window data */
-        data = [[SDL_WindowData alloc] init];
+        data = [[SDL_CocoaWindowData alloc] init];
         if (!data) {
             return SDL_OutOfMemory();
         }
@@ -1679,7 +1679,7 @@ static int SetupWindowData(_THIS, SDL_Window *window, NSWindow *nswindow, NSView
             SDL_SetKeyboardFocus(data.window);
         }
 
-        /* SDL_WindowData will be holding a strong reference to the NSWindow, and
+        /* SDL_CocoaWindowData will be holding a strong reference to the NSWindow, and
          * it will also call [NSWindow close] in DestroyWindow before releasing the
          * NSWindow, so the extra release provided by releasedWhenClosed isn't
          * necessary. */
@@ -1691,7 +1691,7 @@ static int SetupWindowData(_THIS, SDL_Window *window, NSWindow *nswindow, NSView
         [nswindow setOneShot:NO];
 
         /* All done! */
-        window->driverdata = data;
+        window->driverdata = (SDL_WindowData *)CFBridgingRetain(data);
         return 0;
     }
 }
@@ -1699,7 +1699,7 @@ static int SetupWindowData(_THIS, SDL_Window *window, NSWindow *nswindow, NSView
 int Cocoa_CreateWindow(_THIS, SDL_Window *window)
 {
     @autoreleasepool {
-        SDL_VideoData *videodata = _this->driverdata;
+        SDL_CocoaVideoData *videodata = (__bridge SDL_CocoaVideoData *)_this->driverdata;
         NSWindow *nswindow;
         SDL_VideoDisplay *display = SDL_GetVideoDisplayForWindow(window);
         NSRect rect;
@@ -1868,7 +1868,7 @@ void Cocoa_SetWindowTitle(_THIS, SDL_Window *window)
 {
     @autoreleasepool {
         const char *title = window->title ? window->title : "";
-        NSWindow *nswindow = window->driverdata.nswindow;
+        NSWindow *nswindow = ((__bridge SDL_CocoaWindowData *)window->driverdata).nswindow;
         NSString *string = [[NSString alloc] initWithUTF8String:title];
         [nswindow setTitle:string];
     }
@@ -1892,7 +1892,7 @@ int Cocoa_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon)
 void Cocoa_SetWindowPosition(_THIS, SDL_Window *window)
 {
     @autoreleasepool {
-        SDL_WindowData *windata = window->driverdata;
+        SDL_CocoaWindowData *windata = (__bridge SDL_CocoaW

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