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 <marc.mutz@kdab.com>
This commit is contained in:
parent
f9547c89ea
commit
0a7e8350ae
@ -443,13 +443,13 @@ void QWidgetWindow::handleDragEnterMoveEvent(QDragMoveEvent *event)
|
|||||||
QWidget *widget = m_widget->childAt(event->pos());
|
QWidget *widget = m_widget->childAt(event->pos());
|
||||||
if (!widget)
|
if (!widget)
|
||||||
widget = m_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())
|
if (widget && !widget->acceptDrops())
|
||||||
widget = 0;
|
widget = 0;
|
||||||
// Target widget unchanged: DragMove
|
// Target widget unchanged: DragMove
|
||||||
if (widget && widget == m_dragTarget.data()) {
|
if (widget && widget == m_dragTarget.data()) {
|
||||||
Q_ASSERT(event->type() == QEvent::DragMove);
|
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());
|
QDragMoveEvent translated(mapped, event->possibleActions(), event->mimeData(), event->mouseButtons(), event->keyboardModifiers());
|
||||||
translated.setDropAction(event->dropAction());
|
translated.setDropAction(event->dropAction());
|
||||||
QGuiApplication::sendSpontaneousEvent(widget, &translated);
|
QGuiApplication::sendSpontaneousEvent(widget, &translated);
|
||||||
@ -472,7 +472,7 @@ void QWidgetWindow::handleDragEnterMoveEvent(QDragMoveEvent *event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_dragTarget = widget;
|
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());
|
QDragEnterEvent translated(mapped, event->possibleActions(), event->mimeData(), event->mouseButtons(), event->keyboardModifiers());
|
||||||
QGuiApplication::sendSpontaneousEvent(widget, &translated);
|
QGuiApplication::sendSpontaneousEvent(widget, &translated);
|
||||||
if (translated.isAccepted()) {
|
if (translated.isAccepted()) {
|
||||||
@ -492,7 +492,7 @@ void QWidgetWindow::handleDragLeaveEvent(QDragLeaveEvent *event)
|
|||||||
|
|
||||||
void QWidgetWindow::handleDropEvent(QDropEvent *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());
|
QDropEvent translated(mapped, event->possibleActions(), event->mimeData(), event->mouseButtons(), event->keyboardModifiers());
|
||||||
QGuiApplication::sendSpontaneousEvent(m_dragTarget.data(), &translated);
|
QGuiApplication::sendSpontaneousEvent(m_dragTarget.data(), &translated);
|
||||||
if (translated.isAccepted())
|
if (translated.isAccepted())
|
||||||
|
@ -409,7 +409,13 @@ static const char *expectedLogC[] = {
|
|||||||
"acceptingDropsWidget2::dragMoveEvent at 1,31 action=1 MIME_DATA_ADDRESS 'testmimetext'",
|
"acceptingDropsWidget2::dragMoveEvent at 1,31 action=1 MIME_DATA_ADDRESS 'testmimetext'",
|
||||||
"Event at 11,241 accepted",
|
"Event at 11,241 accepted",
|
||||||
"acceptingDropsWidget2::dropEvent at 1,51 action=1 MIME_DATA_ADDRESS 'testmimetext'",
|
"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.
|
// 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->resize(180, 80);
|
||||||
dropsAcceptingWidget1->move(10, 110);
|
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);
|
QWidget *dropsAcceptingWidget2 = new DnDEventLoggerWidget(&log, &dndTestWidget);
|
||||||
dropsAcceptingWidget2->setAcceptDrops(true);
|
dropsAcceptingWidget2->setAcceptDrops(true);
|
||||||
dropsAcceptingWidget2->setObjectName(QLatin1String("acceptingDropsWidget2"));
|
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.
|
// Compare logs.
|
||||||
QStringList expectedLog;
|
QStringList expectedLog;
|
||||||
const int expectedLogSize = int(sizeof(expectedLogC) / sizeof(expectedLogC[0]));
|
const int expectedLogSize = int(sizeof(expectedLogC) / sizeof(expectedLogC[0]));
|
||||||
|
Loading…
Reference in New Issue
Block a user