diff --git a/src/wine-host/bridges/vst3-impls/connection-point-proxy.cpp b/src/wine-host/bridges/vst3-impls/connection-point-proxy.cpp index 39b547d2..f4ef6ff0 100644 --- a/src/wine-host/bridges/vst3-impls/connection-point-proxy.cpp +++ b/src/wine-host/bridges/vst3-impls/connection-point-proxy.cpp @@ -52,7 +52,11 @@ Vst3ConnectionPointProxyImpl::disconnect(IConnectionPoint* /*other*/) { tresult PLUGIN_API Vst3ConnectionPointProxyImpl::notify(Steinberg::Vst::IMessage* message) { if (message) { - return bridge.send_message( + // FabFilter plugins require this to be done from the GUI thread so we + // need to use our mutual recursion mechanism. Luckily only Ardour uses + // connection proxies, so if this ends up breaking something it will + // only affect Ardour. + return bridge.send_mutually_recursive_message( YaConnectionPoint::Notify{.instance_id = owner_instance_id(), .message_ptr = YaMessagePtr(*message)}); } else { diff --git a/src/wine-host/bridges/vst3.cpp b/src/wine-host/bridges/vst3.cpp index dc4e8420..1d553e9d 100644 --- a/src/wine-host/bridges/vst3.cpp +++ b/src/wine-host/bridges/vst3.cpp @@ -280,9 +280,17 @@ void Vst3Bridge::run() { // We should thus be passing a (raw) pointer to the // original object so we can pretend none of this wrapping // and serializing has ever happened. - return object_instances[request.instance_id] - .connection_point->notify( - request.message_ptr.get_original()); + // NOTE: FabFilter plugins require some of their messages to be + // handled from the GUI thread. This could make the GUI + // much slower in Ardour, but there's no other non-hacky + // solution for this (and bypassing Ardour's connection + // proxies sort of goes against the idea behind yabridge) + return do_mutual_recursion_or_handle_in_main_context( + [&]() { + return object_instances[request.instance_id] + .connection_point->notify( + request.message_ptr.get_original()); + }); }, [&](YaContextMenuTarget::ExecuteMenuItem& request) -> YaContextMenuTarget::ExecuteMenuItem::Response {