Small bug: PopupMenu not getting closed when using trackpad (under certain circumstances)


#1

There is an issue with PopupMenu under those conditions :

  • the popupMenu has a ParentComponent
  • we use CustomComponents for the popupMenu items
  • we click on those custom items just by taping the trackpad (*), not with ‘real’ clicks

(*) it’s probably the default setting, but check that you have “Tap To click” turned ON in System preferences -> TrackPad -> Point & Click -> Tap To click

here below is a pip to reproduce (tested on 10.13)

  • open the app.
  • click on the button to open a popupmenu
  • ‘tap’ on the popupMenu’s item “just a CustomComponent”

-> sometimes the popup is destoyed (that’s what we want), but most of the time the tap won’t close the menu.

note that if the popupMenu does not have a parent component, or if you tap on normal items, then the popupMenu always closes correctly.

PIP Project
/*******************************************************************************
 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:             CustomPopupTest

  dependencies:     juce_core, juce_data_structures, juce_events, juce_graphics, juce_gui_basics
  exporters:        xcode_mac

  moduleFlags:      JUCE_STRICT_REFCOUNTEDPOINTER=1

  type:             Component
  mainClass:        MyComponent

 END_JUCE_PIP_METADATA

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

#pragma once

struct MyMenuItem : public PopupMenu::CustomComponent
{
    void paint (Graphics& g) override
    {
        g.setColour (Colours::white);
        g.drawText ("just a CustomComponent", getLocalBounds(), Justification::left);
    }

    void getIdealSize (int& idealW, int& idealH) override
    {
        idealW = 300;
        idealH = 50;
    }
};

//==============================================================================
class MyComponent   : public Component, public Button::Listener
{
public:
    //==============================================================================
    MyComponent()
    {
        textButton.addListener (this);
        addAndMakeVisible (textButton);
        addAndMakeVisible (parentCompOptionButton);
        parentCompOptionButton.setToggleState (true, dontSendNotification);
        setSize (600, 400);
    }

    //==============================================================================
    void paint (Graphics& g) override
    {
        g.fillAll (Colours::darkslategrey);
    }

    void resized() override
    {
        auto buttonBounds = getLocalBounds().withSizeKeepingCentre (200, 40);
        textButton.setBounds (buttonBounds);
        parentCompOptionButton.setBounds (buttonBounds.translated (0, -60));
    }

    void buttonClicked (Button*) override
    {
        auto* parent = parentCompOptionButton.getToggleState() ? this : nullptr;
        auto options = PopupMenu::Options().withTargetComponent (&textButton).withParentComponent (parent);

        PopupMenu popup;
        popup.addCustomItem (1, new MyMenuItem());
        popup.addCustomItem (2, new MyMenuItem());
        popup.addItem (3, "a normal item");
        popup.showMenuAsync (options, nullptr);
    }

private:
    //==============================================================================
    TextButton textButton { "click to open a popup" };
    ToggleButton parentCompOptionButton { "use a parent component" };

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MyComponent)
};