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

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

_______________________________________________
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development

Reply via email to