diff --git a/src/cocoa_init.m b/src/cocoa_init.m index 25039e37..30dd1f56 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -479,7 +479,8 @@ static GLFWbool initializeTIS(void) int _glfwPlatformInit(void) { - _glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init]; + @autoreleasepool { + _glfw.ns.helper = [[GLFWHelper alloc] init]; [NSThread detachNewThreadSelector:@selector(doNothing:) @@ -542,10 +543,14 @@ int _glfwPlatformInit(void) _glfwPollMonitorsNS(); return GLFW_TRUE; + + } // autoreleasepool } void _glfwPlatformTerminate(void) { + @autoreleasepool { + if (_glfw.ns.inputSource) { CFRelease(_glfw.ns.inputSource); @@ -586,8 +591,7 @@ void _glfwPlatformTerminate(void) _glfwTerminateNSGL(); _glfwTerminateJoysticksNS(); - [_glfw.ns.autoreleasePool release]; - _glfw.ns.autoreleasePool = nil; + } // autoreleasepool } const char* _glfwPlatformGetVersionString(void) diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index 37e8fd13..acaba8c4 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -387,17 +387,23 @@ void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor) void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) { + @autoreleasepool { + const CGRect bounds = CGDisplayBounds(monitor->ns.displayID); if (xpos) *xpos = (int) bounds.origin.x; if (ypos) *ypos = (int) bounds.origin.y; + + } // autoreleasepool } void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, float* xscale, float* yscale) { + @autoreleasepool { + if (!refreshMonitorScreen(monitor)) return; @@ -408,12 +414,16 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor, *xscale = (float) (pixels.size.width / points.size.width); if (yscale) *yscale = (float) (pixels.size.height / points.size.height); + + } // autoreleasepool } void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height) { + @autoreleasepool { + if (!refreshMonitorScreen(monitor)) return; @@ -427,10 +437,14 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, *width = frameRect.size.width; if (height) *height = frameRect.size.height; + + } // autoreleasepool } GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) { + @autoreleasepool { + CFArrayRef modes; CFIndex found, i, j; GLFWvidmode* result; @@ -469,10 +483,14 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) CFRelease(modes); CVDisplayLinkRelease(link); return result; + + } // autoreleasepool } void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode) { + @autoreleasepool { + CGDisplayModeRef displayMode; CVDisplayLinkRef link; @@ -483,10 +501,14 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode) CGDisplayModeRelease(displayMode); CVDisplayLinkRelease(link); + + } // autoreleasepool } GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) { + @autoreleasepool { + uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID); CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue)); @@ -508,10 +530,14 @@ GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) free(values); return GLFW_TRUE; + + } // autoreleasepool } void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) { + @autoreleasepool { + int i; CGGammaValue* values = calloc(ramp->size * 3, sizeof(CGGammaValue)); @@ -529,6 +555,8 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) values + ramp->size * 2); free(values); + + } // autoreleasepool } diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index 4f3cebc8..7f188492 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -104,7 +104,6 @@ typedef struct _GLFWlibraryNS { CGEventSourceRef eventSource; id delegate; - id autoreleasePool; GLFWbool finishedLaunching; GLFWbool cursorHidden; TISInputSourceRef inputSource; diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 6ee8a097..11702778 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -910,6 +910,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig) { + @autoreleasepool { + if (!_glfw.ns.finishedLaunching) { [NSApp run]; @@ -952,10 +954,14 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, } return GLFW_TRUE; + + } // autoreleasepool } void _glfwPlatformDestroyWindow(_GLFWwindow* window) { + @autoreleasepool { + if (_glfw.ns.disabledCursorWindow == window) _glfw.ns.disabledCursorWindow = NULL; @@ -977,16 +983,17 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) [window->ns.object close]; window->ns.object = nil; - [_glfw.ns.autoreleasePool drain]; - _glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init]; + } // autoreleasepool } void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *title) { + @autoreleasepool { [window->ns.object setTitle:@(title)]; // HACK: Set the miniwindow title explicitly as setTitle: doesn't update it // if the window lacks NSWindowStyleMaskTitled [window->ns.object setMiniwindowTitle:@(title)]; + } // autoreleasepool } void _glfwPlatformSetWindowIcon(_GLFWwindow* window, @@ -997,6 +1004,8 @@ void _glfwPlatformSetWindowIcon(_GLFWwindow* window, void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) { + @autoreleasepool { + const NSRect contentRect = [window->ns.object contentRectForFrameRect:[window->ns.object frame]]; @@ -1004,28 +1013,40 @@ void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) *xpos = contentRect.origin.x; if (ypos) *ypos = _glfwTransformYNS(contentRect.origin.y + contentRect.size.height); + + } // autoreleasepool } void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y) { + @autoreleasepool { + const NSRect contentRect = [window->ns.view frame]; const NSRect dummyRect = NSMakeRect(x, _glfwTransformYNS(y + contentRect.size.height), 0, 0); const NSRect frameRect = [window->ns.object frameRectForContentRect:dummyRect]; [window->ns.object setFrameOrigin:frameRect.origin]; + + } // autoreleasepool } void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) { + @autoreleasepool { + const NSRect contentRect = [window->ns.view frame]; if (width) *width = contentRect.size.width; if (height) *height = contentRect.size.height; + + } // autoreleasepool } void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) { + @autoreleasepool { + if (window->monitor) { if (window->monitor->window == window) @@ -1033,12 +1054,16 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) } else [window->ns.object setContentSize:NSMakeSize(width, height)]; + + } // autoreleasepool } void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight) { + @autoreleasepool { + if (minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE) [window->ns.object setContentMinSize:NSMakeSize(0, 0)]; else @@ -1048,18 +1073,24 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, [window->ns.object setContentMaxSize:NSMakeSize(DBL_MAX, DBL_MAX)]; else [window->ns.object setContentMaxSize:NSMakeSize(maxwidth, maxheight)]; + + } // autoreleasepool } void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom) { + @autoreleasepool { 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 } void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) { + @autoreleasepool { + const NSRect contentRect = [window->ns.view frame]; 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; if (height) *height = (int) fbRect.size.height; + + } // autoreleasepool } void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, int* left, int* top, int* right, int* bottom) { + @autoreleasepool { + const NSRect contentRect = [window->ns.view frame]; const NSRect frameRect = [window->ns.object frameRectForContentRect:contentRect]; @@ -1086,11 +1121,15 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, contentRect.origin.x - contentRect.size.width; if (bottom) *bottom = contentRect.origin.y - frameRect.origin.y; + + } // autoreleasepool } void _glfwPlatformGetWindowContentScale(_GLFWwindow* window, float* xscale, float* yscale) { + @autoreleasepool { + const NSRect points = [window->ns.view frame]; const NSRect pixels = [window->ns.view convertRectToBacking:points]; @@ -1098,51 +1137,66 @@ void _glfwPlatformGetWindowContentScale(_GLFWwindow* window, *xscale = (float) (pixels.size.width / points.size.width); if (yscale) *yscale = (float) (pixels.size.height / points.size.height); + + } // autoreleasepool } void _glfwPlatformIconifyWindow(_GLFWwindow* window) { + @autoreleasepool { [window->ns.object miniaturize:nil]; + } // autoreleasepool } void _glfwPlatformRestoreWindow(_GLFWwindow* window) { + @autoreleasepool { if ([window->ns.object isMiniaturized]) [window->ns.object deminiaturize:nil]; else if ([window->ns.object isZoomed]) [window->ns.object zoom:nil]; + } // autoreleasepool } void _glfwPlatformMaximizeWindow(_GLFWwindow* window) { + @autoreleasepool { if (![window->ns.object isZoomed]) [window->ns.object zoom:nil]; + } // autoreleasepool } void _glfwPlatformShowWindow(_GLFWwindow* window) { + @autoreleasepool { [window->ns.object orderFront:nil]; + } // autoreleasepool } void _glfwPlatformHideWindow(_GLFWwindow* window) { + @autoreleasepool { [window->ns.object orderOut:nil]; + } // autoreleasepool } void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) { + @autoreleasepool { [NSApp requestUserAttention:NSInformationalRequest]; + } // autoreleasepool } void _glfwPlatformFocusWindow(_GLFWwindow* window) { + @autoreleasepool { // 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 } void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, @@ -1151,6 +1205,8 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, int width, int height, int refreshRate) { + @autoreleasepool { + if (window->monitor == monitor) { if (monitor) @@ -1232,30 +1288,42 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, // title property but the miniwindow title property is unaffected [window->ns.object setTitle:[window->ns.object miniwindowTitle]]; } + + } // autoreleasepool } int _glfwPlatformWindowFocused(_GLFWwindow* window) { + @autoreleasepool { return [window->ns.object isKeyWindow]; + } // autoreleasepool } int _glfwPlatformWindowIconified(_GLFWwindow* window) { + @autoreleasepool { return [window->ns.object isMiniaturized]; + } // autoreleasepool } int _glfwPlatformWindowVisible(_GLFWwindow* window) { + @autoreleasepool { return [window->ns.object isVisible]; + } // autoreleasepool } int _glfwPlatformWindowMaximized(_GLFWwindow* window) { + @autoreleasepool { return [window->ns.object isZoomed]; + } // autoreleasepool } int _glfwPlatformWindowHovered(_GLFWwindow* window) { + @autoreleasepool { + const NSPoint point = [NSEvent mouseLocation]; if ([NSWindow windowNumberAtPoint:point belowWindowWithWindowNumber:0] != @@ -1266,40 +1334,54 @@ int _glfwPlatformWindowHovered(_GLFWwindow* window) return NSPointInRect(point, [window->ns.object convertRectToScreen:[window->ns.view bounds]]); + + } // autoreleasepool } int _glfwPlatformFramebufferTransparent(_GLFWwindow* window) { + @autoreleasepool { return ![window->ns.object isOpaque] && ![window->ns.view isOpaque]; + } // autoreleasepool } void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled) { + @autoreleasepool { [window->ns.object setStyleMask:getStyleMask(window)]; + } // autoreleasepool } void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) { + @autoreleasepool { [window->ns.object setStyleMask:getStyleMask(window)]; [window->ns.object makeFirstResponder:window->ns.view]; + } // autoreleasepool } void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) { + @autoreleasepool { if (enabled) [window->ns.object setLevel:NSFloatingWindowLevel]; else [window->ns.object setLevel:NSNormalWindowLevel]; + } // autoreleasepool } float _glfwPlatformGetWindowOpacity(_GLFWwindow* window) { + @autoreleasepool { return (float) [window->ns.object alphaValue]; + } // autoreleasepool } void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity) { + @autoreleasepool { [window->ns.object setAlphaValue:opacity]; + } // autoreleasepool } void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled) @@ -1313,6 +1395,8 @@ GLFWbool _glfwPlatformRawMouseMotionSupported(void) void _glfwPlatformPollEvents(void) { + @autoreleasepool { + for (;;) { NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny @@ -1325,12 +1409,13 @@ void _glfwPlatformPollEvents(void) [NSApp sendEvent:event]; } - [_glfw.ns.autoreleasePool drain]; - _glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init]; + } // autoreleasepool } void _glfwPlatformWaitEvents(void) { + @autoreleasepool { + // I wanted to pass NO to dequeue:, and rely on PollEvents to // dequeue and send. For reasons not at all clear to me, passing // NO to dequeue: causes this method never to return. @@ -1341,10 +1426,14 @@ void _glfwPlatformWaitEvents(void) [NSApp sendEvent:event]; _glfwPlatformPollEvents(); + + } // autoreleasepool } void _glfwPlatformWaitEventsTimeout(double timeout) { + @autoreleasepool { + NSDate* date = [NSDate dateWithTimeIntervalSinceNow:timeout]; NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:date @@ -1354,11 +1443,14 @@ void _glfwPlatformWaitEventsTimeout(double timeout) [NSApp sendEvent:event]; _glfwPlatformPollEvents(); + + } // autoreleasepool } void _glfwPlatformPostEmptyEvent(void) { - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + @autoreleasepool { + NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined location:NSMakePoint(0, 0) modifierFlags:0 @@ -1369,11 +1461,14 @@ void _glfwPlatformPostEmptyEvent(void) data1:0 data2:0]; [NSApp postEvent:event atStart:YES]; - [pool drain]; + + } // autoreleasepool } void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) { + @autoreleasepool { + const NSRect contentRect = [window->ns.view frame]; const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream]; @@ -1381,10 +1476,14 @@ void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) *xpos = pos.x; if (ypos) *ypos = contentRect.size.height - pos.y - 1; + + } // autoreleasepool } void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) { + @autoreleasepool { + updateCursorImage(window); const NSRect contentRect = [window->ns.view frame]; @@ -1407,16 +1506,22 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) CGWarpMouseCursorPosition(CGPointMake(globalPoint.x, _glfwTransformYNS(globalPoint.y))); } + + } // autoreleasepool } void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) { + @autoreleasepool { if (_glfwPlatformWindowFocused(window)) updateCursorMode(window); + } // autoreleasepool } const char* _glfwPlatformGetScancodeName(int scancode) { + @autoreleasepool { + UInt32 deadKeyState = 0; UniChar characters[8]; UniCharCount characterCount = 0; @@ -1449,6 +1554,8 @@ const char* _glfwPlatformGetScancodeName(int scancode) CFRelease(string); return _glfw.ns.keyName; + + } // autoreleasepool } int _glfwPlatformGetKeyScancode(int key) @@ -1460,6 +1567,8 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot) { + @autoreleasepool { + NSImage* native; NSBitmapImageRep* rep; @@ -1494,10 +1603,14 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor, return GLFW_FALSE; return GLFW_TRUE; + + } // autoreleasepool } int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) { + @autoreleasepool { + if (shape == GLFW_ARROW_CURSOR) cursor->ns.object = [NSCursor arrowCursor]; else if (shape == GLFW_IBEAM_CURSOR) @@ -1520,29 +1633,39 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) [cursor->ns.object retain]; return GLFW_TRUE; + + } // autoreleasepool } void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) { + @autoreleasepool { if (cursor->ns.object) [(NSCursor*) cursor->ns.object release]; + } // autoreleasepool } void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) { + @autoreleasepool { if (cursorInContentArea(window)) updateCursorImage(window); + } // autoreleasepool } void _glfwPlatformSetClipboardString(const char* string) { + @autoreleasepool { NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; [pasteboard declareTypes:@[NSPasteboardTypeString] owner:nil]; [pasteboard setString:@(string) forType:NSPasteboardTypeString]; + } // autoreleasepool } const char* _glfwPlatformGetClipboardString(void) { + @autoreleasepool { + NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; if (![[pasteboard types] containsObject:NSPasteboardTypeString]) @@ -1564,6 +1687,8 @@ const char* _glfwPlatformGetClipboardString(void) _glfw.ns.clipboardString = _glfw_strdup([object UTF8String]); return _glfw.ns.clipboardString; + + } // autoreleasepool } void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) @@ -1587,6 +1712,8 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface) { + @autoreleasepool { + #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100 VkResult err; VkMacOSSurfaceCreateInfoMVK sci; @@ -1639,6 +1766,8 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, #else return VK_ERROR_EXTENSION_NOT_PRESENT; #endif + + } // autoreleasepool } diff --git a/src/nsgl_context.m b/src/nsgl_context.m index ec1012e9..f3bf2425 100644 --- a/src/nsgl_context.m +++ b/src/nsgl_context.m @@ -33,27 +33,37 @@ static void makeContextCurrentNSGL(_GLFWwindow* window) { + @autoreleasepool { + if (window) [window->context.nsgl.object makeCurrentContext]; else [NSOpenGLContext clearCurrentContext]; _glfwPlatformSetTls(&_glfw.contextSlot, window); + + } // autoreleasepool } static void swapBuffersNSGL(_GLFWwindow* window) { + @autoreleasepool { // ARP appears to be unnecessary, but this is future-proof [window->context.nsgl.object flushBuffer]; + } // autoreleasepool } static void swapIntervalNSGL(int interval) { + @autoreleasepool { + _GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot); GLint sync = interval; [window->context.nsgl.object setValues:&sync forParameter:NSOpenGLContextParameterSwapInterval]; + + } // autoreleasepool } static int extensionSupportedNSGL(const char* extension) @@ -80,11 +90,15 @@ static GLFWglproc getProcAddressNSGL(const char* procname) // static void destroyContextNSGL(_GLFWwindow* window) { + @autoreleasepool { + [window->context.nsgl.pixelFormat release]; window->context.nsgl.pixelFormat = nil; [window->context.nsgl.object release]; window->context.nsgl.object = nil; + + } // autoreleasepool }