From 0a7e8350ae0a461d90619382c61e933eb0494be9 Mon Sep 17 00:00:00 2001 From: jian liang Date: Tue, 25 Sep 2012 21:33:55 +0800 Subject: [PATCH] Fix drag and drop with native widgets Task-number: QTBUG-27336 Don't check 'widget != m_widget' in QWidgetWindow::handleDragEnterMoveEvent() since the current window's parent widget may be the actual drop target. I replace it with a check '!widget->isWindow()' to prevent we pass through a top level window. I also change 'widget->mapFrom(m_widget, event->pos())' to 'widget->mapFromGlobal(m_widget->mapToGlobal(event->pos()))' since m_widget may not be widget's parent. Change-Id: Ia4f10f85ccdf1e27223ddc51afabd98b5d16f2fb Reviewed-by: Marc Mutz --- src/widgets/kernel/qwidgetwindow.cpp | 8 +++---- .../kernel/qwidget_window/tst_qwidget_window.cpp | 27 +++++++++++++++++++++- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index ad4b9c9..10ec4d3 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -443,13 +443,13 @@ void QWidgetWindow::handleDragEnterMoveEvent(QDragMoveEvent *event) QWidget *widget = m_widget->childAt(event->pos()); if (!widget) widget = m_widget; - for ( ; widget && widget != m_widget && !widget->acceptDrops(); widget = widget->parentWidget()) ; + for ( ; widget && !widget->isWindow() && !widget->acceptDrops(); widget = widget->parentWidget()) ; if (widget && !widget->acceptDrops()) widget = 0; // Target widget unchanged: DragMove if (widget && widget == m_dragTarget.data()) { Q_ASSERT(event->type() == QEvent::DragMove); - const QPoint mapped = widget->mapFrom(m_widget, event->pos()); + const QPoint mapped = widget->mapFromGlobal(m_widget->mapToGlobal(event->pos())); QDragMoveEvent translated(mapped, event->possibleActions(), event->mimeData(), event->mouseButtons(), event->keyboardModifiers()); translated.setDropAction(event->dropAction()); QGuiApplication::sendSpontaneousEvent(widget, &translated); @@ -472,7 +472,7 @@ void QWidgetWindow::handleDragEnterMoveEvent(QDragMoveEvent *event) return; } m_dragTarget = widget; - const QPoint mapped = widget->mapFrom(m_widget, event->pos()); + const QPoint mapped = widget->mapFromGlobal(m_widget->mapToGlobal(event->pos())); QDragEnterEvent translated(mapped, event->possibleActions(), event->mimeData(), event->mouseButtons(), event->keyboardModifiers()); QGuiApplication::sendSpontaneousEvent(widget, &translated); if (translated.isAccepted()) { @@ -492,7 +492,7 @@ void QWidgetWindow::handleDragLeaveEvent(QDragLeaveEvent *event) void QWidgetWindow::handleDropEvent(QDropEvent *event) { - const QPoint mapped = m_dragTarget.data()->mapFrom(m_widget, event->pos()); + const QPoint mapped = m_dragTarget.data()->mapFromGlobal(m_widget->mapToGlobal(event->pos())); QDropEvent translated(mapped, event->possibleActions(), event->mimeData(), event->mouseButtons(), event->keyboardModifiers()); QGuiApplication::sendSpontaneousEvent(m_dragTarget.data(), &translated); if (translated.isAccepted()) diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp index 65284bf..230fceb 100644 --- a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp +++ b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp @@ -409,7 +409,13 @@ static const char *expectedLogC[] = { "acceptingDropsWidget2::dragMoveEvent at 1,31 action=1 MIME_DATA_ADDRESS 'testmimetext'", "Event at 11,241 accepted", "acceptingDropsWidget2::dropEvent at 1,51 action=1 MIME_DATA_ADDRESS 'testmimetext'", - "Event at 11,261 accepted" + "Event at 11,261 accepted", + "acceptingDropsWidget1::dragEnterEvent at 10,10 action=1 MIME_DATA_ADDRESS 'testmimetext'", + "Event at 0,0 accepted", + "acceptingDropsWidget1::dragMoveEvent at 11,11 action=1 MIME_DATA_ADDRESS 'testmimetext'", + "Event at 1,1 accepted", + "acceptingDropsWidget1::dropEvent at 12,12 action=1 MIME_DATA_ADDRESS 'testmimetext'", + "Event at 2,2 accepted" }; // A widget that logs the DnD events it receives into a QStringList. @@ -497,6 +503,12 @@ void tst_QWidget_window::tst_dnd() dropsAcceptingWidget1->resize(180, 80); dropsAcceptingWidget1->move(10, 110); + // Create a native widget on top of dropsAcceptingWidget1 to check QTBUG-27336 + QWidget *nativeWidget = new QWidget(dropsAcceptingWidget1); + nativeWidget->resize(160, 60); + nativeWidget->move(10, 10); + nativeWidget->winId(); + QWidget *dropsAcceptingWidget2 = new DnDEventLoggerWidget(&log, &dndTestWidget); dropsAcceptingWidget2->setAcceptDrops(true); dropsAcceptingWidget2->setObjectName(QLatin1String("acceptingDropsWidget2")); @@ -535,6 +547,19 @@ void tst_QWidget_window::tst_dnd() } } + window = nativeWidget->windowHandle(); + QDragEnterEvent enterEvent(QPoint(0, 0), Qt::CopyAction, &mimeData, Qt::LeftButton, Qt::NoModifier); + qApp->sendEvent(window, &enterEvent); + log.push_back(msgEventAccepted(enterEvent)); + + QDragMoveEvent moveEvent(QPoint(1, 1), Qt::CopyAction, &mimeData, Qt::LeftButton, Qt::NoModifier); + qApp->sendEvent(window, &moveEvent); + log.push_back(msgEventAccepted(moveEvent)); + + QDropEvent dropEvent(QPoint(2, 2), Qt::CopyAction, &mimeData, Qt::LeftButton, Qt::NoModifier); + qApp->sendEvent(window, &dropEvent); + log.push_back(msgEventAccepted(dropEvent)); + // Compare logs. QStringList expectedLog; const int expectedLogSize = int(sizeof(expectedLogC) / sizeof(expectedLogC[0])); -- 2.7.4