cocoa: ensure app don't crash when receiving drag from other app

Change 939f21be53 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 <filipe.azevedo@kdab.com>
Reviewed-by: Morten Johan Sørvig <morten.sorvig@theqtcompany.com>
This commit is contained in:
Richard Moe Gustavsen 2015-05-05 13:11:12 +02:00 committed by Morten Johan Sørvig
parent f1687148af
commit 762d493990

View File

@ -1844,41 +1844,9 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
return NO;
}
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
- (void)updateCursorFromDragResponse:(QPlatformDragQtResponse)response drag:(QCocoaDrag *)drag
{
return [self handleDrag : sender];
}
- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
{
return [self handleDrag : sender];
}
// Sends drag update to Qt, return the action
- (NSDragOperation)handleDrag:(id <NSDraggingInfo>)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 <NSDraggingInfo>)sender
{
return [self handleDrag : sender];
}
- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
{
return [self handleDrag : sender];
}
// Sends drag update to Qt, return the action
- (NSDragOperation)handleDrag:(id <NSDraggingInfo>)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());
}