Win32: Alt+F4 does not close the window, as WM_SYSKEYDOWN never reaches DefWindowProc #179

Open
opened 2026-10-31 17:22:31 +00:00 by jorijnvdgraaf · 0 comments

Summary

On Win32, Alt+F4 does not close a Crafter window: onClose never fires and open stays true. Line numbers refer to implementations/Crafter.Graphics-Window.cpp at 852ae8a.

WndProc handles WM_SYSKEYDOWN together with WM_KEYDOWN (:181-193), and the case ends in break, so the message returns 0 (:341) without reaching DefWindowProc. Alt+F4 is DefWindowProc's doing: for a WM_SYSKEYDOWN of VK_F4 with Alt held it sends WM_SYSCOMMAND SC_CLOSE, which would become the WM_CLOSE that :158 turns into onClose.

Only the title bar's close button, or the system menu opened from the title bar, closes the window. Under Wine, a window manager that takes Alt+F4 itself hides the bug.

Found while reviewing claude/win32-title.

Suggested fix

Report the key as now, then return DefWindowProc(hwnd, msg, wParam, lParam) for WM_SYSKEYDOWN (DefWindowProcW once claude/win32-title lands). WM_SYSKEYUP can stay swallowed, which keeps a lone Alt or F10 from putting the window into menu mode. PointerWin32 can check it: post WM_SYSKEYDOWN with VK_F4 and the Alt bit (29) set in lParam, and expect onClose.

## Summary On Win32, Alt+F4 does not close a Crafter window: `onClose` never fires and `open` stays true. Line numbers refer to `implementations/Crafter.Graphics-Window.cpp` at `852ae8a`. `WndProc` handles `WM_SYSKEYDOWN` together with `WM_KEYDOWN` (`:181-193`), and the case ends in `break`, so the message returns 0 (`:341`) without reaching `DefWindowProc`. Alt+F4 is `DefWindowProc`'s doing: for a `WM_SYSKEYDOWN` of `VK_F4` with Alt held it sends `WM_SYSCOMMAND` `SC_CLOSE`, which would become the `WM_CLOSE` that `:158` turns into `onClose`. Only the title bar's close button, or the system menu opened from the title bar, closes the window. Under Wine, a window manager that takes Alt+F4 itself hides the bug. Found while reviewing `claude/win32-title`. ## Suggested fix Report the key as now, then return `DefWindowProc(hwnd, msg, wParam, lParam)` for `WM_SYSKEYDOWN` (`DefWindowProcW` once `claude/win32-title` lands). `WM_SYSKEYUP` can stay swallowed, which keeps a lone Alt or F10 from putting the window into menu mode. `PointerWin32` can check it: post `WM_SYSKEYDOWN` with `VK_F4` and the Alt bit (29) set in `lParam`, and expect `onClose`.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Catcrafts/Crafter.Graphics#179
No description provided.