Hi,
I’ve found some annoying behavior I believe should be fixed. When you spring open a PopupMenu, if you click away from the plugin, either to another plugin window or to the host, the PopupMenu will close. This is good. However, if you have a CustomComponent in the menu, such as some buttons, and you have these constructed with the argument false to not dismiss the menu when clicking the custom component:
menu.addCustomItem (1, myComponent, 200, 40, false, nullptr, “custom”);
Then the following occurs:
Open the menu
Click a button within the custom component
Click away from the plugin
The menu stays open.
I suspect this is something to do with the custom component gaining focus, and taking it away from the popup menu.
Is this something that can be easily fixed?
As a gross workaround, for anyone that needs it:
struct CustomComponent : public juce::Component
{
public:
CustomComponent()
{
}
void mouseDown(const juce::MouseEvent& e) override
{
if (focusComp != nullptr)
if (!focusComp->hasKeyboardFocus (false))
focusComp->grabKeyboardFocus ();
}
void resized () override
{
focusComp = getCurrentlyFocusedComponent ();
}
void paint (juce::Graphics& g) override
{
}
juce::Component* focusComp;
private:
};
menu.addCustomItem (1, customComponent, 200, 40, false, nullptr, "custom");
This works for now, but I can see it easily breaking if the menu isn’t holding focus at the exact time that resized is called.
I’ve made a slightly more elegant solution to this issue, perhaps the JUCE team could incorporate something similar into juce::PopupMenu::CustomComponent?
struct MenuComponentBase : public juce::FocusChangeListener, public juce::Component
{
MenuComponentBase ()
{
juce::Desktop::getInstance ().addFocusChangeListener (this);
}
~MenuComponentBase ()
{
juce::Desktop::getInstance ().removeFocusChangeListener (this);
}
bool shouldKeepMenuOpen (juce::Component* comp)
{
while (comp != nullptr)
{
if (dynamic_cast<MenuComponentBase*>(comp))
{
return true;
}
comp = comp->getParentComponent ();
}
return false;
}
void globalFocusChanged (juce::Component* focusedComponent) override
{
if (focusedComponent == this || getIndexOfChildComponent (focusedComponent) != -1)
{
mFocusedComponent = focusedComponent;
}
else if (mFocusedComponent != nullptr)
{
if (!shouldKeepMenuOpen (focusedComponent))
{
mFocusedComponent = nullptr;
juce::PopupMenu::dismissAllActiveMenus ();
}
}
}
juce::Component* mFocusedComponent = nullptr;
};```