Details
-
Type:
Bug
-
Status: Reported
-
Priority:
P3: Somewhat important
-
Resolution: Unresolved
-
Affects Version/s: 5.12.1
-
Fix Version/s: None
-
Component/s: Quick: Mouse Touch and Tablet input
-
Labels:None
-
Platform/s:
Description
I would expect that rejecting a drag event from a particular dragged Item would prevent a DropArea from receiving more drag events from the same dragged Item, at least until it exited the DropArea and re-entered.
Instead, the behavior observed is that every movement of the dragged Item within a DropArea re-triggers onEntered on the DropArea, even if the drag is rejected in onEntered handler of the DropArea.
This makes it very difficult to put significant processing code in onEntered for identifying whether to accept the drag and indicating this to the user through UI behavior. It becomes a performance issue.
Attached is a minimal reproduction example. Dragging an item over the window will cause "ENTERED" to be printed on every mouse movement, many times per second.
I believe that this is caused by the following code in qquickdroparea.cpp:
void QQuickDropArea::dragEnterEvent(QDragEnterEvent *event) { Q_D(QQuickDropArea); const QMimeData *mimeData = event->mimeData(); if (!d->effectiveEnable || d->containsDrag || !mimeData || !d->hasMatchingKey(d->getKeys(mimeData))) return; d->dragPosition = event->pos(); event->accept(); QQuickDropEvent dragTargetEvent(d, event); emit entered(&dragTargetEvent); if (!event->isAccepted()) return; d->containsDrag = true; ...
containsDrag is set after the check on whether the event is accepted, but is checked at the beginning for the early-return. Therefore, if the drag event is always rejected, then containsDrag will never be set true, and the entered signal will continue to be emitted.
Another negative side-effect of this is that containsDrag will be inaccurate if the drag is rejected. From the documentation for containsDrag:
"This property identifies whether the DropArea currently contains any dragged items."
This will not be as documented for a rejected dragged item.