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 152099 c74facfb70ab24462bc0a55c2ff7017e03fa01fc
parent 152098 08f5ba64a98854444bb9aabd1b3952149130861b
child 152100 d439b0f78fe99111a02a59b50861c9940bce2e19
push idunknown
push userunknown
push dateunknown
reviewerstabraldes
bugs930177
milestone27.0a1
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;
 };