From 4767b758b83c29cd9bcd89b2a78f95694d04696b Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sun, 9 Jan 2022 00:41:14 +0100 Subject: [PATCH] Delay showing editor the window This fixes Waves V13 VST3 plugins crashing when opening the editor. They will likely still crash later on anyways because they're kinda broken. Amazing. --- CHANGELOG.md | 5 +++++ src/wine-host/bridges/vst2.cpp | 6 ++++++ src/wine-host/bridges/vst3.cpp | 8 ++++++++ src/wine-host/editor.cpp | 8 ++++---- src/wine-host/editor.h | 7 +++++++ 5 files changed, 30 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a010eaf..5cc05ba7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,11 @@ Versioning](https://semver.org/spec/v2.0.0.html). ### Fixed +- Fixed _Waves_ V13 VST3 plugins crashing when opening the GUI. These plugins + thought it would be a great idea to randomly dereference null pointers if the + window they're embedded in is already visible. A day's worth of debugging well + spent. Even after this, the V13 plugins are a bit unstable under Wine in + general. So as always, if you can avoid them, that would be for the best. - Fixed sluggish UIs in _Output's Thermal_ and likely a handful of other JUCE-based plugins. These plugins would emit hundreds to thousands of events when the GUI changes. Yabridge now detects this, and removes the throttling we diff --git a/src/wine-host/bridges/vst2.cpp b/src/wine-host/bridges/vst2.cpp index 36fc2745..0424c838 100644 --- a/src/wine-host/bridges/vst2.cpp +++ b/src/wine-host/bridges/vst2.cpp @@ -743,6 +743,12 @@ intptr_t Vst2Bridge::dispatch_wrapper(AEffect* plugin, plugin->dispatcher(plugin, opcode, index, value, editor_instance.get_win32_handle(), option); + // NOTE: There's zero reason why the window couldn't already be + // visible from the start, but Waves V13 VST3 plugins think it + // would be a splendid idea to randomly dereference null + // pointers when the window is already visible. Thanks Waves. + editor_instance.show(); + return result; } break; case effEditClose: { diff --git a/src/wine-host/bridges/vst3.cpp b/src/wine-host/bridges/vst3.cpp index 2c3b21d8..f402c873 100644 --- a/src/wine-host/bridges/vst3.cpp +++ b/src/wine-host/bridges/vst3.cpp @@ -809,6 +809,14 @@ void Vst3Bridge::run() { instance.editor->resize(size.getWidth(), size.getHeight()); } + + // NOTE: There's zero reason why the window couldn't + // already be visible from the start, but + // Waves V13 VST3 plugins think it would be a + // splendid idea to randomly dereference null + // pointers when the window is already + // visible. Thanks Waves. + instance.editor->show(); } else { instance.editor.reset(); } diff --git a/src/wine-host/editor.cpp b/src/wine-host/editor.cpp index c102728e..4932acc9 100644 --- a/src/wine-host/editor.cpp +++ b/src/wine-host/editor.cpp @@ -426,8 +426,6 @@ Editor::Editor(MainContext& main_context, // the child window ourselves. This is a hack to work around the issue's // described in `Editor`'s docstring'. do_reparent(wine_window_, wrapper_window_.window_); - - ShowWindow(win32_window_.handle_, SW_SHOWNORMAL); } } @@ -468,6 +466,10 @@ void Editor::resize(uint16_t width, uint16_t height) { } } +void Editor::show() noexcept { + ShowWindow(win32_window_.handle_, SW_SHOWNORMAL); +} + 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 @@ -1110,8 +1112,6 @@ void Editor::do_xembed() const { xcb_map_window(x11_connection_.get(), wine_window_); xcb_flush(x11_connection_.get()); - - ShowWindow(win32_window_.handle_, SW_SHOWNORMAL); } LRESULT CALLBACK window_proc(HWND handle, diff --git a/src/wine-host/editor.h b/src/wine-host/editor.h index f5275b7b..bddf4638 100644 --- a/src/wine-host/editor.h +++ b/src/wine-host/editor.h @@ -195,6 +195,13 @@ class Editor { */ void resize(uint16_t width, uint16_t height); + /** + * Show the window, should be called after the plugin has embedded itself. + * There's absolutely zero reason why this can't be done in the constructor + * or in `do_xembed()`, but it needs to be. Thanks Waves. + */ + void show() noexcept; + /** * Handle X11 events sent to the window our editor is embedded in. */