Bug 1323158 - Part 1: Fire pointer and mouse boundary events when capturing the pointer. r=smaug

--HG--
extra : rebase_source : 2895681bb5d0e4872dc37f9d67dc4e2928bdce33
extra : histedit_source : e08adaaf7299e9667eb1f3887ef518c5edf5dc59
This commit is contained in:
Stone Shih 2017-01-18 15:25:44 +08:00
parent 4db46fd00d
commit eb9ee92c2d
6 changed files with 28 additions and 54 deletions

View File

@ -3874,10 +3874,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 =
@ -4087,14 +4084,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<nsIContent> movingInto = aMouseEvent->retargetedByPointerCapture
? wrapper->mLastOverElement->GetParent()
: aMovingInto;
EnterLeaveDispatcher leaveDispatcher(this, wrapper->mLastOverElement,
movingInto, aMouseEvent,
aMovingInto, aMouseEvent,
isPointer ? ePointerLeave : eMouseLeave);
// Fire mouseout
@ -4115,13 +4106,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
@ -4143,7 +4130,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
@ -4152,11 +4139,9 @@ EventStateManager::NotifyMouseOver(WidgetMouseEvent* aMouseEvent,
bool isPointer = aMouseEvent->mClass == ePointerEventClass;
Maybe<EnterLeaveDispatcher> enterDispatcher;
if (dispatch) {
enterDispatcher.emplace(this, aContent, lastOverElement, aMouseEvent,
isPointer ? ePointerEnter : eMouseEnter);
}
EnterLeaveDispatcher enterDispatcher(this, aContent, lastOverElement,
aMouseEvent,
isPointer ? ePointerEnter : eMouseEnter);
NotifyMouseOut(aMouseEvent, aContent);
@ -4168,18 +4153,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;

View File

@ -18,7 +18,6 @@ support-files =
support-files = pointerevent_capture_mouse-manual.html
[test_pointerevent_capture_suppressing_mouse-manual.html]
support-files = pointerevent_capture_suppressing_mouse-manual.html
disabled = should be investigated
[test_pointerevent_change-touch-action-onpointerdown_touch-manual.html]
support-files = pointerevent_change-touch-action-onpointerdown_touch-manual.html
disabled = disabled

View File

@ -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");

View File

@ -7608,30 +7608,28 @@ 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.
WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent();
MOZ_ASSERT(pointerEvent);
releasePointerCaptureCaller.SetTarget(pointerId,
pointerEvent->inputSource,
pointerEvent->mIsPrimary);

View File

@ -49,7 +49,6 @@ public:
uint32_t twist;
float tangentialPressure;
bool convertToPointer;
bool retargetedByPointerCapture;
WidgetPointerHelper()
: pointerId(0)
@ -58,7 +57,6 @@ public:
, twist(0)
, tangentialPressure(0)
, convertToPointer(true)
, retargetedByPointerCapture(false)
{
}
@ -70,7 +68,6 @@ public:
, twist(aTwist)
, tangentialPressure(aTangentialPressure)
, convertToPointer(true)
, retargetedByPointerCapture(false)
{
}
@ -82,7 +79,6 @@ public:
twist = aEvent.twist;
tangentialPressure = aEvent.tangentialPressure;
convertToPointer = aEvent.convertToPointer;
retargetedByPointerCapture = aEvent.retargetedByPointerCapture;
}
};

View File

@ -230,8 +230,8 @@ struct ParamTraits<mozilla::WidgetPointerHelper>
WriteParam(aMsg, aParam.tiltY);
WriteParam(aMsg, aParam.twist);
WriteParam(aMsg, aParam.tangentialPressure);
// We don't serialize convertToPointer and retargetedByPointerCapture since
// they are temporarily variable and should be reset to default.
// 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)