mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-09 20:29:10 +02:00
Resize the new wrapper window for VST2 plugins
This commit is contained in:
@@ -650,10 +650,10 @@ intptr_t Vst2Bridge::host_callback(AEffect* effect,
|
|||||||
void* data,
|
void* data,
|
||||||
float option) {
|
float option) {
|
||||||
switch (opcode) {
|
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: {
|
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();
|
const VstTimeInfo* cached_time_info = time_info_cache.get();
|
||||||
if (cached_time_info) {
|
if (cached_time_info) {
|
||||||
// This cached value is temporary, so we'll still use the
|
// This cached value is temporary, so we'll still use the
|
||||||
@@ -671,8 +671,8 @@ intptr_t Vst2Bridge::host_callback(AEffect* effect,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
// We also send the current process level for similar reasons
|
||||||
case audioMasterGetCurrentProcessLevel: {
|
case audioMasterGetCurrentProcessLevel: {
|
||||||
// We also send the current process level for similar reasons
|
|
||||||
const int* current_process_level = process_level_cache.get();
|
const int* current_process_level = process_level_cache.get();
|
||||||
if (current_process_level) {
|
if (current_process_level) {
|
||||||
logger.log_event(false, opcode, index, value, nullptr, option,
|
logger.log_event(false, opcode, index, value, nullptr, option,
|
||||||
@@ -683,6 +683,13 @@ intptr_t Vst2Bridge::host_callback(AEffect* effect,
|
|||||||
return *current_process_level;
|
return *current_process_level;
|
||||||
}
|
}
|
||||||
} break;
|
} 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,
|
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
|
// main thread using `main_context.run_in_context()` (where we don't use
|
||||||
// realtime scheduling).
|
// realtime scheduling).
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case effSetBlockSize:
|
case effSetBlockSize: {
|
||||||
// Used to initialize the shared audio buffers when handling
|
// Used to initialize the shared audio buffers when handling
|
||||||
// `effMainsChanged` in `Vst2Bridge::run()`
|
// `effMainsChanged` in `Vst2Bridge::run()`
|
||||||
max_samples_per_block = value;
|
max_samples_per_block = value;
|
||||||
|
|
||||||
return plugin->dispatcher(plugin, opcode, index, value, data,
|
return plugin->dispatcher(plugin, opcode, index, value, data,
|
||||||
option);
|
option);
|
||||||
break;
|
} break;
|
||||||
case effEditOpen: {
|
case effEditOpen: {
|
||||||
// Create a Win32 window through Wine, embed it into the window
|
// Create a Win32 window through Wine, embed it into the window
|
||||||
// provided by the host, and let the plugin embed itself into
|
// 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 = this->plugin]() {
|
||||||
plugin->dispatcher(plugin, effEditIdle, 0, 0, nullptr, 0.0);
|
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 =
|
const intptr_t result =
|
||||||
plugin->dispatcher(plugin, opcode, index, value,
|
plugin->dispatcher(plugin, opcode, index, value,
|
||||||
editor_instance.get_win32_handle(), option);
|
editor_instance.get_win32_handle(), option);
|
||||||
@@ -737,7 +754,7 @@ intptr_t Vst2Bridge::dispatch_wrapper(AEffect* plugin,
|
|||||||
|
|
||||||
return return_value;
|
return return_value;
|
||||||
} break;
|
} break;
|
||||||
case effSetProcessPrecision:
|
case effSetProcessPrecision: {
|
||||||
// Used to initialize the shared audio buffers when handling
|
// Used to initialize the shared audio buffers when handling
|
||||||
// `effMainsChanged` in `Vst2Bridge::run()`
|
// `effMainsChanged` in `Vst2Bridge::run()`
|
||||||
double_precision = value == kVstProcessPrecision64;
|
double_precision = value == kVstProcessPrecision64;
|
||||||
@@ -745,10 +762,12 @@ intptr_t Vst2Bridge::dispatch_wrapper(AEffect* plugin,
|
|||||||
return plugin->dispatcher(plugin, opcode, index, value, data,
|
return plugin->dispatcher(plugin, opcode, index, value, data,
|
||||||
option);
|
option);
|
||||||
break;
|
break;
|
||||||
default:
|
}
|
||||||
|
default: {
|
||||||
return plugin->dispatcher(plugin, opcode, index, value, data,
|
return plugin->dispatcher(plugin, opcode, index, value, data,
|
||||||
option);
|
option);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
void Editor::handle_x11_events() noexcept {
|
||||||
// NOTE: Ardour will unmap the window instead of closing the editor. When
|
// NOTE: Ardour will unmap the window instead of closing the editor. When
|
||||||
// the window is unmapped `wine_window` doesn't exist and any X11
|
// the window is unmapped `wine_window` doesn't exist and any X11
|
||||||
|
|||||||
@@ -189,6 +189,13 @@ class Editor {
|
|||||||
const size_t parent_window_handle,
|
const size_t parent_window_handle,
|
||||||
std::optional<fu2::unique_function<void()>> timer_proc = std::nullopt);
|
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.
|
* Handle X11 events sent to the window our editor is embedded in.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user