Skip to content

win32: fix drag_window and drag_resize_window - #4825

Open
smittie2000 wants to merge 4 commits into
rust-windowing:masterfrom
smittie2000:smittie2000/fix-win32-stuck-dragging
Open

smittie2000 wants to merge 4 commits into
rust-windowing:masterfrom
smittie2000:smittie2000/fix-win32-stuck-dragging

Conversation

@smittie2000

@smittie2000 smittie2000 commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #4821. Supersedes #4765, whose commit is included here unchanged.

This fixes two bugs in how Window::drag_window and Window::drag_resize_window start a native move/size on Windows. They are in the same PostMessageW call, so they are fixed together.

Drags stop working after one that Windows did not perform (#4821)

handle_os_dragging sets WindowState::dragging and returns early while it is set. The flag was only cleared on WM_EXITSIZEMOVE. When Windows declines to start the modal move/size loop, for example when resizing a maximized window, that message never arrives, so the flag stays set and every later drag call silently does nothing. This matches the report's observation that dragging the native title bar un-sticks it, since a real drag sends WM_EXITSIZEMOVE.

  • For WM_NCLBUTTONDOWN, DefWindowProcW runs the modal loop and only returns once it has ended or was never started. It is now called inline and the flag is cleared after it returns, mirroring the existing WM_PAINT arm. The state lock is taken only after the call, because the modal loop re-enters the window procedure. In the normal case WM_EXITSIZEMOVE has already cleared the flag and posted the WM_LBUTTONUP, so the extra clear has no effect. No WM_LBUTTONUP is posted when no loop ran, because the real one was not swallowed.
  • If PostMessageW itself fails (for example, the message queue is full), the message never arrives either, so that now logs a warning and clears the flag.

Wrong cursor coordinates in lParam

The message was posted with &points as *const _ as LPARAM, which passes the address of a POINTS struct rather than the coordinates. Windows reads them from the bits of lParam itself: low word x, high word y, each a signed 16-bit value as decoded by GET_X_LPARAM/GET_Y_LPARAM (WM_NCLBUTTONDOWN). The cursor position is now packed into lParam directly. Each coordinate is truncated to u16 first, so negative positions on monitors left of or above the primary one survive the round trip.

Testing

On Windows with the application example, including on a secondary monitor at negative coordinates:

  • moving and resizing from every edge and corner work;
  • after a drag-resize on a maximized window and restoring it, moving and resizing work again;
  • normal drags still report the left button release.

v0.30.x has both bugs, and #4821 was reported on 0.30.13. I'm happy to open a backport if that's wanted.

🤖 Generated with Claude Code

`dragging` was only cleared on `WM_EXITSIZEMOVE`. When Windows declined to
start the modal move/size loop, such as when resizing a maximized window,
that message never arrived and every later `drag_window` and
`drag_resize_window` call returned early.

`DefWindowProcW` only returns from `WM_NCLBUTTONDOWN` once the loop has
ended or was never started, so clear the flag after it returns.

Fixes rust-windowing#4821.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@smittie2000
smittie2000 force-pushed the smittie2000/fix-win32-stuck-dragging branch from ea70141 to ced83d2 Compare November 8, 2026 08:05
smittie2000 and others added 2 commits November 8, 2026 10:18
If `PostMessageW` fails, for example because the message queue is full,
no `WM_NCLBUTTONDOWN` arrives and nothing clears `dragging`, so later
drags would be ignored. Log a warning and clear the flag instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@smittie2000 smittie2000 changed the title win32: reset dragging state when no move/size loop runs win32: fix drag_window and drag_resize_window Nov 8, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Windows: drag_resize_window on a maximized window breaks later drags

1 participant