Dismiss PopupMenu when focus changes


#1

How can I dissmiss all active menus when a user clicks away from the plugin GUI? As far as I can tell there is no callback that is recieved that allows me to determine that the focus has changed or that a click occured outside of the plugin window. Without this check users can move the plugin window after a menu has been clicked and the menu doesn't move with he plugin window or get dismissed!

For now I have it that i reguarly call getScreenPosition() in the editor to check if the editors window has been moved, if it has I call PopupMenu::dismissAllActiveMenus. However that is hardly an ideal solution and I've noticed Cytomic plugins have managed to solve this issue and they are using JUCE.

Alternatively it would be nice to have a wrapper class that allows the use of OS context menus.


#2

Previously reported.

https://forum.juce.com/t/combobox-modalcallbackfunction

I have a modified PopupMenu and ComboBox class which work… but Jules wouldn’t be happy with my implementation.

Rail


#3

Thank you for the reply.

At first appearence, looking at your final solution, it seems covering the edge cases Jules mentions wouldn't be too difficult. I would probably add a virtual method to ComponentPeer something like shouldDismissMenusOnFocusLoss(), have the default implementation return true and override the method for any ComponetPeer classes that it causes an issue for. I haven't actually looked into this yet so maybe there is a good reason that can't be done, or an edge case that I'm not considering.

In regards to "why it would be a good idea", is because the menus should act 'exactly' as users expect them to act, they should at the very least replicate the basic funcionality of the a system menu; In my opinion, anything else will have a negative impact on user experience.


#4

Sorry to dig up an old thread, but we’re having trouble wrangling PopupMenu in our plugins. Is there a solution for dismissing a PopupMenu when a plugin window moves that doesn’t use a modal loop or require polling getScreenPosition()?

EDIT: polling getScreenPosition() isn’t really viable either because it doesn’t seem to update when the plugin window is being dragged.


#5

The best solution is to set the popup as child of your plugin editor (or your main component or something) :
menu.showMenu (PopupMenu::Options().withParentComponent (&guthzPluginEditor))

edit: ah, note that it won’t dismiss the popup when you move the window, instead the popup will move with it. I think it’s a fine behaviour but perhaps not what you want?


#6

Thanks! That’s interesting. Moving with the window would be just fine — basically anything that doesn’t leave a hanging popup floating in the middle of nowhere.

Would making it a child of the main component mean that it couldn’t display outside the bounds of the plugin window?


#7

yes, the bounds would be constrained by the parent comp.
otherwise, regarding the dismiss when the window is moving I used a code like that in the past (a bit hacky, but that should work) :

void timerCallback() override
{
    if (topComp == nullptr)
        topComp = pluginEditor->getTopLevelComponent();

    if (topComp != nullptr)
    {
        if (ComponentPeer* peer = topComp->getPeer())
        {
            const Point<float> point = peer->localToGlobal (Point<float>());

            if (point != previousPoint)
            {
                 previousPoint = point;
                 PopupMenu::dismissAllActiveMenus();
            }
        }
    }
}

I really like your plugins btw.


#8

Thanks! That’s essentially what I tried, but localToGlobal wasn’t updating while the window was being dragged. Is that what you’re seeing as well?


#9

indeed, it’s not updating continuously while the mouse is dragged, it seems it’s updated just when the mouse movement stops.


#10

Posting again here because some beta testers have reported this behavior to us as a bug. I was hoping it would be something no one would notice or care about, but that appears to not be the case.

Is there nothing that JUCE could do to fix the floating-in-mid-air PopupMenu issue?