From 2fded1aab29242a86fe582c7162c2f1bf7bfec28 Mon Sep 17 00:00:00 2001 From: Peru S Date: Tue, 29 Jul 2025 12:53:19 -0700 Subject: [PATCH 1/2] Fix windowProc when SetPropW() fails silently **Issue** In some cases, on Windows, `SetPropW` returns `FALSE`. glfw currently silently ignores the result. This means that the message pump `windowProc` fails to work (does not receive keyboard events for example). Drawing is fine though as it's a different GLFW mechanism. I had this failure frequently infrequently and it was frustrating to deal with (just have to rerun the program a few times and hope `SetPropW` doesn't return `FALSE`). So sending this fix in case others are facing the issue on Windows. **Fix** On Windows+GLFW, `windowProc` will fallback to looking up the GLFW window list (just like `PollEvents` does). Also added the error code to `_glfwInputError` message to aid debugging in the future. My suggestion is to get rid of `SetPropW`/`GetPropW` as it is a string-based Windows API (slow/fragile) - we already have the lightweight linked list, might as well just use it always - also it's usually just the one or two windows we deal with. - [x] Verified on Windows - message pump is stable with this fix (once I was able to repro this issue). --- src/win32_init.c | 5 +++-- src/win32_window.c | 25 +++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) 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); From 959f13c1bd686821044bc3fae9008167fef22987 Mon Sep 17 00:00:00 2001 From: Peru S Date: Tue, 29 Jul 2025 12:59:07 -0700 Subject: [PATCH 2/2] Add to CONTRIBUTORS.md and README.md --- CONTRIBUTORS.md | 1 + README.md | 1 + 2 files changed, 2 insertions(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 8fa1cb72..ea85f001 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -232,6 +232,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 c453739d..4fbfb565 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,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