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)
This commit is contained in:
@@ -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 <typename FPT, typename FRT, typename SPT, typename SRT>
|
||||
Maybe<int32_t> nsContentUtils::ComparePoints(
|
||||
@@ -7831,7 +7820,7 @@ nsresult nsContentUtils::SendMouseEvent(
|
||||
if (!widget) return NS_ERROR_FAILURE;
|
||||
|
||||
EventMessage msg;
|
||||
Maybe<WidgetMouseEvent::ExitFrom> 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")) {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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<WidgetMouseEvent> 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<WidgetMouseEvent> mouseExitEvent =
|
||||
CreateMouseOrPointerWidgetEvent(mouseEvent,
|
||||
eMouseExitFromWidget,
|
||||
mouseEvent->mRelatedTarget);
|
||||
mouseExitEvent->mExitFrom =
|
||||
Some(WidgetMouseEvent::ePuppetParentToPuppetChild);
|
||||
commonAncestor->SendRealMouseEvent(*mouseExitEvent);
|
||||
}
|
||||
}
|
||||
UniquePtr<WidgetMouseEvent> 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<WidgetMouseEvent> 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
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<div id="reflow"></div>
|
||||
<script>
|
||||
function listener(e) {
|
||||
parent.postMessage({ eventType: e.type, targetName: e.target.localName }, "*");
|
||||
parent.postMessage(e.type, "*");
|
||||
}
|
||||
|
||||
window.addEventListener("message", function(aEvent) {
|
||||
@@ -31,10 +31,6 @@ window.addEventListener("message", function(aEvent) {
|
||||
let target = document.getElementById("target");
|
||||
target.addEventListener("mouseenter", listener);
|
||||
target.addEventListener("mouseleave", listener);
|
||||
|
||||
let root = document.documentElement;
|
||||
root.addEventListener("mouseenter", listener);
|
||||
root.addEventListener("mouseleave", listener);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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 @@
|
||||
<div id="target">
|
||||
<iframe id="frame" frameborder="0" scrolling="no" src="http://example.com/tests/dom/events/test/file_mouse_enterleave.html"></iframe>
|
||||
</div>
|
||||
<div id="target2">
|
||||
<iframe id="frame2" frameborder="0" scrolling="no" src="http://example.com/tests/dom/events/test/file_mouse_enterleave.html"></iframe>
|
||||
</div>
|
||||
<div id="reflow"></div>
|
||||
<script>
|
||||
|
||||
@@ -47,25 +43,17 @@ function reflow() {
|
||||
div.getBoundingClientRect();
|
||||
}
|
||||
|
||||
function waitForMessage(aRemoteTarget, aEventType, aTargetName) {
|
||||
function waitForMessage(aRemoteTarget, aMessage) {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
window.addEventListener("message", function listener(aEvent) {
|
||||
if (aEvent.source != aRemoteTarget.contentWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aEvent.data.eventType !== aEventType) {
|
||||
if (aEvent.data !== aMessage) {
|
||||
window.removeEventListener("message", listener);
|
||||
ok(false, `receive unexpected message ${JSON.stringify(aEvent.data)}`);
|
||||
aReject(new Error(`receive unexpected message ${JSON.stringify(aEvent.data)}`));
|
||||
ok(false, `receive unexpected message ${aEvent.data}`);
|
||||
aReject(new Error(`receive unexpected message ${aEvent.data}`));
|
||||
return;
|
||||
}
|
||||
|
||||
if (aEvent.data.targetName !== aTargetName) {
|
||||
return;
|
||||
}
|
||||
|
||||
ok(true, `receive message ${JSON.stringify(aEvent.data)}`);
|
||||
ok(true, `receive message ${aEvent.data}`);
|
||||
// Trigger a reflow which will generate synthesized mouse move event.
|
||||
aRemoteTarget.contentWindow.postMessage("reflow", "*");
|
||||
// Now wait a bit to see if there is any unexpected message fired.
|
||||
@@ -77,15 +65,6 @@ function waitForMessage(aRemoteTarget, aEventType, aTargetName) {
|
||||
});
|
||||
}
|
||||
|
||||
function waitForLeaveEvent(aTarget) {
|
||||
return new Promise(function(aResolve) {
|
||||
aTarget.addEventListener("mouseleave", function(aEvent) {
|
||||
ok(true, `receive ${aEvent.type}`);
|
||||
aResolve();
|
||||
}, { once: true });
|
||||
});
|
||||
}
|
||||
|
||||
function waitForEnterLeaveEvents(aEnterTarget, aLeaveTarget) {
|
||||
let expectedEvents = [{target: aEnterTarget, eventName: "mouseenter"}];
|
||||
if (aLeaveTarget) {
|
||||
@@ -147,7 +126,6 @@ function moveMouseToInitialPosition() {
|
||||
return new Promise((aResolve) => {
|
||||
let start = document.getElementById("start");
|
||||
let startRect = start.getBoundingClientRect();
|
||||
info("Mouse moves to initial position");
|
||||
synthesizeNativeMouseMove(start, startRect.width / 2, startRect.height / 2,
|
||||
aResolve);
|
||||
});
|
||||
@@ -175,15 +153,13 @@ add_task(async function testMouseEnterLeave() {
|
||||
|
||||
info("Mouse moves into iframe");
|
||||
promise = Promise.all([waitForEnterLeaveEvents(target, div),
|
||||
waitForMessage(iframe, "mouseenter", "div"),
|
||||
waitForMessage(iframe, "mouseenter", "html")]);
|
||||
waitForMessage(iframe, "mouseenter")]);
|
||||
synthesizeNativeMouseMove(target, targetRect.width / 2, targetRect.height / 2);
|
||||
await promise;
|
||||
|
||||
info("Mouse moves out from iframe to the div above iframe");
|
||||
promise = Promise.all([waitForEnterLeaveEvents(div, target),
|
||||
waitForMessage(iframe, "mouseleave", "div"),
|
||||
waitForMessage(iframe, "mouseleave", "html")]);
|
||||
waitForMessage(iframe, "mouseleave")]);
|
||||
synthesizeNativeMouseMove(div, divRect.width / 2, divRect.height / 2);
|
||||
await promise;
|
||||
|
||||
@@ -192,81 +168,4 @@ add_task(async function testMouseEnterLeave() {
|
||||
// multiple times.
|
||||
await moveMouseToInitialPosition();
|
||||
});
|
||||
|
||||
add_task(async function testMouseEnterLeaveBetweenIframe() {
|
||||
let target = document.getElementById("target");
|
||||
let targetRect = target.getBoundingClientRect();
|
||||
let iframe = document.getElementById("frame");
|
||||
|
||||
info("Mouse moves into the first iframe");
|
||||
let promise = Promise.all([waitForEnterLeaveEvents(target),
|
||||
waitForMessage(iframe, "mouseenter", "div"),
|
||||
waitForMessage(iframe, "mouseenter", "html")]);
|
||||
synthesizeNativeMouseMove(target, targetRect.width / 2, targetRect.height / 2);
|
||||
await promise;
|
||||
|
||||
let target2 = document.getElementById("target2");
|
||||
let target2Rect = target2.getBoundingClientRect();
|
||||
let iframe2 = document.getElementById("frame2");
|
||||
|
||||
info("Mouse moves out from the first iframe to the second iframe");
|
||||
promise = Promise.all([waitForEnterLeaveEvents(target2, target),
|
||||
waitForMessage(iframe, "mouseleave", "div"),
|
||||
waitForMessage(iframe, "mouseleave", "html"),
|
||||
waitForMessage(iframe2, "mouseenter", "div"),
|
||||
waitForMessage(iframe2, "mouseenter", "html")]);
|
||||
synthesizeNativeMouseMove(target2, target2Rect.width / 2, target2Rect.height / 2);
|
||||
await promise;
|
||||
|
||||
info("Mouse moves out from the second iframe to the first iframe");
|
||||
promise = Promise.all([waitForEnterLeaveEvents(target, target2),
|
||||
waitForMessage(iframe2, "mouseleave", "div"),
|
||||
waitForMessage(iframe2, "mouseleave", "html"),
|
||||
waitForMessage(iframe, "mouseenter", "div"),
|
||||
waitForMessage(iframe, "mouseenter", "html")]);
|
||||
synthesizeNativeMouseMove(target, targetRect.width / 2, targetRect.height / 2);
|
||||
await promise;
|
||||
|
||||
// Move mouse back to initial position.
|
||||
await Promise.all([waitForLeaveEvent(target),
|
||||
waitForMessage(iframe, "mouseleave", "div"),
|
||||
waitForMessage(iframe, "mouseleave", "html"),
|
||||
moveMouseToInitialPosition()]);
|
||||
});
|
||||
|
||||
add_task(async function testMouseEnterLeaveSwitchWindow() {
|
||||
let target = document.getElementById("target");
|
||||
let targetRect = target.getBoundingClientRect();
|
||||
let iframe = document.getElementById("frame");
|
||||
|
||||
info("Mouse moves into iframe");
|
||||
let promise = Promise.all([waitForEnterLeaveEvents(target),
|
||||
waitForMessage(iframe, "mouseenter", "div"),
|
||||
waitForMessage(iframe, "mouseenter", "html")]);
|
||||
synthesizeNativeMouseMove(target, targetRect.width / 2, targetRect.height / 2);
|
||||
await promise;
|
||||
|
||||
info("Open and switch to new window");
|
||||
promise = Promise.all([waitForLeaveEvent(target),
|
||||
waitForMessage(iframe, "mouseleave", "div"),
|
||||
waitForMessage(iframe, "mouseleave", "html")]);
|
||||
let win = window.open("http://example.com/tests/dom/events/test/file_mouse_enterleave.html");
|
||||
// Trigger a reflow which will generate synthesized mouse move event.
|
||||
win.postMessage("reflow", "*");
|
||||
await promise;
|
||||
|
||||
info("Switch back to test window");
|
||||
promise = Promise.all([waitForEnterLeaveEvents(target),
|
||||
waitForMessage(iframe, "mouseenter", "div"),
|
||||
waitForMessage(iframe, "mouseenter", "html")]);
|
||||
win.close();
|
||||
// Trigger a reflow which will generate synthesized mouse move event.
|
||||
reflow();
|
||||
synthesizeNativeMouseMove(target, targetRect.width / 2, targetRect.height / 2);
|
||||
await promise;
|
||||
|
||||
// Move mouse back to initial position.
|
||||
await Promise.all([waitForLeaveEvent(target),
|
||||
moveMouseToInitialPosition()]);
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -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> delayedMouseEvent =
|
||||
MakeUnique<DelayedMouseEvent>(aGUIEvent->AsMouseEvent());
|
||||
PushDelayedEventIntoQueue(std::move(delayedMouseEvent));
|
||||
|
||||
@@ -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<ExitFrom> 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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -244,11 +244,7 @@ struct ParamTraits<mozilla::WidgetMouseEvent> {
|
||||
WriteParam(aMsg, static_cast<paramType::ReasonType>(aParam.mReason));
|
||||
WriteParam(aMsg, static_cast<paramType::ContextMenuTriggerType>(
|
||||
aParam.mContextMenuTrigger));
|
||||
WriteParam(aMsg, aParam.mExitFrom.isSome());
|
||||
if (aParam.mExitFrom.isSome()) {
|
||||
WriteParam(
|
||||
aMsg, static_cast<paramType::ExitFromType>(aParam.mExitFrom.value()));
|
||||
}
|
||||
WriteParam(aMsg, static_cast<paramType::ExitFromType>(aParam.mExitFrom));
|
||||
WriteParam(aMsg, aParam.mClickCount);
|
||||
}
|
||||
|
||||
@@ -257,24 +253,20 @@ struct ParamTraits<mozilla::WidgetMouseEvent> {
|
||||
bool rv;
|
||||
paramType::ReasonType reason = 0;
|
||||
paramType::ContextMenuTriggerType contextMenuTrigger = 0;
|
||||
bool hasExitFrom = false;
|
||||
paramType::ExitFromType exitFrom = 0;
|
||||
rv = ReadParam(aMsg, aIter,
|
||||
static_cast<mozilla::WidgetMouseEventBase*>(aResult)) &&
|
||||
ReadParam(aMsg, aIter,
|
||||
static_cast<mozilla::WidgetPointerHelper*>(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<paramType::Reason>(reason);
|
||||
aResult->mContextMenuTrigger =
|
||||
static_cast<paramType::ContextMenuTrigger>(contextMenuTrigger);
|
||||
rv = rv && ReadParam(aMsg, aIter, &hasExitFrom);
|
||||
if (hasExitFrom) {
|
||||
paramType::ExitFromType exitFrom = 0;
|
||||
rv = rv && ReadParam(aMsg, aIter, &exitFrom);
|
||||
aResult->mExitFrom = Some(static_cast<paramType::ExitFrom>(exitFrom));
|
||||
}
|
||||
rv = rv && ReadParam(aMsg, aIter, &aResult->mClickCount);
|
||||
aResult->mExitFrom = static_cast<paramType::ExitFrom>(exitFrom);
|
||||
return rv;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user