summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorten Johan Sørvig <morten.sorvig@digia.com>2014-02-26 12:33:29 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-04-09 20:53:06 +0200
commit000693018b50414b2cd46830b15073e5c8eefe2c (patch)
tree101e585fd58f44c8d8333e16b49b2d75b7036b87
parent1a6011e09f6378e177426d5b1bb783419faea02a (diff)
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>
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm34
1 files changed, 28 insertions, 6 deletions
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index e17cd0a4cc..83a1f08973 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -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