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
smime.p7s
Description: Firma crittografica S/MIME
_______________________________________________ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest