From ce6101b6064a5e6b5c3193afc9b72c3f376ca09f Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Wed, 21 Oct 2015 22:16:40 +1300 Subject: [PATCH] bug 1216916 clean up when InvokeDragSession() fails r=roc --- widget/cocoa/nsDragService.h | 6 ++++-- widget/cocoa/nsDragService.mm | 14 +++++--------- widget/gtk/nsDragService.cpp | 15 +++++++++++---- widget/gtk/nsDragService.h | 4 ++++ widget/nsBaseDragService.cpp | 10 +++++++++- widget/nsBaseDragService.h | 9 +++++++++ widget/nsDragServiceProxy.cpp | 19 +++++-------------- widget/nsDragServiceProxy.h | 9 ++++----- widget/windows/nsDragService.cpp | 23 ++++++++--------------- widget/windows/nsDragService.h | 9 ++++----- 10 files changed, 63 insertions(+), 55 deletions(-) diff --git a/widget/cocoa/nsDragService.h b/widget/cocoa/nsDragService.h index afc4d98b370..2ad0e4fbefa 100644 --- a/widget/cocoa/nsDragService.h +++ b/widget/cocoa/nsDragService.h @@ -30,9 +30,11 @@ class nsDragService : public nsBaseDragService public: nsDragService(); + // nsBaseDragService + virtual nsresult InvokeDragSessionImpl(nsISupportsArray* anArrayTransferables, + nsIScriptableRegion* aRegion, + uint32_t aActionType); // nsIDragService - NS_IMETHOD InvokeDragSession(nsIDOMNode *aDOMNode, nsISupportsArray * anArrayTransferables, - nsIScriptableRegion * aRegion, uint32_t aActionType); NS_IMETHOD EndDragSession(bool aDoneDrag); // nsIDragSession diff --git a/widget/cocoa/nsDragService.mm b/widget/cocoa/nsDragService.mm index 6b42f34ed7f..fb52074f1f3 100644 --- a/widget/cocoa/nsDragService.mm +++ b/widget/cocoa/nsDragService.mm @@ -273,17 +273,13 @@ nsDragService::ConstructDragImage(nsIDOMNode* aDOMNode, // 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. -NS_IMETHODIMP -nsDragService::InvokeDragSession(nsIDOMNode* aDOMNode, nsISupportsArray* aTransferableArray, - nsIScriptableRegion* aDragRgn, uint32_t aActionType) +nsresult +nsDragService::InvokeDragSessionImpl(nsISupportsArray* aTransferableArray, + nsIScriptableRegion* aDragRgn, + uint32_t aActionType) { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; - nsresult rv = nsBaseDragService::InvokeDragSession(aDOMNode, - aTransferableArray, - aDragRgn, aActionType); - NS_ENSURE_SUCCESS(rv, rv); - mDataItems = aTransferableArray; // put data on the clipboard @@ -291,7 +287,7 @@ nsDragService::InvokeDragSession(nsIDOMNode* aDOMNode, nsISupportsArray* aTransf return NS_ERROR_FAILURE; nsIntRect dragRect(0, 0, 20, 20); - NSImage* image = ConstructDragImage(aDOMNode, &dragRect, aDragRgn); + NSImage* image = ConstructDragImage(mSourceNode, &dragRect, aDragRgn); if (!image) { // if no image was returned, just draw a rectangle NSSize size; diff --git a/widget/gtk/nsDragService.cpp b/widget/gtk/nsDragService.cpp index ff22974c2d2..82756370449 100644 --- a/widget/gtk/nsDragService.cpp +++ b/widget/gtk/nsDragService.cpp @@ -312,11 +312,16 @@ nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, if (mSourceNode) return NS_ERROR_NOT_AVAILABLE; - nsresult rv = nsBaseDragService::InvokeDragSession(aDOMNode, - aArrayTransferables, - aRegion, aActionType); - NS_ENSURE_SUCCESS(rv, rv); + return nsBaseDragService::InvokeDragSession(aDOMNode, aArrayTransferables, + aRegion, aActionType); +} +// nsBaseDragService +nsresult +nsDragService::InvokeDragSessionImpl(nsISupportsArray* aArrayTransferables, + nsIScriptableRegion* aRegion, + uint32_t aActionType) +{ // make sure that we have an array of transferables to use if (!aArrayTransferables) return NS_ERROR_INVALID_ARG; @@ -377,6 +382,7 @@ nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, mSourceRegion = nullptr; + nsresult rv; if (context) { StartDragSession(); @@ -391,6 +397,7 @@ nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, } // We don't have a drag end point yet. mEndDragPoint = nsIntPoint(-1, -1); + rv = NS_OK; } else { rv = NS_ERROR_FAILURE; diff --git a/widget/gtk/nsDragService.h b/widget/gtk/nsDragService.h index d7247210735..162986f0984 100644 --- a/widget/gtk/nsDragService.h +++ b/widget/gtk/nsDragService.h @@ -58,6 +58,10 @@ public: NS_DECL_NSIOBSERVER + // nsBaseDragService + virtual nsresult InvokeDragSessionImpl(nsISupportsArray* anArrayTransferables, + nsIScriptableRegion* aRegion, + uint32_t aActionType) override; // nsIDragService NS_IMETHOD InvokeDragSession (nsIDOMNode *aDOMNode, nsISupportsArray * anArrayTransferables, diff --git a/widget/nsBaseDragService.cpp b/widget/nsBaseDragService.cpp index 497b6fa0f47..85c6ef05816 100644 --- a/widget/nsBaseDragService.cpp +++ b/widget/nsBaseDragService.cpp @@ -225,7 +225,15 @@ nsBaseDragService::InvokeDragSession(nsIDOMNode *aDOMNode, // are in the wrong coord system, so turn off mouse capture. nsIPresShell::ClearMouseCapture(nullptr); - return NS_OK; + nsresult rv = InvokeDragSessionImpl(aTransferableArray, + aDragRgn, aActionType); + + if (NS_FAILED(rv)) { + mSourceNode = nullptr; + mSourceDocument = nullptr; + } + + return rv; } NS_IMETHODIMP diff --git a/widget/nsBaseDragService.h b/widget/nsBaseDragService.h index 24b1a72b29c..0502869b588 100644 --- a/widget/nsBaseDragService.h +++ b/widget/nsBaseDragService.h @@ -63,6 +63,15 @@ public: protected: virtual ~nsBaseDragService(); + /** + * Called from nsBaseDragService to initiate a platform drag from a source + * in this process. This is expected to ensure that StartDragSession() and + * EndDragSession() get called if the platform drag is successfully invoked. + */ + virtual nsresult InvokeDragSessionImpl(nsISupportsArray* aTransferableArray, + nsIScriptableRegion* aDragRgn, + uint32_t aActionType) = 0; + /** * Draw the drag image, if any, to a surface and return it. The drag image * is constructed from mImage if specified, or aDOMNode if mImage is null. diff --git a/widget/nsDragServiceProxy.cpp b/widget/nsDragServiceProxy.cpp index 86bc1c8354f..6f6ea2b9a42 100644 --- a/widget/nsDragServiceProxy.cpp +++ b/widget/nsDragServiceProxy.cpp @@ -23,21 +23,12 @@ nsDragServiceProxy::~nsDragServiceProxy() { } -NS_IMETHODIMP -nsDragServiceProxy::InvokeDragSession(nsIDOMNode* aDOMNode, - nsISupportsArray* aArrayTransferables, - nsIScriptableRegion* aRegion, - uint32_t aActionType) +nsresult +nsDragServiceProxy::InvokeDragSessionImpl(nsISupportsArray* aArrayTransferables, + nsIScriptableRegion* aRegion, + uint32_t aActionType) { - nsresult rv = nsBaseDragService::InvokeDragSession(aDOMNode, - aArrayTransferables, - aRegion, - aActionType); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr sourceDocument; - aDOMNode->GetOwnerDocument(getter_AddRefs(sourceDocument)); - nsCOMPtr doc = do_QueryInterface(sourceDocument); + nsCOMPtr doc = do_QueryInterface(mSourceDocument); NS_ENSURE_STATE(doc->GetDocShell()); mozilla::dom::TabChild* child = mozilla::dom::TabChild::GetFrom(doc->GetDocShell()); diff --git a/widget/nsDragServiceProxy.h b/widget/nsDragServiceProxy.h index 8fe35aa0fcb..bbfaade14db 100644 --- a/widget/nsDragServiceProxy.h +++ b/widget/nsDragServiceProxy.h @@ -15,11 +15,10 @@ public: NS_DECL_ISUPPORTS_INHERITED - // nsIDragService - NS_IMETHOD InvokeDragSession(nsIDOMNode* aDOMNode, - nsISupportsArray* anArrayTransferables, - nsIScriptableRegion* aRegion, - uint32_t aActionType) override; + // nsBaseDragService + virtual nsresult InvokeDragSessionImpl(nsISupportsArray* anArrayTransferables, + nsIScriptableRegion* aRegion, + uint32_t aActionType) override; private: virtual ~nsDragServiceProxy(); }; diff --git a/widget/windows/nsDragService.cpp b/widget/windows/nsDragService.cpp index e090b5766c5..6d4a30988f1 100644 --- a/widget/windows/nsDragService.cpp +++ b/widget/windows/nsDragService.cpp @@ -170,18 +170,11 @@ nsDragService::CreateDragImage(nsIDOMNode *aDOMNode, } //------------------------------------------------------------------------- -NS_IMETHODIMP -nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, - nsISupportsArray *anArrayTransferables, - nsIScriptableRegion *aRegion, - uint32_t aActionType) +nsresult +nsDragService::InvokeDragSessionImpl(nsISupportsArray* anArrayTransferables, + nsIScriptableRegion* aRegion, + uint32_t aActionType) { - nsresult rv = nsBaseDragService::InvokeDragSession(aDOMNode, - anArrayTransferables, - aRegion, - aActionType); - NS_ENSURE_SUCCESS(rv, rv); - // Try and get source URI of the items that are being dragged nsIURI *uri = nullptr; @@ -191,7 +184,7 @@ nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, } uint32_t numItemsToDrag = 0; - rv = anArrayTransferables->Count(&numItemsToDrag); + nsresult rv = anArrayTransferables->Count(&numItemsToDrag); if (!numItemsToDrag) return NS_ERROR_FAILURE; @@ -214,7 +207,7 @@ nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, nsCOMPtr trans(do_QueryInterface(supports)); if (trans) { // set the requestingNode on the transferable - trans->SetRequestingNode(aDOMNode); + trans->SetRequestingNode(mSourceNode); RefPtr dataObj; rv = nsClipboard::CreateNativeDataObject(trans, getter_AddRefs(dataObj), uri); @@ -233,7 +226,7 @@ nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, nsCOMPtr trans(do_QueryInterface(supports)); if (trans) { // set the requestingNode on the transferable - trans->SetRequestingNode(aDOMNode); + trans->SetRequestingNode(mSourceNode); rv = nsClipboard::CreateNativeDataObject(trans, getter_AddRefs(itemToDrag), uri); @@ -247,7 +240,7 @@ nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, CLSCTX_INPROC_SERVER, IID_IDragSourceHelper, (void**)&pdsh))) { SHDRAGIMAGE sdi; - if (CreateDragImage(aDOMNode, aRegion, &sdi)) { + if (CreateDragImage(mSourceNode, aRegion, &sdi)) { if (FAILED(pdsh->InitializeFromBitmap(&sdi, itemToDrag))) DeleteObject(sdi.hbmpDragImage); } diff --git a/widget/windows/nsDragService.h b/widget/windows/nsDragService.h index eb165da6e9d..9228e72047a 100644 --- a/widget/windows/nsDragService.h +++ b/widget/windows/nsDragService.h @@ -23,11 +23,10 @@ public: nsDragService(); virtual ~nsDragService(); - // nsIDragService - NS_IMETHOD InvokeDragSession(nsIDOMNode *aDOMNode, - nsISupportsArray *anArrayTransferables, - nsIScriptableRegion *aRegion, - uint32_t aActionType); + // nsBaseDragService + virtual nsresult InvokeDragSessionImpl(nsISupportsArray* anArrayTransferables, + nsIScriptableRegion* aRegion, + uint32_t aActionType); // nsIDragSession NS_IMETHOD GetData(nsITransferable * aTransferable, uint32_t anItem);