diff --git a/CHANGELOG.md b/CHANGELOG.md index c24f1285..4e20debb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +# Fixed + +- Added a temporary workaround for yabridge hanging indefinitely on startup as + the result of a new bug in Wine 7.21: + https://bugs.winehq.org/show_bug.cgi?id=53912 + # yabridgectl - Fixed converted VST 3.7.5 `moduleinfo.json` files being considered orphan diff --git a/src/wine-host/editor.cpp b/src/wine-host/editor.cpp index 84586205..028532b0 100644 --- a/src/wine-host/editor.cpp +++ b/src/wine-host/editor.cpp @@ -117,7 +117,23 @@ constexpr uint32_t xembed_focus_in_msg = 4; constexpr uint32_t xembed_focus_first = 1; -static const HCURSOR arrow_cursor = LoadCursor(nullptr, IDC_ARROW); +/** + * The default arrow cursor used in Windows. + * + * FIXME: This used to be loaded as a constant, but Wine 7.21 caused this static + * initialization to hang indefinitely: + * https://bugs.winehq.org/show_bug.cgi?id=53912 + * Revert this once Wine 7.21 is old enough that noone uses it anymore. + */ +// static const HCURSOR arrow_cursor = LoadCursor(nullptr, IDC_ARROW); +inline HCURSOR arrow_cursor() { + static HCURSOR cursor{}; + if (!cursor) { + cursor = LoadCursor(nullptr, IDC_ARROW); + } + + return cursor; +} /** * Find the the ancestors for the given window. This returns a list of window @@ -1225,7 +1241,7 @@ LRESULT CALLBACK window_proc(HWND handle, // plugin and keep this as a default. case WM_SETCURSOR: { if (GetCursor() == nullptr) { - SetCursor(arrow_cursor); + SetCursor(arrow_cursor()); } } break; // NOTE: Needed for our `is_cursor_in_wine_window()` implementation. Our @@ -1395,7 +1411,7 @@ ATOM get_window_class() noexcept { window_class.style = CS_DBLCLKS; window_class.lpfnWndProc = window_proc; window_class.hInstance = GetModuleHandle(nullptr); - window_class.hCursor = arrow_cursor; + window_class.hCursor = arrow_cursor(); window_class.lpszClassName = yabridge_window_class_name; window_class_handle = RegisterClassEx(&window_class); diff --git a/src/wine-host/xdnd-proxy.cpp b/src/wine-host/xdnd-proxy.cpp index 2d404aa2..e2fdf0f9 100644 --- a/src/wine-host/xdnd-proxy.cpp +++ b/src/wine-host/xdnd-proxy.cpp @@ -53,8 +53,28 @@ constexpr char mime_text_uri_list_name[] = "text/uri-list"; constexpr char mime_text_plain_name[] = "text/plain"; // We can cheat by just using the Win32 cursors instead of providing our own -static const HCURSOR dnd_accepted_cursor = LoadCursor(nullptr, IDC_HAND); -static const HCURSOR dnd_denied_cursor = LoadCursor(nullptr, IDC_NO); +// FIXME: these used to be loaded as a constant, but Wine 7.21 caused this +// static initialization to hang indefinitely: +// https://bugs.winehq.org/show_bug.cgi?id=53912 +// Revert this once Wine 7.21 is old enough that noone uses it anymore. +// static const HCURSOR dnd_accepted_cursor = LoadCursor(nullptr, IDC_HAND); +inline HCURSOR dnd_accepted_cursor() { + static HCURSOR cursor{}; + if (!cursor) { + cursor = LoadCursor(nullptr, IDC_HAND); + } + + return cursor; +} +// static const HCURSOR dnd_denied_cursor = LoadCursor(nullptr, IDC_NO); +inline HCURSOR dnd_denied_cursor() { + static HCURSOR cursor{}; + if (!cursor) { + cursor = LoadCursor(nullptr, IDC_NO); + } + + return cursor; +} /** * We're doing a bit of a hybrid between a COM-style reference counted smart @@ -337,9 +357,9 @@ void WineXdndProxy::run_xdnd_loop() { // off. Would it be better to just not do anything // at all here? if (accepts_drop) { - SetCursor(dnd_accepted_cursor); + SetCursor(dnd_accepted_cursor()); } else { - SetCursor(dnd_denied_cursor); + SetCursor(dnd_denied_cursor()); } last_window_accepted_status = accepts_drop;