-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PopupMenu broken on embedded, bridged plugins #401
Comments
Plugins built with Cabbage see this too: |
I can confirm this issue in OpenMPT (The host I'm developing), both using jBridge and using my own bridge (to be precise, popup menus currently work using my own bridge but I will use a similar approach as jBridge in an upcoming version, so it will break the same way). I found it happening with the recently released Korg Triton as well as the open-source Dexed synth. When I dug a bit into the JUCE code I arrived at similar conclusions as the initial post; The problem seems to appear when starting a modal UI and the container window of the bridge process is a child window embedded in the host's plugin window; It does not happen if the bridge process window is actually a popup window (without WS_CHILD). As a host developer I'm willing to assist JUCE developers in diagnosing this issue further if required. OpenMPT is open-source as the name implies; the plugin bridge code can be found here: https://github.com/OpenMPT/openmpt/tree/master/pluginBridge |
Possibly the least invasive fix for JUCE would be to check if the window returned by Not setting |
Ping. Is there anything that could be done about this broken implementation? |
Using Rhizomatic Plasmonic (which appears to be made with Juce) in Jeskola Buzz using Polac's VST wrapper, I see the exact same thing: Drop-downs appearing for a fraction of second, and the disappearing again. Having watched the bug reports video on youtube and read the descriptions leading to this bug report, I am fairly certain this is the same problem happening. |
I've added a fix for this issue here: 1ee106d Please try it out and let me know if you run into any issues. |
I tried upgrading Helm (linked above) to use the latest JUCE, and while it was a bit of a battle, I think the plugin (or at least the parts I care about for testing) should still work. However, rightclicking on components in Helm that should open a context menu still doesn't work in OpenMPT's plugin bridge:
Unless there are any changes that would have to be made to Helm's GUI code (which wouldn't be too surprising since this was last updated in 2018), I think something is still not quite correct here. |
It sounds like Helm is not setting the popup's target component. For PopupMenus to work as expected in a bridged plugin, they must be created with a 'target component'. The change I linked above checks whether the target component is embedded in an HWND owned by the foreground process. An alternative implementation strategy would have been to check all the parents of all the active desktop components, but this felt a bit wasteful and potentially error-prone. Embedding aside, setting the target component is useful for other reasons. The target component is used to determine the scale to use when drawing the menu, which is essential on HiDPI displays. If Helm is not currently setting a target component when creating menus, I'd highly recommend updating/patching it to include this change. |
The popup is invoked like this:
That looks like it does have a target component? (assuming that this is what |
Yes. To set a target component, you can pass |
I can confirm that this now works through the plugin bridge. However, the behaviour when using I wonder if, as a compromise, you could keep a pointer to the last opened desktop component and only check its parent in case the |
For 1), plugin authors need to set the target component anyway in order for menus to render correctly on HiDPI displays. |
I think this issue is resolved, so I'm going to close it. If you run into any issues or problems with the fix, please let us know and I can reopen this issue. |
A number of DAWs these days feature bridge processes to enable loading 32-bit plugins into a 64-bit host, or vice-versa. The plugin is loaded into the bridge process, with which the host communicates to process/generate audio. A number of DAWs also embed VST GUIs into their main window, usually as an MDI child. However, when a VST from a bridge process is embedded as a child window of the DAW, JUCE's
PopupMenu
s can break, where the popup menu does not appear, or only appears very briefly.This was originally observed with the Helm VST loaded into LMMS, but I have reproduced it with Helm in Hermann Seib's VSTHost too. (I have heard others have had this problem with other JUCE-based VSTs such as Dexed, but I have not been able to reproduce this particular case.)
To reproduce: download Helm and VSTHost (both 32- and 64-bit). Load an instance of Helm with a matching architecture to that of VSTHost, and observe that opening the "PATTERN" menu under "ARP" and the "TYPE" menu under "DISTORTION" behaves exactly as expected. Now load an instance with a non-matching architecture. VSTHost will load this in a bridge process, and attempts to open the same menus will not succeed, the menus either not appearing, or only appearing very briefly.
This behaviour occurs for both 32- and 64-bit VST2 builds under Windows. It may well exist in other versions but I don't own a host with the capabilities to test this. I have built Helm with the latest version of JUCE's
develop
branch (f80df37 at time of writing; a few simple patches to Helm were required) and the issue still persists.The issue seems to stem from the Win32 version of
Process::isForegroundProcess
https://github.com/WeAreROLI/JUCE/blob/f80df37183382a3194023129f3c2badf23176b74/modules/juce_gui_basics/native/juce_win32_Windowing.cpp#L3699-L3710 which returnsfalse
in the case that the plugin is bridged and embedded, since the foreground window belongs to the DAW, which is in a different process to the plugin. ThenMenuWindow::doesAnyJuceCompHaveFocus
returnsfalse
, causingMouseSourceState::checkButtonState
to immediately dismiss the menu.FL Studio, while it can have embedded, bridged plugins, has a workaround; they don't set the
WS_CHILD
style on their VST wrapper window when embedding. Thus, while the plugin is embedded as a child of FL, Windows recognises it as a separate top-level window for the purposes ofGetForegroundWindow
and so the above code works as intended. This, however, is not standard/correct usage of the Win32 API as far as I am aware - child windows should always have WS_CHILD set - and so ideally should not be required.The text was updated successfully, but these errors were encountered: