Browse Source

VST3 Host: Ensure that plugins open with their top left corner in the right position

This fixes a bug on Windows where plugins that do not implement the
IPlugViewContentScaleSupport interface opened in the AudioPluginHost
with their editors in the very top left corner of the window, rather
than below the window's titlebar.

Examples of plugins with no scaling support, suitable for reproducing
the issue:
- U-He Hive 2.1.1 Rev 12092 x64
- FabFilter Pro-C 1.23 x64
v6.1.6
reuk 4 years ago
parent
commit
9bec8e633a
No known key found for this signature in database GPG Key ID: 9ADCD339CFC98A11
1 changed files with 20 additions and 43 deletions
  1. +20
    -43
      modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp

+ 20
- 43
modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp View File

@@ -1450,22 +1450,9 @@ struct VST3PluginWindow : public AudioProcessorEditor,
} }
} }
void componentMovedOrResized (bool wasMoved, bool wasResized) override
void componentMovedOrResized (bool, bool wasResized) override
{ {
if (recursiveResize || getTopLevelComponent()->getPeer() == nullptr)
return;
ignoreUnused (wasMoved);
#if JUCE_WINDOWS
if (wasMoved)
{
const auto pos = getPluginWindowTopLeft();
setPluginWindowPos ({ pos.x, pos.y, 0, 0 }, SWP_NOSIZE);
}
#endif
if (! wasResized)
if (recursiveResize || ! wasResized || getTopLevelComponent()->getPeer() == nullptr)
return; return;
ViewRect rect; ViewRect rect;
@@ -1485,8 +1472,7 @@ struct VST3PluginWindow : public AudioProcessorEditor,
} }
#if JUCE_WINDOWS #if JUCE_WINDOWS
setPluginWindowPos (Rectangle<int> (rect.getWidth(), rect.getHeight())
.withPosition (getPluginWindowTopLeft()), 0);
setPluginWindowPos (rect);
#else #else
embeddedComponent.setBounds (getLocalBounds()); embeddedComponent.setBounds (getLocalBounds());
#endif #endif
@@ -1498,8 +1484,7 @@ struct VST3PluginWindow : public AudioProcessorEditor,
warnOnFailure (view->getSize (&rect)); warnOnFailure (view->getSize (&rect));
#if JUCE_WINDOWS #if JUCE_WINDOWS
setPluginWindowPos (Rectangle<int> (rect.getWidth(), rect.getHeight())
.withPosition (getPluginWindowTopLeft()), 0);
setPluginWindowPos (rect);
#else #else
resizeWithRect (embeddedComponent, rect, nativeScaleFactor); resizeWithRect (embeddedComponent, rect, nativeScaleFactor);
#endif #endif
@@ -1528,13 +1513,10 @@ struct VST3PluginWindow : public AudioProcessorEditor,
nativeScaleFactor = (float) newScaleFactor; nativeScaleFactor = (float) newScaleFactor;
if (pluginHandle == HandleFormat{})
return;
if (scaleInterface != nullptr)
if (pluginHandle != HandleFormat{} && scaleInterface != nullptr)
scaleInterface->setContentScaleFactor ((Steinberg::IPlugViewContentScaleSupport::ScaleFactor) nativeScaleFactor); scaleInterface->setContentScaleFactor ((Steinberg::IPlugViewContentScaleSupport::ScaleFactor) nativeScaleFactor);
componentMovedOrResized (true, true);
else
resizeToFit();
} }
void resizeToFit() void resizeToFit()
@@ -1586,10 +1568,8 @@ private:
//============================================================================== //==============================================================================
static void resizeWithRect (Component& comp, const ViewRect& rect, float scaleFactor) static void resizeWithRect (Component& comp, const ViewRect& rect, float scaleFactor)
{ {
comp.setBounds (roundToInt ((float) rect.left / scaleFactor),
roundToInt ((float) rect.top / scaleFactor),
jmax (10, std::abs (roundToInt ((float) rect.getWidth() / scaleFactor))),
jmax (10, std::abs (roundToInt ((float) rect.getHeight() / scaleFactor))));
comp.setSize (jmax (10, std::abs (roundToInt ((float) rect.getWidth() / scaleFactor))),
jmax (10, std::abs (roundToInt ((float) rect.getHeight() / scaleFactor))));
} }
void attachPluginWindow() void attachPluginWindow()
@@ -1622,8 +1602,8 @@ private:
if (scaleInterface != nullptr) if (scaleInterface != nullptr)
scaleInterface->setContentScaleFactor ((Steinberg::IPlugViewContentScaleSupport::ScaleFactor) nativeScaleFactor); scaleInterface->setContentScaleFactor ((Steinberg::IPlugViewContentScaleSupport::ScaleFactor) nativeScaleFactor);
componentMovedOrResized (true, true);
else
resizeToFit();
} }
} }
@@ -1651,22 +1631,19 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildComponent) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChildComponent)
}; };
Point<int> getPluginWindowTopLeft()
void setPluginWindowPos (ViewRect rect)
{ {
if (auto* topComp = getTopLevelComponent()) if (auto* topComp = getTopLevelComponent())
return (topComp->getLocalPoint (this, Point<int>()) * nativeScaleFactor).roundToInt();
return {};
}
{
auto pos = (topComp->getLocalPoint (this, Point<int>()) * nativeScaleFactor).roundToInt();
void setPluginWindowPos (Rectangle<int> rect, int extraFlags)
{
ScopedThreadDPIAwarenessSetter threadDpiAwarenessSetter { pluginHandle };
ScopedThreadDPIAwarenessSetter threadDpiAwarenessSetter { pluginHandle };
SetWindowPos (pluginHandle, nullptr,
rect.getX(), rect.getY(),
rect.getWidth(), rect.getHeight(),
extraFlags | (isVisible() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
SetWindowPos (pluginHandle, nullptr,
pos.x, pos.y,
rect.getWidth(), rect.getHeight(),
isVisible() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW);
}
} }
ChildComponent embeddedComponent; ChildComponent embeddedComponent;


Loading…
Cancel
Save