[Interest] Click and hold on close button

Giuseppe D'Angelo giuseppe.dangelo at kdab.com
Thu Aug 29 16:32:42 CEST 2019

Il 27/08/19 20:09, Murphy, Sean ha scritto:
> I've attached a sample application below that can be used to test.
> When you build and launch it, a QLabel blinks between green and
> "normal", switching palettes every second. On Windows, if you
> click and hold on any of those 3 buttons, and while holding the
> mouse, move off the original button so that the release event
> doesn't happen on the same button, the blinking will cease the
> entire time you have the button pressed. Do the same thing on
> Linux and the QLabel keeps blinking happily the entire time.

Please put aside the "conspiracy theories".

The very simple reason that the event loop blocks is that Qt doesn't 
know what to do with that event, and it ends up calling DefWindowProc 
[1], "the default window procedure to provide default processing for any 
window messages that an application does not process" [2]. That is a 
blocking call (!); execution stays in there until the OS knows what to 
do, which seems to be not until you release the mouse button.

If you enable QPA logging in the qt.qpa.events category (e.g. via 
QT_LOGGING_RULES), and add "verbose" > 2 to your QPA plugin loading 
(e.g. -platform windows:verbose=2) you'll see the mouse press correctly 
received by Qt.

If also you run your app in a debugger and make it print a stack trace 
while keeping the mouse pressed on a window decoration button, you'll 
see the stack trace in there.


> C:\> timeout 5 & cdb -p 12345

> [timeout trips into the debugger]
> 0:010> ~* k
>    0  Id: d90.3334 Suspend: 1 Teb: 00000095`0578d000 Unfrozen
> Child-SP          RetAddr           Call Site
> 00000095`058fbad8 00007ffb`72b44f7a win32u!NtUserMessageCall+0x14
> 00000095`058fbae0 00007ffb`72b4470f USER32!RealDefWindowProcWorker+0x1fa
> 00000095`058fbbe0 00007ffb`6ecb984e USER32!RealDefWindowProcW+0x4f
> 00000095`058fbc20 00007ffb`6ecd24f7 UxTheme!DoMsgDefault+0x2e
> 00000095`058fbc60 00007ffb`6ecbc49f UxTheme!OnDwpNcLButtonDown+0xa7
> 00000095`058fbca0 00007ffb`6ecbbf81 UxTheme!_ThemeDefWindowProc+0x50f
> 00000095`058fbe80 00007ffb`72b44c4f UxTheme!ThemeDefWindowProcW+0x11
> 00000095`058fbec0 00007ffb`38488d92 USER32!DefWindowProcW+0x1bf
> 00000095`058fbf30 00007ffb`72b4681d qwindowsd!qWindowsWndProc+0x422
> 00000095`058fc170 00007ffb`72b46212 USER32!UserCallWinProcCheckWow+0x2bd
> 00000095`058fc300 00007ffb`3a30d443 USER32!DispatchMessageWorker+0x1e2
> 00000095`058fc380 00007ffb`385524f4 Qt5Cored!QEventDispatcherWin32::processEvents+0x5c3

This also answers why other applications don't freeze -- they must be 
handling the event internally, keeping their event loops unstuck. For 
instance, Chromium / Firefox may just be using client-side decorations, 
and handling clicks on the decoration buttons themselves. (This has 
nothing to do with the fact that their rendering is out of process, 
etc.; actually it's highly likely that you need an event loop running in 
the "main" application, in order to gather the rendering from the other 

So why does Qt call into a blocking Win32 API from the main thread? I 
have absolutely no idea; I'm not a Windows user and I know close to 0 
Win32 API programming. Event loop code looks hairy enough, but if anyone 
knows if there's a "better" way to handle these events, please submit 
bug reports.

> [1] https://code.woboq.org/qt5/qtbase/src/plugins/platforms/windows/qwindowscontext.cpp.html#1600

> [2] https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-defwindowprocw

My 2 c,
Giuseppe D'Angelo | giuseppe.dangelo at kdab.com | Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com
KDAB - The Qt, C++ and OpenGL Experts

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4329 bytes
Desc: Firma crittografica S/MIME
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20190829/9db47e4d/attachment.bin>

More information about the Interest mailing list