Latest tip, no mouseDown events

Did you find the cause of this problem? I cannot reproduce it here but some users of our software are reporting exactly the same problem.

well no i moved back with the juce version to the one i posted above, that’s my “fix” for now.

FWIW we got similar issues (without Juce) when the host relies on VST deprecated method “mouse”

If for some reasons your plugin stops to provide handling for the VST effEditMouse callback, then mouse down events no longer works in certain situations.

This happened to us here when switching from VSTGui 3.5 to 3.6. VstGUI 3.6 by default set VSTGUI_ENABLE_DEPRECATED_METHODS to 0.
This makes the mouse handler “long AEffGUIEditor::mouse (long x, long y)” virtually empty.

Setting VST_FORCE_DEPRECATED to 0 would have similar effects (see audioeffect.cpp from VST SDK, around line 192 – dispatcher code for effEditMouse).

[quote=“atom”]…this weird bug happens only in some hosts[/quote]I think I (well, a tester) may have stumbled across this bug with Maschine. Obviously there’s no Maschine downloadable demo, so I was just enquiring as to what hosts you’d witnessed this problem in? Assuming it’s the same, I’d like to take a crack at fixing it, but I’d need to recreate the bug in-house. Thanks! Edit: I’m an idiot, you did list them already. Time to install Live 7, methinks!

I’ve tracked down the change that causes this problem, but I’m stumped to why it causes this, and even more so as to what the line actually does! The code in question is in juce_mac_SystemStats.mm :

[code]#if JUCE_MAC
struct SharedAppInitialiser
{
SharedAppInitialiser()
{
JUCE_AUTORELEASEPOOL
[NSApplication sharedApplication];

    rlimit lim;
    getrlimit (RLIMIT_NOFILE, &lim);
    lim.rlim_cur = lim.rlim_max = RLIM_INFINITY;
    setrlimit (RLIMIT_NOFILE, &lim);
}

};

static SharedAppInitialiser sharedAppInitialiser;
#endif[/code]

If you comment out the [NSApplication sharedApplication]; line, it seems to works fine (caveat: only smoke-tested on Mac OS X 10.5 / VST). Add the line back, and mouseDown events don’t get through to your plug-in.

[code] SharedAppInitialiser()
{
JUCE_AUTORELEASEPOOL
//[NSApplication sharedApplication];

    rlimit lim;
    getrlimit (RLIMIT_NOFILE, &lim);[/code]

Actually, the situation is (unsurprisingly) slightly more complex than that: if your host first loads a JUCE plug-in that used an older codebase (back when this getrlimit was in an initialiseStats function), and then loads a different JUCE plug-in that uses the sharedApplication method, it’ll work fine. If you load a sharedApplication plug-in first, and then the older one, neither respond to mouseDowns. Actually, it’s even more complicated than THAT: it works fine for some hosts (Kore in Live 8 ) and not for others (Kore in Live 7).

So, any thoughts? Or am I going to have to brush up on my Objective-C garbage collecting, and do a little more investigation?

The sharedApplication call initialises the global NSApplication object, which is shared amongst all the modules. It was required in the past for some kind of complicated reason involving Carbon compatibility, the details of which escape me…

I think you’re referring to NSApplicationLoad(), which (quoth the documentation) "You typically call this function before calling other Cocoa code in a plug-in loaded into a primarily Carbon application. If the shared NSApplication object is not already initialized, this function initializes it and sets up the necessary event handlers for Cocoa. " This is called in the juce_VST_Wrapper.mm, from initialiseMac().

I’m way outside my field of expertise when it comes to Objective-C, but would this be at odds with the [NSApplication sharedApplication]; call, which, being in the constructor of a static object, will occur before the VST wrapper calls NSApplicationLoad?

You’re right: instancing of the NSApplication is required for Mac Apps, otherwise you get a crash and “Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘Error (1002) creating CGSWindow’”. However, it is not needed for plug-ins, and indeed appears to cause problems: I’ve confirmed this with AU, VST, and RTAS projects (smoke tested Carbon and Cocoa UIs, 32-bit, 64-bit, and PPC architectures).

So, perhaps the solution is to move the NSApplication instancing so that it is only called when required - juce_Application would seem the sensible place. I’m proposing: adding the declaration to juce_Application.cpp :

#if JUCE_MAC extern void juce_initialiseMacMainMenu(); extern void juce_initialiseCocoaApp(); #endif

Calling it in the juce_Application constructor:

JUCEApplication::JUCEApplication() : appReturnValue (0), stillInitialising (true) { jassert (isStandaloneApp() && appInstance == nullptr); appInstance = this; #if JUCE_MAC juce_initialiseCocoaApp(); #endif }

And then cleaving the SharedApp initialisation into two separate methods:

[code]#if JUCE_MAC
struct SharedAppInitialiser
{
SharedAppInitialiser()
{
JUCE_AUTORELEASEPOOL
rlimit lim;
getrlimit (RLIMIT_NOFILE, &lim);
lim.rlim_cur = lim.rlim_max = RLIM_INFINITY;
setrlimit (RLIMIT_NOFILE, &lim);
}
};

static SharedAppInitialiser sharedAppInitialiser;

void juce_initialiseCocoaApp()
{
[NSApplication sharedApplication];
}
#endif[/code]

Hmm, yes, that does make a lot of sense! Thanks, I’ll see if I can do something along those lines…