Enable mutually recursive GUI callbacks in CLAP

This fixes resizing under Qtractor.
This commit is contained in:
Robbert van der Helm
2022-10-08 20:32:01 +02:00
parent bd272ffc5f
commit 431dbdca02
3 changed files with 55 additions and 62 deletions
@@ -184,7 +184,7 @@ clap_host_proxy::ext_gui_resize_hints_changed(const clap_host_t* host) {
assert(host && host->host_data); assert(host && host->host_data);
auto self = static_cast<const clap_host_proxy*>(host->host_data); auto self = static_cast<const clap_host_proxy*>(host->host_data);
self->bridge_.send_main_thread_message( self->bridge_.send_mutually_recursive_main_thread_message(
clap::ext::gui::host::ResizeHintsChanged{ clap::ext::gui::host::ResizeHintsChanged{
.owner_instance_id = self->owner_instance_id()}); .owner_instance_id = self->owner_instance_id()});
} }
@@ -195,11 +195,12 @@ bool CLAP_ABI clap_host_proxy::ext_gui_request_resize(const clap_host_t* host,
assert(host && host->host_data); assert(host && host->host_data);
auto self = static_cast<const clap_host_proxy*>(host->host_data); auto self = static_cast<const clap_host_proxy*>(host->host_data);
const bool result = self->bridge_.send_main_thread_message( const bool result =
clap::ext::gui::host::RequestResize{ self->bridge_.send_mutually_recursive_main_thread_message(
.owner_instance_id = self->owner_instance_id(), clap::ext::gui::host::RequestResize{
.width = width, .owner_instance_id = self->owner_instance_id(),
.height = height}); .width = width,
.height = height});
// If the resize request was accepted by the host, then we'll also resize // If the resize request was accepted by the host, then we'll also resize
// our editor window // our editor window
@@ -215,7 +216,7 @@ bool CLAP_ABI clap_host_proxy::ext_gui_request_show(const clap_host_t* host) {
assert(host && host->host_data); assert(host && host->host_data);
auto self = static_cast<const clap_host_proxy*>(host->host_data); auto self = static_cast<const clap_host_proxy*>(host->host_data);
return self->bridge_.send_main_thread_message( return self->bridge_.send_mutually_recursive_main_thread_message(
clap::ext::gui::host::RequestShow{.owner_instance_id = clap::ext::gui::host::RequestShow{.owner_instance_id =
self->owner_instance_id()}); self->owner_instance_id()});
} }
@@ -224,7 +225,7 @@ bool CLAP_ABI clap_host_proxy::ext_gui_request_hide(const clap_host_t* host) {
assert(host && host->host_data); assert(host && host->host_data);
auto self = static_cast<const clap_host_proxy*>(host->host_data); auto self = static_cast<const clap_host_proxy*>(host->host_data);
return self->bridge_.send_main_thread_message( return self->bridge_.send_mutually_recursive_main_thread_message(
clap::ext::gui::host::RequestHide{.owner_instance_id = clap::ext::gui::host::RequestHide{.owner_instance_id =
self->owner_instance_id()}); self->owner_instance_id()});
} }
+45 -53
View File
@@ -429,21 +429,20 @@ void ClapBridge::run() {
<< std::endl; << std::endl;
return false; return false;
} else { } else {
return main_context_ return do_mutual_recursion_on_gui_thread(
.run_in_context([&, plugin = instance.plugin.get(), [&, plugin = instance.plugin.get(),
gui = instance.extensions.gui]() { gui = instance.extensions.gui]() {
return gui->set_scale(plugin, request.scale); return gui->set_scale(plugin, request.scale);
}) });
.get();
} }
}, },
[&](const clap::ext::gui::plugin::GetSize& request) [&](const clap::ext::gui::plugin::GetSize& request)
-> clap::ext::gui::plugin::GetSize::Response { -> clap::ext::gui::plugin::GetSize::Response {
const auto& [instance, _] = get_instance(request.instance_id); const auto& [instance, _] = get_instance(request.instance_id);
return main_context_ return do_mutual_recursion_on_gui_thread(
.run_in_context([&, plugin = instance.plugin.get(), [&, plugin = instance.plugin.get(),
gui = instance.extensions.gui]() { gui = instance.extensions.gui]() {
uint32_t width{}; uint32_t width{};
uint32_t height{}; uint32_t height{};
const bool result = const bool result =
@@ -451,49 +450,46 @@ void ClapBridge::run() {
return clap::ext::gui::plugin::GetSizeResponse{ return clap::ext::gui::plugin::GetSizeResponse{
.result = result, .width = width, .height = height}; .result = result, .width = width, .height = height};
}) });
.get();
}, },
[&](clap::ext::gui::plugin::CanResize& request) [&](clap::ext::gui::plugin::CanResize& request)
-> clap::ext::gui::plugin::CanResize::Response { -> clap::ext::gui::plugin::CanResize::Response {
const auto& [instance, _] = get_instance(request.instance_id); const auto& [instance, _] = get_instance(request.instance_id);
// TODO: Qtractor calls this in response to request_resize(), so return do_mutual_recursion_on_gui_thread(
// we need to handle mutual recursion here. We should do [&, plugin = instance.plugin.get(),
// this for all GUI functions just to be safe. gui = instance.extensions.gui]() {
return main_context_
.run_in_context([&, plugin = instance.plugin.get(),
gui = instance.extensions.gui]() {
return gui->can_resize(plugin); return gui->can_resize(plugin);
}) });
.get();
}, },
[&](const clap::ext::gui::plugin::GetResizeHints& request) [&](const clap::ext::gui::plugin::GetResizeHints& request)
-> clap::ext::gui::plugin::GetResizeHints::Response { -> clap::ext::gui::plugin::GetResizeHints::Response {
const auto& [instance, _] = get_instance(request.instance_id); const auto& [instance, _] = get_instance(request.instance_id);
return main_context_ return do_mutual_recursion_on_gui_thread([&,
.run_in_context([&, plugin = instance.plugin.get(), plugin =
gui = instance.extensions.gui]() { instance.plugin
clap_gui_resize_hints_t hints{}; .get(),
if (gui->get_resize_hints(plugin, &hints)) { gui = instance
return clap::ext::gui::plugin:: .extensions
GetResizeHintsResponse{.result = .gui]() {
std::move(hints)}; clap_gui_resize_hints_t hints{};
} else { if (gui->get_resize_hints(plugin, &hints)) {
return clap::ext::gui::plugin:: return clap::ext::gui::plugin::GetResizeHintsResponse{
GetResizeHintsResponse{.result = std::nullopt}; .result = std::move(hints)};
} } else {
}) return clap::ext::gui::plugin::GetResizeHintsResponse{
.get(); .result = std::nullopt};
}
});
}, },
[&](const clap::ext::gui::plugin::AdjustSize& request) [&](const clap::ext::gui::plugin::AdjustSize& request)
-> clap::ext::gui::plugin::AdjustSize::Response { -> clap::ext::gui::plugin::AdjustSize::Response {
const auto& [instance, _] = get_instance(request.instance_id); const auto& [instance, _] = get_instance(request.instance_id);
return main_context_ return do_mutual_recursion_on_gui_thread(
.run_in_context([&, plugin = instance.plugin.get(), [&, plugin = instance.plugin.get(),
gui = instance.extensions.gui]() { gui = instance.extensions.gui]() {
uint32_t width = request.width; uint32_t width = request.width;
uint32_t height = request.height; uint32_t height = request.height;
const bool result = const bool result =
@@ -503,17 +499,16 @@ void ClapBridge::run() {
.result = result, .result = result,
.updated_width = width, .updated_width = width,
.updated_height = height}; .updated_height = height};
}) });
.get();
}, },
[&](const clap::ext::gui::plugin::SetSize& request) [&](const clap::ext::gui::plugin::SetSize& request)
-> clap::ext::gui::plugin::SetSize::Response { -> clap::ext::gui::plugin::SetSize::Response {
const auto& [instance, _] = get_instance(request.instance_id); const auto& [instance, _] = get_instance(request.instance_id);
return main_context_ return do_mutual_recursion_on_gui_thread(
.run_in_context([&, plugin = instance.plugin.get(), [&, plugin = instance.plugin.get(),
gui = instance.extensions.gui, gui = instance.extensions.gui,
&editor = instance.editor]() { &editor = instance.editor]() {
if (gui->set_size(plugin, request.width, if (gui->set_size(plugin, request.width,
request.height)) { request.height)) {
// Also resize the editor window. We do the same // Also resize the editor window. We do the same
@@ -525,8 +520,7 @@ void ClapBridge::run() {
} else { } else {
return false; return false;
} }
}) });
.get();
}, },
[&](const clap::ext::gui::plugin::SetParent& request) [&](const clap::ext::gui::plugin::SetParent& request)
-> clap::ext::gui::plugin::SetParent::Response { -> clap::ext::gui::plugin::SetParent::Response {
@@ -578,23 +572,21 @@ void ClapBridge::run() {
// We don't need any special handling for our editor window, but // We don't need any special handling for our editor window, but
// the plugin may use these functions to suspend drawing or stop // the plugin may use these functions to suspend drawing or stop
// other tasks while the window is hdden // other tasks while the window is hdden
return main_context_ return do_mutual_recursion_on_gui_thread(
.run_in_context([&, plugin = instance.plugin.get(), [&, plugin = instance.plugin.get(),
gui = instance.extensions.gui]() { gui = instance.extensions.gui]() {
return gui->show(plugin); return gui->show(plugin);
}) });
.get();
}, },
[&](const clap::ext::gui::plugin::Hide& request) [&](const clap::ext::gui::plugin::Hide& request)
-> clap::ext::gui::plugin::Hide::Response { -> clap::ext::gui::plugin::Hide::Response {
const auto& [instance, _] = get_instance(request.instance_id); const auto& [instance, _] = get_instance(request.instance_id);
return main_context_ return do_mutual_recursion_on_gui_thread(
.run_in_context([&, plugin = instance.plugin.get(), [&, plugin = instance.plugin.get(),
gui = instance.extensions.gui]() { gui = instance.extensions.gui]() {
return gui->hide(plugin); return gui->hide(plugin);
}) });
.get();
}, },
[&](clap::ext::latency::plugin::Get& request) [&](clap::ext::latency::plugin::Get& request)
-> clap::ext::latency::plugin::Get::Response { -> clap::ext::latency::plugin::Get::Response {
+1 -1
View File
@@ -264,7 +264,7 @@ class ClapBridge : public HostBridge {
"message()' called from a non-GUI thread, sending the " "message()' called from a non-GUI thread, sending the "
"message directly"; "message directly";
}); });
send_main_thread_message(object); return send_main_thread_message(object);
} }
} }