BR: dangling pointer with options.getTargetComponent()

I use that trick to paint popup menu differently for ComboBox:

void LookAndFeel::drawPopupMenuBackgroundWithOptions (juce::Graphics& g,
    int width,
    int height,
    const juce::PopupMenu::Options& options)
{
    const bool isComboBox = (dynamic_cast<juce::ComboBox*> (options.getTargetComponent()) != nullptr);
    
    ...
}

But if i manually close the window while a ComboBox’s popup is still on screen it crashes.
It seems that while the ComboBox is properly destroyed, the popup menu is not (or delayed).
Thus an async paint fetch a dangling pointer with options.getTargetComponent() returned value.
Am i wrong? What can i do?

Note that if i call juce::PopupMenu::dismissAllActiveMenus() in the window’s content destructor it doesn’t crash. But as the ComboBox’s destructor calls it also, i guess it is not a valid fix (but a matter of chance).

It doesn’t sound like you’re doing anything incorrectly, but it’s hard to say without seeing more code. We can make this a bit nicer though by storing the option’s target and parent components in WeakReferences so they will be nullptr if the component has been deleted. Then in your L&F method you can check that options.getTargetComponent() != nullptr. Would that work for you?

1 Like

I guess it will avoid the crash ; and it is safer for other users too.

I don’t know if the menu will blink repainted with wrong colors ; i’ll surely find a workaround for that. :grin:
Is there a way do dismiss a popup menu synchronously?

If you specify a parent component it will be dismissed when the parent is deleted but for desktop windows it is a bit trickier. Calling dismissAllActiveMenus() in your content’s destructor is safe and synchronous, but will obviously dismiss all menus which might not be the desired behaviour.

1 Like

It randomly crashes even if i call dismissAllActiveMenus() in the content destructor. :grimacing: If it is done synchronously i don’t understand why the LnF drawPopupMenuBackgroundWithOptions is called later with a dangling pointer.

Anyway at this point i guess that i need to provide a minimal example to investigate the stuff. :grinning:

Yes that would help in tracking the issue down. In the meantime the weaf ref change is on the develop branch here:

1 Like

The weak reference fixes the crash as expected and the menu doesn’t seems to blink. Thus i thought it didn"t worth the cost to investigate more. But after few tests i found another bug with MenuBarComponent popup’s in same case. :thinking: I’ll post a complete minimal project ASAP.

An example to show that if the ComboBox’s PopupMenu is dismissed when the window is closed, it is painted once again. With the WeakReference it is a nullptr now, thus it doesn’t crash anymore. And since the menu doesn’t seems to blink, i’m not sure it worths the cost to investigate more.