فهرست منبع

macOS: always use Objective-C ARC (automatic ref counting).

Change Cocoa SDL_VideoData and SDL_WindowData implementations from C structs to Objective-C objects, since bridging between C and ObjC is easier that way.
Alex Szpakowski 2 سال پیش
والد
کامیت
ec8fa57750

+ 1 - 1
CMakeLists.txt

@@ -2902,7 +2902,7 @@ if(ANDROID)
   target_include_directories(sdl-build-options INTERFACE "${ANDROID_NDK}/sources/android/cpufeatures")
 endif()
 
-if(IOS OR TVOS)
+if(APPLE)
   target_compile_options(sdl-build-options INTERFACE "-fobjc-arc")
 endif()
 

+ 5 - 3
Xcode/SDL/SDL.xcodeproj/project.pbxproj

@@ -3469,13 +3469,13 @@
 		F395C1A22569C68F00942BFF /* SDL_iokitjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */; };
 		F395C1A32569C68F00942BFF /* SDL_iokitjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */; };
 		F395C1A42569C68F00942BFF /* SDL_iokitjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */; };
-		F395C1B12569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
+		F395C1B12569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; };
 		F395C1B22569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; };
 		F395C1B32569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; };
-		F395C1B42569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
+		F395C1B42569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; };
 		F395C1B52569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; };
 		F395C1B62569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; };
-		F395C1B72569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
+		F395C1B72569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; };
 		F395C1B82569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; };
 		F395C1B92569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; };
 		F395C1BA2569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1B02569C6A000942BFF /* SDL_mfijoystick_c.h */; };
@@ -9188,6 +9188,7 @@
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
 				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
 				CLANG_WARN_BOOL_CONVERSION = YES;
 				CLANG_WARN_COMMA = YES;
@@ -9273,6 +9274,7 @@
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
 				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
 				CLANG_WARN_BOOL_CONVERSION = YES;
 				CLANG_WARN_COMMA = YES;

+ 2 - 0
Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj

@@ -4041,6 +4041,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ENABLE_OBJC_ARC = YES;
 				FRAMEWORK_SEARCH_PATHS = (
 					"$(SRCROOT)/../SDL/build/$(CONFIGURATION)",
 					"$(HOME)/Library/Frameworks",
@@ -4168,6 +4169,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ENABLE_OBJC_ARC = YES;
 				FRAMEWORK_SEARCH_PATHS = (
 					"$(SRCROOT)/../SDL/build/$(CONFIGURATION)",
 					"$(HOME)/Library/Frameworks",

+ 1 - 89
src/render/metal/SDL_render_metal.m

@@ -142,24 +142,6 @@ typedef struct METAL_ShaderPipelines
 @end
 
 @implementation METAL_RenderData
-#if !__has_feature(objc_arc)
-- (void)dealloc
-{
-    [_mtldevice release];
-    [_mtlcmdqueue release];
-    [_mtlcmdbuffer release];
-    [_mtlcmdencoder release];
-    [_mtllibrary release];
-    [_mtlbackbuffer release];
-    [_mtlsamplernearest release];
-    [_mtlsamplerlinear release];
-    [_mtlbufconstants release];
-    [_mtlbufquadindices release];
-    [_mtllayer release];
-    [_mtlpassdesc release];
-    [super dealloc];
-}
-#endif
 @end
 
 @interface METAL_TextureData : NSObject
@@ -178,16 +160,6 @@ typedef struct METAL_ShaderPipelines
 @end
 
 @implementation METAL_TextureData
-#if !__has_feature(objc_arc)
-- (void)dealloc
-{
-    [_mtltexture release];
-    [_mtltexture_uv release];
-    [_mtlsampler release];
-    [_lockedbuffer release];
-    [super dealloc];
-}
-#endif
 @end
 
 static int
@@ -342,13 +314,6 @@ MakePipelineState(METAL_RenderData *data, METAL_PipelineCache *cache,
 
     METAL_PipelineState *states = SDL_realloc(cache->states, (cache->count + 1) * sizeof(pipeline));
 
-#if !__has_feature(objc_arc)
-    [mtlpipedesc release];  // !!! FIXME: can these be reused for each creation, or does the pipeline obtain it?
-    [mtlvertfn release];
-    [mtlfragfn release];
-    [state release];
-#endif
-
     if (states) {
         states[cache->count++] = pipeline;
         cache->states = states;
@@ -632,9 +597,6 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
     if (yuv || nv12) {
         mtltexture_uv = [data.mtldevice newTextureWithDescriptor:mtltexdesc];
         if (mtltexture_uv == nil) {
-#if !__has_feature(objc_arc)
-            [mtltexture release];
-#endif
             return SDL_SetError("Texture allocation failed");
         }
     }
@@ -677,12 +639,6 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
 #endif
     texture->driverdata = (void*)CFBridgingRetain(texturedata);
 
-#if !__has_feature(objc_arc)
-    [texturedata release];
-    [mtltexture release];
-    [mtltexture_uv release];
-#endif
-
     return 0;
 }}
 
@@ -742,10 +698,6 @@ METAL_UpdateTextureInternal(SDL_Renderer * renderer, METAL_TextureData *textured
         return SDL_OutOfMemory();
     }
 
-#if !__has_feature(objc_arc)
-    [stagingtex autorelease];
-#endif
-
     METAL_UploadTextureData(stagingtex, stagingrect, 0, pixels, pitch);
 
     if (data.mtlcmdencoder != nil) {
@@ -917,11 +869,6 @@ METAL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
     texturedata.lockedbuffer = lockedbuffer;
     *pixels = [lockedbuffer contents];
 
-    /* METAL_TextureData.lockedbuffer retains. */
-#if !__has_feature(objc_arc)
-    [lockedbuffer release];
-#endif
-
     return 0;
 }}
 
@@ -1209,13 +1156,8 @@ METAL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture
 
 typedef struct
 {
-    #if __has_feature(objc_arc)
     __unsafe_unretained id<MTLRenderPipelineState> pipeline;
     __unsafe_unretained id<MTLBuffer> vertex_buffer;
-    #else
-    id<MTLRenderPipelineState> pipeline;
-    id<MTLBuffer> vertex_buffer;
-    #endif
     size_t constants_offset;
     SDL_Texture *texture;
     SDL_bool cliprect_dirty;
@@ -1365,9 +1307,6 @@ METAL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
          * TODO: this buffer is also used for constants. Is performance still
          * good for those, or should we have a managed buffer for them? */
         mtlbufvertex = [data.mtldevice newBufferWithLength:vertsize options:MTLResourceStorageModeShared];
-        #if !__has_feature(objc_arc)
-        [mtlbufvertex autorelease];
-        #endif
         mtlbufvertex.label = @"SDL vertex data";
         SDL_memcpy([mtlbufvertex contents], vertices, vertsize);
 
@@ -1711,9 +1650,6 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
     }
 
     if (view == NULL) {
-#if !__has_feature(objc_arc)
-        [mtldevice release];
-#endif
         SDL_free(renderer);
         if (changed_window) {
             SDL_RecreateWindow(window, window_flags);
@@ -1725,9 +1661,6 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
     data = [[METAL_RenderData alloc] init];
 
     if (data == nil) {
-#if !__has_feature(objc_arc)
-        [mtldevice release];
-#endif
         /* Release the metal view instead of destroying it,
            in case we want to use it later (recreating the renderer)
          */
@@ -1746,7 +1679,7 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
     data.mtlview = view;
 
 #ifdef __MACOSX__
-    layer = (CAMetalLayer *)[(NSView *)view layer];
+    layer = (CAMetalLayer *)[(__bridge NSView *)view layer];
 #else
     layer = (CAMetalLayer *)[(__bridge UIView *)view layer];
 #endif
@@ -1771,9 +1704,6 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
     id<MTLLibrary> mtllibrary = [data.mtldevice newLibraryWithData:mtllibdata error:&err];
     data.mtllibrary = mtllibrary;
     SDL_assert(err == nil);
-#if !__has_feature(objc_arc)
-    dispatch_release(mtllibdata);
-#endif
     data.mtllibrary.label = @"SDL Metal renderer shader library";
 
     /* Do some shader pipeline state loading up-front rather than on demand. */
@@ -1831,9 +1761,6 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
     };
 
     id<MTLBuffer> mtlbufconstantstaging = [data.mtldevice newBufferWithLength:CONSTANTS_LENGTH options:MTLResourceStorageModeShared];
-    #if !__has_feature(objc_arc)
-    [mtlbufconstantstaging autorelease];
-    #endif
 
     char *constantdata = [mtlbufconstantstaging contents];
     SDL_memcpy(constantdata + CONSTANTS_OFFSET_IDENTITY, identitytransform, sizeof(identitytransform));
@@ -1845,9 +1772,6 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
     int quadcount = UINT16_MAX / 4;
     size_t indicessize = sizeof(UInt16) * quadcount * 6;
     id<MTLBuffer> mtlbufquadindicesstaging = [data.mtldevice newBufferWithLength:indicessize options:MTLResourceStorageModeShared];
-#if !__has_feature(objc_arc)
-    [mtlbufquadindicesstaging autorelease];
-#endif
 
     /* Quads in the following vertex order (matches the FillRects vertices):
      * 1---3
@@ -1965,18 +1889,6 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
     renderer->info.max_texture_width = maxtexsize;
     renderer->info.max_texture_height = maxtexsize;
 
-#if !__has_feature(objc_arc)
-    [mtlcmdqueue release];
-    [mtllibrary release];
-    [samplerdesc release];
-    [mtlsamplernearest release];
-    [mtlsamplerlinear release];
-    [mtlbufconstants release];
-    [mtlbufquadindices release];
-    [data release];
-    [mtldevice release];
-#endif
-
     return renderer;
 }}
 

+ 2 - 2
src/video/cocoa/SDL_cocoaclipboard.h

@@ -24,12 +24,12 @@
 #define SDL_cocoaclipboard_h_
 
 /* Forward declaration */
-struct SDL_VideoData;
+@class SDL_VideoData;
 
 extern int Cocoa_SetClipboardText(_THIS, const char *text);
 extern char *Cocoa_GetClipboardText(_THIS);
 extern SDL_bool Cocoa_HasClipboardText(_THIS);
-extern void Cocoa_CheckClipboardUpdate(struct SDL_VideoData * data);
+extern void Cocoa_CheckClipboardUpdate(SDL_VideoData * data);
 
 #endif /* SDL_cocoaclipboard_h_ */
 

+ 6 - 6
src/video/cocoa/SDL_cocoaclipboard.m

@@ -29,7 +29,7 @@ int
 Cocoa_SetClipboardText(_THIS, const char *text)
 { @autoreleasepool
 {
-    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+    SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata;
     NSPasteboard *pasteboard;
     NSString *format = NSPasteboardTypeString;
     NSString *nsstr = [NSString stringWithUTF8String:text];
@@ -38,7 +38,7 @@ Cocoa_SetClipboardText(_THIS, const char *text)
     }
 
     pasteboard = [NSPasteboard generalPasteboard];
-    data->clipboard_count = [pasteboard declareTypes:[NSArray arrayWithObject:format] owner:nil];
+    data.clipboard_count = [pasteboard declareTypes:[NSArray arrayWithObject:format] owner:nil];
     [pasteboard setString:nsstr forType:format];
 
     return 0;
@@ -86,7 +86,7 @@ Cocoa_HasClipboardText(_THIS)
 }
 
 void
-Cocoa_CheckClipboardUpdate(struct SDL_VideoData * data)
+Cocoa_CheckClipboardUpdate(SDL_VideoData * data)
 { @autoreleasepool
 {
     NSPasteboard *pasteboard;
@@ -94,11 +94,11 @@ Cocoa_CheckClipboardUpdate(struct SDL_VideoData * data)
 
     pasteboard = [NSPasteboard generalPasteboard];
     count = [pasteboard changeCount];
-    if (count != data->clipboard_count) {
-        if (data->clipboard_count) {
+    if (count != data.clipboard_count) {
+        if (data.clipboard_count) {
             SDL_SendClipboardUpdate();
         }
-        data->clipboard_count = count;
+        data.clipboard_count = count;
     }
 }}
 

+ 11 - 22
src/video/cocoa/SDL_cocoaevents.m

@@ -45,7 +45,7 @@ static SDL_Window *FindSDLWindowForNSWindow(NSWindow *win)
     SDL_VideoDevice *device = SDL_GetVideoDevice();
     if (device && device->windows) {
         for (sdlwindow = device->windows; sdlwindow; sdlwindow = sdlwindow->next) {
-            NSWindow *nswindow = ((SDL_WindowData *) sdlwindow->driverdata)->nswindow;
+            NSWindow *nswindow = ((__bridge SDL_WindowData *) sdlwindow->driverdata).nswindow;
             if (win == nswindow)
                 return sdlwindow;
         }
@@ -121,7 +121,6 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
                                  [NSNumber numberWithBool:YES], @"ApplePersistenceIgnoreState",
                                  nil];
     [[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
-    [appDefaults release];
 }
 
 @end // SDLApplication
@@ -182,8 +181,6 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
             removeEventHandlerForEventClass:kInternetEventClass
                                  andEventID:kAEGetURL];
     }
-
-    [super dealloc];
 }
 
 - (void)windowWillClose:(NSNotification *)notification;
@@ -374,9 +371,6 @@ CreateApplicationMenus(void)
     /* Create the main menu bar */
     [NSApp setMainMenu:mainMenu];
 
-    [mainMenu release];  /* we're done with it, let NSApp own it. */
-    mainMenu = nil;
-
     /* Create the application menu */
     appName = GetApplicationName();
     appleMenu = [[NSMenu alloc] initWithTitle:@""];
@@ -396,7 +390,6 @@ CreateApplicationMenus(void)
     [menuItem setSubmenu:serviceMenu];
 
     [NSApp setServicesMenu:serviceMenu];
-    [serviceMenu release];
 
     [appleMenu addItem:[NSMenuItem separatorItem]];
 
@@ -417,12 +410,9 @@ CreateApplicationMenus(void)
     menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
     [menuItem setSubmenu:appleMenu];
     [[NSApp mainMenu] addItem:menuItem];
-    [menuItem release];
 
     /* Tell the application object that this is now the application menu */
     [NSApp setAppleMenu:appleMenu];
-    [appleMenu release];
-
 
     /* Create the window menu */
     windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
@@ -442,18 +432,15 @@ CreateApplicationMenus(void)
         menuItem = [[NSMenuItem alloc] initWithTitle:@"Toggle Full Screen" action:@selector(toggleFullScreen:) keyEquivalent:@"f"];
         [menuItem setKeyEquivalentModifierMask:NSEventModifierFlagControl | NSEventModifierFlagCommand];
         [windowMenu addItem:menuItem];
-        [menuItem release];
     }
 
     /* Put menu into the menubar */
     menuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
     [menuItem setSubmenu:windowMenu];
     [[NSApp mainMenu] addItem:menuItem];
-    [menuItem release];
 
     /* Tell the application object that this is now the window menu */
     [NSApp setWindowsMenu:windowMenu];
-    [windowMenu release];
 }
 
 void
@@ -576,7 +563,7 @@ Cocoa_PumpEvents(_THIS)
 void Cocoa_SendWakeupEvent(_THIS, SDL_Window *window)
 { @autoreleasepool
 {
-    NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
+    NSWindow *nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow;
 
     NSEvent* event = [NSEvent otherEventWithType: NSEventTypeApplicationDefined
                                     location: NSMakePoint(0,0)
@@ -595,15 +582,15 @@ void
 Cocoa_SuspendScreenSaver(_THIS)
 { @autoreleasepool
 {
-    SDL_VideoData *data = (SDL_VideoData *)_this->driverdata;
+    SDL_VideoData *data = (__bridge SDL_VideoData *)_this->driverdata;
 
-    if (!data->screensaver_use_iopm) {
+    if (!data.screensaver_use_iopm) {
         return;
     }
 
-    if (data->screensaver_assertion) {
-        IOPMAssertionRelease(data->screensaver_assertion);
-        data->screensaver_assertion = 0;
+    if (data.screensaver_assertion) {
+        IOPMAssertionRelease(data.screensaver_assertion);
+        data.screensaver_assertion = kIOPMNullAssertionID;
     }
 
     if (_this->suspend_screensaver) {
@@ -612,11 +599,13 @@ Cocoa_SuspendScreenSaver(_THIS)
          * seen by OS X power users. there's an additional optional human-readable
          * (localized) reason parameter which we don't set.
          */
+        IOPMAssertionID assertion = kIOPMNullAssertionID;
         NSString *name = [GetApplicationName() stringByAppendingString:@" using SDL_DisableScreenSaver"];
         IOPMAssertionCreateWithDescription(kIOPMAssertPreventUserIdleDisplaySleep,
-                                           (CFStringRef) name,
+                                           (__bridge CFStringRef) name,
                                            NULL, NULL, NULL, 0, NULL,
-                                           &data->screensaver_assertion);
+                                           &assertion);
+        data.screensaver_assertion = assertion;
     }
 }}
 

+ 26 - 29
src/video/cocoa/SDL_cocoakeyboard.m

@@ -104,8 +104,7 @@
     }
 
     if (_markedText != aString) {
-        [_markedText release];
-        _markedText = [aString retain];
+        _markedText = aString;
     }
 
     _selectedRange = selectedRange;
@@ -120,7 +119,6 @@
 
 - (void)unmarkText
 {
-    [_markedText release];
     _markedText = nil;
 
     SDL_SendEditingText("", 0, 0);
@@ -381,14 +379,14 @@ DoSidedModifiers(unsigned short scancode,
 static void
 HandleModifiers(_THIS, unsigned short scancode, unsigned int modifierFlags)
 {
-    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+    SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata;
 
-    if (modifierFlags == data->modifierFlags) {
+    if (modifierFlags == data.modifierFlags) {
         return;
     }
 
-    DoSidedModifiers(scancode, data->modifierFlags, modifierFlags);
-    data->modifierFlags = modifierFlags;
+    DoSidedModifiers(scancode, data.modifierFlags, modifierFlags);
+    data.modifierFlags = modifierFlags;
 }
 
 static void
@@ -402,10 +400,10 @@ UpdateKeymap(SDL_VideoData *data, SDL_bool send_event)
 
     /* See if the keymap needs to be updated */
     key_layout = TISCopyCurrentKeyboardLayoutInputSource();
-    if (key_layout == data->key_layout) {
+    if (key_layout == data.key_layout) {
         return;
     }
-    data->key_layout = key_layout;
+    data.key_layout = key_layout;
 
     SDL_GetDefaultKeymap(keymap);
 
@@ -461,7 +459,7 @@ cleanup:
 void
 Cocoa_InitKeyboard(_THIS)
 {
-    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+    SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata;
 
     UpdateKeymap(data, SDL_FALSE);
 
@@ -473,19 +471,19 @@ Cocoa_InitKeyboard(_THIS)
     SDL_SetScancodeName(SDL_SCANCODE_RALT, "Right Option");
     SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Command");
 
-    data->modifierFlags = (unsigned int)[NSEvent modifierFlags];
-    SDL_ToggleModState(KMOD_CAPS, (data->modifierFlags & NSEventModifierFlagCapsLock) != 0);
+    data.modifierFlags = (unsigned int)[NSEvent modifierFlags];
+    SDL_ToggleModState(KMOD_CAPS, (data.modifierFlags & NSEventModifierFlagCapsLock) != 0);
 }
 
 void
 Cocoa_StartTextInput(_THIS)
 { @autoreleasepool
 {
-    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+    SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata;
     SDL_Window *window = SDL_GetKeyboardFocus();
     NSWindow *nswindow = nil;
     if (window) {
-        nswindow = ((SDL_WindowData*)window->driverdata)->nswindow;
+        nswindow = ((__bridge SDL_WindowData*)window->driverdata).nswindow;
     }
 
     NSView *parentView = [nswindow contentView];
@@ -495,16 +493,16 @@ Cocoa_StartTextInput(_THIS)
      * than one copy. When we switched to another window and requesting for
      * text input, simply remove the field editor from its superview then add
      * it to the front most window's content view */
-    if (!data->fieldEdit) {
-        data->fieldEdit =
+    if (!data.fieldEdit) {
+        data.fieldEdit =
             [[SDLTranslatorResponder alloc] initWithFrame: NSMakeRect(0.0, 0.0, 0.0, 0.0)];
     }
 
-    if (![[data->fieldEdit superview] isEqual:parentView]) {
+    if (![[data.fieldEdit superview] isEqual:parentView]) {
         /* DEBUG_IME(@"add fieldEdit to window contentView"); */
-        [data->fieldEdit removeFromSuperview];
-        [parentView addSubview: data->fieldEdit];
-        [nswindow makeFirstResponder: data->fieldEdit];
+        [data.fieldEdit removeFromSuperview];
+        [parentView addSubview: data.fieldEdit];
+        [nswindow makeFirstResponder: data.fieldEdit];
     }
 }}
 
@@ -512,32 +510,31 @@ void
 Cocoa_StopTextInput(_THIS)
 { @autoreleasepool
 {
-    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+    SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata;
 
-    if (data && data->fieldEdit) {
-        [data->fieldEdit removeFromSuperview];
-        [data->fieldEdit release];
-        data->fieldEdit = nil;
+    if (data && data.fieldEdit) {
+        [data.fieldEdit removeFromSuperview];
+        data.fieldEdit = nil;
     }
 }}
 
 void
 Cocoa_SetTextInputRect(_THIS, SDL_Rect *rect)
 {
-    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+    SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata;
 
     if (!rect) {
         SDL_InvalidParamError("rect");
         return;
     }
 
-    [data->fieldEdit setInputRect:rect];
+    [data.fieldEdit setInputRect:rect];
 }
 
 void
 Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
 {
-    SDL_VideoData *data = _this ? ((SDL_VideoData *) _this->driverdata) : NULL;
+    SDL_VideoData *data = _this ? ((__bridge SDL_VideoData *) _this->driverdata) : nil;
     if (!data) {
         return;  /* can happen when returning from fullscreen Space on shutdown */
     }
@@ -575,7 +572,7 @@ Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
 #endif
         if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
             /* FIXME CW 2007-08-16: only send those events to the field editor for which we actually want text events, not e.g. esc or function keys. Arrow keys in particular seem to produce crashes sometimes. */
-            [data->fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]];
+            [data.fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]];
 #if 0
             text = [[event characters] UTF8String];
             if(text && *text) {

+ 6 - 6
src/video/cocoa/SDL_cocoamessagebox.m

@@ -45,9 +45,9 @@
 
         /* Retain the NSWindow because we'll show the alert later on the main thread */
         if (window) {
-            nswindow = [((SDL_WindowData *) window->driverdata)->nswindow retain];
+            nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow;
         } else {
-            nswindow = NULL;
+            nswindow = nil;
         }
     }
 
@@ -60,7 +60,7 @@
 #ifdef MAC_OS_X_VERSION_10_9
         if ([alert respondsToSelector:@selector(beginSheetModalForWindow:completionHandler:)]) {
             [alert beginSheetModalForWindow:nswindow completionHandler:^(NSModalResponse returnCode) {
-                clicked = returnCode;
+                self->clicked = returnCode;
             }];
         } else
 #endif
@@ -75,7 +75,7 @@
             SDL_Delay(100);
         }
 
-        [nswindow release];
+        nswindow = nil;
     } else {
         clicked = [alert runModal];
     }
@@ -94,7 +94,7 @@ Cocoa_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonid
 {
     Cocoa_RegisterApp();
 
-    NSAlert* alert = [[[NSAlert alloc] init] autorelease];
+    NSAlert* alert = [[NSAlert alloc] init];
 
     if (messageboxdata->flags & SDL_MESSAGEBOX_ERROR) {
         [alert setAlertStyle:NSAlertStyleCritical];
@@ -129,7 +129,7 @@ Cocoa_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonid
         }
     }
 
-    SDLMessageBoxPresenter* presenter = [[[SDLMessageBoxPresenter alloc] initWithParentWindow:messageboxdata->window] autorelease];
+    SDLMessageBoxPresenter* presenter = [[SDLMessageBoxPresenter alloc] initWithParentWindow:messageboxdata->window];
 
     [presenter showAlert:alert];
 

+ 4 - 6
src/video/cocoa/SDL_cocoametalview.m

@@ -89,7 +89,7 @@ SDL_MetalViewEventWatch(void *userdata, SDL_Event *event)
         /* Allow resize. */
         self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
 
-        SDL_AddEventWatch(SDL_MetalViewEventWatch, self);
+        SDL_AddEventWatch(SDL_MetalViewEventWatch, (__bridge void *)(self));
 
         [self updateDrawableSize];
     }
@@ -99,8 +99,7 @@ SDL_MetalViewEventWatch(void *userdata, SDL_Event *event)
 
 - (void)dealloc
 {
-    SDL_DelEventWatch(SDL_MetalViewEventWatch, self);
-    [super dealloc];
+    SDL_DelEventWatch(SDL_MetalViewEventWatch, (__bridge void *)(self));
 }
 
 - (NSInteger)tag
@@ -135,7 +134,7 @@ SDL_MetalView
 Cocoa_Metal_CreateView(_THIS, SDL_Window * window)
 { @autoreleasepool {
     SDL_WindowData* data = (__bridge SDL_WindowData *)window->driverdata;
-    NSView *view = data->nswindow.contentView;
+    NSView *view = data.nswindow.contentView;
     BOOL highDPI = (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) != 0;
     Uint32 windowID = SDL_GetWindowID(window);
     SDL_cocoametalview *newview;
@@ -151,7 +150,6 @@ Cocoa_Metal_CreateView(_THIS, SDL_Window * window)
     [view addSubview:newview];
 
     metalview = (SDL_MetalView)CFBridgingRetain(newview);
-    [newview release];
 
     return metalview;
 }}
@@ -174,7 +172,7 @@ void
 Cocoa_Metal_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
 { @autoreleasepool {
     SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
-    NSView *contentView = data->sdlContentView;
+    NSView *contentView = data.sdlContentView;
     SDL_cocoametalview* metalview = [contentView viewWithTag:SDL_METALVIEW_TAG];
     if (metalview) {
         CAMetalLayer *layer = (CAMetalLayer*)metalview.layer;

+ 1 - 1
src/video/cocoa/SDL_cocoamodes.m

@@ -306,7 +306,7 @@ Cocoa_GetDisplayName(CGDirectDisplayID displayID)
     /* This API is deprecated in 10.9 with no good replacement (as of 10.15). */
     io_service_t servicePort = CGDisplayIOServicePort(displayID);
     CFDictionaryRef deviceInfo = IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName);
-    NSDictionary *localizedNames = [(NSDictionary *)deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]];
+    NSDictionary *localizedNames = [(__bridge NSDictionary *)deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]];
     const char* displayName = NULL;
 
     if ([localizedNames count] > 0) {

+ 18 - 24
src/video/cocoa/SDL_cocoamouse.m

@@ -53,7 +53,7 @@
         NSData *cursorData = [NSData dataWithBytesNoCopy:&cursorBytes[0]
                                                   length:sizeof(cursorBytes)
                                             freeWhenDone:NO];
-        NSImage *cursorImage = [[[NSImage alloc] initWithData:cursorData] autorelease];
+        NSImage *cursorImage = [[NSImage alloc] initWithData:cursorData];
         invisibleCursor = [[NSCursor alloc] initWithImage:cursorImage
                                                   hotSpot:NSZeroPoint];
     }
@@ -75,8 +75,7 @@ Cocoa_CreateDefaultCursor()
     if (nscursor) {
         cursor = SDL_calloc(1, sizeof(*cursor));
         if (cursor) {
-            cursor->driverdata = nscursor;
-            [nscursor retain];
+            cursor->driverdata = (void *)CFBridgingRetain(nscursor);
         }
     }
 
@@ -99,9 +98,7 @@ Cocoa_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
     if (nscursor) {
         cursor = SDL_calloc(1, sizeof(*cursor));
         if (cursor) {
-            cursor->driverdata = nscursor;
-        } else {
-            [nscursor release];
+            cursor->driverdata = (void *)CFBridgingRetain(nscursor);
         }
     }
 
@@ -159,8 +156,7 @@ Cocoa_CreateSystemCursor(SDL_SystemCursor id)
         cursor = SDL_calloc(1, sizeof(*cursor));
         if (cursor) {
             /* We'll free it later, so retain it here */
-            [nscursor retain];
-            cursor->driverdata = nscursor;
+            cursor->driverdata = (void *)CFBridgingRetain(nscursor);
         }
     }
 
@@ -171,9 +167,7 @@ static void
 Cocoa_FreeCursor(SDL_Cursor * cursor)
 { @autoreleasepool
 {
-    NSCursor *nscursor = (NSCursor *)cursor->driverdata;
-
-    [nscursor release];
+    CFBridgingRelease(cursor->driverdata);
     SDL_free(cursor);
 }}
 
@@ -184,11 +178,11 @@ Cocoa_ShowCursor(SDL_Cursor * cursor)
     SDL_VideoDevice *device = SDL_GetVideoDevice();
     SDL_Window *window = (device ? device->windows : NULL);
     for (; window != NULL; window = window->next) {
-        SDL_WindowData *driverdata = (SDL_WindowData *)window->driverdata;
+        SDL_WindowData *driverdata = (__bridge SDL_WindowData *)window->driverdata;
         if (driverdata) {
-            [driverdata->nswindow performSelectorOnMainThread:@selector(invalidateCursorRectsForView:)
-                                                   withObject:[driverdata->nswindow contentView]
-                                                waitUntilDone:NO];
+            [driverdata.nswindow performSelectorOnMainThread:@selector(invalidateCursorRectsForView:)
+                                                  withObject:[driverdata.nswindow contentView]
+                                               waitUntilDone:NO];
         }
     }
     return 0;
@@ -214,10 +208,10 @@ Cocoa_WarpMouseGlobal(int x, int y)
 {
     SDL_Mouse *mouse = SDL_GetMouse();
     if (mouse->focus) {
-        SDL_WindowData *data = (SDL_WindowData *) mouse->focus->driverdata;
-        if ([data->listener isMovingOrFocusClickPending]) {
+        SDL_WindowData *data = (__bridge SDL_WindowData *) mouse->focus->driverdata;
+        if ([data.listener isMovingOrFocusClickPending]) {
             DLog("Postponing warp, window being moved or focused.");
-            [data->listener setPendingMoveX:x Y:y];
+            [data.listener setPendingMoveX:x Y:y];
             return 0;
         }
     }
@@ -282,8 +276,8 @@ 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.
      */
-    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
-    if ([data->listener isMovingOrFocusClickPending]) {
+    SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+    if ([data.listener isMovingOrFocusClickPending]) {
         return 0;
     }
 
@@ -360,18 +354,18 @@ Cocoa_HandleTitleButtonEvent(_THIS, NSEvent *event)
     NSWindow *nswindow = [event window];
 
     for (window = _this->windows; window; window = window->next) {
-        SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
-        if (data && data->nswindow == nswindow) {
+        SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
+        if (data && data.nswindow == nswindow) {
             switch ([event type]) {
             case NSEventTypeLeftMouseDown:
             case NSEventTypeRightMouseDown:
             case NSEventTypeOtherMouseDown:
-                [data->listener setFocusClickPending:[event buttonNumber]];
+                [data.listener setFocusClickPending:[event buttonNumber]];
                 break;
             case NSEventTypeLeftMouseUp:
             case NSEventTypeRightMouseUp:
             case NSEventTypeOtherMouseUp:
-                [data->listener clearFocusClickPending:[event buttonNumber]];
+                [data.listener clearFocusClickPending:[event buttonNumber]];
                 break;
             default:
                 break;

+ 28 - 28
src/video/cocoa/SDL_cocoaopengl.m

@@ -82,10 +82,10 @@
 - (void)setWindow:(SDL_Window *)newWindow
 {
     if (self->window) {
-        SDL_WindowData *oldwindowdata = (SDL_WindowData *)self->window->driverdata;
+        SDL_WindowData *oldwindowdata = (__bridge SDL_WindowData *)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;
+        NSMutableArray *contexts = oldwindowdata.nscontexts;
         @synchronized (contexts) {
             [contexts removeObject:self];
         }
@@ -94,11 +94,11 @@
     self->window = newWindow;
 
     if (newWindow) {
-        SDL_WindowData *windowdata = (SDL_WindowData *)newWindow->driverdata;
-        NSView *contentview = windowdata->sdlContentView;
+        SDL_WindowData *windowdata = (__bridge SDL_WindowData *)newWindow->driverdata;
+        NSView *contentview = windowdata.sdlContentView;
 
         /* Now sign up for scheduled updates for the new window. */
-        NSMutableArray *contexts = windowdata->nscontexts;
+        NSMutableArray *contexts = windowdata.nscontexts;
         @synchronized (contexts) {
             [contexts addObject:self];
         }
@@ -184,6 +184,7 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window)
     NSOpenGLPixelFormatAttribute attr[32];
     NSOpenGLPixelFormat *fmt;
     SDLOpenGLContext *context;
+    SDL_GLContext sdlcontext;
     NSOpenGLContext *share_context = nil;
     int i = 0;
     const char *glversion;
@@ -288,20 +289,20 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window)
     }
 
     if (_this->gl_config.share_with_current_context) {
-        share_context = (NSOpenGLContext*)SDL_GL_GetCurrentContext();
+        share_context = (__bridge NSOpenGLContext*)SDL_GL_GetCurrentContext();
     }
 
     context = [[SDLOpenGLContext alloc] initWithFormat:fmt shareContext:share_context];
 
-    [fmt release];
-
     if (context == nil) {
         SDL_SetError("Failed creating OpenGL context");
         return NULL;
     }
 
-    if ( Cocoa_GL_MakeCurrent(_this, window, context) < 0 ) {
-        Cocoa_GL_DeleteContext(_this, context);
+    sdlcontext = (SDL_GLContext)CFBridgingRetain(context);
+
+    if ( Cocoa_GL_MakeCurrent(_this, window, (__bridge SDL_GLContext)context) < 0 ) {
+        Cocoa_GL_DeleteContext(_this, (__bridge SDL_GLContext)context);
         SDL_SetError("Failed making OpenGL context current");
         return NULL;
     }
@@ -315,27 +316,27 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window)
 
         glGetStringFunc = (const GLubyte *(APIENTRY *)(GLenum)) SDL_GL_GetProcAddress("glGetString");
         if (!glGetStringFunc) {
-            Cocoa_GL_DeleteContext(_this, context);
+            Cocoa_GL_DeleteContext(_this, (__bridge SDL_GLContext)context);
             SDL_SetError ("Failed getting OpenGL glGetString entry point");
             return NULL;
         }
 
         glversion = (const char *)glGetStringFunc(GL_VERSION);
         if (glversion == NULL) {
-            Cocoa_GL_DeleteContext(_this, context);
+            Cocoa_GL_DeleteContext(_this, (__bridge SDL_GLContext)context);
             SDL_SetError ("Failed getting OpenGL context version");
             return NULL;
         }
 
         if (SDL_sscanf(glversion, "%d.%d", &glversion_major, &glversion_minor) != 2) {
-            Cocoa_GL_DeleteContext(_this, context);
+            Cocoa_GL_DeleteContext(_this, (__bridge SDL_GLContext)context);
             SDL_SetError ("Failed parsing OpenGL context version");
             return NULL;
         }
 
         if ((glversion_major < _this->gl_config.major_version) ||
            ((glversion_major == _this->gl_config.major_version) && (glversion_minor < _this->gl_config.minor_version))) {
-            Cocoa_GL_DeleteContext(_this, context);
+            Cocoa_GL_DeleteContext(_this, (__bridge SDL_GLContext)context);
             SDL_SetError ("Failed creating OpenGL context at version requested");
             return NULL;
         }
@@ -346,7 +347,7 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window)
         /*_this->gl_config.major_version = glversion_major;*/
         /*_this->gl_config.minor_version = glversion_minor;*/
     }
-    return context;
+    return sdlcontext;
 }}
 
 int
@@ -354,7 +355,7 @@ Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
 { @autoreleasepool
 {
     if (context) {
-        SDLOpenGLContext *nscontext = (SDLOpenGLContext *)context;
+        SDLOpenGLContext *nscontext = (__bridge SDLOpenGLContext *)context;
         if ([nscontext window] != window) {
             [nscontext setWindow:window];
             [nscontext updateIfNeeded];
@@ -369,9 +370,10 @@ Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
 
 void
 Cocoa_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
+{ @autoreleasepool
 {
-    SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
-    NSView *contentView = windata->sdlContentView;
+    SDL_WindowData *windata = (__bridge SDL_WindowData *) window->driverdata;
+    NSView *contentView = windata.sdlContentView;
     NSRect viewport = [contentView bounds];
 
     if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
@@ -389,7 +391,7 @@ Cocoa_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
     if (h) {
         *h = viewport.size.height;
     }
-}
+}}
 
 int
 Cocoa_GL_SetSwapInterval(_THIS, int interval)
@@ -403,7 +405,7 @@ Cocoa_GL_SetSwapInterval(_THIS, int interval)
         return SDL_SetError("Late swap tearing currently unsupported");
     }
 
-    nscontext = (NSOpenGLContext*)SDL_GL_GetCurrentContext();
+    nscontext = (__bridge NSOpenGLContext*)SDL_GL_GetCurrentContext();
     if (nscontext != nil) {
         value = interval;
         [nscontext setValues:&value forParameter:NSOpenGLCPSwapInterval];
@@ -423,7 +425,7 @@ Cocoa_GL_GetSwapInterval(_THIS)
     GLint value;
     int status = 0;
 
-    nscontext = (NSOpenGLContext*)SDL_GL_GetCurrentContext();
+    nscontext = (__bridge NSOpenGLContext*)SDL_GL_GetCurrentContext();
     if (nscontext != nil) {
         [nscontext getValues:&value forParameter:NSOpenGLCPSwapInterval];
         status = (int)value;
@@ -436,15 +438,15 @@ int
 Cocoa_GL_SwapWindow(_THIS, SDL_Window * window)
 { @autoreleasepool
 {
-    SDLOpenGLContext* nscontext = (SDLOpenGLContext*)SDL_GL_GetCurrentContext();
-    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+    SDLOpenGLContext* nscontext = (__bridge SDLOpenGLContext*)SDL_GL_GetCurrentContext();
+    SDL_VideoData *videodata = (__bridge SDL_VideoData *) _this->driverdata;
 
     /* on 10.14 ("Mojave") and later, this deadlocks if two contexts in two
        threads try to swap at the same time, so put a mutex around it. */
-    SDL_LockMutex(videodata->swaplock);
+    SDL_LockMutex(videodata.swaplock);
     [nscontext flushBuffer];
     [nscontext updateIfNeeded];
-    SDL_UnlockMutex(videodata->swaplock);
+    SDL_UnlockMutex(videodata.swaplock);
     return 0;
 }}
 
@@ -452,10 +454,8 @@ void
 Cocoa_GL_DeleteContext(_THIS, SDL_GLContext context)
 { @autoreleasepool
 {
-    SDLOpenGLContext *nscontext = (SDLOpenGLContext *)context;
-
+    SDLOpenGLContext *nscontext = (SDLOpenGLContext *)CFBridgingRelease(context);
     [nscontext setWindow:NULL];
-    [nscontext release];
 }}
 
 /* We still support OpenGL as long as Apple offers it, deprecated or not, so disable deprecation warnings about it. */

+ 25 - 12
src/video/cocoa/SDL_cocoaopengles.m

@@ -29,8 +29,8 @@
 /* EGL implementation of SDL OpenGL support */
 
 int
-Cocoa_GLES_LoadLibrary(_THIS, const char *path) {
-
+Cocoa_GLES_LoadLibrary(_THIS, const char *path)
+{
     /* If the profile requested is not GL ES, switch over to WIN_GL functions  */
     if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES) {
 #if SDL_VIDEO_OPENGL_CGL
@@ -59,9 +59,10 @@ Cocoa_GLES_LoadLibrary(_THIS, const char *path) {
 
 SDL_GLContext
 Cocoa_GLES_CreateContext(_THIS, SDL_Window * window)
+{ @autoreleasepool
 {
     SDL_GLContext context;
-    SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+    SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
 
 #if SDL_VIDEO_OPENGL_CGL
     if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES) {
@@ -85,25 +86,37 @@ Cocoa_GLES_CreateContext(_THIS, SDL_Window * window)
     }
 #endif
 
-    context = SDL_EGL_CreateContext(_this, data->egl_surface);
+    context = SDL_EGL_CreateContext(_this, data.egl_surface);
     return context;
-}
+}}
 
 void
 Cocoa_GLES_DeleteContext(_THIS, SDL_GLContext context)
+{ @autoreleasepool
 {
     SDL_EGL_DeleteContext(_this, context);
     Cocoa_GLES_UnloadLibrary(_this);
-}
+}}
 
-SDL_EGL_SwapWindow_impl(Cocoa)
-SDL_EGL_MakeCurrent_impl(Cocoa)
+int
+Cocoa_GLES_SwapWindow(_THIS, SDL_Window * window)
+{ @autoreleasepool
+{
+    return SDL_EGL_SwapBuffers(_this, ((__bridge SDL_WindowData *) window->driverdata).egl_surface);
+}}
+
+int
+Cocoa_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
+{ @autoreleasepool
+{
+    return SDL_EGL_MakeCurrent(_this, window ? ((__bridge SDL_WindowData *) window->driverdata).egl_surface : EGL_NO_SURFACE, context);
+}}
 
 int
 Cocoa_GLES_SetupWindow(_THIS, SDL_Window * window)
 {
     /* The current context is lost in here; save it and reset it. */
-    SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata;
+    SDL_WindowData *windowdata = (__bridge SDL_WindowData *) window->driverdata;
     SDL_Window *current_win = SDL_GL_GetCurrentWindow();
     SDL_GLContext current_ctx = SDL_GL_GetCurrentContext();
 
@@ -121,10 +134,10 @@ Cocoa_GLES_SetupWindow(_THIS, SDL_Window * window)
     }
   
     /* Create the GLES window surface */
-    NSView* v = windowdata->nswindow.contentView;
-    windowdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType)[v layer]);
+    NSView* v = windowdata.nswindow.contentView;
+    windowdata.egl_surface = SDL_EGL_CreateSurface(_this, (__bridge NativeWindowType)[v layer]);
 
-    if (windowdata->egl_surface == EGL_NO_SURFACE) {
+    if (windowdata.egl_surface == EGL_NO_SURFACE) {
         return SDL_SetError("Could not create GLES window surface");
     }
 

+ 9 - 8
src/video/cocoa/SDL_cocoashape.m

@@ -29,11 +29,12 @@
 
 SDL_WindowShaper*
 Cocoa_CreateShaper(SDL_Window* window)
+{ @autoreleasepool
 {
-    SDL_WindowData* windata = (SDL_WindowData*)window->driverdata;
-    [windata->nswindow setOpaque:NO];
+    SDL_WindowData* windata = (__bridge SDL_WindowData*)window->driverdata;
+    [windata.nswindow setOpaque:NO];
 
-    [windata->nswindow setStyleMask:NSWindowStyleMaskBorderless];
+    [windata.nswindow setStyleMask:NSWindowStyleMaskBorderless];
 
     SDL_WindowShaper* result = (SDL_WindowShaper *)SDL_malloc(sizeof(SDL_WindowShaper));
     result->window = window;
@@ -44,14 +45,14 @@ Cocoa_CreateShaper(SDL_Window* window)
 
     SDL_ShapeData* data = (SDL_ShapeData *)SDL_malloc(sizeof(SDL_ShapeData));
     result->driverdata = data;
-    data->context = [windata->nswindow graphicsContext];
+    data->context = [windata.nswindow graphicsContext];
     data->saved = SDL_FALSE;
     data->shape = NULL;
 
     int resized_properly = Cocoa_ResizeWindowShape(window);
     SDL_assert(resized_properly == 0);
     return result;
-}
+}}
 
 typedef struct {
     NSView* view;
@@ -74,7 +75,7 @@ Cocoa_SetWindowShape(SDL_WindowShaper *shaper, SDL_Surface *shape, SDL_WindowSha
 { @autoreleasepool
 {
     SDL_ShapeData* data = (SDL_ShapeData*)shaper->driverdata;
-    SDL_WindowData* windata = (SDL_WindowData*)shaper->window->driverdata;
+    SDL_WindowData* windata = (__bridge SDL_WindowData*)shaper->window->driverdata;
     SDL_CocoaClosure closure;
     if(data->saved == SDL_TRUE) {
         [data->context restoreGraphicsState];
@@ -86,10 +87,10 @@ Cocoa_SetWindowShape(SDL_WindowShaper *shaper, SDL_Surface *shape, SDL_WindowSha
     [NSGraphicsContext setCurrentContext:data->context];
 
     [[NSColor clearColor] set];
-    NSRectFill([windata->sdlContentView frame]);
+    NSRectFill([windata.sdlContentView frame]);
     data->shape = SDL_CalculateShapeTree(*shape_mode,shape);
 
-    closure.view = windata->sdlContentView;
+    closure.view = windata.sdlContentView;
     closure.path = [NSBezierPath bezierPath];
     closure.window = shaper->window;
     SDL_TraverseShapeTree(data->shape,&ConvertRects,&closure);

+ 11 - 12
src/video/cocoa/SDL_cocoavideo.h

@@ -97,18 +97,17 @@ DECLARE_ALERT_STYLE(Critical);
 
 @class SDLTranslatorResponder;
 
-typedef struct SDL_VideoData
-{
-    int allow_spaces;
-    unsigned int modifierFlags;
-    void *key_layout;
-    SDLTranslatorResponder *fieldEdit;
-    NSInteger clipboard_count;
-    Uint32 screensaver_activity;
-    BOOL screensaver_use_iopm;
-    IOPMAssertionID screensaver_assertion;
-    SDL_mutex *swaplock;
-} SDL_VideoData;
+@interface SDL_VideoData : NSObject
+    @property (nonatomic) int allow_spaces;
+    @property (nonatomic) unsigned int modifierFlags;
+    @property (nonatomic) void *key_layout;
+    @property (nonatomic) SDLTranslatorResponder *fieldEdit;
+    @property (nonatomic) NSInteger clipboard_count;
+    @property (nonatomic) Uint32 screensaver_activity;
+    @property (nonatomic) BOOL screensaver_use_iopm;
+    @property (nonatomic) IOPMAssertionID screensaver_assertion;
+    @property (nonatomic) SDL_mutex *swaplock;
+@end
 
 /* Utility functions */
 extern NSImage * Cocoa_CreateImage(SDL_Surface * surface);

+ 31 - 19
src/video/cocoa/SDL_cocoavideo.m

@@ -22,6 +22,10 @@
 
 #if SDL_VIDEO_DRIVER_COCOA
 
+#if !__has_feature(objc_arc)
+#error SDL must be built with Objective-C ARC (automatic reference counting) enabled
+#endif
+
 #include "SDL.h"
 #include "SDL_endian.h"
 #include "SDL_cocoavideo.h"
@@ -29,6 +33,10 @@
 #include "SDL_cocoavulkan.h"
 #include "SDL_cocoametalview.h"
 
+@implementation SDL_VideoData
+
+@end
+
 /* Initialization/Query functions */
 static int Cocoa_VideoInit(_THIS);
 static void Cocoa_VideoQuit(_THIS);
@@ -37,16 +45,18 @@ static void Cocoa_VideoQuit(_THIS);
 
 static void
 Cocoa_DeleteDevice(SDL_VideoDevice * device)
+{ @autoreleasepool
 {
     if (device->wakeup_lock) {
         SDL_DestroyMutex(device->wakeup_lock);
     }
-    SDL_free(device->driverdata);
+    CFBridgingRelease(device->driverdata);
     SDL_free(device);
-}
+}}
 
 static SDL_VideoDevice *
 Cocoa_CreateDevice(int devindex)
+{ @autoreleasepool
 {
     SDL_VideoDevice *device;
     SDL_VideoData *data;
@@ -56,16 +66,16 @@ Cocoa_CreateDevice(int devindex)
     /* Initialize all variables that we clean on shutdown */
     device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
     if (device) {
-        data = (struct SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
+        data = [[SDL_VideoData alloc] init];
     } else {
-        data = NULL;
+        data = nil;
     }
     if (!data) {
         SDL_OutOfMemory();
         SDL_free(device);
         return NULL;
     }
-    device->driverdata = data;
+    device->driverdata = (void *)CFBridgingRetain(data);
     device->wakeup_lock = SDL_CreateMutex();
 
     /* Set the function pointers */
@@ -166,7 +176,7 @@ Cocoa_CreateDevice(int devindex)
     device->free = Cocoa_DeleteDevice;
 
     return device;
-}
+}}
 
 VideoBootStrap COCOA_bootstrap = {
     "cocoa", "SDL Cocoa video driver",
@@ -176,8 +186,9 @@ VideoBootStrap COCOA_bootstrap = {
 
 int
 Cocoa_VideoInit(_THIS)
+{ @autoreleasepool
 {
-    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+    SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata;
 
     Cocoa_InitModes(_this);
     Cocoa_InitKeyboard(_this);
@@ -185,29 +196,30 @@ Cocoa_VideoInit(_THIS)
         return -1;
     }
 
-    data->allow_spaces = ((floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) && SDL_GetHintBoolean(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, SDL_TRUE));
+    data.allow_spaces = ((floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) && SDL_GetHintBoolean(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, SDL_TRUE));
 
     /* The IOPM assertion API can disable the screensaver as of 10.7. */
-    data->screensaver_use_iopm = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6;
+    data.screensaver_use_iopm = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6;
 
-    data->swaplock = SDL_CreateMutex();
-    if (!data->swaplock) {
+    data.swaplock = SDL_CreateMutex();
+    if (!data.swaplock) {
         return -1;
     }
 
     return 0;
-}
+}}
 
 void
 Cocoa_VideoQuit(_THIS)
+{ @autoreleasepool
 {
-    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+    SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata;
     Cocoa_QuitModes(_this);
     Cocoa_QuitKeyboard(_this);
     Cocoa_QuitMouse(_this);
-    SDL_DestroyMutex(data->swaplock);
-    data->swaplock = NULL;
-}
+    SDL_DestroyMutex(data.swaplock);
+    data.swaplock = NULL;
+}}
 
 /* This function assumes that it's called from within an autorelease pool */
 NSImage *
@@ -224,7 +236,7 @@ Cocoa_CreateImage(SDL_Surface * surface)
         return nil;
     }
 
-    imgrep = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
+    imgrep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
                     pixelsWide: converted->w
                     pixelsHigh: converted->h
                     bitsPerSample: 8
@@ -233,7 +245,7 @@ Cocoa_CreateImage(SDL_Surface * surface)
                     isPlanar: NO
                     colorSpaceName: NSDeviceRGBColorSpace
                     bytesPerRow: converted->pitch
-                    bitsPerPixel: converted->format->BitsPerPixel] autorelease];
+                    bitsPerPixel: converted->format->BitsPerPixel];
     if (imgrep == nil) {
         SDL_FreeSurface(converted);
         return nil;
@@ -253,7 +265,7 @@ Cocoa_CreateImage(SDL_Surface * surface)
         pixels += 4;
     }
 
-    img = [[[NSImage alloc] initWithSize: NSMakeSize(surface->w, surface->h)] autorelease];
+    img = [[NSImage alloc] initWithSize: NSMakeSize(surface->w, surface->h)];
     if (img != nil) {
         [img addRepresentation: imgrep];
     }

+ 15 - 15
src/video/cocoa/SDL_cocoawindow.h

@@ -29,7 +29,7 @@
 #include "../SDL_egl_c.h"
 #endif
 
-typedef struct SDL_WindowData SDL_WindowData;
+@class SDL_WindowData;
 
 typedef enum
 {
@@ -114,22 +114,22 @@ typedef enum
 /* *INDENT-ON* */
 
 @class SDLOpenGLContext;
-
-struct SDL_WindowData
-{
-    SDL_Window *window;
-    NSWindow *nswindow;
-    NSView *sdlContentView;
-    NSMutableArray *nscontexts;
-    SDL_bool created;
-    SDL_bool inWindowFullscreenTransition;
-    NSInteger flash_request;
-    Cocoa_WindowListener *listener;
-    struct SDL_VideoData *videodata;
+@class SDL_VideoData;
+
+@interface SDL_WindowData : NSObject
+    @property (nonatomic) SDL_Window *window;
+    @property (nonatomic) NSWindow *nswindow;
+    @property (nonatomic) NSView *sdlContentView;
+    @property (nonatomic) NSMutableArray *nscontexts;
+    @property (nonatomic) SDL_bool created;
+    @property (nonatomic) SDL_bool inWindowFullscreenTransition;
+    @property (nonatomic) NSInteger flash_request;
+    @property (nonatomic) Cocoa_WindowListener *listener;
+    @property (nonatomic) SDL_VideoData *videodata;
 #if SDL_VIDEO_OPENGL_EGL
-    EGLSurface egl_surface;
+    @property (nonatomic) EGLSurface egl_surface;
 #endif
-};
+@end
 
 extern int Cocoa_CreateWindow(_THIS, SDL_Window * window);
 extern int Cocoa_CreateWindowFrom(_THIS, SDL_Window * window,

+ 194 - 186
src/video/cocoa/SDL_cocoawindow.m

@@ -62,6 +62,10 @@
 #define NSAppKitVersionNumber10_14      1671
 #endif
 
+@implementation SDL_WindowData
+
+@end
+
 @interface NSWindow (SDL)
 #if MAC_OS_X_VERSION_MAX_ALLOWED < 101000 /* Added in the 10.10 SDK */
 @property (readonly) NSRect contentLayoutRect;
@@ -227,7 +231,7 @@
     /* !!! FIXME: is there a better way to do this? */
     if (_this) {
         for (sdlwindow = _this->windows; sdlwindow; sdlwindow = sdlwindow->next) {
-            NSWindow *nswindow = ((SDL_WindowData *) sdlwindow->driverdata)->nswindow;
+            NSWindow *nswindow = ((__bridge SDL_WindowData *) sdlwindow->driverdata).nswindow;
             if (nswindow == self) {
                 break;
             }
@@ -250,7 +254,7 @@ static void ConvertNSRect(NSScreen *screen, BOOL fullscreen, NSRect *r)
 static void
 ScheduleContextUpdates(SDL_WindowData *data)
 {
-    if (!data || !data->nscontexts) {
+    if (!data || !data.nscontexts) {
         return;
     }
 
@@ -261,7 +265,7 @@ ScheduleContextUpdates(SDL_WindowData *data)
     #endif
 
     NSOpenGLContext *currentContext = [NSOpenGLContext currentContext];
-    NSMutableArray *contexts = data->nscontexts;
+    NSMutableArray *contexts = data.nscontexts;
     @synchronized (contexts) {
         for (SDLOpenGLContext *context in contexts) {
             if (context == currentContext) {
@@ -316,19 +320,19 @@ GetWindowStyle(SDL_Window * window)
 static SDL_bool
 SetWindowStyle(SDL_Window * window, NSUInteger style)
 {
-    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
-    NSWindow *nswindow = data->nswindow;
+    SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+    NSWindow *nswindow = data.nswindow;
 
     /* The view responder chain gets messed with during setStyleMask */
-    if ([data->sdlContentView nextResponder] == data->listener) {
-        [data->sdlContentView setNextResponder:nil];
+    if ([data.sdlContentView nextResponder] == data.listener) {
+        [data.sdlContentView setNextResponder:nil];
     }
 
     [nswindow setStyleMask:style];
 
     /* The view responder chain gets messed with during setStyleMask */
-    if ([data->sdlContentView nextResponder] != data->listener) {
-        [data->sdlContentView setNextResponder:data->listener];
+    if ([data.sdlContentView nextResponder] != data.listener) {
+        [data.sdlContentView setNextResponder:data.listener];
     }
 
     return SDL_TRUE;
@@ -337,9 +341,9 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
 static SDL_bool
 ShouldAdjustCoordinatesForGrab(SDL_Window * window)
 {
-    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+    SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
 
-    if (!data || [data->listener isMovingOrFocusClickPending]) {
+    if (!data || [data.listener isMovingOrFocusClickPending]) {
         return SDL_FALSE;
     }
 
@@ -396,10 +400,10 @@ AdjustCoordinatesForGrab(SDL_Window * window, int x, int y, CGPoint *adjusted)
 static void
 Cocoa_UpdateClipCursor(SDL_Window * window)
 {
-    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+    SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
 
     if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_13_2) {
-        NSWindow *nswindow = data->nswindow;
+        NSWindow *nswindow = data.nswindow;
         SDL_Rect mouse_rect;
 
         SDL_zero(mouse_rect);
@@ -453,8 +457,8 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
 - (void)listen:(SDL_WindowData *)data
 {
     NSNotificationCenter *center;
-    NSWindow *window = data->nswindow;
-    NSView *view = data->sdlContentView;
+    NSWindow *window = data.nswindow;
+    NSView *view = data.sdlContentView;
 
     _data = data;
     observingVisible = YES;
@@ -515,12 +519,12 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
         return;
     }
 
-    if (object == _data->nswindow && [keyPath isEqualToString:@"visible"]) {
+    if (object == _data.nswindow && [keyPath isEqualToString:@"visible"]) {
         int newVisibility = [[change objectForKey:@"new"] intValue];
         if (newVisibility) {
-            SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
+            SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_SHOWN, 0, 0);
         } else {
-            SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
+            SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
         }
     }
 }
@@ -528,18 +532,18 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
 -(void) pauseVisibleObservation
 {
     observingVisible = NO;
-    wasVisible = [_data->nswindow isVisible];
+    wasVisible = [_data.nswindow isVisible];
 }
 
 -(void) resumeVisibleObservation
 {
-    BOOL isVisible = [_data->nswindow isVisible];
+    BOOL isVisible = [_data.nswindow isVisible];
     observingVisible = YES;
     if (wasVisible != isVisible) {
         if (isVisible) {
-            SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
+            SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_SHOWN, 0, 0);
         } else {
-            SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
+            SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
         }
 
         wasVisible = isVisible;
@@ -548,11 +552,11 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
 
 -(BOOL) setFullscreenSpace:(BOOL) state
 {
-    SDL_Window *window = _data->window;
-    NSWindow *nswindow = _data->nswindow;
-    SDL_VideoData *videodata = ((SDL_WindowData *) window->driverdata)->videodata;
+    SDL_Window *window = _data.window;
+    NSWindow *nswindow = _data.nswindow;
+    SDL_VideoData *videodata = ((__bridge SDL_WindowData *) window->driverdata).videodata;
 
-    if (!videodata->allow_spaces) {
+    if (!videodata.allow_spaces) {
         return NO;  /* Spaces are forcibly disabled. */
     } else if (state && ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP)) {
         return NO;  /* we only allow you to make a Space on FULLSCREEN_DESKTOP windows. */
@@ -596,7 +600,7 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
 - (void)close
 {
     NSNotificationCenter *center;
-    NSWindow *window = _data->nswindow;
+    NSWindow *window = _data.nswindow;
     NSView *view = [window contentView];
 
     center = [NSNotificationCenter defaultCenter];
@@ -678,15 +682,15 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
             mouse->WarpMouseGlobal(pendingWindowWarpX, pendingWindowWarpY);
             pendingWindowWarpX = pendingWindowWarpY = INT_MAX;
         }
-        if (mouse->relative_mode && !mouse->relative_mode_warp && mouse->focus == _data->window) {
+        if (mouse->relative_mode && !mouse->relative_mode_warp && mouse->focus == _data.window) {
             /* Move the cursor to the nearest point in the window */
             {
                 int x, y;
                 CGPoint cgpoint;
 
                 SDL_GetMouseState(&x, &y);
-                cgpoint.x = _data->window->x + x;
-                cgpoint.y = _data->window->y + y;
+                cgpoint.x = _data.window->x + x;
+                cgpoint.y = _data.window->y + y;
 
                 Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y);
 
@@ -696,25 +700,25 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
 
             mouse->SetRelativeMouseMode(SDL_TRUE);
         } else {
-            Cocoa_UpdateClipCursor(_data->window);
+            Cocoa_UpdateClipCursor(_data.window);
         }
     }
 }
 
 - (BOOL)windowShouldClose:(id)sender
 {
-    SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_CLOSE, 0, 0);
+    SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_CLOSE, 0, 0);
     return NO;
 }
 
 - (void)windowDidExpose:(NSNotification *)aNotification
 {
-    SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_EXPOSED, 0, 0);
+    SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_EXPOSED, 0, 0);
 }
 
 - (void)windowWillMove:(NSNotification *)aNotification
 {
-    if ([_data->nswindow isKindOfClass:[SDLWindow class]]) {
+    if ([_data.nswindow isKindOfClass:[SDLWindow class]]) {
         pendingWindowWarpX = pendingWindowWarpY = INT_MAX;
         isMoving = YES;
     }
@@ -723,8 +727,8 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
 - (void)windowDidMove:(NSNotification *)aNotification
 {
     int x, y;
-    SDL_Window *window = _data->window;
-    NSWindow *nswindow = _data->nswindow;
+    SDL_Window *window = _data.window;
+    NSWindow *nswindow = _data.nswindow;
     BOOL fullscreen = window->flags & FULLSCREEN_MASK;
     NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
     ConvertNSRect([nswindow screen], fullscreen, &rect);
@@ -764,8 +768,8 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
         return;
     }
 
-    SDL_Window *window = _data->window;
-    NSWindow *nswindow = _data->nswindow;
+    SDL_Window *window = _data.window;
+    NSWindow *nswindow = _data.nswindow;
     int x, y, w, h;
     NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
     ConvertNSRect([nswindow screen], (window->flags & FULLSCREEN_MASK), &rect);
@@ -799,17 +803,17 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
         focusClickPending = 0;
         [self onMovingOrFocusClickPendingStateCleared];
     }
-    SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
+    SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
 }
 
 - (void)windowDidDeminiaturize:(NSNotification *)aNotification
 {
-    SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_RESTORED, 0, 0);
+    SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_RESTORED, 0, 0);
 }
 
 - (void)windowDidBecomeKey:(NSNotification *)aNotification
 {
-    SDL_Window *window = _data->window;
+    SDL_Window *window = _data.window;
     SDL_Mouse *mouse = SDL_GetMouse();
 
     /* We're going to get keyboard events, since we're key. */
@@ -825,7 +829,7 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
         NSPoint point;
         int x, y;
 
-        point = [_data->nswindow mouseLocationOutsideOfEventStream];
+        point = [_data.nswindow mouseLocationOutsideOfEventStream];
         x = (int)point.x;
         y = (int)(window->h - point.y);
 
@@ -835,14 +839,14 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
     }
 
     /* Check to see if someone updated the clipboard */
-    Cocoa_CheckClipboardUpdate(_data->videodata);
+    Cocoa_CheckClipboardUpdate(_data.videodata);
 
     if ((isFullscreenSpace) && ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP)) {
         [NSMenu setMenuBarVisible:NO];
     }
 
     const unsigned int newflags = [NSEvent modifierFlags] & NSEventModifierFlagCapsLock;
-    _data->videodata->modifierFlags = (_data->videodata->modifierFlags & ~NSEventModifierFlagCapsLock) | newflags;
+    _data.videodata.modifierFlags = (_data.videodata.modifierFlags & ~NSEventModifierFlagCapsLock) | newflags;
     SDL_ToggleModState(KMOD_CAPS, newflags != 0);
 }
 
@@ -854,12 +858,12 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
     }
 
     /* Some other window will get mouse events, since we're not key. */
-    if (SDL_GetMouseFocus() == _data->window) {
+    if (SDL_GetMouseFocus() == _data.window) {
         SDL_SetMouseFocus(NULL);
     }
 
     /* Some other window will get keyboard events, since we're not key. */
-    if (SDL_GetKeyboardFocus() == _data->window) {
+    if (SDL_GetKeyboardFocus() == _data.window) {
         SDL_SetKeyboardFocus(NULL);
     }
 
@@ -876,22 +880,22 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
         return;
     }
 
-    if ([oldscale doubleValue] != [_data->nswindow backingScaleFactor]) {
+    if ([oldscale doubleValue] != [_data.nswindow backingScaleFactor]) {
         /* Force a resize event when the backing scale factor changes. */
-        _data->window->w = 0;
-        _data->window->h = 0;
+        _data.window->w = 0;
+        _data.window->h = 0;
         [self windowDidResize:aNotification];
     }
 }
 
 - (void)windowDidChangeScreenProfile:(NSNotification *)aNotification
 {
-    SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0);
+    SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0);
 }
 
 - (void)windowWillEnterFullScreen:(NSNotification *)aNotification
 {
-    SDL_Window *window = _data->window;
+    SDL_Window *window = _data.window;
 
     SetWindowStyle(window, (NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable));
 
@@ -901,7 +905,7 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
 
 - (void)windowDidFailToEnterFullScreen:(NSNotification *)aNotification
 {
-    SDL_Window *window = _data->window;
+    SDL_Window *window = _data.window;
 
     if (window->is_destroying) {
         return;
@@ -917,9 +921,9 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
 
 - (void)windowDidEnterFullScreen:(NSNotification *)aNotification
 {
-    SDL_Window *window = _data->window;
-    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
-    NSWindow *nswindow = data->nswindow;
+    SDL_Window *window = _data.window;
+    SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+    NSWindow *nswindow = data.nswindow;
 
     inFullscreenTransition = NO;
 
@@ -949,7 +953,7 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
 
 - (void)windowWillExitFullScreen:(NSNotification *)aNotification
 {
-    SDL_Window *window = _data->window;
+    SDL_Window *window = _data.window;
 
     isFullscreenSpace = NO;
     inFullscreenTransition = YES;
@@ -967,7 +971,7 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
 
 - (void)windowDidFailToExitFullScreen:(NSNotification *)aNotification
 {
-    SDL_Window *window = _data->window;
+    SDL_Window *window = _data.window;
     
     if (window->is_destroying) {
         return;
@@ -983,8 +987,8 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
 
 - (void)windowDidExitFullScreen:(NSNotification *)aNotification
 {
-    SDL_Window *window = _data->window;
-    NSWindow *nswindow = _data->nswindow;
+    SDL_Window *window = _data.window;
+    NSWindow *nswindow = _data.nswindow;
     NSButton *button = nil;
 
     inFullscreenTransition = NO;
@@ -1077,7 +1081,7 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
 
 -(NSApplicationPresentationOptions)window:(NSWindow *)window willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions
 {
-    if ((_data->window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
+    if ((_data.window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
         return NSApplicationPresentationFullScreen | NSApplicationPresentationHideDock | NSApplicationPresentationHideMenuBar;
     } else {
         return proposedOptions;
@@ -1127,16 +1131,16 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
 
 - (BOOL)processHitTest:(NSEvent *)theEvent
 {
-    SDL_assert(isDragAreaRunning == [_data->nswindow isMovableByWindowBackground]);
+    SDL_assert(isDragAreaRunning == [_data.nswindow isMovableByWindowBackground]);
 
-    if (_data->window->hit_test) {  /* if no hit-test, skip this. */
+    if (_data.window->hit_test) {  /* if no hit-test, skip this. */
         const NSPoint location = [theEvent locationInWindow];
-        const SDL_Point point = { (int) location.x, _data->window->h - (((int) location.y)-1) };
-        const SDL_HitTestResult rc = _data->window->hit_test(_data->window, &point, _data->window->hit_test_data);
+        const SDL_Point point = { (int) location.x, _data.window->h - (((int) location.y)-1) };
+        const SDL_HitTestResult rc = _data.window->hit_test(_data.window, &point, _data.window->hit_test_data);
         if (rc == SDL_HITTEST_DRAGGABLE) {
             if (!isDragAreaRunning) {
                 isDragAreaRunning = YES;
-                [_data->nswindow setMovableByWindowBackground:YES];
+                [_data.nswindow setMovableByWindowBackground:YES];
             }
             return YES;  /* dragging! */
         }
@@ -1144,7 +1148,7 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
 
     if (isDragAreaRunning) {
         isDragAreaRunning = NO;
-        [_data->nswindow setMovableByWindowBackground:NO];
+        [_data.nswindow setMovableByWindowBackground:NO];
         return YES;  /* was dragging, drop event. */
     }
 
@@ -1164,7 +1168,7 @@ Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * w
     //  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] == ((SDL_WindowData *) focus->driverdata)->nswindow) ) {
+    if ( focus && ([theEvent window] == ((__bridge SDL_WindowData *) focus->driverdata).nswindow) ) {
         rc = SDL_SendMouseButtonClicks(window, mouseID, state, button, clicks);
     } else {
         const int orig_x = mouse->x;
@@ -1198,7 +1202,7 @@ Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * w
     }
 
     if ([self processHitTest:theEvent]) {
-        SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0);
+        SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_HIT_TEST, 0, 0);
         return;  /* dragging, drop event. */
     }
 
@@ -1224,7 +1228,7 @@ Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * w
         break;
     }
 
-    Cocoa_SendMouseButtonClicks(mouse, theEvent, _data->window, SDL_PRESSED, button);
+    Cocoa_SendMouseButtonClicks(mouse, theEvent, _data.window, SDL_PRESSED, button);
 }
 
 - (void)rightMouseDown:(NSEvent *)theEvent
@@ -1247,7 +1251,7 @@ Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * w
     int button;
 
     if ([self processHitTest:theEvent]) {
-        SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0);
+        SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_HIT_TEST, 0, 0);
         return;  /* stopped dragging, drop event. */
     }
 
@@ -1271,7 +1275,7 @@ Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * w
         break;
     }
 
-    Cocoa_SendMouseButtonClicks(mouse, theEvent, _data->window, SDL_RELEASED, button);
+    Cocoa_SendMouseButtonClicks(mouse, theEvent, _data.window, SDL_RELEASED, button);
 }
 
 - (void)rightMouseUp:(NSEvent *)theEvent
@@ -1292,7 +1296,7 @@ Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * w
     }
 
     const SDL_MouseID mouseID = mouse->mouseID;
-    SDL_Window *window = _data->window;
+    SDL_Window *window = _data.window;
     NSPoint point;
     int x, y;
 
@@ -1341,7 +1345,7 @@ Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * w
 
 - (void)scrollWheel:(NSEvent *)theEvent
 {
-    Cocoa_HandleMouseWheel(_data->window, theEvent);
+    Cocoa_HandleMouseWheel(_data.window, theEvent);
 }
 
 - (void)touchesBeganWithEvent:(NSEvent *) theEvent
@@ -1531,7 +1535,7 @@ Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * w
        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((SDL_WindowData *) _sdlWindow->driverdata);
+    ScheduleContextUpdates((__bridge SDL_WindowData *) _sdlWindow->driverdata);
     SDL_SendWindowEvent(_sdlWindow, SDL_WINDOWEVENT_EXPOSED, 0, 0);
 }
 
@@ -1555,7 +1559,7 @@ Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * w
 
     if (mouse->cursor_shown && mouse->cur_cursor && !mouse->relative_mode) {
         [self addCursorRect:[self bounds]
-                     cursor:mouse->cur_cursor->driverdata];
+                     cursor:(__bridge NSCursor *)mouse->cur_cursor->driverdata];
     } else {
         [self addCursorRect:[self bounds]
                      cursor:[NSCursor invisibleCursor]];
@@ -1576,23 +1580,23 @@ static int
 SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, NSView *nsview, SDL_bool created)
 { @autoreleasepool
 {
-    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+    SDL_VideoData *videodata = (__bridge SDL_VideoData *) _this->driverdata;
     SDL_WindowData *data;
 
     /* Allocate the window data */
-    window->driverdata = data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data));
+    data = [[SDL_WindowData alloc] init];
     if (!data) {
         return SDL_OutOfMemory();
     }
-    data->window = window;
-    data->nswindow = nswindow;
-    data->created = created;
-    data->videodata = videodata;
-    data->nscontexts = [[NSMutableArray alloc] init];
-    data->sdlContentView = nsview;
+    data.window = window;
+    data.nswindow = nswindow;
+    data.created = created;
+    data.videodata = videodata;
+    data.nscontexts = [[NSMutableArray alloc] init];
+    data.sdlContentView = nsview;
 
     /* Create an event listener for the window */
-    data->listener = [[Cocoa_WindowListener alloc] init];
+    data.listener = [[Cocoa_WindowListener alloc] init];
 
     /* Fill in the SDL window with the window data */
     {
@@ -1605,7 +1609,7 @@ SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, NSView *nsview,
     }
 
     /* Set up the listener after we create the view */
-    [data->listener listen:data];
+    [data.listener listen:data];
 
     if ([nswindow isVisible]) {
         window->flags |= SDL_WINDOW_SHOWN;
@@ -1646,7 +1650,7 @@ SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, NSView *nsview,
 
     if ([nswindow isKeyWindow]) {
         window->flags |= SDL_WINDOW_INPUT_FOCUS;
-        SDL_SetKeyboardFocus(data->window);
+        SDL_SetKeyboardFocus(data.window);
     }
 
     /* Prevents the window's "window device" from being destroyed when it is
@@ -1655,7 +1659,7 @@ SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, NSView *nsview,
     [nswindow setOneShot:NO];
 
     /* All done! */
-    window->driverdata = data;
+    window->driverdata = (void *)CFBridgingRetain(data);
     return 0;
 }}
 
@@ -1663,7 +1667,7 @@ int
 Cocoa_CreateWindow(_THIS, SDL_Window * window)
 { @autoreleasepool
 {
-    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
+    SDL_VideoData *videodata = (__bridge SDL_VideoData *) _this->driverdata;
     NSWindow *nswindow;
     SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
     NSRect rect;
@@ -1708,7 +1712,7 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window)
     }
 #endif
 
-    if (videodata->allow_spaces) {
+    if (videodata.allow_spaces) {
         SDL_assert(floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6);
         SDL_assert([nswindow respondsToSelector:@selector(toggleFullScreen:)]);
         /* we put FULLSCREEN_DESKTOP windows in their own Space, without a toggle button or menubar, later */
@@ -1751,10 +1755,8 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window)
 #endif /* SDL_VIDEO_OPENGL_EGL */
 #endif /* SDL_VIDEO_OPENGL_ES2 */
     [nswindow setContentView:contentView];
-    [contentView release];
 
     if (SetupWindowData(_this, window, nswindow, contentView, SDL_TRUE) < 0) {
-        [nswindow release];
         return -1;
     }
 
@@ -1786,11 +1788,11 @@ Cocoa_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
     NSView* nsview = nil;
     NSWindow *nswindow = nil;
 
-    if ([(id)data isKindOfClass:[NSWindow class]]) {
-      nswindow = (NSWindow*)data;
+    if ([(__bridge id)data isKindOfClass:[NSWindow class]]) {
+      nswindow = (__bridge NSWindow*)data;
       nsview = [nswindow contentView];
-    } else if ([(id)data isKindOfClass:[NSView class]]) {
-      nsview = (NSView*)data;
+    } else if ([(__bridge id)data isKindOfClass:[NSView class]]) {
+      nsview = (__bridge NSView*)data;
       nswindow = [nsview window];
     } else {
       SDL_assert(false);
@@ -1827,10 +1829,9 @@ Cocoa_SetWindowTitle(_THIS, SDL_Window * window)
 { @autoreleasepool
 {
     const char *title = window->title ? window->title : "";
-    NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
+    NSWindow *nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow;
     NSString *string = [[NSString alloc] initWithUTF8String:title];
     [nswindow setTitle:string];
-    [string release];
 }}
 
 void
@@ -1848,8 +1849,8 @@ void
 Cocoa_SetWindowPosition(_THIS, SDL_Window * window)
 { @autoreleasepool
 {
-    SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
-    NSWindow *nswindow = windata->nswindow;
+    SDL_WindowData *windata = (__bridge SDL_WindowData *) window->driverdata;
+    NSWindow *nswindow = windata.nswindow;
     NSRect rect;
     Uint32 moveHack;
 
@@ -1871,8 +1872,8 @@ void
 Cocoa_SetWindowSize(_THIS, SDL_Window * window)
 { @autoreleasepool
 {
-    SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
-    NSWindow *nswindow = windata->nswindow;
+    SDL_WindowData *windata = (__bridge SDL_WindowData *) window->driverdata;
+    NSWindow *nswindow = windata.nswindow;
     NSRect rect;
     Uint32 moveHack;
 
@@ -1898,39 +1899,39 @@ void
 Cocoa_SetWindowMinimumSize(_THIS, SDL_Window * window)
 { @autoreleasepool
 {
-    SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
+    SDL_WindowData *windata = (__bridge SDL_WindowData *) window->driverdata;
 
     NSSize minSize;
     minSize.width = window->min_w;
     minSize.height = window->min_h;
 
-    [windata->nswindow setContentMinSize:minSize];
+    [windata.nswindow setContentMinSize:minSize];
 }}
 
 void
 Cocoa_SetWindowMaximumSize(_THIS, SDL_Window * window)
 { @autoreleasepool
 {
-    SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
+    SDL_WindowData *windata = (__bridge SDL_WindowData *) window->driverdata;
 
     NSSize maxSize;
     maxSize.width = window->max_w;
     maxSize.height = window->max_h;
 
-    [windata->nswindow setContentMaxSize:maxSize];
+    [windata.nswindow setContentMaxSize:maxSize];
 }}
 
 void
 Cocoa_ShowWindow(_THIS, SDL_Window * window)
 { @autoreleasepool
 {
-    SDL_WindowData *windowData = ((SDL_WindowData *) window->driverdata);
-    NSWindow *nswindow = windowData->nswindow;
+    SDL_WindowData *windowData = ((__bridge SDL_WindowData *) window->driverdata);
+    NSWindow *nswindow = windowData.nswindow;
 
     if (![nswindow isMiniaturized]) {
-        [windowData->listener pauseVisibleObservation];
+        [windowData.listener pauseVisibleObservation];
         [nswindow makeKeyAndOrderFront:nil];
-        [windowData->listener resumeVisibleObservation];
+        [windowData.listener resumeVisibleObservation];
     }
 }}
 
@@ -1938,7 +1939,7 @@ void
 Cocoa_HideWindow(_THIS, SDL_Window * window)
 { @autoreleasepool
 {
-    NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
+    NSWindow *nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow;
 
     [nswindow orderOut:nil];
 }}
@@ -1947,26 +1948,26 @@ void
 Cocoa_RaiseWindow(_THIS, SDL_Window * window)
 { @autoreleasepool
 {
-    SDL_WindowData *windowData = ((SDL_WindowData *) window->driverdata);
-    NSWindow *nswindow = windowData->nswindow;
+    SDL_WindowData *windowData = ((__bridge SDL_WindowData *) window->driverdata);
+    NSWindow *nswindow = windowData.nswindow;
 
     /* makeKeyAndOrderFront: has the side-effect of deminiaturizing and showing
        a minimized or hidden window, so check for that before showing it.
      */
-    [windowData->listener pauseVisibleObservation];
+    [windowData.listener pauseVisibleObservation];
     if (![nswindow isMiniaturized] && [nswindow isVisible]) {
         [NSApp activateIgnoringOtherApps:YES];
         [nswindow makeKeyAndOrderFront:nil];
     }
-    [windowData->listener resumeVisibleObservation];
+    [windowData.listener resumeVisibleObservation];
 }}
 
 void
 Cocoa_MaximizeWindow(_THIS, SDL_Window * window)
 { @autoreleasepool
 {
-    SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
-    NSWindow *nswindow = windata->nswindow;
+    SDL_WindowData *windata = (__bridge SDL_WindowData *) window->driverdata;
+    NSWindow *nswindow = windata.nswindow;
 
     [nswindow zoom:nil];
 
@@ -1977,10 +1978,10 @@ void
 Cocoa_MinimizeWindow(_THIS, SDL_Window * window)
 { @autoreleasepool
 {
-    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
-    NSWindow *nswindow = data->nswindow;
-    if ([data->listener isInFullscreenSpaceTransition]) {
-        [data->listener addPendingWindowOperation:PENDING_OPERATION_MINIMIZE];
+    SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+    NSWindow *nswindow = data.nswindow;
+    if ([data.listener isInFullscreenSpaceTransition]) {
+        [data.listener addPendingWindowOperation:PENDING_OPERATION_MINIMIZE];
     } else {
         [nswindow miniaturize:nil];
     }
@@ -1990,7 +1991,7 @@ void
 Cocoa_RestoreWindow(_THIS, SDL_Window * window)
 { @autoreleasepool
 {
-    NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
+    NSWindow *nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow;
 
     if ([nswindow isMiniaturized]) {
         [nswindow deminiaturize:nil];
@@ -2018,14 +2019,14 @@ Cocoa_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable)
      * The window will get permanently stuck if resizable is false.
      * -flibit
      */
-    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
-    Cocoa_WindowListener *listener = data->listener;
-    NSWindow *nswindow = data->nswindow;
-    SDL_VideoData *videodata = ((SDL_WindowData *) window->driverdata)->videodata;
+    SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+    Cocoa_WindowListener *listener = data.listener;
+    NSWindow *nswindow = data.nswindow;
+    SDL_VideoData *videodata = data.videodata;
     if (![listener isInFullscreenSpace]) {
         SetWindowStyle(window, GetWindowStyle(window));
     }
-    if (videodata->allow_spaces) {
+    if (videodata.allow_spaces) {
         if (resizable) {
             /* resizable windows are Spaces-friendly: they get the "go fullscreen" toggle button on their titlebar. */
             [nswindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
@@ -2039,7 +2040,7 @@ void
 Cocoa_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_top)
 { @autoreleasepool
     {
-        NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
+        NSWindow *nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow;
         if (on_top) {
             [nswindow setLevel:NSFloatingWindowLevel];
         } else {
@@ -2051,13 +2052,13 @@ void
 Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
 { @autoreleasepool
 {
-    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
-    NSWindow *nswindow = data->nswindow;
+    SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+    NSWindow *nswindow = data.nswindow;
     NSRect rect;
 
     /* The view responder chain gets messed with during setStyleMask */
-    if ([data->sdlContentView nextResponder] == data->listener) {
-        [data->sdlContentView setNextResponder:nil];
+    if ([data.sdlContentView nextResponder] == data.listener) {
+        [data.sdlContentView setNextResponder:nil];
     }
 
     if (fullscreen) {
@@ -2103,8 +2104,8 @@ Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display
     }
 
     /* The view responder chain gets messed with during setStyleMask */
-    if ([data->sdlContentView nextResponder] != data->listener) {
-        [data->sdlContentView setNextResponder:data->listener];
+    if ([data.sdlContentView nextResponder] != data.listener) {
+        [data.sdlContentView setNextResponder:data.listener];
     }
 
     s_moveHack = 0;
@@ -2127,9 +2128,9 @@ Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display
     }
 
     if ([nswindow isVisible] || fullscreen) {
-        [data->listener pauseVisibleObservation];
+        [data.listener pauseVisibleObservation];
         [nswindow makeKeyAndOrderFront:nil];
-        [data->listener resumeVisibleObservation];
+        [data.listener resumeVisibleObservation];
     }
 
     ScheduleContextUpdates(data);
@@ -2137,6 +2138,7 @@ Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display
 
 int
 Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp)
+{ @autoreleasepool
 {
     SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
     CGDirectDisplayID display_id = ((SDL_DisplayData *)display->driverdata)->display;
@@ -2159,13 +2161,14 @@ Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp)
         return SDL_SetError("CGSetDisplayTransferByTable()");
     }
     return 0;
-}
+}}
 
 void*
 Cocoa_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size)
+{ @autoreleasepool
 {
-    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
-    NSWindow *nswindow = data->nswindow;
+    SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+    NSWindow *nswindow = data.nswindow;
     NSScreen *screen = [nswindow screen];
     NSData* iccProfileData = nil;
     void* retIccProfileData = NULL;
@@ -2195,10 +2198,13 @@ Cocoa_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size)
     [iccProfileData getBytes:retIccProfileData length:[iccProfileData length]];
     *size = [iccProfileData length];
     return retIccProfileData;
-}
+}}
 
-int Cocoa_GetWindowDisplayIndex(_THIS, SDL_Window * window){
-    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+int
+Cocoa_GetWindowDisplayIndex(_THIS, SDL_Window * window)
+{ @autoreleasepool
+{
+    SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
 
     /* Not recognized via CHECK_WINDOW_MAGIC */
     if (data == NULL){
@@ -2210,7 +2216,7 @@ int Cocoa_GetWindowDisplayIndex(_THIS, SDL_Window * window){
      instead of checking in which display the window is placed, we should check which SDL display matches the display described
      via displayframe.
     */
-    NSRect displayframe = data->nswindow.screen.frame;
+    NSRect displayframe = data.nswindow.screen.frame;
     SDL_Point display_center;
     SDL_Rect sdl_display_rect;
     
@@ -2225,7 +2231,7 @@ int Cocoa_GetWindowDisplayIndex(_THIS, SDL_Window * window){
     }
     SDL_SetError("Couldn't find the display where the window is attached to.");
     return -1;
-}
+}}
 
 int
 Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp)
@@ -2259,59 +2265,58 @@ Cocoa_SetWindowMouseRect(_THIS, SDL_Window * window)
 
 void
 Cocoa_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
+{ @autoreleasepool
 {
-    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+    SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
 
     Cocoa_UpdateClipCursor(window);
 
     if (data && (window->flags & SDL_WINDOW_FULLSCREEN)) {
         if (SDL_ShouldAllowTopmost() && (window->flags & SDL_WINDOW_INPUT_FOCUS)
-            && ![data->listener isInFullscreenSpace]) {
+            && ![data.listener isInFullscreenSpace]) {
             /* OpenGL is rendering to the window, so make it visible! */
             /* Doing this in 10.11 while in a Space breaks things (bug #3152) */
-            [data->nswindow setLevel:CGShieldingWindowLevel()];
+            [data.nswindow setLevel:CGShieldingWindowLevel()];
         } else if (window->flags & SDL_WINDOW_ALWAYS_ON_TOP) {
-            [data->nswindow setLevel:NSFloatingWindowLevel];
+            [data.nswindow setLevel:NSFloatingWindowLevel];
         } else {
-            [data->nswindow setLevel:kCGNormalWindowLevel];
+            [data.nswindow setLevel:kCGNormalWindowLevel];
         }
     }
-}
+}}
 
 void
 Cocoa_DestroyWindow(_THIS, SDL_Window * window)
 { @autoreleasepool
 {
-    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+    SDL_WindowData *data = (SDL_WindowData *) CFBridgingRelease(window->driverdata);
 
     if (data) {
-        if ([data->listener isInFullscreenSpace]) {
+        if ([data.listener isInFullscreenSpace]) {
             [NSMenu setMenuBarVisible:YES];
         }
-        [data->listener close];
-        [data->listener release];
-        if (data->created) {
+        [data.listener close];
+        data.listener = nil;
+        if (data.created) {
             /* Release the content view to avoid further updateLayer callbacks */
-            [data->nswindow setContentView:nil];
-            [data->nswindow close];
+            [data.nswindow setContentView:nil];
+            [data.nswindow close];
         }
 
-        NSArray *contexts = [[data->nscontexts copy] autorelease];
+        NSArray *contexts = [data.nscontexts copy];
         for (SDLOpenGLContext *context in contexts) {
             /* Calling setWindow:NULL causes the context to remove itself from the context list. */            
             [context setWindow:NULL];
         }
-        [data->nscontexts release];
-
-        SDL_free(data);
     }
     window->driverdata = NULL;
 }}
 
 SDL_bool
 Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
+{ @autoreleasepool
 {
-    NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
+    NSWindow *nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow;
 
     if (info->version.major <= SDL_MAJOR_VERSION) {
         info->subsystem = SDL_SYSWM_COCOA;
@@ -2322,33 +2327,34 @@ Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
                      SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
         return SDL_FALSE;
     }
-}
+}}
 
 SDL_bool
 Cocoa_IsWindowInFullscreenSpace(SDL_Window * window)
+{ @autoreleasepool
 {
-    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+    SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
 
-    if ([data->listener isInFullscreenSpace]) {
+    if ([data.listener isInFullscreenSpace]) {
         return SDL_TRUE;
     } else {
         return SDL_FALSE;
     }
-}
+}}
 
 SDL_bool
 Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state)
 { @autoreleasepool
 {
     SDL_bool succeeded = SDL_FALSE;
-    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+    SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
 
-    if (data->inWindowFullscreenTransition) {
+    if (data.inWindowFullscreenTransition) {
         return SDL_FALSE;
     }
 
-    data->inWindowFullscreenTransition = SDL_TRUE;
-    if ([data->listener setFullscreenSpace:(state ? YES : NO)]) {
+    data.inWindowFullscreenTransition = SDL_TRUE;
+    if ([data.listener setFullscreenSpace:(state ? YES : NO)]) {
         const int maxattempts = 3;
         int attempt = 0;
         while (++attempt <= maxattempts) {
@@ -2357,7 +2363,7 @@ Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state)
              */
             const int limit = 10000;
             int count = 0;
-            while ([data->listener isInFullscreenSpaceTransition]) {
+            while ([data.listener isInFullscreenSpaceTransition]) {
                 if ( ++count == limit ) {
                     /* Uh oh, transition isn't completing. Should we assert? */
                     break;
@@ -2365,16 +2371,16 @@ Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state)
                 SDL_Delay(1);
                 SDL_PumpEvents();
             }
-            if ([data->listener isInFullscreenSpace] == (state ? YES : NO))
+            if ([data.listener isInFullscreenSpace] == (state ? YES : NO))
                 break;
             /* Try again, the last attempt was interrupted by user gestures */
-            if (![data->listener setFullscreenSpace:(state ? YES : NO)])
+            if (![data.listener setFullscreenSpace:(state ? YES : NO)])
                 break; /* ??? */
         }
         /* Return TRUE to prevent non-space fullscreen logic from running */
         succeeded = SDL_TRUE;
     }
-    data->inWindowFullscreenTransition = SDL_FALSE;
+    data.inWindowFullscreenTransition = SDL_FALSE;
 
     return succeeded;
 }}
@@ -2387,25 +2393,26 @@ Cocoa_SetWindowHitTest(SDL_Window * window, SDL_bool enabled)
 
 void
 Cocoa_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept)
+{ @autoreleasepool
 {
-    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+    SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
     if (accept) {
-        [data->nswindow registerForDraggedTypes:[NSArray arrayWithObject:(NSString *)kUTTypeFileURL]];
+        [data.nswindow registerForDraggedTypes:[NSArray arrayWithObject:(NSString *)kUTTypeFileURL]];
     } else {
-        [data->nswindow unregisterDraggedTypes];
+        [data.nswindow unregisterDraggedTypes];
     }
-}
+}}
 
 int
 Cocoa_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation)
 { @autoreleasepool
 {
     /* Note that this is app-wide and not window-specific! */
-    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+    SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
 
-    if (data->flash_request) {
-        [NSApp cancelUserAttentionRequest:data->flash_request];
-        data->flash_request = 0;
+    if (data.flash_request) {
+        [NSApp cancelUserAttentionRequest:data.flash_request];
+        data.flash_request = 0;
     }
 
     switch (operation) {
@@ -2413,10 +2420,10 @@ Cocoa_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation)
         /* Canceled above */
         break;
     case SDL_FLASH_BRIEFLY:
-        data->flash_request = [NSApp requestUserAttention:NSInformationalRequest];
+        data.flash_request = [NSApp requestUserAttention:NSInformationalRequest];
         break;
     case SDL_FLASH_UNTIL_FOCUSED:
-        data->flash_request = [NSApp requestUserAttention:NSCriticalRequest];
+        data.flash_request = [NSApp requestUserAttention:NSCriticalRequest];
         break;
     default:
         return SDL_Unsupported();
@@ -2426,11 +2433,12 @@ Cocoa_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation)
 
 int
 Cocoa_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
+{ @autoreleasepool
 {
-    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
-    [data->nswindow setAlphaValue:opacity];
+    SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+    [data.nswindow setAlphaValue:opacity];
     return 0;
-}
+}}
 
 #endif /* SDL_VIDEO_DRIVER_COCOA */