This is the main reason that asynchronous operations (which may inclue certain QML-side layouting) are slower on Windows. I wonder if this is about general Win32 message queue, and not necessarily a Qt issue.
Fixing this issue is going to make the application much more responsive on Windows.
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Qt seems to be delaying its own posted events on Windows, where I assume includes delayed bindings and queued connections [1]:
// Start a timer to deliver posted events when the message queue is emptied.sendPostedEventsTimerId=SetTimer(internalHwnd,SendPostedEventsTimerId,USER_TIMER_MINIMUM,NULL);
It prioritizes other event types. And the timer used to delay seems to be USER_TIMER_MINIMUM, which is 10. Does this mean queued connections are delayed by 10 milliseconds? If that is the case, this seems a really bad idea to me because a GUI application would almost always have messages in the queue (consider input messages such as mouse move)...
QEventDispatcherWin32: avoid livelock in a foreign event loopAccording to Windows docs, GetMessage() function retrieves the messagesfrom the input queue in defined order, where posted messages areprocessed ahead of input messages, even if they were posted later.Therefore, if the application produces a posted event permanently, asa result of processing that event, user input messages may be blockeddue to hard CPU usage by the application.It's not a problem, if an internal Qt event loop is running. By callingsendPostedEvents() on the beginning of processEvents(), we are sendingposted events only once per iteration. However, during execution ofthe foreign loop, we should artificially lower the priority of theWM_QT_SENDPOSTEDEVENTS message in order to enable delivery of otherinput messages.To solve the problem, it is proposed to postpone theWM_QT_SENDPOSTEDEVENTS message until the message queue becomes empty,as it works for the internal loop.
QEventDispatcherWin32: fix posted events deliveringTo avoid livelocks, posted events should be delivered when all pendingmessages have been processed, and the thread's message queue becomesempty. Although the logic of the previous patch is correct, it turnedout that determining the moment when the message queue is really emptyis not so simple. It is worth noting that the GetQueueStatus functionsometimes reports unexpected results due to internal filtering andprocessing. Indeed, Windows docs say that "the return value fromGetQueueStatus should be considered only a hint as to whetherGetMessage or PeekMessage should be called". Thus, we cannot rely onGetQueueStatus in unambiguous logic inside the qt_GetMessageHook.To solve the problem, this patch introduces a guard timer whichguarantees low priority processing for posted events in foreign loop.The wakeUps flag reset logic has also been changed to provide clearersynchronization of the Qt internal loop.