Bug 1893119: Part 3 - Add widget to nsContentUtils::GetDragSession r=gstoll,rkraesig

Updates each client of the nsContentUtils method to get the right drag session -- the one for the widget that is currently the source or target of the drag session.
The change to nsDOMWindowUtils::DispatchDOMEventViaPresShellForTesting() supports the change to WidgetDragEvent::InitDropEffectForTests() and enabled a
large number of test fixes in the next patch.

Differential Revision: https://phabricator.services.mozilla.com/D211067
This commit is contained in:
David P
2024-07-04 07:48:04 +00:00
parent 6755e73ac9
commit 805b8742ba
14 changed files with 73 additions and 21 deletions

View File

@@ -6375,14 +6375,23 @@ void nsContentUtils::HidePopupsInDocument(Document* aDocument) {
}
/* static */
already_AddRefed<nsIDragSession> nsContentUtils::GetDragSession() {
already_AddRefed<nsIDragSession> nsContentUtils::GetDragSession(
nsIWidget* aWidget) {
nsCOMPtr<nsIDragSession> dragSession;
nsCOMPtr<nsIDragService> dragService =
do_GetService("@mozilla.org/widget/dragservice;1");
if (dragService) dragService->GetCurrentSession(getter_AddRefs(dragSession));
if (dragService) {
dragSession = dragService->GetCurrentSession(aWidget);
}
return dragSession.forget();
}
/* static */
already_AddRefed<nsIDragSession> nsContentUtils::GetDragSession(
nsPresContext* aPC) {
return GetDragSession(aPC->GetRootWidget());
}
/* static */
nsresult nsContentUtils::SetDataTransferInEvent(WidgetDragEvent* aDragEvent) {
if (aDragEvent->mDataTransfer || !aDragEvent->IsTrusted()) {
@@ -6395,7 +6404,7 @@ nsresult nsContentUtils::SetDataTransferInEvent(WidgetDragEvent* aDragEvent) {
NS_ASSERTION(aDragEvent->mMessage != eDragStart,
"draggesture event created without a dataTransfer");
nsCOMPtr<nsIDragSession> dragSession = GetDragSession();
nsCOMPtr<nsIDragSession> dragSession = GetDragSession(aDragEvent->mWidget);
NS_ENSURE_TRUE(dragSession, NS_OK); // no drag in progress
RefPtr<DataTransfer> initialDataTransfer = dragSession->GetDataTransfer();

View File

@@ -2231,7 +2231,9 @@ class nsContentUtils {
/**
* Retrieve the current drag session, or null if no drag is currently occuring
*/
static already_AddRefed<nsIDragSession> GetDragSession();
static already_AddRefed<nsIDragSession> GetDragSession(nsIWidget* aWidget);
static already_AddRefed<nsIDragSession> GetDragSession(nsPresContext* aPC);
/*
* Initialize and set the dataTransfer field of an WidgetDragEvent.

View File

@@ -2295,6 +2295,12 @@ NS_IMETHODIMP nsDOMWindowUtils::DispatchDOMEventViaPresShellForTesting(
RefPtr<PresShell> targetPresShell = targetDoc->GetPresShell();
NS_ENSURE_STATE(targetPresShell);
WidgetGUIEvent* guiEvent = internalEvent->AsGUIEvent();
if (guiEvent && !guiEvent->mWidget) {
auto* pc = GetPresContext();
guiEvent->mWidget = pc ? pc->GetRootWidget() : nullptr;
}
targetDoc->FlushPendingNotifications(FlushType::Layout);
nsEventStatus status = nsEventStatus_eIgnore;

View File

@@ -2034,7 +2034,9 @@ void EventStateManager::DispatchCrossProcessEvent(WidgetEvent* aEvent,
browserParent->Manager()->MaybeInvokeDragSession(browserParent,
aEvent->mMessage);
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
RefPtr<nsIWidget> widget = browserParent->GetTopLevelWidget();
nsCOMPtr<nsIDragSession> dragSession =
nsContentUtils::GetDragSession(widget);
uint32_t dropEffect = nsIDragService::DRAGDROP_ACTION_NONE;
uint32_t action = nsIDragService::DRAGDROP_ACTION_NONE;
nsCOMPtr<nsIPrincipal> principal;
@@ -4243,7 +4245,8 @@ nsresult EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
}
}
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
nsCOMPtr<nsIDragSession> dragSession =
nsContentUtils::GetDragSession(mPresContext);
if (!dragSession) break;
// Reset the flag.
@@ -4360,7 +4363,8 @@ nsresult EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
if (aEvent->mFlags.mIsSynthesizedForTests) {
nsCOMPtr<nsIDragService> dragService =
do_GetService("@mozilla.org/widget/dragservice;1");
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
nsCOMPtr<nsIDragSession> dragSession =
nsContentUtils::GetDragSession(mPresContext);
if (dragSession && dragService &&
!dragService->GetNeverAllowSessionIsSynthesizedForTests()) {
MOZ_ASSERT(dragSession->IsSynthesizedForTests());
@@ -5811,7 +5815,8 @@ void EventStateManager::UpdateDragDataTransfer(WidgetDragEvent* dragEvent) {
return;
}
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
nsCOMPtr<nsIDragSession> dragSession =
nsContentUtils::GetDragSession(mPresContext);
if (dragSession) {
// the initial dataTransfer is the one from the dragstart event that

View File

@@ -1892,7 +1892,7 @@ mozilla::ipc::IPCResult BrowserChild::RecvRealDragEvent(
WidgetDragEvent localEvent(aEvent);
localEvent.mWidget = mPuppetWidget;
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
nsCOMPtr<nsIDragSession> dragSession = GetDragSession();
if (dragSession) {
dragSession->SetDragAction(aDragAction);
dragSession->SetTriggeringPrincipal(aPrincipal);
@@ -3795,6 +3795,12 @@ BrowserChild::ContentTransformsReceived(JSContext* aCx,
return rv.StealNSResult();
}
already_AddRefed<nsIDragSession> BrowserChild::GetDragSession() {
RefPtr<nsIDragSession> session =
nsContentUtils::GetDragSession(mPuppetWidget);
return session.forget();
}
BrowserChildMessageManager::BrowserChildMessageManager(
BrowserChild* aBrowserChild)
: ContentFrameMessageManager(new nsFrameMessageManager(aBrowserChild)),

View File

@@ -657,6 +657,8 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
aCanvasFingerprinter,
const Maybe<bool> aCanvasFingerprinterKnownText);
already_AddRefed<nsIDragSession> GetDragSession();
protected:
virtual ~BrowserChild();

View File

@@ -1625,7 +1625,9 @@ LayoutDeviceToCSSScale BrowserParent::GetLayoutDeviceToCSSScale() {
bool BrowserParent::QueryDropLinksForVerification() {
// Before sending the dragEvent, we query the links being dragged and
// store them on the parent, to make sure the child can not modify links.
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
RefPtr<nsIWidget> widget = GetTopLevelWidget();
nsCOMPtr<nsIDragSession> dragSession =
nsContentUtils::GetDragSession(widget);
if (!dragSession) {
NS_WARNING("No dragSession to query links for verification");
return false;

View File

@@ -3305,7 +3305,8 @@ mozilla::ipc::IPCResult ContentChild::RecvEndDragSession(
nsCOMPtr<nsIDragService> dragService =
do_GetService("@mozilla.org/widget/dragservice;1");
if (dragService) {
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
nsCOMPtr<nsIDragSession> dragSession;
dragService->GetCurrentSession(getter_AddRefs(dragSession));
if (dragSession) {
if (aUserCancelled) {
dragSession->UserCancelled();

View File

@@ -5248,7 +5248,13 @@ void ContentParent::MaybeInvokeDragSession(BrowserParent* aParent,
mozilla::ipc::IPCResult ContentParent::RecvUpdateDropEffect(
const uint32_t& aDragAction, const uint32_t& aDropEffect) {
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
nsCOMPtr<nsIDragService> dragService =
do_GetService("@mozilla.org/widget/dragservice;1");
if (!dragService) {
return IPC_OK();
}
nsCOMPtr<nsIDragSession> dragSession;
dragService->GetCurrentSession(getter_AddRefs(dragSession));
if (dragSession) {
dragSession->SetDragAction(aDragAction);
RefPtr<DataTransfer> dt = dragSession->GetDataTransfer();

View File

@@ -4622,7 +4622,9 @@ nsresult EditorBase::HandleDropEvent(DragEvent* aDropEvent) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
RefPtr<nsIWidget> widget = GetWidget();
nsCOMPtr<nsIDragSession> dragSession =
nsContentUtils::GetDragSession(widget);
if (NS_WARN_IF(!dragSession)) {
return NS_ERROR_FAILURE;
}

View File

@@ -5758,7 +5758,13 @@ static BrowserBridgeChild* GetChildBrowser(nsView* aView) {
void PresShell::ProcessSynthMouseMoveEvent(bool aFromScroll) {
// If drag session has started, we shouldn't synthesize mousemove event.
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
nsView* rootView = mViewManager ? mViewManager->GetRootView() : nullptr;
if (!rootView || !rootView->HasWidget()) {
mSynthMouseMoveEvent.Forget();
return;
}
nsCOMPtr<nsIDragSession> dragSession =
nsContentUtils::GetDragSession(rootView->GetWidget());
if (dragSession) {
mSynthMouseMoveEvent.Forget();
return;
@@ -5770,9 +5776,8 @@ void PresShell::ProcessSynthMouseMoveEvent(bool aFromScroll) {
mSynthMouseMoveEvent.Forget();
}
nsView* rootView = mViewManager ? mViewManager->GetRootView() : nullptr;
if (mMouseLocation == nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) ||
!rootView || !rootView->HasWidget() || !mPresContext) {
!mPresContext) {
mSynthMouseMoveEvent.Forget();
return;
}
@@ -8521,7 +8526,8 @@ bool PresShell::EventHandler::PrepareToDispatchEvent(
return true;
}
case eDrop: {
nsCOMPtr<nsIDragSession> session = nsContentUtils::GetDragSession();
nsCOMPtr<nsIDragSession> session =
nsContentUtils::GetDragSession(GetPresContext());
if (session) {
bool onlyChromeDrop = false;
session->GetOnlyChromeDrop(&onlyChromeDrop);

View File

@@ -143,7 +143,8 @@ void nsTextControlFrame::Destroy(DestroyContext& aContext) {
// text node in the text control. If so, we should set source node to the
// text control because another text node may be recreated soon if the text
// control is just reframed.
if (nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession()) {
if (nsCOMPtr<nsIDragSession> dragSession =
nsContentUtils::GetDragSession(PresContext())) {
if (dragSession->IsDraggingTextInTextControl() && mRootNode &&
mRootNode->GetFirstChild()) {
nsCOMPtr<nsINode> sourceNode;
@@ -481,7 +482,8 @@ bool nsTextControlFrame::ShouldInitializeEagerly() const {
// If text in the editor is being dragged, we need the editor to create
// new source node for the drag session (TextEditor creates the text node
// in the anonymous <div> element.
if (nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession()) {
if (nsCOMPtr<nsIDragSession> dragSession =
nsContentUtils::GetDragSession(PresContext())) {
if (dragSession->IsDraggingTextInTextControl()) {
nsCOMPtr<nsINode> sourceNode;
if (NS_SUCCEEDED(
@@ -1216,7 +1218,8 @@ nsTextControlFrame::EditorInitializer::Run() {
// and its source node is the text control element, we're being reframed.
// In this case we should restore the source node of the drag session to
// new text node because it's required for dispatching `dragend` event.
if (nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession()) {
if (nsCOMPtr<nsIDragSession> dragSession =
nsContentUtils::GetDragSession(mFrame->PresContext())) {
if (dragSession->IsDraggingTextInTextControl()) {
nsCOMPtr<nsINode> sourceNode;
if (NS_SUCCEEDED(

View File

@@ -749,8 +749,9 @@ void WidgetMouseEvent::AssertContextMenuEventButtonConsistency() const {
void WidgetDragEvent::InitDropEffectForTests() {
MOZ_ASSERT(mFlags.mIsSynthesizedForTests);
MOZ_ASSERT(mWidget);
nsCOMPtr<nsIDragSession> session = nsContentUtils::GetDragSession();
nsCOMPtr<nsIDragSession> session = nsContentUtils::GetDragSession(mWidget);
if (NS_WARN_IF(!session)) {
return;
}

View File

@@ -61,6 +61,7 @@
#include "mozilla/webrender/WebRenderTypes.h"
#include "mozilla/widget/ScreenManager.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsBaseDragService.h"
#include "nsCOMPtr.h"
#include "nsContentUtils.h"
#include "nsDeviceContext.h"