author | Stephen A Pohl <spohl.mozilla.bugs@gmail.com> |
Wed, 15 Feb 2017 18:46:02 -0500 | |
changeset 343225 | f5d3690285980b574bd87d2b1bfbd81de5964a57 |
parent 343224 | 492fa407d12ca8ef6adf35051cee7356d75ac2c1 |
child 343226 | 0b83dd97c786bfc2641d1733e278faa35475d09c |
push id | 31372 |
push user | cbook@mozilla.com |
push date | Thu, 16 Feb 2017 12:16:10 +0000 |
treeherder | mozilla-central@2737f66ad6ac [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mstange |
bugs | 1329997 |
milestone | 54.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/widget/cocoa/nsDragService.mm +++ b/widget/cocoa/nsDragService.mm @@ -272,34 +272,39 @@ nsDragService::GetFilePath(NSPasteboardI } } return nil; NS_OBJC_END_TRY_ABORT_BLOCK_NIL; } -// We can only invoke NSView's 'dragImage:at:offset:event:pasteboard:source:slideBack:' from -// within NSView's 'mouseDown:' or 'mouseDragged:'. Luckily 'mouseDragged' is always on the -// stack when InvokeDragSession gets called. nsresult nsDragService::InvokeDragSessionImpl(nsIArray* aTransferableArray, nsIScriptableRegion* aDragRgn, uint32_t aActionType) { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; + if (!gLastDragView) { + // gLastDragView is only set during -[ChildView mouseDragged:]. + // InvokeDragSessionImpl is only called while Gecko processes a mouse move + // event. So if we get here with gLastDragView being null, that means that + // the mouse button has already been released, and mouseMoved is on the + // stack instead of mouseDragged. In that case we need to abort the drag + // because the OS won't know where to drop whatever's being dragged, and we + // might end up with a stuck drag & drop session. + return NS_ERROR_FAILURE; + } + mDataItems = aTransferableArray; // Save the transferables away in case a promised file callback is invoked. gDraggedTransferables = aTransferableArray; - nsBaseDragService::StartDragSession(); - nsBaseDragService::OpenDragPopup(); - // We need to retain the view and the event during the drag in case either // gets destroyed. mNativeDragView = [gLastDragView retain]; mNativeDragEvent = [gLastDragMouseDownEvent retain]; gUserCancelledDrag = false; NSPasteboardItem* pbItem = [NSPasteboardItem new]; @@ -340,16 +345,19 @@ nsDragService::InvokeDragSessionImpl(nsI localDragRect.origin.x = draggingPoint.x; localDragRect.origin.y = draggingPoint.y - localDragRect.size.height; NSDraggingItem* dragItem = [[NSDraggingItem alloc] initWithPasteboardWriter:pbItem]; [pbItem release]; [dragItem setDraggingFrame:localDragRect contents:image]; + nsBaseDragService::StartDragSession(); + nsBaseDragService::OpenDragPopup(); + NSDraggingSession* draggingSession = [mNativeDragView beginDraggingSessionWithItems: [NSArray arrayWithObject:[dragItem autorelease]] event:mNativeDragEvent source:mNativeDragView]; draggingSession.animatesToStartingPositionsOnCancelOrFail = YES; return NS_OK;