Bug 930177 - Consolidate async scroll event handling with keyboard handling. r=tabraldes
authorJim Mathies <jmathies@mozilla.com>
Thu, 24 Oct 2013 16:35:07 -0500
changeset 165914 c74facfb70ab24462bc0a55c2ff7017e03fa01fc
parent 165913 08f5ba64a98854444bb9aabd1b3952149130861b
child 165915 d439b0f78fe99111a02a59b50861c9940bce2e19
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstabraldes
bugs930177
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 930177 - Consolidate async scroll event handling with keyboard handling. r=tabraldes
widget/MiscEvents.h
widget/windows/WinMouseScrollHandler.cpp
widget/windows/nsWindow.cpp
widget/windows/nsWindow.h
widget/windows/nsWindowBase.h
widget/windows/winrt/MetroWidget.cpp
widget/windows/winrt/MetroWidget.h
--- a/widget/MiscEvents.h
+++ b/widget/MiscEvents.h
@@ -58,16 +58,27 @@ public:
     uint8_t mUnit;      // [in]
     bool mIsHorizontal; // [in]
   } mScroll;
 
   bool mOnlyEnabledCheck; // [in]
 
   bool mSucceeded; // [out]
   bool mIsEnabled; // [out]
+
+  void AssignContentCommandEventData(const WidgetContentCommandEvent& aEvent,
+                                     bool aCopyTargets)
+  {
+    AssignGUIEventData(aEvent, aCopyTargets);
+
+    mScroll = aEvent.mScroll;
+    mOnlyEnabledCheck = aEvent.mOnlyEnabledCheck;
+    mSucceeded = aEvent.mSucceeded;
+    mIsEnabled = aEvent.mIsEnabled;
+  }
 };
 
 /******************************************************************************
  * mozilla::WidgetCommandEvent
  *
  * This sends a command to chrome.  If you want to request what is performed
  * in focused content, you should use WidgetContentCommandEvent instead.
  *
--- a/widget/windows/WinMouseScrollHandler.cpp
+++ b/widget/windows/WinMouseScrollHandler.cpp
@@ -323,17 +323,18 @@ MouseScrollHandler::SynthesizeNativeMous
            Synthesize(pts, target, aNativeMessage, wParam, lParam, kbdState);
 }
 
 /* static */
 bool
 MouseScrollHandler::DispatchEvent(nsWindowBase* aWidget,
                                   WidgetGUIEvent& aEvent)
 {
-  return aWidget->DispatchWindowEvent(&aEvent);
+  // note, in metrofx, this will always return false for now
+  return aWidget->DispatchScrollEvent(&aEvent);
 }
 
 /* static */
 void
 MouseScrollHandler::InitEvent(nsWindowBase* aWidget,
                               WidgetGUIEvent& aEvent,
                               nsIntPoint* aPoint)
 {
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -3676,16 +3676,23 @@ bool nsWindow::DispatchStandardEvent(uin
 
 bool nsWindow::DispatchKeyboardEvent(WidgetGUIEvent* event)
 {
   nsEventStatus status;
   DispatchEvent(event, status);
   return ConvertStatus(status);
 }
 
+bool nsWindow::DispatchScrollEvent(WidgetGUIEvent* event)
+{
+  nsEventStatus status;
+  DispatchEvent(event, status);
+  return ConvertStatus(status);
+}
+
 bool nsWindow::DispatchWindowEvent(WidgetGUIEvent* event)
 {
   nsEventStatus status;
   DispatchEvent(event, status);
   return ConvertStatus(status);
 }
 
 bool nsWindow::DispatchWindowEvent(WidgetGUIEvent* event,
--- a/widget/windows/nsWindow.h
+++ b/widget/windows/nsWindow.h
@@ -86,16 +86,17 @@ public:
 
   friend class nsWindowGfx;
 
   // nsWindowBase
   virtual void InitEvent(mozilla::WidgetGUIEvent& aEvent,
                          nsIntPoint* aPoint = nullptr) MOZ_OVERRIDE;
   virtual bool DispatchWindowEvent(mozilla::WidgetGUIEvent* aEvent) MOZ_OVERRIDE;
   virtual bool DispatchKeyboardEvent(mozilla::WidgetGUIEvent* aEvent) MOZ_OVERRIDE;
+  virtual bool DispatchScrollEvent(mozilla::WidgetGUIEvent* aEvent) MOZ_OVERRIDE;
   virtual nsWindowBase* GetParentWindowBase(bool aIncludeOwner) MOZ_OVERRIDE;
   virtual bool IsTopLevelWidget() MOZ_OVERRIDE { return mIsTopWidgetWindow; }
 
   // nsIWidget interface
   NS_IMETHOD              Create(nsIWidget *aParent,
                                  nsNativeWidget aNativeParent,
                                  const nsIntRect &aRect,
                                  nsDeviceContext *aContext,
--- a/widget/windows/nsWindowBase.h
+++ b/widget/windows/nsWindowBase.h
@@ -51,16 +51,23 @@ public:
   /*
    * Dispatch a gecko keyboard event for this widget. This
    * is called by KeyboardLayout to dispatch gecko events.
    * Returns true if it's consumed.  Otherwise, false.
    */
   virtual bool DispatchKeyboardEvent(mozilla::WidgetGUIEvent* aEvent) = 0;
 
   /*
+   * Dispatch a gecko scroll event for this widget. This
+   * is called by ScrollHandler to dispatch gecko events.
+   * Returns true if it's consumed.  Otherwise, false.
+   */
+  virtual bool DispatchScrollEvent(mozilla::WidgetGUIEvent* aEvent) = 0;
+
+  /*
    * Default dispatch of a plugin event.
    */
   virtual bool DispatchPluginEvent(const MSG& aMsg);
 
   /*
    * Returns true if a plugin has focus on this widget.  Otherwise, false.
    */
   virtual bool PluginHasFocus() const MOZ_FINAL
--- a/widget/windows/winrt/MetroWidget.cpp
+++ b/widget/windows/winrt/MetroWidget.cpp
@@ -29,16 +29,17 @@
 #ifdef MOZ_CRASHREPORTER
 #include "nsExceptionHandler.h"
 #endif
 #include "UIABridgePrivate.h"
 #include "WinMouseScrollHandler.h"
 #include "InputData.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/TouchEvents.h"
+#include "mozilla/MiscEvents.h"
 
 using namespace Microsoft::WRL;
 using namespace Microsoft::WRL::Wrappers;
 
 using namespace mozilla;
 using namespace mozilla::widget;
 using namespace mozilla::layers;
 using namespace mozilla::widget::winrt;
@@ -562,78 +563,61 @@ CloseGesture()
     do_GetService(NS_APPSTARTUP_CONTRACTID);
   if (appStartup) {
     appStartup->Quit(nsIAppStartup::eForceQuit);
   }
 }
 
 // Async event sending for mouse and keyboard input.
 
-// Simple Windows message wrapper for dispatching async events. 
-class DispatchMsg
-{
-public:
-  DispatchMsg(UINT aMsg, WPARAM aWParam, LPARAM aLParam) :
-    mMsg(aMsg),
-    mWParam(aWParam),
-    mLParam(aLParam)
-  {
-  }
-  ~DispatchMsg()
-  {
-  }
-
-  UINT mMsg;
-  WPARAM mWParam;
-  LPARAM mLParam;
-};
-
-DispatchMsg*
-MetroWidget::CreateDispatchMsg(UINT aMsg, WPARAM aWParam, LPARAM aLParam)
+// defined in nsWindowBase, called from shared module WinMouseScrollHandler.
+bool
+MetroWidget::DispatchScrollEvent(mozilla::WidgetGUIEvent* aEvent)
 {
-  switch (aMsg) {
-    case WM_SETTINGCHANGE:
-    case WM_MOUSEWHEEL:
-    case WM_MOUSEHWHEEL:
-    case WM_HSCROLL:
-    case WM_VSCROLL:
-    case MOZ_WM_HSCROLL:
-    case MOZ_WM_VSCROLL:
-    case WM_KEYDOWN:
-    case WM_KEYUP:
-    // MOZ_WM events are plugin specific, we keep them for completness
-    case MOZ_WM_MOUSEVWHEEL:
-    case MOZ_WM_MOUSEHWHEEL:
-      return new DispatchMsg(aMsg, aWParam, aLParam);
+  WidgetGUIEvent* newEvent = nullptr;
+  switch(aEvent->eventStructType) {
+    case NS_WHEEL_EVENT:
+    {
+      WidgetWheelEvent* oldEvent = aEvent->AsWheelEvent();
+      WidgetWheelEvent* wheelEvent =
+        new WidgetWheelEvent(oldEvent->mFlags.mIsTrusted, oldEvent->message, oldEvent->widget);
+      wheelEvent->AssignWheelEventData(*oldEvent, true);
+      newEvent = static_cast<WidgetGUIEvent*>(wheelEvent);
+    }
+    break;
+    case NS_CONTENT_COMMAND_EVENT:
+    {
+      WidgetContentCommandEvent* oldEvent = aEvent->AsContentCommandEvent();
+      WidgetContentCommandEvent* cmdEvent =
+        new WidgetContentCommandEvent(oldEvent->mFlags.mIsTrusted, oldEvent->message, oldEvent->widget);
+      cmdEvent->AssignContentCommandEventData(*oldEvent, true);
+      newEvent = static_cast<WidgetGUIEvent*>(cmdEvent);
+    }
+    break;
     default:
-      MOZ_CRASH("Unknown event being passed to CreateDispatchMsg.");
-      return nullptr;
+      MOZ_CRASH("unknown event in DispatchScrollEvent");
+    break;
   }
-}
-
-void
-MetroWidget::DispatchAsyncScrollEvent(DispatchMsg* aEvent)
-{
-  mMsgEventQueue.Push(aEvent);
+  mEventQueue.Push(newEvent);
   nsCOMPtr<nsIRunnable> runnable =
     NS_NewRunnableMethod(this, &MetroWidget::DeliverNextScrollEvent);
   NS_DispatchToCurrentThread(runnable);
+  return false;
 }
 
 void
 MetroWidget::DeliverNextScrollEvent()
 {
-  DispatchMsg* msg = static_cast<DispatchMsg*>(mMsgEventQueue.PopFront());
-  MOZ_ASSERT(msg);
-  MSGResult msgResult;
-  MouseScrollHandler::ProcessMessage(this, msg->mMsg, msg->mWParam, msg->mLParam, msgResult);
-  delete msg;
+  WidgetGUIEvent* event =
+    static_cast<WidgetInputEvent*>(mEventQueue.PopFront());
+  DispatchWindowEvent(event);
+  delete event;
 }
 
-// defined in nsWiondowBase, called from shared module KeyboardLayout.
+// defined in nsWindowBase, called from shared module KeyboardLayout.
 bool
 MetroWidget::DispatchKeyboardEvent(WidgetGUIEvent* aEvent)
 {
   MOZ_ASSERT(aEvent);
   WidgetKeyboardEvent* oldKeyEvent = aEvent->AsKeyboardEvent();
   WidgetKeyboardEvent* keyEvent =
     new WidgetKeyboardEvent(oldKeyEvent->mFlags.mIsTrusted,
                             oldKeyEvent->message, oldKeyEvent->widget);
@@ -707,24 +691,20 @@ MetroWidget::WindowProcedure(HWND aWnd, 
 
   // Indicates if we should hand messages to the default windows
   // procedure for processing.
   bool processDefault = true;
 
   // The result returned if we do not do default processing.
   LRESULT processResult = 0;
 
-  // We ignore return results from the scroll module and pass everything
-  // to mMetroWndProc. These fall through to winrt handlers that generate
-  // input events in MetroInput. Since we have no listeners for scroll
-  // events no processing should occur. For now processDefault must be left
-  // true since the mouse module consumes non-mouse wheel related events.
-  if (MouseScrollHandler::NeedsMessage(aMsg)) {
-    DispatchMsg* msg = CreateDispatchMsg(aMsg, aWParam, aLParam);
-    DispatchAsyncScrollEvent(msg);
+  MSGResult msgResult(&processResult);
+  MouseScrollHandler::ProcessMessage(this, aMsg, aWParam, aLParam, msgResult);
+  if (msgResult.mConsumed) {
+    return processResult;
   }
 
   switch (aMsg) {
     case WM_PAINT:
     {
       HRGN rgn = CreateRectRgn(0, 0, 0, 0);
       GetUpdateRgn(mWnd, rgn, false);
       nsIntRegion region = WinUtils::ConvertHRGNToRegion(rgn);
--- a/widget/windows/winrt/MetroWidget.h
+++ b/widget/windows/winrt/MetroWidget.h
@@ -69,16 +69,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIOBSERVER
 
   static HWND GetICoreWindowHWND() { return sICoreHwnd; }
 
   // nsWindowBase
   virtual bool DispatchWindowEvent(mozilla::WidgetGUIEvent* aEvent) MOZ_OVERRIDE;
   virtual bool DispatchKeyboardEvent(mozilla::WidgetGUIEvent* aEvent) MOZ_OVERRIDE;
+  virtual bool DispatchScrollEvent(mozilla::WidgetGUIEvent* aEvent) MOZ_OVERRIDE;
   virtual bool DispatchPluginEvent(const MSG &aMsg) MOZ_OVERRIDE { return false; }
   virtual bool IsTopLevelWidget() MOZ_OVERRIDE { return true; }
   virtual nsWindowBase* GetParentWindowBase(bool aIncludeOwner) MOZ_OVERRIDE { return nullptr; }
   // InitEvent assumes physical coordinates and is used by shared win32 code. Do
   // not hand winrt event coordinates to this routine.
   virtual void InitEvent(mozilla::WidgetGUIEvent& aEvent,
                          nsIntPoint* aPoint = nullptr) MOZ_OVERRIDE;
 
@@ -246,12 +247,12 @@ protected:
   nsTransparencyMode mTransparencyMode;
   nsIntRegion mInvalidatedRegion;
   nsCOMPtr<nsIdleService> mIdleService;
   HWND mWnd;
   static HWND sICoreHwnd;
   WNDPROC mMetroWndProc;
   bool mTempBasicLayerInUse;
   uint64_t mRootLayerTreeId;
-  nsDeque mMsgEventQueue;
+  nsDeque mEventQueue;
   nsDeque mKeyEventQueue;
   nsRefPtr<APZController> mController;
 };