Work around static initialization bug in WIne 7.21

As reported here: https://bugs.winehq.org/show_bug.cgi?id=53912
This commit is contained in:
Robbert van der Helm
2022-11-14 13:59:18 +01:00
parent 8c1679a034
commit fea6eded49
3 changed files with 49 additions and 7 deletions
+6
View File
@@ -8,6 +8,12 @@ Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased] ## [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 # yabridgectl
- Fixed converted VST 3.7.5 `moduleinfo.json` files being considered orphan - Fixed converted VST 3.7.5 `moduleinfo.json` files being considered orphan
+19 -3
View File
@@ -117,7 +117,23 @@ constexpr uint32_t xembed_focus_in_msg = 4;
constexpr uint32_t xembed_focus_first = 1; 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 * 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. // plugin and keep this as a default.
case WM_SETCURSOR: { case WM_SETCURSOR: {
if (GetCursor() == nullptr) { if (GetCursor() == nullptr) {
SetCursor(arrow_cursor); SetCursor(arrow_cursor());
} }
} break; } break;
// NOTE: Needed for our `is_cursor_in_wine_window()` implementation. Our // 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.style = CS_DBLCLKS;
window_class.lpfnWndProc = window_proc; window_class.lpfnWndProc = window_proc;
window_class.hInstance = GetModuleHandle(nullptr); window_class.hInstance = GetModuleHandle(nullptr);
window_class.hCursor = arrow_cursor; window_class.hCursor = arrow_cursor();
window_class.lpszClassName = yabridge_window_class_name; window_class.lpszClassName = yabridge_window_class_name;
window_class_handle = RegisterClassEx(&window_class); window_class_handle = RegisterClassEx(&window_class);
+24 -4
View File
@@ -53,8 +53,28 @@ constexpr char mime_text_uri_list_name[] = "text/uri-list";
constexpr char mime_text_plain_name[] = "text/plain"; constexpr char mime_text_plain_name[] = "text/plain";
// We can cheat by just using the Win32 cursors instead of providing our own // We can cheat by just using the Win32 cursors instead of providing our own
static const HCURSOR dnd_accepted_cursor = LoadCursor(nullptr, IDC_HAND); // FIXME: these used to be loaded as a constant, but Wine 7.21 caused this
static const HCURSOR dnd_denied_cursor = LoadCursor(nullptr, IDC_NO); // 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 * 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 // off. Would it be better to just not do anything
// at all here? // at all here?
if (accepts_drop) { if (accepts_drop) {
SetCursor(dnd_accepted_cursor); SetCursor(dnd_accepted_cursor());
} else { } else {
SetCursor(dnd_denied_cursor); SetCursor(dnd_denied_cursor());
} }
last_window_accepted_status = accepts_drop; last_window_accepted_status = accepts_drop;