1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

VST3 Client: Fix drifting and growing windows due to inaccurate constrainer operations

The input coordinates were unnecessarily converted and truncated to
integral values before follow up calculations, and then a final
conversion back to integral values.
This commit is contained in:
attila 2024-09-13 14:19:33 +02:00
parent d6e37d78b8
commit 2c9b15e52c

View file

@ -1923,7 +1923,7 @@ private:
}
lastReportedSize.reset();
rect = convertFromHostBounds (*newSize);
rect = roundToViewRect (convertFromHostBounds (*newSize));
if (component == nullptr)
return kResultTrue;
@ -1958,7 +1958,7 @@ private:
const auto editorBounds = component->getSizeToContainChild();
const auto sizeToReport = lastReportedSize.has_value()
? *lastReportedSize
: convertToHostBounds ({ 0, 0, editorBounds.getWidth(), editorBounds.getHeight() });
: convertToHostBounds (editorBounds.withZeroOrigin().toFloat());
lastReportedSize = *size = sizeToReport;
return kResultTrue;
@ -1988,18 +1988,15 @@ private:
auto constrainedRect = component->getLocalArea (editor, editor->getLocalBounds())
.getSmallestIntegerContainer();
*rectToCheck = convertFromHostBounds (*rectToCheck);
*rectToCheck = roundToViewRect (convertFromHostBounds (*rectToCheck));
rectToCheck->right = rectToCheck->left + roundToInt (constrainedRect.getWidth());
rectToCheck->bottom = rectToCheck->top + roundToInt (constrainedRect.getHeight());
*rectToCheck = convertToHostBounds (*rectToCheck);
*rectToCheck = convertToHostBounds (createRectangle (*rectToCheck));
}
else if (auto* constrainer = editor->getConstrainer())
{
*rectToCheck = convertFromHostBounds (*rectToCheck);
auto editorBounds = editor->getLocalArea (component.get(),
Rectangle<int>::leftTopRightBottom (rectToCheck->left, rectToCheck->top,
rectToCheck->right, rectToCheck->bottom).toFloat());
const auto clientBounds = convertFromHostBounds (*rectToCheck);
const auto editorBounds = editor->getLocalArea (component.get(), clientBounds);
auto minW = (float) constrainer->getMinimumWidth();
auto maxW = (float) constrainer->getMaximumWidth();
@ -2047,13 +2044,10 @@ private:
}
}
auto constrainedRect = component->getLocalArea (editor, Rectangle<float> (width, height))
.getSmallestIntegerContainer();
auto constrainedRect = component->getLocalArea (editor, Rectangle<float> (width, height));
rectToCheck->right = rectToCheck->left + roundToInt (constrainedRect.getWidth());
rectToCheck->bottom = rectToCheck->top + roundToInt (constrainedRect.getHeight());
*rectToCheck = convertToHostBounds (*rectToCheck);
*rectToCheck = convertToHostBounds (clientBounds.withWidth (constrainedRect.getWidth())
.withHeight (constrainedRect.getHeight()));
}
}
@ -2144,30 +2138,37 @@ private:
onSize (&viewRect);
}
static ViewRect convertToHostBounds (ViewRect pluginRect)
static ViewRect roundToViewRect (Rectangle<float> r)
{
auto desktopScale = Desktop::getInstance().getGlobalScaleFactor();
if (approximatelyEqual (desktopScale, 1.0f))
return pluginRect;
return { roundToInt ((float) pluginRect.left * desktopScale),
roundToInt ((float) pluginRect.top * desktopScale),
roundToInt ((float) pluginRect.right * desktopScale),
roundToInt ((float) pluginRect.bottom * desktopScale) };
const auto rounded = r.toNearestIntEdges();
return { rounded.getX(),
rounded.getY(),
rounded.getRight(),
rounded.getBottom() };
}
static ViewRect convertFromHostBounds (ViewRect hostRect)
static Rectangle<float> createRectangle (ViewRect viewRect)
{
auto desktopScale = Desktop::getInstance().getGlobalScaleFactor();
return Rectangle<float>::leftTopRightBottom ((float) viewRect.left,
(float) viewRect.top,
(float) viewRect.right,
(float) viewRect.bottom);
}
if (approximatelyEqual (desktopScale, 1.0f))
return hostRect;
static ViewRect convertToHostBounds (Rectangle<float> pluginRect)
{
const auto desktopScale = Desktop::getInstance().getGlobalScaleFactor();
return roundToViewRect (approximatelyEqual (desktopScale, 1.0f) ? pluginRect
: pluginRect * desktopScale);
}
return { roundToInt ((float) hostRect.left / desktopScale),
roundToInt ((float) hostRect.top / desktopScale),
roundToInt ((float) hostRect.right / desktopScale),
roundToInt ((float) hostRect.bottom / desktopScale) };
static Rectangle<float> convertFromHostBounds (ViewRect hostViewRect)
{
const auto desktopScale = Desktop::getInstance().getGlobalScaleFactor();
const auto hostRect = createRectangle (hostViewRect);
return approximatelyEqual (desktopScale, 1.0f) ? hostRect
: (hostRect / desktopScale);
}
//==============================================================================
@ -2275,7 +2276,7 @@ private:
{
const ScopedValueSetter<bool> resizingChildSetter (resizingChild, true);
pluginEditor->setBounds (pluginEditor->getLocalArea (this, newBounds).withPosition (0, 0));
pluginEditor->setBounds (pluginEditor->getLocalArea (this, newBounds).withZeroOrigin());
}
lastBounds = newBounds;
@ -2299,7 +2300,7 @@ private:
if (owner.plugFrame != nullptr)
{
auto editorBounds = getSizeToContainChild();
auto newSize = convertToHostBounds ({ 0, 0, editorBounds.getWidth(), editorBounds.getHeight() });
auto newSize = convertToHostBounds (editorBounds.withZeroOrigin().toFloat());
{
const ScopedValueSetter<bool> resizingParentSetter (resizingParent, true);
@ -2313,7 +2314,7 @@ private:
#else
if (host.isWavelab() || host.isAbletonLive() || host.isBitwigStudio() || owner.owner->blueCatPatchwork)
#endif
setBounds (editorBounds.withPosition (0, 0));
setBounds (editorBounds.withZeroOrigin());
}
}
}
@ -2328,7 +2329,7 @@ private:
const ScopedValueSetter<bool> resizingChildSetter (resizingChild, true);
pluginEditor->setScaleFactor (scale);
pluginEditor->setBounds (prevEditorBounds.withPosition (0, 0));
pluginEditor->setBounds (prevEditorBounds.withZeroOrigin());
}
lastBounds = getSizeToContainChild();