Bug 1893119: Part 3 - Add widget to nsContentUtils::GetDragSession a=diannaS

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.

Original Revision: https://phabricator.services.mozilla.com/D211067

Differential Revision: https://phabricator.services.mozilla.com/D221156
This commit is contained in:
David P 2024-09-06 14:44:11 +00:00
parent bfefb51a43
commit 4be02b2419
14 changed files with 73 additions and 21 deletions

View file

@ -6347,14 +6347,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()) {
@ -6367,7 +6376,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

@ -2211,7 +2211,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

@ -2296,6 +2296,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

@ -2027,7 +2027,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;
@ -4226,7 +4228,8 @@ nsresult EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
}
}
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
nsCOMPtr<nsIDragSession> dragSession =
nsContentUtils::GetDragSession(mPresContext);
if (!dragSession) break;
// Reset the flag.
@ -4343,7 +4346,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());
@ -5794,7 +5798,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

@ -1872,7 +1872,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);
@ -3775,6 +3775,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

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

View file

@ -1597,7 +1597,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

@ -3246,7 +3246,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

@ -5571,7 +5571,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

@ -4620,7 +4620,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

@ -5773,7 +5773,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;
@ -5785,9 +5791,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;
}
@ -8529,7 +8534,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

@ -706,8 +706,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"