diff options
Diffstat (limited to 'layout/base/nsPresShell.cpp')
-rw-r--r-- | layout/base/nsPresShell.cpp | 142 |
1 files changed, 69 insertions, 73 deletions
diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 56ac370b9..63dfbd8a3 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -6514,10 +6514,11 @@ nsIPresShell::GetPointerCapturingContent(uint32_t aPointerId) } /* static */ void -nsIPresShell::CheckPointerCaptureState(uint32_t aPointerId, - uint16_t aPointerType, bool aIsPrimary) +nsIPresShell::CheckPointerCaptureState(const WidgetPointerEvent* aPointerEvent) { - PointerCaptureInfo* captureInfo = GetPointerCaptureInfo(aPointerId); + PointerCaptureInfo* captureInfo = + GetPointerCaptureInfo(aPointerEvent->pointerId); + if (captureInfo && captureInfo->mPendingContent != captureInfo->mOverrideContent) { // cache captureInfo->mPendingContent since it may be changed in the pointer @@ -6525,17 +6526,16 @@ nsIPresShell::CheckPointerCaptureState(uint32_t aPointerId, nsIContent* pendingContent = captureInfo->mPendingContent.get(); if (captureInfo->mOverrideContent) { DispatchGotOrLostPointerCaptureEvent(/* aIsGotCapture */ false, - aPointerId, aPointerType, aIsPrimary, + aPointerEvent, captureInfo->mOverrideContent); } if (pendingContent) { - DispatchGotOrLostPointerCaptureEvent(/* aIsGotCapture */ true, aPointerId, - aPointerType, aIsPrimary, - pendingContent); + DispatchGotOrLostPointerCaptureEvent(/* aIsGotCapture */ true, + aPointerEvent, pendingContent); } captureInfo->mOverrideContent = pendingContent; if (captureInfo->Empty()) { - sPointerCaptureList->Remove(aPointerId); + sPointerCaptureList->Remove(aPointerEvent->pointerId); } } } @@ -6976,37 +6976,30 @@ DispatchPointerFromMouseOrTouch(PresShell* aShell, return NS_OK; } -class ReleasePointerCaptureCaller +class ReleasePointerCaptureCaller final { public: - ReleasePointerCaptureCaller() : - mPointerId(0), - mPointerType(nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN), - mIsPrimary(false), - mIsSet(false) + ReleasePointerCaptureCaller() + : mPointerEvent(nullptr) { } ~ReleasePointerCaptureCaller() { - if (mIsSet) { - nsIPresShell::ReleasePointerCapturingContent(mPointerId); - nsIPresShell::CheckPointerCaptureState(mPointerId, mPointerType, - mIsPrimary); + if (mPointerEvent) { + nsIPresShell::ReleasePointerCapturingContent(mPointerEvent->pointerId); + nsIPresShell::CheckPointerCaptureState(mPointerEvent); } } - void SetTarget(uint32_t aPointerId, uint16_t aPointerType, bool aIsPrimary) + + void SetTarget(const WidgetPointerEvent* aPointerEvent) { - mPointerId = aPointerId; - mPointerType = aPointerType; - mIsPrimary = aIsPrimary; - mIsSet = true; + MOZ_ASSERT(aPointerEvent); + mPointerEvent = aPointerEvent; } private: - int32_t mPointerId; - uint16_t mPointerType; - bool mIsPrimary; - bool mIsSet; + // This is synchronously used inside PresShell::HandleEvent. + const WidgetPointerEvent* mPointerEvent; }; static bool @@ -7719,9 +7712,7 @@ PresShell::HandleEvent(nsIFrame* aFrame, nsWeakFrame frameKeeper(frame); // Handle pending pointer capture before any pointer events except // gotpointercapture / lostpointercapture. - CheckPointerCaptureState(pointerEvent->pointerId, - pointerEvent->inputSource, - pointerEvent->mIsPrimary); + CheckPointerCaptureState(pointerEvent); // Prevent application crashes, in case damaged frame. if (!frameKeeper.IsAlive()) { frame = nullptr; @@ -7742,33 +7733,29 @@ PresShell::HandleEvent(nsIFrame* aFrame, } } - if (aEvent->mClass == ePointerEventClass && - aEvent->mMessage != ePointerDown) { - if (WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent()) { - uint32_t pointerId = pointerEvent->pointerId; + // Mouse events should be fired to the same target as their mapped pointer + // events + if ((aEvent->mClass == ePointerEventClass || + aEvent->mClass == eMouseEventClass) && + aEvent->mMessage != ePointerDown && aEvent->mMessage != eMouseDown) { + if (WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent()) { + uint32_t pointerId = mouseEvent->pointerId; nsIContent* pointerCapturingContent = GetPointerCapturingContent(pointerId); if (pointerCapturingContent) { if (nsIFrame* capturingFrame = pointerCapturingContent->GetPrimaryFrame()) { - // If pointer capture is set, we should suppress - // pointerover/pointerenter events for all elements except element - // which have pointer capture. (Code in EventStateManager) - pointerEvent->retargetedByPointerCapture = - frame && frame->GetContent() && - !nsContentUtils::ContentIsDescendantOf(frame->GetContent(), - pointerCapturingContent); frame = capturingFrame; } - if (pointerEvent->mMessage == ePointerUp || - pointerEvent->mMessage == ePointerCancel) { + if (aEvent->mMessage == ePointerUp || + aEvent->mMessage == ePointerCancel) { // Implicitly releasing capture for given pointer. // ePointerLostCapture should be send after ePointerUp or // ePointerCancel. - releasePointerCaptureCaller.SetTarget(pointerId, - pointerEvent->inputSource, - pointerEvent->mIsPrimary); + WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent(); + MOZ_ASSERT(pointerEvent); + releasePointerCaptureCaller.SetTarget(pointerEvent); } } } @@ -8340,35 +8327,44 @@ PresShell::HandleEventInternal(WidgetEvent* aEvent, return rv; } -void -nsIPresShell::DispatchGotOrLostPointerCaptureEvent(bool aIsGotCapture, - uint32_t aPointerId, - uint16_t aPointerType, - bool aIsPrimary, - nsIContent* aCaptureTarget) -{ - PointerEventInit init; - init.mPointerId = aPointerId; - init.mBubbles = true; - ConvertPointerTypeToString(aPointerType, init.mPointerType); - init.mIsPrimary = aIsPrimary; - RefPtr<mozilla::dom::PointerEvent> event; - event = PointerEvent::Constructor(aCaptureTarget, - aIsGotCapture - ? NS_LITERAL_STRING("gotpointercapture") - : NS_LITERAL_STRING("lostpointercapture"), - init); - if (event) { +/* static */ void +nsIPresShell::DispatchGotOrLostPointerCaptureEvent( + bool aIsGotCapture, + const WidgetPointerEvent* aPointerEvent, + nsIContent* aCaptureTarget) +{ + nsIDocument* targetDoc = aCaptureTarget->OwnerDoc(); + nsCOMPtr<nsIPresShell> shell = targetDoc->GetShell(); + NS_ENSURE_TRUE_VOID(shell); + + if (!aIsGotCapture && !aCaptureTarget->IsInUncomposedDoc()) { + // If the capturing element was removed from the DOM tree, fire + // ePointerLostCapture at the document. + PointerEventInit init; + init.mPointerId = aPointerEvent->pointerId; + init.mBubbles = true; + init.mComposed = true; + ConvertPointerTypeToString(aPointerEvent->inputSource, init.mPointerType); + init.mIsPrimary = aPointerEvent->mIsPrimary; + RefPtr<mozilla::dom::PointerEvent> event; + event = PointerEvent::Constructor(aCaptureTarget, + NS_LITERAL_STRING("lostpointercapture"), + init); bool dummy; - // If the capturing element was removed from the DOM tree, - // lostpointercapture event should be fired at the document. - if (!aIsGotCapture && !aCaptureTarget->IsInUncomposedDoc()) { - aCaptureTarget->OwnerDoc()->DispatchEvent(event->InternalDOMEvent(), - &dummy); - } else { - aCaptureTarget->DispatchEvent(event->InternalDOMEvent(), &dummy); - } + targetDoc->DispatchEvent(event->InternalDOMEvent(), &dummy); + return; } + nsEventStatus status = nsEventStatus_eIgnore; + WidgetPointerEvent localEvent(aPointerEvent->IsTrusted(), + aIsGotCapture ? ePointerGotCapture : + ePointerLostCapture, + aPointerEvent->mWidget); + localEvent.AssignPointerEventData(*aPointerEvent, true); + nsresult rv = shell->HandleEventWithTarget( + &localEvent, + aCaptureTarget->GetPrimaryFrame(), + aCaptureTarget, &status); + NS_ENSURE_SUCCESS_VOID(rv); } nsresult |