Bug 672175 part.14 Move WM_MOUSE*WHEEL and WM_*SCROLL handlers into MouseScrollHandler r=jimm
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 06 Mar 2012 12:20:29 +0900
changeset 88356 26165b0572ed776f6316f6c43ffa6c3f63cc1338
parent 88355 e4dfd3a36f200c97c533065df1cda701accaf366
child 88357 24a298cde1e58096b922ad317823973c96e0574f
push id22194
push usermak77@bonardo.net
push dateWed, 07 Mar 2012 09:33:54 +0000
treeherdermozilla-central@8ef88a69f861 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs672175
milestone13.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 672175 part.14 Move WM_MOUSE*WHEEL and WM_*SCROLL handlers into MouseScrollHandler r=jimm
widget/windows/WinMouseScrollHandler.cpp
widget/windows/WinMouseScrollHandler.h
widget/windows/nsWindow.cpp
widget/windows/nsWindow.h
widget/xpwidgets/nsBaseWidget.h
--- a/widget/windows/WinMouseScrollHandler.cpp
+++ b/widget/windows/WinMouseScrollHandler.cpp
@@ -136,16 +136,35 @@ MouseScrollHandler::ProcessMessage(nsWin
         return false;
       }
       if (wParam == SPI_SETWHEELSCROLLLINES ||
           wParam == SPI_SETWHEELSCROLLCHARS) {
         sInstance->mSystemSettings.MarkDirty();
       }
       return false;
 
+    case WM_MOUSEWHEEL:
+    case WM_MOUSEHWHEEL:
+      GetInstance()->
+        ProcessNativeMouseWheelMessage(aWindow, msg, wParam, lParam);
+      // We don't need to call next wndproc for WM_MOUSEWHEEL and
+      // WM_MOUSEHWHEEL.  We should consume them always.  If the messages
+      // would be handled by our window again, it caused making infinite
+      // message loop.
+      aEatMessage = true;
+      *aRetValue = (msg != WM_MOUSEHWHEEL);
+      return true;
+
+    case WM_HSCROLL:
+    case WM_VSCROLL:
+      aEatMessage =
+        GetInstance()->ProcessNativeScrollMessage(aWindow, msg, wParam, lParam);
+      *aRetValue = 0;
+      return true;
+
     case MOZ_WM_MOUSEVWHEEL:
     case MOZ_WM_MOUSEHWHEEL:
       GetInstance()->HandleMouseWheelMessage(aWindow, msg, wParam, lParam);
       // Doesn't need to call next wndproc for internal wheel message.
       aEatMessage = true;
       return true;
 
     case MOZ_WM_HSCROLL:
@@ -300,16 +319,212 @@ MouseScrollHandler::GetScrollTargetInfo(
      aWindow, GetBoolName(result.dispatchPixelScrollEvent),
      GetBoolName(result.reversePixelScrollDirection), result.actualScrollAmount,
      result.actualScrollAction, result.pixelsPerUnit));
 
   return result;
 }
 
 void
+MouseScrollHandler::ProcessNativeMouseWheelMessage(nsWindow* aWindow,
+                                                   UINT aMessage,
+                                                   WPARAM aWParam,
+                                                   LPARAM aLParam)
+{
+  POINT point = ComputeMessagePos(aMessage, aWParam, aLParam);
+
+  PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
+    ("MouseScroll::ProcessNativeMouseWheelMessage: aWindow=%p, "
+     "aMessage=%s, wParam=0x%08X, lParam=0x%08X, point: { x=%d, y=%d }",
+     aWindow, aMessage == WM_MOUSEWHEEL ? "WM_MOUSEWHEEL" :
+              aMessage == WM_MOUSEHWHEEL ? "WM_MOUSEHWHEEL" :
+              aMessage == WM_VSCROLL ? "WM_VSCROLL" : "WM_HSCROLL",
+     aWParam, aLParam, point.x, point.y));
+  LOG_KEYSTATE();
+
+  HWND underCursorWnd = ::WindowFromPoint(point);
+  if (!underCursorWnd) {
+    PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
+      ("MouseScroll::ProcessNativeMouseWheelMessage: "
+       "No window is not found under the cursor"));
+    return;
+  }
+
+  if (Device::Elantech::IsPinchHackNeeded() &&
+      Device::Elantech::IsHelperWindow(underCursorWnd)) {
+    // The Elantech driver places a window right underneath the cursor
+    // when sending a WM_MOUSEWHEEL event to us as part of a pinch-to-zoom
+    // gesture.  We detect that here, and search for our window that would
+    // be beneath the cursor if that window wasn't there.
+    underCursorWnd = WinUtils::FindOurWindowAtPoint(point);
+    if (!underCursorWnd) {
+      PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
+        ("MouseScroll::ProcessNativeMouseWheelMessage: "
+         "Our window is not found under the Elantech helper window"));
+      return;
+    }
+  }
+
+  // Handle most cases first.  If the window under mouse cursor is our window
+  // except plugin window (MozillaWindowClass), we should handle the message
+  // on the window.
+  if (WinUtils::IsOurProcessWindow(underCursorWnd)) {
+    nsWindow* destWindow = WinUtils::GetNSWindowPtr(underCursorWnd);
+    if (!destWindow) {
+      PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
+        ("MouseScroll::ProcessNativeMouseWheelMessage: "
+         "Found window under the cursor isn't managed by nsWindow..."));
+      HWND wnd = ::GetParent(underCursorWnd);
+      for (; wnd; wnd = ::GetParent(wnd)) {
+        destWindow = WinUtils::GetNSWindowPtr(wnd);
+        if (destWindow) {
+          break;
+        }
+      }
+      if (!wnd) {
+        PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
+          ("MouseScroll::ProcessNativeMouseWheelMessage: Our window which is "
+           "managed by nsWindow is not found under the cursor"));
+        return;
+      }
+    }
+
+    MOZ_ASSERT(destWindow, "destWindow must not be NULL");
+
+    // If the found window is our plugin window, it means that the message
+    // has been handled by the plugin but not consumed.  We should handle the
+    // message on its parent window.  However, note that the DOM event may
+    // cause accessing the plugin.  Therefore, we should unlock the plugin
+    // process by using PostMessage().
+    if (destWindow->GetWindowType() == eWindowType_plugin) {
+      destWindow = destWindow->GetParentWindow(false);
+      if (!destWindow) {
+        PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
+          ("MouseScroll::ProcessNativeMouseWheelMessage: "
+           "Our window which is a parent of a plugin window is not found"));
+        return;
+      }
+    }
+    PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
+      ("MouseScroll::ProcessNativeMouseWheelMessage: Succeeded, "
+       "Posting internal message to an nsWindow (%p)...",
+       destWindow));
+    UINT internalMessage = WinUtils::GetInternalMessage(aMessage);
+    ::PostMessage(destWindow->GetWindowHandle(), internalMessage,
+                  aWParam, aLParam);
+    return;
+  }
+
+  // If the window under cursor is not in our process, it means:
+  // 1. The window may be a plugin window (GeckoPluginWindow or its descendant).
+  // 2. The window may be another application's window.
+  HWND pluginWnd = WinUtils::FindOurProcessWindow(underCursorWnd);
+  if (!pluginWnd) {
+    // If there is no plugin window in ancestors of the window under cursor,
+    // the window is for another applications (case 2).
+    // We don't need to handle this message.
+    PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
+      ("MouseScroll::ProcessNativeMouseWheelMessage: "
+       "Our window is not found under the cursor"));
+    return;
+  }
+
+  // If we're a plugin window (MozillaWindowClass) and cursor in this window,
+  // the message shouldn't go to plugin's wndproc again.  So, we should handle
+  // it on parent window.  However, note that the DOM event may cause accessing
+  // the plugin.  Therefore, we should unlock the plugin process by using
+  // PostMessage().
+  if (aWindow->GetWindowType() == eWindowType_plugin &&
+      aWindow->GetWindowHandle() == pluginWnd) {
+    nsWindow* destWindow = aWindow->GetParentWindow(false);
+    if (!destWindow) {
+      PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
+        ("MouseScroll::ProcessNativeMouseWheelMessage: Our normal window which "
+         "is a parent of this plugin window is not found"));
+      return;
+    }
+    PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
+      ("MouseScroll::ProcessNativeMouseWheelMessage: Succeeded, "
+       "Posting internal message to an nsWindow (%p) which is parent of this "
+       "plugin window...",
+       destWindow));
+    UINT internalMessage = WinUtils::GetInternalMessage(aMessage);
+    ::PostMessage(destWindow->GetWindowHandle(), internalMessage,
+                  aWParam, aLParam);
+    return;
+  }
+
+  // If the window is a part of plugin, we should post the message to it.
+  PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
+    ("MouseScroll::ProcessNativeMouseWheelMessage: Succeeded, "
+     "Redirecting the message to a window which is a plugin child window"));
+  ::PostMessage(underCursorWnd, aMessage, aWParam, aLParam);
+}
+
+bool
+MouseScrollHandler::ProcessNativeScrollMessage(nsWindow* aWindow,
+                                               UINT aMessage,
+                                               WPARAM aWParam,
+                                               LPARAM aLParam)
+{
+  if (aLParam || mUserPrefs.IsScrollMessageHandledAsWheelMessage()) {
+    // Scroll message generated by Thinkpad Trackpoint Driver or similar
+    // Treat as a mousewheel message and scroll appropriately
+    ProcessNativeMouseWheelMessage(aWindow, aMessage, aWParam, aLParam);
+    // Always consume the scroll message if we try to emulate mouse wheel
+    // action.
+    return true;
+  }
+
+  PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
+    ("MouseScroll::ProcessNativeScrollMessage: aWindow=%p, "
+     "aMessage=%s, wParam=0x%08X, lParam=0x%08X",
+     aWindow, aMessage == WM_VSCROLL ? "WM_VSCROLL" : "WM_HSCROLL",
+     aWParam, aLParam));
+
+  // Scroll message generated by external application
+  nsContentCommandEvent commandEvent(true, NS_CONTENT_COMMAND_SCROLL, aWindow);
+
+  commandEvent.mScroll.mIsHorizontal = (aMessage == WM_HSCROLL);
+
+  switch (LOWORD(aWParam)) {
+    case SB_LINEUP:   // SB_LINELEFT
+      commandEvent.mScroll.mUnit = nsContentCommandEvent::eCmdScrollUnit_Line;
+      commandEvent.mScroll.mAmount = -1;
+      break;
+    case SB_LINEDOWN: // SB_LINERIGHT
+      commandEvent.mScroll.mUnit = nsContentCommandEvent::eCmdScrollUnit_Line;
+      commandEvent.mScroll.mAmount = 1;
+      break;
+    case SB_PAGEUP:   // SB_PAGELEFT
+      commandEvent.mScroll.mUnit = nsContentCommandEvent::eCmdScrollUnit_Page;
+      commandEvent.mScroll.mAmount = -1;
+      break;
+    case SB_PAGEDOWN: // SB_PAGERIGHT
+      commandEvent.mScroll.mUnit = nsContentCommandEvent::eCmdScrollUnit_Page;
+      commandEvent.mScroll.mAmount = 1;
+      break;
+    case SB_TOP:      // SB_LEFT
+      commandEvent.mScroll.mUnit = nsContentCommandEvent::eCmdScrollUnit_Whole;
+      commandEvent.mScroll.mAmount = -1;
+      break;
+    case SB_BOTTOM:   // SB_RIGHT
+      commandEvent.mScroll.mUnit = nsContentCommandEvent::eCmdScrollUnit_Whole;
+      commandEvent.mScroll.mAmount = 1;
+      break;
+    default:
+      return false;
+  }
+  // XXX If this is a plugin window, we should dispatch the event from
+  //     parent window.
+  DispatchEvent(aWindow, commandEvent);
+  return true;
+}
+
+void
 MouseScrollHandler::HandleMouseWheelMessage(nsWindow* aWindow,
                                             UINT aMessage,
                                             WPARAM aWParam,
                                             LPARAM aLParam)
 {
   NS_ABORT_IF_FALSE(
     (aMessage == MOZ_WM_MOUSEVWHEEL || aMessage == MOZ_WM_MOUSEHWHEEL),
     "HandleMouseWheelMessage must be called with "
--- a/widget/windows/WinMouseScrollHandler.h
+++ b/widget/windows/WinMouseScrollHandler.h
@@ -30,31 +30,16 @@ public:
 
   static bool ProcessMessage(nsWindow* aWindow,
                              UINT msg,
                              WPARAM wParam,
                              LPARAM lParam,
                              LRESULT *aRetValue,
                              bool &aEatMessage);
 
-  /**
-   * ComputeMessagePos() computes the cursor position when the message was
-   * added to the queue.
-   *
-   * @param aMessage    Handling message.
-   * @param aWParam     Handling message's wParam.
-   * @param aLParam     Handling message's lParam.
-   * @return            Mouse cursor position when the message is added to
-   *                    the queue or current cursor position if the result of
-   *                    ::GetMessagePos() is broken.
-   */
-  POINT ComputeMessagePos(UINT aMessage,
-                          WPARAM aWParam,
-                          LPARAM aLParam);
-
 private:
   MouseScrollHandler();
   ~MouseScrollHandler();
 
   static MouseScrollHandler* sInstance;
 
   /**
    * DispatchEvent() dispatches aEvent on aWindow.
@@ -68,16 +53,52 @@ private:
    * Note that some devices need some hack for the modifier key state.
    * This method does it automatically.
    *
    * @param aMessage    Handling message.
    */
   static nsModifierKeyState GetModifierKeyState(UINT aMessage);
 
   /**
+   * ProcessNativeMouseWheelMessage() processes WM_MOUSEWHEEL and
+   * WM_MOUSEHWHEEL.  Additionally, processes WM_VSCROLL and WM_HSCROLL if they
+   * should be processed as mouse wheel message.
+   * This method posts MOZ_WM_MOUSEVWHEEL, MOZ_WM_MOUSEHWHEEL,
+   * MOZ_WM_VSCROLL or MOZ_WM_HSCROLL if we need to dispatch mouse scroll
+   * events.  That avoids deadlock with plugin process.
+   *
+   * @param aWindow     A window which receives the message.
+   * @param aMessage    WM_MOUSEWHEEL, WM_MOUSEHWHEEL, WM_VSCROLL or
+   *                    WM_HSCROLL.
+   * @param aWParam     The wParam value of the message.
+   * @param aLParam     The lParam value of the message.
+   */
+  void ProcessNativeMouseWheelMessage(nsWindow* aWindow,
+                                      UINT aMessage,
+                                      WPARAM aWParam,
+                                      LPARAM aLParam);
+
+  /**
+   * ProcessNativeScrollMessage() processes WM_VSCROLL and WM_HSCROLL.
+   * This method just call ProcessMouseWheelMessage() if the message should be
+   * processed as mouse wheel message.  Otherwise, dispatches a content
+   * command event.
+   *
+   * @param aWindow     A window which receives the message.
+   * @param aMessage    WM_VSCROLL or WM_HSCROLL.
+   * @param aWParam     The wParam value of the message.
+   * @param aLParam     The lParam value of the message.
+   * @return            TRUE if the message is processed.  Otherwise, FALSE.
+   */
+  bool ProcessNativeScrollMessage(nsWindow* aWindow,
+                                  UINT aMessage,
+                                  WPARAM aWParam,
+                                  LPARAM aLParam);
+
+  /**
    * HandleMouseWheelMessage() processes MOZ_WM_MOUSEVWHEEL and
    * MOZ_WM_MOUSEHWHEEL which are posted when one of our windows received
    * WM_MOUSEWHEEL or WM_MOUSEHWHEEL for avoiding deadlock with OOPP.
    *
    * @param aWindow     A window which receives the wheel message.
    * @param aMessage    MOZ_WM_MOUSEWHEEL or MOZ_WM_MOUSEHWHEEL.
    * @param aWParam     The wParam value of the original message.
    * @param aLParam     The lParam value of the original message.
@@ -98,16 +119,31 @@ private:
    * @param aWParam     The wParam value of the original message.
    * @param aLParam     The lParam value of the original message.
    */
   void HandleScrollMessageAsMouseWheelMessage(nsWindow* aWindow,
                                               UINT aMessage,
                                               WPARAM aWParam,
                                               LPARAM aLParam);
 
+  /**
+   * ComputeMessagePos() computes the cursor position when the message was
+   * added to the queue.
+   *
+   * @param aMessage    Handling message.
+   * @param aWParam     Handling message's wParam.
+   * @param aLParam     Handling message's lParam.
+   * @return            Mouse cursor position when the message is added to
+   *                    the queue or current cursor position if the result of
+   *                    ::GetMessagePos() is broken.
+   */
+  POINT ComputeMessagePos(UINT aMessage,
+                          WPARAM aWParam,
+                          LPARAM aLParam);
+
   class EventInfo;
   /**
    * GetScrollTargetInfo() returns scroll target information which is
    * computed from the result of NS_QUERY_SCROLL_TARGET_INFO event.
    *
    * @param aWindow           An nsWindow which is handling the event.
    * @param aEventInfo        The EventInfo which is being handled.
    * @param aModifierKeyState The modifier key state.
@@ -274,17 +310,16 @@ private:
   private:
     bool mInitialized;
     PRInt32 mScrollLines;
     PRInt32 mScrollChars;
   };
 
   SystemSettings mSystemSettings;
 
-public:
   class UserPrefs {
   public:
     UserPrefs();
     ~UserPrefs();
 
     void MarkDirty();
 
     bool IsPixelScrollingEnabled()
@@ -308,22 +343,16 @@ public:
       return 0;
     }
 
     bool mInitialized;
     bool mPixelScrollingEnabled;
     bool mScrollMessageHandledAsWheelMessage;
   };
 
-  UserPrefs& GetUserPrefs()
-  {
-    return mUserPrefs;
-  }
-
-private:
   UserPrefs mUserPrefs;
 
 public:
 
   class Device {
   public:
     class Elantech {
     public:
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -5051,22 +5051,16 @@ bool nsWindow::ProcessMessage(UINT msg, 
           *aRetValue = 1;
           result = true;
           break;
       }
       // default = false - tell the driver that the event was not handled
     }
     break;
 
-    case WM_HSCROLL:
-    case WM_VSCROLL:
-      *aRetValue = 0;
-      result = OnScroll(msg, wParam, lParam);
-      break;
-
     // The WM_ACTIVATE event is fired when a window is raised or lowered,
     // and the loword of wParam specifies which. But we don't want to tell
     // the focus system about this until the WM_SETFOCUS or WM_KILLFOCUS
     // events are fired. Instead, set either the sJustGotActivate or
     // gJustGotDeativate flags and fire the NS_ACTIVATE or NS_DEACTIVATE
     // events once the focus events arrive.
     case WM_ACTIVATE:
       if (mEventCallback) {
@@ -5201,24 +5195,16 @@ bool nsWindow::ProcessMessage(UINT msg, 
         DisplaySystemMenu(mWnd, mSizeMode, mIsRTL,
                           MOZ_SYSCONTEXT_X_POS,
                           MOZ_SYSCONTEXT_Y_POS);
         result = true;
       }
     }
     break;
 
-  case WM_MOUSEWHEEL:
-  case WM_MOUSEHWHEEL:
-    OnMouseWheel(msg, wParam, lParam, aRetValue);
-    // We don't need to call next wndproc WM_MOUSEWHEEL and WM_MOUSEHWHEEL.
-    // We should consume them always.  If the messages would be handled by
-    // our window again, it causes making infinite message loop.
-    return true;
-
   case WM_DWMCOMPOSITIONCHANGED:
     // First, update the compositor state to latest one. All other methods
     // should use same state as here for consistency painting.
     nsUXThemeData::CheckForCompositor(true);
 
     UpdateNonClientMargins();
     RemovePropW(mWnd, kManageWindowInfoProperty);
     BroadcastMsg(mWnd, WM_DWMCOMPOSITIONCHANGED);
@@ -7025,168 +7011,16 @@ bool nsWindow::OnResize(nsIntRect &aWind
   return false;
 }
 
 bool nsWindow::OnHotKey(WPARAM wParam, LPARAM lParam)
 {
   return true;
 }
 
-/**
- * OnMouseWheel() is called when ProcessMessage() handles WM_MOUSEWHEEL,
- * WM_MOUSEHWHEEL and also OnScroll() tries to emulate mouse wheel action for
- * WM_VSCROLL or WM_HSCROLL.
- * So, aMsg may be WM_MOUSEWHEEL, WM_MOUSEHWHEEL, WM_VSCROLL or WM_HSCROLL.
- */
-void
-nsWindow::OnMouseWheel(UINT aMsg, WPARAM aWParam, LPARAM aLParam,
-                       LRESULT *aRetValue)
-{
-  *aRetValue = (aMsg != WM_MOUSEHWHEEL) ? TRUE : FALSE;
-
-  MouseScrollHandler* handler = MouseScrollHandler::GetInstance();
-  POINT point = handler->ComputeMessagePos(aMsg, aWParam, aLParam);
-  HWND underCursorWnd = ::WindowFromPoint(point);
-  if (!underCursorWnd) {
-    return;
-  }
-
-  if (MouseScrollHandler::Device::Elantech::IsPinchHackNeeded() &&
-      MouseScrollHandler::Device::Elantech::IsHelperWindow(underCursorWnd)) {
-    // The Elantech driver places a window right underneath the cursor
-    // when sending a WM_MOUSEWHEEL event to us as part of a pinch-to-zoom
-    // gesture.  We detect that here, and search for our window that would
-    // be beneath the cursor if that window wasn't there.
-    underCursorWnd = WinUtils::FindOurWindowAtPoint(point);
-    if (!underCursorWnd) {
-      return;
-    }
-  }
-
-  // Handle most cases first.  If the window under mouse cursor is our window
-  // except plugin window (MozillaWindowClass), we should handle the message
-  // on the window.
-  if (WinUtils::IsOurProcessWindow(underCursorWnd)) {
-    nsWindow* destWindow = WinUtils::GetNSWindowPtr(underCursorWnd);
-    if (!destWindow) {
-      NS_WARNING("We're not sure what cause this is.");
-      HWND wnd = ::GetParent(underCursorWnd);
-      for (; wnd; wnd = ::GetParent(wnd)) {
-        destWindow = WinUtils::GetNSWindowPtr(wnd);
-        if (destWindow) {
-          break;
-        }
-      }
-      if (!wnd) {
-        return;
-      }
-    }
-
-    NS_ASSERTION(destWindow, "destWindow must not be NULL");
-    // If the found window is our plugin window, it means that the message
-    // has been handled by the plugin but not consumed.  We should handle the
-    // message on its parent window.  However, note that the DOM event may
-    // cause accessing the plugin.  Therefore, we should unlock the plugin
-    // process by using PostMessage().
-    if (destWindow->mWindowType == eWindowType_plugin) {
-      destWindow = destWindow->GetParentWindow(false);
-      NS_ENSURE_TRUE(destWindow, );
-    }
-    UINT internalMessage = WinUtils::GetInternalMessage(aMsg);
-    ::PostMessage(destWindow->mWnd, internalMessage, aWParam, aLParam);
-    return;
-  }
-
-  // If the window under cursor is not in our process, it means:
-  // 1. The window may be a plugin window (GeckoPluginWindow or its descendant).
-  // 2. The window may be another application's window.
-  HWND pluginWnd = WinUtils::FindOurProcessWindow(underCursorWnd);
-  if (!pluginWnd) {
-    // If there is no plugin window in ancestors of the window under cursor,
-    // the window is for another applications (case 2).
-    // We don't need to handle this message.
-    return;
-  }
-
-  // If we're a plugin window (MozillaWindowClass) and cursor in this window,
-  // the message shouldn't go to plugin's wndproc again.  So, we should handle
-  // it on parent window.  However, note that the DOM event may cause accessing
-  // the plugin.  Therefore, we should unlock the plugin process by using
-  // PostMessage().
-  if (mWindowType == eWindowType_plugin && pluginWnd == mWnd) {
-    nsWindow* destWindow = GetParentWindow(false);
-    NS_ENSURE_TRUE(destWindow, );
-    UINT internalMessage = WinUtils::GetInternalMessage(aMsg);
-    ::PostMessage(destWindow->mWnd, internalMessage, aWParam, aLParam);
-    return;
-  }
-
-  // If the window is a part of plugin, we should post the message to it.
-  ::PostMessage(underCursorWnd, aMsg, aWParam, aLParam);
-}
-
-/**
- * OnScroll() is called when ProcessMessage() handles WM_VSCROLL or WM_HSCROLL.
- * aMsg may be WM_VSCROLL or WM_HSCROLL.
- */
-bool
-nsWindow::OnScroll(UINT aMsg, WPARAM aWParam, LPARAM aLParam)
-{
-  if (aLParam ||
-      MouseScrollHandler::GetInstance()->
-        GetUserPrefs().IsScrollMessageHandledAsWheelMessage()) {
-    // Scroll message generated by Thinkpad Trackpoint Driver or similar
-    // Treat as a mousewheel message and scroll appropriately
-    LRESULT retVal;
-    OnMouseWheel(aMsg, aWParam, aLParam, &retVal);
-    // Always consume the scroll message if we try to emulate mouse wheel
-    // action.
-    return true;
-  }
-
-  // Scroll message generated by external application
-  nsContentCommandEvent command(true, NS_CONTENT_COMMAND_SCROLL, this);
-
-  command.mScroll.mIsHorizontal = (aMsg == WM_HSCROLL);
-
-  switch (LOWORD(aWParam))
-  {
-    case SB_LINEUP:   // SB_LINELEFT
-      command.mScroll.mUnit = nsContentCommandEvent::eCmdScrollUnit_Line;
-      command.mScroll.mAmount = -1;
-      break;
-    case SB_LINEDOWN: // SB_LINERIGHT
-      command.mScroll.mUnit = nsContentCommandEvent::eCmdScrollUnit_Line;
-      command.mScroll.mAmount = 1;
-      break;
-    case SB_PAGEUP:   // SB_PAGELEFT
-      command.mScroll.mUnit = nsContentCommandEvent::eCmdScrollUnit_Page;
-      command.mScroll.mAmount = -1;
-      break;
-    case SB_PAGEDOWN: // SB_PAGERIGHT
-      command.mScroll.mUnit = nsContentCommandEvent::eCmdScrollUnit_Page;
-      command.mScroll.mAmount = 1;
-      break;
-    case SB_TOP:      // SB_LEFT
-      command.mScroll.mUnit = nsContentCommandEvent::eCmdScrollUnit_Whole;
-      command.mScroll.mAmount = -1;
-      break;
-    case SB_BOTTOM:   // SB_RIGHT
-      command.mScroll.mUnit = nsContentCommandEvent::eCmdScrollUnit_Whole;
-      command.mScroll.mAmount = 1;
-      break;
-    default:
-      return false;
-  }
-  // XXX If this is a plugin window, we should dispatch the event from
-  //     parent window.
-  DispatchWindowEvent(&command);
-  return true;
-}
-
 // Can be overriden. Controls auto-erase of background.
 bool nsWindow::AutoErase(HDC dc)
 {
   return false;
 }
 
 void
 nsWindow::AllowD3D9Callback(nsWindow *aWindow)
--- a/widget/windows/nsWindow.h
+++ b/widget/windows/nsWindow.h
@@ -391,25 +391,22 @@ protected:
   LRESULT                 OnKeyUp(const MSG &aMsg,
                                   nsModifierKeyState &aModKeyState,
                                   bool *aEventDispatched);
   LRESULT                 OnCharRaw(UINT charCode, UINT aScanCode,
                                     nsModifierKeyState &aModKeyState,
                                     PRUint32 aFlags = 0,
                                     const MSG *aMsg = nsnull,
                                     bool *aEventDispatched = nsnull);
-  bool                    OnScroll(UINT aMsg, WPARAM aWParam, LPARAM aLParam);
   bool                    OnGesture(WPARAM wParam, LPARAM lParam);
   bool                    OnTouch(WPARAM wParam, LPARAM lParam);
   bool                    OnHotKey(WPARAM wParam, LPARAM lParam);
   BOOL                    OnInputLangChange(HKL aHKL);
   bool                    OnPaint(HDC aDC, PRUint32 aNestingLevel);
   void                    OnWindowPosChanged(WINDOWPOS *wp, bool& aResult);
-  void                    OnMouseWheel(UINT aMsg, WPARAM aWParam,
-                                       LPARAM aLParam, LRESULT *aRetValue);
   void                    OnWindowPosChanging(LPWINDOWPOS& info);
   void                    OnSysColorChanged();
 
   /**
    * Function that registers when the user has been active (used for detecting
    * when the user is idle).
    */
   void                    UserActivity();
--- a/widget/xpwidgets/nsBaseWidget.h
+++ b/widget/xpwidgets/nsBaseWidget.h
@@ -232,16 +232,18 @@ public:
 
   bool HasDestroyStarted() const 
   {
     return mOnDestroyCalled;
   }
 
   bool                    Destroyed() { return mOnDestroyCalled; }
 
+  nsWindowType            GetWindowType() { return mWindowType; }
+
 protected:
 
   virtual void            ResolveIconName(const nsAString &aIconName,
                                           const nsAString &aIconSuffix,
                                           nsILocalFile **aResult);
   virtual void            OnDestroy();
   virtual void            BaseCreate(nsIWidget *aParent,
                                      const nsIntRect &aRect,