diff --git a/content/events/src/nsDOMMouseEvent.cpp b/content/events/src/nsDOMMouseEvent.cpp index 75d5aa758739..8ba574007855 100644 --- a/content/events/src/nsDOMMouseEvent.cpp +++ b/content/events/src/nsDOMMouseEvent.cpp @@ -54,6 +54,9 @@ nsDOMMouseEvent::nsDOMMouseEvent(nsPresContext* aPresContext, // DOM event. if (aEvent) { + NS_ASSERTION(static_cast(mEvent)->reason + != nsMouseEvent::eSynthesized, + "Don't dispatch DOM events from synthesized mouse events"); mEventIsInternal = PR_FALSE; } else { diff --git a/content/events/src/nsEventStateManager.cpp b/content/events/src/nsEventStateManager.cpp index 264f2f4e3b7c..51e53b39d516 100644 --- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -184,6 +184,15 @@ static PRUint32 gPixelScrollDeltaTimeout = 0; static nscoord GetScrollableLineHeight(nsIFrame* aTargetFrame); +static inline PRBool +IsMouseEventReal(nsEvent* aEvent) +{ + NS_ABORT_IF_FALSE(aEvent->eventStructType == NS_MOUSE_EVENT, + "Not a mouse event"); + // Return true if not synthesized. + return static_cast(aEvent)->reason == nsMouseEvent::eReal; +} + #ifdef DEBUG_DOCSHELL_FOCUS static void PrintDocTree(nsIDocShellTreeItem* aParentItem, int aLevel) @@ -509,7 +518,7 @@ nsMouseWheelTransaction::OnEvent(nsEvent* aEvent) return; case NS_MOUSE_MOVE: case NS_DRAGDROP_OVER: - if (((nsMouseEvent*)aEvent)->reason == nsMouseEvent::eReal) { + if (IsMouseEventReal(aEvent)) { // If the cursor is moving to be outside the frame, // terminate the scrollwheel transaction. nsIntPoint pt = GetScreenPoint((nsGUIEvent*)aEvent); @@ -1031,7 +1040,7 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext, // when user is not active doesn't change the state to active. if (NS_IS_TRUSTED_EVENT(aEvent) && ((aEvent->eventStructType == NS_MOUSE_EVENT && - static_cast(aEvent)->reason == nsMouseEvent::eReal && + IsMouseEventReal(aEvent) && aEvent->message != NS_MOUSE_ENTER && aEvent->message != NS_MOUSE_EXIT) || aEvent->eventStructType == NS_MOUSE_SCROLL_EVENT || @@ -2819,13 +2828,15 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext, case NS_MOUSE_BUTTON_UP: { SetContentState(nsnull, NS_EVENT_STATE_ACTIVE); - if (!mCurrentTarget) { - nsIFrame* targ; - GetEventTarget(&targ); - } - if (mCurrentTarget) { - ret = - CheckForAndDispatchClick(presContext, (nsMouseEvent*)aEvent, aStatus); + if (IsMouseEventReal(aEvent)) { + if (!mCurrentTarget) { + nsIFrame* targ; + GetEventTarget(&targ); + } + if (mCurrentTarget) { + ret = CheckForAndDispatchClick(presContext, (nsMouseEvent*)aEvent, + aStatus); + } } nsIPresShell *shell = presContext->GetPresShell(); diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 765010edbba9..b1b6c94eaee9 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -6330,8 +6330,8 @@ PresShell::HandleEventWithTarget(nsEvent* aEvent, nsIFrame* aFrame, return NS_OK; } -inline PRBool -IsSynthesizedMouseMove(nsEvent* aEvent) +static inline PRBool +IsSynthesizedMouseEvent(nsEvent* aEvent) { return aEvent->eventStructType == NS_MOUSE_EVENT && static_cast(aEvent)->reason != nsMouseEvent::eReal; @@ -6458,7 +6458,9 @@ PresShell::HandleEventInternal(nsEvent* aEvent, nsIView *aView, if (GetCurrentEventFrame() && NS_SUCCEEDED(rv)) { // We want synthesized mouse moves to cause mouseover and mouseout // DOM events (PreHandleEvent above), but not mousemove DOM events. - if (!IsSynthesizedMouseMove(aEvent)) { + // Synthesized button up events also do not cause DOM events + // because they do not have a reliable refPoint. + if (!IsSynthesizedMouseEvent(aEvent)) { nsPresShellEventCB eventCB(this); if (mCurrentEventContent) { nsEventDispatcher::Dispatch(mCurrentEventContent, mPresContext, diff --git a/view/src/nsViewManager.cpp b/view/src/nsViewManager.cpp index 96b623eeaf54..09a6b0883b5f 100644 --- a/view/src/nsViewManager.cpp +++ b/view/src/nsViewManager.cpp @@ -948,7 +948,7 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent, default: { if ((NS_IS_MOUSE_EVENT(aEvent) && - // Ignore moves that we synthesize. + // Ignore mouse events that we synthesize. static_cast(aEvent)->reason == nsMouseEvent::eReal && // Ignore mouse exit and enter (we'll get moves if the user