Resize the new wrapper window for VST2 plugins

This commit is contained in:
Robbert van der Helm
2021-07-21 15:53:30 +02:00
parent 42762d1abe
commit 418cd68a81
3 changed files with 48 additions and 8 deletions
+27 -8
View File
@@ -650,10 +650,10 @@ intptr_t Vst2Bridge::host_callback(AEffect* effect,
void* data,
float option) {
switch (opcode) {
// During a processing call we'll have already sent the current
// transport information from the plugin side to avoid an unnecessary
// callback
case audioMasterGetTime: {
// During a processing call we'll have already sent the current
// transport information from the plugin side to avoid an
// unnecessary callback
const VstTimeInfo* cached_time_info = time_info_cache.get();
if (cached_time_info) {
// This cached value is temporary, so we'll still use the
@@ -671,8 +671,8 @@ intptr_t Vst2Bridge::host_callback(AEffect* effect,
return result;
}
} break;
// We also send the current process level for similar reasons
case audioMasterGetCurrentProcessLevel: {
// We also send the current process level for similar reasons
const int* current_process_level = process_level_cache.get();
if (current_process_level) {
logger.log_event(false, opcode, index, value, nullptr, option,
@@ -683,6 +683,13 @@ intptr_t Vst2Bridge::host_callback(AEffect* effect,
return *current_process_level;
}
} break;
// If the plugin changes its window size, we'll also resize the wrapper
// window accordingly.
case audioMasterSizeWindow: {
if (editor) {
editor->resize(index, value);
}
} break;
}
HostCallbackDataConverter converter(effect, last_time_info,
@@ -704,14 +711,14 @@ intptr_t Vst2Bridge::dispatch_wrapper(AEffect* plugin,
// main thread using `main_context.run_in_context()` (where we don't use
// realtime scheduling).
switch (opcode) {
case effSetBlockSize:
case effSetBlockSize: {
// Used to initialize the shared audio buffers when handling
// `effMainsChanged` in `Vst2Bridge::run()`
max_samples_per_block = value;
return plugin->dispatcher(plugin, opcode, index, value, data,
option);
break;
} break;
case effEditOpen: {
// Create a Win32 window through Wine, embed it into the window
// provided by the host, and let the plugin embed itself into
@@ -723,6 +730,16 @@ intptr_t Vst2Bridge::dispatch_wrapper(AEffect* plugin,
[plugin = this->plugin]() {
plugin->dispatcher(plugin, effEditIdle, 0, 0, nullptr, 0.0);
});
// Make sure the wrapper window has the correct initial size. The
// plugin can later change this size using `audioMasterSizeWindow`.
VstRect* editor_rect = nullptr;
plugin->dispatcher(plugin, effEditGetRect, 0, 0, &editor_rect, 0.0);
if (editor_rect) {
editor->resize(editor_rect->right - editor_rect->left,
editor_rect->bottom - editor_rect->top);
}
const intptr_t result =
plugin->dispatcher(plugin, opcode, index, value,
editor_instance.get_win32_handle(), option);
@@ -737,7 +754,7 @@ intptr_t Vst2Bridge::dispatch_wrapper(AEffect* plugin,
return return_value;
} break;
case effSetProcessPrecision:
case effSetProcessPrecision: {
// Used to initialize the shared audio buffers when handling
// `effMainsChanged` in `Vst2Bridge::run()`
double_precision = value == kVstProcessPrecision64;
@@ -745,10 +762,12 @@ intptr_t Vst2Bridge::dispatch_wrapper(AEffect* plugin,
return plugin->dispatcher(plugin, opcode, index, value, data,
option);
break;
default:
}
default: {
return plugin->dispatcher(plugin, opcode, index, value, data,
option);
break;
}
}
}
+14
View File
@@ -428,6 +428,20 @@ Editor::Editor(MainContext& main_context,
}
}
void Editor::resize(uint16_t width, uint16_t height) noexcept {
logger.log_editor_trace([&]() {
return "DEBUG: Resizing wrapper window to " + std::to_string(width) +
"x" + std::to_string(height);
});
const uint16_t value_mask =
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
const std::array<uint32_t, 2> values{width, height};
xcb_configure_window(x11_connection.get(), wrapper_window.window,
value_mask, values.data());
xcb_flush(x11_connection.get());
}
void Editor::handle_x11_events() noexcept {
// NOTE: Ardour will unmap the window instead of closing the editor. When
// the window is unmapped `wine_window` doesn't exist and any X11
+7
View File
@@ -189,6 +189,13 @@ class Editor {
const size_t parent_window_handle,
std::optional<fu2::unique_function<void()>> timer_proc = std::nullopt);
/**
* Resize the `wrapper_window` to this new size. We need to manually call
* this whenever the plugin requests a resize, or when the host resizes the
* window (using the plugin API). Before yabridge 3.5.0 this was implicit.
*/
void resize(uint16_t width, uint16_t height) noexcept;
/**
* Handle X11 events sent to the window our editor is embedded in.
*/