Bug 1653949 - Part 2: Add ePuppet to WidgetMouseEvent::ExitFrom; r=smaug

eTopLevel is reused in content process to indicates that the mouse leaves
the puppet widget rendering area, now we add a separated type, ePuppet, for it.

Differential Revision: https://phabricator.services.mozilla.com/D84748
This commit is contained in:
Edgar Chen 2020-08-27 17:19:14 +00:00
parent 36ccda1d13
commit 55691da377
4 changed files with 23 additions and 15 deletions

View File

@ -7835,7 +7835,8 @@ nsresult nsContentUtils::SendMouseEvent(
exitFrom = Some(WidgetMouseEvent::eChild); exitFrom = Some(WidgetMouseEvent::eChild);
} else if (aType.EqualsLiteral("mousecancel")) { } else if (aType.EqualsLiteral("mousecancel")) {
msg = eMouseExitFromWidget; msg = eMouseExitFromWidget;
exitFrom = Some(WidgetMouseEvent::eTopLevel); exitFrom = Some(XRE_IsParentProcess() ? WidgetMouseEvent::eTopLevel
: WidgetMouseEvent::ePuppet);
} else if (aType.EqualsLiteral("mouselongtap")) { } else if (aType.EqualsLiteral("mouselongtap")) {
msg = eMouseLongTap; msg = eMouseLongTap;
} else if (aType.EqualsLiteral("contextmenu")) { } else if (aType.EqualsLiteral("contextmenu")) {

View File

@ -646,10 +646,11 @@ nsresult EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
// above, at eMouseEnterIntoWidget case. // above, at eMouseEnterIntoWidget case.
aEvent->StopCrossProcessForwarding(); aEvent->StopCrossProcessForwarding();
// If the event is not a top-level window exit, then it's not // If the event is not a top-level window or puppet widget exit, then it's
// really an exit --- we may have traversed widget boundaries but // not really an exit --- we may have traversed widget boundaries but
// we're still in our toplevel window. // we're still in our toplevel window or puppet widget.
if (mouseEvent->mExitFrom.value() != WidgetMouseEvent::eTopLevel) { if (mouseEvent->mExitFrom.value() != WidgetMouseEvent::eTopLevel &&
mouseEvent->mExitFrom.value() != WidgetMouseEvent::ePuppet) {
// Treat it as a synthetic move so we don't generate spurious // Treat it as a synthetic move so we don't generate spurious
// "exit" or "move" events. Any necessary "out" or "over" events // "exit" or "move" events. Any necessary "out" or "over" events
// will be generated by GenerateMouseEnterExit // will be generated by GenerateMouseEnterExit
@ -657,10 +658,14 @@ nsresult EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
mouseEvent->mReason = WidgetMouseEvent::eSynthesized; mouseEvent->mReason = WidgetMouseEvent::eSynthesized;
// then fall through... // then fall through...
} else { } else {
MOZ_ASSERT_IF(XRE_IsParentProcess(), mouseEvent->mExitFrom.value() ==
WidgetMouseEvent::eTopLevel);
MOZ_ASSERT_IF(XRE_IsContentProcess(), mouseEvent->mExitFrom.value() ==
WidgetMouseEvent::ePuppet);
// We should synthetize corresponding pointer events // We should synthetize corresponding pointer events
GeneratePointerEnterExit(ePointerLeave, mouseEvent); GeneratePointerEnterExit(ePointerLeave, mouseEvent);
GenerateMouseEnterExit(mouseEvent); GenerateMouseEnterExit(mouseEvent);
// This is a window level mouse exit event and should stop here // This is really an exit and should stop here
aEvent->mMessage = eVoidEvent; aEvent->mMessage = eVoidEvent;
break; break;
} }
@ -4220,11 +4225,11 @@ nsIFrame* EventStateManager::DispatchMouseOrPointerEvent(
// event to the remote frame. // event to the remote frame.
if (IsTopLevelRemoteTarget(targetContent)) { if (IsTopLevelRemoteTarget(targetContent)) {
if (aMessage == eMouseOut) { if (aMessage == eMouseOut) {
// For remote content, send a "top-level" widget mouse exit event. // For remote content, send a puppet widget mouse exit event.
UniquePtr<WidgetMouseEvent> remoteEvent = UniquePtr<WidgetMouseEvent> remoteEvent =
CreateMouseOrPointerWidgetEvent(aMouseEvent, eMouseExitFromWidget, CreateMouseOrPointerWidgetEvent(aMouseEvent, eMouseExitFromWidget,
relatedContent); relatedContent);
remoteEvent->mExitFrom = Some(WidgetMouseEvent::eTopLevel); remoteEvent->mExitFrom = Some(WidgetMouseEvent::ePuppet);
// mCurrentTarget is set to the new target, so we must reset it to the // mCurrentTarget is set to the new target, so we must reset it to the
// old target and then dispatch a cross-process event. (mCurrentTarget // old target and then dispatch a cross-process event. (mCurrentTarget

View File

@ -6984,9 +6984,11 @@ nsresult PresShell::EventHandler::HandleEventUsingCoordinates(
} }
WidgetMouseEvent* mouseEvent = aGUIEvent->AsMouseEvent(); WidgetMouseEvent* mouseEvent = aGUIEvent->AsMouseEvent();
bool isWindowLevelMouseExit = (aGUIEvent->mMessage == eMouseExitFromWidget) && bool isWindowLevelMouseExit =
(mouseEvent && mouseEvent->mExitFrom.value() == (aGUIEvent->mMessage == eMouseExitFromWidget) &&
WidgetMouseEvent::eTopLevel); (mouseEvent &&
(mouseEvent->mExitFrom.value() == WidgetMouseEvent::eTopLevel ||
mouseEvent->mExitFrom.value() == WidgetMouseEvent::ePuppet));
// Get the frame at the event point. However, don't do this if we're // Get the frame at the event point. However, don't do this if we're
// capturing and retargeting the event because the captured frame will // capturing and retargeting the event because the captured frame will

View File

@ -190,8 +190,8 @@ class WidgetMouseEvent : public WidgetMouseEventBase,
eControlClick eControlClick
}; };
typedef bool ExitFromType; typedef uint8_t ExitFromType;
enum ExitFrom : ExitFromType { eChild, eTopLevel }; enum ExitFrom : ExitFromType { eChild, eTopLevel, ePuppet };
protected: protected:
WidgetMouseEvent() WidgetMouseEvent()
@ -267,8 +267,8 @@ class WidgetMouseEvent : public WidgetMouseEventBase,
ContextMenuTrigger mContextMenuTrigger; ContextMenuTrigger mContextMenuTrigger;
// mExitFrom contains a value only when mMessage is eMouseExitFromWidget. // mExitFrom contains a value only when mMessage is eMouseExitFromWidget.
// This indicates if the mouse cursor exits from a top level widget or // This indicates if the mouse cursor exits from a top level platform widget,
// a child widget. // a child widget or a puppet widget.
Maybe<ExitFrom> mExitFrom; Maybe<ExitFrom> mExitFrom;
// Whether the event should ignore scroll frame bounds during dispatch. // Whether the event should ignore scroll frame bounds during dispatch.