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.

E.g.

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 processes.)

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.dang...@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

Attachment: smime.p7s
Description: Firma crittografica S/MIME

_______________________________________________
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest

Reply via email to