Plugin wrapper GUI issue on MacOSX


#1

Hi,

I’m working on a plugin wrapper project, the idea is to add external connectivity to a regular plugin. My wrapper is implementing an AudioProcessor and an AudioProcessorListener to ensure tunneling between the host and the “normal” plugin. My wrapper’s editor is of course based on an AudioProcessorEditor and just contain a simple child component which is the AudioProcessorEditor related to the “normal” plugin. My editor is a little bit larger than the “normal” editor to display some extra information from the paint method.

Everything is working perfectly under Windows, but I have an issue related to the GUI on Mac with some AU plugins… and I’m completely lost since I’m definitely not used with things related to Cocoa/Carbon/ObjectiveC.

It is working with some plugins such as ACE, Addictive Drums… I can load my wrapper in any host and see the extended editor view including the regular plugin’s GUI. But with some other plugins (Sawer for example) I just get the wrapper’s editor GUI (the result of my editor’s paint). I ran the code step by step to check if some error occurs around JuceAUView during the plugin’s editor creation. Nope… It seems that the “child NSWindow in front of a HIView” (cf a comment in juce_AU_Wrapper.mm) is not visible. Something interesting: after activating the JUCE_ENABLE_REPAINT_DEBUGGING define, I succeeded accidentally to get the plugin’s GUI visible after a pause on a breakpoint. I say “accidentally” because I can’t reproduce it. But at this time, the plugin’s editor was visible on the screen, in front of my wrapper’s editor window, and unanchored from this window! I was able to move my editor’s window on the screen, but the plugin’s GUI didn’t move. But at this time, the editor was fully functional and replicating the parameter changes I was sending remotely from the network.

I’m using the latest Juce code, my wrapper pass successfully the auval check, and something important: I don’t have the issue if I load the plugin in a standalone application implementing the same code than my wrapper minus the plugin client part.

This issue is related to some plugins and occurs within a host execution context (I tried with several hosts such as AU Lab, Numerology, Mainstage, Garage Band…) It’s not due to some incompatibility since I got the GUI on screen once after activating repaint debugging (strange window behavior, but working). So I guess it is related to something from within the “normal” plugin, maybe the library used for the GUI (cocoa or carbon)? Is it something possible? Or maybe a timing issue? a threading issue? what else? any idea?

/Phil


#2

I had some similar issues when i was doing my own wrapper. I got it working, you can compare my code here: http://rawmaterialsoftware.com/viewtopic.php?f=6&t=11396

What i noticed is that OSX has compatibility issues so watch out what platform version you are targeting when you do your Xcode builds (if you build for 10.8 it won’t run on 10.7 or it will run with problems, there is some update to 10.7 that my friend had to install to get my build on 10.8 with 10.7 compatibility to run)


#3

Thanks, but I have not found anything relevant. My wrapper is fully functional in VST mode, I just have the issue with some AU plugins.

I have new information today. First, tracing step by step AudioUnitPluginInstance::createEditor for several plugins revealed that the issue occurs when I’m trying to wrap a plugin based on Carbon. The plugins using Cocoa are working perfectly.

Then I wanted to know if any component is not visible, so I changed component size and background colour of the involved components. My editor background is red, the AudioUnitPluginWindowCarbon is green, and I’ve added a paint() to fill the CarbonViewWrapperComponent in yellow.
=> When I open the editor, I see a beautiful yellow rectangle. So it means that the component stack is well created, the top component is a CarbonViewWrapperComponent, its size is correct and it is visible.

The strange think is I can see the plugin’s editor when I create an editor from a stand alone application. But it does not work when I create the plugin’s editor from my wrapper plugin’s. I was thinking about some system messaging issue, but breakpoints within CarbonViewWrapperComponent::carbonEventHandler and carbonEventCallback are hit. Moreover I’ve also tried to set the time limit in timercallback at 10 seconds instead of 1 to call recursiveHIViewRepaint longer… Finally, I’ve added a call to recursiveHIViewRepaint from CarbonViewWrapperComponent::paint(), but nothing new…

So… what else… Jules, do you have some hint for me? I guess I have to find out why the Carbon window associated with the CarbonViewWrapperComponent is not visible, but what could I do now?


#4

Ha haaaaa. Checking the several plugins with AU, I can say that the plugins working with my wrapper plugin have both or Carbon UI, and the plugin that does not show their editor through my wrapper are only Cocoa.

So, here is a resume of the situation:

  • my wrapper is a plugin based on Juce, hosting itself another 3rd party plugin
  • I can see the 3rd party plugin editor in any host
  • but when I load this 3rd party plugin through my wrapper, only those having a Cocoa UI are able to show their UI.
  • checking my wrapper with auval confirms that it is exposing both Cocoa and Carbon UI…

Any idea why my Juce-based wrapper is seems to refuse to display Carbon UI component?


#5

Cocoa UIs are embedded as NSViews, which is great, but the only way to handle the old carbon UIs is to float them as a desktop window in front of the host’s window, which is a total nightmare to manage in terms of z-order. It may be possible to stack a carbon wrapper window inside another carbon wrapper window and get everything in the right order, but I didn’t write the code with that in mind, so good luck!

You might want to disable Carbon in your plugin, so it can only be used in cocoa hosts - that’d cut out a lot of hassle. Probably most hosts are cocoa nowadays anyway… (?)


#6

Well, actually my plugin is cocoa and carbon compliant since it’s Juce based. But my plugin is wrapping 3rd party plugins that can be carbon exclusive…

For example, Addictive Drums is an AU plugin exposing only Carbon UI. I can load it in MainStage, AU Lab, Live. So these hosts are able to manage Carbon exclusive plugins. But when I load it through my wrapper plugin I can’t get the Addictive Drum UI visible. I just see my wrapper editor’s component. I suspect that the host is loading my plugin, choose the Cocoa interface (since I provide both), my plugin is loading Addictive Drums and has not choice but using Carbon UI… Is this plausible? If so, a solution could be building two versions of my plugin, the first using Cocoa and the second Carbon, then my wrapper managing tool can choose the appropriate version when customizing the wrapper for a specific plugin.

Is it possible to tweak the juce_AU_Wrapper to build only Carbon version of the plugin?


#7

Just a status update: I have now two version of my wrapper plugin, the first in cocoa and the second in carbon. And now I can get the 3rd party plugin GUI on screen if I load it through the plugin wrapper matching its GUI library.

Finally, my wrapper plugin must use cocoa or carbon depending on the wrapped plugin.

Last issue: in carbon mode, the 3rd party GUI is not anchored to my wrapper plugin GUI… I mean, if I move the window hosting my plugin, the wrapped plugin GUI stay at the same place…

The Sawer’s GUI should be over the yellow part of my wrapper:
[attachment=0]Screen Shot 2013-06-13 at 15.43.40.jpg[/attachment]


#8

Hi there,

Just an update to tell you that finally I succeeded to fix the “carbon floating editor’s GUI” issue :wink:

Remember, when I’m hosting a Carbon plugin, the plugin’s GUI do not follow the Editor’s window when moving it (see the image in the post above). I just found why :!:

CarbonViewWrapperComponent is using a ComponentMovementWatcher to update the wrapperWindow position and size. That’s fine to track Editor’s moving and resizing related to the top level component… but not related to top level component position on screen. When I move the editor window on screen, its children position and size doesn’t change, and so CarbonViewWrapper::componentMoveOrResized is not called, resulting in a top window move not followed by the wrapperWindow :lol:

I’ve fixed it by overriding the ComponentListener’s version of componentMoveOrResized within the CarbonViewWrapper class like this:

    void componentMovedOrResized(Component& component, bool wasMoved, bool wasResized)
    {
        ComponentMovementWatcher::componentMovedOrResized(component, wasMoved, wasResized);
        if (&component == getTopLevelComponent())
            setEmbeddedWindowToOurSize();
    }

=> Jules, I think it would be great to update the Juce source code with this fix.

Cheers,

/Phil


#9

Ah - very interesting, thanks! Excellent detective-work, I’ll take a look at that and figure something out…