mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-07 12:10:09 +02:00
Run certain GUI tasks from the host's run loop
This was a bit of a tricky one because it requires simulating mutual recursion, but it's needed for REAPER as otherwide calls to `IPlugFrame::resizeView()` and `IContextMenu::popup()` might cause REAPER to segfault because its GUI is not thread safe.
This commit is contained in:
+14
-14
@@ -206,20 +206,16 @@ Vst3PluginBridge::Vst3PluginBridge()
|
||||
},
|
||||
[&](const YaContextMenu::Popup& request)
|
||||
-> YaContextMenu::Popup::Response {
|
||||
// FIXME: In REAPER having the menu open without interacting
|
||||
// with it causes malloc failures or failing font
|
||||
// drawing calls. Valgrind reports all kinds of
|
||||
// memory errors within REAPER when this happens, and
|
||||
// I'm not sure if yabridge is to blame here. - As it
|
||||
// turns out a lot of stuff in REAPEr, including
|
||||
// calls to `IPlugFrame::resizeView()`, are not
|
||||
// thread safe. We need to hook into `IRunLoop` and
|
||||
// execute `IContextMenu::popup()` and
|
||||
// `IPlugFrame::resizeView()` functions from there.
|
||||
// REAPER requires this to be run from its provided event
|
||||
// loop or else it will likely segfault at some point
|
||||
return plugin_proxies.at(request.owner_instance_id)
|
||||
.get()
|
||||
.context_menus.at(request.context_menu_id)
|
||||
.menu->popup(request.x, request.y);
|
||||
.last_created_plug_view->run_gui_task<tresult>([&]() {
|
||||
return plugin_proxies.at(request.owner_instance_id)
|
||||
.get()
|
||||
.context_menus.at(request.context_menu_id)
|
||||
.menu->popup(request.x, request.y);
|
||||
});
|
||||
},
|
||||
[&](YaConnectionPoint::Notify& request)
|
||||
-> YaConnectionPoint::Notify::Response {
|
||||
@@ -267,8 +263,12 @@ Vst3PluginBridge::Vst3PluginBridge()
|
||||
.get()
|
||||
.last_created_plug_view;
|
||||
|
||||
return plug_view->plug_frame->resizeView(plug_view,
|
||||
&request.new_size);
|
||||
// REAPER requires this to be run from its provided event
|
||||
// loop or else it will likely segfault at some point
|
||||
return plug_view->run_gui_task<tresult>([&]() {
|
||||
return plug_view->plug_frame->resizeView(
|
||||
plug_view, &request.new_size);
|
||||
});
|
||||
},
|
||||
[&](const YaPlugInterfaceSupport::IsPlugInterfaceSupported&
|
||||
request) -> YaPlugInterfaceSupport::
|
||||
|
||||
Reference in New Issue
Block a user