Quitting while popup showing causes assert

Hi I’m current doing this which is probably over the top, but I’m still getting a jassert (masterReference.getNumActiveWeakReferences() == 0 assert when I:

~MyplugAudioProcessorEditor()
{
	setLookAndFeel(nullptr);
	popupMenu.setLookAndFeel(nullptr);
	popupMenu.dismissAllActiveMenus();
	popupMenu.clear();
}

How do I quit properly while a popup menu is showing? For example - bring up menu, then quit the host.
This is on Windows, I haven’t tried Mac yet.
Thanks.
Dave

It doesn’t assert when have a break point in the destructor, which I presume gives it enough time to dismiss the menu.
So I need a way of making sure the popup is properly gone before quitting.
I can still see the menu on screen when it calls the assert. ( I’m using FL Studio which quits very quickly)

It looks like I have to use the general look with:

LookAndFeel::setDefaultLookAndFeel(popupLook);
Not forgetting to null it on the GUI destructor.

to set the look of the menu, NOT…

popupMenu->setLookAndFeel(popupLook)
Which nulling in destructor fires the assert later. Which I guess is a bug.

Have you tried using your lookandfeel object created in the editor object and fetching that instance into your popup? Will need a parameter in your popup constructor to feed your editor pointer in there unless you fetch the parent component in some other way. But that’s what I’ve done and no problems with assertions. That way the lookandfeel stays alive until the whole editor is destroyed. Dunno if it’s wise to do so… but works. :slight_smile:

I had a strange problem with setDefaultLookAndFeel();
When I have 2 open instances and I delete one of them the default look-and-feel gets reset to the standard look-and-feel in the other. I had to close and reopen the window so that LookAndFeel::setDefaultLookAndFeel() gets called again.
So in the end I started using the components setLookAndFeel() and just reset it in the destructor.
Maybe something to test.

I was doing this:

editor class ....
ScopedPointer<PopupMenuLookAndFeel> popupLook;

Which is what I do for the components, whose references get nulled in the destructor. And all is fine. But of course the popup menu is not a component class.

So this happens when you call quit() as result of the PopupMenu?

It sounds to me like you are quitting synchronously, while closing the popupMenu would happen asynchronously afterwards.

One suggestion would be to call the quit using MessageManager::callAsync().

Bugger!! Thanks! You’re right, closing the second instance removes the look and feel from the first.
Damn it! I though I’d finished with this nightmare! :frowning:

Thanks for the reply, I nearly missed it.
The popup is open when I quit the host.
Where would I call ‘MessageManager::callAsync()’ ?

Same problem here:

The async closing of the PopupMenu is the problem, as the lookAndFeel() will be destroyed already.

Exactly. How do I force it to go away or wait for it to finish?

Unfortunately, I have no idea… Maybe @daniel has more insights of what is possible here.
However, it’s just an assertion which probably won’t affect the release builds. But for debugging, it’s quite annoying.

To activate the quit after the popup menu had the chance to finish, you would call:

if (result == quitID)
{
    MessageManager::callAsync ([](){ JUCEApplication::quit(); });
}

And about dismissing the menu manually:

dismissAllActiveMenus() is a static method. If you call this on an instance, it can’t work, because that would require the menu to commit suicide. Call it instead like:

PopupMenu::dismissAllActiveMenus();

I would take an assertion seriously, since it is an indicator, that a condition is not met, that a further operation might rely on (and therefore might crash there later).

Hope that helps

Addition: if you set your lookAndFeel to the popupmenu, you should probably make sure the popup is dismissed before you delete the lookAndFeel (in your case it should be safe, since you are only resetting it to nullptr, the deletion of the ScopedPointer happens only once the destructor has finished).

That does not work, as dismissAllActiveMenus() is an async call, and it won’t be processed in time.

I used that project and added PopupMenu::dismissAllActiveMenus(); to the Editor’s destructor in my local copy, and I still get the assertion. It’s the async call…

Sorry to be so direct but: could someone give us a solution for exactly that problem, using my minimal project which shows this problem? I would appreciate it :slight_smile:

How to reproduce with the project: Just load that plug-in into the JUCE plug-in host, click the comboBox and close the plugin-host (e.g. cmd+q on mac). Even closing the plug-in window triggers that assertion.

1 Like

Yes you are quite correct about the dismiss not working as you can see in my first post. I have found the way to make the default look and feel work properly with multiple instances -you have to set it as default very time the popup is about to be shown. This is all kinds of quirky though.

Also PopupMenu::dismissAllActiveMenus() does not work either, like danielrudrich says. The menu stays on the screen and the assert is still fired.

I just ran DanielRudrich’s code in FL Studio in Windows and yep, I get the same assert.

Well I can’t get rid of that assert, Daniel, I hope we’re not being ignored.

Sorry @DaveH, I had a look into it, and I can reproduce it. But I had to leave it after looking into it for quite some time, since I am not really assigned to JUCE but other projects here inside Roli.

1 Like

You’re not being ignored. As a few people in this thread have already established it’s not a trivial fix, so it’s going to take a little while to implement anything differently. Whilst it is no doubt annoying it’s also not going to cause any problems in release builds, which in turn lowers its priority a little.

1 Like