From a164f6cbd92f6774cfb5dd49ee94396c5df31ea8 Mon Sep 17 00:00:00 2001
From: Sergey Fedorov <barracuda@macos-powerpc.org>
Date: Thu, 30 Jul 2026 09:33:57 +0000
Subject: [PATCH] highgui: make Cocoa backend build with GCC and pre-10.7
 SDKs

- Wrap autorelease pools in CV_AUTORELEASE_POOL_BEGIN/END: clang keeps
  @autoreleasepool, GCC (whose Objective-C frontend lacks the syntax and
  ARC) gets an equivalent explicit NSAutoreleasePool. Restructure the few
  functions that returned from inside the pool scope.
- Declare explicit ivars for CVView and synthesize all its properties:
  required by GCC and by the 32-bit (fragile) Objective-C ABI.
- Use numeric availability values (1060/1070): MAC_OS_X_VERSION_10_7 is
  not defined by the 10.6 SDK and an undefined macro evaluates to 0 in
  #if, silently selecting the wrong branch.
- Guard 10.7+ APIs (NSFullScreenWindowMask, toggleFullScreen:,
  convertRectToScreen:/FromScreen:, scrollingDelta*) and invoke
  convertSizeFromBacking: through a typed IMP so the NSSize struct-return
  ABI is correct when the method is not declared by the SDK.
- Use pre-10.12 event constant names (NSScrollWheel) consistently with
  the rest of the file; message sends instead of dot syntax on old-SDK
  methods; CGFloat casts for 32-bit std::min/max; define
  NSAppKitVersionNumber10_5 at file scope (missing from the 10.5 SDK).
- Provide cvSetOpenGlDrawCallback/cvSetOpenGlContext/cvUpdateWindow error
  stubs under HAVE_OPENGL so highgui links when OpenGL interop is enabled
  with the Cocoa backend.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmeP4C25nM6MhcEXEpT6Ae
---
 modules/highgui/src/window_cocoa.mm | 366 +++++++++++++++++-----------
 1 file changed, 224 insertions(+), 142 deletions(-)

diff --git a/modules/highgui/src/window_cocoa.mm b/modules/highgui/src/window_cocoa.mm
index d68b20b..247e26f 100644
--- a/modules/highgui/src/window_cocoa.mm
+++ b/modules/highgui/src/window_cocoa.mm
@@ -75,13 +75,41 @@ CV_IMPL int cvWaitKey (int maxWait) {return 0;}
 
 #include <iostream>
 
+// GCC's Objective-C frontend does not support the @autoreleasepool syntax.
+// This file is always compiled without ARC, so an explicit NSAutoreleasePool
+// is an exact replacement. Note that returning or jumping out of the pool
+// scope is not allowed with the NSAutoreleasePool implementation.
+#ifdef __clang__
+#define CV_AUTORELEASE_POOL_BEGIN @autoreleasepool {
+#define CV_AUTORELEASE_POOL_END   }
+#else
+#define CV_AUTORELEASE_POOL_BEGIN { NSAutoreleasePool* cvAutoreleasePool = [[NSAutoreleasePool alloc] init];
+#define CV_AUTORELEASE_POOL_END   [cvAutoreleasePool drain]; }
+#endif
+
+// Availability checks below use numeric values (1060, 1070) instead of the
+// MAC_OS_X_VERSION_10_x constants: pre-10.7 SDKs do not define the later
+// constants, and in #if directives an undefined macro silently evaluates to 0,
+// selecting the wrong branch.
+
+// Not defined by the 10.5 SDK
+#ifndef NSAppKitVersionNumber10_5
+#define NSAppKitVersionNumber10_5 949
+#endif
+
 const int MIN_SLIDER_WIDTH=200;
 
 static NSApplication *application = nil;
 static NSMutableDictionary *windows = nil;
 static bool wasInitialized = false;
 
-@interface CVView : NSView
+// Explicit ivars are required by the 32-bit ("fragile") Objective-C ABI and by
+// GCC, which does not auto-synthesize property backing storage.
+@interface CVView : NSView {
+    NSView *imageView;
+    NSImage *image;
+    int sliderHeight;
+}
 @property(retain) NSView *imageView;
 @property(retain) NSImage *image;
 @property int sliderHeight;
@@ -138,11 +166,7 @@ CV_IMPL int cvInitSystem( int , char** )
     application = [NSApplication sharedApplication];
     windows = [[NSMutableDictionary alloc] init];
 
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
-
-#ifndef NSAppKitVersionNumber10_5
-#define NSAppKitVersionNumber10_5 949
-#endif
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
     if( floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5 )
         [application setActivationPolicy:NSApplicationActivationPolicyRegular];
 #endif
@@ -153,13 +177,13 @@ CV_IMPL int cvInitSystem( int , char** )
 
 static CVWindow *cvGetWindow(const char *name) {
     CVWindow *retval = nil;
-    @autoreleasepool{
+    CV_AUTORELEASE_POOL_BEGIN
         NSString *cvname = [NSString stringWithFormat:@"%s", name];
         retval = (CVWindow*) [windows valueForKey:cvname];
         if (retval != nil) {
             [retval retain];
         }
-    }
+    CV_AUTORELEASE_POOL_END
     return [retval autorelease];
 }
 
@@ -170,33 +194,37 @@ CV_IMPL int cvStartWindowThread()
 
 CV_IMPL void cvDestroyWindow( const char* name)
 {
-    @autoreleasepool {
+    CV_AUTORELEASE_POOL_BEGIN
         CVWindow *window = cvGetWindow(name);
         if(window) {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
             if ([window styleMask] & NSFullScreenWindowMask) {
                 [window toggleFullScreen:nil];
             }
+#endif
             [window close];
             [windows removeObjectForKey:[NSString stringWithFormat:@"%s", name]];
         }
-    }
+    CV_AUTORELEASE_POOL_END
 }
 
 
 CV_IMPL void cvDestroyAllWindows( void )
 {
-    @autoreleasepool {
+    CV_AUTORELEASE_POOL_BEGIN
         NSDictionary* list = [NSDictionary dictionaryWithDictionary:windows];
-        for(NSString *key in list) {
+        NSEnumerator *enumerator = [list keyEnumerator];
+        NSString *key;
+        while((key = [enumerator nextObject]) != nil) {
             cvDestroyWindow([key cStringUsingEncoding:NSASCIIStringEncoding]);
         }
-    }
+    CV_AUTORELEASE_POOL_END
 }
 
 
 CV_IMPL void cvShowImage( const char* name, const CvArr* arr)
 {
-    @autoreleasepool{
+    CV_AUTORELEASE_POOL_BEGIN
         CVWindow *window = cvGetWindow(name);
         if(!window)
         {
@@ -221,21 +249,25 @@ CV_IMPL void cvShowImage( const char* name, const CvArr* arr)
                     if ([[window contentView] respondsToSelector:@selector(convertSizeFromBacking:)])
                     {
                         // Only resize for retina displays if the image is bigger than the screen
-                        NSSize screenSize = NSScreen.mainScreen.visibleFrame.size;
-                        CGFloat titleBarHeight = window.frame.size.height - [window contentRectForFrameRect:window.frame].size.height;
+                        NSSize screenSize = [[NSScreen mainScreen] visibleFrame].size;
+                        CGFloat titleBarHeight = [window frame].size.height - [window contentRectForFrameRect:[window frame]].size.height;
                         screenSize.height -= titleBarHeight;
                         if (imageSize.width > screenSize.width || imageSize.height > screenSize.height)
                         {
                             CGFloat fx = screenSize.width/std::max(imageSize.width, (CGFloat)1.f);
                             CGFloat fy = screenSize.height/std::max(imageSize.height, (CGFloat)1.f);
                             CGFloat min_f = std::min(fx, fy);
-                            scaledImageSize = [[window contentView] convertSizeFromBacking:imageSize];
+                            // -convertSizeFromBacking: is not declared in pre-10.7 SDKs;
+                            // call it through a typed IMP so the struct-return ABI is correct.
+                            typedef NSSize (*ConvertSizeFunc)(id, SEL, NSSize);
+                            ConvertSizeFunc convertFunc = (ConvertSizeFunc)[[window contentView] methodForSelector:@selector(convertSizeFromBacking:)];
+                            scaledImageSize = convertFunc([window contentView], @selector(convertSizeFromBacking:), imageSize);
                             scaledImageSize.width = std::min(scaledImageSize.width, min_f*imageSize.width);
                             scaledImageSize.height = std::min(scaledImageSize.height, min_f*imageSize.height);
                         }
                     }
                     NSSize contentSize = vrectOld.size;
-                    contentSize.height = scaledImageSize.height + [window contentView].sliderHeight;
+                    contentSize.height = scaledImageSize.height + [[window contentView] sliderHeight];
                     contentSize.width = std::max<int>(scaledImageSize.width, MIN_SLIDER_WIDTH);
                     [window setContentSize:contentSize]; //adjust sliders to fit new window size
                     if([window firstContent])
@@ -253,19 +285,19 @@ CV_IMPL void cvShowImage( const char* name, const CvArr* arr)
             }
             [window setFirstContent:NO];
         }
-    }
+    CV_AUTORELEASE_POOL_END
 }
 
 CV_IMPL void cvResizeWindow( const char* name, int width, int height)
 {
-    @autoreleasepool{
+    CV_AUTORELEASE_POOL_BEGIN
         CVWindow *window = cvGetWindow(name);
         if(window && ![window autosize]) {
-            height += [window contentView].sliderHeight;
+            height += [[window contentView] sliderHeight];
             NSSize size = { (CGFloat)width, (CGFloat)height };
             [window setContentSize:size];
         }
-    }
+    CV_AUTORELEASE_POOL_END
 }
 
 CV_IMPL void cvMoveWindow( const char* name, int x, int y)
@@ -278,7 +310,7 @@ CV_IMPL void cvMoveWindow( const char* name, int x, int y)
 
     if(name == NULL)
         CV_ERROR( CV_StsNullPtr, "NULL window name" );
-    @autoreleasepool{
+    CV_AUTORELEASE_POOL_BEGIN
         window = cvGetWindow(name);
         if(window) {
             if([window firstContent]) {
@@ -291,7 +323,7 @@ CV_IMPL void cvMoveWindow( const char* name, int x, int y)
                 [window setFrameTopLeftPoint:NSMakePoint(x, y)];
             }
         }
-    }
+    CV_AUTORELEASE_POOL_END
     __END__;
 }
 
@@ -308,7 +340,7 @@ CV_IMPL int cvCreateTrackbar (const char* trackbar_name,
     __BEGIN__;
     if(window_name == NULL)
         CV_ERROR( CV_StsNullPtr, "NULL window name" );
-    @autoreleasepool {
+    CV_AUTORELEASE_POOL_BEGIN
         window = cvGetWindow(window_name);
         if(window) {
             [window createSliderWithName:trackbar_name
@@ -317,7 +349,7 @@ CV_IMPL int cvCreateTrackbar (const char* trackbar_name,
                                 callback:on_notify];
             result = 1;
         }
-    }
+    CV_AUTORELEASE_POOL_END
     __END__;
     return result;
 }
@@ -330,7 +362,7 @@ CV_IMPL int cvCreateTrackbar2(const char* trackbar_name,
                               void* userdata)
 {
     int res = cvCreateTrackbar(trackbar_name, window_name, val, count, NULL);
-    @autoreleasepool{
+    CV_AUTORELEASE_POOL_BEGIN
         if(res) {
             CVWindow *window = cvGetWindow(window_name);
             if (window && [window respondsToSelector:@selector(sliders)]) {
@@ -339,7 +371,7 @@ CV_IMPL int cvCreateTrackbar2(const char* trackbar_name,
                 [slider setUserData:userdata];
             }
         }
-    }
+    CV_AUTORELEASE_POOL_END
     return res;
 }
 
@@ -353,13 +385,13 @@ cvSetMouseCallback( const char* name, CvMouseCallback function, void* info)
     __BEGIN__;
     if(name == NULL)
         CV_ERROR( CV_StsNullPtr, "NULL window name" );
-    @autoreleasepool{
+    CV_AUTORELEASE_POOL_BEGIN
         window = cvGetWindow(name);
         if(window) {
             [window setMouseCallback:function];
             [window setMouseParam:info];
         }
-    }
+    CV_AUTORELEASE_POOL_END
     __END__;
 }
 
@@ -374,7 +406,7 @@ cvSetMouseCallback( const char* name, CvMouseCallback function, void* info)
     if(trackbar_name == NULL || window_name == NULL)
         CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" );
 
-    @autoreleasepool{
+    CV_AUTORELEASE_POOL_BEGIN
         window = cvGetWindow(window_name);
         if(window && [window respondsToSelector:@selector(sliders)]) {
             CVSlider *slider = [[window sliders] valueForKey:[NSString stringWithFormat:@"%s", trackbar_name]];
@@ -382,7 +414,7 @@ cvSetMouseCallback( const char* name, CvMouseCallback function, void* info)
                 pos = [[slider slider] intValue];
             }
         }
-    }
+    CV_AUTORELEASE_POOL_END
     __END__;
     return pos;
 }
@@ -401,7 +433,7 @@ CV_IMPL void cvSetTrackbarPos(const char* trackbar_name, const char* window_name
     if(pos < 0)
         CV_ERROR( CV_StsOutOfRange, "Bad trackbar maximal value" );
 
-    @autoreleasepool{
+    CV_AUTORELEASE_POOL_BEGIN
         window = cvGetWindow(window_name);
         if(window && [window respondsToSelector:@selector(sliders)]) {
             slider = [[window sliders] valueForKey:[NSString stringWithFormat:@"%s", trackbar_name]];
@@ -412,7 +444,7 @@ CV_IMPL void cvSetTrackbarPos(const char* trackbar_name, const char* window_name
                 }
             }
         }
-    }
+    CV_AUTORELEASE_POOL_END
     __END__;
 }
 
@@ -427,7 +459,7 @@ CV_IMPL void cvSetTrackbarMax(const char* trackbar_name, const char* window_name
     if(trackbar_name == NULL || window_name == NULL)
         CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" );
 
-    @autoreleasepool{
+    CV_AUTORELEASE_POOL_BEGIN
         window = cvGetWindow(window_name);
         if(window && [window respondsToSelector:@selector(sliders)]) {
             slider = [[window sliders] valueForKey:[NSString stringWithFormat:@"%s", trackbar_name]];
@@ -439,7 +471,7 @@ CV_IMPL void cvSetTrackbarMax(const char* trackbar_name, const char* window_name
                 }
             }
         }
-    }
+    CV_AUTORELEASE_POOL_END
     __END__;
 }
 
@@ -454,7 +486,7 @@ CV_IMPL void cvSetTrackbarMin(const char* trackbar_name, const char* window_name
     if(trackbar_name == NULL || window_name == NULL)
         CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" );
 
-    @autoreleasepool{
+    CV_AUTORELEASE_POOL_BEGIN
         window = cvGetWindow(window_name);
         if(window && [window respondsToSelector:@selector(sliders)]) {
             slider = [[window sliders] valueForKey:[NSString stringWithFormat:@"%s", trackbar_name]];
@@ -466,7 +498,7 @@ CV_IMPL void cvSetTrackbarMin(const char* trackbar_name, const char* window_name
                 }
             }
         }
-    }
+    CV_AUTORELEASE_POOL_END
     __END__;
 }
 
@@ -478,14 +510,18 @@ CV_IMPL void* cvGetWindowHandle( const char* name )
 
 CV_IMPL const char* cvGetWindowName( void* window_handle )
 {
-    @autoreleasepool{
-        for(NSString *key in windows) {
+    const char* name = 0;
+    CV_AUTORELEASE_POOL_BEGIN
+        NSEnumerator *enumerator = [windows keyEnumerator];
+        NSString *key;
+        while((key = [enumerator nextObject]) != nil) {
             if([windows valueForKey:key] == window_handle) {
-                return [key UTF8String];
+                name = [key UTF8String];
+                break;
             }
         }
-    }
-    return 0;
+    CV_AUTORELEASE_POOL_END
+    return name;
 }
 
 CV_IMPL int cvNamedWindow( const char* name, int flags )
@@ -493,58 +529,62 @@ CV_IMPL int cvNamedWindow( const char* name, int flags )
     if( !wasInitialized )
         cvInitSystem(0, 0);
 
-    @autoreleasepool{
+    int result = -1;
+    CV_AUTORELEASE_POOL_BEGIN
         CVWindow *window = cvGetWindow(name);
         if( window )
         {
             [window setAutosize:(flags == CV_WINDOW_AUTOSIZE)];
-            return 0;
-        }
-
-        NSScreen* mainDisplay = [NSScreen mainScreen];
-        NSString *windowName = [NSString stringWithFormat:@"%s", name];
-        NSUInteger showResize = NSResizableWindowMask;
-        NSUInteger styleMask = NSTitledWindowMask|NSMiniaturizableWindowMask|showResize;
-        CGFloat windowWidth = [NSWindow minFrameWidthWithTitle:windowName styleMask:styleMask];
-        NSRect initContentRect = NSMakeRect(0, 0, windowWidth, 0);
-        if (mainDisplay) {
-            NSRect dispFrame = [mainDisplay visibleFrame];
-            initContentRect.origin.y = dispFrame.size.height-20;
+            result = 0;
         }
+        else
+        {
+            NSScreen* mainDisplay = [NSScreen mainScreen];
+            NSString *windowName = [NSString stringWithFormat:@"%s", name];
+            NSUInteger showResize = NSResizableWindowMask;
+            NSUInteger styleMask = NSTitledWindowMask|NSMiniaturizableWindowMask|showResize;
+            CGFloat windowWidth = [NSWindow minFrameWidthWithTitle:windowName styleMask:styleMask];
+            NSRect initContentRect = NSMakeRect(0, 0, windowWidth, 0);
+            if (mainDisplay) {
+                NSRect dispFrame = [mainDisplay visibleFrame];
+                initContentRect.origin.y = dispFrame.size.height-20;
+            }
 
-        window = [[CVWindow alloc] initWithContentRect:initContentRect
-                                            styleMask:NSTitledWindowMask|NSMiniaturizableWindowMask|showResize
-                                            backing:NSBackingStoreBuffered
-                                                defer:YES
-                                                screen:mainDisplay];
+            window = [[CVWindow alloc] initWithContentRect:initContentRect
+                                                styleMask:NSTitledWindowMask|NSMiniaturizableWindowMask|showResize
+                                                backing:NSBackingStoreBuffered
+                                                    defer:YES
+                                                    screen:mainDisplay];
 
-        [window setFrameTopLeftPoint:initContentRect.origin];
+            [window setFrameTopLeftPoint:initContentRect.origin];
 
-        [window setFirstContent:YES];
-        [window setX0:-1];
-        [window setY0:-1];
+            [window setFirstContent:YES];
+            [window setX0:-1];
+            [window setY0:-1];
 
-        [window setContentView:[[CVView alloc] init]];
+            [window setContentView:[[CVView alloc] init]];
 
-        [NSApp activateIgnoringOtherApps:YES];
+            [NSApp activateIgnoringOtherApps:YES];
 
-        [window setHasShadow:YES];
-        [window setAcceptsMouseMovedEvents:YES];
-        [window useOptimizedDrawing:YES];
-        [window setTitle:windowName];
-        [window makeKeyAndOrderFront:nil];
+            [window setHasShadow:YES];
+            [window setAcceptsMouseMovedEvents:YES];
+            [window useOptimizedDrawing:YES];
+            [window setTitle:windowName];
+            [window makeKeyAndOrderFront:nil];
 
-        [window setAutosize:(flags == CV_WINDOW_AUTOSIZE)];
+            [window setAutosize:(flags == CV_WINDOW_AUTOSIZE)];
 
-        [windows setValue:window forKey:windowName];
-        return [windows count]-1;
-    }
+            [windows setValue:window forKey:windowName];
+            result = [windows count]-1;
+        }
+    CV_AUTORELEASE_POOL_END
+    return result;
 }
 
 CV_IMPL int cvWaitKey (int maxWait)
 {
     int returnCode = -1;
-    @autoreleasepool{
+    CV_AUTORELEASE_POOL_BEGIN
         double start = [[NSDate date] timeIntervalSince1970];
 
         while(true) {
@@ -568,8 +608,8 @@ CV_IMPL int cvWaitKey (int maxWait)
 
             [NSThread sleepForTimeInterval:1/100.];
         }
-        return returnCode;
-    }
+    CV_AUTORELEASE_POOL_END
+    return returnCode;
 }
 
 CvRect cvGetWindowRect_COCOA( const char* name )
@@ -590,16 +630,16 @@ CvRect cvGetWindowRect_COCOA( const char* name )
     {
         CV_ERROR( CV_StsNullPtr, "NULL window" );
     } else {
-        @autoreleasepool {
+        CV_AUTORELEASE_POOL_BEGIN
             NSRect rect = [window frame];
-#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_6
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
             NSPoint pt = [window convertRectToScreen:rect].origin;
 #else
             NSPoint pt = [window convertBaseToScreen:rect.origin];
 #endif
             NSSize sz = [[[window contentView] image] size];
             result = cvRect(pt.x, pt.y, sz.width, sz.height);
-        }
+        CV_AUTORELEASE_POOL_END
     }
     __END__;
     return result;
@@ -624,7 +664,7 @@ double cvGetModeWindow_COCOA( const char* name )
         CV_ERROR( CV_StsNullPtr, "NULL window" );
     }
 
-    result = window.status;
+    result = [window status];
     __END__;
     return result;
 }
@@ -633,7 +673,7 @@ void cvSetModeWindow_COCOA( const char* name, double prop_value )
 {
     CVWindow *window = nil;
 
-#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
     NSDictionary *fullscreenOptions = nil;
 #endif
 
@@ -656,13 +696,13 @@ void cvSetModeWindow_COCOA( const char* name, double prop_value )
         return;
     }
 
-    @autoreleasepool{
-#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_6
+    CV_AUTORELEASE_POOL_BEGIN
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
         if ( ([window styleMask] & NSFullScreenWindowMask) && prop_value==CV_WINDOW_NORMAL )
         {
             [window toggleFullScreen:nil];
 
-            window.status=CV_WINDOW_NORMAL;
+            [window setStatus:CV_WINDOW_NORMAL];
         }
         else if( !([window styleMask] & NSFullScreenWindowMask) && prop_value==CV_WINDOW_FULLSCREEN )
         {
@@ -679,22 +719,22 @@ void cvSetModeWindow_COCOA( const char* name, double prop_value )
 
             [window setFrameTopLeftPoint: frame.origin];
 
-            window.status=CV_WINDOW_FULLSCREEN;
+            [window setStatus:CV_WINDOW_FULLSCREEN];
         }
 #else
         fullscreenOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:NSFullScreenModeSetting];
         if ( [[window contentView] isInFullScreenMode] && prop_value==CV_WINDOW_NORMAL )
         {
             [[window contentView] exitFullScreenModeWithOptions:fullscreenOptions];
-            window.status=CV_WINDOW_NORMAL;
+            [window setStatus:CV_WINDOW_NORMAL];
         }
         else if( ![[window contentView] isInFullScreenMode] && prop_value==CV_WINDOW_FULLSCREEN )
         {
             [[window contentView] enterFullScreenMode:[NSScreen mainScreen] withOptions:fullscreenOptions];
-            window.status=CV_WINDOW_FULLSCREEN;
+            [window setStatus:CV_WINDOW_FULLSCREEN];
         }
 #endif
-    }
+    CV_AUTORELEASE_POOL_END
 
     __END__;
 }
@@ -718,7 +758,7 @@ double cvGetPropVisible_COCOA(const char* name)
         CV_ERROR(CV_StsNullPtr, "NULL window");
     }
 
-    result = window.isVisible ? 1 : 0;
+    result = [window isVisible] ? 1 : 0;
 
     __END__;
     return result;
@@ -743,7 +783,7 @@ double cvGetPropTopmost_COCOA(const char* name)
         CV_ERROR(CV_StsNullPtr, "NULL window");
     }
 
-    result = (window.level == NSStatusWindowLevel) ? 1 : 0;
+    result = ([window level] == NSStatusWindowLevel) ? 1 : 0;
 
     __END__;
     return result;
@@ -759,35 +799,37 @@ void cvSetPropTopmost_COCOA( const char* name, const bool topmost )
     {
         CV_ERROR( CV_StsNullPtr, "NULL name string" );
     }
-    @autoreleasepool{
-        window = cvGetWindow(name);
-        if ( window == NULL )
-        {
-            CV_ERROR( CV_StsNullPtr, "NULL window" );
-        }
-
-        if (([window styleMask] & NSFullScreenWindowMask))
-        {
-            EXIT;
-        }
+    window = cvGetWindow(name);
+    if ( window == NULL )
+    {
+        CV_ERROR( CV_StsNullPtr, "NULL window" );
+    }
 
-        if (topmost)
-        {
-            [window makeKeyAndOrderFront:window.self];
-            [window setLevel:CGWindowLevelForKey(kCGMaximumWindowLevelKey)];
-        }
-        else
+    CV_AUTORELEASE_POOL_BEGIN
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+        const bool isFullScreen = ([window styleMask] & NSFullScreenWindowMask) != 0;
+#else
+        const bool isFullScreen = false;
+#endif
+        if (!isFullScreen)
         {
-            [window makeKeyAndOrderFront:nil];
+            if (topmost)
+            {
+                [window makeKeyAndOrderFront:window];
+                [window setLevel:CGWindowLevelForKey(kCGMaximumWindowLevelKey)];
+            }
+            else
+            {
+                [window makeKeyAndOrderFront:nil];
+            }
         }
-    }
+    CV_AUTORELEASE_POOL_END
     __END__;
 }
 
 void setWindowTitle_COCOA(const cv::String& winname, const cv::String& title)
 {
-
-    @autoreleasepool{
+    CV_AUTORELEASE_POOL_BEGIN
         CVWindow *window = cvGetWindow(winname.c_str());
 
         if (window == NULL)
@@ -801,10 +843,33 @@ void setWindowTitle_COCOA(const cv::String& winname, const cv::String& title)
 
         NSString *windowTitle = [NSString stringWithFormat:@"%s", title.c_str()];
         [window setTitle:windowTitle];
-    }
+    CV_AUTORELEASE_POOL_END
+}
 
+#ifdef HAVE_OPENGL
+
+// The Cocoa backend does not implement OpenGL windows. These stubs make
+// highgui link when OpenCV is configured with WITH_OPENGL=ON (which enables
+// cv::ogl interoperability in the core module); window-related OpenGL
+// functionality remains unavailable.
+
+CV_IMPL void cvSetOpenGlDrawCallback(const char*, CvOpenGlDrawCallback, void*)
+{
+    CV_Error(cv::Error::OpenGlNotSupported, "OpenGL windows are not supported by the Cocoa backend");
 }
 
+CV_IMPL void cvSetOpenGlContext(const char*)
+{
+    CV_Error(cv::Error::OpenGlNotSupported, "OpenGL windows are not supported by the Cocoa backend");
+}
+
+CV_IMPL void cvUpdateWindow(const char*)
+{
+    CV_Error(cv::Error::OpenGlNotSupported, "OpenGL windows are not supported by the Cocoa backend");
+}
+
+#endif // HAVE_OPENGL
+
 static NSSize constrainAspectRatio(NSSize base, NSSize constraint) {
     CGFloat heightDiff = (base.height / constraint.height);
     CGFloat widthDiff = (base.width / constraint.width);
@@ -837,28 +902,40 @@ static NSSize constrainAspectRatio(NSSize base, NSSize constraint) {
 - (void)cvSendMouseEvent:(NSEvent *)event type:(int)type flags:(int)flags {
     (void)event;
     NSPoint mp = [NSEvent mouseLocation];
-    mp = [self convertScreenToBase: mp];
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+    if ([self respondsToSelector:@selector(convertRectFromScreen:)]) {
+        NSRect screenRect = NSMakeRect(mp.x, mp.y, 0, 0);
+        mp = [self convertRectFromScreen:screenRect].origin;
+    } else
+#endif
+    {
+        mp = [self convertScreenToBase: mp];
+    }
     CVView *contentView = [self contentView];
     NSSize viewSize = contentView.frame.size;
-    if (contentView.imageView) {
-        viewSize = contentView.imageView.frame.size;
+    if ([contentView imageView]) {
+        viewSize = [[contentView imageView] frame].size;
     }
     else {
-        viewSize.height -= contentView.sliderHeight;
+        viewSize.height -= [contentView sliderHeight];
     }
     mp.y = viewSize.height - mp.y;
 
-    NSSize imageSize = contentView.image.size;
-    mp.y *= (imageSize.height / std::max(viewSize.height, 1.));
-    mp.x *= (imageSize.width / std::max(viewSize.width, 1.));
-
-    if( [event type] == NSEventTypeScrollWheel ) {
-        if( event.hasPreciseScrollingDeltas ) {
-            mp.x = int(event.scrollingDeltaX);
-            mp.y = int(event.scrollingDeltaY);
-        } else {
-            mp.x = int(event.scrollingDeltaX / 0.100006);
-            mp.y = int(event.scrollingDeltaY / 0.100006);
+    NSSize imageSize = [[contentView image] size];
+    mp.y *= (imageSize.height / std::max(viewSize.height, (CGFloat)1.));
+    mp.x *= (imageSize.width / std::max(viewSize.width, (CGFloat)1.));
+
+    if( [event type] == NSScrollWheel ) {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+        // scrollingDelta* are 10.7+ APIs; fall back to line-based deltas below
+        if( [event respondsToSelector:@selector(hasPreciseScrollingDeltas)] && [event hasPreciseScrollingDeltas] ) {
+            mp.x = int([event scrollingDeltaX]);
+            mp.y = int([event scrollingDeltaY]);
+        } else
+#endif
+        {
+            mp.x = int([event deltaX] * 10.0);
+            mp.y = int([event deltaY] * 10.0);
         }
         if( mp.x && !mp.y && cv::EVENT_MOUSEWHEEL == type ) {
             type = cv::EVENT_MOUSEHWHEEL;
@@ -899,7 +976,7 @@ static NSSize constrainAspectRatio(NSSize base, NSSize constraint) {
     if([event type] == NSLeftMouseDragged) {[self cvSendMouseEvent:event type:cv::EVENT_MOUSEMOVE   flags:flags | cv::EVENT_FLAG_LBUTTON];}
     if([event type] == NSRightMouseDragged)	{[self cvSendMouseEvent:event type:cv::EVENT_MOUSEMOVE   flags:flags | cv::EVENT_FLAG_RBUTTON];}
     if([event type] == NSOtherMouseDragged)	{[self cvSendMouseEvent:event type:cv::EVENT_MOUSEMOVE   flags:flags | cv::EVENT_FLAG_MBUTTON];}
-    if([event type] == NSEventTypeScrollWheel) {[self cvSendMouseEvent:event type:cv::EVENT_MOUSEWHEEL   flags:flags ];}
+    if([event type] == NSScrollWheel) {[self cvSendMouseEvent:event type:cv::EVENT_MOUSEWHEEL   flags:flags ];}
 }
 
 -(void)scrollWheel:(NSEvent *)theEvent {
@@ -955,7 +1032,7 @@ static NSSize constrainAspectRatio(NSSize base, NSSize constraint) {
     // Create slider
     CVSlider *slider = [[CVSlider alloc] init];
     [[slider name] setStringValue:cvname];
-    slider.initialName = [NSString stringWithFormat:@"%s", name];
+    [slider setInitialName:[NSString stringWithFormat:@"%s", name]];
     [[slider slider] setMaxValue:max];
     [[slider slider] setMinValue:0];
     if(value)
@@ -981,7 +1058,7 @@ static NSSize constrainAspectRatio(NSSize base, NSSize constraint) {
     viewSize.width = std::max<int>(viewSize.width, MIN_SLIDER_WIDTH);
 
     // Update slider sizes
-    [self contentView].sliderHeight += sliderSize.height;
+    [[self contentView] setSliderHeight:[[self contentView] sliderHeight] + sliderSize.height];
 
     if ([[self contentView] image] && ![[self contentView] imageView]) {
         [[self contentView] setNeedsDisplay:YES];
@@ -999,7 +1076,9 @@ static NSSize constrainAspectRatio(NSSize base, NSSize constraint) {
 
 @implementation CVView
 
+@synthesize imageView;
 @synthesize image;
+@synthesize sliderHeight;
 
 - (id)init {
     [super init];
@@ -1008,7 +1087,7 @@ static NSSize constrainAspectRatio(NSSize base, NSSize constraint) {
 
 - (void)setImageData:(CvArr *)arr {
     cv::Mat arrMat = cv::cvarrToMat(arr);
-    @autoreleasepool{
+    CV_AUTORELEASE_POOL_BEGIN
         NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
                     pixelsWide:arrMat.cols
                     pixelsHigh:arrMat.rows
@@ -1070,7 +1149,7 @@ static NSSize constrainAspectRatio(NSSize base, NSSize constraint) {
             redisplayRect.size.height -= [self sliderHeight];
             [self setNeedsDisplayInRect:redisplayRect];
         }
-    }
+    CV_AUTORELEASE_POOL_END
 }
 
 - (void)setFrameSize:(NSSize)size {
@@ -1078,19 +1157,22 @@ static NSSize constrainAspectRatio(NSSize base, NSSize constraint) {
 
     int height = size.height;
 
-    @autoreleasepool{
+    CV_AUTORELEASE_POOL_BEGIN
         CVWindow *cvwindow = (CVWindow *)[self window];
         if ([cvwindow respondsToSelector:@selector(sliders)]) {
-            for(NSString *key in [cvwindow slidersKeys]) {
+            NSEnumerator *enumerator = [[cvwindow slidersKeys] objectEnumerator];
+            NSString *key;
+            while((key = [enumerator nextObject]) != nil) {
                 CVSlider *slider = [[cvwindow sliders] valueForKey:key];
                 NSRect r = [slider frame];
                 r.origin.y = height - r.size.height;
                 r.size.width = [[cvwindow contentView] frame].size.width;
 
-                CGRect sliderRect = slider.slider.frame;
+                // NSRect and CGRect are distinct types in 32-bit builds
+                NSRect sliderRect = [[slider slider] frame];
                 CGFloat targetWidth = r.size.width - (sliderRect.origin.x + 10);
                 sliderRect.size.width = targetWidth < 0 ? 0 : targetWidth;
-                slider.slider.frame = sliderRect;
+                [[slider slider] setFrame:sliderRect];
 
                 [slider setFrame:r];
                 height -= r.size.height;
@@ -1107,21 +1189,21 @@ static NSSize constrainAspectRatio(NSSize base, NSSize constraint) {
             NSRect constrainedFrame = { imageViewFrame.origin, constrainAspectRatio(imageViewFrame.size, [image size]) };
             [[self imageView] setFrame:constrainedFrame];
         }
-    }
+    CV_AUTORELEASE_POOL_END
 }
 
 - (void)drawRect:(NSRect)rect {
     [super drawRect:rect];
     // If imageView exists, all drawing will be done by it and nothing needs to happen here
     if ([self image] && ![self imageView]) {
-        @autoreleasepool{
+        CV_AUTORELEASE_POOL_BEGIN
             if(image != nil) {
                 [image drawInRect: [self frame]
                         fromRect: NSZeroRect
                         operation: NSCompositeSourceOver
                         fraction: 1.0];
             }
-        }
+        CV_AUTORELEASE_POOL_END
     }
 }
 
