BR: PopupMenu CustomComponent keeps menu open

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;

	};```