diff options
Diffstat (limited to 'layout/base/nsPresShell.cpp')
-rw-r--r-- | layout/base/nsPresShell.cpp | 229 |
1 files changed, 71 insertions, 158 deletions
diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 56ac370b9..3e5320c22 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -201,10 +201,6 @@ #include "nsIDocShellTreeOwner.h" #endif -#ifdef MOZ_B2G -#include "nsIHardwareKeyHandler.h" -#endif - #ifdef MOZ_TASK_TRACER #include "GeckoTaskTracer.h" using namespace mozilla::tasktracer; @@ -4068,23 +4064,6 @@ PresShell::FlushPendingNotifications(mozilla::ChangesToFlush aFlush) */ mozFlushType flushType = aFlush.mFlushType; -#ifdef MOZ_ENABLE_PROFILER_SPS - static const char flushTypeNames[][20] = { - "Content", - "ContentAndNotify", - "Style", - "InterruptibleLayout", - "Layout", - "Display" - }; - - // Make sure that we don't miss things added to mozFlushType! - MOZ_ASSERT(static_cast<uint32_t>(flushType) <= ArrayLength(flushTypeNames)); - - PROFILER_LABEL_PRINTF("PresShell", "Flush", - js::ProfileEntry::Category::GRAPHICS, "(Flush_%s)", flushTypeNames[flushType - 1]); -#endif - #ifdef ACCESSIBILITY #ifdef DEBUG nsAccessibilityService* accService = GetAccService(); @@ -6514,10 +6493,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 +6505,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 +6955,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 @@ -7243,38 +7215,6 @@ PresShell::HandleKeyboardEvent(nsINode* aTarget, DispatchAfterKeyboardEventInternal(chain, aEvent, aEvent.DefaultPrevented()); } -#ifdef MOZ_B2G -bool -PresShell::ForwardKeyToInputMethodApp(nsINode* aTarget, - WidgetKeyboardEvent& aEvent, - nsEventStatus* aStatus) -{ - if (!XRE_IsParentProcess() || aEvent.mIsSynthesizedByTIP || - aEvent.IsKeyEventOnPlugin()) { - return false; - } - - if (!mHardwareKeyHandler) { - nsresult rv; - mHardwareKeyHandler = - do_GetService("@mozilla.org/HardwareKeyHandler;1", &rv); - if (!NS_SUCCEEDED(rv) || !mHardwareKeyHandler) { - return false; - } - } - - if (mHardwareKeyHandler->ForwardKeyToInputMethodApp(aTarget, - aEvent.AsKeyboardEvent(), - aStatus)) { - // No need to dispatch the forwarded keyboard event to it's child process - aEvent.mFlags.mNoCrossProcessBoundaryForwarding = true; - return true; - } - - return false; -} -#endif // MOZ_B2G - bool PresShell::ForwardKeyToInputMethodAppOrDispatch(bool aIsTargetRemote, nsINode* aTarget, @@ -7282,41 +7222,9 @@ PresShell::ForwardKeyToInputMethodAppOrDispatch(bool aIsTargetRemote, nsEventStatus* aStatus, EventDispatchingCallback* aEventCB) { -#ifndef MOZ_B2G - // No need to forward to input-method-app if the platform isn't run on B2G. EventDispatcher::Dispatch(aTarget, mPresContext, &aEvent, nullptr, aStatus, aEventCB); return false; -#else - // In-process case: the event target is in the current process - if (!aIsTargetRemote) { - if(ForwardKeyToInputMethodApp(aTarget, aEvent, aStatus)) { - return true; - } - - // If the keyboard event isn't forwarded to the input-method-app, - // then it should be dispatched to its event target directly. - EventDispatcher::Dispatch(aTarget, mPresContext, - &aEvent, nullptr, aStatus, aEventCB); - - return false; - } - - // OOP case: the event target is in its child process. - // Dispatch the keyboard event to the iframe that embeds the remote - // event target first. - EventDispatcher::Dispatch(aTarget, mPresContext, - &aEvent, nullptr, aStatus, aEventCB); - - // If the event is defaultPrevented, then there is no need to forward it - // to the input-method-app. - if (aEvent.mFlags.mDefaultPrevented) { - return false; - } - - // Try forwarding to the input-method-app. - return ForwardKeyToInputMethodApp(aTarget, aEvent, aStatus); -#endif // MOZ_B2G } nsresult @@ -7719,9 +7627,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 +7648,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); } } } @@ -8204,6 +8106,8 @@ PresShell::HandleEventInternal(WidgetEvent* aEvent, } case eMouseDown: case eMouseUp: + case ePointerDown: + case ePointerUp: isHandlingUserInput = true; break; @@ -8340,35 +8244,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 |