Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-74496

Performance issue: rejected drag re-triggers drag enter event every frame while mouse moves

    XMLWordPrintable

Details

    • All
    • d194d32fc9 (qt/qtdeclarative/6.3) 10bb5cf3fc (qt/qtdeclarative/6.4) 0b7374fefa (qt/qtdeclarative/dev) 0b7374fefa (qt/qtdeclarative/wip/material3) d194d32fc9 (qt/tqtc-qtdeclarative/6.3) 10bb5cf3fc (qt/tqtc-qtdeclarative/6.4)

    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.
      UPDATE:
      DragEnter causes a spike in the CPU profiler. When one has DropAreas that accepts a 'text/uri-list' type (the type of a file from the OS), With multiple Drag area this becomes worst. See No_keys_on_droparea_dragenter_is_expensive.png
      Further these DragEnter events keep getting fired if dragging within a DropArea that does not accept the 'text/uri-list' type. This leads to causes massive slowdown for the entire duration that the dragging is occurring in these DropAreas. See Keys_that_dont_include_text/uri-list_dragEnter_always_firing.png

      Attachments

        Issue Links

          Activity

            People

              santhoshkumar Santhosh Kumar Selvaraj
              daniel.ford Daniel Ford
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0 minutes
                  0m
                  Logged:
                  Time Spent - 4 days
                  4d