PopupMenu destruction


#1

Hi,

I’d like to add a popup when right clicking on a component but I am having a hard time. When I display a popup which has submenus, move over an item that opens a submenu to trigger the opening (without going into the submenu) and then click away from the popup, PopupMenu::Window::inputAttemptWhenModal() tries to call isOverAnyMenu() at a point where the window has already been freed which results in a crash.

A breakpoint in PopupMenu::Window::~Window() gives me the following call stack. The crash happends in inputAttemptWhenModal as soon as timerCallback has returned.

vst.dll!juce::PopupMenu::Window::~Window() Line 306 C++ vst.dll!juce::PopupMenu::Window::`scalar deleting destructor'() + 0x14 bytes C++ vst.dll!juce::ScopedPointer<juce::PopupMenu::Window>::operator=(juce::PopupMenu::Window * const newObjectToTakePossessionOf=0x00000000) Line 124 + 0x20 bytes C++ vst.dll!juce::PopupMenu::Window::hide(const juce::PopupMenu::Item * const item=0x00000000) Line 437 C++ vst.dll!juce::PopupMenu::Window::dismissMenu(const juce::PopupMenu::Item * const item=0x00000000) Line 470 C++ vst.dll!juce::PopupMenu::Window::dismissMenu(const juce::PopupMenu::Item * const item=0x00000000) Line 457 C++ vst.dll!juce::PopupMenu::Window::timerCallback() Line 709 C++ vst.dll!juce::PopupMenu::Window::inputAttemptWhenModal() Line 564 C++ vst.dll!juce::Component::internalModalInputAttempt() Line 2049 C++ vst.dll!juce::Component::internalMouseDown(juce::MouseInputSource & source={...}, const juce::Point<int> & relativePos={...}, const juce::Time & time={...}) Line 2346 C++ vst.dll!juce::MouseInputSourceInternal::sendMouseDown(juce::Component * const comp=0x12070140, const juce::Point<int> & screenPos={...}, const __int64 time=1275511250048) Line 122 + 0x4b bytes C++

I haven’t had the time to dig into the inner workings of the popups, but I really can’t see what I could be doing wrong here since what I am doing is really basic:

virtual void mouseDown (const MouseEvent& e) { if (e.mods.isRightButtonDown()) { PopupMenu& popup = getMyPopup(); const int result = popup.showAt(this); } }

Using coordinates or a component to center the popup does not seem to make a difference. I have a TooltipWindow around but it does not seem to make a difference either. I am also using EditorRequiresKeyboardFocus.

Any ideas? I am really stuck on this quite distrubing issue!
Thanks!


#2

The first thing I noticed in your post was the line “PopupMenu& popup = getMyPopup();”, which looks like a dangling pointer…?


#3

I’m puzzled, why would it be a dangling pointer?

I’ve built a popup menu once and for all and because of the reference I wouldn’t expect it to get destroyed at any time. Even if I strip out the reference, I still have the same problem, but since we are showing the menu modally I wouldn’t see dangling pointers problems in here either. Sorry if I’m missing something big and evident!


#4

Sorry, I was just assuming your method was returning a PopupMenu object by value. Just wanted to check that wasn’t the problem before spending time digging through the menu code! Will take a look now…


#5

ok, looks pretty straightforward, (I’m surprised I’ve not noticed this before, actually)

Presumably this tweak will fix it for you:

[code] void inputAttemptWhenModal()
{
Component::SafePointer deletionChecker (this);

    timerCallback();

    if (deletionChecker != 0 && ! isOverAnyMenu())
    {
        ..etc

[/code]


#6

I’m surprised nobody ever stumbled upon this before. Anyway, works like a charm, thanks!


#7

Yes… it’s very odd, I use that functionality all the time… The fix is checked in now - thanks for letting me know!