From 1dbc50be8266fc6a2dbf36f08a069590ff9de36d Mon Sep 17 00:00:00 2001 From: Cosmin Sabou Date: Thu, 27 Aug 2020 20:13:20 +0300 Subject: [PATCH] Backed out 5 changesets (bug 1653949) for assertion failures on EventStateManager.cpp. CLOSED TREE Backed out changeset ad7c35ab2a40 (bug 1653949) Backed out changeset 31cb90ef998a (bug 1653949) Backed out changeset 03e65cbd2a11 (bug 1653949) Backed out changeset a87ac2a7db70 (bug 1653949) Backed out changeset 390dd2c04cd4 (bug 1653949) --- dom/base/nsContentUtils.cpp | 17 +-- dom/base/nsContentUtils.h | 8 -- dom/events/EventStateManager.cpp | 107 ++------------- dom/events/test/file_mouse_enterleave.html | 6 +- dom/events/test/mochitest.ini | 1 - .../test/test_mouse_enterleave_iframe.html | 123 ++---------------- layout/base/PresShell.cpp | 7 +- widget/MouseEvents.h | 21 ++- widget/cocoa/nsChildView.mm | 6 +- widget/gtk/nsWindow.cpp | 6 +- widget/nsGUIEventIPC.h | 20 +-- widget/windows/nsWindow.cpp | 5 +- 12 files changed, 51 insertions(+), 276 deletions(-) diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 47cc430a29ce..24eda39cf2c0 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -2540,17 +2540,6 @@ nsINode* nsContentUtils::GetCommonAncestorUnderInteractiveContent( return parent; } -/* static */ -BrowserParent* nsContentUtils::GetCommonBrowserParentAncestor( - BrowserParent* aBrowserParent1, BrowserParent* aBrowserParent2) { - return GetCommonAncestorInternal( - aBrowserParent1, aBrowserParent2, [](BrowserParent* aBrowserParent) { - return aBrowserParent->GetBrowserBridgeParent() - ? aBrowserParent->GetBrowserBridgeParent()->Manager() - : nullptr; - }); -} - /* static */ template Maybe nsContentUtils::ComparePoints( @@ -7831,7 +7820,7 @@ nsresult nsContentUtils::SendMouseEvent( if (!widget) return NS_ERROR_FAILURE; EventMessage msg; - Maybe exitFrom; + WidgetMouseEvent::ExitFrom exitFrom = WidgetMouseEvent::eChild; bool contextMenuKey = false; if (aType.EqualsLiteral("mousedown")) { msg = eMouseDown; @@ -7843,11 +7832,9 @@ nsresult nsContentUtils::SendMouseEvent( msg = eMouseEnterIntoWidget; } else if (aType.EqualsLiteral("mouseout")) { msg = eMouseExitFromWidget; - exitFrom = Some(WidgetMouseEvent::eChild); } else if (aType.EqualsLiteral("mousecancel")) { msg = eMouseExitFromWidget; - exitFrom = Some(XRE_IsParentProcess() ? WidgetMouseEvent::eTopLevel - : WidgetMouseEvent::ePuppet); + exitFrom = WidgetMouseEvent::eTopLevel; } else if (aType.EqualsLiteral("mouselongtap")) { msg = eMouseLongTap; } else if (aType.EqualsLiteral("contextmenu")) { diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 16c127704d0f..2448ca3eff1b 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -452,14 +452,6 @@ class nsContentUtils { static nsINode* GetCommonAncestorUnderInteractiveContent(nsINode* aNode1, nsINode* aNode2); - /** - * Returns the common BrowserParent ancestor, if any, for two given - * BrowserParent. - */ - static mozilla::dom::BrowserParent* GetCommonBrowserParentAncestor( - mozilla::dom::BrowserParent* aBrowserParent1, - mozilla::dom::BrowserParent* aBrowserParent2); - /** * Returns true if aNode1 is before aNode2 in the same connected * tree. diff --git a/dom/events/EventStateManager.cpp b/dom/events/EventStateManager.cpp index 1fca3ee11243..8e3ec9258e47 100644 --- a/dom/events/EventStateManager.cpp +++ b/dom/events/EventStateManager.cpp @@ -646,11 +646,10 @@ nsresult EventStateManager::PreHandleEvent(nsPresContext* aPresContext, // above, at eMouseEnterIntoWidget case. aEvent->StopCrossProcessForwarding(); - // If the event is not a top-level window or puppet widget exit, then it's - // not really an exit --- we may have traversed widget boundaries but - // we're still in our toplevel window or puppet widget. - if (mouseEvent->mExitFrom.value() != WidgetMouseEvent::eTopLevel && - mouseEvent->mExitFrom.value() != WidgetMouseEvent::ePuppet) { + // If the event is not a top-level window exit, then it's not + // really an exit --- we may have traversed widget boundaries but + // we're still in our toplevel window. + if (mouseEvent->mExitFrom != WidgetMouseEvent::eTopLevel) { // Treat it as a synthetic move so we don't generate spurious // "exit" or "move" events. Any necessary "out" or "over" events // will be generated by GenerateMouseEnterExit @@ -658,14 +657,10 @@ nsresult EventStateManager::PreHandleEvent(nsPresContext* aPresContext, mouseEvent->mReason = WidgetMouseEvent::eSynthesized; // then fall through... } 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 GeneratePointerEnterExit(ePointerLeave, mouseEvent); GenerateMouseEnterExit(mouseEvent); - // This is really an exit and should stop here + // This is a window level mouse exit event and should stop here aEvent->mMessage = eVoidEvent; break; } @@ -1284,40 +1279,6 @@ bool EventStateManager::WalkESMTreeToHandleAccessKey( return false; } // end of HandleAccessKey -static BrowserParent* GetBrowserParentAncestor(BrowserParent* aBrowserParent) { - MOZ_ASSERT(aBrowserParent); - - BrowserBridgeParent* bbp = aBrowserParent->GetBrowserBridgeParent(); - if (!bbp) { - return nullptr; - } - - return bbp->Manager(); -} - -static void DispatchCrossProcessMouseExitEvents(WidgetMouseEvent* aMouseEvent, - BrowserParent* aRemoteTarget, - BrowserParent* aStopAncestor, - bool aIsReallyExit) { - MOZ_ASSERT(aMouseEvent); - MOZ_ASSERT(aRemoteTarget); - MOZ_ASSERT(aRemoteTarget != aStopAncestor); - MOZ_ASSERT_IF(aStopAncestor, nsContentUtils::GetCommonBrowserParentAncestor( - aRemoteTarget, aStopAncestor)); - - while (aRemoteTarget != aStopAncestor) { - UniquePtr mouseExitEvent = - CreateMouseOrPointerWidgetEvent(aMouseEvent, eMouseExitFromWidget, - aMouseEvent->mRelatedTarget); - mouseExitEvent->mExitFrom = - Some(aIsReallyExit ? WidgetMouseEvent::ePuppet - : WidgetMouseEvent::ePuppetParentToPuppetChild); - aRemoteTarget->SendRealMouseEvent(*mouseExitEvent); - - aRemoteTarget = GetBrowserParentAncestor(aRemoteTarget); - } -} - void EventStateManager::DispatchCrossProcessEvent(WidgetEvent* aEvent, BrowserParent* aRemoteTarget, nsEventStatus* aStatus) { @@ -1351,27 +1312,6 @@ void EventStateManager::DispatchCrossProcessEvent(WidgetEvent* aEvent, switch (aEvent->mClass) { case eMouseEventClass: { - BrowserParent* oldRemote = BrowserParent::GetLastMouseRemoteTarget(); - - // If this is a eMouseExitFromWidget event, need to redirect the event to - // the last remote and and notify all its ancestors about the exit, if - // any. - if (mouseEvent->mMessage == eMouseExitFromWidget) { - MOZ_ASSERT(mouseEvent->mExitFrom.value() == WidgetMouseEvent::ePuppet); - MOZ_ASSERT(mouseEvent->mReason == WidgetMouseEvent::eReal); - MOZ_ASSERT(!mouseEvent->mLayersId.IsValid()); - MOZ_ASSERT(remote->GetBrowserHost()); - - if (oldRemote && oldRemote != remote) { - MOZ_ASSERT(nsContentUtils::GetCommonBrowserParentAncestor( - remote, oldRemote) == remote); - remote = oldRemote; - } - - DispatchCrossProcessMouseExitEvents(mouseEvent, remote, nullptr, true); - return; - } - // If a mouse is over a remote target A, and then moves to // remote target B, we'd deliver the event directly to remote target B // after the moving, A would never get notified that the mouse left. @@ -1380,37 +1320,14 @@ void EventStateManager::DispatchCrossProcessEvent(WidgetEvent* aEvent, // process directly (see // https://bugzilla.mozilla.org/show_bug.cgi?id=1549355), we probably // don't need to check mReason then. + BrowserParent* oldRemote = BrowserParent::GetLastMouseRemoteTarget(); if (mouseEvent->mReason == WidgetMouseEvent::eReal && remote != oldRemote) { - MOZ_ASSERT(mouseEvent->mMessage != eMouseExitFromWidget); if (oldRemote) { - BrowserParent* commonAncestor = - nsContentUtils::GetCommonBrowserParentAncestor(remote, oldRemote); - if (commonAncestor == oldRemote) { - // Mouse moves to the inner OOP frame, it is not a really exit. - DispatchCrossProcessMouseExitEvents( - mouseEvent, GetBrowserParentAncestor(remote), - GetBrowserParentAncestor(commonAncestor), false); - } else if (commonAncestor == remote) { - // Mouse moves to the outer OOP frame, it is a really exit. - DispatchCrossProcessMouseExitEvents(mouseEvent, oldRemote, - commonAncestor, true); - } else { - // Mouse moves to OOP frame in other subtree, it is a really exit, - // need to notify all its ancestors before common ancestor about the - // exit. - DispatchCrossProcessMouseExitEvents(mouseEvent, oldRemote, - commonAncestor, true); - if (commonAncestor) { - UniquePtr mouseExitEvent = - CreateMouseOrPointerWidgetEvent(mouseEvent, - eMouseExitFromWidget, - mouseEvent->mRelatedTarget); - mouseExitEvent->mExitFrom = - Some(WidgetMouseEvent::ePuppetParentToPuppetChild); - commonAncestor->SendRealMouseEvent(*mouseExitEvent); - } - } + UniquePtr mouseExitEvent = + CreateMouseOrPointerWidgetEvent(mouseEvent, eMouseExitFromWidget, + mouseEvent->mRelatedTarget); + oldRemote->SendRealMouseEvent(*mouseExitEvent); } if (mouseEvent->mMessage != eMouseExitFromWidget && @@ -4302,11 +4219,11 @@ nsIFrame* EventStateManager::DispatchMouseOrPointerEvent( // event to the remote frame. if (IsTopLevelRemoteTarget(targetContent)) { if (aMessage == eMouseOut) { - // For remote content, send a puppet widget mouse exit event. + // For remote content, send a "top-level" widget mouse exit event. UniquePtr remoteEvent = CreateMouseOrPointerWidgetEvent(aMouseEvent, eMouseExitFromWidget, relatedContent); - remoteEvent->mExitFrom = Some(WidgetMouseEvent::ePuppet); + remoteEvent->mExitFrom = WidgetMouseEvent::eTopLevel; // mCurrentTarget is set to the new target, so we must reset it to the // old target and then dispatch a cross-process event. (mCurrentTarget diff --git a/dom/events/test/file_mouse_enterleave.html b/dom/events/test/file_mouse_enterleave.html index 9e3d1f1d8b04..75fa7bda3ce3 100644 --- a/dom/events/test/file_mouse_enterleave.html +++ b/dom/events/test/file_mouse_enterleave.html @@ -15,7 +15,7 @@
diff --git a/dom/events/test/mochitest.ini b/dom/events/test/mochitest.ini index 51a22859b87b..60f5bbd29d1e 100644 --- a/dom/events/test/mochitest.ini +++ b/dom/events/test/mochitest.ini @@ -193,7 +193,6 @@ support-files = [test_mouse_enterleave_iframe.html] support-files = file_mouse_enterleave.html -skip-if = verify # Bug 1659940 [test_moz_mouse_pixel_scroll_event.html] [test_offsetxy.html] [test_onerror_handler_args.html] diff --git a/dom/events/test/test_mouse_enterleave_iframe.html b/dom/events/test/test_mouse_enterleave_iframe.html index ee4b4f6fc13e..d6196ed6763f 100644 --- a/dom/events/test/test_mouse_enterleave_iframe.html +++ b/dom/events/test/test_mouse_enterleave_iframe.html @@ -10,14 +10,13 @@ height: 30px; } -#target, #target2 { - width: 150px; - height: 150px; +#target { + width: 300px; + height: 300px; background-color: #fcc; - display: inline-block; } -#frame, #frame2 { +#frame { height: 100%; width: 100%; } @@ -33,9 +32,6 @@
-
- -
diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp index 7db70b11c563..db83c8cfb395 100644 --- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -6982,9 +6982,7 @@ nsresult PresShell::EventHandler::HandleEventUsingCoordinates( WidgetMouseEvent* mouseEvent = aGUIEvent->AsMouseEvent(); bool isWindowLevelMouseExit = (aGUIEvent->mMessage == eMouseExitFromWidget) && - (mouseEvent && - (mouseEvent->mExitFrom.value() == WidgetMouseEvent::eTopLevel || - mouseEvent->mExitFrom.value() == WidgetMouseEvent::ePuppet)); + (mouseEvent && mouseEvent->mExitFrom == WidgetMouseEvent::eTopLevel); // 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 @@ -7606,8 +7604,7 @@ bool PresShell::EventHandler::MaybeDiscardOrDelayMouseEvent( (aGUIEvent->mMessage == eMouseUp || // contextmenu is triggered after right mouseup on Windows and // right mousedown on other platforms. - aGUIEvent->mMessage == eContextMenu || - aGUIEvent->mMessage == eMouseExitFromWidget)) { + aGUIEvent->mMessage == eContextMenu)) { UniquePtr delayedMouseEvent = MakeUnique(aGUIEvent->AsMouseEvent()); PushDelayedEventIntoQueue(std::move(delayedMouseEvent)); diff --git a/widget/MouseEvents.h b/widget/MouseEvents.h index 865526948875..8cc40e5b4583 100644 --- a/widget/MouseEvents.h +++ b/widget/MouseEvents.h @@ -190,18 +190,14 @@ class WidgetMouseEvent : public WidgetMouseEventBase, eControlClick }; - typedef uint8_t ExitFromType; - enum ExitFrom : ExitFromType { - eChild, - eTopLevel, - ePuppet, - ePuppetParentToPuppetChild - }; + typedef bool ExitFromType; + enum ExitFrom : ExitFromType { eChild, eTopLevel }; protected: WidgetMouseEvent() : mReason(eReal), mContextMenuTrigger(eNormal), + mExitFrom(eChild), mIgnoreRootScrollFrame(false), mClickCount(0), mUseLegacyNonPrimaryDispatch(false) {} @@ -211,6 +207,7 @@ class WidgetMouseEvent : public WidgetMouseEventBase, : WidgetMouseEventBase(aIsTrusted, aMessage, aWidget, aEventClassID), mReason(aReason), mContextMenuTrigger(eNormal), + mExitFrom(eChild), mIgnoreRootScrollFrame(false), mClickCount(0), mUseLegacyNonPrimaryDispatch(false) {} @@ -224,6 +221,7 @@ class WidgetMouseEvent : public WidgetMouseEventBase, : WidgetMouseEventBase(aIsTrusted, aMessage, aWidget, eMouseEventClass), mReason(aReason), mContextMenuTrigger(aContextMenuTrigger), + mExitFrom(eChild), mIgnoreRootScrollFrame(false), mClickCount(0), mUseLegacyNonPrimaryDispatch(false) { @@ -271,10 +269,10 @@ class WidgetMouseEvent : public WidgetMouseEventBase, // other reasons (typically, a click of right mouse button). ContextMenuTrigger mContextMenuTrigger; - // mExitFrom contains a value only when mMessage is eMouseExitFromWidget. - // This indicates if the mouse cursor exits from a top level platform widget, - // a child widget or a puppet widget. - Maybe mExitFrom; + // mExitFrom is valid only when mMessage is eMouseExitFromWidget. + // This indicates if the mouse cursor exits from a top level widget or + // a child widget. + ExitFrom mExitFrom; // Whether the event should ignore scroll frame bounds during dispatch. bool mIgnoreRootScrollFrame; @@ -292,7 +290,6 @@ class WidgetMouseEvent : public WidgetMouseEventBase, AssignMouseEventBaseData(aEvent, aCopyTargets); AssignPointerHelperData(aEvent, /* aCopyCoalescedEvents */ true); - mExitFrom = aEvent.mExitFrom; mIgnoreRootScrollFrame = aEvent.mIgnoreRootScrollFrame; mClickCount = aEvent.mClickCount; mUseLegacyNonPrimaryDispatch = aEvent.mUseLegacyNonPrimaryDispatch; diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 589e69f8b5a9..7f80f6aa7396 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -3159,9 +3159,9 @@ NSEvent* gLastDragMouseDownEvent = nil; // [strong] EventMessage msg = aEnter ? eMouseEnterIntoWidget : eMouseExitFromWidget; WidgetMouseEvent event(true, msg, mGeckoChild, WidgetMouseEvent::eReal); event.mRefPoint = mGeckoChild->CocoaPointsToDevPixels(localEventLocation); - if (event.mMessage == eMouseExitFromWidget) { - event.mExitFrom = Some(aExitFrom); - } + + event.mExitFrom = aExitFrom; + nsEventStatus status; // ignored mGeckoChild->DispatchEvent(&event, status); } diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 9f9dadd9a661..0807ad0fa344 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -3199,9 +3199,9 @@ void nsWindow::OnLeaveNotifyEvent(GdkEventCrossing* aEvent) { event.mRefPoint = GdkEventCoordsToDevicePixels(aEvent->x, aEvent->y); event.AssignEventTime(GetWidgetEventTime(aEvent->time)); - event.mExitFrom = Some(is_top_level_mouse_exit(mGdkWindow, aEvent) - ? WidgetMouseEvent::eTopLevel - : WidgetMouseEvent::eChild); + event.mExitFrom = is_top_level_mouse_exit(mGdkWindow, aEvent) + ? WidgetMouseEvent::eTopLevel + : WidgetMouseEvent::eChild; LOG(("OnLeaveNotify: %p\n", (void*)this)); diff --git a/widget/nsGUIEventIPC.h b/widget/nsGUIEventIPC.h index a5c8e5c66232..75f12d691c02 100644 --- a/widget/nsGUIEventIPC.h +++ b/widget/nsGUIEventIPC.h @@ -244,11 +244,7 @@ struct ParamTraits { WriteParam(aMsg, static_cast(aParam.mReason)); WriteParam(aMsg, static_cast( aParam.mContextMenuTrigger)); - WriteParam(aMsg, aParam.mExitFrom.isSome()); - if (aParam.mExitFrom.isSome()) { - WriteParam( - aMsg, static_cast(aParam.mExitFrom.value())); - } + WriteParam(aMsg, static_cast(aParam.mExitFrom)); WriteParam(aMsg, aParam.mClickCount); } @@ -257,24 +253,20 @@ struct ParamTraits { bool rv; paramType::ReasonType reason = 0; paramType::ContextMenuTriggerType contextMenuTrigger = 0; - bool hasExitFrom = false; + paramType::ExitFromType exitFrom = 0; rv = ReadParam(aMsg, aIter, static_cast(aResult)) && ReadParam(aMsg, aIter, static_cast(aResult)) && ReadParam(aMsg, aIter, &aResult->mIgnoreRootScrollFrame) && ReadParam(aMsg, aIter, &reason) && - ReadParam(aMsg, aIter, &contextMenuTrigger); + ReadParam(aMsg, aIter, &contextMenuTrigger) && + ReadParam(aMsg, aIter, &exitFrom) && + ReadParam(aMsg, aIter, &aResult->mClickCount); aResult->mReason = static_cast(reason); aResult->mContextMenuTrigger = static_cast(contextMenuTrigger); - rv = rv && ReadParam(aMsg, aIter, &hasExitFrom); - if (hasExitFrom) { - paramType::ExitFromType exitFrom = 0; - rv = rv && ReadParam(aMsg, aIter, &exitFrom); - aResult->mExitFrom = Some(static_cast(exitFrom)); - } - rv = rv && ReadParam(aMsg, aIter, &aResult->mClickCount); + aResult->mExitFrom = static_cast(exitFrom); return rv; } }; diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 37c1e18ea3da..78b9e2cf7237 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -4555,9 +4555,8 @@ bool nsWindow::DispatchMouseEvent(EventMessage aEventMessage, WPARAM wParam, } break; case eMouseExitFromWidget: - event.mExitFrom = - Some(IsTopLevelMouseExit(mWnd) ? WidgetMouseEvent::eTopLevel - : WidgetMouseEvent::eChild); + event.mExitFrom = IsTopLevelMouseExit(mWnd) ? WidgetMouseEvent::eTopLevel + : WidgetMouseEvent::eChild; break; default: break;