Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.2.1, 5.4.2, 5.6.0 Alpha, 5.11.0 Beta 4
-
None
-
I've reproduced the bug for all of these:
* Qt 5.2.1 on Ubuntu 14.04
* Qt 5.4.2 on Ubuntu 15.10
* Qt 5.6.0 Beta (snapshot 275) on Ubuntu 15.10
* Qt 5.11.0 Beta on Ubuntu 16.10
Description
The attached application has a simple QTableWidget with some items that can be dragged into a drop-enabled QWidget subclass. On Linux, if you quickly drag an item from the table widget to the drop area, some drops are lost.
See the attached video for a demonstration of this bug.
Looking into this issue, I have discovered that an unexpected QEvent::Leave is sent about 200 ms after the start of any QDrag operation. This seems to be related to creation of the drag icon. The attached code prints out these leave messages. If you have already moved into the drop region by the time this event is sent, then the drop may fail.
It doesn't seem to matter whether you're dropping into the same Qt Application or dropping into any other linux application; the drop may be lost in either case. I have also tested this on the mac, and the unexpected QEvent::Leave still occurs, but it does not result in a failed drop.
I have been able to suppress this problem in two different ways by modifying Qt sources. I doubt that either one of these is appropriate as a true solution, but at least they may point the right person in a good direction.
(1) The problem goes away if you remove the following line from qsimpledrag.cpp, in QBasicDrag::startDrag():
m_drag_icon_window->setVisible(true);
If the drag icon is not shown, then the undesired Leave event is not sent, and the problem goes away. Of course, this isn't a good solution because it means that the drag icon is never shown.
(2) The problem also goes away if you remove the following lines from qxcbdrag.cpp, in QXcbDrag::move(const QMouseEvent *me): (somewhere around line 427, depending upon the revision of the source file)
if (current_target)
send_leave();
This doesn't suppress the strange Leave event, but it prevents this Leave event from being translated into a DragLeaveEvent. This solution works fine, and everything else in the test App seems to work fine as well. I'm not sure what these lines are intended to do, but removing them doesn't have any bad effect as far as I can see. Also, all the existing tests in tests/gui pass after this change.
Looking through existing bug reports, I do not see any previous reference. The closest candidate is QTBUG-37019, but there isn't a lot of information there and this seems to have a greater impact than that describes.
Hopefully this gives a good starting point from which to address this bug. In our application on Linux, we are doing many drag and drop operations, and some of them unexpectedly fail.
Attachments
Issue Links
- relates to
-
QTBUG-37019 No dropEvent received after less than two dragMoveEvents received.
- Closed
-
QTBUG-34331 [regression] DnD won't send "drop()" unless mouse moves > 1 px after QDrag::exec()
- Closed