diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index f66cf3f905..c6b304183b 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -731,6 +731,9 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext, FlushPendingEvents(aPresContext); break; } + case ePointerGotCapture: + GenerateMouseEnterExit(mouseEvent); + break; case eDragStart: if (Prefs::ClickHoldContextMenu()) { // an external drag gesture event came in, not generated internally @@ -3890,10 +3893,7 @@ CreateMouseOrPointerWidgetEvent(WidgetMouseEvent* aMouseEvent, newPointerEvent->mWidth = sourcePointer->mWidth; newPointerEvent->mHeight = sourcePointer->mHeight; newPointerEvent->inputSource = sourcePointer->inputSource; - newPointerEvent->relatedTarget = - nsIPresShell::GetPointerCapturingContent(sourcePointer->pointerId) - ? nullptr - : aRelatedContent; + newPointerEvent->relatedTarget = aRelatedContent; aNewEvent = newPointerEvent.forget(); } else { aNewEvent = @@ -4106,14 +4106,8 @@ EventStateManager::NotifyMouseOut(WidgetMouseEvent* aMouseEvent, SetContentState(nullptr, NS_EVENT_STATE_HOVER); } - // In case we go out from capturing element (retargetedByPointerCapture is true) - // we should dispatch ePointerLeave event and only for capturing element. - RefPtr movingInto = aMouseEvent->retargetedByPointerCapture - ? wrapper->mLastOverElement->GetParent() - : aMovingInto; - EnterLeaveDispatcher leaveDispatcher(this, wrapper->mLastOverElement, - movingInto, aMouseEvent, + aMovingInto, aMouseEvent, isPointer ? ePointerLeave : eMouseLeave); // Fire mouseout @@ -4134,13 +4128,9 @@ EventStateManager::NotifyMouseOver(WidgetMouseEvent* aMouseEvent, { NS_ASSERTION(aContent, "Mouse must be over something"); - // If pointer capture is set, we should suppress pointerover/pointerenter events - // for all elements except element which have pointer capture. - bool dispatch = !aMouseEvent->retargetedByPointerCapture; - OverOutElementsWrapper* wrapper = GetWrapperByEventID(aMouseEvent); - if (wrapper->mLastOverElement == aContent && dispatch) + if (wrapper->mLastOverElement == aContent) return; // Before firing mouseover, check for recursion @@ -4163,7 +4153,7 @@ EventStateManager::NotifyMouseOver(WidgetMouseEvent* aMouseEvent, } // Firing the DOM event in the parent document could cause all kinds // of havoc. Reverify and take care. - if (wrapper->mLastOverElement == aContent && dispatch) + if (wrapper->mLastOverElement == aContent) return; // Remember mLastOverElement as the related content for the @@ -4172,11 +4162,9 @@ EventStateManager::NotifyMouseOver(WidgetMouseEvent* aMouseEvent, bool isPointer = aMouseEvent->mClass == ePointerEventClass; - Maybe enterDispatcher; - if (dispatch) { - enterDispatcher.emplace(this, aContent, lastOverElement, aMouseEvent, - isPointer ? ePointerEnter : eMouseEnter); - } + EnterLeaveDispatcher enterDispatcher(this, aContent, lastOverElement, + aMouseEvent, + isPointer ? ePointerEnter : eMouseEnter); NotifyMouseOut(aMouseEvent, aContent); @@ -4188,18 +4176,13 @@ EventStateManager::NotifyMouseOver(WidgetMouseEvent* aMouseEvent, SetContentState(aContent, NS_EVENT_STATE_HOVER); } - if (dispatch) { - // Fire mouseover - wrapper->mLastOverFrame = - DispatchMouseOrPointerEvent(aMouseEvent, - isPointer ? ePointerOver : eMouseOver, - aContent, lastOverElement); - enterDispatcher->Dispatch(); - wrapper->mLastOverElement = aContent; - } else { - wrapper->mLastOverFrame = nullptr; - wrapper->mLastOverElement = nullptr; - } + // Fire mouseover + wrapper->mLastOverFrame = + DispatchMouseOrPointerEvent(aMouseEvent, + isPointer ? ePointerOver : eMouseOver, + aContent, lastOverElement); + enterDispatcher.Dispatch(); + wrapper->mLastOverElement = aContent; // Turn recursion protection back off wrapper->mFirstOverEventElement = nullptr; @@ -4292,6 +4275,7 @@ EventStateManager::GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent) MOZ_FALLTHROUGH; case ePointerMove: case ePointerDown: + case ePointerGotCapture: { // Get the target content target (mousemove target == mouseover target) nsCOMPtr targetElement = GetEventTargetContent(aMouseEvent); diff --git a/dom/events/PointerEvent.cpp b/dom/events/PointerEvent.cpp index f537398634..fbaa0f737f 100644 --- a/dom/events/PointerEvent.cpp +++ b/dom/events/PointerEvent.cpp @@ -93,8 +93,10 @@ PointerEvent::Constructor(EventTarget* aOwner, widgetEvent->mWidth = aParam.mWidth; widgetEvent->mHeight = aParam.mHeight; widgetEvent->pressure = aParam.mPressure; + widgetEvent->tangentialPressure = aParam.mTangentialPressure; widgetEvent->tiltX = aParam.mTiltX; widgetEvent->tiltY = aParam.mTiltY; + widgetEvent->twist = aParam.mTwist; widgetEvent->inputSource = ConvertStringToPointerType(aParam.mPointerType); widgetEvent->mIsPrimary = aParam.mIsPrimary; widgetEvent->buttons = aParam.mButtons; @@ -145,6 +147,12 @@ PointerEvent::Pressure() return mEvent->AsPointerEvent()->pressure; } +float +PointerEvent::TangentialPressure() +{ + return mEvent->AsPointerEvent()->tangentialPressure; +} + int32_t PointerEvent::TiltX() { @@ -157,6 +165,12 @@ PointerEvent::TiltY() return mEvent->AsPointerEvent()->tiltY; } +int32_t +PointerEvent::Twist() +{ + return mEvent->AsPointerEvent()->twist; +} + bool PointerEvent::IsPrimary() { diff --git a/dom/events/PointerEvent.h b/dom/events/PointerEvent.h index 62c5a0c365..12d4941dc4 100644 --- a/dom/events/PointerEvent.h +++ b/dom/events/PointerEvent.h @@ -44,8 +44,10 @@ public: int32_t Width(); int32_t Height(); float Pressure(); + float TangentialPressure(); int32_t TiltX(); int32_t TiltY(); + int32_t Twist(); bool IsPrimary(); void GetPointerType(nsAString& aPointerType); }; diff --git a/dom/events/test/pointerevents/mochitest.ini b/dom/events/test/pointerevents/mochitest.ini index 58eae12fed..5de7f27ea1 100644 --- a/dom/events/test/pointerevents/mochitest.ini +++ b/dom/events/test/pointerevents/mochitest.ini @@ -148,5 +148,6 @@ support-files = support-files = bug1293174_implicit_pointer_capture_for_touch_1.html [test_bug1293174_implicit_pointer_capture_for_touch_2.html] support-files = bug1293174_implicit_pointer_capture_for_touch_2.html +[test_bug1323158.html] [test_empty_file.html] disabled = disabled # Bug 1150091 - Issue with support-files diff --git a/dom/events/test/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html b/dom/events/test/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html index 31fe919af1..2614790f35 100644 --- a/dom/events/test/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html +++ b/dom/events/test/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html @@ -12,20 +12,24 @@ +

Pointer Event: releasePointerCapture() - subsequent events follow normal hitting testing mechanisms

- Use mouse, touch or pen to contact here and move around.

Test complete: Scroll to Summary to view Pass/Fail Results.

diff --git a/dom/events/test/pointerevents/test_bug1285128.html b/dom/events/test/pointerevents/test_bug1285128.html index f7f1eb6980..9577940c18 100644 --- a/dom/events/test/pointerevents/test_bug1285128.html +++ b/dom/events/test/pointerevents/test_bug1285128.html @@ -13,7 +13,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1285128 Mozilla Bug 1285128

-
+
+
+ + + + +

+ + + diff --git a/dom/events/test/pointerevents/test_pointerevent_capture_suppressing_mouse-manual.html b/dom/events/test/pointerevents/test_pointerevent_capture_suppressing_mouse-manual.html index 5eb631f6a0..2b08e2bb8d 100644 --- a/dom/events/test/pointerevents/test_pointerevent_capture_suppressing_mouse-manual.html +++ b/dom/events/test/pointerevents/test_pointerevent_capture_suppressing_mouse-manual.html @@ -19,6 +19,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1000870 function executeTest(int_win) { sendMouseEvent(int_win, "target0", "mousemove"); sendMouseEvent(int_win, "target1", "mousemove"); + sendMouseEvent(int_win, "btnCapture", "mousemove"); sendMouseEvent(int_win, "btnCapture", "mousedown"); sendMouseEvent(int_win, "target1", "mousemove"); sendMouseEvent(int_win, "target0", "mousemove"); diff --git a/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_events_to_original_target-manual.html b/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_events_to_original_target-manual.html index cbf91df74c..35350e0165 100644 --- a/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_events_to_original_target-manual.html +++ b/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_events_to_original_target-manual.html @@ -17,9 +17,30 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1000870 runTestInNewWindow("pointerevent_releasepointercapture_events_to_original_target-manual.html"); } function executeTest(int_win) { - sendTouchEvent(int_win, "target0", "touchstart"); - sendTouchEvent(int_win, "target0", "touchmove"); - sendTouchEvent(int_win, "target0", "touchend"); + // Synthesize mouse events to run this test. + sendMouseEvent(int_win, "target0", "mousemove"); + sendMouseEvent(int_win, "target0", "mousedown"); + sendMouseEvent(int_win, "target0", "mousemove", {buttons: 1}); + sendMouseEvent(int_win, "target0", "mousemove", {buttons: 1}); + sendMouseEvent(int_win, "target0", "mouseup"); + + window.addEventListener("message", function(aEvent) { + if (aEvent.data == "Test Touch") { + // Synthesize touch events to run this test. + sendTouchEvent(int_win, "target0", "touchstart"); + sendTouchEvent(int_win, "target0", "touchmove"); + sendTouchEvent(int_win, "target0", "touchend"); + window.postMessage("Test Pen", "*"); + } else if (aEvent.data == "Test Pen") { + // Synthesize pen events to run this test. + sendMouseEvent(int_win, "target0", "mousemove", {inputSource:MouseEvent.MOZ_SOURCE_PEN}); + sendMouseEvent(int_win, "target0", "mousedown", {inputSource:MouseEvent.MOZ_SOURCE_PEN}); + sendMouseEvent(int_win, "target0", "mousemove", {inputSource:MouseEvent.MOZ_SOURCE_PEN, buttons: 1}); + sendMouseEvent(int_win, "target0", "mousemove", {inputSource:MouseEvent.MOZ_SOURCE_PEN, buttons: 1}); + sendMouseEvent(int_win, "target0", "mouseup", {inputSource:MouseEvent.MOZ_SOURCE_PEN}); + } + }); + window.postMessage("Test Touch", "*"); } diff --git a/dom/events/test/pointerevents/test_pointerevent_setpointercapture_relatedtarget-manual.html b/dom/events/test/pointerevents/test_pointerevent_setpointercapture_relatedtarget-manual.html index 0883d616ba..09e97ec972 100644 --- a/dom/events/test/pointerevents/test_pointerevent_setpointercapture_relatedtarget-manual.html +++ b/dom/events/test/pointerevents/test_pointerevent_setpointercapture_relatedtarget-manual.html @@ -19,8 +19,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1000870 function executeTest(int_win) { sendMouseEvent(int_win, "target1", "mousemove"); sendMouseEvent(int_win, "btnCapture", "mousedown"); - sendMouseEvent(int_win, "target1", "mousemove"); - sendMouseEvent(int_win, "target1", "mouseup"); + sendMouseEvent(int_win, "btnCapture", "mousemove"); + sendMouseEvent(int_win, "btnCapture", "mouseup"); } diff --git a/dom/webidl/PointerEvent.webidl b/dom/webidl/PointerEvent.webidl index 2e83922c84..4e8a0eb901 100644 --- a/dom/webidl/PointerEvent.webidl +++ b/dom/webidl/PointerEvent.webidl @@ -17,8 +17,10 @@ interface PointerEvent : MouseEvent readonly attribute long width; readonly attribute long height; readonly attribute float pressure; + readonly attribute float tangentialPressure; readonly attribute long tiltX; readonly attribute long tiltY; + readonly attribute long twist; readonly attribute DOMString pointerType; readonly attribute boolean isPrimary; }; @@ -29,8 +31,10 @@ dictionary PointerEventInit : MouseEventInit long width = 1; long height = 1; float pressure = 0; + float tangentialPressure = 0; long tiltX = 0; long tiltY = 0; + long twist = 0; DOMString pointerType = ""; boolean isPrimary = false; }; diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index cbbae0e8fd..5990402ed5 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -1298,11 +1298,11 @@ public: } }; - static void DispatchGotOrLostPointerCaptureEvent(bool aIsGotCapture, - uint32_t aPointerId, - uint16_t aPointerType, - bool aIsPrimary, - nsIContent* aCaptureTarget); + static void DispatchGotOrLostPointerCaptureEvent( + bool aIsGotCapture, + const mozilla::WidgetPointerEvent* aPointerEvent, + nsIContent* aCaptureTarget); + static PointerCaptureInfo* GetPointerCaptureInfo(uint32_t aPointerId); static void SetPointerCapturingContent(uint32_t aPointerId, nsIContent* aContent); @@ -1311,8 +1311,8 @@ public: // CheckPointerCaptureState checks cases, when got/lostpointercapture events // should be fired. - static void CheckPointerCaptureState(uint32_t aPointerId, - uint16_t aPointerType, bool aIsPrimary); + static void CheckPointerCaptureState( + const mozilla::WidgetPointerEvent* aPointerEvent); // GetPointerInfo returns true if pointer with aPointerId is situated in // device, false otherwise. diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 56ac370b96..63dfbd8a39 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) +/* static */ void +nsIPresShell::DispatchGotOrLostPointerCaptureEvent( + bool aIsGotCapture, + const WidgetPointerEvent* aPointerEvent, + nsIContent* aCaptureTarget) { - PointerEventInit init; - init.mPointerId = aPointerId; - init.mBubbles = true; - ConvertPointerTypeToString(aPointerType, init.mPointerType); - init.mIsPrimary = aIsPrimary; - RefPtr event; - event = PointerEvent::Constructor(aCaptureTarget, - aIsGotCapture - ? NS_LITERAL_STRING("gotpointercapture") - : NS_LITERAL_STRING("lostpointercapture"), - init); - if (event) { + nsIDocument* targetDoc = aCaptureTarget->OwnerDoc(); + nsCOMPtr 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 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 diff --git a/layout/base/tests/bug1078327_inner.html b/layout/base/tests/bug1078327_inner.html index 9e32fc996f..0cfb9da7f8 100644 --- a/layout/base/tests/bug1078327_inner.html +++ b/layout/base/tests/bug1078327_inner.html @@ -24,16 +24,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1078327 var test_mediator_move = false; var test_mediator_out = false; var test_listener = false; + var test_lost_capture = false; function TargetHandler(event) { logger("Target receive event: " + event.type + ". Mediator.setPointerCapture()"); mediator.setPointerCapture(event.pointerId); test_target = true; + test_capture = true; } function MediatorHandler(event) { logger("Mediator receive event: " + event.type); - if(event.type == "gotpointercapture") - test_capture = true; if(!test_capture) return; if(event.type == "pointermove") @@ -43,7 +43,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1078327 if(event.type == "pointerout") test_mediator_out++; if(event.type == "lostpointercapture") - test_capture = false; + test_lost_capture = true; } function ListenerHandler(event) { logger("Listener receive event: " + event.type); @@ -86,7 +86,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1078327 } function finishTest() { parent.is(test_target, true, "pointerdown event should be received by target"); - parent.is(test_capture, false, "test_capture should be false at the end of the test"); + parent.is(test_lost_capture, true, "mediator should receive lostpointercapture"); parent.is(test_mediator_over, 1, "mediator should receive pointerover event only once"); parent.is(test_mediator_move, 5, "mediator should receive pointermove event five times"); parent.is(test_mediator_out, 1, "mediator should receive pointerout event only once"); diff --git a/layout/base/tests/bug1162990_inner_1.html b/layout/base/tests/bug1162990_inner_1.html index 4ea5edb5c8..0f950df8d4 100644 --- a/layout/base/tests/bug1162990_inner_1.html +++ b/layout/base/tests/bug1162990_inner_1.html @@ -111,10 +111,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1162990 } function finishTest() { - parent.is(test_basketLeave, 0, "Part1: basket should not receive pointerleave event after pointer capturing"); + parent.is(test_basketLeave, 1, "Part1: basket should receive pointerleave event after pointer capturing"); parent.is(test_targetGotCapture, 1, "Part1: target should receive gotpointercapture event"); parent.is(test_targetLostCapture, 1, "Part1: target should receive lostpointercapture event"); - parent.is(test_targetLeave, 2, "Part1: target should receive pointerleave event two times"); + parent.is(test_targetLeave, 1, "Part1: target should receive pointerleave event only one time"); parent.is(test_childLeave, 0, "Part1: child should not receive pointerleave event after pointer capturing"); parent.is(test_listenerDown, 1, "Part1: listener should receive pointerdown event"); parent.is(test_listenerLeave, 1, "Part1: listener should receive pointerleave event only one time"); diff --git a/layout/base/tests/bug1162990_inner_2.html b/layout/base/tests/bug1162990_inner_2.html index 54aa74ca3a..e418927bd6 100644 --- a/layout/base/tests/bug1162990_inner_2.html +++ b/layout/base/tests/bug1162990_inner_2.html @@ -116,7 +116,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1162990 parent.is(test_targetDown, 1, "Part2: target should receive pointerdown event"); parent.is(test_targetGotCapture, 1, "Part2: target should receive gotpointercapture event"); parent.is(test_targetLostCapture, 1, "Part2: target should receive lostpointercapture event"); - parent.is(test_targetLeave, 1, "Part2: target should receive pointerleave event"); + parent.is(test_targetLeave, 0, "Part2: target should not receive pointerleave event"); parent.is(test_childLeave, 0, "Part2: child should not receive pointerleave event after pointer capturing"); parent.is(test_listenerLeave, 0, "Part2: listener should not receive pointerleave event after pointer capturing"); logger("finishTest"); diff --git a/layout/base/tests/bug976963_inner.html b/layout/base/tests/bug976963_inner.html deleted file mode 100644 index 2c55fbccd4..0000000000 --- a/layout/base/tests/bug976963_inner.html +++ /dev/null @@ -1,241 +0,0 @@ - - - - - - Test for Bug 976963 - - - - - - - - Mozilla Bug 976963 -

- -
div id=listener
-
div id=middler
-
div id=target
-
-  
- - diff --git a/layout/base/tests/bug977003_inner_5.html b/layout/base/tests/bug977003_inner_5.html index 70fc5ba403..81094043c5 100644 --- a/layout/base/tests/bug977003_inner_5.html +++ b/layout/base/tests/bug977003_inner_5.html @@ -26,6 +26,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1098139 var test_lost_listener = false; var test_lost_type = ""; var test_move_listener = false; + var test_over_listener = false; var test_listener = false; var test_lost_primary = false; @@ -53,6 +54,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1098139 logger("Receive event on Listener: " + event.type); test_move_listener = true; } + function ListenerOverHandler(event) { + logger("Receive event on Listener: " + event.type); + test_over_listener = true; + } function ListenerHandler(event) { logger("Receive event on Listener: " + event.type); test_listener = true; @@ -74,7 +79,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1098139 target.addEventListener("pointerdown", TargetDownHandler, false); listener.addEventListener("gotpointercapture", ListenerGotPCHandler, false); listener.addEventListener("lostpointercapture", ListenerLostPCHandler, false); - listener.addEventListener("pointerover", ListenerHandler, false); + listener.addEventListener("pointerover", ListenerOverHandler, false); listener.addEventListener("pointermove", ListenerMoveHandler, false); listener.addEventListener("pointerup", ListenerHandler, false); listener.addEventListener("pointerout", ListenerHandler, false); @@ -93,6 +98,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1098139 parent.is(test_lost_type, "touch", "Part 5: lostpointercapture event should have pointerType touch"); parent.is(test_lost_primary, true, "Part 5: lostpointercapture event should have isPrimary as true"); parent.is(test_move_listener, true, "Part 5: gotpointercapture should be triggered by pointermove"); + parent.is(test_over_listener, true, "Part 5: listener should receive pointerover when capturing pointer"); parent.is(test_listener, false, "Part 5: listener should not receive any other events"); logger("finishTest"); parent.finishTest(); diff --git a/layout/base/tests/bug977003_inner_6.html b/layout/base/tests/bug977003_inner_6.html index 12424b1f2b..b60ca5c314 100644 --- a/layout/base/tests/bug977003_inner_6.html +++ b/layout/base/tests/bug977003_inner_6.html @@ -19,6 +19,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1073563 var listener = undefined; var test_target = false; var test_move = false; + var test_over = false; var test_listener = false; var receive_lostpointercapture = false; @@ -44,6 +45,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1073563 } } else if(event.type == "pointermove") { test_move = true; + } else if(event.type == "pointerover") { + test_over = true; } else { test_listener = true; } @@ -81,7 +84,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1073563 // PE level 2 defines that the pending pointer capture is processed when firing next pointer events. // In this test case, pointer capture release is processed when firing pointermove parent.is(test_move, true, "Part 6: gotpointercapture should be triggered by pointermove"); - parent.is(test_listener, false, "Part 6: no other pointerevents should be fired before gotpointercapture"); + parent.is(test_over, true, "Part 6: pointerover should be received when capturing pointer"); + parent.is(test_listener, false, "Part 6: no other pointerevents should be fired before gotpointercapture except pointerover"); logger("finishTest"); parent.finishTest(); } diff --git a/layout/base/tests/mochitest.ini b/layout/base/tests/mochitest.ini index 279b0af8aa..405697977c 100644 --- a/layout/base/tests/mochitest.ini +++ b/layout/base/tests/mochitest.ini @@ -256,8 +256,6 @@ skip-if = toolkit == 'android' support-files = bug851445_helper.html [test_bug970964.html] support-files = bug970964_inner.html -[test_bug976963.html] -support-files = bug976963_inner.html [test_bug977003.html] support-files = bug977003_inner_1.html diff --git a/layout/base/tests/test_bug976963.html b/layout/base/tests/test_bug976963.html deleted file mode 100644 index 4b8da3a6e8..0000000000 --- a/layout/base/tests/test_bug976963.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - Test for Bug 976963 - - - - - - - - diff --git a/widget/MouseEvents.h b/widget/MouseEvents.h index f214ec22bc..442ac41e82 100644 --- a/widget/MouseEvents.h +++ b/widget/MouseEvents.h @@ -46,15 +46,17 @@ public: uint32_t pointerId; uint32_t tiltX; uint32_t tiltY; + uint32_t twist; + float tangentialPressure; bool convertToPointer; - bool retargetedByPointerCapture; WidgetPointerHelper() : pointerId(0) , tiltX(0) , tiltY(0) + , twist(0) + , tangentialPressure(0) , convertToPointer(true) - , retargetedByPointerCapture(false) { } @@ -63,8 +65,9 @@ public: pointerId = aEvent.pointerId; tiltX = aEvent.tiltX; tiltY = aEvent.tiltY; + twist = aEvent.twist; + tangentialPressure = aEvent.tangentialPressure; convertToPointer = aEvent.convertToPointer; - retargetedByPointerCapture = aEvent.retargetedByPointerCapture; } }; diff --git a/widget/nsGUIEventIPC.h b/widget/nsGUIEventIPC.h index e06e3784a0..e45189bb10 100644 --- a/widget/nsGUIEventIPC.h +++ b/widget/nsGUIEventIPC.h @@ -228,8 +228,10 @@ struct ParamTraits WriteParam(aMsg, aParam.pointerId); WriteParam(aMsg, aParam.tiltX); WriteParam(aMsg, aParam.tiltY); - // We don't serialize convertToPointer and retargetedByPointerCapture since - // they are temporarily variable and should be reset to default. + WriteParam(aMsg, aParam.twist); + WriteParam(aMsg, aParam.tangentialPressure); + // We don't serialize convertToPointer since it's temporarily variable and + // should be reset to default. } static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) @@ -237,7 +239,9 @@ struct ParamTraits bool rv; rv = ReadParam(aMsg, aIter, &aResult->pointerId) && ReadParam(aMsg, aIter, &aResult->tiltX) && - ReadParam(aMsg, aIter, &aResult->tiltY); + ReadParam(aMsg, aIter, &aResult->tiltY) && + ReadParam(aMsg, aIter, &aResult->twist) && + ReadParam(aMsg, aIter, &aResult->tangentialPressure); return rv; } };