Juce 7.0.8. Mac.
I have recently taken to making my MainComponent the parent of all PopupMenus (to keep them inside the mainComponent), so this has become an issue that I just noticed.
It occurs anywhere you use a PopupMenu, but I’m focusing on ComboBoxes here. I’m calling it a bug, but at the very least it’s an annoying inconsistency, especially if you were to mix using a parentComponent and not using a parentComponent for comboBoxes within the same project.
With a parentComponent, the ComboBox will lose focus on item selection.
Here is a simple test project:
ComboBoxFocusTest.zip (11.2 KB)
ComboBox 1 has no parent specified for the popup. ComboBox 2 has a parentComponent (the mainComponent) specified by assigning it a custom LookAndFeel:
class MainComponent : public juce::Component
{
public:
//==============================================================================
MainComponent();
~MainComponent() override;
//==============================================================================
void paint (juce::Graphics&) override;
void resized() override;
private:
//==============================================================================
// Your private member variables go here...
juce::ComboBox cbox1 {"Box1"};
juce::ComboBox cbox2 {"Box2"};
class CustomLAF : public juce::LookAndFeel_V4
{
public:
CustomLAF(MainComponent* main)
: mainComponent(main) {}
juce::Component* getParentComponentForMenuOptions (const juce::PopupMenu::Options& options)
{
return mainComponent;
}
private:
MainComponent* mainComponent;
};
CustomLAF customLAF {this};
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
//==============================================================================
MainComponent::MainComponent()
{
setWantsKeyboardFocus(true);
juce::StringArray menuList = {"Item 1", "Item 2", "Item 3" };
addAndMakeVisible(cbox1);
cbox1.addItemList (menuList, 1);
cbox1.setSelectedItemIndex(0, juce::NotificationType::dontSendNotification);
cbox1.setHasFocusOutline(true);
addAndMakeVisible(cbox2);
cbox2.addItemList (menuList, 1);
cbox2.setSelectedItemIndex(0, juce::NotificationType::dontSendNotification);
cbox2.setHasFocusOutline(true);
cbox2.setLookAndFeel(&customLAF);
setSize (600, 400);
}
So ComboBox1 is focused by me clicking on it. It gets a focus outline. The menu opens. Without a parentComponent, selecting an item from the menu closes the menu and leaves the ComboBox focused (as it should be):
You could then use the keyboard (for example) to make selections.
But with a parentComponent specified for the popup in ComboBox2, selecting an item with the mouse (as soon as you click down) focuses on the parentComponent and the ComboBox loses its focus.
I tracked the issue down to these lines at the end of
Component::grabKeyboardFocusInternal (FocusChangeType cause, bool canTryParent, FocusChangeDirection direction)
// if no children want it and we're allowed to try our parent comp,
// then pass up to parent, which will try our siblings.
if (canTryParent && parentComponent != nullptr)
parentComponent->grabKeyboardFocusInternal (cause, true, direction);
The problem is that canTryParent is always passed in as true from up the chain. So if the popupMenu has a parent, it always ends up focusing back on the parentComponent of it, i.e. the MainComponent.


