Reparent to the root window before deferring close

We did this before implementing the deferred close in yabridge 3.0.0. It
didn't seem necessary anymore so we got rid of it, but without this
closing an iZotope Rx plugin's editor in Renoise was guaranteed to
trigger an X11 error and crash Renoise. Doing this reparent doesn't seem
to cause any slowdown but it does at least fix the specific combination
of iZotope Rx and Renoise.
This commit is contained in:
Robbert van der Helm
2021-04-26 18:47:58 +02:00
parent 0d53f03b28
commit 0c7dbe8a4a
3 changed files with 34 additions and 5 deletions
+8
View File
@@ -22,6 +22,14 @@ Versioning](https://semver.org/spec/v2.0.0.html).
### Fixed
- In certain rare circumstances, closing a plugin editor would trigger an X11
error and crash the Wine plugin host, and with that likely the entire DAW.
This happened because Wine would try to destroy a window that had already been
destroyed. I've seen this happen in Renoise and to a lesser degree in REAPER
with plugins that take a while to close their editors, such as the iZotope Rx
plugins. We now explicitly reparent the window to back the root window first
before deferring the window closing. This should work around the issue, while
still keeping editor closing nice and snappy.
- _PSPaudioware InifniStrip_ would fail to initialize because the plugin expects
the host to always be using Microsoft COM and it won't initialize it by
itself. InfiniStrip loads as expected now.
+19 -3
View File
@@ -114,10 +114,25 @@ xcb_window_t get_x11_handle(HWND win32_handle);
*/
ATOM get_window_class();
DeferredWindow::DeferredWindow(MainContext& main_context, HWND window)
: handle(window), main_context(main_context) {}
DeferredWindow::DeferredWindow(MainContext& main_context,
std::shared_ptr<xcb_connection_t> x11_connection,
HWND window)
: handle(window),
main_context(main_context),
x11_connection(x11_connection) {}
DeferredWindow::~DeferredWindow() {
// NOTE: For some rason, Wine will sometimes try to delete a window twice if
// the parent window no longer exists. I've only seen this cause
// issues with plugins that hang when their window is hidden, like the
// iZotope Rx plugins. In Renoise this would otherwise trigger an X11
// error every time you close such a plugin's editor, and in other
// DAWs I've also seen it happen from time to time.
const xcb_window_t wine_window = get_x11_handle(handle);
const xcb_window_t root_window =
get_root_window(*x11_connection, wine_window);
xcb_reparent_window(x11_connection.get(), wine_window, root_window, 0, 0);
// XXX: We are already deferring this closing by posting `WM_CLOSE` to the
// message loop instead of calling `DestroyWindow()` ourselves, but we
// can take it one step further. If we post this message directly then
@@ -156,6 +171,7 @@ Editor::Editor(MainContext& main_context,
// expect) and also causes mouse coordinates to be relative to the window
// itself.
win32_window(main_context,
x11_connection,
CreateWindowEx(WS_EX_TOOLWINDOW,
reinterpret_cast<LPCSTR>(get_window_class()),
"yabridge plugin",
@@ -288,7 +304,7 @@ Editor::Editor(MainContext& main_context,
// As explained above, we can't do this directly in the initializer
// list
win32_child_window.emplace(
main_context,
main_context, x11_connection,
CreateWindowEx(WS_EX_TOOLWINDOW,
reinterpret_cast<LPCSTR>(get_window_class()),
"yabridge plugin child", WS_CHILD, CW_USEDEFAULT,
+7 -2
View File
@@ -78,9 +78,13 @@ class DeferredWindow {
*
* @param main_context This application's main IO context running on the GUI
* thread.
* @param x11_connection The X11 connection handle we're using for this
* editor.
* @param window A `HWND` obtained through a call to `CreateWindowEx`
*/
DeferredWindow(MainContext& main_context, HWND window);
DeferredWindow(MainContext& main_context,
std::shared_ptr<xcb_connection_t> x11_connection,
HWND window);
/**
* Post a `WM_CLOSE` message to the `handle`'s message queue as described
@@ -92,6 +96,7 @@ class DeferredWindow {
private:
MainContext& main_context;
std::shared_ptr<xcb_connection_t> x11_connection;
};
/**
@@ -222,7 +227,7 @@ class Editor {
*/
void do_xembed() const;
std::unique_ptr<xcb_connection_t, decltype(&xcb_disconnect)> x11_connection;
std::shared_ptr<xcb_connection_t> x11_connection;
/**
* The Wine window's client area, or the maximum size of that window. This