1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Fixed sporadic deadlock caused by presentation window title update

Fixes occasional deadlock when alt-tabbing in Age of Wonders: Shadow Magic.
This commit is contained in:
narzoul 2024-04-14 19:08:36 +02:00
parent ea4097d810
commit 8485017afc
4 changed files with 27 additions and 42 deletions

View File

@ -9,9 +9,23 @@ namespace
{
ATOM g_classAtom = 0;
std::wstring getWindowText(HWND hwnd)
{
const UINT MAX_LEN = 256;
wchar_t windowText[MAX_LEN] = {};
InternalGetWindowText(hwnd, windowText, MAX_LEN);
return windowText;
}
LRESULT CALLBACK presentationWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LOG_FUNC("presentationWindowProc", Compat::WindowMessageStruct(hwnd, uMsg, wParam, lParam));
if (WM_NULL == uMsg && WM_GETTEXT == wParam && WM_SETTEXT == lParam)
{
std::wstring windowText(L"[DDrawCompat] " + getWindowText(GetParent(hwnd)));
SetWindowTextW(hwnd, windowText.c_str());
return LOG_RESULT(0);
}
return LOG_RESULT(CALL_ORIG_FUNC(DefWindowProcA)(hwnd, uMsg, wParam, lParam));
}
}

View File

@ -54,7 +54,6 @@ namespace
decltype(&DwmSetIconicThumbnail) g_dwmSetIconicThumbnail = nullptr;
wchar_t g_dummyWindowText;
std::map<HMENU, UINT> g_menuMaxHeight;
std::set<Gdi::WindowPosChangeNotifyFunc> g_windowPosChangeNotifyFuncs;
@ -71,7 +70,6 @@ namespace
void dwmSendIconicThumbnail(HWND hwnd, LONG width, LONG height);
WindowProc getWindowProc(HWND hwnd);
std::wstring getWindowText(HWND hwnd, WNDPROC wndProc);
bool isUser32ScrollBar(HWND hwnd);
void onDestroyWindow(HWND hwnd);
void onGetMinMaxInfo(MINMAXINFO& mmi);
@ -146,19 +144,6 @@ namespace
}
break;
case WM_NULL:
if (WM_GETTEXT == wParam && reinterpret_cast<LPARAM>(&g_dummyWindowText) == lParam)
{
auto presentationWindow = Gdi::Window::getPresentationWindow(hwnd);
if (presentationWindow)
{
std::wstring windowText(L"[DDrawCompat] " + getWindowText(hwnd, wndProc));
SendMessageW(presentationWindow, WM_SETTEXT, 0, reinterpret_cast<LPARAM>(windowText.c_str()));
}
return 0;
}
break;
case WM_SYNCPAINT:
if (Gdi::Window::isTopLevelWindow(hwnd))
{
@ -412,25 +397,6 @@ namespace
return it != g_windowProc.end() ? it->second : WindowProc{};
}
std::wstring getWindowText(HWND hwnd, WNDPROC wndProc)
{
const UINT MAX_LEN = 256;
if (IsWindowUnicode(hwnd))
{
wchar_t windowText[MAX_LEN] = {};
CallWindowProcW(wndProc, hwnd, WM_GETTEXT, MAX_LEN, reinterpret_cast<LPARAM>(windowText));
windowText[MAX_LEN - 1] = 0;
return windowText;
}
else
{
char windowText[MAX_LEN] = {};
CallWindowProcA(wndProc, hwnd, WM_GETTEXT, MAX_LEN, reinterpret_cast<LPARAM>(windowText));
windowText[MAX_LEN - 1] = 0;
return std::wstring(windowText, windowText + strlen(windowText));
}
}
template <auto func, typename... Params>
int WINAPI messageBox(Params... params)
{
@ -813,7 +779,11 @@ namespace
case EVENT_OBJECT_NAMECHANGE:
if (OBJID_WINDOW == idObject && Gdi::Window::isTopLevelWindow(hwnd) && !Gdi::GuiThread::isGuiThreadWindow(hwnd))
{
Gdi::WinProc::updatePresentationWindowText(hwnd);
auto presentationWindow = Gdi::Window::getPresentationWindow(hwnd);
if (presentationWindow)
{
Gdi::Window::updatePresentationWindowText(presentationWindow);
}
break;
}
@ -1038,11 +1008,6 @@ namespace Gdi
}
}
void updatePresentationWindowText(HWND owner)
{
SendNotifyMessageW(owner, WM_NULL, WM_GETTEXT, reinterpret_cast<LPARAM>(&g_dummyWindowText));
}
void watchWindowPosChanges(WindowPosChangeNotifyFunc notifyFunc)
{
g_windowPosChangeNotifyFuncs.insert(notifyFunc);

View File

@ -290,7 +290,7 @@ namespace
if (!isLayered)
{
it->second.presentationWindow = Gdi::PresentationWindow::create(hwnd);
Gdi::WinProc::updatePresentationWindowText(hwnd);
Gdi::Window::updatePresentationWindowText(it->second.presentationWindow);
}
else if (it->second.presentationWindow)
{
@ -662,7 +662,7 @@ namespace Gdi
if (it->second.presentationWindow)
{
Gdi::WinProc::updatePresentationWindowText(hwnd);
updatePresentationWindowText(it->second.presentationWindow);
Gdi::GuiThread::setWindowRgn(it->second.presentationWindow, getWindowRgn(hwnd));
}
@ -729,6 +729,11 @@ namespace Gdi
});
}
void updatePresentationWindowText(HWND presentationWindow)
{
PostMessageW(presentationWindow, WM_NULL, WM_GETTEXT, WM_SETTEXT);
}
void updateWindowPos(HWND hwnd)
{
if (IsWindowVisible(hwnd) && !IsIconic(hwnd))

View File

@ -33,6 +33,7 @@ namespace Gdi
void updateLayeredWindowInfo(HWND hwnd, HDC hdcSrc, const POINT* pptSrc,
COLORREF colorKey, BYTE alpha, BYTE alphaFormat);
void updatePresentationWindowPos(HWND presentationWindow, HWND owner);
void updatePresentationWindowText(HWND presentationWindow);
void updateWindowPos(HWND hwnd);
}
}