commit 2b2f64ab47c6afad3740e75d3fb4d25bff5c1802
parent a3cc61e48284e8826413fec4459021f8d805c376
Author: falkTX <falktx@falktx.com>
Date: Wed, 29 Dec 2021 01:29:24 +0000
Code tweaks to better support VST3 host-side resizing, fix autoscale
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
11 files changed, 94 insertions(+), 26 deletions(-)
diff --git a/dgl/TopLevelWidget.hpp b/dgl/TopLevelWidget.hpp
@@ -110,7 +110,8 @@ public:
void setGeometryConstraints(uint minimumWidth,
uint minimumHeight,
bool keepAspectRatio = false,
- bool automaticallyScale = false);
+ bool automaticallyScale = false,
+ bool resizeNowIfAutoScaling = true);
DISTRHO_DEPRECATED_BY("getApp()")
Application& getParentApp() const noexcept { return getApp(); }
@@ -132,6 +133,8 @@ private:
#ifdef DISTRHO_DEFINES_H_INCLUDED
friend class DISTRHO_NAMESPACE::UI;
#endif
+ /** @internal */
+ virtual void requestSizeChange(uint width, uint height);
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(TopLevelWidget)
};
diff --git a/dgl/Window.hpp b/dgl/Window.hpp
@@ -399,7 +399,8 @@ public:
void setGeometryConstraints(uint minimumWidth,
uint minimumHeight,
bool keepAspectRatio = false,
- bool automaticallyScale = false);
+ bool automaticallyScale = false,
+ bool resizeNowIfAutoScaling = true);
/** DEPRECATED Use isIgnoringKeyRepeat(). */
DISTRHO_DEPRECATED_BY("isIgnoringKeyRepeat()")
@@ -473,6 +474,7 @@ private:
uint height,
double scaleFactor,
bool resizable,
+ bool isVST3,
bool doPostInit);
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Window);
diff --git a/dgl/src/TopLevelWidget.cpp b/dgl/src/TopLevelWidget.cpp
@@ -60,7 +60,7 @@ void TopLevelWidget::setSize(const Size<uint>& size)
pData->window.setSize(size);
}
-bool TopLevelWidget::setClipboard(const char* mimeType, const void* data, size_t dataSize)
+bool TopLevelWidget::setClipboard(const char* const mimeType, const void* const data, const size_t dataSize)
{
return pData->window.setClipboard(mimeType, data, dataSize);
}
@@ -103,9 +103,14 @@ void TopLevelWidget::repaint(const Rectangle<uint>& rect) noexcept
void TopLevelWidget::setGeometryConstraints(const uint minimumWidth,
const uint minimumHeight,
const bool keepAspectRatio,
- const bool automaticallyScale)
+ const bool automaticallyScale,
+ const bool resizeNowIfAutoScaling)
{
- pData->window.setGeometryConstraints(minimumWidth, minimumHeight, keepAspectRatio, automaticallyScale);
+ pData->window.setGeometryConstraints(minimumWidth,
+ minimumHeight,
+ keepAspectRatio,
+ automaticallyScale,
+ resizeNowIfAutoScaling);
}
// --------------------------------------------------------------------------------------------------------------------
@@ -137,4 +142,10 @@ bool TopLevelWidget::onScroll(const ScrollEvent& ev)
// --------------------------------------------------------------------------------------------------------------------
+void TopLevelWidget::requestSizeChange(uint, uint)
+{
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+
END_NAMESPACE_DGL
diff --git a/dgl/src/TopLevelWidgetPrivateData.hpp b/dgl/src/TopLevelWidgetPrivateData.hpp
@@ -30,7 +30,7 @@ struct TopLevelWidget::PrivateData {
Widget* const selfw;
Window& window;
- explicit PrivateData(TopLevelWidget* const s, Window& w);
+ explicit PrivateData(TopLevelWidget* self, Window& window);
~PrivateData();
void display();
bool keyboardEvent(const KeyboardEvent& ev);
diff --git a/dgl/src/Window.cpp b/dgl/src/Window.cpp
@@ -15,6 +15,7 @@
*/
#include "WindowPrivateData.hpp"
+#include "../TopLevelWidget.hpp"
#include "pugl.hpp"
@@ -87,7 +88,7 @@ Window::Window(Application& app,
const uint height,
const double scaleFactor,
const bool resizable)
- : pData(new PrivateData(app, this, parentWindowHandle, width, height, scaleFactor, resizable))
+ : pData(new PrivateData(app, this, parentWindowHandle, width, height, scaleFactor, resizable, false))
{
pData->initPost();
}
@@ -98,8 +99,9 @@ Window::Window(Application& app,
const uint height,
const double scaleFactor,
const bool resizable,
+ const bool isVST3,
const bool doPostInit)
- : pData(new PrivateData(app, this, parentWindowHandle, width, height, scaleFactor, resizable))
+ : pData(new PrivateData(app, this, parentWindowHandle, width, height, scaleFactor, resizable, isVST3))
{
if (doPostInit)
pData->initPost();
@@ -228,7 +230,19 @@ void Window::setSize(uint width, uint height)
}
}
- puglSetWindowSize(pData->view, width, height);
+ if (pData->usesSizeRequest)
+ {
+ DISTRHO_SAFE_ASSERT_RETURN(pData->topLevelWidgets.size() != 0,);
+
+ TopLevelWidget* const topLevelWidget = pData->topLevelWidgets.front();
+ DISTRHO_SAFE_ASSERT_RETURN(topLevelWidget != nullptr,);
+
+ topLevelWidget->requestSizeChange(width, height);
+ }
+ else
+ {
+ puglSetWindowSize(pData->view, width, height);
+ }
}
void Window::setSize(const Size<uint>& size)
@@ -371,10 +385,11 @@ Size<uint> Window::getGeometryConstraints(bool& keepAspectRatio)
return Size<uint>(pData->minWidth, pData->minHeight);
}
-void Window::setGeometryConstraints(const uint minimumWidth,
- const uint minimumHeight,
+void Window::setGeometryConstraints(uint minimumWidth,
+ uint minimumHeight,
const bool keepAspectRatio,
- const bool automaticallyScale)
+ const bool automaticallyScale,
+ const bool resizeNowIfAutoScaling)
{
DISTRHO_SAFE_ASSERT_RETURN(minimumWidth > 0,);
DISTRHO_SAFE_ASSERT_RETURN(minimumHeight > 0,);
@@ -389,12 +404,15 @@ void Window::setGeometryConstraints(const uint minimumWidth,
const double scaleFactor = pData->scaleFactor;
- puglSetGeometryConstraints(pData->view,
- static_cast<uint>(minimumWidth * scaleFactor + 0.5),
- static_cast<uint>(minimumHeight * scaleFactor + 0.5),
- keepAspectRatio);
+ if (automaticallyScale && scaleFactor != 1.0)
+ {
+ minimumWidth *= scaleFactor;
+ minimumHeight *= scaleFactor;
+ }
+
+ puglSetGeometryConstraints(pData->view, minimumWidth, minimumHeight, keepAspectRatio);
- if (scaleFactor != 1.0)
+ if (scaleFactor != 1.0 && automaticallyScale && resizeNowIfAutoScaling)
{
const Size<uint> size(getSize());
diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp
@@ -76,6 +76,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s)
isClosed(true),
isVisible(false),
isEmbed(false),
+ usesSizeRequest(false),
scaleFactor(getDesktopScaleFactor(view)),
autoScaling(false),
autoScaleFactor(1.0),
@@ -103,6 +104,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, PrivateData* c
isClosed(true),
isVisible(false),
isEmbed(false),
+ usesSizeRequest(false),
scaleFactor(ppData->scaleFactor),
autoScaling(false),
autoScaleFactor(1.0),
@@ -134,6 +136,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s,
isClosed(parentWindowHandle == 0),
isVisible(parentWindowHandle != 0),
isEmbed(parentWindowHandle != 0),
+ usesSizeRequest(false),
scaleFactor(scale != 0.0 ? scale : getDesktopScaleFactor(view)),
autoScaling(false),
autoScaleFactor(1.0),
@@ -157,7 +160,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s,
Window::PrivateData::PrivateData(Application& a, Window* const s,
const uintptr_t parentWindowHandle,
const uint width, const uint height,
- const double scale, const bool resizable)
+ const double scale, const bool resizable, const bool isVST3)
: app(a),
appData(a.pData),
self(s),
@@ -167,6 +170,7 @@ Window::PrivateData::PrivateData(Application& a, Window* const s,
isClosed(parentWindowHandle == 0),
isVisible(parentWindowHandle != 0 && view != nullptr),
isEmbed(parentWindowHandle != 0),
+ usesSizeRequest(isVST3),
scaleFactor(scale != 0.0 ? scale : getDesktopScaleFactor(view)),
autoScaling(false),
autoScaleFactor(1.0),
diff --git a/dgl/src/WindowPrivateData.hpp b/dgl/src/WindowPrivateData.hpp
@@ -63,6 +63,9 @@ struct Window::PrivateData : IdleCallback {
/** Whether this Window is embed into another (usually not DGL-controlled) Window. */
const bool isEmbed;
+ /** Whether to ignore resize requests and feed them into the host instead. used for VST3 */
+ const bool usesSizeRequest;
+
/** Scale factor to report to widgets on request, purely informational. */
double scaleFactor;
@@ -127,7 +130,7 @@ struct Window::PrivateData : IdleCallback {
/** Constructor for an embed Window, with a few extra hints from the host side. */
explicit PrivateData(Application& app, Window* self, uintptr_t parentWindowHandle,
- uint width, uint height, double scaling, bool resizable);
+ uint width, uint height, double scaling, bool resizable, bool isVST3);
/** Destructor. */
~PrivateData() override;
diff --git a/distrho/DistrhoUI.hpp b/distrho/DistrhoUI.hpp
@@ -84,7 +84,7 @@ public:
It assumes aspect ratio is meant to be kept.
Manually call setGeometryConstraints instead if keeping UI aspect ratio is not required.
*/
- UI(uint width = 0, uint height = 0, bool automaticallyScale = false);
+ UI(uint width = 0, uint height = 0, bool automaticallyScaleAndSetAsMinimumSize = false);
/**
Destructor.
@@ -358,6 +358,10 @@ private:
PrivateData* const uiData;
friend class DGL_NAMESPACE::PluginWindow;
friend class UIExporter;
+#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+ /** @internal */
+ void requestSizeChange(uint width, uint height) override;
+#endif
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UI)
};
diff --git a/distrho/src/DistrhoUI.cpp b/distrho/src/DistrhoUI.cpp
@@ -189,21 +189,21 @@ UI::PrivateData::createNextWindow(UI* const ui, const uint width, const uint hei
/* ------------------------------------------------------------------------------------------------------------
* UI */
-UI::UI(const uint width, const uint height, const bool automaticallyScale)
+UI::UI(const uint width, const uint height, const bool automaticallyScaleAndSetAsMinimumSize)
: UIWidget(UI::PrivateData::createNextWindow(this, width, height)),
uiData(UI::PrivateData::s_nextPrivateData)
{
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
- if (width > 0 && height > 0)
+ if (width != 0 && height != 0)
{
Widget::setSize(width, height);
- if (automaticallyScale)
+ if (automaticallyScaleAndSetAsMinimumSize)
setGeometryConstraints(width, height, true, true);
}
#else
// unused
- return; (void)automaticallyScale;
+ (void)automaticallyScaleAndSetAsMinimumSize;
#endif
}
@@ -370,9 +370,20 @@ void UI::onResize(const ResizeEvent& ev)
{
UIWidget::onResize(ev);
+#ifndef DISTRHO_PLUGIN_TARGET_VST3
+ if (uiData->initializing)
+ return;
+
const uint width = ev.size.getWidth();
const uint height = ev.size.getHeight();
uiData->setSizeCallback(width, height);
+#endif
+}
+
+// NOTE: only used for VST3
+void UI::requestSizeChange(const uint width, const uint height)
+{
+ uiData->setSizeCallback(width, height);
}
#endif
diff --git a/distrho/src/DistrhoUIInternal.hpp b/distrho/src/DistrhoUIInternal.hpp
@@ -98,6 +98,7 @@ public:
DISTRHO_SAFE_ASSERT_RETURN(uiPtr != nullptr,);
ui = uiPtr;
+ uiData->initializing = false;
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
// unused
diff --git a/distrho/src/DistrhoUIPrivateData.hpp b/distrho/src/DistrhoUIPrivateData.hpp
@@ -33,7 +33,13 @@
# define DISTRHO_UI_IS_STANDALONE 0
#endif
-#if defined(DISTRHO_PLUGIN_TARGET_VST2)
+#ifdef DISTRHO_PLUGIN_TARGET_VST3
+# define DISTRHO_UI_IS_VST3 1
+#else
+# define DISTRHO_UI_IS_VST3 0
+#endif
+
+#ifdef DISTRHO_PLUGIN_TARGET_VST2
# undef DISTRHO_UI_USER_RESIZABLE
# define DISTRHO_UI_USER_RESIZABLE 0
#endif
@@ -175,7 +181,8 @@ public:
const uint width,
const uint height,
const double scaleFactor)
- : Window(app, parentWindowHandle, width, height, scaleFactor, DISTRHO_UI_USER_RESIZABLE, false),
+ : Window(app, parentWindowHandle, width, height, scaleFactor,
+ DISTRHO_UI_USER_RESIZABLE, DISTRHO_UI_IS_VST3, false),
ui(uiPtr),
initializing(true),
receivedReshapeDuringInit(false)
@@ -332,6 +339,9 @@ struct UI::PrivateData {
#endif
char* bundlePath;
+ // Ignore initial resize events while initializing
+ bool initializing;
+
// Callbacks
void* callbacksPtr;
editParamFunc editParamCallbackFunc;
@@ -355,6 +365,7 @@ struct UI::PrivateData {
uiStateFileKeyRequest(nullptr),
#endif
bundlePath(nullptr),
+ initializing(true),
callbacksPtr(nullptr),
editParamCallbackFunc(nullptr),
setParamCallbackFunc(nullptr),