From 2b2f64ab47c6afad3740e75d3fb4d25bff5c1802 Mon Sep 17 00:00:00 2001 From: falkTX Date: Wed, 29 Dec 2021 01:29:51 +0000 Subject: [PATCH] Code tweaks to better support VST3 host-side resizing, fix autoscale Signed-off-by: falkTX --- dgl/TopLevelWidget.hpp | 5 +++- dgl/Window.hpp | 4 ++- dgl/src/TopLevelWidget.cpp | 17 ++++++++++-- dgl/src/TopLevelWidgetPrivateData.hpp | 2 +- dgl/src/Window.cpp | 40 +++++++++++++++++++-------- dgl/src/WindowPrivateData.cpp | 6 +++- dgl/src/WindowPrivateData.hpp | 5 +++- distrho/DistrhoUI.hpp | 6 +++- distrho/src/DistrhoUI.cpp | 19 ++++++++++--- distrho/src/DistrhoUIInternal.hpp | 1 + distrho/src/DistrhoUIPrivateData.hpp | 15 ++++++++-- 11 files changed, 94 insertions(+), 26 deletions(-) diff --git a/dgl/TopLevelWidget.hpp b/dgl/TopLevelWidget.hpp index 522dfaf8..5e53784e 100644 --- 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 index f91bb41e..3de57e86 100644 --- 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 index 9a6b5c26..f577a1c9 100644 --- a/dgl/src/TopLevelWidget.cpp +++ b/dgl/src/TopLevelWidget.cpp @@ -60,7 +60,7 @@ void TopLevelWidget::setSize(const Size& 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& 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 index 7105b2f8..fb4e77b2 100644 --- 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 index 1e2f3a12..146fffc7 100644 --- 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& size) @@ -371,10 +385,11 @@ Size Window::getGeometryConstraints(bool& keepAspectRatio) return Size(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(minimumWidth * scaleFactor + 0.5), - static_cast(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 size(getSize()); diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp index 028170fd..6a9467d5 100644 --- 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 index ffb2237a..36d2ce43 100644 --- 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 index e7140828..dc09efda 100644 --- 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 index ee62ee68..7f26308c 100644 --- 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 index 669d2427..742ea537 100644 --- 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 index 1f1192a8..d03ab16e 100644 --- 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),