Combobox popup menu appears behind main component

I might be misreading this, but it sounds to me as if Mikey is assuming the combobox popup is a lightweight component.

OK, I’ll bite. What’s a lightweight component?

Heavyweight vs lightweight refers to whether the component is a physical window object, or just a child object of some other heavyweight component.

The combo box uses a popup menu to show its item list. The popup menu is a desktop level window. It sounds to me that you are thinking of combo popups as just being a normal child component that are floated above all other components, for example how you would implement this kind of thing in HTML/CSS. If so, it would be easy to talking slightly at cross purposes with Jules, who’ll be thinking of this in terms of windows all of which have been tols to “be on top”.

Then I guess the question is why the popup can’t be a lightweight, child component of the combo box? It appears to me that it would solve the problem.

Well you’d need to look inside the PopupMenu code, at the windows that it creates, and make them always-on-top. But like I said, that’s not a change that I can just add to the codebase, because in many cases you wouldn’t want it to be done that way.

[quote=“ssaue”]
Then I guess the question is why the popup can’t be a lightweight, child component of the combo box? It appears to me that it would solve the problem.[/quote]
That’s the question I have. In every other case I’ve used, any child component maintains its hierarchical position in the Z-plane. Any children of that component maintain their relationships as well. These means that once I place things in the Z hierarchy I wish, they’ll maintain that relationship to one another. This combo box thing appears to live by another set of rules. Even though I make the combo box a child of the GUI, the popup component seems to live where it bloody well pleases.

Let me reiterate. I don’t want the popup always on top. I simply want it on top of the GUI, where I placed it when I created it–like any other component. If some other unrelated window is drawn on top of that, I don’t care. I’m just trying to maintain a simple set of relationships within the domain of my plugin.

Well sorry, that’s just not how the PopupMenu was designed to work… I didn’t do it like that because in 99.9% of use-cases people will expect it to be in a separate window, so that it can be larger than its parent component if necessary.

Aah, that’s exactly the piece of information I haven’t understood before: The size of a child component is always limited by the size of its parent. Probably obvious. Now I finally realize why there is no trivial solution to this popup issue.

Jules, you’ve made it clear you won’t budge on this. Would you please, please make sure this behavior is documented in the next round of Doxygen. I spent several days (days I couldn’t spare) tracking down this issue when a customer reported that his preset menu wasn’t appearing. It was only by accident that the popup crept out from behind the GUI that hid it. You may consider the current behavior obvious, but it isn’t. This component needs red flags on it to illustrate how its behavior differs from other components.

I’m really sorry that this got you caught up in a multi-day bug hunt, but I don’t understand what you’re asking me to “budge” on…? It’s not possible to implement a combo box as a child component. No GUI toolkit or OS in the world has ever done it that way, they all do it like me, with a floating window, because otherwise it simply wouldn’t fit! Or are you asking me to “budge” on the always-on-top stuff again??

But its behaviour doesn’t differ from other components that pop things up! They all use the same popup menu classes. What exactly do you want me to write? “Warning! This component pops up a window!”… ??

From our testing, this is a Mac Cocoa problem. It occurs when a host window is modal via runModalForWindow, and the embedded Juce component contains a Juce ComboBox.

I successfully hacked PopupMenu::showMenu to solve this initial problem by adding the following Cocoa code before the call to window->enterModalState:

juce_PopupMenu.cpp::PopupMenu::showMenu:

#if defined (APPLE) && defined (LP64)
NSView* popupView = (NSView*) callback->component->getWindowHandle();
NSWindow* popupWindow = [popupView window];
[popupWindow setLevel:NSPopUpMenuWindowLevel];
#endif

This causes the popup menu to successfully show on top of the parent.

However, there is a further problem once this is solved.

If you click->drag to a popup menu selection it works. But if you click-release, then try to click on a popup selection, it does not work. You get a Mac beep as if the popup menu is not the modal window. You can click the Juce parent component and the popup menu dismisses. BUT, as any drop list should work, click-release followed by selection of the drop list must work. It does not in this case.

Here is a simple Cocoa app which exhibits the behavior:
http://theorypartners.com/downloads/juce/JucePopupTest.zip

The above-quoted PopupMenu Window Level fix is included in the Juce source here. This is using Juce v2.0.28.

Click Show Modal.
Click-drag on the ComboBox, works.
Click-release on the ComboBox, try to select a ComboBox item, DOES NOT work.
Click-release on the Popup, select a PopupItem, DOES WORK.

Interestingly, using a Sheet to display the parent window works as expected. Unfortunately, this is not a solution in many cases.

Jim

That’s interesting Jim. I haven’t seen it on the Mac at all. Only on Windows.

Sorry to get back to that Jules…

But it seems everybody making plugins may be exposed to that issue right?
Would it be bad to set the popup window always on top within some macros such as :

#if (JucePlugin_Build_VST || JucePlugin_Build_AU || JucePlugin_Build_RTAS || JucePlugin_Build_AAX)
 window->setAlwaysOnTop (true);
#endif

I gave up on it and created another class. It’s not the same as Jules’s popup–it stays within the bounds of the main window–but at least it’s the right order in the Z-plane.

hum… any tips on that ? Would like to hear more about how you’re managing it :slight_smile:

Nothing special really (it’s not really general enough to post). Just a component with a virtual grid where I can place text. A little mouse capture logic that looks at those grid coordinates to see which item is selected. Then a little logic to see when I’ve stepped outside of the component bounds so I’ll know when to turn off the visibility of the thing. The rest is more specialized toward what I was trying to accomplish. It took me a while to decide what I really needed, but then only took a couple of days to get working.

It’s all tied to a text button. Click the button and the menu shows up. Since it was declared as a child component after the button, it covers the button. Looks like a combo box, but it really isn’t.

thanks

It seems I'm reviving an old thread. I have also come to notice this problem.

However (and maybe the differences here are due to a later version of Juce) I can't help noticing that the regular PopupMenu is indeed behaving as expected (i.e on-top of the on-top plugin window). As I understand it, the ComboBox popup is very similar to a PopupMenu? Is there any particular reason that the ComboBox popup can't behave just like a popup menu? Is there anything stopping us from always having all popups always-on-top?

You're right in thinking that both use a popup menu, and the popup menu is always always-on-top.. Not sure what could be different TBH..

Hmm, single stepping the popping up of the ComboBox and PopupMenu shows no differences that I can notice; still the ComboBox ends up behind the plug-in window.

Maybe it's because my PopupMenu is still in the old style modal mode, and the ComboBox is managed asynchrously?