Regression in parented PopupMenu mouse behaviour in JUCE 8.0.4

Since updating from 8.0.3 to 8.0.4 juce::PopupMenu is broken in some cases when using a menu inside a parent component using withParentComponent().

I like to make juce::Buttons that trigger menus on mouseDown (using setTriggeredOnMouseDown() and allow the user to make a selection with one gesture on the next mouseUp. The users clicks the button, drags to the item to select and releases. This worked fine up to JUCE 8.0.3. It still works fine if the PopupMenu uses an independent window, but is now broken if the menu is attached to a parent component. The first mouse up event no longer triggers an item in that case.

This happens on both macOS and Windows and is an (unintended) side-effect of the changes made in commit:

The problem comes from the removal of two lines in MouseSourceState::highlightItemUnderMouse()

-if (isMouseOver)
-   window.hasBeenOver = true;

It looks like events are handled quite differently depending on whether a window is used or a parent component. I guess using a parent component the initial event comes from the wrong component and the two lines were needed to work around this. To get back to the old behaviour in JUCE8.0.4, I need to add

+if (isMouseOver) {
+	window.mouseWasOver = true;
+	window.mouseUpCanTrigger = true;
+}

at the spot the lines were removed and make these flags public.

I made a PIP to demonstrate. The left button opens a menu using a window, the right opens the menu with a parentComponent. The one-gesture selection works fine on the left and is broken on the right (using J8.0.4).

/*******************************************************************************
 The block below describes the properties of this PIP. A PIP is a short snippet
 of code that can be read by the Projucer and used to generate a JUCE project.

 BEGIN_JUCE_PIP_METADATA

  name:             PopupMenuTroubles

  dependencies:     juce_core, juce_data_structures, juce_events, juce_graphics, juce_gui_basics
  exporters:        VS2022, XCODE_MAC

  moduleFlags:      JUCE_STRICT_REFCOUNTEDPOINTER=1

  type:             Component
  mainClass:        PopupMenuTroubles

 END_JUCE_PIP_METADATA

*******************************************************************************/

#pragma once


class PopupMenuTroubles  : public juce::Component
{
public:
    PopupMenuTroubles()
    {
		auto createMenu = []{
			juce::PopupMenu m;
			m.addItem("item 1", nullptr);
			m.addItem("item 2", nullptr);
			m.addItem("item 3", nullptr);
			return m;
		};

		buttonA = std::make_unique<juce::TextButton>("no parent");
		addAndMakeVisible(buttonA.get());
		buttonA->setBounds(100, 100, 120, 24);
		buttonA->setTriggeredOnMouseDown(true);
		buttonA->onClick = [this, createMenu]{
			auto m = createMenu();
			m.showMenuAsync(juce::PopupMenu::Options().withTargetComponent(buttonA.get()));
		};

		buttonB = std::make_unique<juce::TextButton>("w/ parent comp");
		addAndMakeVisible(buttonB.get());
		buttonB->setBounds(240, 100, 120, 24);
		buttonB->setTriggeredOnMouseDown(true);
		buttonB->onClick = [this, createMenu]{
			auto m = createMenu();
			m.showMenuAsync(juce::PopupMenu::Options().withTargetComponent(buttonB.get()).withParentComponent(this));
		};

		setSize (460, 300);
    }

	void paint (juce::Graphics& g) override
    {
        g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));
    }

private:
	std::unique_ptr<juce::TextButton> buttonA, buttonB;

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PopupMenuTroubles)
};


Additionally, custom popup menu items that are set to trigger by themselves often don’t trigger at all in 8.0.4 if withParentComponent() is used, this is also fixed by the band-aid changes I made.

Thanks for your patience. This issue should now be resolved:

2 Likes