JuceDemoPlugin (Mac VST) crashs host when resizing

Hi Jules,

I’m currently working on resizing a plugin and went into some problems on Mac. When I change the plugin size in Cubase the Cubase window hosting the plugin doesn’t change size. After reopening the plugin the window is white (so the Cubase bypass/presetbar is blank; the Juce GUI appears as it should), a second reopening returns everything to normal. Looking about resizing problems I found this thread which led me to try PPMulator too where I could reproduce this behaviour.

When trying with the JuceDemoPlugin (OS X 10.6, current Juce tip) I can reproduce a crash (neither my plugin nor PPMulator crash here) when resizing the window and closing the plugin. This also occurs with Reaper. The AU doesn’t crash reaper, but the resize behaviour is different (host window won’t resize)

The Cubase crashlog is:

Thread 0 Crashed:  Dispatch queue: com.apple.main-thread
0   ...rialsoftware.JuceDemoPlugin	0x19cea46f juce::Component::~Component() + 87
1   ...rialsoftware.JuceDemoPlugin	0x19ceff7d juce::Slider::~Slider() + 583
2   ...rialsoftware.JuceDemoPlugin	0x19ce86db juce::Component::deleteAllChildren() + 39
3   ...rialsoftware.JuceDemoPlugin	0x19bba6cc JuceDemoPluginAudioProcessorEditor::~JuceDemoPluginAudioProcessorEditor() + 64
4   ...rialsoftware.JuceDemoPlugin	0x19d8f23c JuceVSTWrapper::EditorCompWrapper::~EditorCompWrapper() + 64
5   ...rialsoftware.JuceDemoPlugin	0x19d8eea6 JuceVSTWrapper::deleteEditor(bool) + 208
6   ...rialsoftware.JuceDemoPlugin	0x19d8f00e JuceVSTWrapper::dispatcher(int, int, int, void*, float) + 310
7   com.steinberg.VSTPlugManager  	0x1d3afd82 0x1d3aa000 + 23938
8   com.steinberg.VSTPlugManager  	0x1d3ad1bb 0x1d3aa000 + 12731
9   com.steinberg.cubase          	0x01438559 CResampleBase::~CResampleBase() + 2259881
10  com.steinberg.cubase          	0x014bd384 CResampleBase::~CResampleBase() + 2804180
11  com.steinberg.cubase          	0x01312a41 CResampleBase::~CResampleBase() + 1056913
12  com.steinberg.cubase          	0x014bd384 CResampleBase::~CResampleBase() + 2804180
13  com.steinberg.cubase          	0x014cbffb CResampleBase::~CResampleBase() + 2864715
14  com.steinberg.cubase          	0x00e72812 0x1000 + 15144978
15  com.steinberg.cubase          	0x00e88d79 0x1000 + 15236473

Crashlog reaper:

0   ...rialsoftware.JuceDemoPlugin	0x182dd46f juce::Component::~Component() + 87
1   ...rialsoftware.JuceDemoPlugin	0x182e2f7d juce::Slider::~Slider() + 583
2   ...rialsoftware.JuceDemoPlugin	0x182db6db juce::Component::deleteAllChildren() + 39
3   ...rialsoftware.JuceDemoPlugin	0x181ad6cc JuceDemoPluginAudioProcessorEditor::~JuceDemoPluginAudioProcessorEditor() + 64
4   ...rialsoftware.JuceDemoPlugin	0x1838223c JuceVSTWrapper::EditorCompWrapper::~EditorCompWrapper() + 64
5   ...rialsoftware.JuceDemoPlugin	0x18381ea6 JuceVSTWrapper::deleteEditor(bool) + 208
6   ...rialsoftware.JuceDemoPlugin	0x1838200e JuceVSTWrapper::dispatcher(int, int, int, void*, float) + 310
7   com.cockos.reaper             	0x001e5b4e VST_HostedPlugin::QuitConfig() + 254
8   com.cockos.reaper             	0x001efa94 _ZN5FxDsp9delConfigEv. + 123
9   com.cockos.reaper             	0x001eea2c FxDsp::fxFloatProc(HWND__*, unsigned int, unsigned long, long) + 1980
10  com.cockos.reaper             	0x001ee229 FxDsp::staticFxFloatProc(HWND__*, unsigned int, unsigned long, long) + 73
11  com.cockos.reaper             	0x0031f6ea SwellDialogDefaultWindowProc(HWND__*, unsigned int, unsigned long, long) + 74
12  com.cockos.reaper             	0x0031863f -[REAPERSwell_hwnd onSwellMessage:p1:p2:] + 207
13  com.cockos.reaper             	0x0032e1f4 DestroyWindow(HWND__*) + 228
14  com.cockos.reaper             	0x001ee36f FxDsp::fxFloatProc(HWND__*, unsigned int, unsigned long, long) + 255
15  com.cockos.reaper             	0x001ee229 FxDsp::staticFxFloatProc(HWND__*, unsigned int, unsigned long, long) + 73

Also can you give any suggestions about plugin resizing on Mac?

Chris

Sorry - try this change, in juce_VST_Wrapper.cpp:

[code] class EditorCompWrapper : public Component,
public AsyncUpdater
{
public:
EditorCompWrapper (JuceVSTWrapper& wrapper_, AudioProcessorEditor* editor)
: wrapper (wrapper_)
{
setOpaque (true);
editor->setOpaque (true);

        setBounds (editor->getBounds());
        editor->setTopLeftPosition (0, 0);
        addAndMakeVisible (editor);

      #if JUCE_WIN
        if (! getHostType().isReceptor())
            addMouseListener (this, true);
      #endif
    }

    ~EditorCompWrapper()
    {
        deleteAllChildren(); // note that we can't use a ScopedPointer because the editor may
                             // have been transferred to another parent which takes over ownership.
    }

    void paint (Graphics&) {}

    void paintOverChildren (Graphics&)
    {
        // this causes an async call to masterIdle() to help
        // creaky old DAWs like Nuendo repaint themselves while we're
        // repainting. Otherwise they just seem to give up and sit there
        // waiting.
        triggerAsyncUpdate();
    }

  #if JUCE_MAC
    bool keyPressed (const KeyPress& kp)
    {
        // If we have an unused keypress, move the key-focus to a host window
        // and re-inject the event..
        forwardCurrentKeyEventToHost (this);
        return true;
    }
  #endif

    AudioProcessorEditor* getEditorComp() const
    {
        return dynamic_cast <AudioProcessorEditor*> (getChildComponent (0));
    }

    void resized()
    {
        Component* const editor = getChildComponent(0);

        if (editor != 0)
            editor->setBounds (getLocalBounds());
    }

    void childBoundsChanged (Component* child)
    {
        child->setTopLeftPosition (0, 0);

        const int cw = child->getWidth();
        const int ch = child->getHeight();

        wrapper.resizeHostWindow (cw, ch);

      #if ! JUCE_LINUX // setSize() on linux causes renoise and energyxt to fail.
        setSize (cw, ch);
      #else
        XResizeWindow (display, (Window) getWindowHandle(), cw, ch);
      #endif

      #if JUCE_MAC
        wrapper.resizeHostWindow (cw, ch);  // (doing this a second time seems to be necessary in tracktion)
      #endif
    }

    void handleAsyncUpdate()
    {
        wrapper.tryMasterIdle();
    }

  #if JUCE_WINDOWS
    void mouseDown (const MouseEvent&)
    {
        broughtToFront();
    }

    void broughtToFront()
    {
        // for hosts like nuendo, need to also pop the MDI container to the
        // front when our comp is clicked on.
        HWND parent = findMDIParentOf ((HWND) getWindowHandle());

        if (parent != 0)
            SetWindowPos (parent, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    }
  #endif

private:
    //==============================================================================
    JuceVSTWrapper& wrapper;

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (EditorCompWrapper);
};[/code]

I replaced the EditorCompWrapper with the code above but the DemoPlugin is still crashing when resizing and then closing the plugin. As before this happens in Cubase (5.5) as well as Reaper (3.72).

I’m currently trying to get a fix for the blank bar in Cubase after resizing my plugin (Cubase doesn’t seem to be aware of the resize and won’t paint its window when firstly reopening the plugin).
While doing some testing I found out that Cubase doesn’t seem to care about the setNativeHostWindowSize (hostWindow, editorComp, newWidth, newHeight, getHostType()); on line 1208 in juce_VST_wrapper.cpp. The resize behaviour doesn’t change when I comment that line.

Inside setNativeHostWindowSize () you mention that you don’t use NSWindow resizing code cause it messes up Live, so I tried resizing with this:

NSRect frame = [hostWindow frame];			
frame.size.height += newHeight - component->getHeight();
frame.size.width += newWidth - component->getWidth();
[hostWindow setFrame: frame display: YES animate: YES];
[hostWindow update];

In Cubase the window (e.g. the part Cubase paints like bypass, presets…) gets blank as soon as I resize the plugin (not only after reloading) while the (Cubase) window size still remains the same. I hoped the update would repaint the Cubase conents but it doesn’t. In fact it hasn’t any effect. (I’m quite new to Objective-C, hopefully this code isn’t to much a mess)

Can you see any possibility to notify Cubase that its window has been resized and it should repaint its content? Since there are other plugins which resize in Cubase without problems it should be possible somehow.

Chris

Hi,

Please could someone tell me what the current state of resizing plug-in windows on OSX is in JUCE?

We’re assessing whether to migrate our VST, AU & RTAS plug-ins over to JUCE, but resizing is a feature we’re interested in and this discussion thread looks like it ended with JUCE occasionally crashing Cubase in OSX. Is that right?

Thanks

Paul

The stuff in this thread should be sorted now - AFAIK it’s fine to resize in OSX.

Great - thanks Jules.