diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index d8eb7aee..cce35b0e 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -234,6 +234,7 @@ video tutorials. - Jan Schürkamp - Christian Sdunek - Matt Sealey + - Perumaal Shanmugam - Steve Sexton - Arkady Shapkin - Mingjie Shen diff --git a/README.md b/README.md index 6eb6b9bd..66a3811d 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,7 @@ information on what to include when reporting a bug. - [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless` - [EGL] Allowed native access on Wayland with `GLFW_CONTEXT_CREATION_API` set to `GLFW_NATIVE_CONTEXT_API` (#2518) + - [Win32] Bugfix: Fix `windowProc` to work when `SetPropW` fails silently ## Contact diff --git a/src/win32_init.c b/src/win32_init.c index 6b6e9d08..5e06c4de 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -493,18 +493,19 @@ void _glfwInputErrorWin32(int error, const char* description) WCHAR buffer[_GLFW_MESSAGE_SIZE] = L""; char message[_GLFW_MESSAGE_SIZE] = ""; + DWORD lastError = GetLastError(); FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, - GetLastError() & 0xffff, + lastError & 0xffff, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof(buffer) / sizeof(WCHAR), NULL); WideCharToMultiByte(CP_UTF8, 0, buffer, -1, message, sizeof(message), NULL, NULL); - _glfwInputError(error, "%s: %s", description, message); + _glfwInputError(error, "%s (0x%lx / %lu): %s", description, lastError, lastError, message); } // Updates key names according to the current keyboard layout diff --git a/src/win32_window.c b/src/win32_window.c index 26f9684b..e9da0821 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -548,8 +548,23 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l EnableNonClientDpiScaling(hWnd); } } + else + { + // HACK: SetPropW returns FALSE in some instances (GetLastError() = 0x8 Insufficient resources). + // We already have the global list of windows, check against it. It's not many, and we are already + // doing this in the (one of the callers) PollEvents below. + window = _glfw.windowListHead; + while (window) + { + if (window->win32.handle == hWnd) { break; } + window = window->next; + } + } - return DefWindowProcW(hWnd, uMsg, wParam, lParam); + if (!window) + { + return DefWindowProcW(hWnd, uMsg, wParam, lParam); + } } switch (uMsg) @@ -1401,7 +1416,13 @@ static int createNativeWindow(_GLFWwindow* window, return GLFW_FALSE; } - SetPropW(window->win32.handle, L"GLFW", window); + if (!SetPropW(window->win32.handle, L"GLFW", window)) + { + // In some cases, SetPropW returns FALSE: GetLastError() returns 0x8 (Insufficient resources). + // The message pump fails to work because windowProc cannot look up the GLFW property. + // Instead of failing the program completely by raising an error instead, windowProc looks up + // the global window list to find the hWnd under consideration. + } ChangeWindowMessageFilterEx(window->win32.handle, WM_DROPFILES, MSGFLT_ALLOW, NULL); ChangeWindowMessageFilterEx(window->win32.handle, WM_COPYDATA, MSGFLT_ALLOW, NULL);