From 762d49399089821d1d7f13cedaab74dfa68e3357 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 5 May 2015 13:11:12 +0200 Subject: [PATCH] cocoa: ensure app don't crash when receiving drag from other app MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change 939f21be53ef introduced a crash when dragging data from a 3rd party app into the app. Basically the current code assumed that we always have QCocoaIntegration::instance()->drag()->currentDrag() but this seems to only be the case if the drag was started by the app itself. The crash was found by testing the fridgemagnets example. Just drag text from other app into the example to see it crash. Also, refactored the cursor code into a separate method to simplify code reading. Change-Id: Ica611a4452a0dd02e01451111aeda14c879f8f1b Reviewed-by: Filipe Azevedo Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qnsview.mm | 71 ++++++++++++++------------ 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index cb8c6ec11a..ff6cd14bc7 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -1844,41 +1844,9 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin return NO; } -- (NSDragOperation)draggingEntered:(id )sender +- (void)updateCursorFromDragResponse:(QPlatformDragQtResponse)response drag:(QCocoaDrag *)drag { - return [self handleDrag : sender]; -} - -- (NSDragOperation)draggingUpdated:(id )sender -{ - return [self handleDrag : sender]; -} - -// Sends drag update to Qt, return the action -- (NSDragOperation)handleDrag:(id )sender -{ - NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil]; - QPoint qt_windowPoint(windowPoint.x, windowPoint.y); - Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]); - - QWindow *target = findEventTargetWindow(m_window); - if (!target) - return NSDragOperationNone; - - // 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(target, nativeDrag->platformDropData(), mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed); - } else { - QCocoaDropData mimeData([sender draggingPasteboard]); - response = QWindowSystemInterface::handleDrag(target, &mimeData, mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed); - } - - QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); - const QPixmap pixmapCursor = nativeDrag->currentDrag()->dragCursor(response.acceptedAction()); + const QPixmap pixmapCursor = drag->currentDrag()->dragCursor(response.acceptedAction()); NSCursor *nativeCursor = nil; if (pixmapCursor.isNull()) { @@ -1918,6 +1886,41 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin )); CGEventPost(kCGHIDEventTap, moveEvent); CFRelease(moveEvent); +} + +- (NSDragOperation)draggingEntered:(id )sender +{ + return [self handleDrag : sender]; +} + +- (NSDragOperation)draggingUpdated:(id )sender +{ + return [self handleDrag : sender]; +} + +// Sends drag update to Qt, return the action +- (NSDragOperation)handleDrag:(id )sender +{ + NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil]; + QPoint qt_windowPoint(windowPoint.x, windowPoint.y); + Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]); + + QWindow *target = findEventTargetWindow(m_window); + if (!target) + return NSDragOperationNone; + + // 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(target, nativeDrag->platformDropData(), mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed); + [self updateCursorFromDragResponse:response drag:nativeDrag]; + } else { + QCocoaDropData mimeData([sender draggingPasteboard]); + response = QWindowSystemInterface::handleDrag(target, &mimeData, mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed); + } return qt_mac_mapDropAction(response.acceptedAction()); }