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 b4fd7b7c..19ed4039 100644 --- a/src/wine-host/bridges/vst3-impls/plug-frame-proxy.cpp +++ b/src/wine-host/bridges/vst3-impls/plug-frame-proxy.cpp @@ -43,6 +43,11 @@ Vst3PlugFrameProxyImpl::resizeView(Steinberg::IPlugView* /*view*/, // assume `view` is the `IPlugView*` returned by the last call to // `IEditController::createView()` + // Resize the editor wrapper window in advance. We will do another + // resize automatically on `IPlugView::onSize()`, but this should make + // resizes look a bit smoother. + bridge.maybe_resize_editor(owner_instance_id(), *newSize); + // 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. diff --git a/src/wine-host/bridges/vst3.cpp b/src/wine-host/bridges/vst3.cpp index e283b2f4..f498fbf4 100644 --- a/src/wine-host/bridges/vst3.cpp +++ b/src/wine-host/bridges/vst3.cpp @@ -749,9 +749,17 @@ void Vst3Bridge::run() { editor_instance.get_win32_handle(), type.c_str()); - // Get rid of the editor again if the plugin didn't - // embed itself in it - if (result != Steinberg::kResultOk) { + // Set the window's initial size according to what the + // plugin reports. Otherwise get rid of the editor again + // if the plugin didn't embed itself in it. + if (result == Steinberg::kResultOk) { + Steinberg::ViewRect size{}; + if (instance.plug_view_instance->plug_view->getSize( + &size) == Steinberg::kResultOk) { + instance.editor->resize(size.getWidth(), + size.getHeight()); + } + } else { instance.editor.reset(); } @@ -837,6 +845,9 @@ void Vst3Bridge::run() { .size = std::move(size)}; }, [&](YaPlugView::OnSize& request) -> YaPlugView::OnSize::Response { + Vst3PluginInstance& instance = + object_instances.at(request.owner_instance_id); + // HACK: This function has to be run from the UI thread since // the plugin probably wants to redraw when it gets // resized. The issue here is that this function can be @@ -847,9 +858,18 @@ void Vst3Bridge::run() { // response to the message it sent. See the docstring of // this function for more information on how this works. return do_mutual_recursion_on_gui_thread([&]() -> tresult { - return object_instances.at(request.owner_instance_id) - .plug_view_instance->plug_view->onSize( + const tresult result = + instance.plug_view_instance->plug_view->onSize( &request.new_size); + + // Also resize our wrapper window if the plugin agreed to + // the new size + if (result == Steinberg::kResultOk && instance.editor) { + instance.editor->resize(request.new_size.getWidth(), + request.new_size.getHeight()); + } + + return result; }); }, [&](const YaPlugView::OnFocus& request) @@ -1202,6 +1222,17 @@ void Vst3Bridge::handle_x11_events() noexcept { } } +bool Vst3Bridge::maybe_resize_editor(size_t instance_id, + const Steinberg::ViewRect& new_size) { + Vst3PluginInstance& instance = object_instances.at(instance_id); + if (instance.editor) { + instance.editor->resize(new_size.getWidth(), new_size.getHeight()); + return true; + } else { + return false; + } +} + void Vst3Bridge::register_context_menu(Vst3ContextMenuProxyImpl& context_menu) { std::lock_guard lock(object_instances.at(context_menu.owner_instance_id()) .registered_context_menus_mutex); diff --git a/src/wine-host/bridges/vst3.h b/src/wine-host/bridges/vst3.h index 6da16c12..bcae26d9 100644 --- a/src/wine-host/bridges/vst3.h +++ b/src/wine-host/bridges/vst3.h @@ -292,6 +292,14 @@ class Vst3Bridge : public HostBridge { void handle_x11_events() noexcept override; + /** + * If the plugin instance has an editor, resize the wrapper window to match + * the new size. This is called from `IPlugFrame::resizeView()` to make sure + * we do the resize before the request gets sent to the host. + */ + bool maybe_resize_editor(size_t instance_id, + const 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