From 62fb5a398a28929b8c26e7750a018eaf93257848 Mon Sep 17 00:00:00 2001
From: Sergey Fedorov <barracuda@macos-powerpc.org>
Date: Tue, 14 Jul 2026 10:41:34 +0000
Subject: [PATCH 1/5] Cocoa/NSGL: Port backend to build on Mac OS X 10.6 with
 GCC, GL 2.0 only

GCC (as shipped for 10.6) lacks clang-only Objective-C features used
throughout the Cocoa backend, and the 10.6 SDK is missing several APIs
introduced in later releases:

- Replace all @autoreleasepool {} blocks with explicit NSAutoreleasePool
  alloc/init/release, since @autoreleasepool is clang-only sugar.
- Replace modern literals (@[], @{}, @(), dictionary/array subscripting)
  with classic NSArray/NSDictionary/NSString factory-method calls.
- Replace the block-based (^{}) local key-up event monitor, which
  requires a blocks-capable compiler, with a GLFWApplication subclass
  overriding -sendEvent: to forward Cmd+KeyUp to the key window.
- Guard 10.7+/10.8+-only APIs (convertRectToBacking:, backingScaleFactor,
  scrollingDeltaX/Y, hasPreciseScrollingDeltas, setWantsBestResolutionOpenGLSurface:,
  kCGLPFASupportsAutomaticGraphicsSwitching, NSWindowCollectionBehaviorFullScreenPrimary/
  Managed) behind MAC_OS_X_VERSION_MAX_ALLOWED checks with 10.6-appropriate
  fallbacks (no HiDPI, plain scroll deltas, default collection behavior).
- Remove the NSOpenGLPFAOpenGLProfile/core-profile pixel format code path,
  since profile selection does not exist on the 10.6 SDK, and hard-reject
  any requested OpenGL version above 2.1 in NSGL context creation.

Only src/cocoa_*, src/nsgl_context.m, and src/context.c were in scope;
context.c required no changes as it is platform-generic.

Rebased onto 3.5.1, where upstream commit 8b574030 (Cocoa: Remove support
for OS X 10.10 Yosemite) dropped several guards this port relies on;
they are restored here as part of the port:

- Guard the now-unconditional CAMetalLayer #import and the direct
  [CAMetalLayer layer] Vulkan surface creation (10.11+ SDK only),
  returning VK_ERROR_EXTENSION_NOT_PRESENT on older SDKs.
- Re-guard -windowDidChangeOcclusionState:, since
  NSWindowOcclusionStateVisible is missing from pre-10.9 SDKs.
- Keep upstream's new window->title source for -setTitle: but use
  -stringWithUTF8String: instead of the clang-only @() boxed literal.
- Drop the NSOpenGLPFAOpenGLProfile selection upstream unguarded, as
  before; NSGL still hard-rejects any context version above 2.1.
---
 src/cocoa_init.m     |  73 ++++++----
 src/cocoa_monitor.m  |  41 +++---
 src/cocoa_platform.h |  10 +-
 src/cocoa_window.m   | 325 +++++++++++++++++++++++++++----------------
 src/nsgl_context.m   |  77 +++++-----
 5 files changed, 322 insertions(+), 204 deletions(-)

diff --git a/src/cocoa_init.m b/src/cocoa_init.m
index 95d6289e..d5784e42 100644
--- a/src/cocoa_init.m
+++ b/src/cocoa_init.m
@@ -89,7 +89,7 @@ static void createMenuBar(void)
 
     for (size_t i = 0;  i < sizeof(nameKeys) / sizeof(nameKeys[0]);  i++)
     {
-        id name = bundleInfo[nameKeys[i]];
+        id name = [bundleInfo objectForKey:nameKeys[i]];
         if (name &&
             [name isKindOfClass:[NSString class]] &&
             ![name isEqualToString:@""])
@@ -103,7 +103,7 @@ static void createMenuBar(void)
     {
         char** progname = _NSGetProgname();
         if (progname && *progname)
-            appName = @(*progname);
+            appName = [NSString stringWithUTF8String:*progname];
         else
             appName = @"GLFW Application";
     }
@@ -394,6 +394,34 @@ static GLFWbool initializeTIS(void)
 
 @end // GLFWHelper
 
+// GLFW application class
+//
+// NOTE: This exists (instead of using -[NSEvent addLocalMonitorForEventsMatchingMask:handler:])
+//       so that forwarding Cmd+KeyUp events to the key window does not require
+//       an Objective-C block, which is unavailable without a blocks-capable
+//       compiler such as clang
+//
+@interface GLFWApplication : NSApplication
+@end
+
+@implementation GLFWApplication
+
+- (void)sendEvent:(NSEvent *)event
+{
+    // NOTE: This replaces the block-based local event monitor used upstream,
+    //       which always forwarded Cmd+KeyUp to the key window and then let
+    //       the event continue through the normal dispatch path below
+    if ([event type] == NSEventTypeKeyUp &&
+        ([event modifierFlags] & NSEventModifierFlagCommand))
+    {
+        [[self keyWindow] sendEvent:event];
+    }
+
+    [super sendEvent:event];
+}
+
+@end // GLFWApplication
+
 @interface GLFWApplicationDelegate : NSObject <NSApplicationDelegate>
 @end
 
@@ -538,7 +566,7 @@ GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform)
 
 int _glfwInitCocoa(void)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     _glfw.ns.helper = [[GLFWHelper alloc] init];
 
@@ -546,35 +574,30 @@ int _glfwInitCocoa(void)
                              toTarget:_glfw.ns.helper
                            withObject:nil];
 
-    [NSApplication sharedApplication];
+    // NOTE: -[GLFWApplication sendEvent:] handles forwarding Cmd+KeyUp events
+    //       to the key window, replacing the block-based local event monitor
+    //       used upstream, so that this does not require a blocks-capable
+    //       compiler
+    [GLFWApplication sharedApplication];
 
     _glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init];
     if (_glfw.ns.delegate == nil)
     {
         _glfwInputError(GLFW_PLATFORM_ERROR,
                         "Cocoa: Failed to create application delegate");
+        [pool release];
         return GLFW_FALSE;
     }
 
     [NSApp setDelegate:_glfw.ns.delegate];
 
-    NSEvent* (^block)(NSEvent*) = ^ NSEvent* (NSEvent* event)
-    {
-        if ([event modifierFlags] & NSEventModifierFlagCommand)
-            [[NSApp keyWindow] sendEvent:event];
-
-        return event;
-    };
-
-    _glfw.ns.keyUpMonitor =
-        [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskKeyUp
-                                              handler:block];
-
     if (_glfw.hints.init.ns.chdir)
         changeToResourcesDirectory();
 
     // Press and Hold prevents some keys from emitting repeated characters
-    NSDictionary* defaults = @{@"ApplePressAndHoldEnabled":@NO};
+    NSDictionary* defaults =
+        [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO]
+                                     forKey:@"ApplePressAndHoldEnabled"];
     [[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
 
     [[NSNotificationCenter defaultCenter]
@@ -587,12 +610,18 @@ int _glfwInitCocoa(void)
 
     _glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
     if (!_glfw.ns.eventSource)
+    {
+        [pool release];
         return GLFW_FALSE;
+    }
 
     CGEventSourceSetLocalEventsSuppressionInterval(_glfw.ns.eventSource, 0.0);
 
     if (!initializeTIS())
+    {
+        [pool release];
         return GLFW_FALSE;
+    }
 
     _glfwPollMonitorsCocoa();
 
@@ -603,14 +632,13 @@ int _glfwInitCocoa(void)
     if (_glfw.hints.init.ns.menubar)
         [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
 
+    [pool release];
     return GLFW_TRUE;
-
-    } // autoreleasepool
 }
 
 void _glfwTerminateCocoa(void)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     if (_glfw.ns.inputSource)
     {
@@ -644,9 +672,6 @@ void _glfwTerminateCocoa(void)
         _glfw.ns.helper = nil;
     }
 
-    if (_glfw.ns.keyUpMonitor)
-        [NSEvent removeMonitor:_glfw.ns.keyUpMonitor];
-
     _glfw_free(_glfw.ns.clipboardString);
 
     _glfwTerminateNSGL();
@@ -655,7 +680,7 @@ void _glfwTerminateCocoa(void)
 
     memset(&_glfw.ns, 0, sizeof(_glfw.ns));
 
-    } // autoreleasepool
+    [pool release];
 }
 
 #endif // _GLFW_COCOA
diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m
index 620a8cfb..e53f291f 100644
--- a/src/cocoa_monitor.m
+++ b/src/cocoa_monitor.m
@@ -324,7 +324,8 @@ void _glfwPollMonitorsCocoa(void)
 
         for (screen in [NSScreen screens])
         {
-            NSNumber* screenNumber = [screen deviceDescription][@"NSScreenNumber"];
+            NSNumber* screenNumber =
+                [[screen deviceDescription] objectForKey:@"NSScreenNumber"];
 
             // HACK: Compare unit numbers instead of display IDs to work around
             //       display replacement on machines with automatic graphics
@@ -450,7 +451,7 @@ void _glfwFreeMonitorCocoa(_GLFWmonitor* monitor)
 
 void _glfwGetMonitorPosCocoa(_GLFWmonitor* monitor, int* xpos, int* ypos)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     const CGRect bounds = CGDisplayBounds(monitor->ns.displayID);
 
@@ -459,13 +460,13 @@ void _glfwGetMonitorPosCocoa(_GLFWmonitor* monitor, int* xpos, int* ypos)
     if (ypos)
         *ypos = (int) bounds.origin.y;
 
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwGetMonitorContentScaleCocoa(_GLFWmonitor* monitor,
                                       float* xscale, float* yscale)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     if (!monitor->ns.screen)
     {
@@ -474,21 +475,27 @@ void _glfwGetMonitorContentScaleCocoa(_GLFWmonitor* monitor,
     }
 
     const NSRect points = [monitor->ns.screen frame];
+    // NOTE: Mac OS X 10.6 has no backing-store scale concept; see the note in
+    //       cocoa_window.m
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
     const NSRect pixels = [monitor->ns.screen convertRectToBacking:points];
+#else
+    const NSRect pixels = points;
+#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
 
     if (xscale)
         *xscale = (float) (pixels.size.width / points.size.width);
     if (yscale)
         *yscale = (float) (pixels.size.height / points.size.height);
 
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwGetMonitorWorkareaCocoa(_GLFWmonitor* monitor,
                                   int* xpos, int* ypos,
                                   int* width, int* height)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     if (!monitor->ns.screen)
     {
@@ -507,12 +514,12 @@ void _glfwGetMonitorWorkareaCocoa(_GLFWmonitor* monitor,
     if (height)
         *height = frameRect.size.height;
 
-    } // autoreleasepool
+    [pool release];
 }
 
 GLFWvidmode* _glfwGetVideoModesCocoa(_GLFWmonitor* monitor, int* count)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     *count = 0;
 
@@ -545,32 +552,31 @@ GLFWvidmode* _glfwGetVideoModesCocoa(_GLFWmonitor* monitor, int* count)
     }
 
     CFRelease(modes);
+    [pool release];
     return result;
-
-    } // autoreleasepool
 }
 
 GLFWbool _glfwGetVideoModeCocoa(_GLFWmonitor* monitor, GLFWvidmode *mode)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     CGDisplayModeRef native = CGDisplayCopyDisplayMode(monitor->ns.displayID);
     if (!native)
     {
         _glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to query display mode");
+        [pool release];
         return GLFW_FALSE;
     }
 
     *mode = vidmodeFromCGDisplayMode(native, monitor->ns.fallbackRefreshRate);
     CGDisplayModeRelease(native);
+    [pool release];
     return GLFW_TRUE;
-
-    } // autoreleasepool
 }
 
 GLFWbool _glfwGetGammaRampCocoa(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     uint32_t size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
     CGGammaValue* values = _glfw_calloc(size * 3, sizeof(CGGammaValue));
@@ -592,14 +598,13 @@ GLFWbool _glfwGetGammaRampCocoa(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
     }
 
     _glfw_free(values);
+    [pool release];
     return GLFW_TRUE;
-
-    } // autoreleasepool
 }
 
 void _glfwSetGammaRampCocoa(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     CGGammaValue* values = _glfw_calloc(ramp->size * 3, sizeof(CGGammaValue));
 
@@ -618,7 +623,7 @@ void _glfwSetGammaRampCocoa(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
 
     _glfw_free(values);
 
-    } // autoreleasepool
+    [pool release];
 }
 
 
diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h
index 175372d6..41421839 100644
--- a/src/cocoa_platform.h
+++ b/src/cocoa_platform.h
@@ -62,6 +62,7 @@ typedef void* id;
  #define NSEventModifierFlagOption NSAlternateKeyMask
  #define NSEventModifierFlagShift NSShiftKeyMask
  #define NSEventTypeApplicationDefined NSApplicationDefined
+ #define NSEventTypeKeyUp NSKeyUp
  #define NSWindowStyleMaskBorderless NSBorderlessWindowMask
  #define NSWindowStyleMaskClosable NSClosableWindowMask
  #define NSWindowStyleMaskMiniaturizable NSMiniaturizableWindowMask
@@ -69,6 +70,14 @@ typedef void* id;
  #define NSWindowStyleMaskTitled NSTitledWindowMask
 #endif
 
+// NOTE: The Lion full-screen window collection behaviors have no pre-10.7
+//       equivalent names, so on such SDKs they are mapped to the default,
+//       pre-Lion-full-screen-aware behavior instead of being renamed
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
+ #define NSWindowCollectionBehaviorFullScreenPrimary NSWindowCollectionBehaviorDefault
+ #define NSWindowCollectionBehaviorManaged NSWindowCollectionBehaviorDefault
+#endif
+
 // NOTE: Many Cocoa dynamically linked constants have been renamed and we need
 //       to build across SDK versions where one is unavailable or deprecated.
 //       We use the newer names in code and replace them with the older names if
@@ -169,7 +178,6 @@ typedef struct _GLFWlibraryNS
     IOHIDManagerRef     hidManager;
     id                  unicodeData;
     id                  helper;
-    id                  keyUpMonitor;
     id                  nibObjects;
 
     char                keynames[GLFW_KEY_LAST + 1][17];
diff --git a/src/cocoa_window.m b/src/cocoa_window.m
index 61049808..545ff073 100644
--- a/src/cocoa_window.m
+++ b/src/cocoa_window.m
@@ -28,7 +28,11 @@
 
 #if defined(_GLFW_COCOA)
 
-#import <QuartzCore/CAMetalLayer.h>
+// NOTE: CAMetalLayer was added in the 10.11 SDK and does not exist on
+//       Mac OS X 10.6
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
+ #import <QuartzCore/CAMetalLayer.h>
+#endif
 
 #include <float.h>
 #include <string.h>
@@ -245,7 +249,14 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
     }
 
     const NSRect contentRect = [window->ns.view frame];
+    // NOTE: -convertRectToBacking: was added in the 10.7 SDK; Mac OS X 10.6 has
+    //       no backing-store scale concept, so the framebuffer is always the
+    //       same size as the content rect in points
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
     const NSRect fbRect = [window->ns.view convertRectToBacking:contentRect];
+#else
+    const NSRect fbRect = contentRect;
+#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
 
     if (fbRect.size.width != window->ns.fbWidth ||
         fbRect.size.height != window->ns.fbHeight)
@@ -312,6 +323,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
 
 - (void)windowDidChangeOcclusionState:(NSNotification* )notification
 {
+    // NOTE: NSWindowOcclusionStateVisible was added in the 10.9 SDK
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
     if ([window->ns.object respondsToSelector:@selector(occlusionState)])
     {
         if ([window->ns.object occlusionState] & NSWindowOcclusionStateVisible)
@@ -319,6 +332,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
         else
             window->ns.occluded = GLFW_TRUE;
     }
+#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
 }
 
 @end
@@ -351,7 +365,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
         markedText = [[NSMutableAttributedString alloc] init];
 
         [self updateTrackingAreas];
-        [self registerForDraggedTypes:@[NSPasteboardTypeURL]];
+        [self registerForDraggedTypes:[NSArray arrayWithObject:NSPasteboardTypeURL]];
     }
 
     return self;
@@ -505,6 +519,11 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
     _glfwInputCursorEnter(window, GLFW_TRUE);
 }
 
+// NOTE: -viewDidChangeBackingProperties is only ever invoked by AppKit on
+//       Mac OS X 10.7.4 and above, and relies on -convertRectToBacking: and
+//       -backingScaleFactor, neither of which exist on the 10.6 SDK, so this
+//       method is compiled out entirely for that target
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
 - (void)viewDidChangeBackingProperties
 {
     const NSRect contentRect = [window->ns.view frame];
@@ -530,6 +549,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
         _glfwInputFramebufferSize(window, fbRect.size.width, fbRect.size.height);
     }
 }
+#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
 
 - (void)drawRect:(NSRect)rect
 {
@@ -567,7 +587,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
 
     _glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods);
 
-    [self interpretKeyEvents:@[event]];
+    [self interpretKeyEvents:[NSArray arrayWithObject:event]];
 }
 
 - (void)flagsChanged:(NSEvent *)event
@@ -629,6 +649,10 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
 
 - (void)scrollWheel:(NSEvent *)event
 {
+    // NOTE: -scrollingDeltaX/Y and -hasPreciseScrollingDeltas are 10.7+
+    //       trackpad APIs that do not exist on the 10.6 SDK, which only
+    //       provides the plain -deltaX/-deltaY pair used below
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
     double deltaX = [event scrollingDeltaX];
     double deltaY = [event scrollingDeltaY];
 
@@ -637,6 +661,10 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
         deltaX *= 0.1;
         deltaY *= 0.1;
     }
+#else
+    double deltaX = [event deltaX];
+    double deltaY = [event deltaY];
+#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
 
     if (fabs(deltaX) > 0.0 || fabs(deltaY) > 0.0)
         _glfwInputScroll(window, deltaX, deltaY);
@@ -657,8 +685,10 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
     _glfwInputCursorPos(window, pos.x, contentRect.size.height - pos.y);
 
     NSPasteboard* pasteboard = [sender draggingPasteboard];
-    NSDictionary* options = @{NSPasteboardURLReadingFileURLsOnlyKey:@YES};
-    NSArray* urls = [pasteboard readObjectsForClasses:@[[NSURL class]]
+    NSDictionary* options =
+        [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]
+                                     forKey:NSPasteboardURLReadingFileURLsOnlyKey];
+    NSArray* urls = [pasteboard readObjectsForClasses:[NSArray arrayWithObject:[NSURL class]]
                                               options:options];
     const NSUInteger count = [urls count];
     if (count)
@@ -666,7 +696,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
         char** paths = _glfw_calloc(count, sizeof(char*));
 
         for (NSUInteger i = 0;  i < count;  i++)
-            paths[i] = _glfw_strdup([urls[i] fileSystemRepresentation]);
+            paths[i] = _glfw_strdup([[urls objectAtIndex:i] fileSystemRepresentation]);
 
         _glfwInputDrop(window, (int) count, (const char**) paths);
 
@@ -898,7 +928,10 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
     }
 
     if (strlen(wndconfig->ns.frameName))
-        [window->ns.object setFrameAutosaveName:@(wndconfig->ns.frameName)];
+    {
+        [window->ns.object setFrameAutosaveName:
+            [NSString stringWithUTF8String:wndconfig->ns.frameName]];
+    }
 
     window->ns.view = [[GLFWContentView alloc] initWithGlfwWindow:window];
     window->ns.scaleFramebuffer = wndconfig->scaleFramebuffer;
@@ -912,7 +945,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
 
     [window->ns.object setContentView:window->ns.view];
     [window->ns.object makeFirstResponder:window->ns.view];
-    [window->ns.object setTitle:@(window->title)];
+    [window->ns.object setTitle:[NSString stringWithUTF8String:window->title]];
     [window->ns.object setDelegate:window->ns.delegate];
     [window->ns.object setAcceptsMouseMovedEvents:YES];
     [window->ns.object setRestorable:NO];
@@ -950,19 +983,28 @@ GLFWbool _glfwCreateWindowCocoa(_GLFWwindow* window,
                                 const _GLFWctxconfig* ctxconfig,
                                 const _GLFWfbconfig* fbconfig)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     if (!createNativeWindow(window, wndconfig, fbconfig))
+    {
+        [pool release];
         return GLFW_FALSE;
+    }
 
     if (ctxconfig->client != GLFW_NO_API)
     {
         if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
         {
             if (!_glfwInitNSGL())
+            {
+                [pool release];
                 return GLFW_FALSE;
+            }
             if (!_glfwCreateContextNSGL(window, ctxconfig, fbconfig))
+            {
+                [pool release];
                 return GLFW_FALSE;
+            }
         }
         else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
         {
@@ -972,20 +1014,35 @@ GLFWbool _glfwCreateWindowCocoa(_GLFWwindow* window,
             window->ns.layer = [window->ns.view layer];
 
             if (!_glfwInitEGL())
+            {
+                [pool release];
                 return GLFW_FALSE;
+            }
             if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
+            {
+                [pool release];
                 return GLFW_FALSE;
+            }
         }
         else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
         {
             if (!_glfwInitOSMesa())
+            {
+                [pool release];
                 return GLFW_FALSE;
+            }
             if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
+            {
+                [pool release];
                 return GLFW_FALSE;
+            }
         }
 
         if (!_glfwRefreshContextAttribs(window, ctxconfig))
+        {
+            [pool release];
             return GLFW_FALSE;
+        }
     }
 
     if (wndconfig->mousePassthrough)
@@ -1010,14 +1067,13 @@ GLFWbool _glfwCreateWindowCocoa(_GLFWwindow* window,
         }
     }
 
+    [pool release];
     return GLFW_TRUE;
-
-    } // autoreleasepool
 }
 
 void _glfwDestroyWindowCocoa(_GLFWwindow* window)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     if (_glfw.ns.disabledCursorWindow == window)
         _glfw.ns.disabledCursorWindow = NULL;
@@ -1043,18 +1099,18 @@ void _glfwDestroyWindowCocoa(_GLFWwindow* window)
     // HACK: Allow Cocoa to catch up before returning
     _glfwPollEventsCocoa();
 
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwSetWindowTitleCocoa(_GLFWwindow* window, const char* title)
 {
-    @autoreleasepool {
-    NSString* string = @(title);
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    NSString* string = [NSString stringWithUTF8String:title];
     [window->ns.object setTitle:string];
     // HACK: Set the miniwindow title explicitly as setTitle: doesn't update it
     //       if the window lacks NSWindowStyleMaskTitled
     [window->ns.object setMiniwindowTitle:string];
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwSetWindowIconCocoa(_GLFWwindow* window,
@@ -1066,7 +1122,7 @@ void _glfwSetWindowIconCocoa(_GLFWwindow* window,
 
 void _glfwGetWindowPosCocoa(_GLFWwindow* window, int* xpos, int* ypos)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     const NSRect contentRect =
         [window->ns.object contentRectForFrameRect:[window->ns.object frame]];
@@ -1076,24 +1132,24 @@ void _glfwGetWindowPosCocoa(_GLFWwindow* window, int* xpos, int* ypos)
     if (ypos)
         *ypos = _glfwTransformYCocoa(contentRect.origin.y + contentRect.size.height - 1);
 
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwSetWindowPosCocoa(_GLFWwindow* window, int x, int y)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     const NSRect contentRect = [window->ns.view frame];
     const NSRect dummyRect = NSMakeRect(x, _glfwTransformYCocoa(y + contentRect.size.height - 1), 0, 0);
     const NSRect frameRect = [window->ns.object frameRectForContentRect:dummyRect];
     [window->ns.object setFrameOrigin:frameRect.origin];
 
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwGetWindowSizeCocoa(_GLFWwindow* window, int* width, int* height)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     const NSRect contentRect = [window->ns.view frame];
 
@@ -1102,12 +1158,12 @@ void _glfwGetWindowSizeCocoa(_GLFWwindow* window, int* width, int* height)
     if (height)
         *height = contentRect.size.height;
 
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwSetWindowSizeCocoa(_GLFWwindow* window, int width, int height)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     if (window->monitor)
     {
@@ -1124,14 +1180,14 @@ void _glfwSetWindowSizeCocoa(_GLFWwindow* window, int width, int height)
                             display:YES];
     }
 
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwSetWindowSizeLimitsCocoa(_GLFWwindow* window,
                                    int minwidth, int minheight,
                                    int maxwidth, int maxheight)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE)
         [window->ns.object setContentMinSize:NSMakeSize(0, 0)];
@@ -1143,39 +1199,45 @@ void _glfwSetWindowSizeLimitsCocoa(_GLFWwindow* window,
     else
         [window->ns.object setContentMaxSize:NSMakeSize(maxwidth, maxheight)];
 
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwSetWindowAspectRatioCocoa(_GLFWwindow* window, int numer, int denom)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     if (numer == GLFW_DONT_CARE || denom == GLFW_DONT_CARE)
         [window->ns.object setResizeIncrements:NSMakeSize(1.0, 1.0)];
     else
         [window->ns.object setContentAspectRatio:NSMakeSize(numer, denom)];
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwGetFramebufferSizeCocoa(_GLFWwindow* window, int* width, int* height)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     const NSRect contentRect = [window->ns.view frame];
+    // NOTE: Mac OS X 10.6 has no backing-store scale concept; see the note in
+    //       windowDidResize: above
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
     const NSRect fbRect = [window->ns.view convertRectToBacking:contentRect];
+#else
+    const NSRect fbRect = contentRect;
+#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
 
     if (width)
         *width = (int) fbRect.size.width;
     if (height)
         *height = (int) fbRect.size.height;
 
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwGetWindowFrameSizeCocoa(_GLFWwindow* window,
                                   int* left, int* top,
                                   int* right, int* bottom)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     const NSRect contentRect = [window->ns.view frame];
     const NSRect frameRect = [window->ns.object frameRectForContentRect:contentRect];
@@ -1191,81 +1253,87 @@ void _glfwGetWindowFrameSizeCocoa(_GLFWwindow* window,
     if (bottom)
         *bottom = contentRect.origin.y - frameRect.origin.y;
 
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwGetWindowContentScaleCocoa(_GLFWwindow* window,
                                      float* xscale, float* yscale)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     const NSRect points = [window->ns.view frame];
+    // NOTE: Mac OS X 10.6 has no backing-store scale concept; content scale
+    //       is always 1.0 there
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
     const NSRect pixels = [window->ns.view convertRectToBacking:points];
+#else
+    const NSRect pixels = points;
+#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
 
     if (xscale)
         *xscale = (float) (pixels.size.width / points.size.width);
     if (yscale)
         *yscale = (float) (pixels.size.height / points.size.height);
 
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwIconifyWindowCocoa(_GLFWwindow* window)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     [window->ns.object miniaturize:nil];
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwRestoreWindowCocoa(_GLFWwindow* window)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     if ([window->ns.object isMiniaturized])
         [window->ns.object deminiaturize:nil];
     else if ([window->ns.object isZoomed])
         [window->ns.object zoom:nil];
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwMaximizeWindowCocoa(_GLFWwindow* window)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     if (![window->ns.object isZoomed])
         [window->ns.object zoom:nil];
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwShowWindowCocoa(_GLFWwindow* window)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     [window->ns.object orderFront:nil];
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwHideWindowCocoa(_GLFWwindow* window)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     [window->ns.object orderOut:nil];
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwRequestWindowAttentionCocoa(_GLFWwindow* window)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     [NSApp requestUserAttention:NSInformationalRequest];
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwFocusWindowCocoa(_GLFWwindow* window)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     // Make us the active application
     // HACK: This is here to prevent applications using only hidden windows from
     //       being activated, but should probably not be done every time any
     //       window is shown
     [NSApp activateIgnoringOtherApps:YES];
     [window->ns.object makeKeyAndOrderFront:nil];
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwSetWindowMonitorCocoa(_GLFWwindow* window,
@@ -1274,7 +1342,7 @@ void _glfwSetWindowMonitorCocoa(_GLFWwindow* window,
                                 int width, int height,
                                 int refreshRate)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     if (window->monitor == monitor)
     {
@@ -1295,6 +1363,7 @@ void _glfwSetWindowMonitorCocoa(_GLFWwindow* window,
             [window->ns.object setFrame:frameRect display:YES];
         }
 
+        [pool release];
         return;
     }
 
@@ -1393,70 +1462,67 @@ void _glfwSetWindowMonitorCocoa(_GLFWwindow* window,
         [window->ns.object setTitle:[window->ns.object miniwindowTitle]];
     }
 
-    } // autoreleasepool
+    [pool release];
 }
 
 GLFWbool _glfwWindowFocusedCocoa(_GLFWwindow* window)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    [pool release];
     return [window->ns.object isKeyWindow];
-    } // autoreleasepool
 }
 
 GLFWbool _glfwWindowIconifiedCocoa(_GLFWwindow* window)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    [pool release];
     return [window->ns.object isMiniaturized];
-    } // autoreleasepool
 }
 
 GLFWbool _glfwWindowVisibleCocoa(_GLFWwindow* window)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    [pool release];
     return [window->ns.object isVisible];
-    } // autoreleasepool
 }
 
 GLFWbool _glfwWindowMaximizedCocoa(_GLFWwindow* window)
 {
-    @autoreleasepool {
-
-    if (window->resizable)
-        return [window->ns.object isZoomed];
-    else
-        return GLFW_FALSE;
-
-    } // autoreleasepool
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    const GLFWbool maximized =
+        window->resizable ? [window->ns.object isZoomed] : GLFW_FALSE;
+    [pool release];
+    return maximized;
 }
 
 GLFWbool _glfwWindowHoveredCocoa(_GLFWwindow* window)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     const NSPoint point = [NSEvent mouseLocation];
 
     if ([NSWindow windowNumberAtPoint:point belowWindowWithWindowNumber:0] !=
         [window->ns.object windowNumber])
     {
+        [pool release];
         return GLFW_FALSE;
     }
 
+    [pool release];
     return NSMouseInRect(point,
         [window->ns.object convertRectToScreen:[window->ns.view frame]], NO);
-
-    } // autoreleasepool
 }
 
 GLFWbool _glfwFramebufferTransparentCocoa(_GLFWwindow* window)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    [pool release];
     return ![window->ns.object isOpaque] && ![window->ns.view isOpaque];
-    } // autoreleasepool
 }
 
 void _glfwSetWindowResizableCocoa(_GLFWwindow* window, GLFWbool enabled)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     const NSUInteger styleMask = [window->ns.object styleMask];
     if (enabled)
@@ -1475,12 +1541,12 @@ void _glfwSetWindowResizableCocoa(_GLFWwindow* window, GLFWbool enabled)
         [window->ns.object setCollectionBehavior:behavior];
     }
 
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwSetWindowDecoratedCocoa(_GLFWwindow* window, GLFWbool enabled)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     NSUInteger styleMask = [window->ns.object styleMask];
     if (enabled)
@@ -1497,38 +1563,38 @@ void _glfwSetWindowDecoratedCocoa(_GLFWwindow* window, GLFWbool enabled)
     [window->ns.object setStyleMask:styleMask];
     [window->ns.object makeFirstResponder:window->ns.view];
 
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwSetWindowFloatingCocoa(_GLFWwindow* window, GLFWbool enabled)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     if (enabled)
         [window->ns.object setLevel:NSFloatingWindowLevel];
     else
         [window->ns.object setLevel:NSNormalWindowLevel];
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwSetWindowMousePassthroughCocoa(_GLFWwindow* window, GLFWbool enabled)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     [window->ns.object setIgnoresMouseEvents:enabled];
-    }
+    [pool release];
 }
 
 float _glfwGetWindowOpacityCocoa(_GLFWwindow* window)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    [pool release];
     return (float) [window->ns.object alphaValue];
-    } // autoreleasepool
 }
 
 void _glfwSetWindowOpacityCocoa(_GLFWwindow* window, float opacity)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     [window->ns.object setAlphaValue:opacity];
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwSetRawMouseMotionCocoa(_GLFWwindow *window, GLFWbool enabled)
@@ -1544,7 +1610,7 @@ GLFWbool _glfwRawMouseMotionSupportedCocoa(void)
 
 void _glfwPollEventsCocoa(void)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     for (;;)
     {
@@ -1558,12 +1624,12 @@ void _glfwPollEventsCocoa(void)
         [NSApp sendEvent:event];
     }
 
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwWaitEventsCocoa(void)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     // I wanted to pass NO to dequeue:, and rely on PollEvents to
     // dequeue and send.  For reasons not at all clear to me, passing
@@ -1576,12 +1642,12 @@ void _glfwWaitEventsCocoa(void)
 
     _glfwPollEventsCocoa();
 
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwWaitEventsTimeoutCocoa(double timeout)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     NSDate* date = [NSDate dateWithTimeIntervalSinceNow:timeout];
     NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
@@ -1593,12 +1659,12 @@ void _glfwWaitEventsTimeoutCocoa(double timeout)
 
     _glfwPollEventsCocoa();
 
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwPostEmptyEventCocoa(void)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined
                                         location:NSMakePoint(0, 0)
@@ -1611,12 +1677,12 @@ void _glfwPostEmptyEventCocoa(void)
                                            data2:0];
     [NSApp postEvent:event atStart:YES];
 
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwGetCursorPosCocoa(_GLFWwindow* window, double* xpos, double* ypos)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     const NSRect contentRect = [window->ns.view frame];
     // NOTE: The returned location uses base 0,1 not 0,0
@@ -1627,12 +1693,12 @@ void _glfwGetCursorPosCocoa(_GLFWwindow* window, double* xpos, double* ypos)
     if (ypos)
         *ypos = contentRect.size.height - pos.y;
 
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwSetCursorPosCocoa(_GLFWwindow* window, double x, double y)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     updateCursorImage(window);
 
@@ -1663,12 +1729,12 @@ void _glfwSetCursorPosCocoa(_GLFWwindow* window, double x, double y)
     if (window->cursorMode != GLFW_CURSOR_DISABLED)
         CGAssociateMouseAndMouseCursorPosition(true);
 
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwSetCursorModeCocoa(_GLFWwindow* window, int mode)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     if (mode == GLFW_CURSOR_CAPTURED)
     {
@@ -1679,22 +1745,26 @@ void _glfwSetCursorModeCocoa(_GLFWwindow* window, int mode)
     if (_glfwWindowFocusedCocoa(window))
         updateCursorMode(window);
 
-    } // autoreleasepool
+    [pool release];
 }
 
 const char* _glfwGetScancodeNameCocoa(int scancode)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     if (scancode < 0 || scancode > 0xff)
     {
         _glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode);
+        [pool release];
         return NULL;
     }
 
     const int key = _glfw.ns.keycodes[scancode];
     if (key == GLFW_KEY_UNKNOWN)
+    {
+        [pool release];
         return NULL;
+    }
 
     UInt32 deadKeyState = 0;
     UniChar characters[4];
@@ -1711,11 +1781,15 @@ const char* _glfwGetScancodeNameCocoa(int scancode)
                        &characterCount,
                        characters) != noErr)
     {
+        [pool release];
         return NULL;
     }
 
     if (!characterCount)
+    {
+        [pool release];
         return NULL;
+    }
 
     CFStringRef string = CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault,
                                                             characters,
@@ -1727,9 +1801,8 @@ const char* _glfwGetScancodeNameCocoa(int scancode)
                        kCFStringEncodingUTF8);
     CFRelease(string);
 
+    [pool release];
     return _glfw.ns.keynames[key];
-
-    } // autoreleasepool
 }
 
 int _glfwGetKeyScancodeCocoa(int key)
@@ -1741,7 +1814,7 @@ GLFWbool _glfwCreateCursorCocoa(_GLFWcursor* cursor,
                                 const GLFWimage* image,
                                 int xhot, int yhot)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     NSImage* native;
     NSBitmapImageRep* rep;
@@ -1760,7 +1833,10 @@ GLFWbool _glfwCreateCursorCocoa(_GLFWcursor* cursor,
                     bitsPerPixel:32];
 
     if (rep == nil)
+    {
+        [pool release];
         return GLFW_FALSE;
+    }
 
     memcpy([rep bitmapData], image->pixels, image->width * image->height * 4);
 
@@ -1774,16 +1850,18 @@ GLFWbool _glfwCreateCursorCocoa(_GLFWcursor* cursor,
     [rep release];
 
     if (cursor->ns.object == nil)
+    {
+        [pool release];
         return GLFW_FALSE;
+    }
 
+    [pool release];
     return GLFW_TRUE;
-
-    } // autoreleasepool
 }
 
 GLFWbool _glfwCreateStandardCursorCocoa(_GLFWcursor* cursor, int shape)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     SEL cursorSelector = NULL;
 
@@ -1846,43 +1924,44 @@ GLFWbool _glfwCreateStandardCursorCocoa(_GLFWcursor* cursor, int shape)
     {
         _glfwInputError(GLFW_CURSOR_UNAVAILABLE,
                         "Cocoa: Standard cursor shape unavailable");
+        [pool release];
         return GLFW_FALSE;
     }
 
     [cursor->ns.object retain];
+    [pool release];
     return GLFW_TRUE;
-
-    } // autoreleasepool
 }
 
 void _glfwDestroyCursorCocoa(_GLFWcursor* cursor)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     if (cursor->ns.object)
         [(NSCursor*) cursor->ns.object release];
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwSetCursorCocoa(_GLFWwindow* window, _GLFWcursor* cursor)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     if (cursorInContentArea(window))
         updateCursorImage(window);
-    } // autoreleasepool
+    [pool release];
 }
 
 void _glfwSetClipboardStringCocoa(const char* string)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
-    [pasteboard declareTypes:@[NSPasteboardTypeString] owner:nil];
-    [pasteboard setString:@(string) forType:NSPasteboardTypeString];
-    } // autoreleasepool
+    [pasteboard declareTypes:[NSArray arrayWithObject:NSPasteboardTypeString] owner:nil];
+    [pasteboard setString:[NSString stringWithUTF8String:string]
+                   forType:NSPasteboardTypeString];
+    [pool release];
 }
 
 const char* _glfwGetClipboardStringCocoa(void)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
 
@@ -1890,6 +1969,7 @@ const char* _glfwGetClipboardStringCocoa(void)
     {
         _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
                         "Cocoa: Failed to retrieve string from pasteboard");
+        [pool release];
         return NULL;
     }
 
@@ -1898,15 +1978,15 @@ const char* _glfwGetClipboardStringCocoa(void)
     {
         _glfwInputError(GLFW_PLATFORM_ERROR,
                         "Cocoa: Failed to retrieve object from pasteboard");
+        [pool release];
         return NULL;
     }
 
     _glfw_free(_glfw.ns.clipboardString);
     _glfw.ns.clipboardString = _glfw_strdup([object UTF8String]);
 
+    [pool release];
     return _glfw.ns.clipboardString;
-
-    } // autoreleasepool
 }
 
 EGLenum _glfwGetEGLPlatformCocoa(EGLint** attribs)
@@ -1976,14 +2056,18 @@ VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance,
                                        const VkAllocationCallbacks* allocator,
                                        VkSurfaceKHR* surface)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
+    // NOTE: CAMetalLayer was added in the 10.11 SDK and does not exist on
+    //       Mac OS X 10.6, so Vulkan surface creation is compiled out there
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
     // NOTE: Create the layer here as makeBackingLayer should not return nil
     window->ns.layer = [CAMetalLayer layer];
     if (!window->ns.layer)
     {
         _glfwInputError(GLFW_PLATFORM_ERROR,
                         "Cocoa: Failed to create layer for view");
+        [pool release];
         return VK_ERROR_EXTENSION_NOT_PRESENT;
     }
 
@@ -2006,6 +2090,7 @@ VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance,
         {
             _glfwInputError(GLFW_API_UNAVAILABLE,
                             "Cocoa: Vulkan instance missing VK_EXT_metal_surface extension");
+            [pool release];
             return VK_ERROR_EXTENSION_NOT_PRESENT;
         }
 
@@ -2026,6 +2111,7 @@ VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance,
         {
             _glfwInputError(GLFW_API_UNAVAILABLE,
                             "Cocoa: Vulkan instance missing VK_MVK_macos_surface extension");
+            [pool release];
             return VK_ERROR_EXTENSION_NOT_PRESENT;
         }
 
@@ -2043,9 +2129,12 @@ VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance,
                         _glfwGetVulkanResultString(err));
     }
 
+    [pool release];
     return err;
-
-    } // autoreleasepool
+#else
+    [pool release];
+    return VK_ERROR_EXTENSION_NOT_PRESENT;
+#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
 }
 
 
diff --git a/src/nsgl_context.m b/src/nsgl_context.m
index cc676171..2b2494c8 100644
--- a/src/nsgl_context.m
+++ b/src/nsgl_context.m
@@ -34,7 +34,7 @@
 
 static void makeContextCurrentNSGL(_GLFWwindow* window)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     if (window)
         [window->context.nsgl.object makeCurrentContext];
@@ -43,12 +43,12 @@ static void makeContextCurrentNSGL(_GLFWwindow* window)
 
     _glfwPlatformSetTls(&_glfw.contextSlot, window);
 
-    } // autoreleasepool
+    [pool release];
 }
 
 static void swapBuffersNSGL(_GLFWwindow* window)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     // HACK: Simulate vsync with usleep as NSGL swap interval does not apply to
     //       windows with a non-visible occlusion state
@@ -74,12 +74,12 @@ static void swapBuffersNSGL(_GLFWwindow* window)
 
     [window->context.nsgl.object flushBuffer];
 
-    } // autoreleasepool
+    [pool release];
 }
 
 static void swapIntervalNSGL(int interval)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
     assert(window != NULL);
@@ -87,7 +87,7 @@ static void swapIntervalNSGL(int interval)
     [window->context.nsgl.object setValues:&interval
                               forParameter:NSOpenGLContextParameterSwapInterval];
 
-    } // autoreleasepool
+    [pool release];
 }
 
 static int extensionSupportedNSGL(const char* extension)
@@ -112,7 +112,7 @@ static GLFWglproc getProcAddressNSGL(const char* procname)
 
 static void destroyContextNSGL(_GLFWwindow* window)
 {
-    @autoreleasepool {
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
 
     [window->context.nsgl.pixelFormat release];
     window->context.nsgl.pixelFormat = nil;
@@ -120,7 +120,7 @@ static void destroyContextNSGL(_GLFWwindow* window)
     [window->context.nsgl.object release];
     window->context.nsgl.object = nil;
 
-    } // autoreleasepool
+    [pool release];
 }
 
 
@@ -160,20 +160,10 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
         return GLFW_FALSE;
     }
 
-    if (ctxconfig->major > 2)
-    {
-        if (ctxconfig->major == 3 && ctxconfig->minor < 2)
-        {
-            _glfwInputError(GLFW_VERSION_UNAVAILABLE,
-                            "NSGL: The targeted version of macOS does not support OpenGL 3.0 or 3.1 but may support 3.2 and above");
-            return GLFW_FALSE;
-        }
-    }
-
-    if (ctxconfig->major >= 3 && ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
+    if (ctxconfig->major > 2 || (ctxconfig->major == 2 && ctxconfig->minor > 1))
     {
         _glfwInputError(GLFW_VERSION_UNAVAILABLE,
-                        "NSGL: The compatibility profile is not available on macOS");
+                        "NSGL: OpenGL 2.1 or below is the only version available on Mac OS X 10.6");
         return GLFW_FALSE;
     }
 
@@ -209,35 +199,32 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
         //       Info.plist for unbundled applications
         // HACK: This assumes that NSOpenGLPixelFormat will remain
         //       a straightforward wrapper of its CGL counterpart
+        // NOTE: kCGLPFASupportsAutomaticGraphicsSwitching was added in the
+        //       10.8 SDK and does not exist on Mac OS X 10.6
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
         ADD_ATTRIB(kCGLPFASupportsAutomaticGraphicsSwitching);
+#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
     }
 
-    if (ctxconfig->major >= 4)
-    {
-        SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core);
-    }
-    else if (ctxconfig->major >= 3)
-    {
-        SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
-    }
+    // NOTE: OpenGL profile selection (NSOpenGLPFAOpenGLProfile) was added in
+    //       the 10.7 SDK; Mac OS X 10.6 only ever provides a legacy context,
+    //       which is all that is requested above, so there is nothing to add
+    //       here for this target
 
-    if (ctxconfig->major <= 2)
-    {
-        if (fbconfig->auxBuffers != GLFW_DONT_CARE)
-            SET_ATTRIB(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
+    if (fbconfig->auxBuffers != GLFW_DONT_CARE)
+        SET_ATTRIB(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
 
-        if (fbconfig->accumRedBits != GLFW_DONT_CARE &&
-            fbconfig->accumGreenBits != GLFW_DONT_CARE &&
-            fbconfig->accumBlueBits != GLFW_DONT_CARE &&
-            fbconfig->accumAlphaBits != GLFW_DONT_CARE)
-        {
-            const int accumBits = fbconfig->accumRedBits +
-                                  fbconfig->accumGreenBits +
-                                  fbconfig->accumBlueBits +
-                                  fbconfig->accumAlphaBits;
+    if (fbconfig->accumRedBits != GLFW_DONT_CARE &&
+        fbconfig->accumGreenBits != GLFW_DONT_CARE &&
+        fbconfig->accumBlueBits != GLFW_DONT_CARE &&
+        fbconfig->accumAlphaBits != GLFW_DONT_CARE)
+    {
+        const int accumBits = fbconfig->accumRedBits +
+                              fbconfig->accumGreenBits +
+                              fbconfig->accumBlueBits +
+                              fbconfig->accumAlphaBits;
 
-            SET_ATTRIB(NSOpenGLPFAAccumSize, accumBits);
-        }
+        SET_ATTRIB(NSOpenGLPFAAccumSize, accumBits);
     }
 
     if (fbconfig->redBits != GLFW_DONT_CARE &&
@@ -332,7 +319,11 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
                                   forParameter:NSOpenGLContextParameterSurfaceOpacity];
     }
 
+    // NOTE: -setWantsBestResolutionOpenGLSurface: was added in the 10.7 SDK
+    //       and Mac OS X 10.6 has no HiDPI/backing-store scale concept
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
     [window->ns.view setWantsBestResolutionOpenGLSurface:window->ns.scaleFramebuffer];
+#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
 
     [window->context.nsgl.object setView:window->ns.view];
 
-- 
2.43.0

