mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-07 03:50:11 +02:00
Defer Win32 window closing
This gets rid of all potential delays when closing windows.
This commit is contained in:
@@ -39,6 +39,10 @@ TODO: Add an updated screenshot with some fancy VST3-only plugins to the readme
|
||||
- Slightly increased resposniveness when resizing plugin GUIs by preventing
|
||||
unnecessary blitting. This also reduces flickering with plugins that don't do
|
||||
double buffering.
|
||||
- Window closing is now deferred. This means that when closing the editor
|
||||
window, the host no longer has to wait for Wine to fully close the window.
|
||||
Most hosts already do something similar themselves, so this may not make any
|
||||
difference in responsiveness.
|
||||
- VST2 editor idle events are now handled slightly differently. This should
|
||||
result in even more responsive GUIs and I have not come across any plugins
|
||||
where this change introduced issues, but please let me know if it does break
|
||||
|
||||
+16
-18
@@ -123,7 +123,7 @@ Editor::Editor(const Configuration& config, const size_t parent_window_handle)
|
||||
nullptr,
|
||||
GetModuleHandle(nullptr),
|
||||
this),
|
||||
DestroyWindow),
|
||||
destroy_window_async),
|
||||
// If `config.editor_double_embed` is set, then we'll also create a child
|
||||
// window in `win32_child_handle`. If we do this before calling
|
||||
// `ShowWindow()` on `win32_handle` we'll run into X11 errors.
|
||||
@@ -213,15 +213,17 @@ Editor::Editor(const Configuration& config, const size_t parent_window_handle)
|
||||
#pragma GCC diagnostic ignored "-Wignored-attributes"
|
||||
// As explained above, we can't do this directly in the initializer
|
||||
// list
|
||||
win32_child_handle = std::unique_ptr<std::remove_pointer_t<HWND>,
|
||||
decltype(&DestroyWindow)>(
|
||||
CreateWindowEx(WS_EX_TOOLWINDOW,
|
||||
reinterpret_cast<LPCSTR>(window_class.atom),
|
||||
"yabridge plugin child", WS_CHILD, CW_USEDEFAULT,
|
||||
CW_USEDEFAULT, client_area.width,
|
||||
client_area.height, win32_handle.get(), nullptr,
|
||||
GetModuleHandle(nullptr), this),
|
||||
DestroyWindow);
|
||||
win32_child_handle =
|
||||
std::unique_ptr<std::remove_pointer_t<HWND>,
|
||||
decltype(&destroy_window_async)>(
|
||||
CreateWindowEx(WS_EX_TOOLWINDOW,
|
||||
reinterpret_cast<LPCSTR>(window_class.atom),
|
||||
"yabridge plugin child", WS_CHILD,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
client_area.width, client_area.height,
|
||||
win32_handle.get(), nullptr,
|
||||
GetModuleHandle(nullptr), this),
|
||||
destroy_window_async);
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
ShowWindow(win32_child_handle->get(), SW_SHOWNORMAL);
|
||||
@@ -250,14 +252,6 @@ Editor::~Editor() {
|
||||
|
||||
xcb_reparent_window(x11_connection.get(), wine_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_child_handle.reset();
|
||||
win32_handle.reset();
|
||||
}
|
||||
|
||||
HWND Editor::get_win32_handle() const {
|
||||
@@ -419,6 +413,10 @@ void Editor::set_input_focus(bool grab) const {
|
||||
xcb_flush(x11_connection.get());
|
||||
}
|
||||
|
||||
void Editor::destroy_window_async(HWND window_handle) {
|
||||
PostMessage(window_handle, WM_CLOSE, 0, 0);
|
||||
}
|
||||
|
||||
bool Editor::is_wine_window_active() const {
|
||||
if (!supports_ewmh_active_window()) {
|
||||
return false;
|
||||
|
||||
+11
-3
@@ -154,6 +154,13 @@ class Editor {
|
||||
const bool use_xembed;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Post a message to this window's message queue to clean up the window.
|
||||
* This way we don't have to wait for the window to actually fully close
|
||||
* before returning.
|
||||
*/
|
||||
static void destroy_window_async(HWND window_handle);
|
||||
|
||||
/**
|
||||
* Returns `true` if the currently active window (as per
|
||||
* `_NET_ACTIVE_WINDOW`) contains `wine_window`. If the window manager does
|
||||
@@ -211,7 +218,8 @@ class Editor {
|
||||
* The handle for the window created through Wine that the plugin uses to
|
||||
* embed itself in.
|
||||
*/
|
||||
std::unique_ptr<std::remove_pointer_t<HWND>, decltype(&DestroyWindow)>
|
||||
std::unique_ptr<std::remove_pointer_t<HWND>,
|
||||
decltype(&destroy_window_async)>
|
||||
win32_handle;
|
||||
|
||||
/**
|
||||
@@ -222,8 +230,8 @@ class Editor {
|
||||
* of the readme for more details). The plugin should then embed itself
|
||||
* within this child window.
|
||||
*/
|
||||
std::optional<
|
||||
std::unique_ptr<std::remove_pointer_t<HWND>, decltype(&DestroyWindow)>>
|
||||
std::optional<std::unique_ptr<std::remove_pointer_t<HWND>,
|
||||
decltype(&destroy_window_async)>>
|
||||
win32_child_handle;
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
Reference in New Issue
Block a user