mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 12:50:09 +00:00
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:
parent
4db46fd00d
commit
eb9ee92c2d
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user