From 8ec0f8b8978a8f6ad4f24150e66b500a49b6312b Mon Sep 17 00:00:00 2001 From: Juuso Kaitila Date: Fri, 16 Jan 2026 19:28:39 +0200 Subject: [PATCH] VST3: Fix making plugin windows larger not working in Carla Fixes making VST3 plugins larger than their original size in Carla. The plugin would resize but not get drawn past the original window size. --- .../bridges/vst3-impls/plug-frame-proxy.cpp | 14 +++++++++++-- src/wine-host/bridges/vst3.cpp | 20 +++++++++++++++++++ src/wine-host/bridges/vst3.h | 8 ++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/wine-host/bridges/vst3-impls/plug-frame-proxy.cpp b/src/wine-host/bridges/vst3-impls/plug-frame-proxy.cpp index f7026d25..f1e2b933 100644 --- a/src/wine-host/bridges/vst3-impls/plug-frame-proxy.cpp +++ b/src/wine-host/bridges/vst3-impls/plug-frame-proxy.cpp @@ -52,8 +52,18 @@ Vst3PlugFrameProxyImpl::resizeView(Steinberg::IPlugView* /*view*/, // We have to use this special sending function here so we can handle // calls to `IPlugView::onSize()` from this same thread (the UI thread). // See the docstring for more information. - return bridge_.send_mutually_recursive_message(YaPlugFrame::ResizeView{ - .owner_instance_id = owner_instance_id(), .new_size = *newSize}); + const tresult result = + bridge_.send_mutually_recursive_message(YaPlugFrame::ResizeView{ + .owner_instance_id = owner_instance_id(), .new_size = *newSize}); + + // Some hosts (like Carla) don't call onSize() after accepting a + // resizeView() request. This causes the plugin to not know about its + // new size, so it doesn't draw beyond the original size. Call the + // plugin's onSize() ourselves to ensure it knows the new size. If the + // host already called onSize(), this will be a harmless duplicate call. + bridge_.notify_plugin_on_new_size(owner_instance_id(), *newSize); + + return result; } else { std::cerr << "WARNING: Null pointer passed to 'IPlugFrame::resizeView()'" diff --git a/src/wine-host/bridges/vst3.cpp b/src/wine-host/bridges/vst3.cpp index d2eec2f5..b48548e8 100644 --- a/src/wine-host/bridges/vst3.cpp +++ b/src/wine-host/bridges/vst3.cpp @@ -1388,6 +1388,26 @@ bool Vst3Bridge::resize_editor(size_t instance_id, } } +void Vst3Bridge::notify_plugin_on_new_size(size_t instance_id, + Steinberg::ViewRect& new_size) { + const auto& [instance, _] = get_instance(instance_id); + + if (instance.plug_view_instance) { + // Skip if the host already called onSize() with this size during + // resizeView(). This is detected by checking if last_set_size already + // matches new_size (the OnSize handler updates last_set_size). + if (instance.last_set_size.getWidth() == new_size.getWidth() && + instance.last_set_size.getHeight() == new_size.getHeight()) { + return; + } + + instance.plug_view_instance->plug_view->onSize(&new_size); + + // Update last_set_size so getSize() returns consistent values + instance.last_set_size = new_size; + } +} + void Vst3Bridge::register_context_menu(Vst3ContextMenuProxyImpl& context_menu) { const auto& [owner_instance, _] = get_instance(context_menu.owner_instance_id()); diff --git a/src/wine-host/bridges/vst3.h b/src/wine-host/bridges/vst3.h index 75054893..3bef4c36 100644 --- a/src/wine-host/bridges/vst3.h +++ b/src/wine-host/bridges/vst3.h @@ -318,6 +318,14 @@ class Vst3Bridge : public HostBridge { */ bool resize_editor(size_t instance_id, const Steinberg::ViewRect& new_size); + /** + * Notify the plugin of its new size by calling `IPlugView::onSize()`. + * This is called after `resize_editor()` for hosts that don't call + * `onSize()` after accepting a `resizeView()` request (like Carla). + */ + void notify_plugin_on_new_size(size_t instance_id, + Steinberg::ViewRect& new_size); + /** * Register a context with with `context_menu`'s ID and owner in * `object_instances`. This will be called during the constructor of