Bug 1893119: Part 21 - Separate nsIDragService and nsIDragSession implementations r=gstoll,geckoview-reviewers,rkraesig,win-reviewers,m_kato
Split the class inheritance trees for nsIDragService and nsIDragSession. Remember that, before the start of this patch series, the inheritance diagram was: nsDragService -> nsBaseDragService -> nsIDragService + nsIDragSession and the only instance was a singleton. We switched it to: nsDragService -> nsDragSession -> nsBaseDragService -> nsIDragService + nsBaseDragSession -> nsIDragSession and maintained the singleton. This allowed us to allow us to move things to the new classes without breaking behavior. We are done with that, so we can now change the inheritance to its final form: nsDragService -> nsBaseDragService -> nsIDragService nsDragSession -> nsBaseDragSession -> nsIDragSession Of course, we also need to properly construct and release the nsIDragSessions (formerly part of the singleton), so that is done here as well. That happens in nsBaseDrag[Service|Session] for parent process drags and in nsDrag[Service|Session]Proxy for content. This is all fairly straightforward, except in the case of gtk, where we need to change some callback behavior. Differential Revision: https://phabricator.services.mozilla.com/D211084
This commit is contained in:
@@ -84,6 +84,7 @@
|
|||||||
#include "nsDeviceContext.h"
|
#include "nsDeviceContext.h"
|
||||||
#include "nsDocShell.h"
|
#include "nsDocShell.h"
|
||||||
#include "nsDocShellLoadState.h"
|
#include "nsDocShellLoadState.h"
|
||||||
|
#include "nsDragServiceProxy.h"
|
||||||
#include "nsExceptionHandler.h"
|
#include "nsExceptionHandler.h"
|
||||||
#include "nsFilePickerProxy.h"
|
#include "nsFilePickerProxy.h"
|
||||||
#include "nsFocusManager.h"
|
#include "nsFocusManager.h"
|
||||||
@@ -502,6 +503,7 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(BrowserChild)
|
|||||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||||
|
|
||||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BrowserChild)
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BrowserChild)
|
||||||
|
NS_INTERFACE_MAP_ENTRY_CONCRETE(BrowserChild)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
|
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
|
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIWindowProvider)
|
NS_INTERFACE_MAP_ENTRY(nsIWindowProvider)
|
||||||
@@ -1919,6 +1921,15 @@ mozilla::ipc::IPCResult BrowserChild::RecvRealDragEvent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
DispatchWidgetEventViaAPZ(localEvent);
|
DispatchWidgetEventViaAPZ(localEvent);
|
||||||
|
|
||||||
|
if (aEvent.mMessage == eDragLeave ||
|
||||||
|
aEvent.mMessage == eDragExit) {
|
||||||
|
// If session is still active, remove its target.
|
||||||
|
dragSession = GetDragSession();
|
||||||
|
if (dragSession) {
|
||||||
|
static_cast<nsDragSessionProxy*>(dragSession.get())->SetDragTarget(nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1971,7 +1982,7 @@ mozilla::ipc::IPCResult BrowserChild::RecvInvokeChildDragSession(
|
|||||||
do_GetService("@mozilla.org/widget/dragservice;1")) {
|
do_GetService("@mozilla.org/widget/dragservice;1")) {
|
||||||
nsIWidget* widget = WebWidget();
|
nsIWidget* widget = WebWidget();
|
||||||
dragService->StartDragSession(widget);
|
dragService->StartDragSession(widget);
|
||||||
if (RefPtr<nsIDragSession> session = nsContentUtils::GetDragSession(widget)) {
|
if (RefPtr<nsIDragSession> session = GetDragSession()) {
|
||||||
session->SetSourceWindowContext(aSourceWindowContext.GetMaybeDiscarded());
|
session->SetSourceWindowContext(aSourceWindowContext.GetMaybeDiscarded());
|
||||||
session->SetSourceTopWindowContext(
|
session->SetSourceTopWindowContext(
|
||||||
aSourceTopWindowContext.GetMaybeDiscarded());
|
aSourceTopWindowContext.GetMaybeDiscarded());
|
||||||
@@ -3889,9 +3900,11 @@ BrowserChild::ContentTransformsReceived(JSContext* aCx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsIDragSession> BrowserChild::GetDragSession() {
|
already_AddRefed<nsIDragSession> BrowserChild::GetDragSession() {
|
||||||
RefPtr<nsIDragSession> session =
|
return RefPtr(mDragSession).forget();
|
||||||
nsContentUtils::GetDragSession(mPuppetWidget);
|
}
|
||||||
return session.forget();
|
|
||||||
|
void BrowserChild::SetDragSession(nsIDragSession* aSession) {
|
||||||
|
mDragSession = aSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
BrowserChildMessageManager::BrowserChildMessageManager(
|
BrowserChildMessageManager::BrowserChildMessageManager(
|
||||||
|
|||||||
@@ -85,6 +85,13 @@ class SessionStoreChild;
|
|||||||
class RequestData;
|
class RequestData;
|
||||||
class WebProgressData;
|
class WebProgressData;
|
||||||
|
|
||||||
|
#define DOM_BROWSERCHILD_IID \
|
||||||
|
{ \
|
||||||
|
0x58a5775d, 0xba05, 0x45bf, { \
|
||||||
|
0xbd, 0xb8, 0xd7, 0x61, 0xf9, 0x01, 0x01, 0x31 \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
class BrowserChildMessageManager : public ContentFrameMessageManager,
|
class BrowserChildMessageManager : public ContentFrameMessageManager,
|
||||||
public nsIMessageSender,
|
public nsIMessageSender,
|
||||||
public nsSupportsWeakReference {
|
public nsSupportsWeakReference {
|
||||||
@@ -181,6 +188,7 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
|||||||
return mUniqueId;
|
return mUniqueId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_DECLARE_STATIC_IID_ACCESSOR(DOM_BROWSERCHILD_IID)
|
||||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
NS_DECL_NSIWEBBROWSERCHROME
|
NS_DECL_NSIWEBBROWSERCHROME
|
||||||
NS_DECL_NSIINTERFACEREQUESTOR
|
NS_DECL_NSIINTERFACEREQUESTOR
|
||||||
@@ -658,6 +666,7 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
|||||||
const Maybe<bool> aCanvasFingerprinterKnownText);
|
const Maybe<bool> aCanvasFingerprinterKnownText);
|
||||||
|
|
||||||
already_AddRefed<nsIDragSession> GetDragSession();
|
already_AddRefed<nsIDragSession> GetDragSession();
|
||||||
|
void SetDragSession(nsIDragSession* aSession);
|
||||||
|
|
||||||
mozilla::ipc::IPCResult RecvInvokeChildDragSession(
|
mozilla::ipc::IPCResult RecvInvokeChildDragSession(
|
||||||
const MaybeDiscarded<WindowContext>& aSourceWindowContext,
|
const MaybeDiscarded<WindowContext>& aSourceWindowContext,
|
||||||
@@ -777,6 +786,8 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
|||||||
RefPtr<ContentChild> mManager;
|
RefPtr<ContentChild> mManager;
|
||||||
RefPtr<BrowsingContext> mBrowsingContext;
|
RefPtr<BrowsingContext> mBrowsingContext;
|
||||||
RefPtr<nsBrowserStatusFilter> mStatusFilter;
|
RefPtr<nsBrowserStatusFilter> mStatusFilter;
|
||||||
|
RefPtr<nsIDragSession> mDragSession;
|
||||||
|
|
||||||
Maybe<CodeNameIndex> mPreviousConsumedKeyDownCode;
|
Maybe<CodeNameIndex> mPreviousConsumedKeyDownCode;
|
||||||
uint32_t mChromeFlags;
|
uint32_t mChromeFlags;
|
||||||
uint32_t mMaxTouchPoints;
|
uint32_t mMaxTouchPoints;
|
||||||
@@ -879,6 +890,8 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
|||||||
DISALLOW_EVIL_CONSTRUCTORS(BrowserChild);
|
DISALLOW_EVIL_CONSTRUCTORS(BrowserChild);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NS_DEFINE_STATIC_IID_ACCESSOR(BrowserChild, DOM_BROWSERCHILD_IID)
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ namespace mozilla::test {
|
|||||||
|
|
||||||
NS_IMPL_ISUPPORTS(MockDragServiceController, nsIMockDragServiceController)
|
NS_IMPL_ISUPPORTS(MockDragServiceController, nsIMockDragServiceController)
|
||||||
|
|
||||||
class MockDragService : public nsBaseDragService {
|
class MockDragSession : public nsBaseDragSession {
|
||||||
public:
|
protected:
|
||||||
MOZ_CAN_RUN_SCRIPT nsresult
|
MOZ_CAN_RUN_SCRIPT nsresult
|
||||||
InvokeDragSessionImpl(nsIWidget* aWidget, nsIArray* aTransferableArray,
|
InvokeDragSessionImpl(nsIWidget* aWidget, nsIArray* aTransferableArray,
|
||||||
const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
|
const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
|
||||||
@@ -50,12 +50,24 @@ class MockDragService : public nsBaseDragService {
|
|||||||
// Note that, like in non-mocked DND, we do this regardless of whether
|
// Note that, like in non-mocked DND, we do this regardless of whether
|
||||||
// the source and target were the same widget -- in that case,
|
// the source and target were the same widget -- in that case,
|
||||||
// EndDragSession is just called twice.
|
// EndDragSession is just called twice.
|
||||||
mDragAction = DRAGDROP_ACTION_MOVE;
|
mDragAction = nsIDragService::DRAGDROP_ACTION_MOVE;
|
||||||
StartDragSession(aWidget);
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
bool IsMockService() override { return true; }
|
class MockDragService : public nsBaseDragService {
|
||||||
|
public:
|
||||||
|
NS_IMETHOD GetIsMockService(bool* aRet) override {
|
||||||
|
*aRet = true;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
uint32_t mLastModifierKeyState = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
already_AddRefed<nsIDragSession> CreateDragSession() override {
|
||||||
|
RefPtr<nsIDragSession> session = new MockDragSession();
|
||||||
|
return session.forget();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void SetDragEndPointFromScreenPoint(
|
static void SetDragEndPointFromScreenPoint(
|
||||||
|
|||||||
@@ -20,9 +20,6 @@
|
|||||||
#include "nsViewManager.h"
|
#include "nsViewManager.h"
|
||||||
#include "nsWindow.h"
|
#include "nsWindow.h"
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS_INHERITED0(nsDragSession, nsBaseDragService)
|
|
||||||
NS_IMPL_ISUPPORTS_INHERITED0(nsDragService, nsDragSession)
|
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::widget;
|
using namespace mozilla::widget;
|
||||||
|
|
||||||
@@ -39,6 +36,11 @@ already_AddRefed<nsDragService> nsDragService::GetInstance() {
|
|||||||
return service.forget();
|
return service.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<nsIDragSession> nsDragService::CreateDragSession() {
|
||||||
|
RefPtr<nsDragSession> session = new nsDragSession();
|
||||||
|
return session.forget();
|
||||||
|
}
|
||||||
|
|
||||||
static nsWindow* GetWindow(dom::Document* aDocument) {
|
static nsWindow* GetWindow(dom::Document* aDocument) {
|
||||||
if (!aDocument) {
|
if (!aDocument) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -63,7 +65,7 @@ static nsWindow* GetWindow(dom::Document* aDocument) {
|
|||||||
return window.get();
|
return window.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult nsDragService::InvokeDragSessionImpl(
|
nsresult nsDragSession::InvokeDragSessionImpl(
|
||||||
nsIWidget* aWidget, nsIArray* aTransferableArray,
|
nsIWidget* aWidget, nsIArray* aTransferableArray,
|
||||||
const Maybe<CSSIntRegion>& aRegion, uint32_t aActionType) {
|
const Maybe<CSSIntRegion>& aRegion, uint32_t aActionType) {
|
||||||
if (jni::GetAPIVersion() < 24) {
|
if (jni::GetAPIVersion() < 24) {
|
||||||
@@ -90,7 +92,6 @@ nsresult nsDragService::InvokeDragSessionImpl(
|
|||||||
if (nsWindow* window = GetWindow(mSourceDocument)) {
|
if (nsWindow* window = GetWindow(mSourceDocument)) {
|
||||||
mTransferable = transferable;
|
mTransferable = transferable;
|
||||||
|
|
||||||
nsBaseDragService::StartDragSession(aWidget);
|
|
||||||
OpenDragPopup();
|
OpenDragPopup();
|
||||||
|
|
||||||
auto bitmap = CreateDragImage(mSourceNode, aRegion);
|
auto bitmap = CreateDragImage(mSourceNode, aRegion);
|
||||||
@@ -230,18 +231,12 @@ void nsDragSession::SetData(nsITransferable* aTransferable) {
|
|||||||
mDataTransfer = nullptr;
|
mDataTransfer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
void nsDragSession::SetDropData(
|
||||||
void nsDragService::SetDropData(
|
|
||||||
mozilla::java::GeckoDragAndDrop::DropData::Param aDropData) {
|
mozilla::java::GeckoDragAndDrop::DropData::Param aDropData) {
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
RefPtr<nsDragService> dragService = nsDragService::GetInstance();
|
|
||||||
if (!dragService) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!aDropData) {
|
if (!aDropData) {
|
||||||
dragService->SetData(nullptr);
|
SetData(nullptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +249,7 @@ void nsDragService::SetDropData(
|
|||||||
|
|
||||||
if (!mime.EqualsLiteral("text/plain") && !mime.EqualsLiteral("text/html")) {
|
if (!mime.EqualsLiteral("text/plain") && !mime.EqualsLiteral("text/html")) {
|
||||||
// Not supported data.
|
// Not supported data.
|
||||||
dragService->SetData(nullptr);
|
SetData(nullptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,12 +258,12 @@ void nsDragService::SetDropData(
|
|||||||
nsPrimitiveHelpers::CreatePrimitiveForData(
|
nsPrimitiveHelpers::CreatePrimitiveForData(
|
||||||
mime, buffer.get(), buffer.Length() * 2, getter_AddRefs(wrapper));
|
mime, buffer.get(), buffer.Length() * 2, getter_AddRefs(wrapper));
|
||||||
if (!wrapper) {
|
if (!wrapper) {
|
||||||
dragService->SetData(nullptr);
|
SetData(nullptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nsCOMPtr<nsITransferable> transferable =
|
nsCOMPtr<nsITransferable> transferable =
|
||||||
do_CreateInstance("@mozilla.org/widget/transferable;1");
|
do_CreateInstance("@mozilla.org/widget/transferable;1");
|
||||||
transferable->Init(nullptr);
|
transferable->Init(nullptr);
|
||||||
transferable->SetTransferData(mime.get(), wrapper);
|
transferable->SetTransferData(mime.get(), wrapper);
|
||||||
dragService->SetData(transferable);
|
SetData(transferable);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,15 +13,11 @@
|
|||||||
|
|
||||||
class nsITransferable;
|
class nsITransferable;
|
||||||
|
|
||||||
// Temporary inheritance from nsBaseDragService instead of nsBaseDragSession
|
/**
|
||||||
// (which nsBaseDragService temporarily inherits).
|
* Android native nsIDragSession implementation
|
||||||
// This will be undone at the end of this patch series.
|
*/
|
||||||
class nsDragSession : public nsBaseDragService {
|
class nsDragSession : public nsBaseDragSession {
|
||||||
public:
|
public:
|
||||||
nsDragSession() = default;
|
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
|
||||||
|
|
||||||
// nsIDragSession
|
// nsIDragSession
|
||||||
NS_IMETHOD GetData(nsITransferable* aTransferable, uint32_t anItem) override;
|
NS_IMETHOD GetData(nsITransferable* aTransferable, uint32_t anItem) override;
|
||||||
NS_IMETHOD GetNumDropItems(uint32_t* aNumItems) override;
|
NS_IMETHOD GetNumDropItems(uint32_t* aNumItems) override;
|
||||||
@@ -32,6 +28,8 @@ class nsDragSession : public nsBaseDragService {
|
|||||||
|
|
||||||
void SetData(nsITransferable* aTransferable);
|
void SetData(nsITransferable* aTransferable);
|
||||||
|
|
||||||
|
void SetDropData(mozilla::java::GeckoDragAndDrop::DropData::Param aDropData);
|
||||||
|
|
||||||
virtual bool MustUpdateDataTransfer(mozilla::EventMessage aMessage) override;
|
virtual bool MustUpdateDataTransfer(mozilla::EventMessage aMessage) override;
|
||||||
|
|
||||||
MOZ_CAN_RUN_SCRIPT nsresult EndDragSessionImpl(
|
MOZ_CAN_RUN_SCRIPT nsresult EndDragSessionImpl(
|
||||||
@@ -40,6 +38,12 @@ class nsDragSession : public nsBaseDragService {
|
|||||||
protected:
|
protected:
|
||||||
virtual ~nsDragSession() = default;
|
virtual ~nsDragSession() = default;
|
||||||
|
|
||||||
|
// nsBaseDragSession
|
||||||
|
MOZ_CAN_RUN_SCRIPT nsresult
|
||||||
|
InvokeDragSessionImpl(nsIWidget* aWidget, nsIArray* anArrayTransferables,
|
||||||
|
const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
|
||||||
|
uint32_t aActionType) override;
|
||||||
|
|
||||||
mozilla::java::sdk::Bitmap::LocalRef CreateDragImage(
|
mozilla::java::sdk::Bitmap::LocalRef CreateDragImage(
|
||||||
nsINode* aNode, const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion);
|
nsINode* aNode, const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion);
|
||||||
|
|
||||||
@@ -47,26 +51,15 @@ class nsDragSession : public nsBaseDragService {
|
|||||||
nsCOMPtr<nsITransferable> mTransferable;
|
nsCOMPtr<nsITransferable> mTransferable;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Temporary inheritance from nsDragSession instead of nsBaseDragService
|
/**
|
||||||
// (which nsDragSession temporarily inherits).
|
* Android native nsIDragService implementation
|
||||||
// This will be undone at the end of this patch series.
|
*/
|
||||||
class nsDragService final : public nsDragSession {
|
class nsDragService final : public nsBaseDragService {
|
||||||
public:
|
public:
|
||||||
static already_AddRefed<nsDragService> GetInstance();
|
static already_AddRefed<nsDragService> GetInstance();
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
|
||||||
|
|
||||||
static void SetDropData(
|
|
||||||
mozilla::java::GeckoDragAndDrop::DropData::Param aDropData);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~nsDragService() = default;
|
already_AddRefed<nsIDragSession> CreateDragSession() override;
|
||||||
|
|
||||||
// nsBaseDragService
|
|
||||||
MOZ_CAN_RUN_SCRIPT nsresult
|
|
||||||
InvokeDragSessionImpl(nsIWidget* aWidget, nsIArray* anArrayTransferables,
|
|
||||||
const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
|
|
||||||
uint32_t aActionType) override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // nsDragService_h__
|
#endif // nsDragService_h__
|
||||||
|
|||||||
@@ -2677,15 +2677,16 @@ void nsWindow::OnDragEvent(int32_t aAction, int64_t aTime, float aX, float aY,
|
|||||||
jni::Object::Param aDropData) {
|
jni::Object::Param aDropData) {
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
LayoutDeviceIntPoint point =
|
||||||
|
LayoutDeviceIntPoint(int32_t(floorf(aX)), int32_t(floorf(aY)));
|
||||||
|
|
||||||
RefPtr<nsDragService> dragService = nsDragService::GetInstance();
|
RefPtr<nsDragService> dragService = nsDragService::GetInstance();
|
||||||
if (!dragService) {
|
if (!dragService) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LayoutDeviceIntPoint point =
|
RefPtr<nsDragSession> dragSession =
|
||||||
LayoutDeviceIntPoint(int32_t(floorf(aX)), int32_t(floorf(aY)));
|
static_cast<nsDragSession*>(dragService->GetCurrentSession(this));
|
||||||
|
|
||||||
nsCOMPtr<nsIDragSession> dragSession = dragService->GetCurrentSession(this);
|
|
||||||
if (dragSession && aAction == java::sdk::DragEvent::ACTION_DRAG_STARTED) {
|
if (dragSession && aAction == java::sdk::DragEvent::ACTION_DRAG_STARTED) {
|
||||||
dragSession->SetDragEndPoint(point.x, point.y);
|
dragSession->SetDragEndPoint(point.x, point.y);
|
||||||
return;
|
return;
|
||||||
@@ -2702,10 +2703,13 @@ void nsWindow::OnDragEvent(int32_t aAction, int64_t aTime, float aX, float aY,
|
|||||||
nsIWidget* widget = this;
|
nsIWidget* widget = this;
|
||||||
dragService->StartDragSession(widget);
|
dragService->StartDragSession(widget);
|
||||||
// For compatibility, we have to set temporary data.
|
// For compatibility, we have to set temporary data.
|
||||||
|
dragSession =
|
||||||
|
static_cast<nsDragSession*>(dragService->GetCurrentSession(this));
|
||||||
|
MOZ_ASSERT(dragSession);
|
||||||
|
|
||||||
auto dropData =
|
auto dropData =
|
||||||
mozilla::java::GeckoDragAndDrop::DropData::Ref::From(aDropData);
|
mozilla::java::GeckoDragAndDrop::DropData::Ref::From(aDropData);
|
||||||
nsDragService::SetDropData(dropData);
|
dragSession->SetDropData(dropData);
|
||||||
dragSession = dragService->GetCurrentSession(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dragSession) {
|
if (dragSession) {
|
||||||
@@ -2727,7 +2731,7 @@ void nsWindow::OnDragEvent(int32_t aAction, int64_t aTime, float aX, float aY,
|
|||||||
}
|
}
|
||||||
auto dropData =
|
auto dropData =
|
||||||
mozilla::java::GeckoDragAndDrop::DropData::Ref::From(aDropData);
|
mozilla::java::GeckoDragAndDrop::DropData::Ref::From(aDropData);
|
||||||
nsDragService::SetDropData(dropData);
|
dragSession->SetDropData(dropData);
|
||||||
dragSession->SetDragEndPoint(point.x, point.y);
|
dragSession->SetDragEndPoint(point.x, point.y);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,10 +11,10 @@
|
|||||||
|
|
||||||
#include <Cocoa/Cocoa.h>
|
#include <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
// Temporary inheritance from nsBaseDragService instead of nsBaseDragSession
|
/**
|
||||||
// (which nsBaseDragService temporarily inherits).
|
* Cocoa native nsIDragSession implementation
|
||||||
// This will be undone at the end of this patch series.
|
*/
|
||||||
class nsDragSession : public nsBaseDragService {
|
class nsDragSession : public nsBaseDragSession {
|
||||||
public:
|
public:
|
||||||
// nsIDragSession
|
// nsIDragSession
|
||||||
NS_IMETHOD GetData(nsITransferable* aTransferable,
|
NS_IMETHOD GetData(nsITransferable* aTransferable,
|
||||||
@@ -34,6 +34,12 @@ class nsDragSession : public nsBaseDragService {
|
|||||||
bool aDoneDrag, uint32_t aKeyModifiers) override;
|
bool aDoneDrag, uint32_t aKeyModifiers) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// nsBaseDragSession
|
||||||
|
MOZ_CAN_RUN_SCRIPT virtual nsresult InvokeDragSessionImpl(
|
||||||
|
nsIWidget* aWidget, nsIArray* anArrayTransferables,
|
||||||
|
const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
|
||||||
|
uint32_t aActionType) override;
|
||||||
|
|
||||||
// Creates and returns the drag image for a drag. aImagePoint will be set to
|
// Creates and returns the drag image for a drag. aImagePoint will be set to
|
||||||
// the origin of the drag relative to mNativeDragView.
|
// the origin of the drag relative to mNativeDragView.
|
||||||
NSImage* ConstructDragImage(
|
NSImage* ConstructDragImage(
|
||||||
@@ -59,21 +65,12 @@ class nsDragSession : public nsBaseDragService {
|
|||||||
bool mDragImageChanged = false;
|
bool mDragImageChanged = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Temporary inheritance from nsDragSession instead of nsBaseDragService
|
/**
|
||||||
// (which nsDragSession temporarily inherits).
|
* Cocoa native nsIDragService implementation
|
||||||
// This will be undone at the end of this patch series.
|
*/
|
||||||
class nsDragService final : public nsDragSession {
|
class nsDragService final : public nsBaseDragService {
|
||||||
public:
|
public:
|
||||||
nsDragService();
|
already_AddRefed<nsIDragSession> CreateDragSession() override;
|
||||||
|
|
||||||
// nsBaseDragService
|
|
||||||
MOZ_CAN_RUN_SCRIPT virtual nsresult InvokeDragSessionImpl(
|
|
||||||
nsIWidget* aWidget, nsIArray* anArrayTransferables,
|
|
||||||
const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
|
|
||||||
uint32_t aActionType) override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual ~nsDragService();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // nsDragService_h_
|
#endif // nsDragService_h_
|
||||||
|
|||||||
@@ -44,9 +44,10 @@ extern bool gUserCancelledDrag;
|
|||||||
// file destination callback.
|
// file destination callback.
|
||||||
mozilla::StaticRefPtr<nsIArray> gDraggedTransferables;
|
mozilla::StaticRefPtr<nsIArray> gDraggedTransferables;
|
||||||
|
|
||||||
nsDragService::nsDragService() {}
|
already_AddRefed<nsIDragSession> nsDragService::CreateDragSession() {
|
||||||
|
RefPtr<nsIDragSession> sess = new nsDragSession();
|
||||||
nsDragService::~nsDragService() {}
|
return sess.forget();
|
||||||
|
}
|
||||||
|
|
||||||
NSImage* nsDragSession::ConstructDragImage(nsINode* aDOMNode,
|
NSImage* nsDragSession::ConstructDragImage(nsINode* aDOMNode,
|
||||||
const Maybe<CSSIntRegion>& aRegion,
|
const Maybe<CSSIntRegion>& aRegion,
|
||||||
@@ -177,7 +178,7 @@ NSImage* nsDragSession::ConstructDragImage(nsINode* aDOMNode,
|
|||||||
NS_OBJC_END_TRY_BLOCK_RETURN(nil);
|
NS_OBJC_END_TRY_BLOCK_RETURN(nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult nsDragService::InvokeDragSessionImpl(
|
nsresult nsDragSession::InvokeDragSessionImpl(
|
||||||
nsIWidget* aWidget, nsIArray* aTransferableArray,
|
nsIWidget* aWidget, nsIArray* aTransferableArray,
|
||||||
const Maybe<CSSIntRegion>& aRegion, uint32_t aActionType) {
|
const Maybe<CSSIntRegion>& aRegion, uint32_t aActionType) {
|
||||||
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
|
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
|
||||||
@@ -250,7 +251,6 @@ nsresult nsDragService::InvokeDragSessionImpl(
|
|||||||
[pbItem release];
|
[pbItem release];
|
||||||
[dragItem setDraggingFrame:localDragRect contents:image];
|
[dragItem setDraggingFrame:localDragRect contents:image];
|
||||||
|
|
||||||
nsBaseDragService::StartDragSession(aWidget);
|
|
||||||
OpenDragPopup();
|
OpenDragPopup();
|
||||||
|
|
||||||
mNSDraggingSession = [mNativeDragView
|
mNSDraggingSession = [mNativeDragView
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include "mozilla/PresShell.h"
|
#include "mozilla/PresShell.h"
|
||||||
#include "mozilla/ScopeExit.h"
|
#include "mozilla/ScopeExit.h"
|
||||||
#include "mozilla/AutoRestore.h"
|
#include "mozilla/AutoRestore.h"
|
||||||
|
#include "mozilla/WidgetUtils.h"
|
||||||
#include "mozilla/WidgetUtilsGtk.h"
|
#include "mozilla/WidgetUtilsGtk.h"
|
||||||
#include "GRefPtr.h"
|
#include "GRefPtr.h"
|
||||||
#include "nsAppShell.h"
|
#include "nsAppShell.h"
|
||||||
@@ -519,7 +520,7 @@ void DragData::Print() const {
|
|||||||
|
|
||||||
/* static */ int nsDragSession::sEventLoopDepth = 0;
|
/* static */ int nsDragSession::sEventLoopDepth = 0;
|
||||||
|
|
||||||
nsDragService::nsDragService() {
|
nsDragSession::nsDragSession() {
|
||||||
// We have to destroy the hidden widget before the event loop stops
|
// We have to destroy the hidden widget before the event loop stops
|
||||||
// running.
|
// running.
|
||||||
nsCOMPtr<nsIObserverService> obsServ =
|
nsCOMPtr<nsIObserverService> obsServ =
|
||||||
@@ -580,8 +581,8 @@ nsDragService::nsDragService() {
|
|||||||
LOGDRAGSERVICE("nsDragService::nsDragService");
|
LOGDRAGSERVICE("nsDragService::nsDragService");
|
||||||
}
|
}
|
||||||
|
|
||||||
nsDragService::~nsDragService() {
|
nsDragSession::~nsDragSession() {
|
||||||
LOGDRAGSERVICE("nsDragService::~nsDragService");
|
LOGDRAGSERVICE("nsDragSession::~nsDragSession");
|
||||||
if (mTaskSource) g_source_remove(mTaskSource);
|
if (mTaskSource) g_source_remove(mTaskSource);
|
||||||
if (mTempFileTimerID) {
|
if (mTempFileTimerID) {
|
||||||
g_source_remove(mTempFileTimerID);
|
g_source_remove(mTempFileTimerID);
|
||||||
@@ -589,7 +590,7 @@ nsDragService::~nsDragService() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS_INHERITED(nsDragService, nsBaseDragService, nsIObserver)
|
NS_IMPL_ISUPPORTS_INHERITED(nsDragSession, nsBaseDragSession, nsIObserver)
|
||||||
|
|
||||||
mozilla::StaticRefPtr<nsDragService> sDragServiceInstance;
|
mozilla::StaticRefPtr<nsDragService> sDragServiceInstance;
|
||||||
/* static */
|
/* static */
|
||||||
@@ -606,13 +607,18 @@ already_AddRefed<nsDragService> nsDragService::GetInstance() {
|
|||||||
return service.forget();
|
return service.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<nsIDragSession> nsDragService::CreateDragSession() {
|
||||||
|
RefPtr<nsIDragSession> session = new nsDragSession();
|
||||||
|
return session.forget();
|
||||||
|
}
|
||||||
|
|
||||||
// nsIObserver
|
// nsIObserver
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDragService::Observe(nsISupports* aSubject, const char* aTopic,
|
nsDragSession::Observe(nsISupports* aSubject, const char* aTopic,
|
||||||
const char16_t* aData) {
|
const char16_t* aData) {
|
||||||
if (!nsCRT::strcmp(aTopic, "quit-application")) {
|
if (!nsCRT::strcmp(aTopic, "quit-application")) {
|
||||||
LOGDRAGSERVICE("nsDragService::Observe(\"quit-application\")");
|
LOGDRAGSERVICE("nsDragSession::Observe(\"quit-application\")");
|
||||||
if (mHiddenWidget) {
|
if (mHiddenWidget) {
|
||||||
gtk_widget_destroy(mHiddenWidget);
|
gtk_widget_destroy(mHiddenWidget);
|
||||||
mHiddenWidget = 0;
|
mHiddenWidget = 0;
|
||||||
@@ -725,15 +731,13 @@ static GtkWindow* GetGtkWindow(dom::Document* aDocument) {
|
|||||||
return GTK_WINDOW(toplevel);
|
return GTK_WINDOW(toplevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
// nsIDragService
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDragService::InvokeDragSession(
|
nsDragSession::InvokeDragSession(
|
||||||
nsIWidget* aWidget, nsINode* aDOMNode, nsIPrincipal* aPrincipal,
|
nsIWidget* aWidget, nsINode* aDOMNode, nsIPrincipal* aPrincipal,
|
||||||
nsIContentSecurityPolicy* aCsp, nsICookieJarSettings* aCookieJarSettings,
|
nsIContentSecurityPolicy* aCsp, nsICookieJarSettings* aCookieJarSettings,
|
||||||
nsIArray* aArrayTransferables, uint32_t aActionType,
|
nsIArray* aArrayTransferables, uint32_t aActionType,
|
||||||
nsContentPolicyType aContentPolicyType = nsIContentPolicy::TYPE_OTHER) {
|
nsContentPolicyType aContentPolicyType = nsIContentPolicy::TYPE_OTHER) {
|
||||||
LOGDRAGSERVICE("nsDragService::InvokeDragSession");
|
LOGDRAGSERVICE("nsDragSession::InvokeDragSession");
|
||||||
|
|
||||||
// If the previous source drag has not yet completed, signal handlers need
|
// If the previous source drag has not yet completed, signal handlers need
|
||||||
// to be removed from sGrabWidget and dragend needs to be dispatched to
|
// to be removed from sGrabWidget and dragend needs to be dispatched to
|
||||||
@@ -741,13 +745,13 @@ nsDragService::InvokeDragSession(
|
|||||||
// know whether or not the drag succeeded.
|
// know whether or not the drag succeeded.
|
||||||
if (mSourceNode) return NS_ERROR_NOT_AVAILABLE;
|
if (mSourceNode) return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
|
||||||
return nsBaseDragService::InvokeDragSession(
|
return nsBaseDragSession::InvokeDragSession(
|
||||||
aWidget, aDOMNode, aPrincipal, aCsp, aCookieJarSettings,
|
aWidget, aDOMNode, aPrincipal, aCsp, aCookieJarSettings,
|
||||||
aArrayTransferables, aActionType, aContentPolicyType);
|
aArrayTransferables, aActionType, aContentPolicyType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// nsBaseDragService
|
// nsBaseDragSession
|
||||||
nsresult nsDragService::InvokeDragSessionImpl(
|
nsresult nsDragSession::InvokeDragSessionImpl(
|
||||||
nsIWidget* aWidget, nsIArray* aArrayTransferables,
|
nsIWidget* aWidget, nsIArray* aArrayTransferables,
|
||||||
const Maybe<CSSIntRegion>& aRegion, uint32_t aActionType) {
|
const Maybe<CSSIntRegion>& aRegion, uint32_t aActionType) {
|
||||||
// make sure that we have an array of transferables to use
|
// make sure that we have an array of transferables to use
|
||||||
@@ -757,7 +761,7 @@ nsresult nsDragService::InvokeDragSessionImpl(
|
|||||||
// length of this call
|
// length of this call
|
||||||
mSourceDataItems = aArrayTransferables;
|
mSourceDataItems = aArrayTransferables;
|
||||||
|
|
||||||
LOGDRAGSERVICE("nsDragService::InvokeDragSessionImpl");
|
LOGDRAGSERVICE("nsDragSession::InvokeDragSessionImpl");
|
||||||
|
|
||||||
GdkDevice* device = widget::GdkGetPointer();
|
GdkDevice* device = widget::GdkGetPointer();
|
||||||
GdkWindow* originGdkWindow = nullptr;
|
GdkWindow* originGdkWindow = nullptr;
|
||||||
@@ -768,7 +772,7 @@ nsresult nsDragService::InvokeDragSessionImpl(
|
|||||||
// Check we have GdkWindow drag source.
|
// Check we have GdkWindow drag source.
|
||||||
if (!originGdkWindow) {
|
if (!originGdkWindow) {
|
||||||
NS_WARNING(
|
NS_WARNING(
|
||||||
"nsDragService::InvokeDragSessionImpl(): Missing origin GdkWindow!");
|
"nsDragSession::InvokeDragSessionImpl(): Missing origin GdkWindow!");
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -781,11 +785,11 @@ nsresult nsDragService::InvokeDragSessionImpl(
|
|||||||
// save our action type
|
// save our action type
|
||||||
GdkDragAction action = GDK_ACTION_DEFAULT;
|
GdkDragAction action = GDK_ACTION_DEFAULT;
|
||||||
|
|
||||||
if (aActionType & DRAGDROP_ACTION_COPY)
|
if (aActionType & nsIDragService::DRAGDROP_ACTION_COPY)
|
||||||
action = (GdkDragAction)(action | GDK_ACTION_COPY);
|
action = (GdkDragAction)(action | GDK_ACTION_COPY);
|
||||||
if (aActionType & DRAGDROP_ACTION_MOVE)
|
if (aActionType & nsIDragService::DRAGDROP_ACTION_MOVE)
|
||||||
action = (GdkDragAction)(action | GDK_ACTION_MOVE);
|
action = (GdkDragAction)(action | GDK_ACTION_MOVE);
|
||||||
if (aActionType & DRAGDROP_ACTION_LINK)
|
if (aActionType & nsIDragService::DRAGDROP_ACTION_LINK)
|
||||||
action = (GdkDragAction)(action | GDK_ACTION_LINK);
|
action = (GdkDragAction)(action | GDK_ACTION_LINK);
|
||||||
|
|
||||||
GdkEvent* existingEvent = widget::GetLastMousePressEvent();
|
GdkEvent* existingEvent = widget::GetLastMousePressEvent();
|
||||||
@@ -826,8 +830,6 @@ nsresult nsDragService::InvokeDragSessionImpl(
|
|||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
if (context) {
|
if (context) {
|
||||||
StartDragSession(aWidget);
|
|
||||||
|
|
||||||
// GTK uses another hidden window for receiving mouse events.
|
// GTK uses another hidden window for receiving mouse events.
|
||||||
sGrabWidget = gtk_window_group_get_current_grab(window_group);
|
sGrabWidget = gtk_window_group_get_current_grab(window_group);
|
||||||
if (sGrabWidget) {
|
if (sGrabWidget) {
|
||||||
@@ -849,7 +851,7 @@ nsresult nsDragService::InvokeDragSessionImpl(
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsDragService::SetAlphaPixmap(SourceSurface* aSurface,
|
bool nsDragSession::SetAlphaPixmap(SourceSurface* aSurface,
|
||||||
GdkDragContext* aContext, int32_t aXOffset,
|
GdkDragContext* aContext, int32_t aXOffset,
|
||||||
int32_t aYOffset,
|
int32_t aYOffset,
|
||||||
const LayoutDeviceIntRect& dragRect) {
|
const LayoutDeviceIntRect& dragRect) {
|
||||||
@@ -902,7 +904,6 @@ bool nsDragService::SetAlphaPixmap(SourceSurface* aSurface,
|
|||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDragService::StartDragSession(nsISupports* aWidgetProvider) {
|
nsDragService::StartDragSession(nsISupports* aWidgetProvider) {
|
||||||
LOGDRAGSERVICE("nsDragService::StartDragSession");
|
LOGDRAGSERVICE("nsDragService::StartDragSession");
|
||||||
mTempFileUrls.Clear();
|
|
||||||
return nsBaseDragService::StartDragSession(aWidgetProvider);
|
return nsBaseDragService::StartDragSession(aWidgetProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -943,7 +944,6 @@ gboolean nsDragSession::TaskRemoveTempFiles(gpointer data) {
|
|||||||
// We manually deref it here.
|
// We manually deref it here.
|
||||||
RefPtr<nsDragSession> session = static_cast<nsDragSession*>(data);
|
RefPtr<nsDragSession> session = static_cast<nsDragSession*>(data);
|
||||||
session.get()->Release();
|
session.get()->Release();
|
||||||
RefPtr<nsDragService> dragService = static_cast<nsDragService*>(data);
|
|
||||||
return session->RemoveTempFiles();
|
return session->RemoveTempFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -968,7 +968,7 @@ nsresult nsDragSession::EndDragSessionImpl(bool aDoneDrag,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// unset our drag action
|
// unset our drag action
|
||||||
SetDragAction(DRAGDROP_ACTION_NONE);
|
SetDragAction(nsIDragService::DRAGDROP_ACTION_NONE);
|
||||||
|
|
||||||
// start timer to remove temporary files
|
// start timer to remove temporary files
|
||||||
if (mTemporaryFiles.Count() > 0 && !mTempFileTimerID) {
|
if (mTemporaryFiles.Count() > 0 && !mTempFileTimerID) {
|
||||||
@@ -1297,15 +1297,15 @@ void nsDragSession::ReplyToDragMotion(GdkDragContext* aDragContext,
|
|||||||
if (mCanDrop) {
|
if (mCanDrop) {
|
||||||
// notify the dragger if we can drop
|
// notify the dragger if we can drop
|
||||||
switch (mDragAction) {
|
switch (mDragAction) {
|
||||||
case DRAGDROP_ACTION_COPY:
|
case nsIDragService::DRAGDROP_ACTION_COPY:
|
||||||
LOGDRAGSERVICE(" set explicit action copy");
|
LOGDRAGSERVICE(" set explicit action copy");
|
||||||
action = GDK_ACTION_COPY;
|
action = GDK_ACTION_COPY;
|
||||||
break;
|
break;
|
||||||
case DRAGDROP_ACTION_LINK:
|
case nsIDragService::DRAGDROP_ACTION_LINK:
|
||||||
LOGDRAGSERVICE(" set explicit action link");
|
LOGDRAGSERVICE(" set explicit action link");
|
||||||
action = GDK_ACTION_LINK;
|
action = GDK_ACTION_LINK;
|
||||||
break;
|
break;
|
||||||
case DRAGDROP_ACTION_NONE:
|
case nsIDragService::DRAGDROP_ACTION_NONE:
|
||||||
LOGDRAGSERVICE(" set explicit action none");
|
LOGDRAGSERVICE(" set explicit action none");
|
||||||
action = (GdkDragAction)0;
|
action = (GdkDragAction)0;
|
||||||
break;
|
break;
|
||||||
@@ -1345,7 +1345,7 @@ void nsDragSession::ReplyToDragMotion(GdkDragContext* aDragContext,
|
|||||||
gdk_drag_status(aDragContext, action, aTime);
|
gdk_drag_status(aDragContext, action, aTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsDragService::SetCachedDragContext(GdkDragContext* aDragContext) {
|
void nsDragSession::SetCachedDragContext(GdkDragContext* aDragContext) {
|
||||||
LOGDRAGSERVICE("nsDragService::SetCachedDragContext(): [drag %p / cached %p]",
|
LOGDRAGSERVICE("nsDragService::SetCachedDragContext(): [drag %p / cached %p]",
|
||||||
aDragContext, (void*)mCachedDragContext);
|
aDragContext, (void*)mCachedDragContext);
|
||||||
// Clear cache data if we're going to D&D with different drag context.
|
// Clear cache data if we're going to D&D with different drag context.
|
||||||
@@ -1371,7 +1371,7 @@ bool nsDragSession::IsTargetContextList(void) {
|
|||||||
return IsDragFlavorAvailable(sMimeListTypeAtom);
|
return IsDragFlavorAvailable(sMimeListTypeAtom);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsDragService::IsDragFlavorAvailable(GdkAtom aRequestedFlavor) {
|
bool nsDragSession::IsDragFlavorAvailable(GdkAtom aRequestedFlavor) {
|
||||||
if (mCachedDragFlavors.IsEmpty()) {
|
if (mCachedDragFlavors.IsEmpty()) {
|
||||||
for (GList* tmp = gdk_drag_context_list_targets(mTargetDragContext); tmp;
|
for (GList* tmp = gdk_drag_context_list_targets(mTargetDragContext); tmp;
|
||||||
tmp = tmp->next) {
|
tmp = tmp->next) {
|
||||||
@@ -1388,7 +1388,7 @@ bool nsDragService::IsDragFlavorAvailable(GdkAtom aRequestedFlavor) {
|
|||||||
// Spins event loop, called from eDragTaskMotion handler by
|
// Spins event loop, called from eDragTaskMotion handler by
|
||||||
// DispatchMotionEvents().
|
// DispatchMotionEvents().
|
||||||
// Can lead to another round of drag_motion events.
|
// Can lead to another round of drag_motion events.
|
||||||
RefPtr<DragData> nsDragService::GetDragData(GdkAtom aRequestedFlavor) {
|
RefPtr<DragData> nsDragSession::GetDragData(GdkAtom aRequestedFlavor) {
|
||||||
LOGDRAGSERVICE("nsDragService::GetDragData(%p) requested '%s'\n",
|
LOGDRAGSERVICE("nsDragService::GetDragData(%p) requested '%s'\n",
|
||||||
mTargetDragContext.get(),
|
mTargetDragContext.get(),
|
||||||
GUniquePtr<gchar>(gdk_atom_name(aRequestedFlavor)).get());
|
GUniquePtr<gchar>(gdk_atom_name(aRequestedFlavor)).get());
|
||||||
@@ -1455,7 +1455,7 @@ RefPtr<DragData> nsDragService::GetDragData(GdkAtom aRequestedFlavor) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsDragService::TargetDataReceived(GtkWidget* aWidget,
|
void nsDragSession::TargetDataReceived(GtkWidget* aWidget,
|
||||||
GdkDragContext* aContext, gint aX,
|
GdkDragContext* aContext, gint aX,
|
||||||
gint aY,
|
gint aY,
|
||||||
GtkSelectionData* aSelectionData,
|
GtkSelectionData* aSelectionData,
|
||||||
@@ -1558,7 +1558,7 @@ static bool CanExportAsURLTarget(const char16_t* aURLData, uint32_t aURLLen) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkTargetList* nsDragService::GetSourceList(void) {
|
GtkTargetList* nsDragSession::GetSourceList(void) {
|
||||||
if (!mSourceDataItems) {
|
if (!mSourceDataItems) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -1691,7 +1691,7 @@ GtkTargetList* nsDragService::GetSourceList(void) {
|
|||||||
return targetList;
|
return targetList;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsDragService::SourceEndDragSession(GdkDragContext* aContext,
|
void nsDragSession::SourceEndDragSession(GdkDragContext* aContext,
|
||||||
gint aResult) {
|
gint aResult) {
|
||||||
LOGDRAGSERVICE("SourceEndDragSession(%p) result %s\n", aContext,
|
LOGDRAGSERVICE("SourceEndDragSession(%p) result %s\n", aContext,
|
||||||
kGtkDragResults[aResult]);
|
kGtkDragResults[aResult]);
|
||||||
@@ -1722,10 +1722,7 @@ void nsDragService::SourceEndDragSession(GdkDragContext* aContext,
|
|||||||
gdk_window_get_device_position(
|
gdk_window_get_device_position(
|
||||||
gdkWindow, gdk_drag_context_get_device(aContext), &x, &y, nullptr);
|
gdkWindow, gdk_drag_context_get_device(aContext), &x, &y, nullptr);
|
||||||
gint scale = gdk_window_get_scale_factor(gdkWindow);
|
gint scale = gdk_window_get_scale_factor(gdkWindow);
|
||||||
nsCOMPtr<nsIDragSession> session = GetCurrentSession(mSourceWindow);
|
SetDragEndPoint(x * scale, y * scale);
|
||||||
if (session) {
|
|
||||||
session->SetDragEndPoint(x * scale, y * scale);
|
|
||||||
}
|
|
||||||
LOGDRAGSERVICE(" guess drag end point %d %d\n", x * scale, y * scale);
|
LOGDRAGSERVICE(" guess drag end point %d %d\n", x * scale, y * scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1750,23 +1747,23 @@ void nsDragService::SourceEndDragSession(GdkDragContext* aContext,
|
|||||||
// unusual action combinations as NONE.
|
// unusual action combinations as NONE.
|
||||||
if (!action) {
|
if (!action) {
|
||||||
LOGDRAGSERVICE(" drop action is none");
|
LOGDRAGSERVICE(" drop action is none");
|
||||||
dropEffect = DRAGDROP_ACTION_NONE;
|
dropEffect = nsIDragService::DRAGDROP_ACTION_NONE;
|
||||||
} else if (action & GDK_ACTION_COPY) {
|
} else if (action & GDK_ACTION_COPY) {
|
||||||
LOGDRAGSERVICE(" drop action is copy");
|
LOGDRAGSERVICE(" drop action is copy");
|
||||||
dropEffect = DRAGDROP_ACTION_COPY;
|
dropEffect = nsIDragService::DRAGDROP_ACTION_COPY;
|
||||||
} else if (action & GDK_ACTION_LINK) {
|
} else if (action & GDK_ACTION_LINK) {
|
||||||
LOGDRAGSERVICE(" drop action is link");
|
LOGDRAGSERVICE(" drop action is link");
|
||||||
dropEffect = DRAGDROP_ACTION_LINK;
|
dropEffect = nsIDragService::DRAGDROP_ACTION_LINK;
|
||||||
} else if (action & GDK_ACTION_MOVE) {
|
} else if (action & GDK_ACTION_MOVE) {
|
||||||
LOGDRAGSERVICE(" drop action is move");
|
LOGDRAGSERVICE(" drop action is move");
|
||||||
dropEffect = DRAGDROP_ACTION_MOVE;
|
dropEffect = nsIDragService::DRAGDROP_ACTION_MOVE;
|
||||||
} else {
|
} else {
|
||||||
LOGDRAGSERVICE(" drop action is copy");
|
LOGDRAGSERVICE(" drop action is copy");
|
||||||
dropEffect = DRAGDROP_ACTION_COPY;
|
dropEffect = nsIDragService::DRAGDROP_ACTION_COPY;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOGDRAGSERVICE(" drop action is none");
|
LOGDRAGSERVICE(" drop action is none");
|
||||||
dropEffect = DRAGDROP_ACTION_NONE;
|
dropEffect = nsIDragService::DRAGDROP_ACTION_NONE;
|
||||||
if (aResult != GTK_DRAG_RESULT_NO_TARGET) {
|
if (aResult != GTK_DRAG_RESULT_NO_TARGET) {
|
||||||
LOGDRAGSERVICE(" drop is user chancelled\n");
|
LOGDRAGSERVICE(" drop is user chancelled\n");
|
||||||
mUserCancelled = true;
|
mUserCancelled = true;
|
||||||
@@ -1778,7 +1775,8 @@ void nsDragService::SourceEndDragSession(GdkDragContext* aContext,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Schedule the appropriate drag end dom events.
|
// Schedule the appropriate drag end dom events.
|
||||||
Schedule(eDragTaskSourceEnd, nullptr, nullptr, LayoutDeviceIntPoint(), 0);
|
Schedule(eDragTaskSourceEnd, mTargetWindow, nullptr, LayoutDeviceIntPoint(),
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static nsresult GetDownloadDetails(nsITransferable* aTransferable,
|
static nsresult GetDownloadDetails(nsITransferable* aTransferable,
|
||||||
@@ -1837,9 +1835,9 @@ static nsresult GetDownloadDetails(nsITransferable* aTransferable,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// See nsContentAreaDragDropDataProvider::GetFlavorData() for reference.
|
// See nsContentAreaDragDropDataProvider::GetFlavorData() for reference.
|
||||||
nsresult nsDragService::CreateTempFile(nsITransferable* aItem,
|
nsresult nsDragSession::CreateTempFile(nsITransferable* aItem,
|
||||||
nsACString& aURI) {
|
nsACString& aURI) {
|
||||||
LOGDRAGSERVICE("nsDragService::CreateTempFile()");
|
LOGDRAGSERVICE("nsDragSession::CreateTempFile()");
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> tmpDir;
|
nsCOMPtr<nsIFile> tmpDir;
|
||||||
nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmpDir));
|
nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmpDir));
|
||||||
@@ -1973,7 +1971,7 @@ nsresult nsDragService::CreateTempFile(nsITransferable* aItem,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsDragService::SourceDataAppendURLFileItem(nsACString& aURI,
|
bool nsDragSession::SourceDataAppendURLFileItem(nsACString& aURI,
|
||||||
nsITransferable* aItem) {
|
nsITransferable* aItem) {
|
||||||
// If there is a file available, create a URI from the file.
|
// If there is a file available, create a URI from the file.
|
||||||
nsCOMPtr<nsISupports> data;
|
nsCOMPtr<nsISupports> data;
|
||||||
@@ -1990,7 +1988,7 @@ bool nsDragService::SourceDataAppendURLFileItem(nsACString& aURI,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsDragService::SourceDataAppendURLItem(nsITransferable* aItem,
|
bool nsDragSession::SourceDataAppendURLItem(nsITransferable* aItem,
|
||||||
bool aExternalDrop,
|
bool aExternalDrop,
|
||||||
nsACString& aURI) {
|
nsACString& aURI) {
|
||||||
nsCOMPtr<nsISupports> data;
|
nsCOMPtr<nsISupports> data;
|
||||||
@@ -2035,7 +2033,7 @@ bool nsDragService::SourceDataAppendURLItem(nsITransferable* aItem,
|
|||||||
return NS_SUCCEEDED(CreateTempFile(aItem, aURI));
|
return NS_SUCCEEDED(CreateTempFile(aItem, aURI));
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsDragService::SourceDataGetUriList(GdkDragContext* aContext,
|
void nsDragSession::SourceDataGetUriList(GdkDragContext* aContext,
|
||||||
GtkSelectionData* aSelectionData,
|
GtkSelectionData* aSelectionData,
|
||||||
uint32_t aDragItems) {
|
uint32_t aDragItems) {
|
||||||
// Check if we're transfering data to another application.
|
// Check if we're transfering data to another application.
|
||||||
@@ -2047,7 +2045,7 @@ void nsDragService::SourceDataGetUriList(GdkDragContext* aContext,
|
|||||||
? !nsWindow::GetWindow(gdk_drag_context_get_dest_window(aContext))
|
? !nsWindow::GetWindow(gdk_drag_context_get_dest_window(aContext))
|
||||||
: !gdk_drag_context_get_dest_window(aContext);
|
: !gdk_drag_context_get_dest_window(aContext);
|
||||||
|
|
||||||
LOGDRAGSERVICE("nsDragService::SourceDataGetUriLists() len %d external %d",
|
LOGDRAGSERVICE("nsDragSession::SourceDataGetUriLists() len %d external %d",
|
||||||
aDragItems, isExternalDrop);
|
aDragItems, isExternalDrop);
|
||||||
|
|
||||||
// Disable processing of native events until we store all files to /tmp.
|
// Disable processing of native events until we store all files to /tmp.
|
||||||
@@ -2081,9 +2079,9 @@ void nsDragService::SourceDataGetUriList(GdkDragContext* aContext,
|
|||||||
uriList.Length());
|
uriList.Length());
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsDragService::SourceDataGetImage(nsITransferable* aItem,
|
void nsDragSession::SourceDataGetImage(nsITransferable* aItem,
|
||||||
GtkSelectionData* aSelectionData) {
|
GtkSelectionData* aSelectionData) {
|
||||||
LOGDRAGSERVICE("nsDragService::SourceDataGetImage()");
|
LOGDRAGSERVICE("nsDragSession::SourceDataGetImage()");
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsCOMPtr<nsISupports> data;
|
nsCOMPtr<nsISupports> data;
|
||||||
@@ -2106,10 +2104,10 @@ void nsDragService::SourceDataGetImage(nsITransferable* aItem,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsDragService::SourceDataGetXDND(nsITransferable* aItem,
|
void nsDragSession::SourceDataGetXDND(nsITransferable* aItem,
|
||||||
GdkDragContext* aContext,
|
GdkDragContext* aContext,
|
||||||
GtkSelectionData* aSelectionData) {
|
GtkSelectionData* aSelectionData) {
|
||||||
LOGDRAGSERVICE("nsDragService::SourceDataGetXDND");
|
LOGDRAGSERVICE("nsDragSession::SourceDataGetXDND");
|
||||||
|
|
||||||
// Indicate failure by default.
|
// Indicate failure by default.
|
||||||
GdkAtom target = gtk_selection_data_get_target(aSelectionData);
|
GdkAtom target = gtk_selection_data_get_target(aSelectionData);
|
||||||
@@ -2200,11 +2198,11 @@ void nsDragService::SourceDataGetXDND(nsITransferable* aItem,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsDragService::SourceDataGetText(nsITransferable* aItem,
|
bool nsDragSession::SourceDataGetText(nsITransferable* aItem,
|
||||||
const nsACString& aMIMEType,
|
const nsACString& aMIMEType,
|
||||||
bool aNeedToDoConversionToPlainText,
|
bool aNeedToDoConversionToPlainText,
|
||||||
GtkSelectionData* aSelectionData) {
|
GtkSelectionData* aSelectionData) {
|
||||||
LOGDRAGSERVICE("nsDragService::SourceDataGetPlain()");
|
LOGDRAGSERVICE("nsDragSession::SourceDataGetPlain()");
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
nsCOMPtr<nsISupports> data;
|
nsCOMPtr<nsISupports> data;
|
||||||
@@ -2248,11 +2246,11 @@ bool nsDragService::SourceDataGetText(nsITransferable* aItem,
|
|||||||
// GtkSelectionData (Gtk D&D interface).
|
// GtkSelectionData (Gtk D&D interface).
|
||||||
// We need to check mSourceDataItems data type and try to convert it
|
// We need to check mSourceDataItems data type and try to convert it
|
||||||
// to data type accepted by Gtk.
|
// to data type accepted by Gtk.
|
||||||
void nsDragService::SourceDataGet(GtkWidget* aWidget, GdkDragContext* aContext,
|
void nsDragSession::SourceDataGet(GtkWidget* aWidget, GdkDragContext* aContext,
|
||||||
GtkSelectionData* aSelectionData,
|
GtkSelectionData* aSelectionData,
|
||||||
guint32 aTime) {
|
guint32 aTime) {
|
||||||
GdkAtom requestedFlavor = gtk_selection_data_get_target(aSelectionData);
|
GdkAtom requestedFlavor = gtk_selection_data_get_target(aSelectionData);
|
||||||
LOGDRAGSERVICE("nsDragService::SourceDataGet(%p) MIME %s", aContext,
|
LOGDRAGSERVICE("nsDragSession::SourceDataGet(%p) MIME %s", aContext,
|
||||||
GUniquePtr<gchar>(gdk_atom_name(requestedFlavor)).get());
|
GUniquePtr<gchar>(gdk_atom_name(requestedFlavor)).get());
|
||||||
|
|
||||||
// check to make sure that we have data items to return.
|
// check to make sure that we have data items to return.
|
||||||
@@ -2321,8 +2319,8 @@ void nsDragService::SourceDataGet(GtkWidget* aWidget, GdkDragContext* aContext,
|
|||||||
/* aNeedToDoConversionToPlainText */ false, aSelectionData);
|
/* aNeedToDoConversionToPlainText */ false, aSelectionData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsDragService::SourceBeginDrag(GdkDragContext* aContext) {
|
void nsDragSession::SourceBeginDrag(GdkDragContext* aContext) {
|
||||||
LOGDRAGSERVICE("nsDragService::SourceBeginDrag(%p)\n", aContext);
|
LOGDRAGSERVICE("nsDragSession::SourceBeginDrag(%p)\n", aContext);
|
||||||
|
|
||||||
nsCOMPtr<nsITransferable> transferable =
|
nsCOMPtr<nsITransferable> transferable =
|
||||||
do_QueryElementAt(mSourceDataItems, 0);
|
do_QueryElementAt(mSourceDataItems, 0);
|
||||||
@@ -2364,10 +2362,10 @@ void nsDragService::SourceBeginDrag(GdkDragContext* aContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsDragService::SetDragIcon(GdkDragContext* aContext) {
|
void nsDragSession::SetDragIcon(GdkDragContext* aContext) {
|
||||||
if (!mHasImage && !mSelection) return;
|
if (!mHasImage && !mSelection) return;
|
||||||
|
|
||||||
LOGDRAGSERVICE("nsDragService::SetDragIcon(%p)", aContext);
|
LOGDRAGSERVICE("nsDragSession::SetDragIcon(%p)", aContext);
|
||||||
|
|
||||||
LayoutDeviceIntRect dragRect;
|
LayoutDeviceIntRect dragRect;
|
||||||
nsPresContext* pc;
|
nsPresContext* pc;
|
||||||
@@ -2445,10 +2443,10 @@ void nsDragService::SetDragIcon(GdkDragContext* aContext) {
|
|||||||
static void invisibleSourceDragBegin(GtkWidget* aWidget,
|
static void invisibleSourceDragBegin(GtkWidget* aWidget,
|
||||||
GdkDragContext* aContext, gpointer aData) {
|
GdkDragContext* aContext, gpointer aData) {
|
||||||
LOGDRAGSERVICESTATIC("invisibleSourceDragBegin (%p)", aContext);
|
LOGDRAGSERVICESTATIC("invisibleSourceDragBegin (%p)", aContext);
|
||||||
nsDragService* dragService = (nsDragService*)aData;
|
nsDragSession* dragSession = (nsDragSession*)aData;
|
||||||
|
|
||||||
dragService->SourceBeginDrag(aContext);
|
dragSession->SourceBeginDrag(aContext);
|
||||||
dragService->SetDragIcon(aContext);
|
dragSession->SetDragIcon(aContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void invisibleSourceDragDataGet(GtkWidget* aWidget,
|
static void invisibleSourceDragDataGet(GtkWidget* aWidget,
|
||||||
@@ -2457,15 +2455,13 @@ static void invisibleSourceDragDataGet(GtkWidget* aWidget,
|
|||||||
guint aInfo, guint32 aTime,
|
guint aInfo, guint32 aTime,
|
||||||
gpointer aData) {
|
gpointer aData) {
|
||||||
LOGDRAGSERVICESTATIC("invisibleSourceDragDataGet (%p)", aContext);
|
LOGDRAGSERVICESTATIC("invisibleSourceDragDataGet (%p)", aContext);
|
||||||
nsDragService* dragService = (nsDragService*)aData;
|
nsDragSession* dragSession = (nsDragSession*)aData;
|
||||||
dragService->SourceDataGet(aWidget, aContext, aSelectionData, aTime);
|
dragSession->SourceDataGet(aWidget, aContext, aSelectionData, aTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean invisibleSourceDragFailed(GtkWidget* aWidget,
|
static gboolean invisibleSourceDragFailed(GtkWidget* aWidget,
|
||||||
GdkDragContext* aContext,
|
GdkDragContext* aContext,
|
||||||
gint aResult, gpointer aData) {
|
gint aResult, gpointer aData) {
|
||||||
nsDragService* dragService = (nsDragService*)aData;
|
|
||||||
|
|
||||||
// Wayland and X11 uses different drag results here. When drag target is
|
// Wayland and X11 uses different drag results here. When drag target is
|
||||||
// missing X11 passes GDK_DRAG_CANCEL_NO_TARGET
|
// missing X11 passes GDK_DRAG_CANCEL_NO_TARGET
|
||||||
// (from gdk_dnd_handle_button_event()/gdkdnd-x11.c)
|
// (from gdk_dnd_handle_button_event()/gdkdnd-x11.c)
|
||||||
@@ -2482,10 +2478,11 @@ static gboolean invisibleSourceDragFailed(GtkWidget* aWidget,
|
|||||||
|
|
||||||
LOGDRAGSERVICESTATIC("invisibleSourceDragFailed(%p) %s", aContext,
|
LOGDRAGSERVICESTATIC("invisibleSourceDragFailed(%p) %s", aContext,
|
||||||
kGtkDragResults[aResult]);
|
kGtkDragResults[aResult]);
|
||||||
|
nsDragSession* dragSession = (nsDragSession*)aData;
|
||||||
// End the drag session now (rather than waiting for the drag-end signal)
|
// End the drag session now (rather than waiting for the drag-end signal)
|
||||||
// so that operations performed on dropEffect == none can start immediately
|
// so that operations performed on dropEffect == none can start immediately
|
||||||
// rather than waiting for the drag-failed animation to finish.
|
// rather than waiting for the drag-failed animation to finish.
|
||||||
dragService->SourceEndDragSession(aContext, aResult);
|
dragSession->SourceEndDragSession(aContext, aResult);
|
||||||
|
|
||||||
// We should return TRUE to disable the drag-failed animation iff the
|
// We should return TRUE to disable the drag-failed animation iff the
|
||||||
// source performed an operation when dropEffect was none, but the handler
|
// source performed an operation when dropEffect was none, but the handler
|
||||||
@@ -2496,10 +2493,10 @@ static gboolean invisibleSourceDragFailed(GtkWidget* aWidget,
|
|||||||
static void invisibleSourceDragEnd(GtkWidget* aWidget, GdkDragContext* aContext,
|
static void invisibleSourceDragEnd(GtkWidget* aWidget, GdkDragContext* aContext,
|
||||||
gpointer aData) {
|
gpointer aData) {
|
||||||
LOGDRAGSERVICESTATIC("invisibleSourceDragEnd(%p)", aContext);
|
LOGDRAGSERVICESTATIC("invisibleSourceDragEnd(%p)", aContext);
|
||||||
nsDragService* dragService = (nsDragService*)aData;
|
nsDragSession* dragSession = (nsDragSession*)aData;
|
||||||
|
|
||||||
// The drag has ended. Release the hostages!
|
// The drag has ended. Release the hostages!
|
||||||
dragService->SourceEndDragSession(aContext, GTK_DRAG_RESULT_SUCCESS);
|
dragSession->SourceEndDragSession(aContext, GTK_DRAG_RESULT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following methods handle responding to GTK drag signals and
|
// The following methods handle responding to GTK drag signals and
|
||||||
@@ -2543,7 +2540,7 @@ static void invisibleSourceDragEnd(GtkWidget* aWidget, GdkDragContext* aContext,
|
|||||||
// Gecko drag events are in flight. This helps event handlers that may not
|
// Gecko drag events are in flight. This helps event handlers that may not
|
||||||
// expect nested events, while accessing an event's dataTransfer for example.
|
// expect nested events, while accessing an event's dataTransfer for example.
|
||||||
|
|
||||||
gboolean nsDragService::ScheduleMotionEvent(nsWindow* aWindow,
|
gboolean nsDragSession::ScheduleMotionEvent(nsWindow* aWindow,
|
||||||
GdkDragContext* aDragContext,
|
GdkDragContext* aDragContext,
|
||||||
LayoutDeviceIntPoint aWindowPoint,
|
LayoutDeviceIntPoint aWindowPoint,
|
||||||
guint aTime) {
|
guint aTime) {
|
||||||
@@ -2561,7 +2558,7 @@ gboolean nsDragService::ScheduleMotionEvent(nsWindow* aWindow,
|
|||||||
return Schedule(eDragTaskMotion, aWindow, aDragContext, aWindowPoint, aTime);
|
return Schedule(eDragTaskMotion, aWindow, aDragContext, aWindowPoint, aTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsDragService::ScheduleLeaveEvent() {
|
void nsDragSession::ScheduleLeaveEvent() {
|
||||||
// We don't know at this stage whether a drop signal will immediately
|
// We don't know at this stage whether a drop signal will immediately
|
||||||
// follow. If the drop signal gets sent it will happen before we return
|
// follow. If the drop signal gets sent it will happen before we return
|
||||||
// to the main loop and the scheduled leave task will be replaced.
|
// to the main loop and the scheduled leave task will be replaced.
|
||||||
@@ -2570,7 +2567,7 @@ void nsDragService::ScheduleLeaveEvent() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean nsDragService::ScheduleDropEvent(nsWindow* aWindow,
|
gboolean nsDragSession::ScheduleDropEvent(nsWindow* aWindow,
|
||||||
GdkDragContext* aDragContext,
|
GdkDragContext* aDragContext,
|
||||||
LayoutDeviceIntPoint aWindowPoint,
|
LayoutDeviceIntPoint aWindowPoint,
|
||||||
guint aTime) {
|
guint aTime) {
|
||||||
@@ -2579,17 +2576,14 @@ gboolean nsDragService::ScheduleDropEvent(nsWindow* aWindow,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIDragSession> session = GetCurrentSession(aWindow);
|
SetDragEndPoint(aWindowPoint.x, aWindowPoint.y);
|
||||||
if (session) {
|
|
||||||
session->SetDragEndPoint(aWindowPoint.x, aWindowPoint.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We'll reply with gtk_drag_finish().
|
// We'll reply with gtk_drag_finish().
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MOZ_LOGGING
|
#ifdef MOZ_LOGGING
|
||||||
const char* nsDragService::GetDragServiceTaskName(DragTask aTask) {
|
const char* nsDragSession::GetDragServiceTaskName(DragTask aTask) {
|
||||||
static const char* taskNames[] = {"eDragTaskNone", "eDragTaskMotion",
|
static const char* taskNames[] = {"eDragTaskNone", "eDragTaskMotion",
|
||||||
"eDragTaskLeave", "eDragTaskDrop",
|
"eDragTaskLeave", "eDragTaskDrop",
|
||||||
"eDragTaskSourceEnd"};
|
"eDragTaskSourceEnd"};
|
||||||
@@ -2598,7 +2592,7 @@ const char* nsDragService::GetDragServiceTaskName(DragTask aTask) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gboolean nsDragService::Schedule(DragTask aTask, nsWindow* aWindow,
|
gboolean nsDragSession::Schedule(DragTask aTask, nsWindow* aWindow,
|
||||||
GdkDragContext* aDragContext,
|
GdkDragContext* aDragContext,
|
||||||
LayoutDeviceIntPoint aWindowPoint,
|
LayoutDeviceIntPoint aWindowPoint,
|
||||||
guint aTime) {
|
guint aTime) {
|
||||||
@@ -2611,7 +2605,7 @@ gboolean nsDragService::Schedule(DragTask aTask, nsWindow* aWindow,
|
|||||||
// within the allowed time). Otherwise, if we haven't yet run a scheduled
|
// within the allowed time). Otherwise, if we haven't yet run a scheduled
|
||||||
// drop or end task, just say that we are not ready to receive another
|
// drop or end task, just say that we are not ready to receive another
|
||||||
// drop.
|
// drop.
|
||||||
LOGDRAGSERVICE("nsDragService::Schedule(%p) task %s window %p\n",
|
LOGDRAGSERVICE("nsDragSession::Schedule(%p) task %s window %p\n",
|
||||||
aDragContext, GetDragServiceTaskName(aTask), aWindow);
|
aDragContext, GetDragServiceTaskName(aTask), aWindow);
|
||||||
|
|
||||||
if (mScheduledTask == eDragTaskSourceEnd ||
|
if (mScheduledTask == eDragTaskSourceEnd ||
|
||||||
@@ -2632,7 +2626,7 @@ gboolean nsDragService::Schedule(DragTask aTask, nsWindow* aWindow,
|
|||||||
// right after drag_motion event handler which is called by Gtk.
|
// right after drag_motion event handler which is called by Gtk.
|
||||||
// An ideal scenario is to call TaskDispatchCallback() directly here
|
// An ideal scenario is to call TaskDispatchCallback() directly here
|
||||||
// but we can't do that. TaskDispatchCallback() spins gtk event loop
|
// but we can't do that. TaskDispatchCallback() spins gtk event loop
|
||||||
// while nsDragService::Schedule() is already called from event loop
|
// while nsDragSession::Schedule() is already called from event loop
|
||||||
// (by drag_motion* gtk_widget events) so that direct call will cause
|
// (by drag_motion* gtk_widget events) so that direct call will cause
|
||||||
// nested recursion.
|
// nested recursion.
|
||||||
mTaskSource = g_timeout_add_full(G_PRIORITY_HIGH, 0, TaskDispatchCallback,
|
mTaskSource = g_timeout_add_full(G_PRIORITY_HIGH, 0, TaskDispatchCallback,
|
||||||
@@ -2649,15 +2643,17 @@ gboolean nsDragService::Schedule(DragTask aTask, nsWindow* aWindow,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean nsDragService::TaskDispatchCallback(gpointer data) {
|
gboolean nsDragSession::TaskDispatchCallback(gpointer data) {
|
||||||
RefPtr<nsDragService> dragService = static_cast<nsDragService*>(data);
|
// Make sure we hold a strong reference to the session while we process
|
||||||
AutoEventLoop loop(dragService);
|
// the task.
|
||||||
return dragService->RunScheduledTask();
|
RefPtr<nsDragSession> dragSession = static_cast<nsDragSession*>(data);
|
||||||
|
AutoEventLoop loop(dragSession);
|
||||||
|
return dragSession->RunScheduledTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean nsDragService::RunScheduledTask() {
|
gboolean nsDragSession::RunScheduledTask() {
|
||||||
LOGDRAGSERVICE(
|
LOGDRAGSERVICE(
|
||||||
"nsDragService::RunScheduledTask() task %s mTargetWindow %p "
|
"nsDragSession::RunScheduledTask() task %s mTargetWindow %p "
|
||||||
"mPendingWindow %p\n",
|
"mPendingWindow %p\n",
|
||||||
GetDragServiceTaskName(mScheduledTask), mTargetWindow.get(),
|
GetDragServiceTaskName(mScheduledTask), mTargetWindow.get(),
|
||||||
mPendingWindow.get());
|
mPendingWindow.get());
|
||||||
@@ -2679,10 +2675,7 @@ gboolean nsDragService::RunScheduledTask() {
|
|||||||
// The drag that was initiated in a different app. End the drag
|
// The drag that was initiated in a different app. End the drag
|
||||||
// session, since we're done with it for now (until the user drags
|
// session, since we're done with it for now (until the user drags
|
||||||
// back into this app).
|
// back into this app).
|
||||||
RefPtr<nsIDragSession> session = GetCurrentSession(mTargetWindow);
|
EndDragSession(false, GetCurrentModifiers());
|
||||||
if (session) {
|
|
||||||
session->EndDragSession(false, GetCurrentModifiers());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2704,10 +2697,7 @@ gboolean nsDragService::RunScheduledTask() {
|
|||||||
LOGDRAGSERVICE(" quit, selected task %s\n", GetDragServiceTaskName(task));
|
LOGDRAGSERVICE(" quit, selected task %s\n", GetDragServiceTaskName(task));
|
||||||
if (task == eDragTaskSourceEnd) {
|
if (task == eDragTaskSourceEnd) {
|
||||||
// Dispatch drag end events.
|
// Dispatch drag end events.
|
||||||
RefPtr<nsIDragSession> session = GetCurrentSession(mTargetWindow);
|
EndDragSession(true, GetCurrentModifiers());
|
||||||
if (session) {
|
|
||||||
session->EndDragSession(true, GetCurrentModifiers());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nothing more to do
|
// Nothing more to do
|
||||||
@@ -2716,10 +2706,6 @@ gboolean nsDragService::RunScheduledTask() {
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This may be the start of a destination drag session.
|
|
||||||
nsIWidget* targetWidget = mTargetWindow;
|
|
||||||
StartDragSession(targetWidget);
|
|
||||||
|
|
||||||
// mTargetWidget may be nullptr if the window has been destroyed.
|
// mTargetWidget may be nullptr if the window has been destroyed.
|
||||||
// (The leave event is not scheduled if a drop task is still scheduled.)
|
// (The leave event is not scheduled if a drop task is still scheduled.)
|
||||||
// We still reply appropriately to indicate that the drop will or didn't
|
// We still reply appropriately to indicate that the drop will or didn't
|
||||||
@@ -2786,10 +2772,7 @@ gboolean nsDragService::RunScheduledTask() {
|
|||||||
}
|
}
|
||||||
// Make sure to end the drag session. If this drag started in a
|
// Make sure to end the drag session. If this drag started in a
|
||||||
// different app, we won't get a drag_end signal to end it from.
|
// different app, we won't get a drag_end signal to end it from.
|
||||||
RefPtr<nsIDragSession> session = GetCurrentSession(mTargetWindow);
|
EndDragSession(true, GetCurrentModifiers());
|
||||||
if (session) {
|
|
||||||
session->EndDragSession(true, GetCurrentModifiers());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We're done with the drag context.
|
// We're done with the drag context.
|
||||||
@@ -2813,14 +2796,14 @@ gboolean nsDragService::RunScheduledTask() {
|
|||||||
// drag context. Gtk gets this from a combination of the key settings
|
// drag context. Gtk gets this from a combination of the key settings
|
||||||
// and what the source is offering.
|
// and what the source is offering.
|
||||||
|
|
||||||
void nsDragService::UpdateDragAction(GdkDragContext* aDragContext) {
|
void nsDragSession::UpdateDragAction(GdkDragContext* aDragContext) {
|
||||||
// This doesn't look right. dragSession.dragAction is used by
|
// This doesn't look right. dragSession.dragAction is used by
|
||||||
// nsContentUtils::SetDataTransferInEvent() to set the initial
|
// nsContentUtils::SetDataTransferInEvent() to set the initial
|
||||||
// dataTransfer.dropEffect, so GdkDragContext::suggested_action would be
|
// dataTransfer.dropEffect, so GdkDragContext::suggested_action would be
|
||||||
// more appropriate. GdkDragContext::actions should be used to set
|
// more appropriate. GdkDragContext::actions should be used to set
|
||||||
// dataTransfer.effectAllowed, which doesn't currently happen with
|
// dataTransfer.effectAllowed, which doesn't currently happen with
|
||||||
// external sources.
|
// external sources.
|
||||||
LOGDRAGSERVICE("nsDragService::UpdateDragAction(%p)", aDragContext);
|
LOGDRAGSERVICE("nsDragSession::UpdateDragAction(%p)", aDragContext);
|
||||||
|
|
||||||
// default is to do nothing
|
// default is to do nothing
|
||||||
int action = nsIDragService::DRAGDROP_ACTION_NONE;
|
int action = nsIDragService::DRAGDROP_ACTION_NONE;
|
||||||
@@ -2836,7 +2819,7 @@ void nsDragService::UpdateDragAction(GdkDragContext* aDragContext) {
|
|||||||
// So we need to call gdk_drag_context_get_selected_action() on Wayland
|
// So we need to call gdk_drag_context_get_selected_action() on Wayland
|
||||||
// to get potential D&D modifier.
|
// to get potential D&D modifier.
|
||||||
// gdk_drag_context_get_selected_action() is also affected by
|
// gdk_drag_context_get_selected_action() is also affected by
|
||||||
// gdk_drag_status(), see nsDragService::ReplyToDragMotion().
|
// gdk_drag_status(), see nsDragSession::ReplyToDragMotion().
|
||||||
if (widget::GdkIsWaylandDisplay()) {
|
if (widget::GdkIsWaylandDisplay()) {
|
||||||
GdkDragAction gdkActionSelected =
|
GdkDragAction gdkActionSelected =
|
||||||
gdk_drag_context_get_selected_action(aDragContext);
|
gdk_drag_context_get_selected_action(aDragContext);
|
||||||
@@ -2871,7 +2854,7 @@ void nsDragService::UpdateDragAction(GdkDragContext* aDragContext) {
|
|||||||
SetDragAction(action);
|
SetDragAction(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsDragService::UpdateDragAction() { UpdateDragAction(mTargetDragContext); }
|
void nsDragSession::UpdateDragAction() { UpdateDragAction(mTargetDragContext); }
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDragSession::UpdateDragEffect() {
|
nsDragSession::UpdateDragEffect() {
|
||||||
@@ -2889,12 +2872,9 @@ void nsDragSession::ReplyToDragMotion() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsDragService::DispatchMotionEvents() {
|
void nsDragSession::DispatchMotionEvents() {
|
||||||
if (mSourceWindow) {
|
if (mSourceWindow) {
|
||||||
RefPtr<nsIDragSession> session = GetCurrentSession(mSourceWindow);
|
FireDragEventAtSource(eDrag, GetCurrentModifiers());
|
||||||
if (session) {
|
|
||||||
session->FireDragEventAtSource(eDrag, GetCurrentModifiers());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (mTargetWindow) {
|
if (mTargetWindow) {
|
||||||
mTargetWindow->DispatchDragEvent(eDragOver, mTargetWindowPoint,
|
mTargetWindow->DispatchDragEvent(eDragOver, mTargetWindowPoint,
|
||||||
@@ -2903,7 +2883,7 @@ void nsDragService::DispatchMotionEvents() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the drop was successful
|
// Returns true if the drop was successful
|
||||||
gboolean nsDragService::DispatchDropEvent() {
|
gboolean nsDragSession::DispatchDropEvent() {
|
||||||
// We need to check IsDestroyed here because the nsRefPtr
|
// We need to check IsDestroyed here because the nsRefPtr
|
||||||
// only protects this from being deleted, it does NOT protect
|
// only protects this from being deleted, it does NOT protect
|
||||||
// against nsView::~nsView() calling Destroy() on it, bug 378273.
|
// against nsView::~nsView() calling Destroy() on it, bug 378273.
|
||||||
@@ -2919,7 +2899,7 @@ gboolean nsDragService::DispatchDropEvent() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
uint32_t nsDragService::GetCurrentModifiers() {
|
uint32_t nsDragSession::GetCurrentModifiers() {
|
||||||
return mozilla::widget::KeymapWrapper::ComputeCurrentKeyModifiers();
|
return mozilla::widget::KeymapWrapper::ComputeCurrentKeyModifiers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -87,11 +87,14 @@ class DragData final {
|
|||||||
nsTArray<nsString> mUris;
|
nsTArray<nsString> mUris;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Temporary inheritance from nsBaseDragService instead of nsBaseDragSession
|
/**
|
||||||
// (which nsBaseDragService temporarily inherits).
|
* GTK native nsIDragSession implementation
|
||||||
// This will be undone at the end of this patch series.
|
*/
|
||||||
class nsDragSession : public nsBaseDragService {
|
class nsDragSession : public nsBaseDragSession, public nsIObserver {
|
||||||
public:
|
public:
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_DECL_NSIOBSERVER
|
||||||
|
|
||||||
// nsIDragSession
|
// nsIDragSession
|
||||||
NS_IMETHOD SetCanDrop(bool aCanDrop) override;
|
NS_IMETHOD SetCanDrop(bool aCanDrop) override;
|
||||||
NS_IMETHOD GetCanDrop(bool* aCanDrop) override;
|
NS_IMETHOD GetCanDrop(bool* aCanDrop) override;
|
||||||
@@ -109,6 +112,7 @@ class nsDragSession : public nsBaseDragService {
|
|||||||
|
|
||||||
MOZ_CAN_RUN_SCRIPT nsresult EndDragSessionImpl(
|
MOZ_CAN_RUN_SCRIPT nsresult EndDragSessionImpl(
|
||||||
bool aDoneDrag, uint32_t aKeyModifiers) override;
|
bool aDoneDrag, uint32_t aKeyModifiers) override;
|
||||||
|
|
||||||
class AutoEventLoop {
|
class AutoEventLoop {
|
||||||
RefPtr<nsDragSession> mSession;
|
RefPtr<nsDragSession> mSession;
|
||||||
|
|
||||||
@@ -123,8 +127,6 @@ class nsDragSession : public nsBaseDragService {
|
|||||||
static int GetLoopDepth() { return sEventLoopDepth; };
|
static int GetLoopDepth() { return sEventLoopDepth; };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~nsDragSession() = default;
|
|
||||||
|
|
||||||
// mScheduledTask indicates what signal has been received from GTK and
|
// mScheduledTask indicates what signal has been received from GTK and
|
||||||
// so what needs to be dispatched when the scheduled task is run. It is
|
// so what needs to be dispatched when the scheduled task is run. It is
|
||||||
// eDragTaskNone when there is no task scheduled (but the
|
// eDragTaskNone when there is no task scheduled (but the
|
||||||
@@ -259,37 +261,25 @@ class nsDragSession : public nsBaseDragService {
|
|||||||
static GdkAtom sFilePromiseURLMimeAtom;
|
static GdkAtom sFilePromiseURLMimeAtom;
|
||||||
static GdkAtom sFilePromiseMimeAtom;
|
static GdkAtom sFilePromiseMimeAtom;
|
||||||
static GdkAtom sNativeImageMimeAtom;
|
static GdkAtom sNativeImageMimeAtom;
|
||||||
};
|
|
||||||
|
|
||||||
// Temporary inheritance from nsDragSession instead of nsBaseDragService
|
nsDragSession();
|
||||||
// (which nsDragSession temporarily inherits).
|
|
||||||
// This will be undone at the end of this patch series.
|
|
||||||
class nsDragService final : public nsDragSession, public nsIObserver {
|
|
||||||
public:
|
|
||||||
nsDragService();
|
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
// nsBaseDragSession
|
||||||
NS_DECL_NSIOBSERVER
|
|
||||||
|
|
||||||
// nsBaseDragService
|
|
||||||
MOZ_CAN_RUN_SCRIPT virtual nsresult InvokeDragSessionImpl(
|
MOZ_CAN_RUN_SCRIPT virtual nsresult InvokeDragSessionImpl(
|
||||||
nsIWidget* aWidget, nsIArray* anArrayTransferables,
|
nsIWidget* aWidget, nsIArray* anArrayTransferables,
|
||||||
const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
|
const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
|
||||||
uint32_t aActionType) override;
|
uint32_t aActionType) override;
|
||||||
// nsIDragService
|
|
||||||
|
// nsIDragSession
|
||||||
MOZ_CAN_RUN_SCRIPT NS_IMETHOD InvokeDragSession(
|
MOZ_CAN_RUN_SCRIPT NS_IMETHOD InvokeDragSession(
|
||||||
nsIWidget* aWidget, nsINode* aDOMNode, nsIPrincipal* aPrincipal,
|
nsIWidget* aWidget, nsINode* aDOMNode, nsIPrincipal* aPrincipal,
|
||||||
nsIContentSecurityPolicy* aCsp, nsICookieJarSettings* aCookieJarSettings,
|
nsIContentSecurityPolicy* aCsp, nsICookieJarSettings* aCookieJarSettings,
|
||||||
nsIArray* anArrayTransferables, uint32_t aActionType,
|
nsIArray* anArrayTransferables, uint32_t aActionType,
|
||||||
nsContentPolicyType aContentPolicyType) override;
|
nsContentPolicyType aContentPolicyType) override;
|
||||||
|
|
||||||
NS_IMETHOD StartDragSession(nsISupports* aWidgetProvider) override;
|
|
||||||
|
|
||||||
// Methods called from nsWindow to handle responding to GTK drag
|
// Methods called from nsWindow to handle responding to GTK drag
|
||||||
// destination signals
|
// destination signals
|
||||||
|
|
||||||
static already_AddRefed<nsDragService> GetInstance();
|
|
||||||
|
|
||||||
void TargetDataReceived(GtkWidget* aWidget, GdkDragContext* aContext, gint aX,
|
void TargetDataReceived(GtkWidget* aWidget, GdkDragContext* aContext, gint aX,
|
||||||
gint aY, GtkSelectionData* aSelection_data,
|
gint aY, GtkSelectionData* aSelection_data,
|
||||||
guint aInfo, guint32 aTime);
|
guint aInfo, guint32 aTime);
|
||||||
@@ -334,7 +324,7 @@ class nsDragService final : public nsDragSession, public nsIObserver {
|
|||||||
void SetDragIcon(GdkDragContext* aContext);
|
void SetDragIcon(GdkDragContext* aContext);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~nsDragService();
|
virtual ~nsDragSession();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// target/destination side vars
|
// target/destination side vars
|
||||||
@@ -370,8 +360,9 @@ class nsDragService final : public nsDragSession, public nsIObserver {
|
|||||||
|
|
||||||
// attempts to create a semi-transparent drag image. Returns TRUE if
|
// attempts to create a semi-transparent drag image. Returns TRUE if
|
||||||
// successful, FALSE if not
|
// successful, FALSE if not
|
||||||
bool SetAlphaPixmap(SourceSurface* aPixbuf, GdkDragContext* aContext,
|
bool SetAlphaPixmap(mozilla::gfx::SourceSurface* aPixbuf,
|
||||||
int32_t aXOffset, int32_t aYOffset,
|
GdkDragContext* aContext, int32_t aXOffset,
|
||||||
|
int32_t aYOffset,
|
||||||
const mozilla::LayoutDeviceIntRect& dragRect);
|
const mozilla::LayoutDeviceIntRect& dragRect);
|
||||||
|
|
||||||
gboolean Schedule(DragTask aTask, nsWindow* aWindow,
|
gboolean Schedule(DragTask aTask, nsWindow* aWindow,
|
||||||
@@ -386,7 +377,7 @@ class nsDragService final : public nsDragSession, public nsIObserver {
|
|||||||
void UpdateDragAction();
|
void UpdateDragAction();
|
||||||
|
|
||||||
#ifdef MOZ_LOGGING
|
#ifdef MOZ_LOGGING
|
||||||
const char* GetDragServiceTaskName(nsDragService::DragTask aTask);
|
const char* GetDragServiceTaskName(DragTask aTask);
|
||||||
#endif
|
#endif
|
||||||
gboolean DispatchDropEvent();
|
gboolean DispatchDropEvent();
|
||||||
static uint32_t GetCurrentModifiers();
|
static uint32_t GetCurrentModifiers();
|
||||||
@@ -394,4 +385,16 @@ class nsDragService final : public nsDragSession, public nsIObserver {
|
|||||||
nsresult CreateTempFile(nsITransferable* aItem, nsACString& aURI);
|
nsresult CreateTempFile(nsITransferable* aItem, nsACString& aURI);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Native GTK nsIDragService implementation
|
||||||
|
*/
|
||||||
|
class nsDragService : public nsBaseDragService {
|
||||||
|
public:
|
||||||
|
static already_AddRefed<nsDragService> GetInstance();
|
||||||
|
NS_IMETHOD StartDragSession(nsISupports* aWidgetProvider) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
already_AddRefed<nsIDragSession> CreateDragSession() override;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // nsDragService_h__
|
#endif // nsDragService_h__
|
||||||
|
|||||||
@@ -591,10 +591,14 @@ void nsWindow::Destroy() {
|
|||||||
UnlockNativePointer();
|
UnlockNativePointer();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// dragService will be null after shutdown of the service manager.
|
// Cancel (dragleave) the current drag session, if any.
|
||||||
RefPtr<nsDragService> dragService = nsDragService::GetInstance();
|
RefPtr<nsDragService> dragService = nsDragService::GetInstance();
|
||||||
if (dragService && this == dragService->GetMostRecentDestWindow()) {
|
if (dragService) {
|
||||||
dragService->ScheduleLeaveEvent();
|
nsDragSession* dragSession =
|
||||||
|
static_cast<nsDragSession*>(dragService->GetCurrentSession(this));
|
||||||
|
if (dragSession && this == dragSession->GetMostRecentDestWindow()) {
|
||||||
|
dragSession->ScheduleLeaveEvent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIRollupListener* rollupListener = nsBaseWidget::GetActiveRollupListener();
|
nsIRollupListener* rollupListener = nsBaseWidget::GetActiveRollupListener();
|
||||||
@@ -5465,9 +5469,13 @@ void nsWindow::OnDragDataReceivedEvent(GtkWidget* aWidget,
|
|||||||
LOGDRAG("nsWindow::OnDragDataReceived");
|
LOGDRAG("nsWindow::OnDragDataReceived");
|
||||||
|
|
||||||
RefPtr<nsDragService> dragService = nsDragService::GetInstance();
|
RefPtr<nsDragService> dragService = nsDragService::GetInstance();
|
||||||
nsDragService::AutoEventLoop loop(dragService);
|
nsDragSession* dragSession =
|
||||||
dragService->TargetDataReceived(aWidget, aDragContext, aX, aY, aSelectionData,
|
static_cast<nsDragSession*>(dragService->GetCurrentSession(this));
|
||||||
|
if (dragSession) {
|
||||||
|
nsDragSession::AutoEventLoop loop(dragSession);
|
||||||
|
dragSession->TargetDataReceived(aWidget, aDragContext, aX, aY, aSelectionData,
|
||||||
aInfo, aTime);
|
aInfo, aTime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsWindow* nsWindow::GetTransientForWindowIfPopup() {
|
nsWindow* nsWindow::GetTransientForWindowIfPopup() {
|
||||||
@@ -8704,8 +8712,20 @@ gboolean WindowDragMotionHandler(GtkWidget* aWidget,
|
|||||||
LOGDRAG("WindowDragMotionHandler target nsWindow [%p]", window.get());
|
LOGDRAG("WindowDragMotionHandler target nsWindow [%p]", window.get());
|
||||||
|
|
||||||
RefPtr<nsDragService> dragService = nsDragService::GetInstance();
|
RefPtr<nsDragService> dragService = nsDragService::GetInstance();
|
||||||
nsDragService::AutoEventLoop loop(dragService);
|
NS_ENSURE_TRUE(dragService, FALSE);
|
||||||
if (!dragService->ScheduleMotionEvent(
|
nsDragSession* dragSession =
|
||||||
|
static_cast<nsDragSession*>(dragService->GetCurrentSession(window));
|
||||||
|
if (!dragSession) {
|
||||||
|
// This may be the start of an external drag session.
|
||||||
|
nsIWidget* widget = window;
|
||||||
|
static_cast<nsDragSession*>(dragService->StartDragSession(widget));
|
||||||
|
dragSession =
|
||||||
|
static_cast<nsDragSession*>(dragService->GetCurrentSession(window));
|
||||||
|
}
|
||||||
|
NS_ENSURE_TRUE(dragSession, FALSE);
|
||||||
|
|
||||||
|
nsDragSession::AutoEventLoop loop(dragSession);
|
||||||
|
if (!dragSession->ScheduleMotionEvent(
|
||||||
window, aDragContext, GetWindowDropPosition(window, aX, aY), aTime)) {
|
window, aDragContext, GetWindowDropPosition(window, aX, aY), aTime)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -8728,9 +8748,17 @@ void WindowDragLeaveHandler(GtkWidget* aWidget) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<nsDragService> dragService = nsDragService::GetInstance();
|
RefPtr<nsDragService> dragService = nsDragService::GetInstance();
|
||||||
nsDragService::AutoEventLoop loop(dragService);
|
nsIWidget* widget = window;
|
||||||
|
nsDragSession* dragSession =
|
||||||
|
static_cast<nsDragSession*>(dragService->GetCurrentSession(widget));
|
||||||
|
if (!dragSession) {
|
||||||
|
LOGDRAG(" Received dragleave after drag had ended.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nsWindow* mostRecentDragWindow = dragService->GetMostRecentDestWindow();
|
nsDragSession::AutoEventLoop loop(dragSession);
|
||||||
|
|
||||||
|
nsWindow* mostRecentDragWindow = dragSession->GetMostRecentDestWindow();
|
||||||
if (!mostRecentDragWindow) {
|
if (!mostRecentDragWindow) {
|
||||||
// This can happen when the target will not accept a drop. A GTK drag
|
// This can happen when the target will not accept a drop. A GTK drag
|
||||||
// source sends the leave message to the destination before the
|
// source sends the leave message to the destination before the
|
||||||
@@ -8750,7 +8778,7 @@ void WindowDragLeaveHandler(GtkWidget* aWidget) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LOGDRAG("WindowDragLeaveHandler nsWindow %p\n", (void*)mostRecentDragWindow);
|
LOGDRAG("WindowDragLeaveHandler nsWindow %p\n", (void*)mostRecentDragWindow);
|
||||||
dragService->ScheduleLeaveEvent();
|
dragSession->ScheduleLeaveEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drag_leave_event_cb(GtkWidget* aWidget,
|
static void drag_leave_event_cb(GtkWidget* aWidget,
|
||||||
@@ -8778,8 +8806,10 @@ gboolean WindowDragDropHandler(GtkWidget* aWidget, GdkDragContext* aDragContext,
|
|||||||
|
|
||||||
LOGDRAG("WindowDragDropHandler nsWindow [%p]", window.get());
|
LOGDRAG("WindowDragDropHandler nsWindow [%p]", window.get());
|
||||||
RefPtr<nsDragService> dragService = nsDragService::GetInstance();
|
RefPtr<nsDragService> dragService = nsDragService::GetInstance();
|
||||||
nsDragService::AutoEventLoop loop(dragService);
|
nsDragSession* dragSession =
|
||||||
return dragService->ScheduleDropEvent(
|
static_cast<nsDragSession*>(dragService->GetCurrentSession(window));
|
||||||
|
nsDragSession::AutoEventLoop loop(dragSession);
|
||||||
|
return dragSession->ScheduleDropEvent(
|
||||||
window, aDragContext, GetWindowDropPosition(window, aX, aY), aTime);
|
window, aDragContext, GetWindowDropPosition(window, aX, aY), aTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ EXPORTS += [
|
|||||||
"nsBaseDragService.h",
|
"nsBaseDragService.h",
|
||||||
"nsBaseFilePicker.h",
|
"nsBaseFilePicker.h",
|
||||||
"nsBaseWidget.h",
|
"nsBaseWidget.h",
|
||||||
|
"nsDragServiceProxy.h",
|
||||||
"nsIDeviceContextSpec.h",
|
"nsIDeviceContextSpec.h",
|
||||||
"nsIRollupListener.h",
|
"nsIRollupListener.h",
|
||||||
"nsIWidget.h",
|
"nsIWidget.h",
|
||||||
|
|||||||
@@ -72,20 +72,22 @@ uint32_t GetSuppressLevel() {
|
|||||||
return static_cast<nsBaseDragService*>(svc.get())->GetSuppressLevel();
|
return static_cast<nsBaseDragService*>(svc.get())->GetSuppressLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsBaseDragService::nsBaseDragService()
|
nsBaseDragService::nsBaseDragService() = default;
|
||||||
: mContentPolicyType(nsIContentPolicy::TYPE_OTHER),
|
|
||||||
mSuppressLevel(0) {}
|
|
||||||
|
|
||||||
nsBaseDragService::~nsBaseDragService() = default;
|
nsBaseDragService::~nsBaseDragService() = default;
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(nsBaseDragService, nsIDragService, nsIDragSession)
|
|
||||||
|
|
||||||
nsBaseDragSession::nsBaseDragSession() {
|
nsBaseDragSession::nsBaseDragSession() {
|
||||||
TakeSessionBrowserListFromService();
|
TakeSessionBrowserListFromService();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsBaseDragSession::~nsBaseDragSession() = default;
|
nsBaseDragSession::~nsBaseDragSession() = default;
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS(nsBaseDragService, nsIDragService)
|
||||||
|
NS_IMPL_ISUPPORTS(nsBaseDragSession, nsIDragSession)
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsBaseDragService::GetIsMockService(bool* aRet) {
|
||||||
|
*aRet = false;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsBaseDragSession::SetCanDrop(bool aCanDrop) {
|
nsBaseDragSession::SetCanDrop(bool aCanDrop) {
|
||||||
@@ -309,7 +311,7 @@ NS_IMETHODIMP nsBaseDragSession::SetDragEndPointForTests(int32_t aScreenX,
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
nsresult nsBaseDragService::InvokeDragSession(
|
nsresult nsBaseDragSession::InvokeDragSession(
|
||||||
nsIWidget* aWidget, nsINode* aDOMNode, nsIPrincipal* aPrincipal,
|
nsIWidget* aWidget, nsINode* aDOMNode, nsIPrincipal* aPrincipal,
|
||||||
nsIContentSecurityPolicy* aCsp, nsICookieJarSettings* aCookieJarSettings,
|
nsIContentSecurityPolicy* aCsp, nsICookieJarSettings* aCookieJarSettings,
|
||||||
nsIArray* aTransferableArray, uint32_t aActionType,
|
nsIArray* aTransferableArray, uint32_t aActionType,
|
||||||
@@ -317,7 +319,6 @@ nsresult nsBaseDragService::InvokeDragSession(
|
|||||||
AUTO_PROFILER_LABEL("nsBaseDragService::InvokeDragSession", OTHER);
|
AUTO_PROFILER_LABEL("nsBaseDragService::InvokeDragSession", OTHER);
|
||||||
|
|
||||||
NS_ENSURE_TRUE(aDOMNode, NS_ERROR_INVALID_ARG);
|
NS_ENSURE_TRUE(aDOMNode, NS_ERROR_INVALID_ARG);
|
||||||
NS_ENSURE_TRUE(mSuppressLevel == 0, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
// stash the document of the dom node
|
// stash the document of the dom node
|
||||||
mSourceDocument = aDOMNode->OwnerDoc();
|
mSourceDocument = aDOMNode->OwnerDoc();
|
||||||
@@ -353,8 +354,11 @@ nsresult nsBaseDragService::InvokeDragSession(
|
|||||||
//
|
//
|
||||||
// The best way to avoid this is to use the mock service in tests. See
|
// The best way to avoid this is to use the mock service in tests. See
|
||||||
// synthesizeMockDragAndDrop.
|
// synthesizeMockDragAndDrop.
|
||||||
|
nsCOMPtr<nsIDragService> dragService =
|
||||||
|
do_GetService("@mozilla.org/widget/dragservice;1");
|
||||||
|
MOZ_ASSERT(dragService);
|
||||||
MOZ_ASSERT(
|
MOZ_ASSERT(
|
||||||
!xpc::IsInAutomation() || IsMockService(),
|
!xpc::IsInAutomation() || dragService->IsMockService(),
|
||||||
"About to start drag-drop native loop on which will prevent later "
|
"About to start drag-drop native loop on which will prevent later "
|
||||||
"tests from running properly.");
|
"tests from running properly.");
|
||||||
}
|
}
|
||||||
@@ -395,10 +399,7 @@ nsresult nsBaseDragService::InvokeDragSession(
|
|||||||
// Set mDoingDrag so that EndDragSession cleans up and sends the dragend
|
// Set mDoingDrag so that EndDragSession cleans up and sends the dragend
|
||||||
// event after the aborted drag.
|
// event after the aborted drag.
|
||||||
mDoingDrag = true;
|
mDoingDrag = true;
|
||||||
RefPtr<nsIDragSession> session = GetCurrentSession(aWidget);
|
EndDragSession(true, 0);
|
||||||
if (session) {
|
|
||||||
session->EndDragSession(true, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
@@ -418,9 +419,27 @@ nsBaseDragService::InvokeDragSessionWithImage(
|
|||||||
NS_ENSURE_TRUE(aDataTransfer, NS_ERROR_NULL_POINTER);
|
NS_ENSURE_TRUE(aDataTransfer, NS_ERROR_NULL_POINTER);
|
||||||
NS_ENSURE_TRUE(mSuppressLevel == 0, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(mSuppressLevel == 0, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
mSessionIsSynthesizedForTests =
|
RefPtr<nsBaseDragSession> session =
|
||||||
|
CreateDragSession().downcast<nsBaseDragSession>();
|
||||||
|
if (XRE_IsParentProcess()) {
|
||||||
|
mCurrentParentDragSession = session;
|
||||||
|
}
|
||||||
|
bool isSynthesized =
|
||||||
aDragEvent->WidgetEventPtr()->mFlags.mIsSynthesizedForTests &&
|
aDragEvent->WidgetEventPtr()->mFlags.mIsSynthesizedForTests &&
|
||||||
!GetNeverAllowSessionIsSynthesizedForTests();
|
!GetNeverAllowSessionIsSynthesizedForTests();
|
||||||
|
return session->InitWithImage(widget, aDOMNode, aPrincipal, aCsp,
|
||||||
|
aCookieJarSettings, aTransferableArray,
|
||||||
|
aActionType, aImage, aImageX, aImageY,
|
||||||
|
aDragEvent, aDataTransfer, isSynthesized);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsBaseDragSession::InitWithImage(
|
||||||
|
nsIWidget* aWidget, nsINode* aDOMNode, nsIPrincipal* aPrincipal,
|
||||||
|
nsIContentSecurityPolicy* aCsp, nsICookieJarSettings* aCookieJarSettings,
|
||||||
|
nsIArray* aTransferableArray, uint32_t aActionType, nsINode* aImage,
|
||||||
|
int32_t aImageX, int32_t aImageY, DragEvent* aDragEvent,
|
||||||
|
DataTransfer* aDataTransfer, bool aIsSynthesizedForTests) {
|
||||||
|
mSessionIsSynthesizedForTests = aIsSynthesizedForTests;
|
||||||
mDataTransfer = aDataTransfer;
|
mDataTransfer = aDataTransfer;
|
||||||
mSelection = nullptr;
|
mSelection = nullptr;
|
||||||
mHasImage = true;
|
mHasImage = true;
|
||||||
@@ -454,7 +473,7 @@ nsBaseDragService::InvokeDragSessionWithImage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult rv = InvokeDragSession(
|
nsresult rv = InvokeDragSession(
|
||||||
widget, aDOMNode, aPrincipal, aCsp, aCookieJarSettings,
|
aWidget, aDOMNode, aPrincipal, aCsp, aCookieJarSettings,
|
||||||
aTransferableArray, aActionType, nsIContentPolicy::TYPE_INTERNAL_IMAGE);
|
aTransferableArray, aActionType, nsIContentPolicy::TYPE_INTERNAL_IMAGE);
|
||||||
mRegion = Nothing();
|
mRegion = Nothing();
|
||||||
return rv;
|
return rv;
|
||||||
@@ -474,9 +493,27 @@ nsBaseDragService::InvokeDragSessionWithRemoteImage(
|
|||||||
NS_ENSURE_TRUE(aDataTransfer, NS_ERROR_NULL_POINTER);
|
NS_ENSURE_TRUE(aDataTransfer, NS_ERROR_NULL_POINTER);
|
||||||
NS_ENSURE_TRUE(mSuppressLevel == 0, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(mSuppressLevel == 0, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
mSessionIsSynthesizedForTests =
|
RefPtr<nsBaseDragSession> session =
|
||||||
|
CreateDragSession().downcast<nsBaseDragSession>();
|
||||||
|
if (XRE_IsParentProcess()) {
|
||||||
|
mCurrentParentDragSession = session;
|
||||||
|
}
|
||||||
|
bool isSynthesized =
|
||||||
aDragEvent->WidgetEventPtr()->mFlags.mIsSynthesizedForTests &&
|
aDragEvent->WidgetEventPtr()->mFlags.mIsSynthesizedForTests &&
|
||||||
!GetNeverAllowSessionIsSynthesizedForTests();
|
!GetNeverAllowSessionIsSynthesizedForTests();
|
||||||
|
return session->InitWithRemoteImage(widget, aDOMNode, aPrincipal, aCsp,
|
||||||
|
aCookieJarSettings, aTransferableArray,
|
||||||
|
aActionType, aDragStartData, aDragEvent,
|
||||||
|
aDataTransfer, isSynthesized);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsBaseDragSession::InitWithRemoteImage(
|
||||||
|
nsIWidget* aWidget, nsINode* aDOMNode, nsIPrincipal* aPrincipal,
|
||||||
|
nsIContentSecurityPolicy* aCsp, nsICookieJarSettings* aCookieJarSettings,
|
||||||
|
nsIArray* aTransferableArray, uint32_t aActionType,
|
||||||
|
RemoteDragStartData* aDragStartData, DragEvent* aDragEvent,
|
||||||
|
DataTransfer* aDataTransfer, bool aIsSynthesizedForTests) {
|
||||||
|
mSessionIsSynthesizedForTests = aIsSynthesizedForTests;
|
||||||
mDataTransfer = aDataTransfer;
|
mDataTransfer = aDataTransfer;
|
||||||
mSelection = nullptr;
|
mSelection = nullptr;
|
||||||
mHasImage = true;
|
mHasImage = true;
|
||||||
@@ -491,7 +528,7 @@ nsBaseDragService::InvokeDragSessionWithRemoteImage(
|
|||||||
mInputSource = aDragEvent->InputSource(CallerType::System);
|
mInputSource = aDragEvent->InputSource(CallerType::System);
|
||||||
|
|
||||||
nsresult rv = InvokeDragSession(
|
nsresult rv = InvokeDragSession(
|
||||||
widget, aDOMNode, aPrincipal, aCsp, aCookieJarSettings,
|
aWidget, aDOMNode, aPrincipal, aCsp, aCookieJarSettings,
|
||||||
aTransferableArray, aActionType, nsIContentPolicy::TYPE_INTERNAL_IMAGE);
|
aTransferableArray, aActionType, nsIContentPolicy::TYPE_INTERNAL_IMAGE);
|
||||||
mRegion = Nothing();
|
mRegion = Nothing();
|
||||||
return rv;
|
return rv;
|
||||||
@@ -511,9 +548,26 @@ nsBaseDragService::InvokeDragSessionWithSelection(
|
|||||||
NS_ENSURE_TRUE(aDragEvent, NS_ERROR_NULL_POINTER);
|
NS_ENSURE_TRUE(aDragEvent, NS_ERROR_NULL_POINTER);
|
||||||
NS_ENSURE_TRUE(mSuppressLevel == 0, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(mSuppressLevel == 0, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
mSessionIsSynthesizedForTests =
|
RefPtr<nsBaseDragSession> session =
|
||||||
|
CreateDragSession().downcast<nsBaseDragSession>();
|
||||||
|
if (XRE_IsParentProcess()) {
|
||||||
|
mCurrentParentDragSession = session;
|
||||||
|
}
|
||||||
|
bool isSynthesized =
|
||||||
aDragEvent->WidgetEventPtr()->mFlags.mIsSynthesizedForTests &&
|
aDragEvent->WidgetEventPtr()->mFlags.mIsSynthesizedForTests &&
|
||||||
!GetNeverAllowSessionIsSynthesizedForTests();
|
!GetNeverAllowSessionIsSynthesizedForTests();
|
||||||
|
return session->InitWithSelection(widget, aSelection, aPrincipal, aCsp,
|
||||||
|
aCookieJarSettings, aTransferableArray,
|
||||||
|
aActionType, aDragEvent, aDataTransfer,
|
||||||
|
isSynthesized);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsBaseDragSession::InitWithSelection(
|
||||||
|
nsIWidget* aWidget, Selection* aSelection, nsIPrincipal* aPrincipal,
|
||||||
|
nsIContentSecurityPolicy* aCsp, nsICookieJarSettings* aCookieJarSettings,
|
||||||
|
nsIArray* aTransferableArray, uint32_t aActionType, DragEvent* aDragEvent,
|
||||||
|
DataTransfer* aDataTransfer, bool aIsSynthesizedForTests) {
|
||||||
|
mSessionIsSynthesizedForTests = aIsSynthesizedForTests;
|
||||||
mDataTransfer = aDataTransfer;
|
mDataTransfer = aDataTransfer;
|
||||||
mSelection = aSelection;
|
mSelection = aSelection;
|
||||||
mHasImage = true;
|
mHasImage = true;
|
||||||
@@ -535,7 +589,7 @@ nsBaseDragService::InvokeDragSessionWithSelection(
|
|||||||
mSourceTopWindowContext =
|
mSourceTopWindowContext =
|
||||||
mSourceWindowContext ? mSourceWindowContext->TopWindowContext() : nullptr;
|
mSourceWindowContext ? mSourceWindowContext->TopWindowContext() : nullptr;
|
||||||
|
|
||||||
return InvokeDragSession(widget, node, aPrincipal, aCsp, aCookieJarSettings,
|
return InvokeDragSession(aWidget, node, aPrincipal, aCsp, aCookieJarSettings,
|
||||||
aTransferableArray, aActionType,
|
aTransferableArray, aActionType,
|
||||||
nsIContentPolicy::TYPE_OTHER);
|
nsIContentPolicy::TYPE_OTHER);
|
||||||
}
|
}
|
||||||
@@ -544,15 +598,17 @@ nsBaseDragService::InvokeDragSessionWithSelection(
|
|||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsBaseDragService::GetCurrentSession(nsISupports* aWidgetProvider,
|
nsBaseDragService::GetCurrentSession(nsISupports* aWidgetProvider,
|
||||||
nsIDragSession** aSession) {
|
nsIDragSession** aSession) {
|
||||||
if (!aSession) return NS_ERROR_INVALID_ARG;
|
MOZ_ASSERT(XRE_IsParentProcess());
|
||||||
|
if (!aSession) {
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
// "this" also implements a drag session, so say we are one but only
|
if (!mSuppressLevel && mCurrentParentDragSession) {
|
||||||
// if there is currently a drag going on.
|
RefPtr<nsIDragSession> session = mCurrentParentDragSession;
|
||||||
if (!mSuppressLevel && mDoingDrag) {
|
session.forget(aSession);
|
||||||
*aSession = this;
|
} else {
|
||||||
NS_ADDREF(*aSession); // addRef because we're a "getter"
|
|
||||||
} else
|
|
||||||
*aSession = nullptr;
|
*aSession = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@@ -560,16 +616,26 @@ nsBaseDragService::GetCurrentSession(nsISupports* aWidgetProvider,
|
|||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsBaseDragService::StartDragSession(nsISupports* aWidgetProvider) {
|
nsBaseDragService::StartDragSession(nsISupports* aWidgetProvider) {
|
||||||
|
MOZ_ASSERT(XRE_IsParentProcess());
|
||||||
if (!aWidgetProvider) {
|
if (!aWidgetProvider) {
|
||||||
return NS_ERROR_NULL_POINTER;
|
return NS_ERROR_NULL_POINTER;
|
||||||
}
|
}
|
||||||
if (mDoingDrag) {
|
if (mCurrentParentDragSession) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_ALREADY_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
mDoingDrag = true;
|
RefPtr<nsIDragSession> session = CreateDragSession();
|
||||||
// By default dispatch drop also to content.
|
if (XRE_IsParentProcess()) {
|
||||||
mOnlyChromeDrop = false;
|
mCurrentParentDragSession = session;
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsBaseDragSession::InitForTests(uint32_t aAllowedEffect) {
|
||||||
|
mDragAction = aAllowedEffect;
|
||||||
|
mEffectAllowedForTests = aAllowedEffect;
|
||||||
|
mSessionIsSynthesizedForTests = true;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -578,12 +644,13 @@ NS_IMETHODIMP nsBaseDragService::StartDragSessionForTests(
|
|||||||
// This method must set mSessionIsSynthesizedForTests
|
// This method must set mSessionIsSynthesizedForTests
|
||||||
MOZ_ASSERT(!mNeverAllowSessionIsSynthesizedForTests);
|
MOZ_ASSERT(!mNeverAllowSessionIsSynthesizedForTests);
|
||||||
|
|
||||||
if (NS_WARN_IF(NS_FAILED(StartDragSession(aWidgetProvider)))) {
|
nsresult rv = StartDragSession(aWidgetProvider);
|
||||||
return NS_ERROR_FAILURE;
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
|
||||||
mDragAction = aAllowedEffect;
|
nsCOMPtr<nsIDragSession> session;
|
||||||
mEffectAllowedForTests = aAllowedEffect;
|
GetCurrentSession(aWidgetProvider, getter_AddRefs(session));
|
||||||
mSessionIsSynthesizedForTests = true;
|
MOZ_ASSERT(session);
|
||||||
|
session->InitForTests(aAllowedEffect);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -660,6 +727,11 @@ nsresult nsBaseDragSession::EndDragSessionImpl(bool aDoneDrag,
|
|||||||
// CC to reclaim the memory.
|
// CC to reclaim the memory.
|
||||||
if (XRE_IsParentProcess()) {
|
if (XRE_IsParentProcess()) {
|
||||||
DiscardInternalTransferData();
|
DiscardInternalTransferData();
|
||||||
|
nsCOMPtr<nsIDragService> svc =
|
||||||
|
do_GetService("@mozilla.org/widget/dragservice;1");
|
||||||
|
if (svc) {
|
||||||
|
static_cast<nsBaseDragService*>(svc.get())->ClearCurrentParentDragSession();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mDoingDrag = false;
|
mDoingDrag = false;
|
||||||
@@ -788,7 +860,7 @@ static PresShell* GetPresShellForContent(nsINode* aDOMNode) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult nsBaseDragService::DrawDrag(nsINode* aDOMNode,
|
nsresult nsBaseDragSession::DrawDrag(nsINode* aDOMNode,
|
||||||
const Maybe<CSSIntRegion>& aRegion,
|
const Maybe<CSSIntRegion>& aRegion,
|
||||||
CSSIntPoint aScreenPosition,
|
CSSIntPoint aScreenPosition,
|
||||||
LayoutDeviceIntRect* aScreenDragRect,
|
LayoutDeviceIntRect* aScreenDragRect,
|
||||||
@@ -940,7 +1012,7 @@ nsresult nsBaseDragService::DrawDrag(nsINode* aDOMNode,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult nsBaseDragService::DrawDragForImage(
|
nsresult nsBaseDragSession::DrawDragForImage(
|
||||||
nsPresContext* aPresContext, nsIImageLoadingContent* aImageLoader,
|
nsPresContext* aPresContext, nsIImageLoadingContent* aImageLoader,
|
||||||
HTMLCanvasElement* aCanvas, LayoutDeviceIntRect* aScreenDragRect,
|
HTMLCanvasElement* aCanvas, LayoutDeviceIntRect* aScreenDragRect,
|
||||||
RefPtr<SourceSurface>* aSurface) {
|
RefPtr<SourceSurface>* aSurface) {
|
||||||
@@ -1005,7 +1077,10 @@ nsresult nsBaseDragService::DrawDragForImage(
|
|||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsBaseDragService::Suppress() {
|
nsBaseDragService::Suppress() {
|
||||||
EndDragSession(false, 0);
|
RefPtr<nsIDragSession> session = mCurrentParentDragSession;
|
||||||
|
if (session) {
|
||||||
|
session->EndDragSession(false, 0);
|
||||||
|
}
|
||||||
++mSuppressLevel;
|
++mSuppressLevel;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@@ -1075,28 +1150,20 @@ static bool RemoveAllBrowsers(nsTArray<nsWeakPtr>& aBrowsers) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool nsBaseDragService::MaybeAddBrowser(BrowserParent* aBP) {
|
bool nsBaseDragService::MaybeAddBrowser(BrowserParent* aBP) {
|
||||||
/*
|
|
||||||
// TODO: until nsBaseDragService and nsBaseDragSession separate
|
|
||||||
// (part 21), they automatically share mBrowsers, so skip this.
|
|
||||||
nsCOMPtr<nsIDragSession> session;
|
nsCOMPtr<nsIDragSession> session;
|
||||||
GetCurrentSession(nullptr, getter_AddRefs(session));
|
GetCurrentSession(nullptr, getter_AddRefs(session));
|
||||||
if (session) {
|
if (session) {
|
||||||
return session->MaybeAddBrowser(aBP);
|
return session->MaybeAddBrowser(aBP);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
return ::MaybeAddBrowser(mBrowsers, aBP);
|
return ::MaybeAddBrowser(mBrowsers, aBP);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsBaseDragService::RemoveAllBrowsers() {
|
bool nsBaseDragService::RemoveAllBrowsers() {
|
||||||
/*
|
|
||||||
// TODO: until nsBaseDragService and nsBaseDragSession separate
|
|
||||||
// (part 21), they automatically share mBrowsers, so skip this.
|
|
||||||
nsCOMPtr<nsIDragSession> session;
|
nsCOMPtr<nsIDragSession> session;
|
||||||
GetCurrentSession(nullptr, getter_AddRefs(session));
|
GetCurrentSession(nullptr, getter_AddRefs(session));
|
||||||
if (session) {
|
if (session) {
|
||||||
return session->RemoveAllBrowsers();
|
return session->RemoveAllBrowsers();
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
return ::RemoveAllBrowsers(mBrowsers);
|
return ::RemoveAllBrowsers(mBrowsers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1172,3 +1239,33 @@ void nsBaseDragSession::TakeSessionBrowserListFromService() {
|
|||||||
NS_ENSURE_TRUE_VOID(svc);
|
NS_ENSURE_TRUE_VOID(svc);
|
||||||
mBrowsers = static_cast<nsBaseDragService*>(svc.get())->TakeSessionBrowserList();
|
mBrowsers = static_cast<nsBaseDragService*>(svc.get())->TakeSessionBrowserList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
nsIWidget* nsBaseDragService::GetWidgetFromWidgetProvider(nsISupports* aWidgetProvider) {
|
||||||
|
nsCOMPtr<nsIWidget> widget = do_QueryObject(aWidgetProvider);
|
||||||
|
if (widget) {
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsPIDOMWindowOuter* outer;
|
||||||
|
if (aWidgetProvider) {
|
||||||
|
nsCOMPtr<mozIDOMWindow> window = do_GetInterface(aWidgetProvider);
|
||||||
|
NS_ENSURE_TRUE(window, nullptr);
|
||||||
|
RefPtr<nsPIDOMWindowInner> innerWin = nsGlobalWindowInner::Cast(window);
|
||||||
|
NS_ENSURE_TRUE(innerWin, nullptr);
|
||||||
|
outer = innerWin->GetOuterWindow();
|
||||||
|
} else {
|
||||||
|
nsCOMPtr<nsPIDOMWindowInner> winInner;
|
||||||
|
winInner = do_QueryInterface(GetEntryGlobal());
|
||||||
|
NS_ENSURE_TRUE(winInner, nullptr);
|
||||||
|
outer = winInner->GetOuterWindow();
|
||||||
|
}
|
||||||
|
NS_ENSURE_TRUE(outer, nullptr);
|
||||||
|
nsIDocShell* docShell = outer->GetDocShell();
|
||||||
|
NS_ENSURE_TRUE(docShell, nullptr);
|
||||||
|
PresShell* presShell = docShell->GetPresShell();
|
||||||
|
NS_ENSURE_TRUE(presShell, nullptr);
|
||||||
|
nsViewManager* vm = presShell->GetViewManager();
|
||||||
|
NS_ENSURE_TRUE(vm, nullptr);
|
||||||
|
return vm->GetRootWidget();
|
||||||
|
}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ class MockDragServiceController;
|
|||||||
*/
|
*/
|
||||||
class nsBaseDragSession : public nsIDragSession {
|
class nsBaseDragSession : public nsIDragSession {
|
||||||
public:
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSIDRAGSESSION
|
NS_DECL_NSIDRAGSESSION
|
||||||
|
|
||||||
int32_t TakeChildProcessDragAction();
|
int32_t TakeChildProcessDragAction();
|
||||||
@@ -68,9 +69,106 @@ class nsBaseDragSession : public nsIDragSession {
|
|||||||
mEndDragPoint = aEndDragPoint;
|
mEndDragPoint = aEndDragPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t GetInputSource() { return mInputSource; }
|
||||||
|
|
||||||
|
// The nsIDragService uses this to create nsIDragSessions when dragging
|
||||||
|
// from a child process.
|
||||||
|
MOZ_CAN_RUN_SCRIPT nsresult InitWithRemoteImage(
|
||||||
|
nsIWidget* aWidget, nsINode* aDOMNode, nsIPrincipal* aPrincipal,
|
||||||
|
nsIContentSecurityPolicy* aCsp, nsICookieJarSettings* aCookieJarSettings,
|
||||||
|
nsIArray* aTransferableArray, uint32_t aActionType,
|
||||||
|
mozilla::dom::RemoteDragStartData* aDragStartData,
|
||||||
|
mozilla::dom::DragEvent* aDragEvent,
|
||||||
|
mozilla::dom::DataTransfer* aDataTransfer, bool aIsSynthesizedForTests);
|
||||||
|
|
||||||
|
// The nsIDragService uses this to create nsIDragSessions for dragging
|
||||||
|
// a selected region from a Gecko window.
|
||||||
|
MOZ_CAN_RUN_SCRIPT nsresult InitWithSelection(
|
||||||
|
nsIWidget* aWidget, mozilla::dom::Selection* aSelection,
|
||||||
|
nsIPrincipal* aPrincipal, nsIContentSecurityPolicy* aCsp,
|
||||||
|
nsICookieJarSettings* aCookieJarSettings, nsIArray* aTransferableArray,
|
||||||
|
uint32_t aActionType, mozilla::dom::DragEvent* aDragEvent,
|
||||||
|
mozilla::dom::DataTransfer* aDataTransfer, bool aIsSynthesizedForTests);
|
||||||
|
|
||||||
|
// The nsIDragService uses this to create nsIDragSessions when dragging
|
||||||
|
// from anywhere else.
|
||||||
|
MOZ_CAN_RUN_SCRIPT nsresult InitWithImage(
|
||||||
|
nsIWidget* aWidget, nsINode* aDOMNode, nsIPrincipal* aPrincipal,
|
||||||
|
nsIContentSecurityPolicy* aCsp, nsICookieJarSettings* aCookieJarSettings,
|
||||||
|
nsIArray* aTransferableArray, uint32_t aActionType, nsINode* aImage,
|
||||||
|
int32_t aImageX, int32_t aImageY, mozilla::dom::DragEvent* aDragEvent,
|
||||||
|
mozilla::dom::DataTransfer* aDataTransfer, bool aIsSynthesizedForTests);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsBaseDragSession();
|
nsBaseDragSession();
|
||||||
~nsBaseDragSession();
|
virtual ~nsBaseDragSession();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a modal drag session with an array of transaferables.
|
||||||
|
*
|
||||||
|
* @param aPrincipal - the triggering principal of the drag, or null if
|
||||||
|
* it's from browser chrome or OS
|
||||||
|
* @param aCsp - The csp of the triggering Document
|
||||||
|
* @param aTransferables - an array of transferables to be dragged
|
||||||
|
* @param aActionType - specified which of copy/move/link are allowed
|
||||||
|
* @param aContentPolicyType - the contentPolicyType that will be
|
||||||
|
* passed to the loadInfo when creating a new channel
|
||||||
|
* (defaults to TYPE_OTHER)
|
||||||
|
*/
|
||||||
|
MOZ_CAN_RUN_SCRIPT virtual nsresult InvokeDragSession(
|
||||||
|
nsIWidget* aWidget, nsINode* aDOMNode, nsIPrincipal* aPrincipal,
|
||||||
|
nsIContentSecurityPolicy* aCsp, nsICookieJarSettings* aCookieJarSettings,
|
||||||
|
nsIArray* aTransferableArray, uint32_t aActionType,
|
||||||
|
nsContentPolicyType aContentPolicyType = nsIContentPolicy::TYPE_OTHER);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to create a drag session with a Gecko source. Like all drag
|
||||||
|
* sessions, the resulting session needs to be eventually ended with a call
|
||||||
|
* to nsIDragSession::EndDragSession.
|
||||||
|
*/
|
||||||
|
MOZ_CAN_RUN_SCRIPT virtual nsresult InvokeDragSessionImpl(
|
||||||
|
nsIWidget* aWidget, nsIArray* aTransferableArray,
|
||||||
|
const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* aRegion may be used to draw only a subset of the element. This region
|
||||||
|
* should be supplied using x and y coordinates measured in css pixels
|
||||||
|
* that are relative to the upper-left corner of the window.
|
||||||
|
*
|
||||||
|
* aScreenPosition should be the screen coordinates of the mouse click
|
||||||
|
* for the drag. These are in CSS pixels.
|
||||||
|
*
|
||||||
|
* On return, aScreenDragRect will contain the screen coordinates of the
|
||||||
|
* area being dragged. This is used by the platform-specific part of the
|
||||||
|
* drag service to determine the drag feedback. This rect will be in the
|
||||||
|
* device pixels of the presContext.
|
||||||
|
*
|
||||||
|
* If there is no drag image, the returned surface will be null, but
|
||||||
|
* aScreenDragRect will still be set to the drag area.
|
||||||
|
*
|
||||||
|
* aPresContext will be set to the nsPresContext used determined from
|
||||||
|
* whichever of mImage or aDOMNode is used.
|
||||||
|
*/
|
||||||
|
nsresult DrawDrag(nsINode* aDOMNode,
|
||||||
|
const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
|
||||||
|
mozilla::CSSIntPoint aScreenPosition,
|
||||||
|
mozilla::LayoutDeviceIntRect* aScreenDragRect,
|
||||||
|
RefPtr<mozilla::gfx::SourceSurface>* aSurface,
|
||||||
|
nsPresContext** aPresContext);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw a drag image for an image node specified by aImageLoader or aCanvas.
|
||||||
|
* This is called by DrawDrag.
|
||||||
|
*/
|
||||||
|
nsresult DrawDragForImage(nsPresContext* aPresContext,
|
||||||
|
nsIImageLoadingContent* aImageLoader,
|
||||||
|
mozilla::dom::HTMLCanvasElement* aCanvas,
|
||||||
|
mozilla::LayoutDeviceIntRect* aScreenDragRect,
|
||||||
|
RefPtr<mozilla::gfx::SourceSurface>* aSurface);
|
||||||
|
|
||||||
MOZ_CAN_RUN_SCRIPT virtual nsresult EndDragSessionImpl(
|
MOZ_CAN_RUN_SCRIPT virtual nsresult EndDragSessionImpl(
|
||||||
bool aDoneDrag, uint32_t aKeyModifiers);
|
bool aDoneDrag, uint32_t aKeyModifiers);
|
||||||
@@ -133,6 +231,10 @@ class nsBaseDragSession : public nsIDragSession {
|
|||||||
// The position relative to the top level widget where the drag ended.
|
// The position relative to the top level widget where the drag ended.
|
||||||
mozilla::LayoutDeviceIntPoint mEndDragPoint;
|
mozilla::LayoutDeviceIntPoint mEndDragPoint;
|
||||||
|
|
||||||
|
// the contentpolicy type passed to the channel when initiating the drag
|
||||||
|
// session
|
||||||
|
nsContentPolicyType mContentPolicyType = nsIContentPolicy::TYPE_OTHER;
|
||||||
|
|
||||||
uint32_t mDragAction = nsIDragService::DRAGDROP_ACTION_NONE;
|
uint32_t mDragAction = nsIDragService::DRAGDROP_ACTION_NONE;
|
||||||
uint32_t mDragActionFromChildProcess =
|
uint32_t mDragActionFromChildProcess =
|
||||||
nsIDragService::DRAGDROP_ACTION_UNINITIALIZED;
|
nsIDragService::DRAGDROP_ACTION_UNINITIALIZED;
|
||||||
@@ -145,7 +247,8 @@ class nsBaseDragSession : public nsIDragSession {
|
|||||||
// The input source of the drag event. Possible values are from MouseEvent.
|
// The input source of the drag event. Possible values are from MouseEvent.
|
||||||
uint16_t mInputSource = mozilla::dom::MouseEvent_Binding::MOZ_SOURCE_MOUSE;
|
uint16_t mInputSource = mozilla::dom::MouseEvent_Binding::MOZ_SOURCE_MOUSE;
|
||||||
|
|
||||||
bool mDoingDrag = false;
|
// false after EndDragSession has run
|
||||||
|
bool mDoingDrag = true;
|
||||||
|
|
||||||
bool mCanDrop = false;
|
bool mCanDrop = false;
|
||||||
bool mOnlyChromeDrop = false;
|
bool mOnlyChromeDrop = false;
|
||||||
@@ -166,14 +269,9 @@ class nsBaseDragSession : public nsIDragSession {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Platform-agnostic base for nsIDragService.
|
* Platform-agnostic base for nsIDragService.
|
||||||
* NB: This class temporarily subclasses nsBaseDragSession while we move
|
|
||||||
* methods from it to nsBaseDragSession. The inheritance relationship
|
|
||||||
* will be severed by the end of this patch series.
|
|
||||||
*/
|
*/
|
||||||
class nsBaseDragService : public nsIDragService, public nsBaseDragSession {
|
class nsBaseDragService : public nsIDragService {
|
||||||
public:
|
public:
|
||||||
typedef mozilla::gfx::SourceSurface SourceSurface;
|
|
||||||
|
|
||||||
nsBaseDragService();
|
nsBaseDragService();
|
||||||
|
|
||||||
// nsISupports
|
// nsISupports
|
||||||
@@ -181,8 +279,6 @@ class nsBaseDragService : public nsIDragService, public nsBaseDragSession {
|
|||||||
|
|
||||||
NS_DECL_NSIDRAGSERVICE
|
NS_DECL_NSIDRAGSERVICE
|
||||||
|
|
||||||
uint16_t GetInputSource() { return mInputSource; }
|
|
||||||
|
|
||||||
using nsIDragService::GetCurrentSession;
|
using nsIDragService::GetCurrentSession;
|
||||||
|
|
||||||
uint32_t GetSuppressLevel() { return mSuppressLevel; };
|
uint32_t GetSuppressLevel() { return mSuppressLevel; };
|
||||||
@@ -191,89 +287,34 @@ class nsBaseDragService : public nsIDragService, public nsBaseDragSession {
|
|||||||
return std::move(mBrowsers);
|
return std::move(mBrowsers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClearCurrentParentDragSession() {
|
||||||
|
mCurrentParentDragSession = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static nsIWidget* GetWidgetFromWidgetProvider(nsISupports* aWidgetProvider);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~nsBaseDragService();
|
virtual ~nsBaseDragService();
|
||||||
|
|
||||||
/**
|
virtual already_AddRefed<nsIDragSession> CreateDragSession() = 0;
|
||||||
* Starts a modal drag session with an array of transaferables.
|
|
||||||
*
|
|
||||||
* @param aPrincipal - the triggering principal of the drag, or null if
|
|
||||||
* it's from browser chrome or OS
|
|
||||||
* @param aCsp - The csp of the triggering Document
|
|
||||||
* @param aTransferables - an array of transferables to be dragged
|
|
||||||
* @param aActionType - specified which of copy/move/link are allowed
|
|
||||||
* @param aContentPolicyType - the contentPolicyType that will be
|
|
||||||
* passed to the loadInfo when creating a new channel
|
|
||||||
* (defaults to TYPE_OTHER)
|
|
||||||
*/
|
|
||||||
MOZ_CAN_RUN_SCRIPT virtual nsresult InvokeDragSession(
|
|
||||||
nsIWidget* aWidget, nsINode* aDOMNode, nsIPrincipal* aPrincipal,
|
|
||||||
nsIContentSecurityPolicy* aCsp, nsICookieJarSettings* aCookieJarSettings,
|
|
||||||
nsIArray* aTransferableArray, uint32_t aActionType,
|
|
||||||
nsContentPolicyType aContentPolicyType = nsIContentPolicy::TYPE_OTHER);
|
|
||||||
|
|
||||||
/**
|
// The drag session representing the user's current actions, if any.
|
||||||
* Called from nsBaseDragService to initiate a platform drag from a source
|
// This value is only valid in the parent process. For child
|
||||||
* in this process. This is expected to ensure that StartDragSession() and
|
// process drag sessions, see BrowserChild and PuppetWidget.
|
||||||
* EndDragSession() get called if the platform drag is successfully invoked.
|
RefPtr<nsIDragSession> mCurrentParentDragSession;
|
||||||
*/
|
|
||||||
MOZ_CAN_RUN_SCRIPT virtual nsresult InvokeDragSessionImpl(
|
|
||||||
nsIWidget* aWidget, nsIArray* aTransferableArray,
|
|
||||||
const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
|
|
||||||
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.
|
|
||||||
*
|
|
||||||
* aRegion may be used to draw only a subset of the element. This region
|
|
||||||
* should be supplied using x and y coordinates measured in css pixels
|
|
||||||
* that are relative to the upper-left corner of the window.
|
|
||||||
*
|
|
||||||
* aScreenPosition should be the screen coordinates of the mouse click
|
|
||||||
* for the drag. These are in CSS pixels.
|
|
||||||
*
|
|
||||||
* On return, aScreenDragRect will contain the screen coordinates of the
|
|
||||||
* area being dragged. This is used by the platform-specific part of the
|
|
||||||
* drag service to determine the drag feedback. This rect will be in the
|
|
||||||
* device pixels of the presContext.
|
|
||||||
*
|
|
||||||
* If there is no drag image, the returned surface will be null, but
|
|
||||||
* aScreenDragRect will still be set to the drag area.
|
|
||||||
*
|
|
||||||
* aPresContext will be set to the nsPresContext used determined from
|
|
||||||
* whichever of mImage or aDOMNode is used.
|
|
||||||
*/
|
|
||||||
nsresult DrawDrag(nsINode* aDOMNode,
|
|
||||||
const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
|
|
||||||
mozilla::CSSIntPoint aScreenPosition,
|
|
||||||
mozilla::LayoutDeviceIntRect* aScreenDragRect,
|
|
||||||
RefPtr<SourceSurface>* aSurface,
|
|
||||||
nsPresContext** aPresContext);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Draw a drag image for an image node specified by aImageLoader or aCanvas.
|
|
||||||
* This is called by DrawDrag.
|
|
||||||
*/
|
|
||||||
nsresult DrawDragForImage(nsPresContext* aPresContext,
|
|
||||||
nsIImageLoadingContent* aImageLoader,
|
|
||||||
mozilla::dom::HTMLCanvasElement* aCanvas,
|
|
||||||
mozilla::LayoutDeviceIntRect* aScreenDragRect,
|
|
||||||
RefPtr<SourceSurface>* aSurface);
|
|
||||||
|
|
||||||
virtual bool IsMockService() { return false; }
|
|
||||||
|
|
||||||
// the contentpolicy type passed to the channel when initiating the drag
|
|
||||||
// session
|
|
||||||
nsContentPolicyType mContentPolicyType;
|
|
||||||
|
|
||||||
uint32_t mSuppressLevel;
|
|
||||||
|
|
||||||
// Sub-region for tree-selections.
|
// Sub-region for tree-selections.
|
||||||
mozilla::Maybe<mozilla::CSSIntRegion> mRegion;
|
mozilla::Maybe<mozilla::CSSIntRegion> mRegion;
|
||||||
|
|
||||||
RefPtr<mozilla::test::MockDragServiceController> mMockController;
|
RefPtr<mozilla::test::MockDragServiceController> mMockController;
|
||||||
|
|
||||||
|
// Weak references to PBrowsers that are currently engaged in drags.
|
||||||
|
// Once an nsIDragSession is created for the remote drag, these browsers
|
||||||
|
// will be moved to that object.
|
||||||
|
nsTArray<nsWeakPtr> mBrowsers;
|
||||||
|
|
||||||
|
uint32_t mSuppressLevel = 0;
|
||||||
|
|
||||||
// If this is set, mSessionIsSynthesizedForTests should not become true.
|
// If this is set, mSessionIsSynthesizedForTests should not become true.
|
||||||
// This hack is used to bypass the "old" drag-drop test behavior.
|
// This hack is used to bypass the "old" drag-drop test behavior.
|
||||||
// See nsIDragService.idl for details.
|
// See nsIDragService.idl for details.
|
||||||
|
|||||||
@@ -24,11 +24,36 @@ using mozilla::gfx::SourceSurface;
|
|||||||
using mozilla::gfx::SurfaceFormat;
|
using mozilla::gfx::SurfaceFormat;
|
||||||
using mozilla::ipc::Shmem;
|
using mozilla::ipc::Shmem;
|
||||||
|
|
||||||
nsDragServiceProxy::nsDragServiceProxy() = default;
|
|
||||||
|
|
||||||
nsDragServiceProxy::~nsDragServiceProxy() = default;
|
nsDragServiceProxy::~nsDragServiceProxy() = default;
|
||||||
|
|
||||||
nsresult nsDragServiceProxy::InvokeDragSessionImpl(
|
nsDragSessionProxy::~nsDragSessionProxy() = default;
|
||||||
|
|
||||||
|
already_AddRefed<nsIDragSession> nsDragServiceProxy::CreateDragSession() {
|
||||||
|
RefPtr<nsIDragSession> session = new nsDragSessionProxy();
|
||||||
|
return session.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsDragSessionProxy::InvokeDragSession(
|
||||||
|
nsIWidget* aWidget, nsINode* aDOMNode, nsIPrincipal* aPrincipal,
|
||||||
|
nsIContentSecurityPolicy* aCsp, nsICookieJarSettings* aCookieJarSettings,
|
||||||
|
nsIArray* aTransferableArray, uint32_t aActionType,
|
||||||
|
nsContentPolicyType aContentPolicyType) {
|
||||||
|
BrowserChild* sourceBrowser = aWidget->GetOwningBrowserChild();
|
||||||
|
NS_ENSURE_TRUE(sourceBrowser, NS_ERROR_INVALID_ARG);
|
||||||
|
[[maybe_unused]] RefPtr<nsIDragSession> sourceSession =
|
||||||
|
sourceBrowser->GetDragSession();
|
||||||
|
MOZ_ASSERT(!sourceSession);
|
||||||
|
nsresult rv = nsBaseDragSession::InvokeDragSession(aWidget, aDOMNode,
|
||||||
|
aPrincipal, aCsp, aCookieJarSettings, aTransferableArray, aActionType,
|
||||||
|
aContentPolicyType);
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
MOZ_ALWAYS_SUCCEEDS(sourceBrowser->GetWeakReference(getter_AddRefs(mSourceBrowser)));
|
||||||
|
sourceBrowser->SetDragSession(this);
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsDragSessionProxy::InvokeDragSessionImpl(
|
||||||
nsIWidget* aWidget, nsIArray* aArrayTransferables,
|
nsIWidget* aWidget, nsIArray* aArrayTransferables,
|
||||||
const Maybe<CSSIntRegion>& aRegion, uint32_t aActionType) {
|
const Maybe<CSSIntRegion>& aRegion, uint32_t aActionType) {
|
||||||
NS_ENSURE_STATE(mSourceDocument->GetDocShell());
|
NS_ENSURE_STATE(mSourceDocument->GetDocShell());
|
||||||
@@ -81,7 +106,6 @@ nsresult nsDragServiceProxy::InvokeDragSessionImpl(
|
|||||||
std::move(transferables), aActionType, std::move(surfaceData),
|
std::move(transferables), aActionType, std::move(surfaceData),
|
||||||
stride, dataSurface->GetFormat(), dragRect, principal, csp, csArgs,
|
stride, dataSurface->GetFormat(), dragRect, principal, csp, csArgs,
|
||||||
mSourceWindowContext, mSourceTopWindowContext);
|
mSourceWindowContext, mSourceTopWindowContext);
|
||||||
StartDragSession(aWidget);
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,6 +115,88 @@ nsresult nsDragServiceProxy::InvokeDragSessionImpl(
|
|||||||
std::move(transferables), aActionType, Nothing(), 0,
|
std::move(transferables), aActionType, Nothing(), 0,
|
||||||
static_cast<SurfaceFormat>(0), dragRect, principal, csp, csArgs,
|
static_cast<SurfaceFormat>(0), dragRect, principal, csp, csArgs,
|
||||||
mSourceWindowContext, mSourceTopWindowContext);
|
mSourceWindowContext, mSourceTopWindowContext);
|
||||||
StartDragSession(aWidget);
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDragServiceProxy::StartDragSession(nsISupports* aWidgetProvider) {
|
||||||
|
nsIWidget* widget = GetWidgetFromWidgetProvider(aWidgetProvider);
|
||||||
|
NS_ENSURE_TRUE(widget, NS_ERROR_INVALID_ARG);
|
||||||
|
BrowserChild* targetBrowser = widget->GetOwningBrowserChild();
|
||||||
|
NS_ENSURE_TRUE(targetBrowser, NS_ERROR_INVALID_ARG);
|
||||||
|
RefPtr<nsIDragSession> session = targetBrowser->GetDragSession();
|
||||||
|
if (session) {
|
||||||
|
// session already exists on the browser
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
session = CreateDragSession();
|
||||||
|
MOZ_ASSERT(session);
|
||||||
|
static_cast<nsDragSessionProxy*>(session.get())->SetDragTarget(targetBrowser);
|
||||||
|
targetBrowser->SetDragSession(session);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDragServiceProxy::GetCurrentSession(nsISupports* aWidgetProvider,
|
||||||
|
nsIDragSession** aSession) {
|
||||||
|
if (!aSession) {
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
*aSession = nullptr;
|
||||||
|
|
||||||
|
nsIWidget* widget = GetWidgetFromWidgetProvider(aWidgetProvider);
|
||||||
|
NS_ENSURE_TRUE(widget, NS_ERROR_INVALID_ARG);
|
||||||
|
BrowserChild* browser = widget->GetOwningBrowserChild();
|
||||||
|
NS_ENSURE_TRUE(browser, NS_ERROR_INVALID_ARG);
|
||||||
|
RefPtr<nsIDragSession> session = browser->GetDragSession();
|
||||||
|
|
||||||
|
if (!mSuppressLevel && session) {
|
||||||
|
session.forget(aSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsDragSessionProxy::SetDragTarget(BrowserChild* aTarget) {
|
||||||
|
if (!aTarget) {
|
||||||
|
if (mTargetBrowser) {
|
||||||
|
nsCOMPtr<BrowserChild> targetBC = do_QueryReferent(mTargetBrowser);
|
||||||
|
MOZ_ASSERT(targetBC);
|
||||||
|
if (targetBC) {
|
||||||
|
targetBC->SetDragSession(nullptr);
|
||||||
|
}
|
||||||
|
mTargetBrowser = nullptr;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
[[maybe_unused]] RefPtr<nsIDragSession> session =
|
||||||
|
aTarget->GetDragSession();
|
||||||
|
MOZ_ASSERT(!session);
|
||||||
|
MOZ_ALWAYS_SUCCEEDS(aTarget->GetWeakReference(getter_AddRefs(mTargetBrowser)));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsDragSessionProxy::EndDragSessionImpl(bool aDoneDrag,
|
||||||
|
uint32_t aKeyModifiers) {
|
||||||
|
if (mSourceBrowser) {
|
||||||
|
nsCOMPtr<BrowserChild> sourceBC = do_QueryReferent(mSourceBrowser);
|
||||||
|
MOZ_ASSERT(sourceBC);
|
||||||
|
[[maybe_unused]] RefPtr<nsIDragSession> session =
|
||||||
|
sourceBC->GetDragSession();
|
||||||
|
MOZ_ASSERT(session == this);
|
||||||
|
sourceBC->SetDragSession(nullptr);
|
||||||
|
mSourceBrowser = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTargetBrowser) {
|
||||||
|
nsCOMPtr<BrowserChild> targetBC = do_QueryReferent(mTargetBrowser);
|
||||||
|
MOZ_ASSERT(targetBC);
|
||||||
|
[[maybe_unused]] RefPtr<nsIDragSession> session =
|
||||||
|
targetBC->GetDragSession();
|
||||||
|
MOZ_ASSERT(session == this);
|
||||||
|
targetBC->SetDragSession(nullptr);
|
||||||
|
mTargetBrowser = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nsBaseDragSession::EndDragSessionImpl(aDoneDrag, aKeyModifiers);
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,26 +8,48 @@
|
|||||||
|
|
||||||
#include "nsBaseDragService.h"
|
#include "nsBaseDragService.h"
|
||||||
|
|
||||||
// Temporary inheritance from nsBaseDragService instead of nsBaseDragSession
|
class nsDragSessionProxy : public nsBaseDragSession {
|
||||||
// (which nsBaseDragService temporarily inherits).
|
|
||||||
// This will be undone at the end of this patch series.
|
|
||||||
class nsDragSessionProxy : public nsBaseDragService {};
|
|
||||||
|
|
||||||
// Temporary inheritance from nsDragSessionProxy instead of nsBaseDragService
|
|
||||||
// (which nsDragSession temporarily inherits).
|
|
||||||
// This will be undone at the end of this patch series.
|
|
||||||
class nsDragServiceProxy final : public nsDragSessionProxy {
|
|
||||||
public:
|
public:
|
||||||
nsDragServiceProxy();
|
NS_INLINE_DECL_REFCOUNTING_INHERITED(nsDragSessionProxy, nsBaseDragSession)
|
||||||
|
|
||||||
NS_INLINE_DECL_REFCOUNTING_INHERITED(nsDragServiceProxy, nsDragSessionProxy)
|
MOZ_CAN_RUN_SCRIPT virtual nsresult InvokeDragSession(
|
||||||
|
nsIWidget* aWidget, nsINode* aDOMNode, nsIPrincipal* aPrincipal,
|
||||||
|
nsIContentSecurityPolicy* aCsp, nsICookieJarSettings* aCookieJarSettings,
|
||||||
|
nsIArray* aTransferableArray, uint32_t aActionType,
|
||||||
|
nsContentPolicyType aContentPolicyType) override;
|
||||||
|
|
||||||
// nsBaseDragService
|
nsresult InvokeDragSessionImpl(
|
||||||
virtual nsresult InvokeDragSessionImpl(
|
|
||||||
nsIWidget* aWidget, nsIArray* anArrayTransferables,
|
nsIWidget* aWidget, nsIArray* anArrayTransferables,
|
||||||
const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
|
const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
|
||||||
uint32_t aActionType) override;
|
uint32_t aActionType) override;
|
||||||
|
|
||||||
|
void SetDragTarget(mozilla::dom::BrowserChild* aTarget);
|
||||||
|
|
||||||
|
MOZ_CAN_RUN_SCRIPT
|
||||||
|
nsresult EndDragSessionImpl(bool aDoneDrag, uint32_t aKeyModifiers) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
~nsDragSessionProxy();
|
||||||
|
|
||||||
|
// The source for this drag. This is null if the source is a different
|
||||||
|
// application or drag session.
|
||||||
|
nsWeakPtr mSourceBrowser;
|
||||||
|
// The target for this drag. This is null if the target is a different
|
||||||
|
// application or drag session.
|
||||||
|
nsWeakPtr mTargetBrowser;
|
||||||
|
};
|
||||||
|
|
||||||
|
class nsDragServiceProxy : public nsBaseDragService {
|
||||||
|
public:
|
||||||
|
NS_INLINE_DECL_REFCOUNTING_INHERITED(nsDragServiceProxy, nsBaseDragService)
|
||||||
|
|
||||||
|
already_AddRefed<nsIDragSession> CreateDragSession() override;
|
||||||
|
|
||||||
|
NS_IMETHOD StartDragSession(nsISupports* aWidgetProvider) override;
|
||||||
|
|
||||||
|
NS_IMETHOD GetCurrentSession(nsISupports* aWidgetProvider,
|
||||||
|
nsIDragSession** aSession) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual ~nsDragServiceProxy();
|
virtual ~nsDragServiceProxy();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -128,15 +128,7 @@ interface nsIDragService : nsISupports
|
|||||||
*/
|
*/
|
||||||
nsIDragSession getCurrentSession([optional] in nsISupports aWidgetProvider);
|
nsIDragSession getCurrentSession([optional] in nsISupports aWidgetProvider);
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: Temporary proxy for old C++ callers, for whom [optional] is
|
|
||||||
* insufficient. This method is removed at the end of this patch series.
|
|
||||||
*/
|
|
||||||
%{ C++
|
%{ C++
|
||||||
nsresult GetCurrentSession(nsIDragSession** aSession) {
|
|
||||||
return GetCurrentSession(nullptr, aSession);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIDragSession* GetCurrentSession(nsIWidget* aWidget) {
|
nsIDragSession* GetCurrentSession(nsIWidget* aWidget) {
|
||||||
nsCOMPtr<nsIDragSession> session;
|
nsCOMPtr<nsIDragSession> session;
|
||||||
GetCurrentSession(aWidget, getter_AddRefs(session));
|
GetCurrentSession(aWidget, getter_AddRefs(session));
|
||||||
@@ -195,6 +187,20 @@ interface nsIDragService : nsISupports
|
|||||||
*/
|
*/
|
||||||
nsIMockDragServiceController getMockDragController();
|
nsIMockDragServiceController getMockDragController();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if this is a mock nsIDragService, created with
|
||||||
|
* createMockDragController().
|
||||||
|
*/
|
||||||
|
readonly attribute boolean isMockService;
|
||||||
|
|
||||||
|
%{ C++
|
||||||
|
bool IsMockService() {
|
||||||
|
bool ret = false;
|
||||||
|
MOZ_ALWAYS_SUCCEEDS(GetIsMockService(&ret));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this is true, mSessionIsSynthesizedForTests should not become true.
|
* If this is true, mSessionIsSynthesizedForTests should not become true.
|
||||||
* This hack is used to bypass the "old" drag-drop test behavior, which needed
|
* This hack is used to bypass the "old" drag-drop test behavior, which needed
|
||||||
|
|||||||
@@ -137,6 +137,12 @@ interface nsIDragSession : nsISupports
|
|||||||
// nsIDragService::InvokeDragSessionWithImage.
|
// nsIDragService::InvokeDragSessionWithImage.
|
||||||
void updateDragImage(in Node aImage, in long aImageX, in long aImageY);
|
void updateDragImage(in Node aImage, in long aImageX, in long aImageY);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tell Gecko that this session is generated for automated testing.
|
||||||
|
* This should be called immediately after StartDragSession when testing.
|
||||||
|
*/
|
||||||
|
[noscript] void InitForTests(in uint32_t aAllowedEffect);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns effects allowed at starting the session for tests.
|
* Returns effects allowed at starting the session for tests.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -46,13 +46,13 @@ using namespace mozilla;
|
|||||||
using namespace mozilla::gfx;
|
using namespace mozilla::gfx;
|
||||||
using namespace mozilla::widget;
|
using namespace mozilla::widget;
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// DragService destructor
|
|
||||||
//
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
nsDragSession::~nsDragSession() { NS_IF_RELEASE(mDataObject); }
|
nsDragSession::~nsDragSession() { NS_IF_RELEASE(mDataObject); }
|
||||||
|
|
||||||
|
already_AddRefed<nsIDragSession> nsDragService::CreateDragSession() {
|
||||||
|
RefPtr<nsIDragSession> session = new nsDragSession();
|
||||||
|
return session.forget();
|
||||||
|
}
|
||||||
|
|
||||||
bool nsDragSession::CreateDragImage(nsINode* aDOMNode,
|
bool nsDragSession::CreateDragImage(nsINode* aDOMNode,
|
||||||
const Maybe<CSSIntRegion>& aRegion,
|
const Maybe<CSSIntRegion>& aRegion,
|
||||||
SHDRAGIMAGE* psdi) {
|
SHDRAGIMAGE* psdi) {
|
||||||
@@ -140,7 +140,7 @@ bool nsDragSession::CreateDragImage(nsINode* aDOMNode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
nsresult nsDragService::InvokeDragSessionImpl(
|
nsresult nsDragSession::InvokeDragSessionImpl(
|
||||||
nsIWidget* aWidget, nsIArray* anArrayTransferables,
|
nsIWidget* aWidget, nsIArray* anArrayTransferables,
|
||||||
const Maybe<CSSIntRegion>& aRegion, uint32_t aActionType) {
|
const Maybe<CSSIntRegion>& aRegion, uint32_t aActionType) {
|
||||||
// Try and get source URI of the items that are being dragged
|
// Try and get source URI of the items that are being dragged
|
||||||
@@ -229,7 +229,7 @@ static HWND GetSourceWindow(dom::Document* aSourceDocument) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
nsresult nsDragService::StartInvokingDragSession(nsIWidget* aWidget,
|
nsresult nsDragSession::StartInvokingDragSession(nsIWidget* aWidget,
|
||||||
IDataObject* aDataObj,
|
IDataObject* aDataObj,
|
||||||
uint32_t aActionType) {
|
uint32_t aActionType) {
|
||||||
// To do the drag we need to create an object that
|
// To do the drag we need to create an object that
|
||||||
@@ -240,13 +240,13 @@ nsresult nsDragService::StartInvokingDragSession(nsIWidget* aWidget,
|
|||||||
// Now figure out what the native drag effect should be
|
// Now figure out what the native drag effect should be
|
||||||
DWORD winDropRes;
|
DWORD winDropRes;
|
||||||
DWORD effects = DROPEFFECT_SCROLL;
|
DWORD effects = DROPEFFECT_SCROLL;
|
||||||
if (aActionType & DRAGDROP_ACTION_COPY) {
|
if (aActionType & nsIDragService::DRAGDROP_ACTION_COPY) {
|
||||||
effects |= DROPEFFECT_COPY;
|
effects |= DROPEFFECT_COPY;
|
||||||
}
|
}
|
||||||
if (aActionType & DRAGDROP_ACTION_MOVE) {
|
if (aActionType & nsIDragService::DRAGDROP_ACTION_MOVE) {
|
||||||
effects |= DROPEFFECT_MOVE;
|
effects |= DROPEFFECT_MOVE;
|
||||||
}
|
}
|
||||||
if (aActionType & DRAGDROP_ACTION_LINK) {
|
if (aActionType & nsIDragService::DRAGDROP_ACTION_LINK) {
|
||||||
effects |= DROPEFFECT_LINK;
|
effects |= DROPEFFECT_LINK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,7 +256,6 @@ nsresult nsDragService::StartInvokingDragSession(nsIWidget* aWidget,
|
|||||||
mSentLocalDropEvent = false;
|
mSentLocalDropEvent = false;
|
||||||
|
|
||||||
// Start dragging
|
// Start dragging
|
||||||
StartDragSession(aWidget);
|
|
||||||
OpenDragPopup();
|
OpenDragPopup();
|
||||||
|
|
||||||
RefPtr<IDataObjectAsyncCapability> pAsyncOp;
|
RefPtr<IDataObjectAsyncCapability> pAsyncOp;
|
||||||
@@ -277,19 +276,19 @@ nsresult nsDragService::StartInvokingDragSession(nsIWidget* aWidget,
|
|||||||
uint32_t dropResult;
|
uint32_t dropResult;
|
||||||
// Order is important, since multiple flags can be returned.
|
// Order is important, since multiple flags can be returned.
|
||||||
if (winDropRes & DROPEFFECT_COPY)
|
if (winDropRes & DROPEFFECT_COPY)
|
||||||
dropResult = DRAGDROP_ACTION_COPY;
|
dropResult = nsIDragService::DRAGDROP_ACTION_COPY;
|
||||||
else if (winDropRes & DROPEFFECT_LINK)
|
else if (winDropRes & DROPEFFECT_LINK)
|
||||||
dropResult = DRAGDROP_ACTION_LINK;
|
dropResult = nsIDragService::DRAGDROP_ACTION_LINK;
|
||||||
else if (winDropRes & DROPEFFECT_MOVE)
|
else if (winDropRes & DROPEFFECT_MOVE)
|
||||||
dropResult = DRAGDROP_ACTION_MOVE;
|
dropResult = nsIDragService::DRAGDROP_ACTION_MOVE;
|
||||||
else
|
else
|
||||||
dropResult = DRAGDROP_ACTION_NONE;
|
dropResult = nsIDragService::DRAGDROP_ACTION_NONE;
|
||||||
|
|
||||||
if (mDataTransfer) {
|
if (mDataTransfer) {
|
||||||
if (res == DRAGDROP_S_DROP) // Success
|
if (res == DRAGDROP_S_DROP) // Success
|
||||||
mDataTransfer->SetDropEffectInt(dropResult);
|
mDataTransfer->SetDropEffectInt(dropResult);
|
||||||
else
|
else
|
||||||
mDataTransfer->SetDropEffectInt(DRAGDROP_ACTION_NONE);
|
mDataTransfer->SetDropEffectInt(nsIDragService::DRAGDROP_ACTION_NONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,11 +309,8 @@ nsresult nsDragService::StartInvokingDragSession(nsIWidget* aWidget,
|
|||||||
}
|
}
|
||||||
SetDragEndPoint(LayoutDeviceIntPoint(cpos.x, cpos.y));
|
SetDragEndPoint(LayoutDeviceIntPoint(cpos.x, cpos.y));
|
||||||
|
|
||||||
RefPtr<nsIDragSession> session = GetCurrentSession(aWidget);
|
|
||||||
if (session) {
|
|
||||||
ModifierKeyState modifierKeyState;
|
ModifierKeyState modifierKeyState;
|
||||||
session->EndDragSession(true, modifierKeyState.GetModifiers());
|
EndDragSession(true, modifierKeyState.GetModifiers());
|
||||||
}
|
|
||||||
|
|
||||||
mDoingDrag = false;
|
mDoingDrag = false;
|
||||||
|
|
||||||
@@ -471,7 +467,7 @@ void nsDragSession::SetIDataObject(IDataObject* aDataObj) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
void nsDragService::SetDroppedLocal() {
|
void nsDragSession::SetDroppedLocal() {
|
||||||
// Sent from the native drag handler, letting us know
|
// Sent from the native drag handler, letting us know
|
||||||
// a drop occurred within the application vs. outside of it.
|
// a drop occurred within the application vs. outside of it.
|
||||||
mSentLocalDropEvent = true;
|
mSentLocalDropEvent = true;
|
||||||
|
|||||||
@@ -13,10 +13,10 @@
|
|||||||
struct IDataObject;
|
struct IDataObject;
|
||||||
class nsDataObjCollection;
|
class nsDataObjCollection;
|
||||||
|
|
||||||
// Temporary inheritance from nsBaseDragService instead of nsBaseDragSession
|
/**
|
||||||
// (which nsBaseDragService temporarily inherits).
|
* Windows native nsIDragSession implementation
|
||||||
// This will be undone at the end of this patch series.
|
*/
|
||||||
class nsDragSession : public nsBaseDragService {
|
class nsDragSession : public nsBaseDragSession {
|
||||||
public:
|
public:
|
||||||
virtual ~nsDragSession();
|
virtual ~nsDragSession();
|
||||||
|
|
||||||
@@ -30,9 +30,21 @@ class nsDragSession : public nsBaseDragService {
|
|||||||
void SetIDataObject(IDataObject* aDataObj);
|
void SetIDataObject(IDataObject* aDataObj);
|
||||||
IDataObject* GetDataObject() { return mDataObject; }
|
IDataObject* GetDataObject() { return mDataObject; }
|
||||||
|
|
||||||
|
MOZ_CAN_RUN_SCRIPT virtual nsresult InvokeDragSessionImpl(
|
||||||
|
nsIWidget* aWidget, nsIArray* anArrayTransferables,
|
||||||
|
const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
|
||||||
|
uint32_t aActionType);
|
||||||
|
|
||||||
MOZ_CAN_RUN_SCRIPT nsresult EndDragSessionImpl(
|
MOZ_CAN_RUN_SCRIPT nsresult EndDragSessionImpl(
|
||||||
bool aDoneDrag, uint32_t aKeyModifiers) override;
|
bool aDoneDrag, uint32_t aKeyModifiers) override;
|
||||||
|
|
||||||
|
MOZ_CAN_RUN_SCRIPT nsresult StartInvokingDragSession(nsIWidget* aWidget,
|
||||||
|
IDataObject* aDataObj,
|
||||||
|
uint32_t aActionType);
|
||||||
|
|
||||||
|
// A drop occurred within the application vs. outside of it.
|
||||||
|
void SetDroppedLocal();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// determine if we have a single data object or one of our private
|
// determine if we have a single data object or one of our private
|
||||||
// collections
|
// collections
|
||||||
@@ -45,29 +57,16 @@ class nsDragSession : public nsBaseDragService {
|
|||||||
SHDRAGIMAGE* psdi);
|
SHDRAGIMAGE* psdi);
|
||||||
|
|
||||||
IDataObject* mDataObject = nullptr;
|
IDataObject* mDataObject = nullptr;
|
||||||
};
|
|
||||||
|
|
||||||
// Temporary inheritance from nsDragSession instead of nsBaseDragService
|
|
||||||
// (which nsDragSession temporarily inherits).
|
|
||||||
// This will be undone at the end of this patch series.
|
|
||||||
class nsDragService final : public nsDragSession {
|
|
||||||
public:
|
|
||||||
// nsBaseDragService
|
|
||||||
MOZ_CAN_RUN_SCRIPT virtual nsresult InvokeDragSessionImpl(
|
|
||||||
nsIWidget* aWidget, nsIArray* anArrayTransferables,
|
|
||||||
const mozilla::Maybe<mozilla::CSSIntRegion>& aRegion,
|
|
||||||
uint32_t aActionType);
|
|
||||||
|
|
||||||
// native impl.
|
|
||||||
MOZ_CAN_RUN_SCRIPT nsresult StartInvokingDragSession(nsIWidget* aWidget,
|
|
||||||
IDataObject* aDataObj,
|
|
||||||
uint32_t aActionType);
|
|
||||||
|
|
||||||
// A drop occurred within the application vs. outside of it.
|
|
||||||
void SetDroppedLocal();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool mSentLocalDropEvent = false;
|
bool mSentLocalDropEvent = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Windows native nsIDragService implementation
|
||||||
|
*/
|
||||||
|
class nsDragService final : public nsBaseDragService {
|
||||||
|
public:
|
||||||
|
already_AddRefed<nsIDragSession> CreateDragSession() override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
#endif // nsDragService_h__
|
#endif // nsDragService_h__
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "nsClipboard.h"
|
#include "nsClipboard.h"
|
||||||
#include "KeyboardLayout.h"
|
#include "KeyboardLayout.h"
|
||||||
|
|
||||||
|
#include "mozilla/dom/MouseEventBinding.h"
|
||||||
#include "mozilla/MouseEvents.h"
|
#include "mozilla/MouseEvents.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
@@ -152,8 +153,13 @@ void nsNativeDragTarget::DispatchDragDropEvent(EventMessage aEventMessage,
|
|||||||
ModifierKeyState modifierKeyState;
|
ModifierKeyState modifierKeyState;
|
||||||
modifierKeyState.InitInputEvent(event);
|
modifierKeyState.InitInputEvent(event);
|
||||||
|
|
||||||
event.mInputSource =
|
nsDragSession* currSession =
|
||||||
static_cast<nsBaseDragService*>(mDragService.get())->GetInputSource();
|
static_cast<nsDragSession*>(mDragService->GetCurrentSession(mWidget));
|
||||||
|
if (currSession) {
|
||||||
|
event.mInputSource = currSession->GetInputSource();
|
||||||
|
} else {
|
||||||
|
event.mInputSource = dom::MouseEvent_Binding::MOZ_SOURCE_MOUSE;
|
||||||
|
}
|
||||||
|
|
||||||
mWidget->DispatchInputEvent(&event);
|
mWidget->DispatchInputEvent(&event);
|
||||||
}
|
}
|
||||||
@@ -426,14 +432,12 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pData, DWORD grfKeyState, POINTL aPT,
|
|||||||
return S_OK; // DragCancel() was called.
|
return S_OK; // DragCancel() was called.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let the win drag service know whether this session experienced
|
// Let the win drag session know whether it experienced
|
||||||
// a drop event within the application. Drop will not oocur if the
|
// a drop event within the application. Drop will not oocur if the
|
||||||
// drop landed outside the app. (used in tab tear off, bug 455884)
|
// drop landed outside the app. (used in tab tear off, bug 455884)
|
||||||
RefPtr<nsDragService> winDragService =
|
currentDragSession->SetDroppedLocal();
|
||||||
static_cast<nsDragService*>(mDragService.get());
|
|
||||||
winDragService->SetDroppedLocal();
|
|
||||||
|
|
||||||
// tell the drag service we're done with the session
|
// Tell the drag session we're done with it.
|
||||||
// Use GetMessagePos to get the position of the mouse at the last message
|
// Use GetMessagePos to get the position of the mouse at the last message
|
||||||
// seen by the event loop. (Bug 489729)
|
// seen by the event loop. (Bug 489729)
|
||||||
DWORD pos = ::GetMessagePos();
|
DWORD pos = ::GetMessagePos();
|
||||||
|
|||||||
Reference in New Issue
Block a user