Cocoa: Fix DnD when using native widgets.
Adding a native widget such as QGLWidget often causes other widgets to become native, through native ancestor and sibling propagation. This includes QFocusFrame, which typically sits on top of item views. QFocusFrame is mostly transparent (except for the frame) and also has the WA_TransparentForMouseEvents flag set. Its window has the corresponding WindowTransparentForInput flag set. Cocoa does not know about WindowTransparentForInput. Forward the drag calls to the correct window. Task-number: QTBUG-37077 Change-Id: I02201c7027915b1e82d0cd7e9c2e787ca6b2338b Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com>
This commit is contained in:
parent
1a6011e09f
commit
000693018b
@ -1648,6 +1648,21 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
|
||||
}
|
||||
}
|
||||
|
||||
static QWindow *findEventTargetWindow(QWindow *candidate)
|
||||
{
|
||||
while (candidate) {
|
||||
if (!(candidate->flags() & Qt::WindowTransparentForInput))
|
||||
return candidate;
|
||||
candidate = candidate->parent();
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint point)
|
||||
{
|
||||
return target->mapFromGlobal(source->mapToGlobal(point));
|
||||
}
|
||||
|
||||
- (NSDragOperation) draggingSourceOperationMaskForLocal:(BOOL)isLocal
|
||||
{
|
||||
Q_UNUSED(isLocal);
|
||||
@ -1677,16 +1692,18 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
|
||||
QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
|
||||
Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]);
|
||||
|
||||
QWindow *target = findEventTargetWindow(m_window);
|
||||
|
||||
// update these so selecting move/copy/link works
|
||||
QGuiApplicationPrivate::modifier_buttons = [QNSView convertKeyModifiers: [[NSApp currentEvent] modifierFlags]];
|
||||
|
||||
QPlatformDragQtResponse response(false, Qt::IgnoreAction, QRect());
|
||||
if ([sender draggingSource] != nil) {
|
||||
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
|
||||
response = QWindowSystemInterface::handleDrag(m_window, nativeDrag->platformDropData(), qt_windowPoint, qtAllowed);
|
||||
response = QWindowSystemInterface::handleDrag(target, nativeDrag->platformDropData(), mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed);
|
||||
} else {
|
||||
QCocoaDropData mimeData([sender draggingPasteboard]);
|
||||
response = QWindowSystemInterface::handleDrag(m_window, &mimeData, qt_windowPoint, qtAllowed);
|
||||
response = QWindowSystemInterface::handleDrag(target, &mimeData, mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed);
|
||||
}
|
||||
|
||||
return qt_mac_mapDropAction(response.acceptedAction());
|
||||
@ -1694,16 +1711,20 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
|
||||
|
||||
- (void)draggingExited:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
QWindow *target = findEventTargetWindow(m_window);
|
||||
|
||||
NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil];
|
||||
QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
|
||||
|
||||
// Send 0 mime data to indicate drag exit
|
||||
QWindowSystemInterface::handleDrag(m_window, 0 ,qt_windowPoint, Qt::IgnoreAction);
|
||||
QWindowSystemInterface::handleDrag(target, 0, mapWindowCoordinates(m_window, target, qt_windowPoint), Qt::IgnoreAction);
|
||||
}
|
||||
|
||||
// called on drop, send the drop to Qt and return if it was accepted.
|
||||
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
QWindow *target = findEventTargetWindow(m_window);
|
||||
|
||||
NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil];
|
||||
QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
|
||||
Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]);
|
||||
@ -1711,10 +1732,10 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
|
||||
QPlatformDropQtResponse response(false, Qt::IgnoreAction);
|
||||
if ([sender draggingSource] != nil) {
|
||||
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
|
||||
response = QWindowSystemInterface::handleDrop(m_window, nativeDrag->platformDropData(), qt_windowPoint, qtAllowed);
|
||||
response = QWindowSystemInterface::handleDrop(target, nativeDrag->platformDropData(), mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed);
|
||||
} else {
|
||||
QCocoaDropData mimeData([sender draggingPasteboard]);
|
||||
response = QWindowSystemInterface::handleDrop(m_window, &mimeData, qt_windowPoint, qtAllowed);
|
||||
response = QWindowSystemInterface::handleDrop(target, &mimeData, mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed);
|
||||
}
|
||||
if (response.isAccepted()) {
|
||||
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
|
||||
@ -1727,6 +1748,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
|
||||
{
|
||||
Q_UNUSED(img);
|
||||
Q_UNUSED(operation);
|
||||
QWindow *target = findEventTargetWindow(m_window);
|
||||
|
||||
// keep our state, and QGuiApplication state (buttons member) in-sync,
|
||||
// or future mouse events will be processed incorrectly
|
||||
@ -1739,7 +1761,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
|
||||
NSPoint screenPoint = [window convertBaseToScreen :point];
|
||||
QPoint qtScreenPoint = QPoint(screenPoint.x, qt_mac_flipYCoordinate(screenPoint.y));
|
||||
|
||||
QWindowSystemInterface::handleMouseEvent(m_window, qtWindowPoint, qtScreenPoint, m_buttons);
|
||||
QWindowSystemInterface::handleMouseEvent(target, mapWindowCoordinates(m_window, target, qtWindowPoint), qtScreenPoint, m_buttons);
|
||||
}
|
||||
|
||||
@end
|
||||
|
Loading…
Reference in New Issue
Block a user