Pro Tools 2023.3 - popups not working

Just getting more and more customer feedback that our plugins under some conditions do not receive mouse clicks on child windows like async-popup menus on Mac. It looks like that on other external windows the mouse-clicks can still be received. Also it happens not always.

Our plugins are currently based on Juce 6.1.6

I’m aware that I could add the popup menus, with the withParentComponent option directly to the plugin editor, but this creates layout issues and is currently not an option for us as a quick fix.

I have a little bit hope, because that doesn’t affect other child windows, like alert-components.
I’m not sure what popups makes so special, maybe some sort of window flags. If this could be applied to popup windows, via a quick fix, this would be great fix.

Also I’m not sure if the problem still persists the latest Juce 7, but chances are high.

If anybody does know more, or have a tip, it would be awesome.

Strangely some of our plugins seems the be affected, others not.
I found out that the non-affected plugins use also openGL optionally. Maybe I have a trace, maybe just coincidence.

added:
I guess the problem is maybe not that the mouse-click is not received, instead the click may closes the popup before it can handle the mouse-click. That explains why others windows are not affected. Unfortunately, I have no possibility to debug at the moment.

added:
It looks like it works, when there is a second window is added to the desktop, that explains why its working with openGL

I could confirm this problem, with a plugin from another vendor.
Can anybody can confirm this problem with the latest juce, using no OpenGL, and no withParentComponent?

	PopupMenu pop;

	pop.addItem(1, "A");
	pop.addItem(2, "B");

    pop.showMenuAsync(PopupMenu::Options().withTargetComponent(button), ModalCallbackFunction::forComponent(handleOptionsPopupMenu, this));

→ when clicking on “A” or “B” the callback function won’t be called, instead the menu just disappears.

Just want to confirm this issue. JUCE 6.1.5 here. No OpenGL. Happens with both AppleSilicon and through Rosetta.

This is a major issue making our plugins completely unusable in ProTools 2023.3!

1 Like

Alarmed by this thread I updated to Pro Tools 2023.3, but I cannot confirm the issue for my stuff - it seems to work just fine running natively on Apple Silicon as well as when using Rosetta. I’m using JUCE 6.1.6 and no OpenGL at all.

To avoid spending time reproducing an issue that may have already been fixed, can anyone confirm that the issue is present on the develop branch?

@pflugshaupt @chkn Interesting. Perhaps we could compare some details? Here are some from my end:

JUCE: 6.1.5
MacOS target: 10.9
Preprocessor Defs: JUCE_MODAL_LOOPS_PERMITTED=1, SE_COREGRAPHICS_RENDERING=1, JUCE_COREGRAPHICS_DRAW_ASYNC=1
Test machine: BigSur (11.6.8) on M1

For what it’s worth I’m using the popup like this:

    const int result = m.showAt(&someComponent,0,100,0,28);

    if (result != 0) {
        // do something... but it never happens
    }

I have run into this issue on AUv3 targets, since AUv3 plugins run in a non-privileged sandbox and indeed separate process space, the binding of the UI context between a parent window (plugin main window) and any popup windows (sub-windows such as popups) is broken, and events do not propagate from the UI down through the hierarchy to sub-windows. This is by design, on Apples’ part.

There was some discussion in the forum about this already, and it was claimed by others that this bug was fixed in recent 7.x-develop branches, which re-establish the binding order of parent/child window relationships so that events properly propagate, again … but as I have converted my plugins to use radio buttons instead of popup menus (better for iOS/tablet/mobile devices anyway), I haven’t gone back to verify this is actually the case - or to put it another way, I’m not sure that the bug I ran into with parent/child contexts being broken was the actual issue, and it seems more experienced JUCE devs pushed a fix that made it irrelevant, anyway - although I have not confirmed this personally.

@anon48770766
I’m not sure if it’s really the same issue; but if it’s fixed in the latest juce I will try to bisect AFAIK. ProTools in Rosetta doesn’t use a sandbox; so it must be something different. Also it works if there is another windows (from the plugin) is open.

@pflugshaupt
Sure NOT using withParentComponent() ?

@ericsen
JUCE: 6.1.6
MacOS target: 10.9
I am using no modal loops, and non of your mentioned flags, but JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS

can anybody point me to this fix; maybe interesting for me

My test machine is on Monterey 12.3.1, so that’s one difference. I use popups similar to the earlier example - definitely not (yet) using withParentComponent()

popupMenu.showMenuAsync(PopupMenu::Options().withTargetComponent(targetComponent), ModalCallbackFunction::forComponent(handleOptionsPopupMenu, this));
1 Like

For reference:

… and here, see also @jules comments:

1 Like

Thanks, I think this is a different thing. The problem is not that is in not showing. Actually it is showing, it also receives mouseMove etc. Only when you click it disappears, instead of getting the click. I guess it has something todo with the hide() logic. There are several conditions which like other open windows, that make it work anyway. I’m trying to replicated with a blank 6.1.6 project, but wasn’t successful yet. It’s a mystery. :face_with_head_bandage:

If you tell me names of affected plugins, I could check those. Maybe it’s system/machine specific somehow.

For example ShaperBox 2.4.5 (not mine), if you click on the burger menu and select some entry it has no effect.

I tried to add the popup-button to a clean editor, and it actually works.
but if the button is in a nested structure of other components, it does not work.
But if there is a button on the first level; and the popup button in the nested structure it does work :exploding_head:

Hopefully I am able to debug this soon (waiting for the license) so I have more info whats actually going on

Yep, I get the issue in ShaperBox 2.4.5, but in none of my plugins. I definitely have buttons with popup-menus and combo-boxes as child components. Maybe I just have “lucky nesting” that prevents the issue from occurring - or it is triggered by something else.

Thanks, I couldn’t recreate in the current developer-build of ProTools (edit!) but

I have a nested structure like this

editor → scaling wrapper → componentA → componentB → button

I removed the scaling function, still not working.

But If I put a TextButton next to the componentA it works, if I just put a normal Component to it does not work. So whats the difference between a TextButton and a normal component.
The TextButton wants the keyboard focus, and is a settableToolTip client. Is that the reason, no idea. I will investigate.

I tested some more aax plugins known to use Juce in Pro Tools 2023.3. The only plugins I could find to be affected by this problems are ShaperBox 2 and ShaperBox 3 - and I’m not sure these use Juce or not. All the others I tried had working popup menus and from the visible shadows it’s quite likely they are using the child-window variant of popup menus. So I guess this bug only happens in very specific conditions. Or maybe it’s caused by some weirdness like we had some time ago in PT with the naming of certain static variables… can’t quite remember what that was :confused:

I get the problem even when triggering a PopupMenu from a TextButton that’s a direct child of the editor. It returns 0, as if the popup was dismissed.

Interestingly, simply opening the popup menu using the right mouse button seems make the selection work :thinking: Not sure if that is specific to my project?

I was finally able to reproduce this issue on a clean plugin project.

The problem happens also with latest JUCE 7 from develop @reuk in ProTools 2023.3

An editor with one button, with setWantsKeyboardFocus(false);
(It seems the problem appears when there is no component present which wants the keyboard focus.)

If you select an entry from the popup, nothing happens.

@ericson because you use a modal-loop your case is a bit different, but maybe has the same reason

#pragma once

#include <JuceHeader.h>
#include "PluginProcessor.h"

//==============================================================================
/**
*/
class Juce7pluginAudioProcessorEditor  : public juce::AudioProcessorEditor
{
public:
    Juce7pluginAudioProcessorEditor (Juce7pluginAudioProcessor&);
    ~Juce7pluginAudioProcessorEditor() override;

    static void handleOptionsPopupMenu(int result, Juce7pluginAudioProcessorEditor* editor)
    {
        if (result == 1)
        {
            editor->col=juce::Colours::yellow;
        } else
            if (result == 2)
            {
                editor->col=juce::Colours::blue;
            };
        editor->repaint();
    }
    
    
    //==============================================================================
    void paint (juce::Graphics&) override;
    void resized() override;
    
    juce::TextButton button { "Change Colour"};
    juce::Colour col { juce::Colours::red };
    
  

private:
    // This reference is provided as a quick way for your editor to
    // access the processor object that created it.
    Juce7pluginAudioProcessor& audioProcessor;

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Juce7pluginAudioProcessorEditor)
};

#include "PluginProcessor.h"
#include "PluginEditor.h"

//==============================================================================
Juce7pluginAudioProcessorEditor::Juce7pluginAudioProcessorEditor (Juce7pluginAudioProcessor& p)
    : AudioProcessorEditor (&p), audioProcessor (p)
{
    // Make sure that before the constructor has finished, you've set the
    // editor's size to whatever you need it to be.
    setSize (400, 300);
    
    addAndMakeVisible(button);
    button.setWantsKeyboardFocus(false);
    
    button.onClick = [this](){
        juce::PopupMenu pop;
      /*  pop.addItem("yellow",[this](){ col = juce::Colours::yellow; repaint();} );
        pop.addItem("red",[this](){ col = juce::Colours::red; repaint();} );
        pop.showMenuAsync(juce::PopupMenu::Options().withTargetComponent(&button));*/
        pop.addItem(1, "yellow");
        pop.addItem(2, "blue");
        for (int i=3; i<20; i++)
            pop.addItem(i,"very long entry, bigger than the plugin");
        pop.showMenuAsync(juce::PopupMenu::Options().withTargetComponent(button), juce::ModalCallbackFunction::forComponent(handleOptionsPopupMenu, this));
    };
    
  
}

Juce7pluginAudioProcessorEditor::~Juce7pluginAudioProcessorEditor()
{
}

//==============================================================================
void Juce7pluginAudioProcessorEditor::paint (juce::Graphics& g)
{
    // (Our component is opaque, so we must completely fill the background with a solid colour)
    g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));

    g.setColour (col);
    g.setFont (30.0f);
    g.drawFittedText ("Hello World!"+juce::SystemStats::getJUCEVersion(), getLocalBounds(), juce::Justification::centred, 1);
}

void Juce7pluginAudioProcessorEditor::resized()
{
    // This is generally where you'll want to lay out the positions of any
    // subcomponents in your editor..
   
    
    button.setBounds(300, 20, 100, 30);
    
}

2 Likes