Asymmetry in VST3PluginWindow::checkBounds leading to window jitter

We’ve got an issue when viewing VST3 plugin windows that allow the host window to control their size. They essentially flip between two sizes making it impossible to use (see attached video). This happens on macOS and Windows.

The problem seems to be an asymmetry when converting coordinates from juce to vst3 space and back again:

    void checkBounds (Rectangle<int>& bounds,
                      const Rectangle<int>&,
                      const Rectangle<int>&,
                      bool,
                      bool,
                      bool,
                      bool) override
    {
        auto rect = componentToVST3Rect (bounds);
        view->checkSizeConstraint (&rect);
        bounds = vst3ToComponentRect (rect);
    }

    /*  Convert from the component's coordinate system to the hosted VST3's coordinate system. */
    ViewRect componentToVST3Rect (Rectangle<int> r) const
    {
        const auto physical = localAreaToGlobal (r) * nativeScaleFactor * getDesktopScaleFactor();
        return { 0, 0, physical.getWidth(), physical.getHeight() };
    }

    /*  Convert from the hosted VST3's coordinate system to the component's coordinate system. */
    Rectangle<int> vst3ToComponentRect (const ViewRect& vr) const
    {
        return getLocalArea (nullptr, Rectangle<int> { vr.right, vr.bottom } / (nativeScaleFactor * getDesktopScaleFactor()));
    }

N.B. this is better on the juce8 branch with this modification:

        auto rect = componentToVST3Rect (bounds);
        auto constrainedRect = rect;
        view->checkSizeConstraint (&constrainedRect);

        // Prevent inadvertent window growth while dragging; see componentMovedOrResized below
        if (constrainedRect.getWidth() != rect.getWidth() || constrainedRect.getHeight() != rect.getHeight())
            bounds = vst3ToComponentRect (constrainedRect);

but that doesn’t fully solve the problem…


The problem is that the origin is getting sliced off so is being used to reposition the window.

    void checkBounds (Rectangle<int>& bounds,
                      const Rectangle<int>&,
                      const Rectangle<int>&,
                      bool,
                      bool,
                      bool,
                      bool) override
    {
        auto pos = bounds.getPosition();
        auto rect = componentToVST3Rect (bounds);
        auto constrainedRect = rect;
        view->checkSizeConstraint (&constrainedRect);

        // Prevent inadvertent window growth while dragging; see componentMovedOrResized below
        if (constrainedRect.getWidth() != rect.getWidth() || constrainedRect.getHeight() != rect.getHeight())
            bounds = vst3ToComponentRect (constrainedRect).withPosition (pos);
    }

Shouldn’t it be something like this to ensure the position doesn’t change?

Thank you for reporting this. I agree with the suggested change. We did not notice this issue earlier because the AudioPluginHost relies on code that restores the lost position.

With the proposed change in place, is the issue completely resolved in your codebase?

I’ve just had a report this morning that the window borders are lost when Windows scaling is not 100% with this change. I need to double check why that is and if it’s new behaviour or not.

Hi Dave,

We still have this lined up for release, as it seems a real issue. Did you have any feedback suggesting that this caused the window border changes? I haven’t discovered such issues in my testing.

Hi @attila I’ve just tested this and it seems to work ok now so I think the fix is good to go. Thanks.