OSX - Quit menu does not call the callback

lmgava wrote on Friday, January 03, 2014:

I’ve registered the callback through glfwSetWindowCloseCallback(), and it’s called as expected if I click on the close button on the window.

The OSX menu works for Hide, but not for Quit.
The callback is not called.

I’ve tried to compile the .dylib by setting and removing the GLFW_USE_MENUBAR option using CMake but nothing changed.

I’m using OSX 10.8.5 ML, and the 64 bit version of the dynamic library (glfw 3.0.4).

Any ideas ? Is this a bug ? Am I doing something wrong ?

Thanks!

Luis

EDIT: forgot to mention the relevant point in the the docs:

“OS X: Selecting Quit from the application menu will trigger the close callback for all windows”

lmgava wrote on Saturday, January 04, 2014:

If it can be useful in diagnosing the problem (if any), this is the configuration string returned by glfwGetVersionString()

“3.0.4 Cocoa NSGL chdir menubar dynamic”

Thanks

lmgava wrote on Sunday, January 05, 2014:

I’ve made some experiments. “Quit” works with your examples, namely “Simple”.
With “Simple” I have also a menu with an “About Simple”.
Probably this “menu building” is based on the contents of the bundle ? Maybe Info.plist ?
Problem is I’m not using XCode or C as my language.
I’m using PureBasic, a cross platform x86/x64 compiler.
I’ve made a wrapper/binder for your dylib. Basically it’s just a conversion of the include files with some calls to bind the functions inside the library.
It all works, on Win/Lin/OSX.
The only problem I have is with the menu on osx. The Info.plist generated by PureBasic has a lot less entries than the one generated using the native OSX compiler, and if you use that info to build the menu that could explain why the “about” is missing and the “quit” doesn’t work.

Ouch…

EDIT: no, it’s not that because I’ve tried to “unbundle” the Simple executable from the .app, copied it all alone on the desktop and both the “about” and “quit” menu continued to work.

I’m at a loss, unfortunately I’ve just started to look at a MAC and so its Cocoa-inner-workings are still quite a mystery to me. In fact I was hoping to use glfw to avoid to know about them.

EDIT: Thanks to another user on the PB forum (Danilo) now all is sorted out

// Initialize the Cocoa Application Kit
//
static GLboolean initializeAppKit(void)
{
    if (NSApp)
        return GL_TRUE;

    // Implicitly create shared NSApplication instance
    [GLFWApplication sharedApplication];

    // In case we are unbundled, make us a proper UI application
    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];

#if defined(_GLFW_USE_MENUBAR)
    // Menu bar setup must go between sharedApplication above and
    // finishLaunching below, in order to properly emulate the behavior
    // of NSApplicationMain
    createMenuBar();
#endif

    [NSApp finishLaunching];

    return GL_TRUE;
}

The problem was:

    if (NSApp)
        return GL_TRUE;

Using PB the (NSApp) was always TRUE and so the code after that was never executed.

Modifying the code this way:

bool appKitAlreadyInitialized = false;

// Initialize the Cocoa Application Kit
//
static GLboolean initializeAppKit(void)
{
    if ((appKitAlreadyInitialized == true) && NSApp)
        return GL_TRUE;

    appKitAlreadyInitialized = true;

    // Implicitly create shared NSApplication instance
    [GLFWApplication sharedApplication];

    // In case we are unbundled, make us a proper UI application
    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];

#if defined(_GLFW_USE_MENUBAR)
    // Menu bar setup must go between sharedApplication above and
    // finishLaunching below, in order to properly emulate the behavior
    // of NSApplicationMain
    createMenuBar();
#endif

    [NSApp finishLaunching];

    return GL_TRUE;
}

fixed the problem.