On 03/06/2022 23:05, Volker Hilsheimer wrote:
If we were to deliver a mouseReleaseEvent to the widget that initiated the drag via QDrag::exec after the exec returns, then we handle the mouseReleaseEvent twice.
Why twice? It receives only one?Note that the infrastructure for sending a release when the drag ends is already there:
https://github.com/qt/qtbase/blob/dev/src/gui/kernel/qsimpledrag.cpp#L125
It's just that in QtWidgets it never reaches the widget, as it gets filtered out by QApplicationPrivate::pickMouseReceiver (called by QWidgetWindow::handleMouse).
Given the blame on that code shows no changes since Nokia times, something just tells me that this has never worked properly and people started 1) relying on the release to be never received, and/or 2) add workarounds for that.
<rant>This isn't the only case where Qt event handling is very very inconsistent. Leave/Enter events are also extremely unreliable (if a widget is shown under the cursor, you may or may not get a enter event. Same for a widget moving on its own, moving under or outside the cursor.)
</rant>
In the case of the button, it would mean that we emit clicked() if the drag is dropped inside the button. Check the following, which simulates that Qt would do that. Drag from the button, and drop the drag inside the button. The button now emits clicked(). You most certainly don’t want slot connected to that signal to execute in that interaction.
That's kind of an orthogonal story, that is, adding DND support on top of a class that already uses mouse interactions isn't always possible. But you could say the same for any other event-driven interaction when you start messing with the received events. What if tomorrow we add DND support to QPushButton itself, with the related logic in the mouse event handlers? Then the overrides in the testcase will break (they might _re_start DND).
This is of course a special case, but it shows that we can’t just start delivering MouseButtonRelease events to widgets when a drag operation finishes, because they would suddenly execute mouseReleaseEvent code in a state in which they don’t expect it to.
Yes, I'm not claiming that this should be a fix to cherry-pick back. Being likely a 10+ yo behavior, it's dev material only.
For instance, QAbstractItemView does not expect to get a mouseReleaseEvent when QAbstractItemView::startDrag returns. I didn’t test it, but it start the editor of the item that was dragged, which might crash when that index got removed by the drag! Widgets that support drag’n’drop need to reset their state when QDrag::exec returns, and must be able to rely that they don’t get a mouseReleaseEvent when that mouse release already was processed by the drag’n’drop system to end the drag.
But this simply can't be done reliably in general, as you don't necessarily have access to that state so you can't reset it. Again, what if tomorrow QPushButton starts drawing itself differently depending on mouse movements, and wants to see the release to reset its drawing?
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: S/MIME Cryptographic Signature
_______________________________________________ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development