We had some separate discussion with Rémi about this, and I did some more testing around, summarizing that here.
The idea of "on-demand" messages generation suggested above would imply generating this message in get_message handling (in the wineserver). Trying to see if that is about how it works on Windows, I made a test making PeekMessage() loop in test's MsgCheckProc in WM_WINDOWPOSCHANGED. And this yielded no change: PeekMessage wasn't returning anything and the test was still succeeding (i. e., receiving mouse messages as expected after WM_WINDOWSPOSCHANGED and winevent notifications). However, playing more with it, I discovered that adding a delay before that message loop (implicit with trace() or, better for reliability, Sleep(50)) resulted in WM_MOUSEMOVE being delivered in this message loop (without otherwise preceding WM_SETCURSOR however). I think these results basically exclude the possibility that Windows generates that message "on demand" during PeekMessage handling, hard to guess how the delay there would be possible (without anything else besides trace or Sleep() being called). I think more likely Windows hardware events handling process sees the window configuration change with a bit of delay and generates the event.
The closest match with Wine would probably do that in something like check_for_driver_events(), having some thread flag to know that window configuration has been updated. But we discussed that probably this is more ugly than the present solution without obvious benefits.