The biggest problem I encountered with OpenCV windows on macOS is that they never open on top of my current window when an application using OpenCV is launched. So I created a helper function that does just that.

Let’s start with the code:

#ifdef __APPLE__
#  include <objc/runtime.h>
#  include <objc/message.h>
#  include <objc/NSObjCRuntime.h>
#endif

inline void createWindow(const std::string& name)
{
    cv::namedWindow(name);

#ifdef __APPLE__
    Class applicationClass = objc_getClass("NSApplication");
    id application = reinterpret_cast<id (*)(Class, SEL)>(&objc_msgSend)(applicationClass, sel_getUid("sharedApplication")); // [NSApplication sharedApplication]

    id windows = reinterpret_cast<id (*)(id, SEL)>(&objc_msgSend)(application, sel_getUid("windows")); // [application windows]

    NSUInteger windowCount = reinterpret_cast<NSUInteger (*)(id, SEL)>(&objc_msgSend)(windows, sel_getUid("count")); // [windows count]

    for (NSUInteger i = 0; i < windowCount; ++i)
    {
        id window = reinterpret_cast<id (*)(id, SEL, NSUInteger)>(&objc_msgSend)(windows, sel_getUid("objectAtIndex:"), i); // [windows objectAtIndex:i]
        id title = reinterpret_cast<id (*)(id, SEL)>(&objc_msgSend)(window, sel_getUid("title")); // [window title]
        const char* titleString = reinterpret_cast<const char* (*)(id, SEL)>(&objc_msgSend)(title, sel_getUid("UTF8String")); // [string UTF8String]
        if (name == titleString)
            reinterpret_cast<void (*)(id, SEL)>(&objc_msgSend)(window, sel_getUid("orderFrontRegardless")); // [window orderFrontRegardless]
    }
#endif
}

I added #ifdef __APPLE__ so that the code get’s compilet only on macOS. First I create the OpenCV window with cv::namedWindow. I use Objective-C runtime functions to send Objective-C messages. I get an instance of NSApplication class by calling the C equivalent of [NSApplication sharedApplication]. After getting the pointer of the main application I get the list of all windows ([application windows]) and iterate through them ([windows count]). For every window ([windows objectAtIndex:i]) I get its title ([window title]) convert it to C string ([string UTF8String]) and compare it to the name of the window. If they match, then I bring it to front ([window orderFrontRegardless]).

To use the code just call createWindow instead of cv::namedWindow.