[Development] QPushButton: drag and drop
Giuseppe D'Angelo
giuseppe.dangelo at kdab.com
Sat Jun 4 00:08:13 CEST 2022
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.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: 4244 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.qt-project.org/pipermail/development/attachments/20220604/2e0120ae/attachment-0001.bin>
More information about the Development
mailing list