qtbug-72844.patch 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. From 52e0d9e23c3f7a1b0faf6649cf3dd825bcfd4f08 Mon Sep 17 00:00:00 2001
  2. From: Christian Ehrlicher <ch.ehrlicher@gmx.de>
  3. Date: Thu, 3 Jan 2019 20:33:57 +0100
  4. Subject: Drag'n'Drop: fix dnd when dragMoveEvent() is not implemented
  5. The refactoring of dnd with f8944a7f07112c85dc4f66848cabb490514cd28e
  6. added a regression which results in a need to reimplement
  7. dragMoveEvent() on the drop side. Before this change it was possible to
  8. accept the dnd in dragEnterEvent() without again accepting it in
  9. dragMoveEvent().
  10. Fix it in a similar way it's done in
  11. QGuiApplicationPrivate::processDrag() by prefilling the first simulated
  12. QDragMoveEvent with the values from the previous QDragEnterEvent before
  13. it is sent to the drop receiver.
  14. Fixes: QTBUG-72844
  15. Change-Id: I1300dd02b7f1d9dcd44ecefa8335f92ad6c6cafa
  16. Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io>
  17. ---
  18. src/widgets/kernel/qwidgetwindow.cpp | 7 +++--
  19. .../kernel/qwidget_window/tst_qwidget_window.cpp | 36 +++++++++++++++++++---
  20. 2 files changed, 37 insertions(+), 6 deletions(-)
  21. diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
  22. index 279c6c0282..991a05fa02 100644
  23. --- a/src/widgets/kernel/qwidgetwindow.cpp
  24. +++ b/src/widgets/kernel/qwidgetwindow.cpp
  25. @@ -899,10 +899,10 @@ void QWidgetWindow::handleDragMoveEvent(QDragMoveEvent *event)
  26. const QPoint mapped = widget->mapFromGlobal(m_widget->mapToGlobal(event->pos()));
  27. QDragMoveEvent translated(mapped, event->possibleActions(), event->mimeData(),
  28. event->mouseButtons(), event->keyboardModifiers());
  29. - translated.setDropAction(event->dropAction());
  30. - translated.setAccepted(event->isAccepted());
  31. if (widget == m_dragTarget) { // Target widget unchanged: Send DragMove
  32. + translated.setDropAction(event->dropAction());
  33. + translated.setAccepted(event->isAccepted());
  34. QGuiApplication::forwardEvent(m_dragTarget, &translated, event);
  35. } else {
  36. if (m_dragTarget) { // Send DragLeave to previous
  37. @@ -912,6 +912,9 @@ void QWidgetWindow::handleDragMoveEvent(QDragMoveEvent *event)
  38. }
  39. // Send DragEnter to new widget.
  40. handleDragEnterEvent(static_cast<QDragEnterEvent*>(event), widget);
  41. + // Handling 'DragEnter' should suffice for the application.
  42. + translated.setDropAction(event->dropAction());
  43. + translated.setAccepted(event->isAccepted());
  44. // The drag enter event is always immediately followed by a drag move event,
  45. // see QDragEnterEvent documentation.
  46. QGuiApplication::forwardEvent(m_dragTarget, &translated, event);
  47. diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp
  48. index f4da4c3e5f..431d6ba960 100644
  49. --- a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp
  50. +++ b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp
  51. @@ -470,6 +470,10 @@ static const char *expectedLogC[] = {
  52. "Event at 11,241 accepted",
  53. "acceptingDropsWidget2::dropEvent at 1,51 action=1 MIME_DATA_ADDRESS 'testmimetext'",
  54. "Event at 11,261 accepted",
  55. + "acceptingDropsWidget3::dragEnterEvent at 1,21 action=1 MIME_DATA_ADDRESS 'testmimetext'",
  56. + "Event at 11,281 accepted",
  57. + "acceptingDropsWidget3::dragLeaveEvent QDragLeaveEvent",
  58. + "Event at 11,301 ignored",
  59. "acceptingDropsWidget1::dragEnterEvent at 10,10 action=1 MIME_DATA_ADDRESS 'testmimetext'",
  60. "Event at 0,0 accepted",
  61. "acceptingDropsWidget1::dragMoveEvent at 11,11 action=1 MIME_DATA_ADDRESS 'testmimetext'",
  62. @@ -482,8 +486,9 @@ static const char *expectedLogC[] = {
  63. class DnDEventLoggerWidget : public QWidget
  64. {
  65. public:
  66. - DnDEventLoggerWidget(QStringList *log, QWidget *w = 0) : QWidget(w), m_log(log) {}
  67. -
  68. + DnDEventLoggerWidget(QStringList *log, QWidget *w = nullptr, bool ignoreDragMove = false)
  69. + : QWidget(w), m_log(log), m_ignoreDragMove(ignoreDragMove)
  70. + {}
  71. protected:
  72. void dragEnterEvent(QDragEnterEvent *);
  73. void dragMoveEvent(QDragMoveEvent *);
  74. @@ -493,6 +498,7 @@ protected:
  75. private:
  76. void formatDropEvent(const char *function, const QDropEvent *e, QTextStream &str) const;
  77. QStringList *m_log;
  78. + bool m_ignoreDragMove;
  79. };
  80. void DnDEventLoggerWidget::formatDropEvent(const char *function, const QDropEvent *e, QTextStream &str) const
  81. @@ -513,6 +519,8 @@ void DnDEventLoggerWidget::dragEnterEvent(QDragEnterEvent *e)
  82. void DnDEventLoggerWidget::dragMoveEvent(QDragMoveEvent *e)
  83. {
  84. + if (m_ignoreDragMove)
  85. + return;
  86. e->accept();
  87. QString message;
  88. QTextStream str(&message);
  89. @@ -580,7 +588,17 @@ void tst_QWidget_window::tst_dnd()
  90. dropsRefusingWidget2->resize(160, 60);
  91. dropsRefusingWidget2->move(10, 10);
  92. + QWidget *dropsAcceptingWidget3 = new DnDEventLoggerWidget(&log, &dndTestWidget, true);
  93. + dropsAcceptingWidget3->setAcceptDrops(true);
  94. + dropsAcceptingWidget3->setObjectName(QLatin1String("acceptingDropsWidget3"));
  95. + // 260 + 40 = 300 = widget size, must not be more than that.
  96. + // otherwise it will break WinRT because there the tlw is maximized every time
  97. + // and this window will receive one more event
  98. + dropsAcceptingWidget3->resize(180, 40);
  99. + dropsAcceptingWidget3->move(10, 260);
  100. +
  101. dndTestWidget.show();
  102. + QVERIFY(QTest::qWaitForWindowExposed(&dndTestWidget));
  103. qApp->setActiveWindow(&dndTestWidget);
  104. QVERIFY(QTest::qWaitForWindowActive(&dndTestWidget));
  105. @@ -595,16 +613,17 @@ void tst_QWidget_window::tst_dnd()
  106. log.push_back(msgEventAccepted(e));
  107. while (true) {
  108. position.ry() += 20;
  109. - if (position.y() >= 250) {
  110. + if (position.y() >= 250 && position.y() < 270) {
  111. QDropEvent e(position, Qt::CopyAction, &mimeData, Qt::LeftButton, Qt::NoModifier);
  112. qApp->sendEvent(window, &e);
  113. log.push_back(msgEventAccepted(e));
  114. - break;
  115. } else {
  116. QDragMoveEvent e(position, Qt::CopyAction, &mimeData, Qt::LeftButton, Qt::NoModifier);
  117. qApp->sendEvent(window, &e);
  118. log.push_back(msgEventAccepted(e));
  119. }
  120. + if (position.y() > 290)
  121. + break;
  122. }
  123. window = nativeWidget->windowHandle();
  124. @@ -628,6 +647,15 @@ void tst_QWidget_window::tst_dnd()
  125. for (int i= 0; i < expectedLogSize; ++i)
  126. expectedLog.push_back(QString::fromLatin1(expectedLogC[i]).replace(mimeDataAddressPlaceHolder, mimeDataAddress));
  127. + if (log.size() != expectedLog.size()) {
  128. + for (int i = 0; i < log.size() && i < expectedLog.size(); ++i)
  129. + QCOMPARE(log.at(i), expectedLog.at(i));
  130. + const int iMin = std::min(log.size(), expectedLog.size());
  131. + for (int i = iMin; i < log.size(); ++i)
  132. + qDebug() << "log[" << i << "]:" << log.at(i);
  133. + for (int i = iMin; i < expectedLog.size(); ++i)
  134. + qDebug() << "exp[" << i << "]:" << log.at(i);
  135. + }
  136. QCOMPARE(log, expectedLog);
  137. }
  138. --
  139. cgit v1.2.1