Cocoa: Replace global autorelease pool with blocks

This is another small step towards having GLFW play nice with other
toolkits sharing the same process, including AppKit.

Any macOS platform function that touches Cocoa must now wrap itself in
an autoreleasepool block.

Since GLFW no longer provides an autoreleasepool outside of its
functions, THIS MAY BREAK EXISTING CODE MIXING GLFW AND COCOA.  Sorry!
Please add your own autoreleasepool blocks as needed.

Fixes #1107.
Closes #1114.
This commit is contained in:
Camilla Löwy 2019-03-05 19:05:57 +01:00
parent 9883cb64f0
commit 4e3204d86d
5 changed files with 185 additions and 11 deletions

View File

@ -479,7 +479,8 @@ static GLFWbool initializeTIS(void)
int _glfwPlatformInit(void) int _glfwPlatformInit(void)
{ {
_glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init]; @autoreleasepool {
_glfw.ns.helper = [[GLFWHelper alloc] init]; _glfw.ns.helper = [[GLFWHelper alloc] init];
[NSThread detachNewThreadSelector:@selector(doNothing:) [NSThread detachNewThreadSelector:@selector(doNothing:)
@ -542,10 +543,14 @@ int _glfwPlatformInit(void)
_glfwPollMonitorsNS(); _glfwPollMonitorsNS();
return GLFW_TRUE; return GLFW_TRUE;
} // autoreleasepool
} }
void _glfwPlatformTerminate(void) void _glfwPlatformTerminate(void)
{ {
@autoreleasepool {
if (_glfw.ns.inputSource) if (_glfw.ns.inputSource)
{ {
CFRelease(_glfw.ns.inputSource); CFRelease(_glfw.ns.inputSource);
@ -586,8 +591,7 @@ void _glfwPlatformTerminate(void)
_glfwTerminateNSGL(); _glfwTerminateNSGL();
_glfwTerminateJoysticksNS(); _glfwTerminateJoysticksNS();
[_glfw.ns.autoreleasePool release]; } // autoreleasepool
_glfw.ns.autoreleasePool = nil;
} }
const char* _glfwPlatformGetVersionString(void) const char* _glfwPlatformGetVersionString(void)

View File

@ -387,17 +387,23 @@ void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
{ {
@autoreleasepool {
const CGRect bounds = CGDisplayBounds(monitor->ns.displayID); const CGRect bounds = CGDisplayBounds(monitor->ns.displayID);
if (xpos) if (xpos)
*xpos = (int) bounds.origin.x; *xpos = (int) bounds.origin.x;
if (ypos) if (ypos)
*ypos = (int) bounds.origin.y; *ypos = (int) bounds.origin.y;
} // autoreleasepool
} }
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
float* xscale, float* yscale) float* xscale, float* yscale)
{ {
@autoreleasepool {
if (!refreshMonitorScreen(monitor)) if (!refreshMonitorScreen(monitor))
return; return;
@ -408,12 +414,16 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
*xscale = (float) (pixels.size.width / points.size.width); *xscale = (float) (pixels.size.width / points.size.width);
if (yscale) if (yscale)
*yscale = (float) (pixels.size.height / points.size.height); *yscale = (float) (pixels.size.height / points.size.height);
} // autoreleasepool
} }
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
int* xpos, int* ypos, int* xpos, int* ypos,
int* width, int* height) int* width, int* height)
{ {
@autoreleasepool {
if (!refreshMonitorScreen(monitor)) if (!refreshMonitorScreen(monitor))
return; return;
@ -427,10 +437,14 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
*width = frameRect.size.width; *width = frameRect.size.width;
if (height) if (height)
*height = frameRect.size.height; *height = frameRect.size.height;
} // autoreleasepool
} }
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
{ {
@autoreleasepool {
CFArrayRef modes; CFArrayRef modes;
CFIndex found, i, j; CFIndex found, i, j;
GLFWvidmode* result; GLFWvidmode* result;
@ -469,10 +483,14 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
CFRelease(modes); CFRelease(modes);
CVDisplayLinkRelease(link); CVDisplayLinkRelease(link);
return result; return result;
} // autoreleasepool
} }
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode) void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode)
{ {
@autoreleasepool {
CGDisplayModeRef displayMode; CGDisplayModeRef displayMode;
CVDisplayLinkRef link; CVDisplayLinkRef link;
@ -483,10 +501,14 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode)
CGDisplayModeRelease(displayMode); CGDisplayModeRelease(displayMode);
CVDisplayLinkRelease(link); CVDisplayLinkRelease(link);
} // autoreleasepool
} }
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{ {
@autoreleasepool {
uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID); uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue)); CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue));
@ -508,10 +530,14 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
free(values); free(values);
return GLFW_TRUE; return GLFW_TRUE;
} // autoreleasepool
} }
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{ {
@autoreleasepool {
int i; int i;
CGGammaValue* values = calloc(ramp->size * 3, sizeof(CGGammaValue)); CGGammaValue* values = calloc(ramp->size * 3, sizeof(CGGammaValue));
@ -529,6 +555,8 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
values + ramp->size * 2); values + ramp->size * 2);
free(values); free(values);
} // autoreleasepool
} }

View File

@ -104,7 +104,6 @@ typedef struct _GLFWlibraryNS
{ {
CGEventSourceRef eventSource; CGEventSourceRef eventSource;
id delegate; id delegate;
id autoreleasePool;
GLFWbool finishedLaunching; GLFWbool finishedLaunching;
GLFWbool cursorHidden; GLFWbool cursorHidden;
TISInputSourceRef inputSource; TISInputSourceRef inputSource;

View File

@ -910,6 +910,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig) const _GLFWfbconfig* fbconfig)
{ {
@autoreleasepool {
if (!_glfw.ns.finishedLaunching) if (!_glfw.ns.finishedLaunching)
{ {
[NSApp run]; [NSApp run];
@ -952,10 +954,14 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
} }
return GLFW_TRUE; return GLFW_TRUE;
} // autoreleasepool
} }
void _glfwPlatformDestroyWindow(_GLFWwindow* window) void _glfwPlatformDestroyWindow(_GLFWwindow* window)
{ {
@autoreleasepool {
if (_glfw.ns.disabledCursorWindow == window) if (_glfw.ns.disabledCursorWindow == window)
_glfw.ns.disabledCursorWindow = NULL; _glfw.ns.disabledCursorWindow = NULL;
@ -977,16 +983,17 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
[window->ns.object close]; [window->ns.object close];
window->ns.object = nil; window->ns.object = nil;
[_glfw.ns.autoreleasePool drain]; } // autoreleasepool
_glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init];
} }
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *title) void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *title)
{ {
@autoreleasepool {
[window->ns.object setTitle:@(title)]; [window->ns.object setTitle:@(title)];
// HACK: Set the miniwindow title explicitly as setTitle: doesn't update it // HACK: Set the miniwindow title explicitly as setTitle: doesn't update it
// if the window lacks NSWindowStyleMaskTitled // if the window lacks NSWindowStyleMaskTitled
[window->ns.object setMiniwindowTitle:@(title)]; [window->ns.object setMiniwindowTitle:@(title)];
} // autoreleasepool
} }
void _glfwPlatformSetWindowIcon(_GLFWwindow* window, void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
@ -997,6 +1004,8 @@ void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
{ {
@autoreleasepool {
const NSRect contentRect = const NSRect contentRect =
[window->ns.object contentRectForFrameRect:[window->ns.object frame]]; [window->ns.object contentRectForFrameRect:[window->ns.object frame]];
@ -1004,28 +1013,40 @@ void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
*xpos = contentRect.origin.x; *xpos = contentRect.origin.x;
if (ypos) if (ypos)
*ypos = _glfwTransformYNS(contentRect.origin.y + contentRect.size.height); *ypos = _glfwTransformYNS(contentRect.origin.y + contentRect.size.height);
} // autoreleasepool
} }
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y) void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y)
{ {
@autoreleasepool {
const NSRect contentRect = [window->ns.view frame]; const NSRect contentRect = [window->ns.view frame];
const NSRect dummyRect = NSMakeRect(x, _glfwTransformYNS(y + contentRect.size.height), 0, 0); const NSRect dummyRect = NSMakeRect(x, _glfwTransformYNS(y + contentRect.size.height), 0, 0);
const NSRect frameRect = [window->ns.object frameRectForContentRect:dummyRect]; const NSRect frameRect = [window->ns.object frameRectForContentRect:dummyRect];
[window->ns.object setFrameOrigin:frameRect.origin]; [window->ns.object setFrameOrigin:frameRect.origin];
} // autoreleasepool
} }
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
{ {
@autoreleasepool {
const NSRect contentRect = [window->ns.view frame]; const NSRect contentRect = [window->ns.view frame];
if (width) if (width)
*width = contentRect.size.width; *width = contentRect.size.width;
if (height) if (height)
*height = contentRect.size.height; *height = contentRect.size.height;
} // autoreleasepool
} }
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
{ {
@autoreleasepool {
if (window->monitor) if (window->monitor)
{ {
if (window->monitor->window == window) if (window->monitor->window == window)
@ -1033,12 +1054,16 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
} }
else else
[window->ns.object setContentSize:NSMakeSize(width, height)]; [window->ns.object setContentSize:NSMakeSize(width, height)];
} // autoreleasepool
} }
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
int minwidth, int minheight, int minwidth, int minheight,
int maxwidth, int maxheight) int maxwidth, int maxheight)
{ {
@autoreleasepool {
if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE) if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE)
[window->ns.object setContentMinSize:NSMakeSize(0, 0)]; [window->ns.object setContentMinSize:NSMakeSize(0, 0)];
else else
@ -1048,18 +1073,24 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
[window->ns.object setContentMaxSize:NSMakeSize(DBL_MAX, DBL_MAX)]; [window->ns.object setContentMaxSize:NSMakeSize(DBL_MAX, DBL_MAX)];
else else
[window->ns.object setContentMaxSize:NSMakeSize(maxwidth, maxheight)]; [window->ns.object setContentMaxSize:NSMakeSize(maxwidth, maxheight)];
} // autoreleasepool
} }
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom) void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)
{ {
@autoreleasepool {
if (numer == GLFW_DONT_CARE || denom == GLFW_DONT_CARE) if (numer == GLFW_DONT_CARE || denom == GLFW_DONT_CARE)
[window->ns.object setResizeIncrements:NSMakeSize(1.0, 1.0)]; [window->ns.object setResizeIncrements:NSMakeSize(1.0, 1.0)];
else else
[window->ns.object setContentAspectRatio:NSMakeSize(numer, denom)]; [window->ns.object setContentAspectRatio:NSMakeSize(numer, denom)];
} // autoreleasepool
} }
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
{ {
@autoreleasepool {
const NSRect contentRect = [window->ns.view frame]; const NSRect contentRect = [window->ns.view frame];
const NSRect fbRect = [window->ns.view convertRectToBacking:contentRect]; const NSRect fbRect = [window->ns.view convertRectToBacking:contentRect];
@ -1067,12 +1098,16 @@ void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* heigh
*width = (int) fbRect.size.width; *width = (int) fbRect.size.width;
if (height) if (height)
*height = (int) fbRect.size.height; *height = (int) fbRect.size.height;
} // autoreleasepool
} }
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
int* left, int* top, int* left, int* top,
int* right, int* bottom) int* right, int* bottom)
{ {
@autoreleasepool {
const NSRect contentRect = [window->ns.view frame]; const NSRect contentRect = [window->ns.view frame];
const NSRect frameRect = [window->ns.object frameRectForContentRect:contentRect]; const NSRect frameRect = [window->ns.object frameRectForContentRect:contentRect];
@ -1086,11 +1121,15 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
contentRect.origin.x - contentRect.size.width; contentRect.origin.x - contentRect.size.width;
if (bottom) if (bottom)
*bottom = contentRect.origin.y - frameRect.origin.y; *bottom = contentRect.origin.y - frameRect.origin.y;
} // autoreleasepool
} }
void _glfwPlatformGetWindowContentScale(_GLFWwindow* window, void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
float* xscale, float* yscale) float* xscale, float* yscale)
{ {
@autoreleasepool {
const NSRect points = [window->ns.view frame]; const NSRect points = [window->ns.view frame];
const NSRect pixels = [window->ns.view convertRectToBacking:points]; const NSRect pixels = [window->ns.view convertRectToBacking:points];
@ -1098,51 +1137,66 @@ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
*xscale = (float) (pixels.size.width / points.size.width); *xscale = (float) (pixels.size.width / points.size.width);
if (yscale) if (yscale)
*yscale = (float) (pixels.size.height / points.size.height); *yscale = (float) (pixels.size.height / points.size.height);
} // autoreleasepool
} }
void _glfwPlatformIconifyWindow(_GLFWwindow* window) void _glfwPlatformIconifyWindow(_GLFWwindow* window)
{ {
@autoreleasepool {
[window->ns.object miniaturize:nil]; [window->ns.object miniaturize:nil];
} // autoreleasepool
} }
void _glfwPlatformRestoreWindow(_GLFWwindow* window) void _glfwPlatformRestoreWindow(_GLFWwindow* window)
{ {
@autoreleasepool {
if ([window->ns.object isMiniaturized]) if ([window->ns.object isMiniaturized])
[window->ns.object deminiaturize:nil]; [window->ns.object deminiaturize:nil];
else if ([window->ns.object isZoomed]) else if ([window->ns.object isZoomed])
[window->ns.object zoom:nil]; [window->ns.object zoom:nil];
} // autoreleasepool
} }
void _glfwPlatformMaximizeWindow(_GLFWwindow* window) void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
{ {
@autoreleasepool {
if (![window->ns.object isZoomed]) if (![window->ns.object isZoomed])
[window->ns.object zoom:nil]; [window->ns.object zoom:nil];
} // autoreleasepool
} }
void _glfwPlatformShowWindow(_GLFWwindow* window) void _glfwPlatformShowWindow(_GLFWwindow* window)
{ {
@autoreleasepool {
[window->ns.object orderFront:nil]; [window->ns.object orderFront:nil];
} // autoreleasepool
} }
void _glfwPlatformHideWindow(_GLFWwindow* window) void _glfwPlatformHideWindow(_GLFWwindow* window)
{ {
@autoreleasepool {
[window->ns.object orderOut:nil]; [window->ns.object orderOut:nil];
} // autoreleasepool
} }
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
{ {
@autoreleasepool {
[NSApp requestUserAttention:NSInformationalRequest]; [NSApp requestUserAttention:NSInformationalRequest];
} // autoreleasepool
} }
void _glfwPlatformFocusWindow(_GLFWwindow* window) void _glfwPlatformFocusWindow(_GLFWwindow* window)
{ {
@autoreleasepool {
// Make us the active application // Make us the active application
// HACK: This is here to prevent applications using only hidden windows from // HACK: This is here to prevent applications using only hidden windows from
// being activated, but should probably not be done every time any // being activated, but should probably not be done every time any
// window is shown // window is shown
[NSApp activateIgnoringOtherApps:YES]; [NSApp activateIgnoringOtherApps:YES];
[window->ns.object makeKeyAndOrderFront:nil]; [window->ns.object makeKeyAndOrderFront:nil];
} // autoreleasepool
} }
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
@ -1151,6 +1205,8 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
int width, int height, int width, int height,
int refreshRate) int refreshRate)
{ {
@autoreleasepool {
if (window->monitor == monitor) if (window->monitor == monitor)
{ {
if (monitor) if (monitor)
@ -1232,30 +1288,42 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
// title property but the miniwindow title property is unaffected // title property but the miniwindow title property is unaffected
[window->ns.object setTitle:[window->ns.object miniwindowTitle]]; [window->ns.object setTitle:[window->ns.object miniwindowTitle]];
} }
} // autoreleasepool
} }
int _glfwPlatformWindowFocused(_GLFWwindow* window) int _glfwPlatformWindowFocused(_GLFWwindow* window)
{ {
@autoreleasepool {
return [window->ns.object isKeyWindow]; return [window->ns.object isKeyWindow];
} // autoreleasepool
} }
int _glfwPlatformWindowIconified(_GLFWwindow* window) int _glfwPlatformWindowIconified(_GLFWwindow* window)
{ {
@autoreleasepool {
return [window->ns.object isMiniaturized]; return [window->ns.object isMiniaturized];
} // autoreleasepool
} }
int _glfwPlatformWindowVisible(_GLFWwindow* window) int _glfwPlatformWindowVisible(_GLFWwindow* window)
{ {
@autoreleasepool {
return [window->ns.object isVisible]; return [window->ns.object isVisible];
} // autoreleasepool
} }
int _glfwPlatformWindowMaximized(_GLFWwindow* window) int _glfwPlatformWindowMaximized(_GLFWwindow* window)
{ {
@autoreleasepool {
return [window->ns.object isZoomed]; return [window->ns.object isZoomed];
} // autoreleasepool
} }
int _glfwPlatformWindowHovered(_GLFWwindow* window) int _glfwPlatformWindowHovered(_GLFWwindow* window)
{ {
@autoreleasepool {
const NSPoint point = [NSEvent mouseLocation]; const NSPoint point = [NSEvent mouseLocation];
if ([NSWindow windowNumberAtPoint:point belowWindowWithWindowNumber:0] != if ([NSWindow windowNumberAtPoint:point belowWindowWithWindowNumber:0] !=
@ -1266,40 +1334,54 @@ int _glfwPlatformWindowHovered(_GLFWwindow* window)
return NSPointInRect(point, return NSPointInRect(point,
[window->ns.object convertRectToScreen:[window->ns.view bounds]]); [window->ns.object convertRectToScreen:[window->ns.view bounds]]);
} // autoreleasepool
} }
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window) int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
{ {
@autoreleasepool {
return ![window->ns.object isOpaque] && ![window->ns.view isOpaque]; return ![window->ns.object isOpaque] && ![window->ns.view isOpaque];
} // autoreleasepool
} }
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled) void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
{ {
@autoreleasepool {
[window->ns.object setStyleMask:getStyleMask(window)]; [window->ns.object setStyleMask:getStyleMask(window)];
} // autoreleasepool
} }
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
{ {
@autoreleasepool {
[window->ns.object setStyleMask:getStyleMask(window)]; [window->ns.object setStyleMask:getStyleMask(window)];
[window->ns.object makeFirstResponder:window->ns.view]; [window->ns.object makeFirstResponder:window->ns.view];
} // autoreleasepool
} }
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
{ {
@autoreleasepool {
if (enabled) if (enabled)
[window->ns.object setLevel:NSFloatingWindowLevel]; [window->ns.object setLevel:NSFloatingWindowLevel];
else else
[window->ns.object setLevel:NSNormalWindowLevel]; [window->ns.object setLevel:NSNormalWindowLevel];
} // autoreleasepool
} }
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window) float _glfwPlatformGetWindowOpacity(_GLFWwindow* window)
{ {
@autoreleasepool {
return (float) [window->ns.object alphaValue]; return (float) [window->ns.object alphaValue];
} // autoreleasepool
} }
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity) void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity)
{ {
@autoreleasepool {
[window->ns.object setAlphaValue:opacity]; [window->ns.object setAlphaValue:opacity];
} // autoreleasepool
} }
void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled) void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled)
@ -1313,6 +1395,8 @@ GLFWbool _glfwPlatformRawMouseMotionSupported(void)
void _glfwPlatformPollEvents(void) void _glfwPlatformPollEvents(void)
{ {
@autoreleasepool {
for (;;) for (;;)
{ {
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
@ -1325,12 +1409,13 @@ void _glfwPlatformPollEvents(void)
[NSApp sendEvent:event]; [NSApp sendEvent:event];
} }
[_glfw.ns.autoreleasePool drain]; } // autoreleasepool
_glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init];
} }
void _glfwPlatformWaitEvents(void) void _glfwPlatformWaitEvents(void)
{ {
@autoreleasepool {
// I wanted to pass NO to dequeue:, and rely on PollEvents to // I wanted to pass NO to dequeue:, and rely on PollEvents to
// dequeue and send. For reasons not at all clear to me, passing // dequeue and send. For reasons not at all clear to me, passing
// NO to dequeue: causes this method never to return. // NO to dequeue: causes this method never to return.
@ -1341,10 +1426,14 @@ void _glfwPlatformWaitEvents(void)
[NSApp sendEvent:event]; [NSApp sendEvent:event];
_glfwPlatformPollEvents(); _glfwPlatformPollEvents();
} // autoreleasepool
} }
void _glfwPlatformWaitEventsTimeout(double timeout) void _glfwPlatformWaitEventsTimeout(double timeout)
{ {
@autoreleasepool {
NSDate* date = [NSDate dateWithTimeIntervalSinceNow:timeout]; NSDate* date = [NSDate dateWithTimeIntervalSinceNow:timeout];
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
untilDate:date untilDate:date
@ -1354,11 +1443,14 @@ void _glfwPlatformWaitEventsTimeout(double timeout)
[NSApp sendEvent:event]; [NSApp sendEvent:event];
_glfwPlatformPollEvents(); _glfwPlatformPollEvents();
} // autoreleasepool
} }
void _glfwPlatformPostEmptyEvent(void) void _glfwPlatformPostEmptyEvent(void)
{ {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @autoreleasepool {
NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined
location:NSMakePoint(0, 0) location:NSMakePoint(0, 0)
modifierFlags:0 modifierFlags:0
@ -1369,11 +1461,14 @@ void _glfwPlatformPostEmptyEvent(void)
data1:0 data1:0
data2:0]; data2:0];
[NSApp postEvent:event atStart:YES]; [NSApp postEvent:event atStart:YES];
[pool drain];
} // autoreleasepool
} }
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
{ {
@autoreleasepool {
const NSRect contentRect = [window->ns.view frame]; const NSRect contentRect = [window->ns.view frame];
const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream]; const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream];
@ -1381,10 +1476,14 @@ void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
*xpos = pos.x; *xpos = pos.x;
if (ypos) if (ypos)
*ypos = contentRect.size.height - pos.y - 1; *ypos = contentRect.size.height - pos.y - 1;
} // autoreleasepool
} }
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
{ {
@autoreleasepool {
updateCursorImage(window); updateCursorImage(window);
const NSRect contentRect = [window->ns.view frame]; const NSRect contentRect = [window->ns.view frame];
@ -1407,16 +1506,22 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
CGWarpMouseCursorPosition(CGPointMake(globalPoint.x, CGWarpMouseCursorPosition(CGPointMake(globalPoint.x,
_glfwTransformYNS(globalPoint.y))); _glfwTransformYNS(globalPoint.y)));
} }
} // autoreleasepool
} }
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{ {
@autoreleasepool {
if (_glfwPlatformWindowFocused(window)) if (_glfwPlatformWindowFocused(window))
updateCursorMode(window); updateCursorMode(window);
} // autoreleasepool
} }
const char* _glfwPlatformGetScancodeName(int scancode) const char* _glfwPlatformGetScancodeName(int scancode)
{ {
@autoreleasepool {
UInt32 deadKeyState = 0; UInt32 deadKeyState = 0;
UniChar characters[8]; UniChar characters[8];
UniCharCount characterCount = 0; UniCharCount characterCount = 0;
@ -1449,6 +1554,8 @@ const char* _glfwPlatformGetScancodeName(int scancode)
CFRelease(string); CFRelease(string);
return _glfw.ns.keyName; return _glfw.ns.keyName;
} // autoreleasepool
} }
int _glfwPlatformGetKeyScancode(int key) int _glfwPlatformGetKeyScancode(int key)
@ -1460,6 +1567,8 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image, const GLFWimage* image,
int xhot, int yhot) int xhot, int yhot)
{ {
@autoreleasepool {
NSImage* native; NSImage* native;
NSBitmapImageRep* rep; NSBitmapImageRep* rep;
@ -1494,10 +1603,14 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
return GLFW_FALSE; return GLFW_FALSE;
return GLFW_TRUE; return GLFW_TRUE;
} // autoreleasepool
} }
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
{ {
@autoreleasepool {
if (shape == GLFW_ARROW_CURSOR) if (shape == GLFW_ARROW_CURSOR)
cursor->ns.object = [NSCursor arrowCursor]; cursor->ns.object = [NSCursor arrowCursor];
else if (shape == GLFW_IBEAM_CURSOR) else if (shape == GLFW_IBEAM_CURSOR)
@ -1520,29 +1633,39 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
[cursor->ns.object retain]; [cursor->ns.object retain];
return GLFW_TRUE; return GLFW_TRUE;
} // autoreleasepool
} }
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
{ {
@autoreleasepool {
if (cursor->ns.object) if (cursor->ns.object)
[(NSCursor*) cursor->ns.object release]; [(NSCursor*) cursor->ns.object release];
} // autoreleasepool
} }
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
{ {
@autoreleasepool {
if (cursorInContentArea(window)) if (cursorInContentArea(window))
updateCursorImage(window); updateCursorImage(window);
} // autoreleasepool
} }
void _glfwPlatformSetClipboardString(const char* string) void _glfwPlatformSetClipboardString(const char* string)
{ {
@autoreleasepool {
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
[pasteboard declareTypes:@[NSPasteboardTypeString] owner:nil]; [pasteboard declareTypes:@[NSPasteboardTypeString] owner:nil];
[pasteboard setString:@(string) forType:NSPasteboardTypeString]; [pasteboard setString:@(string) forType:NSPasteboardTypeString];
} // autoreleasepool
} }
const char* _glfwPlatformGetClipboardString(void) const char* _glfwPlatformGetClipboardString(void)
{ {
@autoreleasepool {
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
if (![[pasteboard types] containsObject:NSPasteboardTypeString]) if (![[pasteboard types] containsObject:NSPasteboardTypeString])
@ -1564,6 +1687,8 @@ const char* _glfwPlatformGetClipboardString(void)
_glfw.ns.clipboardString = _glfw_strdup([object UTF8String]); _glfw.ns.clipboardString = _glfw_strdup([object UTF8String]);
return _glfw.ns.clipboardString; return _glfw.ns.clipboardString;
} // autoreleasepool
} }
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
@ -1587,6 +1712,8 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
const VkAllocationCallbacks* allocator, const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface) VkSurfaceKHR* surface)
{ {
@autoreleasepool {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
VkResult err; VkResult err;
VkMacOSSurfaceCreateInfoMVK sci; VkMacOSSurfaceCreateInfoMVK sci;
@ -1639,6 +1766,8 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
#else #else
return VK_ERROR_EXTENSION_NOT_PRESENT; return VK_ERROR_EXTENSION_NOT_PRESENT;
#endif #endif
} // autoreleasepool
} }

View File

@ -33,27 +33,37 @@
static void makeContextCurrentNSGL(_GLFWwindow* window) static void makeContextCurrentNSGL(_GLFWwindow* window)
{ {
@autoreleasepool {
if (window) if (window)
[window->context.nsgl.object makeCurrentContext]; [window->context.nsgl.object makeCurrentContext];
else else
[NSOpenGLContext clearCurrentContext]; [NSOpenGLContext clearCurrentContext];
_glfwPlatformSetTls(&_glfw.contextSlot, window); _glfwPlatformSetTls(&_glfw.contextSlot, window);
} // autoreleasepool
} }
static void swapBuffersNSGL(_GLFWwindow* window) static void swapBuffersNSGL(_GLFWwindow* window)
{ {
@autoreleasepool {
// ARP appears to be unnecessary, but this is future-proof // ARP appears to be unnecessary, but this is future-proof
[window->context.nsgl.object flushBuffer]; [window->context.nsgl.object flushBuffer];
} // autoreleasepool
} }
static void swapIntervalNSGL(int interval) static void swapIntervalNSGL(int interval)
{ {
@autoreleasepool {
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
GLint sync = interval; GLint sync = interval;
[window->context.nsgl.object setValues:&sync [window->context.nsgl.object setValues:&sync
forParameter:NSOpenGLContextParameterSwapInterval]; forParameter:NSOpenGLContextParameterSwapInterval];
} // autoreleasepool
} }
static int extensionSupportedNSGL(const char* extension) static int extensionSupportedNSGL(const char* extension)
@ -80,11 +90,15 @@ static GLFWglproc getProcAddressNSGL(const char* procname)
// //
static void destroyContextNSGL(_GLFWwindow* window) static void destroyContextNSGL(_GLFWwindow* window)
{ {
@autoreleasepool {
[window->context.nsgl.pixelFormat release]; [window->context.nsgl.pixelFormat release];
window->context.nsgl.pixelFormat = nil; window->context.nsgl.pixelFormat = nil;
[window->context.nsgl.object release]; [window->context.nsgl.object release];
window->context.nsgl.object = nil; window->context.nsgl.object = nil;
} // autoreleasepool
} }