From d6260c1d6beb7f1d0669a61c8aa8325b891a985f Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sat, 29 Jan 2022 01:44:03 +0100 Subject: [PATCH] Delay editor_force_xdnd until the reparent #160 This fixes the option not working correctly when REAPER reparents the plugin's window to a new FX window. --- CHANGELOG.md | 4 ++++ src/wine-host/editor.cpp | 46 +++++++++++++++++++++++++++------------- src/wine-host/editor.h | 6 ++++++ 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c67be60..f5259fa1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,10 @@ Versioning](https://semver.org/spec/v2.0.0.html). ### Fixed +- Fix the **REAPER**-specific `editor_force_dnd` option not working correctly + when using the `Track -> Insert virtual instrument on new track...` option. + When this happens, REAPER creates the plugin's window offscreen first and it + will only create the FX window once the plugin is ready. - Fixed the VST3 version of _IK Multimedia's T-RackS 5_ producing silence while doing offline rendering. This could happen when exporting or bouncing audio in **Bitwig Studio 4.1**, **Ardour** and in **REAPER**. These plugins apparently diff --git a/src/wine-host/editor.cpp b/src/wine-host/editor.cpp index 4932acc9..9b7de9ef 100644 --- a/src/wine-host/editor.cpp +++ b/src/wine-host/editor.cpp @@ -263,6 +263,7 @@ Editor::Editor(MainContext& main_context, const size_t parent_window_handle, std::optional> timer_proc) : use_coordinate_hack_(config.editor_coordinate_hack), + use_force_dnd_(config.editor_force_dnd), use_xembed_(config.editor_xembed), logger_(logger), x11_connection_(xcb_connect(nullptr, nullptr), xcb_disconnect), @@ -367,21 +368,6 @@ Editor::Editor(MainContext& main_context, << std::endl; } - // If the `editor_force_dnd` option is set, we'll strip `XdndAware` from all - // of `wine_window_`'s ancestors (including `parent_window_`) to forcefully - // enable drag-and-drop support in REAPER. See the docstring on - // `Configuration::editor_force_dnd` and the option description in the - // readme for more information. - if (config.editor_force_dnd) { - const xcb_atom_t xcb_xdnd_aware_property = - get_atom_by_name(*x11_connection_, xdnd_aware_property_name); - for (const xcb_window_t& window : - find_ancestor_windows(*x11_connection_, parent_window_)) { - xcb_delete_property(x11_connection_.get(), window, - xcb_xdnd_aware_property); - } - } - // When using XEmbed we'll need the atoms for the corresponding properties xcb_xembed_message_ = get_atom_by_name(*x11_connection_, xembed_message_name); @@ -492,6 +478,9 @@ void Editor::handle_x11_events() noexcept { // which breaks our input focus handling. To work around // this, we will just check if the host's window has // changed whenever the parent window gets reparented. + // REAPER does the same thing when inserting a plugin on a + // new track with the `Track -> Insert virtual instrument + // on new track...` option. case XCB_REPARENT_NOTIFY: { const auto event = reinterpret_cast( @@ -506,6 +495,33 @@ void Editor::handle_x11_events() noexcept { }); redetect_host_window(); + + // If the `editor_force_dnd` option is set, we'll strip + // `XdndAware` from all of `wine_window_`'s ancestors + // (including `parent_window_`) to forcefully enable + // drag-and-drop support in REAPER. See the docstring on + // `Configuration::editor_force_dnd` and the option + // description in the readme for more information. + // NOTE: This also needs to be done here for the same reason + // as the one mentioned above + if (use_force_dnd_) { + logger_.log_editor_trace([&]() { + return "DEBUG: Removing XdndAware properties from " + "window " + + std::to_string(parent_window_) + + " and all of its ancestors"; + }); + + const xcb_atom_t xcb_xdnd_aware_property = + get_atom_by_name(*x11_connection_, + xdnd_aware_property_name); + for (const xcb_window_t& window : find_ancestor_windows( + *x11_connection_, parent_window_)) { + xcb_delete_property(x11_connection_.get(), window, + xcb_xdnd_aware_property); + } + } + } break; // We're listening for `ConfigureNotify` events on the host's // window (i.e. the window that's actually going to get dragged diff --git a/src/wine-host/editor.h b/src/wine-host/editor.h index bddf4638..8466750f 100644 --- a/src/wine-host/editor.h +++ b/src/wine-host/editor.h @@ -268,6 +268,12 @@ class Editor { */ const bool use_coordinate_hack_; + /** + * Whether the `editor_force_dnd` workaround for REAPER should be activated. + * See the implementation in `editor.cpp` for more details. + */ + const bool use_force_dnd_; + /** * Whether to use XEmbed instead of yabridge's normal window embedded. Wine * with XEmbed tends to cause rendering issues, so it's disabled by default.