From d46f7882bdc6849674ad1e976736a4c64b6caabd Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Mon, 16 Aug 2021 20:48:41 +0200 Subject: [PATCH] Reposition to (0, 0) while fixing coordinates The goal is to have the window be at (0, 0), while Wine's X11 event layer thinks it is at the actual screen coordinates. This is needed to prevent drawing issues with buggy plugins that rely on absolute screen coordinates to draw their GUI. --- CHANGELOG.md | 13 +++++++++++++ src/wine-host/editor.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d9d8629..06ad4b1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,19 @@ Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed + +- Yabridge's Wine window embedding now takes more measures to make sure that the + plugin draws itself properly in the top left corner of the window. This is + needed for some buggy plugins that draw window based on absolute screen + coordinates, instead of their positioning within the parent window, like the + _Soundtoys_ plugins. + +### Fixed + +- Fixed an offset editor GUI after clicking the 'Tweak' button in _Soundtoys + Crytallizer_. + ### Packaging notes - We now target VST3 SDK version 3.7.3 with git tag `v3.7.3_build_20-patched`. diff --git a/src/wine-host/editor.cpp b/src/wine-host/editor.cpp index 557cc569..f0066bef 100644 --- a/src/wine-host/editor.cpp +++ b/src/wine-host/editor.cpp @@ -459,6 +459,12 @@ void Editor::resize(uint16_t width, uint16_t height) noexcept { xcb_configure_window(x11_connection.get(), wrapper_window.window, value_mask, values.data()); xcb_flush(x11_connection.get()); + + // Make sure that after the resize the screen coordinates always match up + // properly. Without this Soundtoys Crystallizer might appear choppy or skip + // a frame during their resize animation (which somehow calls + // `audioMasterSizeWindow()` with the same size a bunch of times in a row). + fix_local_coordinates(); } void Editor::handle_x11_events() noexcept { @@ -734,6 +740,23 @@ void Editor::fix_local_coordinates() const { return; } + // Before lying to Wine about the window's coordinates, we do need to make + // sure that the window is actually placed at (0, 0) coordinates. Otherwise + // some plugins that rely on screen coordinates, like the Soundtoys plugins + // and older PSPaudioware plugins, will draw their GUI at the wrong + // location. In case we have multiple `ConfiguratioNotify` events in a row, + // we'll only need to do this once. + RECT current_pos{}; + if (GetWindowRect(win32_window.handle, ¤t_pos) || + current_pos.left != 0 || current_pos.top != 0) { + logger.log_editor_trace([]() { + return "DEBUG: Resetting Wine window position back to (0, 0)"; + }); + SetWindowPos(win32_window.handle, nullptr, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOREDRAW | SWP_NOACTIVATE | + SWP_NOCOPYBITS | SWP_NOOWNERZORDER | SWP_DEFERERASE); + } + // We're purposely not using XEmbed here. This has the consequence that wine // still thinks that any X and Y coordinates are relative to the x11 window // root instead of the parent window provided by the DAW, causing all sorts @@ -777,6 +800,12 @@ void Editor::fix_local_coordinates() const { translated_event.x = translated_coordinates->dst_x; translated_event.y = translated_coordinates->dst_y; + logger.log_editor_trace([&]() { + return "DEBUG: Spoofing local coordinates to (" + + std::to_string(translated_event.x) + ", " + + std::to_string(translated_event.y) + ")"; + }); + xcb_send_event( x11_connection.get(), false, wine_window, XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY,