From 8e5ab999d2f040ee05e4aa873dd63ef8a28abd24 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Sat, 2 Feb 2019 02:20:25 +0000 Subject: [PATCH] Bug 1466208 - part 9: Create PresShell::EventHandler::MaybeHandleEventWithAnotherPresShell() to handle event with another PresShell if necessary r=smaug Let's move the redirection of coming event in PresShell::EventHandler::HandleEvent() into a method. This makes the caller easier to read. Differential Revision: https://phabricator.services.mozilla.com/D16959 --- layout/base/PresShell.cpp | 65 +++++++++++++++++++++++++++++---------- layout/base/PresShell.h | 22 +++++++++++++ 2 files changed, 71 insertions(+), 16 deletions(-) diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp index ff0b7b8f47255..49c7a5cf6e692 100644 --- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -6521,22 +6521,13 @@ nsresult PresShell::EventHandler::HandleEvent(nsIFrame* aFrame, } if (!aDontRetargetEvents) { - RefPtr retargetEventDoc; - if (!GetRetargetEventDocument(aGUIEvent, - getter_AddRefs(retargetEventDoc))) { - return NS_OK; // Not need to return error. - } - - if (retargetEventDoc) { - nsIFrame* frame = - GetFrameForHandlingEventWith(aGUIEvent, retargetEventDoc, aFrame); - if (!frame) { - return NS_OK; // Not need to return error. - } - if (frame != aFrame) { - nsCOMPtr shell = frame->PresContext()->GetPresShell(); - return shell->HandleEvent(frame, aGUIEvent, true, aEventStatus); - } + // If aGUIEvent should be handled in another PresShell, we should call its + // HandleEvent() and do nothing here. + nsresult rv = NS_OK; + if (MaybeHandleEventWithAnotherPresShell(aFrame, aGUIEvent, aEventStatus, + &rv)) { + // Handled by another PresShell or nobody can handle the event. + return rv; } } @@ -7220,6 +7211,48 @@ nsIFrame* PresShell::EventHandler::GetFrameForHandlingEventWith( return GetNearestFrameContainingPresShell(retargetPresShell); } +bool PresShell::EventHandler::MaybeHandleEventWithAnotherPresShell( + nsIFrame* aFrameForPresShell, WidgetGUIEvent* aGUIEvent, + nsEventStatus* aEventStatus, nsresult* aRv) { + MOZ_ASSERT(aGUIEvent); + MOZ_ASSERT(aEventStatus); + MOZ_ASSERT(aRv); + + *aRv = NS_OK; + + RefPtr retargetEventDoc; + if (!GetRetargetEventDocument(aGUIEvent, getter_AddRefs(retargetEventDoc))) { + // Nobody can handle this event. So, treat as handled by somebody to make + // caller do nothing anymore. + return true; + } + + // If there is no proper retarget document, the caller should handle the + // event by itself. + if (!retargetEventDoc) { + return false; + } + + nsIFrame* frame = GetFrameForHandlingEventWith(aGUIEvent, retargetEventDoc, + aFrameForPresShell); + if (!frame) { + // Nobody can handle this event. So, treat as handled by somebody to make + // caller do nothing anymore. + return true; + } + + // If we reached same frame as set to HandleEvent(), the caller should handle + // the event by itself. + if (frame == aFrameForPresShell) { + return false; + } + + // We need to handle aGUIEvent with another PresShell. + nsCOMPtr shell = frame->PresContext()->GetPresShell(); + *aRv = shell->HandleEvent(frame, aGUIEvent, true, aEventStatus); + return true; +} + Document* PresShell::GetPrimaryContentDocument() { nsPresContext* context = GetPresContext(); if (!context || !context->IsRoot()) { diff --git a/layout/base/PresShell.h b/layout/base/PresShell.h index 45915c0042a15..7eddd36fff049 100644 --- a/layout/base/PresShell.h +++ b/layout/base/PresShell.h @@ -616,6 +616,28 @@ class PresShell final : public nsIPresShell, Document* aRetargetDocument, nsIFrame* aFrameForPresShell); + /** + * MaybeHandleEventWithAnotherPresShell() may handle aGUIEvent with another + * PresShell. + * + * @param aFrameForPresShell Set aFrame of HandleEvent() which called + * this method. + * @param aGUIEvent Handling event. + * @param aEventStatus [in/out] EventStatus of aGUIEvent. + * @param aRv [out] Returns error if this gets an + * error handling the event. + * @return false if caller needs to keep handling + * the event by itself. + * true if caller shouldn't keep handling + * the event. Note that when no PresShell + * can handle the event, this returns true. + */ + MOZ_CAN_RUN_SCRIPT + bool MaybeHandleEventWithAnotherPresShell(nsIFrame* aFrameForPresShell, + WidgetGUIEvent* aGUIEvent, + nsEventStatus* aEventStatus, + nsresult* aRv); + MOZ_CAN_RUN_SCRIPT nsresult RetargetEventToParent(WidgetGUIEvent* aGUIEvent, nsEventStatus* aEventStatus);