Bug 930860 Move IsLeftClickEvent() and IsContextMenuKeyEvent() from WidgetEvent to WidgetMouseEvent(Base) r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Mon, 28 Oct 2013 18:03:19 +0900
changeset 167231 b9d18faa1a974138b0282e7ae5170ed73edfbce5
parent 167207 7e749f99448d948b49de2bc28e4847d2684bc201
child 167232 43b42fb3dc190b7ff107e67bd902d3b701877e94
push id428
push userbbajaj@mozilla.com
push dateTue, 28 Jan 2014 00:16:25 +0000
treeherdermozilla-release@cd72a7ff3a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs930860
milestone27.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 930860 Move IsLeftClickEvent() and IsContextMenuKeyEvent() from WidgetEvent to WidgetMouseEvent(Base) r=smaug
content/base/src/Element.cpp
content/events/src/nsEventStateManager.cpp
content/html/content/src/HTMLButtonElement.cpp
content/html/content/src/HTMLImageElement.cpp
content/html/content/src/HTMLInputElement.cpp
content/html/content/src/HTMLLabelElement.cpp
layout/xul/base/src/nsButtonBoxFrame.cpp
layout/xul/base/src/nsResizerFrame.cpp
layout/xul/base/src/nsResizerFrame.h
layout/xul/base/src/nsScrollBoxFrame.cpp
layout/xul/base/src/nsTitleBarFrame.cpp
layout/xul/base/src/nsTitleBarFrame.h
view/src/nsViewManager.cpp
widget/BasicEvents.h
widget/MouseEvents.h
widget/shared/WidgetEventImpl.cpp
--- a/content/base/src/Element.cpp
+++ b/content/base/src/Element.cpp
@@ -2240,40 +2240,40 @@ Element::PostHandleEventForLinks(nsEvent
 
           nsEventStateManager::SetActiveManager(
             aVisitor.mPresContext->EventStateManager(), this);
         }
       }
     }
     break;
 
-  case NS_MOUSE_CLICK:
-    if (aVisitor.mEvent->IsLeftClickEvent()) {
-      WidgetInputEvent* inputEvent = aVisitor.mEvent->AsInputEvent();
-      if (inputEvent->IsControl() || inputEvent->IsMeta() ||
-          inputEvent->IsAlt() ||inputEvent->IsShift()) {
+  case NS_MOUSE_CLICK: {
+    WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
+    if (mouseEvent->IsLeftClickEvent()) {
+      if (mouseEvent->IsControl() || mouseEvent->IsMeta() ||
+          mouseEvent->IsAlt() ||mouseEvent->IsShift()) {
         break;
       }
 
       // The default action is simply to dispatch DOMActivate
       nsCOMPtr<nsIPresShell> shell = aVisitor.mPresContext->GetPresShell();
       if (shell) {
         // single-click
         nsEventStatus status = nsEventStatus_eIgnore;
-        InternalUIEvent actEvent(aVisitor.mEvent->mFlags.mIsTrusted,
+        InternalUIEvent actEvent(mouseEvent->mFlags.mIsTrusted,
                                  NS_UI_ACTIVATE, 1);
 
         rv = shell->HandleDOMEventWithTarget(this, &actEvent, &status);
         if (NS_SUCCEEDED(rv)) {
           aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
         }
       }
     }
     break;
-
+  }
   case NS_UI_ACTIVATE:
     {
       if (aVisitor.mEvent->originalTarget == this) {
         nsAutoString target;
         GetLinkTarget(target);
         nsContentUtils::TriggerLink(this, aVisitor.mPresContext, absURI, target,
                                     true, true,
                                     aVisitor.mEvent->mFlags.mIsTrusted);
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -1004,32 +1004,33 @@ nsEventStateManager::PreHandleEvent(nsPr
 #ifdef DEBUG
   if (aEvent->HasDragEventMessage() && sIsPointerLocked) {
     NS_ASSERTION(sIsPointerLocked,
       "sIsPointerLocked is true. Drag events should be suppressed when the pointer is locked.");
   }
 #endif
   // Store last known screenPoint and clientPoint so pointer lock
   // can use these values as constants.
+  WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
   if (aEvent->mFlags.mIsTrusted &&
-      ((aEvent->IsMouseDerivedEvent() && IsMouseEventReal(aEvent)) ||
-       aEvent->eventStructType == NS_WHEEL_EVENT)) {
-    if (!sIsPointerLocked) {
-      sLastScreenPoint = nsDOMUIEvent::CalculateScreenPoint(aPresContext, aEvent);
-      sLastClientPoint = nsDOMUIEvent::CalculateClientPoint(aPresContext, aEvent, nullptr);
-    }
+      ((mouseEvent && IsMouseEventReal(mouseEvent)) ||
+       aEvent->eventStructType == NS_WHEEL_EVENT) &&
+      !sIsPointerLocked) {
+    sLastScreenPoint =
+      nsDOMUIEvent::CalculateScreenPoint(aPresContext, aEvent);
+    sLastClientPoint =
+      nsDOMUIEvent::CalculateClientPoint(aPresContext, aEvent, nullptr);
   }
 
   // Do not take account NS_MOUSE_ENTER/EXIT so that loading a page
   // when user is not active doesn't change the state to active.
   if (aEvent->mFlags.mIsTrusted &&
-      ((aEvent->eventStructType == NS_MOUSE_EVENT  &&
-        IsMouseEventReal(aEvent) &&
-        aEvent->message != NS_MOUSE_ENTER &&
-        aEvent->message != NS_MOUSE_EXIT) ||
+      ((mouseEvent && IsMouseEventReal(mouseEvent) &&
+        mouseEvent->message != NS_MOUSE_ENTER &&
+        mouseEvent->message != NS_MOUSE_EXIT) ||
        aEvent->eventStructType == NS_WHEEL_EVENT ||
        aEvent->eventStructType == NS_KEY_EVENT)) {
     if (gMouseOrKeyboardEventCounter == 0) {
       nsCOMPtr<nsIObserverService> obs =
         mozilla::services::GetObserverService();
       if (obs) {
         obs->NotifyObservers(nullptr, "user-interaction-active", nullptr);
         UpdateUserActivityTimer();
@@ -1039,17 +1040,16 @@ nsEventStateManager::PreHandleEvent(nsPr
   }
 
   *aStatus = nsEventStatus_eIgnore;
 
   nsMouseWheelTransaction::OnEvent(aEvent);
 
   switch (aEvent->message) {
   case NS_MOUSE_BUTTON_DOWN: {
-    WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
     switch (mouseEvent->button) {
     case WidgetMouseEvent::eLeftButton:
 #ifndef XP_OS2
       BeginTrackingDragGesture(aPresContext, mouseEvent, aTargetFrame);
 #endif
       mLClickCount = mouseEvent->clickCount;
       SetClickCount(aPresContext, mouseEvent, aStatus);
       sNormalLMouseEventInProcess = true;
@@ -1064,17 +1064,16 @@ nsEventStateManager::PreHandleEvent(nsPr
 #endif
       mRClickCount = mouseEvent->clickCount;
       SetClickCount(aPresContext, mouseEvent, aStatus);
       break;
     }
     break;
   }
   case NS_MOUSE_BUTTON_UP: {
-    WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
     switch (mouseEvent->button) {
       case WidgetMouseEvent::eLeftButton:
         if (Prefs::ClickHoldContextMenu()) {
           KillClickHoldTimer();
         }
 #ifndef XP_OS2
         StopTrackingDragGesture();
 #endif
@@ -1090,40 +1089,36 @@ nsEventStateManager::PreHandleEvent(nsPr
         break;
     }
     break;
   }
   case NS_MOUSE_EXIT:
     // 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.
-    {
-      WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
-      if (mouseEvent->exit != 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
-        mouseEvent->message = NS_MOUSE_MOVE;
-        mouseEvent->reason = WidgetMouseEvent::eSynthesized;
-        // then fall through...
-      } else {
-        GenerateMouseEnterExit(mouseEvent);
-        //This is a window level mouse exit event and should stop here
-        aEvent->message = 0;
-        break;
-      }
+    if (mouseEvent->exit != 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
+      mouseEvent->message = NS_MOUSE_MOVE;
+      mouseEvent->reason = WidgetMouseEvent::eSynthesized;
+      // then fall through...
+    } else {
+      GenerateMouseEnterExit(mouseEvent);
+      //This is a window level mouse exit event and should stop here
+      aEvent->message = 0;
+      break;
     }
   case NS_MOUSE_MOVE: {
     // on the Mac, GenerateDragGesture() may not return until the drag
     // has completed and so |aTargetFrame| may have been deleted (moving
     // a bookmark, for example).  If this is the case, however, we know
     // that ClearFrameRefs() has been called and it cleared out
     // |mCurrentTarget|. As a result, we should pass |mCurrentTarget|
     // into UpdateCursor().
-    WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
     GenerateDragGesture(aPresContext, mouseEvent);
     UpdateCursor(aPresContext, aEvent, mCurrentTarget, aStatus);
     GenerateMouseEnterExit(mouseEvent);
     // Flush pending layout changes, so that later mouse move events
     // will go to the right nodes.
     FlushPendingEvents(aPresContext);
     break;
   }
--- a/content/html/content/src/HTMLButtonElement.cpp
+++ b/content/html/content/src/HTMLButtonElement.cpp
@@ -193,18 +193,19 @@ HTMLButtonElement::PreHandleEvent(nsEven
   if (IsDisabledForEvents(aVisitor.mEvent->message)) {
     return NS_OK;
   }
 
   // Track whether we're in the outermost Dispatch invocation that will
   // cause activation of the input.  That is, if we're a click event, or a
   // DOMActivate that was dispatched directly, this will be set, but if we're
   // a DOMActivate dispatched from click handling, it will not be set.
+  WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
   bool outerActivateEvent =
-    (aVisitor.mEvent->IsLeftClickEvent() ||
+    ((mouseEvent && mouseEvent->IsLeftClickEvent()) ||
      (aVisitor.mEvent->message == NS_UI_ACTIVATE &&
       !mInInternalActivate));
 
   if (outerActivateEvent) {
     aVisitor.mItemFlags |= NS_OUTER_ACTIVATE_EVENT;
     if (mType == NS_FORM_BUTTON_SUBMIT && mForm) {
       aVisitor.mItemFlags |= NS_IN_SUBMIT_CLICK;
       // tell the form that we are about to enter a click handler.
@@ -220,32 +221,35 @@ HTMLButtonElement::PreHandleEvent(nsEven
 nsresult
 HTMLButtonElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
 {
   nsresult rv = NS_OK;
   if (!aVisitor.mPresContext) {
     return rv;
   }
 
-  if (aVisitor.mEventStatus != nsEventStatus_eConsumeNoDefault &&
-      aVisitor.mEvent->IsLeftClickEvent()) {
-    InternalUIEvent actEvent(aVisitor.mEvent->mFlags.mIsTrusted,
-                             NS_UI_ACTIVATE, 1);
+  if (aVisitor.mEventStatus != nsEventStatus_eConsumeNoDefault) {
+    WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
+    if (mouseEvent && mouseEvent->IsLeftClickEvent()) {
+      InternalUIEvent actEvent(aVisitor.mEvent->mFlags.mIsTrusted,
+                               NS_UI_ACTIVATE, 1);
 
-    nsCOMPtr<nsIPresShell> shell = aVisitor.mPresContext->GetPresShell();
-    if (shell) {
-      nsEventStatus status = nsEventStatus_eIgnore;
-      mInInternalActivate = true;
-      shell->HandleDOMEventWithTarget(this, &actEvent, &status);
-      mInInternalActivate = false;
+      nsCOMPtr<nsIPresShell> shell = aVisitor.mPresContext->GetPresShell();
+      if (shell) {
+        nsEventStatus status = nsEventStatus_eIgnore;
+        mInInternalActivate = true;
+        shell->HandleDOMEventWithTarget(this, &actEvent, &status);
+        mInInternalActivate = false;
 
-      // If activate is cancelled, we must do the same as when click is
-      // cancelled (revert the checkbox to its original value).
-      if (status == nsEventStatus_eConsumeNoDefault)
-        aVisitor.mEventStatus = status;
+        // If activate is cancelled, we must do the same as when click is
+        // cancelled (revert the checkbox to its original value).
+        if (status == nsEventStatus_eConsumeNoDefault) {
+          aVisitor.mEventStatus = status;
+        }
+      }
     }
   }
 
   // mForm is null if the event handler removed us from the document (bug 194582).
   if ((aVisitor.mItemFlags & NS_IN_SUBMIT_CLICK) && mForm) {
     // tell the form that we are about to exit a click handler
     // so the form knows not to defer subsequent submissions
     // the pending ones that were created during the handler
--- a/content/html/content/src/HTMLImageElement.cpp
+++ b/content/html/content/src/HTMLImageElement.cpp
@@ -368,17 +368,18 @@ HTMLImageElement::AfterSetAttr(int32_t a
 
 nsresult
 HTMLImageElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
 {
   // If we are a map and get a mouse click, don't let it be handled by
   // the Generic Element as this could cause a click event to fire
   // twice, once by the image frame for the map and once by the Anchor
   // element. (bug 39723)
-  if (aVisitor.mEvent->IsLeftClickEvent()) {
+  WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
+  if (mouseEvent && mouseEvent->IsLeftClickEvent()) {
     bool isMap = false;
     GetIsMap(&isMap);
     if (isMap) {
       aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
     }
   }
   return nsGenericHTMLElement::PreHandleEvent(aVisitor);
 }
--- a/content/html/content/src/HTMLInputElement.cpp
+++ b/content/html/content/src/HTMLInputElement.cpp
@@ -3107,18 +3107,19 @@ HTMLInputElement::PreHandleEvent(nsEvent
   //
   // This is a compatibility hack.
   //
 
   // Track whether we're in the outermost Dispatch invocation that will
   // cause activation of the input.  That is, if we're a click event, or a
   // DOMActivate that was dispatched directly, this will be set, but if we're
   // a DOMActivate dispatched from click handling, it will not be set.
+  WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
   bool outerActivateEvent =
-    (aVisitor.mEvent->IsLeftClickEvent() ||
+    ((mouseEvent && mouseEvent->IsLeftClickEvent()) ||
      (aVisitor.mEvent->message == NS_UI_ACTIVATE && !mInInternalActivate));
 
   if (outerActivateEvent) {
     aVisitor.mItemFlags |= NS_OUTER_ACTIVATE_EVENT;
   }
 
   bool originalCheckedValue = false;
 
@@ -3337,24 +3338,28 @@ HTMLInputElement::MaybeInitPickers(nsEve
 {
   // Open a file picker when we receive a click on a <input type='file'>, or
   // open a color picker when we receive a click on a <input type='color'>.
   // A click is handled in the following cases:
   // - preventDefault() has not been called (or something similar);
   // - it's the left mouse button.
   // We do not prevent non-trusted click because authors can already use
   // .click(). However, the pickers will follow the rules of popup-blocking.
-  if (aVisitor.mEvent->IsLeftClickEvent() &&
-      !aVisitor.mEvent->mFlags.mDefaultPrevented) {
-    if (mType == NS_FORM_INPUT_FILE) {
-      return InitFilePicker(FILE_PICKER_FILE);
-    }
-    if (mType == NS_FORM_INPUT_COLOR) {
-      return InitColorPicker();
-    }
+  if (aVisitor.mEvent->mFlags.mDefaultPrevented) {
+    return NS_OK;
+  }
+  WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
+  if (!(mouseEvent && mouseEvent->IsLeftClickEvent())) {
+    return NS_OK;
+  }
+  if (mType == NS_FORM_INPUT_FILE) {
+    return InitFilePicker(FILE_PICKER_FILE);
+  }
+  if (mType == NS_FORM_INPUT_COLOR) {
+    return InitColorPicker();
   }
   return NS_OK;
 }
 
 nsresult
 HTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
 {
   if (!aVisitor.mPresContext) {
@@ -3390,33 +3395,36 @@ HTMLInputElement::PostHandleEvent(nsEven
   // Ideally we would make the default action for click and space just dispatch
   // DOMActivate, and the default action for DOMActivate flip the checkbox/
   // radio state and fire onchange.  However, for backwards compatibility, we
   // need to flip the state before firing click, and we need to fire click
   // when space is pressed.  So, we just nest the firing of DOMActivate inside
   // the click event handling, and allow cancellation of DOMActivate to cancel
   // the click.
   if (aVisitor.mEventStatus != nsEventStatus_eConsumeNoDefault &&
-      !IsSingleLineTextControl(true) &&
-      aVisitor.mEvent->IsLeftClickEvent() &&
-      !ShouldPreventDOMActivateDispatch(aVisitor.mEvent->originalTarget)) {
-    InternalUIEvent actEvent(aVisitor.mEvent->mFlags.mIsTrusted,
-                             NS_UI_ACTIVATE, 1);
-
-    nsCOMPtr<nsIPresShell> shell = aVisitor.mPresContext->GetPresShell();
-    if (shell) {
-      nsEventStatus status = nsEventStatus_eIgnore;
-      mInInternalActivate = true;
-      rv = shell->HandleDOMEventWithTarget(this, &actEvent, &status);
-      mInInternalActivate = false;
-
-      // If activate is cancelled, we must do the same as when click is
-      // cancelled (revert the checkbox to its original value).
-      if (status == nsEventStatus_eConsumeNoDefault)
-        aVisitor.mEventStatus = status;
+      !IsSingleLineTextControl(true)) {
+    WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
+    if (mouseEvent && mouseEvent->IsLeftClickEvent() &&
+        !ShouldPreventDOMActivateDispatch(aVisitor.mEvent->originalTarget)) {
+      InternalUIEvent actEvent(aVisitor.mEvent->mFlags.mIsTrusted,
+                               NS_UI_ACTIVATE, 1);
+
+      nsCOMPtr<nsIPresShell> shell = aVisitor.mPresContext->GetPresShell();
+      if (shell) {
+        nsEventStatus status = nsEventStatus_eIgnore;
+        mInInternalActivate = true;
+        rv = shell->HandleDOMEventWithTarget(this, &actEvent, &status);
+        mInInternalActivate = false;
+
+        // If activate is cancelled, we must do the same as when click is
+        // cancelled (revert the checkbox to its original value).
+        if (status == nsEventStatus_eConsumeNoDefault) {
+          aVisitor.mEventStatus = status;
+        }
+      }
     }
   }
 
   if (outerActivateEvent) {
     switch(oldType) {
       case NS_FORM_INPUT_SUBMIT:
       case NS_FORM_INPUT_IMAGE:
         if (mForm) {
--- a/content/html/content/src/HTMLLabelElement.cpp
+++ b/content/html/content/src/HTMLLabelElement.cpp
@@ -109,48 +109,47 @@ DestroyMouseDownPoint(void *    /*aObjec
 {
   LayoutDeviceIntPoint* pt = static_cast<LayoutDeviceIntPoint*>(aPropertyValue);
   delete pt;
 }
 
 nsresult
 HTMLLabelElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
 {
+  WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
   if (mHandlingEvent ||
-      (!aVisitor.mEvent->IsLeftClickEvent() &&
+      (!(mouseEvent && mouseEvent->IsLeftClickEvent()) &&
        aVisitor.mEvent->message != NS_MOUSE_BUTTON_DOWN) ||
       aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault ||
       !aVisitor.mPresContext ||
       // Don't handle the event if it's already been handled by another label
       aVisitor.mEvent->mFlags.mMultipleActionsPrevented) {
     return NS_OK;
   }
 
   // Strong ref because event dispatch is going to happen.
   nsRefPtr<Element> content = GetLabeledElement();
 
   if (content && !EventTargetIn(aVisitor.mEvent, content, this)) {
     mHandlingEvent = true;
     switch (aVisitor.mEvent->message) {
       case NS_MOUSE_BUTTON_DOWN:
-        if (aVisitor.mEvent->AsMouseEvent()->button ==
-              WidgetMouseEvent::eLeftButton) {
+        if (mouseEvent->button == WidgetMouseEvent::eLeftButton) {
           // We reset the mouse-down point on every event because there is
           // no guarantee we will reach the NS_MOUSE_CLICK code below.
           LayoutDeviceIntPoint* curPoint =
-            new LayoutDeviceIntPoint(aVisitor.mEvent->refPoint);
+            new LayoutDeviceIntPoint(mouseEvent->refPoint);
           SetProperty(nsGkAtoms::labelMouseDownPtProperty,
                       static_cast<void*>(curPoint),
                       DestroyMouseDownPoint);
         }
         break;
 
       case NS_MOUSE_CLICK:
-        if (aVisitor.mEvent->IsLeftClickEvent()) {
-          WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
+        if (mouseEvent->IsLeftClickEvent()) {
           LayoutDeviceIntPoint* mouseDownPoint =
             static_cast<LayoutDeviceIntPoint*>(
               GetProperty(nsGkAtoms::labelMouseDownPtProperty));
 
           bool dragSelect = false;
           if (mouseDownPoint) {
             LayoutDeviceIntPoint dragDistance = *mouseDownPoint;
             DeleteProperty(nsGkAtoms::labelMouseDownPtProperty);
--- a/layout/xul/base/src/nsButtonBoxFrame.cpp
+++ b/layout/xul/base/src/nsButtonBoxFrame.cpp
@@ -11,16 +11,17 @@
 #include "nsINameSpaceManager.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsEventStateManager.h"
 #include "nsIDOMElement.h"
 #include "nsDisplayList.h"
 #include "nsContentUtils.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/MouseEvents.h"
 #include "mozilla/TextEvents.h"
 
 using namespace mozilla;
 
 //
 // NS_NewXULButtonFrame
 //
 // Creates a new Button frame and returns it
@@ -103,21 +104,23 @@ nsButtonBoxFrame::HandleEvent(nsPresCont
           esm->SetContentState(nullptr, NS_EVENT_STATE_ACTIVE);
           esm->SetContentState(nullptr, NS_EVENT_STATE_HOVER);
           MouseClicked(aPresContext, aEvent);
         }
       }
       break;
     }
 
-    case NS_MOUSE_CLICK:
-      if (aEvent->IsLeftClickEvent()) {
-        MouseClicked(aPresContext, aEvent);
+    case NS_MOUSE_CLICK: {
+      WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
+      if (mouseEvent->IsLeftClickEvent()) {
+        MouseClicked(aPresContext, mouseEvent);
       }
       break;
+    }
   }
 
   return nsBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
 }
 
 void 
 nsButtonBoxFrame::DoMouseClick(WidgetGUIEvent* aEvent, bool aTrustEvent)
 {
--- a/layout/xul/base/src/nsResizerFrame.cpp
+++ b/layout/xul/base/src/nsResizerFrame.cpp
@@ -278,23 +278,23 @@ nsResizerFrame::HandleEvent(nsPresContex
         window->SetPositionAndSize(rect.x, rect.y, rect.width, rect.height, true); // do the repaint.
       }
 
       doDefault = false;
     }
   }
   break;
 
-  case NS_MOUSE_CLICK:
-    if (aEvent->IsLeftClickEvent())
-    {
-      MouseClicked(aPresContext, aEvent);
+  case NS_MOUSE_CLICK: {
+    WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
+    if (mouseEvent->IsLeftClickEvent()) {
+      MouseClicked(aPresContext, mouseEvent);
     }
     break;
-
+  }
   case NS_MOUSE_DOUBLECLICK:
     if (aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton) {
       nsCOMPtr<nsIBaseWindow> window;
       nsIPresShell* presShell = aPresContext->GetPresShell();
       nsIContent* contentToResize =
         GetContentToResize(presShell, getter_AddRefs(window));
       if (contentToResize) {
         nsMenuPopupFrame* menuPopupFrame = do_QueryFrame(contentToResize->GetPrimaryFrame());
@@ -531,14 +531,14 @@ nsResizerFrame::GetDirection()
     direction.mHorizontal *= -1;
     return direction;
   }
   return directions[index];
 }
 
 void
 nsResizerFrame::MouseClicked(nsPresContext* aPresContext,
-                             WidgetGUIEvent *aEvent)
+                             WidgetMouseEvent* aEvent)
 {
   // Execute the oncommand event handler.
   nsContentUtils::DispatchXULCommand(mContent,
                                      aEvent && aEvent->mFlags.mIsTrusted);
 }
--- a/layout/xul/base/src/nsResizerFrame.h
+++ b/layout/xul/base/src/nsResizerFrame.h
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef nsResizerFrame_h___
 #define nsResizerFrame_h___
 
 #include "mozilla/Attributes.h"
+#include "mozilla/EventForwards.h"
 #include "nsTitleBarFrame.h"
 
 class nsIBaseWindow;
 class nsMenuPopupFrame;
 
 class nsResizerFrame : public nsTitleBarFrame 
 {
 protected:
@@ -26,17 +27,17 @@ public:
 
   nsResizerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   NS_IMETHOD HandleEvent(nsPresContext* aPresContext,
                          mozilla::WidgetGUIEvent* aEvent,
                          nsEventStatus* aEventStatus) MOZ_OVERRIDE;
 
   virtual void MouseClicked(nsPresContext* aPresContext,
-                            mozilla::WidgetGUIEvent* aEvent) MOZ_OVERRIDE;
+                            mozilla::WidgetMouseEvent* aEvent) MOZ_OVERRIDE;
 
 protected:
   nsIContent* GetContentToResize(nsIPresShell* aPresShell, nsIBaseWindow** aWindow);
 
   Direction GetDirection();
 
   /**
    * Adjust the window position and size in a direction according to the mouse
--- a/layout/xul/base/src/nsScrollBoxFrame.cpp
+++ b/layout/xul/base/src/nsScrollBoxFrame.cpp
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsCOMPtr.h"
 #include "nsPresContext.h"
 #include "nsGkAtoms.h"
 #include "nsButtonBoxFrame.h"
 #include "nsITimer.h"
 #include "nsRepeatService.h"
-#include "mozilla/BasicEvents.h"
+#include "mozilla/MouseEvents.h"
 #include "nsIContent.h"
 
 using namespace mozilla;
 
 class nsAutoRepeatBoxFrame : public nsButtonBoxFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS
@@ -99,22 +99,24 @@ nsAutoRepeatBoxFrame::HandleEvent(nsPres
     case NS_MOUSE_EXIT:
     case NS_MOUSE_EXIT_SYNTH:
       // always stop on mouse exit
       StopRepeat();
       // Not really necessary but do this to be safe
       mTrustedEvent = false;
       break;
 
-    case NS_MOUSE_CLICK:
-      if (aEvent->IsLeftClickEvent()) {
+    case NS_MOUSE_CLICK: {
+      WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
+      if (mouseEvent->IsLeftClickEvent()) {
         // skip button frame handling to prevent click handling
-         return nsBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
+        return nsBoxFrame::HandleEvent(aPresContext, mouseEvent, aEventStatus);
       }
       break;
+    }
   }
      
   return nsButtonBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
 }
 
 NS_IMETHODIMP
 nsAutoRepeatBoxFrame::HandlePress(nsPresContext* aPresContext,
                                   WidgetGUIEvent* aEvent,
--- a/layout/xul/base/src/nsTitleBarFrame.cpp
+++ b/layout/xul/base/src/nsTitleBarFrame.cpp
@@ -143,32 +143,31 @@ nsTitleBarFrame::HandleEvent(nsPresConte
 
          *aEventStatus = nsEventStatus_eConsumeNoDefault;
 
          doDefault = false;
        }
      }
      break;
 
-
-
-    case NS_MOUSE_CLICK:
-      if (aEvent->IsLeftClickEvent())
-      {
-        MouseClicked(aPresContext, aEvent);
+    case NS_MOUSE_CLICK: {
+      WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
+      if (mouseEvent->IsLeftClickEvent()) {
+        MouseClicked(aPresContext, mouseEvent);
       }
       break;
+    }
   }
 
   if ( doDefault )
     return nsBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
   else
     return NS_OK;
 }
 
 void
 nsTitleBarFrame::MouseClicked(nsPresContext* aPresContext,
-                              WidgetGUIEvent* aEvent)
+                              WidgetMouseEvent* aEvent)
 {
   // Execute the oncommand event handler.
   nsContentUtils::DispatchXULCommand(mContent,
                                      aEvent && aEvent->mFlags.mIsTrusted);
 }
--- a/layout/xul/base/src/nsTitleBarFrame.h
+++ b/layout/xul/base/src/nsTitleBarFrame.h
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef nsTitleBarFrame_h___
 #define nsTitleBarFrame_h___
 
 #include "mozilla/Attributes.h"
+#include "mozilla/EventForwards.h"
 #include "nsBoxFrame.h"
 
 class nsTitleBarFrame : public nsBoxFrame  
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewTitleBarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);  
@@ -21,17 +22,17 @@ public:
                                            const nsRect&           aDirtyRect,
                                            const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   NS_IMETHOD HandleEvent(nsPresContext* aPresContext,
                          mozilla::WidgetGUIEvent* aEvent,
                          nsEventStatus* aEventStatus) MOZ_OVERRIDE;
 
   virtual void MouseClicked(nsPresContext* aPresContext,
-                            mozilla::WidgetGUIEvent* aEvent);
+                            mozilla::WidgetMouseEvent* aEvent);
 
   void UpdateMouseThrough() MOZ_OVERRIDE { AddStateBits(NS_FRAME_MOUSE_THROUGH_NEVER); }
 
 protected:
 	bool mTrackingMouseMove;	
 	nsIntPoint mLastPoint;
 
 }; // class nsTitleBarFrame
--- a/view/src/nsViewManager.cpp
+++ b/view/src/nsViewManager.cpp
@@ -698,24 +698,25 @@ void nsViewManager::DidPaintWindow()
 
 void
 nsViewManager::DispatchEvent(WidgetGUIEvent *aEvent,
                              nsView* aView,
                              nsEventStatus* aStatus)
 {
   PROFILER_LABEL("event", "nsViewManager::DispatchEvent");
 
-  if ((aEvent->HasMouseEventMessage() &&
+  WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
+  if ((mouseEvent &&
        // Ignore mouse events that we synthesize.
-       aEvent->AsMouseEvent()->reason == WidgetMouseEvent::eReal &&
+       mouseEvent->reason == WidgetMouseEvent::eReal &&
        // Ignore mouse exit and enter (we'll get moves if the user
        // is really moving the mouse) since we get them when we
        // create and destroy widgets.
-       aEvent->message != NS_MOUSE_EXIT &&
-       aEvent->message != NS_MOUSE_ENTER) ||
+       mouseEvent->message != NS_MOUSE_EXIT &&
+       mouseEvent->message != NS_MOUSE_ENTER) ||
       aEvent->HasKeyEventMessage() ||
       aEvent->HasIMEEventMessage() ||
       aEvent->message == NS_PLUGIN_INPUT_EVENT) {
     gLastUserEventTime = PR_IntervalToMicroseconds(PR_IntervalNow());
   }
 
   // Find the view whose coordinates system we're in.
   nsView* view = aView;
--- a/widget/BasicEvents.h
+++ b/widget/BasicEvents.h
@@ -733,24 +733,16 @@ public:
    */
   bool HasIMEEventMessage() const;
   /**
    * Returns true if the event message is one of plugin activation events.
    */
   bool HasPluginActivationEventMessage() const;
 
   /**
-   * Returns true if left click event.
-   */
-  bool IsLeftClickEvent() const;
-  /**
-   * Returns true if the event is a context menu event caused by key.
-   */
-  bool IsContextMenuKeyEvent() const;
-  /**
    * Returns true if the event is native event deliverer event for plugin and
    * it should be retarted to focused document.
    */
   bool IsRetargetedNativeEventDelivererForPlugin() const;
   /**
    * Returns true if the event is native event deliverer event for plugin and
    * it should NOT be retarted to focused document.
    */
--- a/widget/MouseEvents.h
+++ b/widget/MouseEvents.h
@@ -103,16 +103,24 @@ public:
     AssignInputEventData(aEvent, aCopyTargets);
 
     relatedTarget = aCopyTargets ? aEvent.relatedTarget : nullptr;
     button = aEvent.button;
     buttons = aEvent.buttons;
     pressure = aEvent.pressure;
     inputSource = aEvent.inputSource;
   }
+
+  /**
+   * Returns true if left click event.
+   */
+  bool IsLeftClickEvent() const
+  {
+    return message == NS_MOUSE_CLICK && button == eLeftButton;
+  }
 };
 
 /******************************************************************************
  * mozilla::WidgetMouseEvent
  ******************************************************************************/
 
 class WidgetMouseEvent : public WidgetMouseEventBase
 {
@@ -216,16 +224,24 @@ public:
   void AssignMouseEventData(const WidgetMouseEvent& aEvent, bool aCopyTargets)
   {
     AssignMouseEventBaseData(aEvent, aCopyTargets);
 
     acceptActivation = aEvent.acceptActivation;
     ignoreRootScrollFrame = aEvent.ignoreRootScrollFrame;
     clickCount = aEvent.clickCount;
   }
+
+  /**
+   * Returns true if the event is a context menu event caused by key.
+   */
+  bool IsContextMenuKeyEvent() const
+  {
+    return message == NS_CONTEXTMENU && context == eContextMenuKey;
+  }
 };
 
 /******************************************************************************
  * mozilla::WidgetDragEvent
  ******************************************************************************/
 
 class WidgetDragEvent : public WidgetMouseEvent
 {
--- a/widget/shared/WidgetEventImpl.cpp
+++ b/widget/shared/WidgetEventImpl.cpp
@@ -162,32 +162,16 @@ WidgetEvent::HasPluginActivationEventMes
 
 /******************************************************************************
  * mozilla::WidgetEvent
  *
  * Specific event checking methods.
  ******************************************************************************/
 
 bool
-WidgetEvent::IsLeftClickEvent() const
-{
-  const WidgetMouseEvent* mouseEvent = AsMouseEvent();
-  return mouseEvent && message == NS_MOUSE_CLICK &&
-         mouseEvent->button == WidgetMouseEvent::eLeftButton;
-}
-
-bool
-WidgetEvent::IsContextMenuKeyEvent() const
-{
-  const WidgetMouseEvent* mouseEvent = AsMouseEvent();
-  return mouseEvent && message == NS_CONTEXTMENU &&
-         mouseEvent->context == WidgetMouseEvent::eContextMenuKey;
-}
-
-bool
 WidgetEvent::IsRetargetedNativeEventDelivererForPlugin() const
 {
   const WidgetPluginEvent* pluginEvent = AsPluginEvent();
   return pluginEvent && pluginEvent->retargetToFocusedDocument;
 }
 
 bool
 WidgetEvent::IsNonRetargetedNativeEventDelivererForPlugin() const
@@ -200,38 +184,47 @@ bool
 WidgetEvent::IsIMERelatedEvent() const
 {
   return HasIMEEventMessage() || IsQueryContentEvent() || IsSelectionEvent();
 }
 
 bool
 WidgetEvent::IsUsingCoordinates() const
 {
+  const WidgetMouseEvent* mouseEvent = AsMouseEvent();
+  if (mouseEvent) {
+    return !mouseEvent->IsContextMenuKeyEvent();
+  }
   return !HasKeyEventMessage() && !IsIMERelatedEvent() &&
-         !IsContextMenuKeyEvent() &&
          !HasPluginActivationEventMessage() &&
          !IsNativeEventDelivererForPlugin() &&
          !IsContentCommandEvent() &&
          message != NS_PLUGIN_RESOLUTION_CHANGED;
 }
 
 bool
 WidgetEvent::IsTargetedAtFocusedWindow() const
 {
+  const WidgetMouseEvent* mouseEvent = AsMouseEvent();
+  if (mouseEvent) {
+    return mouseEvent->IsContextMenuKeyEvent();
+  }
   return HasKeyEventMessage() || IsIMERelatedEvent() ||
-         IsContextMenuKeyEvent() ||
          IsContentCommandEvent() ||
          IsRetargetedNativeEventDelivererForPlugin();
 }
 
 bool
 WidgetEvent::IsTargetedAtFocusedContent() const
 {
+  const WidgetMouseEvent* mouseEvent = AsMouseEvent();
+  if (mouseEvent) {
+    return mouseEvent->IsContextMenuKeyEvent();
+  }
   return HasKeyEventMessage() || IsIMERelatedEvent() ||
-         IsContextMenuKeyEvent() ||
          IsRetargetedNativeEventDelivererForPlugin();
 }
 
 bool
 WidgetEvent::IsAllowedToDispatchDOMEvent() const
 {
   switch (eventStructType) {
     case NS_MOUSE_EVENT: