mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-06-14 23:43:52 +02:00
Fix hanging when closing the editor
This commit is contained in:
@@ -10,7 +10,6 @@ as possible.
|
|||||||
There are a few things that should be done before releasing this, including:
|
There are a few things that should be done before releasing this, including:
|
||||||
|
|
||||||
- Fix implementation bugs:
|
- Fix implementation bugs:
|
||||||
- Closing editor windows is slow, this can be improved,
|
|
||||||
- Polish GUIs even further. There are some todos left in
|
- Polish GUIs even further. There are some todos left in
|
||||||
`src/wine-host/editor.{h,cpp}`.
|
`src/wine-host/editor.{h,cpp}`.
|
||||||
- There are likely some minor issues left.
|
- There are likely some minor issues left.
|
||||||
|
|||||||
@@ -58,12 +58,12 @@ Editor::Editor(const std::string& window_class_name,
|
|||||||
nullptr,
|
nullptr,
|
||||||
GetModuleHandle(nullptr),
|
GetModuleHandle(nullptr),
|
||||||
this),
|
this),
|
||||||
&DestroyWindow),
|
DestroyWindow),
|
||||||
parent_window(parent_window_handle),
|
parent_window(parent_window_handle),
|
||||||
child_window(get_x11_handle(win32_handle.get())),
|
child_window(get_x11_handle(win32_handle.get())),
|
||||||
// Needed to send update messages on a timer
|
// Needed to send update messages on a timer
|
||||||
plugin(effect),
|
plugin(effect),
|
||||||
x11_connection(xcb_connect(nullptr, nullptr), &xcb_disconnect) {
|
x11_connection(xcb_connect(nullptr, nullptr), xcb_disconnect) {
|
||||||
// The Win32 API will block the `DispatchMessage` call when opening e.g. a
|
// The Win32 API will block the `DispatchMessage` call when opening e.g. a
|
||||||
// dropdown, but it will still allow timers to be run so the GUI can still
|
// dropdown, but it will still allow timers to be run so the GUI can still
|
||||||
// update in the background. Because of this we send `effEditIdle` to the
|
// update in the background. Because of this we send `effEditIdle` to the
|
||||||
@@ -90,6 +90,26 @@ Editor::Editor(const std::string& window_class_name,
|
|||||||
ShowWindow(win32_handle.get(), SW_SHOWNORMAL);
|
ShowWindow(win32_handle.get(), SW_SHOWNORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Editor::~Editor() {
|
||||||
|
// Wine will wait for the parent window to properly delete the window during
|
||||||
|
// `DestroyWindow()`. Instead of implementing this behavior ourselves we
|
||||||
|
// just reparent the window back to the window root and let the WM handle
|
||||||
|
// it.
|
||||||
|
xcb_window_t root =
|
||||||
|
xcb_setup_roots_iterator(xcb_get_setup(x11_connection.get()))
|
||||||
|
.data->root;
|
||||||
|
|
||||||
|
xcb_reparent_window(x11_connection.get(), child_window, root, 0, 0);
|
||||||
|
xcb_flush(x11_connection.get());
|
||||||
|
|
||||||
|
// FIXME: I have no idea why, but for some reason the window still hangs
|
||||||
|
// some of the times without manually resetting the
|
||||||
|
// `std::unique_ptr`` to the window handle` (which calls
|
||||||
|
// `DestroyWindow()`), even though the behavior should be identical
|
||||||
|
// without this line.
|
||||||
|
win32_handle.reset();
|
||||||
|
}
|
||||||
|
|
||||||
void Editor::send_idle_event() {
|
void Editor::send_idle_event() {
|
||||||
plugin->dispatcher(plugin, effEditIdle, 0, 0, nullptr, 0);
|
plugin->dispatcher(plugin, effEditIdle, 0, 0, nullptr, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ class Editor {
|
|||||||
AEffect* effect,
|
AEffect* effect,
|
||||||
const size_t parent_window_handle);
|
const size_t parent_window_handle);
|
||||||
|
|
||||||
|
~Editor();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a single `effEditIdle` event to the plugin to allow it to update its
|
* Send a single `effEditIdle` event to the plugin to allow it to update its
|
||||||
* GUI state. This is called periodically from a timer while the GUI is
|
* GUI state. This is called periodically from a timer while the GUI is
|
||||||
@@ -92,7 +94,7 @@ class Editor {
|
|||||||
* The handle for the window created through Wine that the plugin uses to
|
* The handle for the window created through Wine that the plugin uses to
|
||||||
* embed itself in.
|
* embed itself in.
|
||||||
*/
|
*/
|
||||||
const std::unique_ptr<std::remove_pointer_t<HWND>, decltype(&DestroyWindow)>
|
std::unique_ptr<std::remove_pointer_t<HWND>, decltype(&DestroyWindow)>
|
||||||
win32_handle;
|
win32_handle;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -263,9 +263,6 @@ intptr_t PluginBridge::dispatch_wrapper(AEffect* plugin,
|
|||||||
plugin->dispatcher(plugin, opcode, index, value, data, option);
|
plugin->dispatcher(plugin, opcode, index, value, data, option);
|
||||||
|
|
||||||
// Cleanup is handled through RAII
|
// Cleanup is handled through RAII
|
||||||
// TODO: We might want to manually unmap the X11 window instead of
|
|
||||||
// having the host do it. Right now the window editor window
|
|
||||||
// stays open for a second when removing a plugin.
|
|
||||||
editor = std::nullopt;
|
editor = std::nullopt;
|
||||||
|
|
||||||
return return_value;
|
return return_value;
|
||||||
|
|||||||
Reference in New Issue
Block a user