Bug 719320 part.12 Replace legacy mouse scroll event dispatchers with D3E wheel event dispatcher on Windows r=smaug+jimm
authorMasayuki Nakano <masayuki@d-toybox.com>
Sun, 12 Aug 2012 10:42:37 +0900
changeset 107542 4dd145ea74d2f82ed7608555b5381fecd467acbe
parent 107541 738efdde4d4ce9db56e60d7ed1b867c63691b7f7
child 107543 e9a626db6c6916ec64c2192f5aa865189a0ff5e2
push id1490
push userakeybl@mozilla.com
push dateMon, 08 Oct 2012 18:29:50 +0000
treeherdermozilla-beta@f335e7dacdc1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs719320
milestone17.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 719320 part.12 Replace legacy mouse scroll event dispatchers with D3E wheel event dispatcher on Windows r=smaug+jimm
widget/nsGUIEvent.h
widget/nsGUIEventIPC.h
widget/tests/window_mouse_scroll_win.html
widget/windows/KeyboardLayout.cpp
widget/windows/WinMouseScrollHandler.cpp
widget/windows/WinMouseScrollHandler.h
widget/windows/nsWinGesture.cpp
widget/windows/nsWinGesture.h
widget/windows/nsWindow.cpp
--- a/widget/nsGUIEvent.h
+++ b/widget/nsGUIEvent.h
@@ -388,22 +388,16 @@ class nsHashKey;
 // Query for the selection in the form of a nsITransferable.
 #define NS_QUERY_SELECTION_AS_TRANSFERABLE (NS_QUERY_CONTENT_EVENT_START + 7)
 // Query for character at a point.  This returns the character offset and its
 // rect.  The point is specified by nsEvent::refPoint.
 #define NS_QUERY_CHARACTER_AT_POINT     (NS_QUERY_CONTENT_EVENT_START + 8)
 // Query if the DOM element under nsEvent::refPoint belongs to our widget
 // or not.
 #define NS_QUERY_DOM_WIDGET_HITTEST     (NS_QUERY_CONTENT_EVENT_START + 9)
-// Query for some information about mouse wheel event's target
-// XXX This is used only for supporting high resolution mouse scroll on Windows
-//     and it's going to be reimplemented with another approach.  At that time,
-//     this even is going to be removed. Therefore,  DON'T use this event for
-//     other purpose.
-#define NS_QUERY_SCROLL_TARGET_INFO     (NS_QUERY_CONTENT_EVENT_START + 99)
 
 // Video events
 #define NS_MEDIA_EVENT_START            3300
 #define NS_LOADSTART           (NS_MEDIA_EVENT_START)
 #define NS_PROGRESS            (NS_MEDIA_EVENT_START+1)
 #define NS_SUSPEND             (NS_MEDIA_EVENT_START+2)
 #define NS_EMPTIED             (NS_MEDIA_EVENT_START+3)
 #define NS_STALLED             (NS_MEDIA_EVENT_START+4)
@@ -1351,33 +1345,19 @@ public:
                             // a fallback for pixel scroll events.
                             // These scroll events are used by things that can't
                             // be scrolled pixel-wise, like trees. You should
                             // ignore them when processing pixel scroll events
                             // to avoid double-processing the same scroll gesture.
                             // When kHasPixels is set, the event is guaranteed to
                             // be followed up by an event that contains pixel
                             // scrolling information.
-    kNoLines =      1 << 4, // Marks pixel scroll events that will not be
-                            // followed by a line scroll events. EventStateManager
-                            // will compute the appropriate height/width based on
-                            // view lineHeight and generate line scroll events
-                            // as needed.
-    kNoDefer =      1 << 5, // For scrollable views, indicates scroll should not
-                            // occur asynchronously.
-    kIsMomentum =   1 << 6, // Marks scroll events that aren't controlled by the
+    kIsMomentum =   1 << 6  // Marks scroll events that aren't controlled by the
                             // user but fire automatically as the result of a
                             // "momentum" scroll.
-    kAllowSmoothScroll = 1 << 7, // Allow smooth scroll for the pixel scroll
-                                 // event.
-    kFromLines =    1 << 8  // For a pixels scroll event, indicates that it
-                            // originated from a lines scroll event.
-                            // (Only used on windows which generates "faked"
-                            // pixel scroll events even for simple mouse wheel
-                            // scroll)
 };
 
   nsMouseScrollEvent(bool isTrusted, PRUint32 msg, nsIWidget *w)
     : nsMouseEvent_base(isTrusted, msg, w, NS_MOUSE_SCROLL_EVENT),
       scrollFlags(0), delta(0), scrollOverflow(0)
   {
   }
 
@@ -1559,23 +1539,16 @@ public:
 
   void InitForQueryDOMWidgetHittest(nsIntPoint& aPoint)
   {
     NS_ASSERTION(message == NS_QUERY_DOM_WIDGET_HITTEST,
                  "wrong initializer is called");
     refPoint = aPoint;
   }
 
-  void InitForQueryScrollTargetInfo(nsMouseScrollEvent* aEvent)
-  {
-    NS_ASSERTION(message == NS_QUERY_SCROLL_TARGET_INFO,
-                 "wrong initializer is called");
-    mInput.mMouseScrollEvent = aEvent;
-  }
-
   PRUint32 GetSelectionStart(void) const
   {
     NS_ASSERTION(message == NS_QUERY_SELECTED_TEXT,
                  "not querying selection");
     return mReply.mOffset + (mReply.mReversed ? mReply.mString.Length() : 0);
   }
 
   PRUint32 GetSelectionEnd(void) const
@@ -1585,43 +1558,29 @@ public:
     return mReply.mOffset + (mReply.mReversed ? 0 : mReply.mString.Length());
   }
 
   bool mSucceeded;
   bool mWasAsync;
   struct {
     PRUint32 mOffset;
     PRUint32 mLength;
-    // used by NS_QUERY_SCROLL_TARGET_INFO
-    nsMouseScrollEvent* mMouseScrollEvent;
   } mInput;
   struct {
     void* mContentsRoot;
     PRUint32 mOffset;
     nsString mString;
     nsIntRect mRect; // Finally, the coordinates is system coordinates.
     // The return widget has the caret. This is set at all query events.
     nsIWidget* mFocusedWidget;
     bool mReversed; // true if selection is reversed (end < start)
     bool mHasSelection; // true if the selection exists
     bool mWidgetIsHit; // true if DOM element under mouse belongs to widget
     // used by NS_QUERY_SELECTION_AS_TRANSFERABLE
     nsCOMPtr<nsITransferable> mTransferable;
-    // used by NS_QUERY_SCROLL_TARGET_INFO
-    PRInt32 mLineHeight;
-    PRInt32 mPageWidth;
-    PRInt32 mPageHeight;
-    // used by NS_QUERY_SCROLL_TARGET_INFO
-    // the mouse wheel scrolling amount may be overridden by prefs or
-    // overriding system scrolling speed mechanism.
-    // If mMouseScrollEvent is a line scroll event, the unit of this value is
-    // line.  If mMouseScrollEvent is a page scroll event, the unit of this
-    // value is page.
-    PRInt32 mComputedScrollAmount;
-    PRInt32 mComputedScrollAction;
   } mReply;
 
   enum {
     NOT_FOUND = PR_UINT32_MAX
   };
 
   // values of mComputedScrollAction
   enum {
@@ -2012,18 +1971,17 @@ enum nsDragDropEventStatus {
   (event)->flags &= ~NS_EVENT_FLAG_DISPATCHING; \
   (event)->flags |= NS_EVENT_DISPATCHED;
 
 // Be aware the query content events and the selection events are a part of IME
 // processing.  So, you shouldn't use NS_IS_IME_EVENT macro directly in most
 // cases, you should use NS_IS_IME_RELATED_EVENT instead.
 #define NS_IS_IME_RELATED_EVENT(evnt) \
   (NS_IS_IME_EVENT(evnt) || \
-   (NS_IS_QUERY_CONTENT_EVENT(evnt) && \
-    evnt->message != NS_QUERY_SCROLL_TARGET_INFO) || \
+   NS_IS_QUERY_CONTENT_EVENT(evnt) || \
    NS_IS_SELECTION_EVENT(evnt))
 
 /*
  * Virtual key bindings for keyboard events.
  * These come from nsIDOMKeyEvent.h, which is generated from MouseKeyEvent.idl.
  * Really, it would be better if we phased out the NS_VK symbols altogether
  * in favor of the DOM ones, but at least this way they'll be in sync.
  */
--- a/widget/nsGUIEventIPC.h
+++ b/widget/nsGUIEventIPC.h
@@ -390,49 +390,37 @@ struct ParamTraits<nsQueryContentEvent>
   typedef nsQueryContentEvent paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, static_cast<nsGUIEvent>(aParam));
     WriteParam(aMsg, aParam.mSucceeded);
     WriteParam(aMsg, aParam.mInput.mOffset);
     WriteParam(aMsg, aParam.mInput.mLength);
-    WriteParam(aMsg, *aParam.mInput.mMouseScrollEvent);
     WriteParam(aMsg, aParam.mReply.mOffset);
     WriteParam(aMsg, aParam.mReply.mString);
     WriteParam(aMsg, aParam.mReply.mRect);
     WriteParam(aMsg, aParam.mReply.mReversed);
     WriteParam(aMsg, aParam.mReply.mHasSelection);
     WriteParam(aMsg, aParam.mReply.mWidgetIsHit);
-    WriteParam(aMsg, aParam.mReply.mLineHeight);
-    WriteParam(aMsg, aParam.mReply.mPageHeight);
-    WriteParam(aMsg, aParam.mReply.mPageWidth);
-    WriteParam(aMsg, aParam.mReply.mComputedScrollAmount);
-    WriteParam(aMsg, aParam.mReply.mComputedScrollAction);
   }
 
   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   {
     aResult->mWasAsync = true;
     return ReadParam(aMsg, aIter, static_cast<nsGUIEvent*>(aResult)) &&
            ReadParam(aMsg, aIter, &aResult->mSucceeded) &&
            ReadParam(aMsg, aIter, &aResult->mInput.mOffset) &&
            ReadParam(aMsg, aIter, &aResult->mInput.mLength) &&
-           ReadParam(aMsg, aIter, aResult->mInput.mMouseScrollEvent) &&
            ReadParam(aMsg, aIter, &aResult->mReply.mOffset) &&
            ReadParam(aMsg, aIter, &aResult->mReply.mString) &&
            ReadParam(aMsg, aIter, &aResult->mReply.mRect) &&
            ReadParam(aMsg, aIter, &aResult->mReply.mReversed) &&
            ReadParam(aMsg, aIter, &aResult->mReply.mHasSelection) &&
-           ReadParam(aMsg, aIter, &aResult->mReply.mWidgetIsHit) &&
-           ReadParam(aMsg, aIter, &aResult->mReply.mLineHeight) &&
-           ReadParam(aMsg, aIter, &aResult->mReply.mPageHeight) &&
-           ReadParam(aMsg, aIter, &aResult->mReply.mPageWidth) &&
-           ReadParam(aMsg, aIter, &aResult->mReply.mComputedScrollAmount) &&
-           ReadParam(aMsg, aIter, &aResult->mReply.mComputedScrollAction);
+           ReadParam(aMsg, aIter, &aResult->mReply.mWidgetIsHit);
   }
 };
 
 template<>
 struct ParamTraits<nsSelectionEvent>
 {
   typedef nsSelectionEvent paramType;
 
--- a/widget/tests/window_mouse_scroll_win.html
+++ b/widget/tests/window_mouse_scroll_win.html
@@ -58,17 +58,16 @@ const kAltKeyDeltaMultiplierXPref   = "m
 const kAltKeyDeltaMultiplierYPref   = "mousewheel.with_alt.delta_multiplier_y";
 const kCtrlKeyDeltaMultiplierXPref  = "mousewheel.with_control.delta_multiplier_x";
 const kCtrlKeyDeltaMultiplierYPref  = "mousewheel.with_control.delta_multiplier_y";
 const kShiftKeyDeltaMultiplierXPref = "mousewheel.with_shift.delta_multiplier_x";
 const kShiftKeyDeltaMultiplierYPref = "mousewheel.with_shift.delta_multiplier_y";
 const kWinKeyDeltaMultiplierXPref   = "mousewheel.with_win.delta_multiplier_x";
 const kWinKeyDeltaMultiplierYPref   = "mousewheel.with_win.delta_multiplier_y";
 
-const kPixelEnabledPref           = "mousewheel.enable_pixel_scrolling";
 const kEmulateWheelByWMSCROLLPref = "mousewheel.emulate_at_wm_scroll";
 const kVAmountPref                = "mousewheel.windows.vertical_amount_override";
 const kHAmountPref                = "mousewheel.windows.horizontal_amount_override";
 const kTimeoutPref                = "mousewheel.windows.transaction.timeout";
 
 const kMouseLineScrollEvent  = "DOMMouseScroll";
 const kMousePixelScrollEvent = "MozMousePixelScroll";
 
@@ -117,17 +116,16 @@ function onUnload()
   SpecialPowers.clearUserPref(kCtrlKeyDeltaMultiplierXPref);
   SpecialPowers.clearUserPref(kCtrlKeyDeltaMultiplierYPref);
   SpecialPowers.clearUserPref(kShiftKeyDeltaMultiplierXPref);
   SpecialPowers.clearUserPref(kShiftKeyDeltaMultiplierYPref);
   SpecialPowers.clearUserPref(kWinKeyDeltaMultiplierXPref);
   SpecialPowers.clearUserPref(kWinKeyDeltaMultiplierYPref);
 
   SpecialPowers.clearUserPref(kSystemScrollSpeedOverridePref);
-  SpecialPowers.clearUserPref(kPixelEnabledPref);
   SpecialPowers.clearUserPref(kEmulateWheelByWMSCROLLPref);
   SpecialPowers.clearUserPref(kVAmountPref);
   SpecialPowers.clearUserPref(kHAmountPref);
   SpecialPowers.clearUserPref(kTimeoutPref);
   window.opener.wrappedJSObject.SimpleTest.finish();
 }
 
 function getWindowUtils(aWindow)
@@ -219,149 +217,85 @@ function cut(aNum)
  *
  * finish:
  *   Must be a function or null.  If this value is a function, it's called
  *   after received all expected events or timeout if no events are expected.
  */
 
 // First, get the computed line height, char width, page height and page width.
 var gPreparingSteps = [
-  { description: "Preparing gLineHeight #1",
-    message: WM_MOUSEWHEEL, delta: -60,
+  { description: "Preparing gLineHeight",
+    message: WM_MOUSEWHEEL, delta: -120,
     target: gP1, x: 10, y: 10, window: window,
     modifiers: 0,
     additionalFlags: 0,
     onLineScrollEvent: function (aEvent) {
       return true;
     },
     onPixelScrollEvent: function (aEvent) {
       gLineHeight = aEvent.detail;
       return true;
     },
     expected: {
-      axis: kVAxis, lines: 0, pixels: 1,
+      axis: kVAxis, lines: 1, pixels: 1,
     },
     init: function () {
       SpecialPowers.setIntPref(kVAmountPref, 1);
       SpecialPowers.setIntPref(kHAmountPref, 1);
     },
   },
-  { description: "Preparing gLineHeight #2",
-    message: WM_MOUSEWHEEL, delta: -60,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    onLineScrollEvent: function (aEvent) {
-      return true;
-    },
-    onPixelScrollEvent: function (aEvent) {
-      gLineHeight += aEvent.detail;
-      return true;
-    },
-    expected: {
-      axis: kVAxis, lines: 1, pixels: 1,
-    },
-  },
-  { description: "Preparing gCharWidth #1",
-    message: WM_MOUSEHWHEEL, delta: 60,
+  { description: "Preparing gCharWidth",
+    message: WM_MOUSEHWHEEL, delta: 120,
     target: gP1, x: 10, y: 10, window: window,
     modifiers: 0,
     additionalFlags: 0,
     onLineScrollEvent: function (aEvent) {
       return true;
     },
     onPixelScrollEvent: function (aEvent) {
       gCharWidth = aEvent.detail;
       return true;
     },
     expected: {
-      axis: kVAxis, lines: 0, pixels: 1,
-    },
-  },
-  { description: "Preparing gCharWidth #2",
-    message: WM_MOUSEHWHEEL, delta: 60,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    onLineScrollEvent: function (aEvent) {
-      return true;
-    },
-    onPixelScrollEvent: function (aEvent) {
-      gCharWidth += aEvent.detail;
-      return true;
-    },
-    expected: {
       axis: kVAxis, lines: 1, pixels: 1,
     },
   },
-  { description: "Preparing gPageHeight #1",
-    message: WM_MOUSEWHEEL, delta: -60,
+  { description: "Preparing gPageHeight",
+    message: WM_MOUSEWHEEL, delta: -120,
     target: gP1, x: 10, y: 10, window: window,
     modifiers: 0,
     additionalFlags: 0,
     onLineScrollEvent: function (aEvent) {
       return true;
     },
     onPixelScrollEvent: function (aEvent) {
       gPageHeight = aEvent.detail;
       return true;
     },
     expected: {
-      axis: kHAxis, lines: 0, pixels: 1,
+      axis: kHAxis, lines: 1, pixels: 1,
     },
     init: function () {
       SpecialPowers.setIntPref(kVAmountPref, 0xFFFF);
       SpecialPowers.setIntPref(kHAmountPref, 0xFFFF);
     },
   },
-  { description: "Preparing gPageHeight #2",
-    message: WM_MOUSEWHEEL, delta: -60,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    onLineScrollEvent: function (aEvent) {
-      return true;
-    },
-    onPixelScrollEvent: function (aEvent) {
-      gPageHeight += aEvent.detail;
-      return true;
-    },
-    expected: {
-      axis: kHAxis, lines: 1, pixels: 1,
-    },
-  },
-  { description: "Preparing gPageWidth #1",
-    message: WM_MOUSEHWHEEL, delta: 60,
+  { description: "Preparing gPageWidth",
+    message: WM_MOUSEHWHEEL, delta: 120,
     target: gP1, x: 10, y: 10, window: window,
     modifiers: 0,
     additionalFlags: 0,
     onLineScrollEvent: function (aEvent) {
       return true;
     },
     onPixelScrollEvent: function (aEvent) {
       gPageWidth = aEvent.detail;
       return true;
     },
     expected: {
-      axis: kHAxis, lines: 0, pixels: 1,
-    },
-  },
-  { description: "Preparing gPageWidth",
-    message: WM_MOUSEHWHEEL, delta: 60,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    onLineScrollEvent: function (aEvent) {
-      return true;
-    },
-    onPixelScrollEvent: function (aEvent) {
-      gPageWidth += aEvent.detail;
-      return true;
-    },
-    expected: {
       axis: kHAxis, lines: 1, pixels: 1,
     },
     finish: function () {
       ok(gLineHeight > 0, "gLineHeight isn't positive got " + gLineHeight);
       ok(gCharWidth > 0, "gCharWidth isn't positive got " + gCharWidth);
       ok(gPageHeight > 0, "gPageHeight isn't positive got " + gPageHeight);
       ok(gPageWidth > 0, "gPageWidth isn't positive got " + gPageWidth);
 
@@ -416,36 +350,34 @@ var gBasicTests = [
     target: gP1, x: 10, y: 10, window: window,
     modifiers: 0,
     additionalFlags: 0,
     expected: {
       axis: kHAxis, lines: -3, pixels: function () { return gCharWidth * -3; },
     },
   },
 
-  // When pixel scroll is enabled (default), pixel scroll event should be fired
-  // always but line scroll event should be fired only when accumulated
-  // delta value is over a line.
+  // Pixel scroll event should be fired always but line scroll event should be
+  // fired only when accumulated delta value is over a line.
   { description: "WM_MOUSEWHEEL, -20, 0.5 lines",
     message: WM_MOUSEWHEEL, delta: -20,
     target: gP1, x: 10, y: 10, window: window,
     modifiers: 0,
     additionalFlags: 0,
     expected: {
       axis: kVAxis, lines: 0, pixels: function () { return gLineHeight / 2; },
     },
   },
   { description: "WM_MOUSEWHEEL, -20, 0.5 lines (pending: 0.5 lines)",
     message: WM_MOUSEWHEEL, delta: -20,
     target: gP1, x: 10, y: 10, window: window,
     modifiers: 0,
     additionalFlags: 0,
     expected: {
-      axis: kVAxis, lines: 1,
-      pixels: function () { return ((gLineHeight / 2) + (gLineHeight % 2)); },
+      axis: kVAxis, lines: 1, pixels: function () { return gLineHeight / 2; },
     },
   },
   { description: "WM_MOUSEWHEEL, -20, 0.5 lines",
     message: WM_MOUSEWHEEL, delta: -20,
     target: gP1, x: 10, y: 10, window: window,
     modifiers: 0,
     additionalFlags: 0,
     expected: {
@@ -463,18 +395,17 @@ var gBasicTests = [
     },
   },
   { description: "WM_MOUSEWHEEL, 20, -0.5 lines (pending: -0.5 lines)",
     message: WM_MOUSEWHEEL, delta: 20,
     target: gP1, x: 10, y: 10, window: window,
     modifiers: 0,
     additionalFlags: 0,
     expected: {
-      axis: kVAxis, lines: -1,
-      pixels: function () { return -((gLineHeight / 2) + (gLineHeight % 2)); },
+      axis: kVAxis, lines: -1, pixels: function () { return -gLineHeight / 2; },
     },
   },
   { description: "WM_MOUSEWHEEL, 20, -0.5 lines",
     message: WM_MOUSEWHEEL, delta: 20,
     target: gP1, x: 10, y: 10, window: window,
     modifiers: 0,
     additionalFlags: 0,
     expected: {
@@ -492,18 +423,17 @@ var gBasicTests = [
     },
   },
   { description: "WM_MOUSEHWHEEL, 20, 0.5 chars (pending: 0.5 chars)",
     message: WM_MOUSEHWHEEL, delta: 20,
     target: gP1, x: 10, y: 10, window: window,
     modifiers: 0,
     additionalFlags: 0,
     expected: {
-      axis: kHAxis, lines: 1,
-      pixels: function () { return ((gCharWidth / 2) + (gCharWidth % 2)); },
+      axis: kHAxis, lines: 1, pixels: function () { return gCharWidth / 2; },
     },
   },
   { description: "WM_MOUSEHWHEEL, 20, 0.5 chars",
     message: WM_MOUSEHWHEEL, delta: 20,
     target: gP1, x: 10, y: 10, window: window,
     modifiers: 0,
     additionalFlags: 0,
     expected: {
@@ -521,150 +451,29 @@ var gBasicTests = [
     },
   },
   { description: "WM_MOUSEHWHEEL, -20, -0.5 chars (pending: -0.5 chars)",
     message: WM_MOUSEHWHEEL, delta: -20,
     target: gP1, x: 10, y: 10, window: window,
     modifiers: 0,
     additionalFlags: 0,
     expected: {
-      axis: kHAxis, lines: -1,
-      pixels: function () { return -((gCharWidth / 2) + (gCharWidth % 2)); },
+      axis: kHAxis, lines: -1, pixels: function () { return -gCharWidth / 2; },
     },
   },
   { description: "WM_MOUSEHWHEEL, -20, -0.5 chars",
     message: WM_MOUSEHWHEEL, delta: -20,
     target: gP1, x: 10, y: 10, window: window,
     modifiers: 0,
     additionalFlags: 0,
     expected: {
       axis: kHAxis, lines: 0, pixels: function () { return gCharWidth / -2; },
     },
   },
 
-  // When pixel scroll is disabled, pixel scroll event shouldn't be fired
-  // without line scroll event.
-  { description: "WM_MOUSEWHEEL, -20, 0.5 lines, pixel scrolling is disabled",
-    message: WM_MOUSEWHEEL, delta: -20,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kVAxis, lines: 0, pixels: 0,
-    },
-    init: function () {
-      SpecialPowers.setBoolPref(kPixelEnabledPref, false);
-    },
-  },
-  { description: "WM_MOUSEWHEEL, -20, 0.5 lines (pending: 0.5 lines), pixel scrolling is disabled",
-    message: WM_MOUSEWHEEL, delta: -20,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kVAxis, lines: 1, pixels: function () { return gLineHeight; },
-    },
-  },
-  { description: "WM_MOUSEWHEEL, -20, 0.5 lines, pixel scrolling is disabled",
-    message: WM_MOUSEWHEEL, delta: -20,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kVAxis, lines: 0, pixels: 0,
-    },
-  },
-
-  { description: "WM_MOUSEWHEEL, 20, -0.5 lines (pending: 0.5 lines), pixel scrolling is disabled",
-    message: WM_MOUSEWHEEL, delta: 20,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kVAxis, lines: 0, pixels: 0,
-    },
-  },
-  { description: "WM_MOUSEWHEEL, 20, -0.5 lines (pending: -0.5 lines), pixel scrolling is disabled",
-    message: WM_MOUSEWHEEL, delta: 20,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kVAxis, lines: -1, pixels: function () { return -gLineHeight; },
-    },
-  },
-  { description: "WM_MOUSEWHEEL, 20, -0.5 lines, pixel scrolling is disabled",
-    message: WM_MOUSEWHEEL, delta: 20,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kVAxis, lines: 0, pixels: 0,
-    },
-  },
-
-  { description: "WM_MOUSEHWHEEL, 20, 0.5 chars, pixel scrolling is disabled",
-    message: WM_MOUSEHWHEEL, delta: 20,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kHAxis, lines: 0, pixels: 0,
-    },
-  },
-  { description: "WM_MOUSEHWHEEL, 20, 0.5 chars (pending: 0.5 chars), pixel scrolling is disabled",
-    message: WM_MOUSEHWHEEL, delta: 20,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kHAxis, lines: 1, pixels: function () { return gCharWidth; },
-    },
-  },
-  { description: "WM_MOUSEHWHEEL, 20, 0.5 chars, pixel scrolling is disabled",
-    message: WM_MOUSEHWHEEL, delta: 20,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kHAxis, lines: 0, pixels: 0,
-    },
-  },
-
-  { description: "WM_MOUSEHWHEEL, -20, -0.5 chars (pending: 0.5 chars), pixel scrolling is disabled",
-    message: WM_MOUSEHWHEEL, delta: -20,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kHAxis, lines: 0, pixels: 0,
-    },
-  },
-  { description: "WM_MOUSEHWHEEL, -20, -0.5 chars (pending: -0.5 chars), pixel scrolling is disabled",
-    message: WM_MOUSEHWHEEL, delta: -20,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kHAxis, lines: -1, pixels: function () { return -gCharWidth; },
-    },
-  },
-  { description: "WM_MOUSEHWHEEL, -20, -0.5 chars, pixel scrolling is disabled",
-    message: WM_MOUSEHWHEEL, delta: -20,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kHAxis, lines: 0, pixels: 0,
-    },
-    finish: function () {
-      SpecialPowers.setBoolPref(kPixelEnabledPref, true);
-    },
-  },
-
   // Even if the mouse cursor is an element whose font-size is different than
   // the scrollable element, the pixel scroll amount shouldn't be changed.
   // Widget shouldn't dispatch a pixel event if the delta can be devided by
   // lines to be scrolled.  However, pixel events should be fired by ESM.
   { description: "WM_MOUSEWHEEL, -120, 3 lines, on the other div whose font-size is larger",
     message: WM_MOUSEWHEEL, delta: -120,
     target: gP2, x: 10, y: 10, window: window,
     modifiers: 0,
@@ -816,70 +625,18 @@ var gBasicTests = [
 
     finish: function () {
       runNextTest(gScrollMessageTests, 0);
     }
   },
 ];
 
 var gPageScrllTests = [
-  // Widget shouldn't dispatch a pixel event if the delta means one page scroll.
-  // However, pixel events should be fired by ESM.
-  { description: "WM_MOUSEWHEEL, -120, 1 page",
-    message: WM_MOUSEWHEEL, delta: -120,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kVAxis, lines: DOM_PAGE_SCROLL_DELTA,
-      pixels: function () { return gPageHeight; },
-    },
-    init: function () {
-      SpecialPowers.setIntPref(kVAmountPref, WHEEL_PAGESCROLL);
-      SpecialPowers.setIntPref(kHAmountPref, WHEEL_PAGESCROLL);
-      SpecialPowers.setBoolPref(kPixelEnabledPref, true);
-    },
-  },
-
-  { description: "WM_MOUSEWHEEL, 120, -1 page",
-    message: WM_MOUSEWHEEL, delta: 120,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kVAxis, lines: -DOM_PAGE_SCROLL_DELTA,
-      pixels: function () { return gPageHeight; },
-    },
-  },
-
-  { description: "WM_MOUSEHWHEEL, 120, 1 page",
-    message: WM_MOUSEHWHEEL, delta: 120,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kHAxis, lines: DOM_PAGE_SCROLL_DELTA,
-      pixels: function () { return gPageWidth; },
-    },
-  },
-
-  { description: "WM_MOUSEHWHEEL, -120, -1 page",
-    message: WM_MOUSEHWHEEL, delta: -120,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kHAxis, lines: -DOM_PAGE_SCROLL_DELTA,
-      pixels: function () { return gPageWidth; },
-    },
-  },
-
-  // When pixel scroll is enabled (default), pixel scroll event should be fired
-  // always but line scroll event should be fired only when accumulated
-  // delta value is over a line.
+  // Pixel scroll event should be fired always but line scroll event should be
+  // fired only when accumulated delta value is over a line.
   { description: "WM_MOUSEWHEEL, -60, 0.5 pages",
     message: WM_MOUSEWHEEL, delta: -60,
     target: gP1, x: 10, y: 10, window: window,
     modifiers: 0,
     additionalFlags: 0,
     expected: {
       axis: kVAxis, lines: 0, pixels: function () { return gPageHeight / 2; },
     },
@@ -985,140 +742,16 @@ var gPageScrllTests = [
     message: WM_MOUSEHWHEEL, delta: -60,
     target: gP1, x: 10, y: 10, window: window,
     modifiers: 0,
     additionalFlags: 0,
     expected: {
       axis: kHAxis, lines: 0, pixels: function () { return gCharWidth / -2; },
     },
   },
-
-  // When pixel scroll is disabled, pixel scroll event shouldn't be fired
-  // without line scroll event.
-  { description: "WM_MOUSEWHEEL, -60, 0.5 pages, pixel scrolling is disabled",
-    message: WM_MOUSEWHEEL, delta: -60,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kVAxis, lines: 0, pixels: 0,
-    },
-    init: function () {
-      SpecialPowers.setBoolPref(kPixelEnabledPref, false);
-    },
-  },
-  { description: "WM_MOUSEWHEEL, -60, 0.5 pages (pending: 0.5 pages), pixel scrolling is disabled",
-    message: WM_MOUSEWHEEL, delta: -60,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kVAxis, lines: DOM_PAGE_SCROLL_DELTA,
-      pixels: function () { return gPageHeight; },
-    },
-  },
-  { description: "WM_MOUSEWHEEL, -60, 0.5 pages, pixel scrolling is disabled",
-    message: WM_MOUSEWHEEL, delta: -60,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kVAxis, lines: 0, pixels: 0,
-    },
-  },
-
-  { description: "WM_MOUSEWHEEL, 60, -0.5 pages (pending: 0.5 pages), pixel scrolling is disabled",
-    message: WM_MOUSEWHEEL, delta: 60,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kVAxis, lines: 0, pixels: 0,
-    },
-  },
-  { description: "WM_MOUSEWHEEL, 60, -0.5 pages (pending: -0.5 pages), pixel scrolling is disabled",
-    message: WM_MOUSEWHEEL, delta: 60,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kVAxis, lines: -DOM_PAGE_SCROLL_DELTA, pixels: -gPageHeight,
-    },
-  },
-  { description: "WM_MOUSEWHEEL, 60, -0.5 pages, pixel scrolling is disabled",
-    message: WM_MOUSEWHEEL, delta: 60,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kVAxis, lines: 0, pixels: 0,
-    },
-  },
-
-  { description: "WM_MOUSEHWHEEL, 60, 0.5 pages, pixel scrolling is disabled",
-    message: WM_MOUSEHWHEEL, delta: 60,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kHAxis, lines: 0, pixels: 0,
-    },
-  },
-  { description: "WM_MOUSEHWHEEL, 60, 0.5 pages (pending: 0.5 pages), pixel scrolling is disabled",
-    message: WM_MOUSEHWHEEL, delta: 60,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kHAxis, lines: DOM_PAGE_SCROLL_DELTA,
-      pixels: function () { return gPageWidth; },
-    },
-  },
-  { description: "WM_MOUSEHWHEEL, 60, 0.5 pages, pixel scrolling is disabled",
-    message: WM_MOUSEHWHEEL, delta: 60,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kHAxis, lines: 0, pixels: 0,
-    },
-  },
-
-  { description: "WM_MOUSEHWHEEL, -60, -0.5 pages (pending: 0.5 pages), pixel scrolling is disabled",
-    message: WM_MOUSEHWHEEL, delta: -60,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kHAxis, lines: 0, pixels: 0,
-    },
-  },
-  { description: "WM_MOUSEHWHEEL, -60, -0.5 pages (pending: -0.5 pages), pixel scrolling is disabled",
-    message: WM_MOUSEHWHEEL, delta: -60,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kHAxis, lines: -DOM_PAGE_SCROLL_DELTA,
-      pixels: function () { return -gPageWidth; },
-    },
-  },
-  { description: "WM_MOUSEHWHEEL, -60, -0.5 pages, pixel scrolling is disabled",
-    message: WM_MOUSEHWHEEL, delta: -60,
-    target: gP1, x: 10, y: 10, window: window,
-    modifiers: 0,
-    additionalFlags: 0,
-    expected: {
-      axis: kHAxis, lines: 0, pixels: 0,
-    },
-
-    finish: function () {
-      runNextTest(gScrollMessageTests, 0);
-    }
-  },
 ];
 
 var gScrollMessageTests = [
   // Widget should dispatch neither line scroll event nor pixel scroll event if
   // the WM_*SCROLL's lParam is NULL and mouse wheel emulation is disabled.
   { description: "WM_VSCROLL, SB_LINEDOWN, lParam is NULL, emulation disabled",
     message: WM_VSCROLL, delta: SB_LINEDOWN,
     target: gP1, x: 10, y: 10, window: window,
@@ -1884,17 +1517,16 @@ function prepareTests()
   SpecialPowers.setIntPref(kCtrlKeyDeltaMultiplierXPref, 100);
   SpecialPowers.setIntPref(kCtrlKeyDeltaMultiplierYPref, 100);
   SpecialPowers.setIntPref(kShiftKeyDeltaMultiplierXPref, 100);
   SpecialPowers.setIntPref(kShiftKeyDeltaMultiplierYPref, 100);
   SpecialPowers.setIntPref(kWinKeyDeltaMultiplierXPref, 100);
   SpecialPowers.setIntPref(kWinKeyDeltaMultiplierYPref, 100);
 
   SpecialPowers.setBoolPref(kSystemScrollSpeedOverridePref, false);
-  SpecialPowers.setBoolPref(kPixelEnabledPref, true);
   SpecialPowers.setIntPref(kTimeoutPref, -1);
 
   runNextTest(gPreparingSteps, 0);
 }
 
 </script>
 </body>
 
--- a/widget/windows/KeyboardLayout.cpp
+++ b/widget/windows/KeyboardLayout.cpp
@@ -123,17 +123,17 @@ ModifierKeyState::InitInputEvent(nsInput
       break;
   }
 }
 
 void
 ModifierKeyState::InitMouseEvent(nsInputEvent& aMouseEvent) const
 {
   NS_ASSERTION(aMouseEvent.eventStructType == NS_MOUSE_EVENT ||
-               aMouseEvent.eventStructType == NS_MOUSE_SCROLL_EVENT ||
+               aMouseEvent.eventStructType == NS_WHEEL_EVENT ||
                aMouseEvent.eventStructType == NS_DRAG_EVENT ||
                aMouseEvent.eventStructType == NS_SIMPLE_GESTURE_EVENT ||
                aMouseEvent.eventStructType == NS_MOZTOUCH_EVENT,
                "called with non-mouse event");
 
   nsMouseEvent_base& mouseEvent = static_cast<nsMouseEvent_base&>(aMouseEvent);
   mouseEvent.buttons = 0;
   if (::GetKeyState(VK_LBUTTON) < 0) {
--- a/widget/windows/WinMouseScrollHandler.cpp
+++ b/widget/windows/WinMouseScrollHandler.cpp
@@ -10,16 +10,17 @@
 #include "prlog.h"
 
 #include "WinMouseScrollHandler.h"
 #include "nsWindow.h"
 #include "KeyboardLayout.h"
 #include "WinUtils.h"
 #include "nsGkAtoms.h"
 #include "nsIDOMWindowUtils.h"
+#include "nsIDOMWheelEvent.h"
 
 #include "mozilla/Preferences.h"
 
 #include <psapi.h>
 
 namespace mozilla {
 namespace widget {
 
@@ -354,101 +355,16 @@ MouseScrollHandler::ComputeMessagePos(UI
   } else {
     POINTS pts = GetCurrentMessagePos();
     point.x = pts.x;
     point.y = pts.y;
   }
   return point;
 }
 
-MouseScrollHandler::ScrollTargetInfo
-MouseScrollHandler::GetScrollTargetInfo(
-                      nsWindow* aWindow,
-                      const EventInfo& aEventInfo,
-                      const ModifierKeyState& aModifierKeyState)
-{
-  ScrollTargetInfo result;
-  result.dispatchPixelScrollEvent = false;
-  result.reversePixelScrollDirection = false;
-  result.actualScrollAmount = aEventInfo.GetScrollAmount();
-  result.actualScrollAction = nsQueryContentEvent::SCROLL_ACTION_NONE;
-  result.pixelsPerUnit = 0;
-  if (!mUserPrefs.IsPixelScrollingEnabled()) {
-    PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
-      ("MouseScroll::GetPixelScrollInfo: Succeeded, aWindow=%p, "
-       "result: { dispatchPixelScrollEvent: %s, actualScrollAmount: %d }",
-       aWindow, GetBoolName(result.dispatchPixelScrollEvent),
-       result.actualScrollAmount));
-    return result;
-  }
-
-  nsMouseScrollEvent testEvent(true, NS_MOUSE_SCROLL, aWindow);
-  InitEvent(aWindow, testEvent);
-  aModifierKeyState.InitInputEvent(testEvent);
-
-  testEvent.scrollFlags = aEventInfo.GetScrollFlags();
-  testEvent.delta       = result.actualScrollAmount;
-  if ((aEventInfo.IsVertical() && aEventInfo.IsPositive()) ||
-      (!aEventInfo.IsVertical() && !aEventInfo.IsPositive())) {
-    testEvent.delta *= -1;
-  }
-
-  nsQueryContentEvent queryEvent(true, NS_QUERY_SCROLL_TARGET_INFO, aWindow);
-  InitEvent(aWindow, queryEvent);
-  queryEvent.InitForQueryScrollTargetInfo(&testEvent);
-  DispatchEvent(aWindow, queryEvent);
-
-  // If the necessary interger isn't larger than 0, we should assume that
-  // the event failed for us.
-  if (!queryEvent.mSucceeded) {
-    PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
-      ("MouseScroll::GetPixelScrollInfo: Failed to query the "
-       "scroll target information, aWindow=%p"
-       "result: { dispatchPixelScrollEvent: %s, actualScrollAmount: %d }",
-       aWindow, GetBoolName(result.dispatchPixelScrollEvent),
-       result.actualScrollAmount));
-    return result;
-  }
-
-  result.actualScrollAction = queryEvent.mReply.mComputedScrollAction;
-
-  if (result.actualScrollAction == nsQueryContentEvent::SCROLL_ACTION_PAGE) {
-    result.pixelsPerUnit =
-      aEventInfo.IsVertical() ? queryEvent.mReply.mPageHeight :
-                                queryEvent.mReply.mPageWidth;
-  } else {
-    result.pixelsPerUnit = queryEvent.mReply.mLineHeight;
-  }
-
-  result.actualScrollAmount = queryEvent.mReply.mComputedScrollAmount;
-
-  if (result.pixelsPerUnit > 0 && result.actualScrollAmount != 0 &&
-      result.actualScrollAction != nsQueryContentEvent::SCROLL_ACTION_NONE) {
-    result.dispatchPixelScrollEvent = true;
-    // If original delta's sign and computed delta's one are different,
-    // we need to reverse the pixel scroll direction at dispatching it.
-    result.reversePixelScrollDirection =
-      (testEvent.delta > 0 && result.actualScrollAmount < 0) ||
-      (testEvent.delta < 0 && result.actualScrollAmount > 0);
-    // scroll amount must be positive.
-    result.actualScrollAmount = NS_ABS(result.actualScrollAmount);
-  }
-
-  PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
-    ("MouseScroll::GetPixelScrollInfo: Succeeded, aWindow=%p, "
-     "result: { dispatchPixelScrollEvent: %s, reversePixelScrollDirection: %s, "
-     "actualScrollAmount: %d, actualScrollAction: 0x%01X, "
-     "pixelsPerUnit: %d }",
-     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)
 {
   if (SynthesizingEvent::IsSynthesizing()) {
     mSynthesizingEvent->NativeMessageReceived(aWindow, aMessage,
@@ -668,17 +584,17 @@ MouseScrollHandler::HandleMouseWheelMess
      "aMessage=MOZ_WM_MOUSE%sWHEEL, aWParam=0x%08X, aLParam=0x%08X",
      aWindow, aMessage == MOZ_WM_MOUSEVWHEEL ? "V" : "H",
      aWParam, aLParam));
 
   mIsWaitingInternalMessage = false;
 
   EventInfo eventInfo(aWindow, WinUtils::GetNativeMessage(aMessage),
                       aWParam, aLParam);
-  if (!eventInfo.CanDispatchMouseScrollEvent()) {
+  if (!eventInfo.CanDispatchWheelEvent()) {
     PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
       ("MouseScroll::HandleMouseWheelMessage: Cannot dispatch the events"));
     mLastEventInfo.ResetTransaction();
     return;
   }
 
   // Discard the remaining delta if current wheel message and last one are
   // received by different window or to scroll different direction or
@@ -686,72 +602,40 @@ MouseScrollHandler::HandleMouseWheelMess
   if (!mLastEventInfo.CanContinueTransaction(eventInfo)) {
     mLastEventInfo.ResetTransaction();
   }
 
   mLastEventInfo.RecordEvent(eventInfo);
 
   ModifierKeyState modKeyState = GetModifierKeyState(aMessage);
 
-  // Before dispatching line scroll event, we should get the current scroll
-  // event target information for pixel scroll.
-  ScrollTargetInfo scrollTargetInfo =
-    GetScrollTargetInfo(aWindow, eventInfo, modKeyState);
-
   // Grab the widget, it might be destroyed by a DOM event handler.
   nsRefPtr<nsWindow> kungFuDethGrip(aWindow);
 
-  bool fromLines = false;
-  nsMouseScrollEvent scrollEvent(true, NS_MOUSE_SCROLL, aWindow);
-  if (mLastEventInfo.InitMouseScrollEvent(aWindow, scrollEvent,
-                                          scrollTargetInfo, modKeyState)) {
+  WheelEvent wheelEvent(true, NS_WHEEL_WHEEL, aWindow);
+  if (mLastEventInfo.InitWheelEvent(aWindow, wheelEvent, modKeyState)) {
     PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
       ("MouseScroll::HandleMouseWheelMessage: dispatching "
-       "NS_MOUSE_SCROLL event"));
-    fromLines = true;
-    DispatchEvent(aWindow, scrollEvent);
+       "NS_WHEEL_WHEEL event"));
+    DispatchEvent(aWindow, wheelEvent);
     if (aWindow->Destroyed()) {
       PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
         ("MouseScroll::HandleMouseWheelMessage: The window was destroyed "
-         "by NS_MOUSE_SCROLL event"));
+         "by NS_WHEEL_WHEEL event"));
       mLastEventInfo.ResetTransaction();
       return;
     }
   }
 #ifdef PR_LOGGING
   else {
     PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
-      ("MouseScroll::HandleMouseWheelMessage: NS_MOUSE_SCROLL event is not "
+      ("MouseScroll::HandleMouseWheelMessage: NS_WHEEL_WHEEL event is not "
        "dispatched"));
   }
 #endif
-
-  nsMouseScrollEvent pixelEvent(true, NS_MOUSE_PIXEL_SCROLL, aWindow);
-  if (mLastEventInfo.InitMousePixelScrollEvent(aWindow, pixelEvent,
-                                               scrollTargetInfo, modKeyState)) {
-    PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
-      ("MouseScroll::HandleMouseWheelMessage: dispatching "
-       "NS_MOUSE_PIXEL_SCROLL event"));
-    pixelEvent.scrollFlags |= fromLines ? nsMouseScrollEvent::kFromLines : 0;
-    DispatchEvent(aWindow, pixelEvent);
-    if (aWindow->Destroyed()) {
-      PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
-        ("MouseScroll::HandleMouseWheelMessage: The window was destroyed "
-         "by NS_MOUSE_PIXEL_SCROLL event"));
-      mLastEventInfo.ResetTransaction();
-      return;
-    }
-  }
-#ifdef PR_LOGGING
-  else {
-    PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
-      ("MouseScroll::HandleMouseWheelMessage: NS_MOUSE_PIXEL_SCROLL event is "
-       "not dispatched"));
-  }
-#endif
 }
 
 void
 MouseScrollHandler::HandleScrollMessageAsMouseWheelMessage(nsWindow* aWindow,
                                                            UINT aMessage,
                                                            WPARAM aWParam,
                                                            LPARAM aLParam)
 {
@@ -759,54 +643,66 @@ MouseScrollHandler::HandleScrollMessageA
     (aMessage == MOZ_WM_VSCROLL || aMessage == MOZ_WM_HSCROLL),
     "HandleScrollMessageAsMouseWheelMessage must be called with "
     "MOZ_WM_VSCROLL or MOZ_WM_HSCROLL");
 
   mIsWaitingInternalMessage = false;
 
   ModifierKeyState modKeyState = GetModifierKeyState(aMessage);
 
-  nsMouseScrollEvent scrollEvent(true, NS_MOUSE_SCROLL, aWindow);
-  scrollEvent.scrollFlags =
-    (aMessage == MOZ_WM_VSCROLL) ? nsMouseScrollEvent::kIsVertical :
-                                   nsMouseScrollEvent::kIsHorizontal;
+  WheelEvent wheelEvent(true, NS_WHEEL_WHEEL, aWindow);
+  double& delta =
+   (aMessage == MOZ_WM_VSCROLL) ? wheelEvent.deltaY : wheelEvent.deltaX;
+  PRInt32& lineOrPageDelta =
+   (aMessage == MOZ_WM_VSCROLL) ? wheelEvent.lineOrPageDeltaY :
+                                  wheelEvent.lineOrPageDeltaX;
+
+  delta = 1.0;
+  lineOrPageDelta = 1;
+
   switch (LOWORD(aWParam)) {
+    case SB_PAGEUP:
+      delta = -1.0;
+      lineOrPageDelta = -1;
     case SB_PAGEDOWN:
-      scrollEvent.scrollFlags |= nsMouseScrollEvent::kIsFullPage;
+      wheelEvent.deltaMode = nsIDOMWheelEvent::DOM_DELTA_PAGE;
+      break;
+
+    case SB_LINEUP:
+      delta = -1.0;
+      lineOrPageDelta = -1;
     case SB_LINEDOWN:
-      scrollEvent.delta = 1;
+      wheelEvent.deltaMode = nsIDOMWheelEvent::DOM_DELTA_LINE;
       break;
-    case SB_PAGEUP:
-      scrollEvent.scrollFlags |= nsMouseScrollEvent::kIsFullPage;
-    case SB_LINEUP:
-      scrollEvent.delta = -1;
-      break;
+
     default:
       return;
   }
-  modKeyState.InitInputEvent(scrollEvent);
+  modKeyState.InitInputEvent(wheelEvent);
   // XXX Current mouse position may not be same as when the original message
   //     is received.  We need to know the actual mouse cursor position when
   //     the original message was received.
-  InitEvent(aWindow, scrollEvent);
+  InitEvent(aWindow, wheelEvent);
 
   PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
     ("MouseScroll::HandleScrollMessageAsMouseWheelMessage: aWindow=%p, "
      "aMessage=MOZ_WM_%sSCROLL, aWParam=0x%08X, aLParam=0x%08X, "
-     "scrollEvent { refPoint: { x: %d, y: %d }, delta: %d, "
-     "scrollFlags: 0x%04X, isShift: %s, isControl: %s, isAlt: %s, isMeta: %s }",
-     aWindow, (aMessage == MOZ_WM_VSCROLL) ? "V" : "H",
-     aWParam, aLParam, scrollEvent.refPoint.x, scrollEvent.refPoint.y,
-     scrollEvent.delta, scrollEvent.scrollFlags,
-     GetBoolName(scrollEvent.IsShift()),
-     GetBoolName(scrollEvent.IsControl()),
-     GetBoolName(scrollEvent.IsAlt()),
-     GetBoolName(scrollEvent.IsMeta())));
+     "wheelEvent { refPoint: { x: %d, y: %d }, deltaX: %f, deltaY: %f, "
+     "lineOrPageDeltaX: %d, lineOrPageDeltaY: %d, "
+     "isShift: %s, isControl: %s, isAlt: %s, isMeta: %s }",
+     aWindow, (aMessage == MOZ_WM_VSCROLL) ? "V" : "H", aWParam, aLParam,
+     wheelEvent.refPoint.x, wheelEvent.refPoint.y,
+     wheelEvent.deltaX, wheelEvent.deltaY,
+     wheelEvent.lineOrPageDeltaX, wheelEvent.lineOrPageDeltaY,
+     GetBoolName(wheelEvent.IsShift()),
+     GetBoolName(wheelEvent.IsControl()),
+     GetBoolName(wheelEvent.IsAlt()),
+     GetBoolName(wheelEvent.IsMeta())));
 
-  DispatchEvent(aWindow, scrollEvent);
+  DispatchEvent(aWindow, wheelEvent);
 }
 
 /******************************************************************************
  *
  * EventInfo
  *
  ******************************************************************************/
 
@@ -823,17 +719,17 @@ MouseScrollHandler::EventInfo::EventInfo
   mIsPage = MouseScrollHandler::sInstance->
               mSystemSettings.IsPageScroll(mIsVertical);
   mDelta = (short)HIWORD(aWParam);
   mWnd = aWindow->GetWindowHandle();
   mTimeStamp = TimeStamp::Now();
 }
 
 bool
-MouseScrollHandler::EventInfo::CanDispatchMouseScrollEvent() const
+MouseScrollHandler::EventInfo::CanDispatchWheelEvent() const
 {
   if (!GetScrollAmount()) {
     // XXX I think that we should dispatch mouse wheel events even if the
     // operation will not scroll because the wheel operation really happened
     // and web application may want to handle the event for non-scroll action.
     return false;
   }
 
@@ -845,25 +741,16 @@ MouseScrollHandler::EventInfo::GetScroll
 {
   if (mIsPage) {
     return 1;
   }
   return MouseScrollHandler::sInstance->
            mSystemSettings.GetScrollAmount(mIsVertical);
 }
 
-PRInt32
-MouseScrollHandler::EventInfo::GetScrollFlags() const
-{
-  PRInt32 result = mIsPage ? nsMouseScrollEvent::kIsFullPage : 0;
-  result |= mIsVertical ? nsMouseScrollEvent::kIsVertical :
-                          nsMouseScrollEvent::kIsHorizontal;
-  return result;
-}
-
 /******************************************************************************
  *
  * LastEventInfo
  *
  ******************************************************************************/
 
 bool
 MouseScrollHandler::LastEventInfo::CanContinueTransaction(
@@ -887,18 +774,17 @@ MouseScrollHandler::LastEventInfo::Reset
   if (!mWnd) {
     return;
   }
 
   PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
     ("MouseScroll::LastEventInfo::ResetTransaction()"));
 
   mWnd = nullptr;
-  mRemainingDeltaForScroll = 0;
-  mRemainingDeltaForPixel = 0;
+  mAccumulatedDelta = 0;
 }
 
 void
 MouseScrollHandler::LastEventInfo::RecordEvent(const EventInfo& aEvent)
 {
   mWnd = aEvent.GetWindowHandle();
   mDelta = aEvent.GetNativeDelta();
   mIsVertical = aEvent.IsVertical();
@@ -909,145 +795,68 @@ MouseScrollHandler::LastEventInfo::Recor
 /* static */
 PRInt32
 MouseScrollHandler::LastEventInfo::RoundDelta(double aDelta)
 {
   return (aDelta >= 0) ? (PRInt32)floor(aDelta) : (PRInt32)ceil(aDelta);
 }
 
 bool
-MouseScrollHandler::LastEventInfo::InitMouseScrollEvent(
+MouseScrollHandler::LastEventInfo::InitWheelEvent(
                                      nsWindow* aWindow,
-                                     nsMouseScrollEvent& aMouseScrollEvent,
-                                     const ScrollTargetInfo& aScrollTargetInfo,
+                                     WheelEvent& aWheelEvent,
                                      const ModifierKeyState& aModKeyState)
 {
-  NS_ABORT_IF_FALSE(aMouseScrollEvent.message == NS_MOUSE_SCROLL,
-    "aMouseScrollEvent must be NS_MOUSE_SCROLL");
+  MOZ_ASSERT(aWheelEvent.message == NS_WHEEL_WHEEL);
 
   // XXX Why don't we use lParam value? We should use lParam value because
   //     our internal message is always posted by original message handler.
   //     So, GetMessagePos() may return different cursor position.
-  InitEvent(aWindow, aMouseScrollEvent);
-
-  aModKeyState.InitInputEvent(aMouseScrollEvent);
+  InitEvent(aWindow, aWheelEvent);
 
-  // If we dispatch pixel scroll event after the line scroll event,
-  // we should set kHasPixels flag to the line scroll event.
-  aMouseScrollEvent.scrollFlags =
-    aScrollTargetInfo.dispatchPixelScrollEvent ?
-      nsMouseScrollEvent::kHasPixels : 0;
-  aMouseScrollEvent.scrollFlags |= GetScrollFlags();
+  aModKeyState.InitInputEvent(aWheelEvent);
 
   // Our positive delta value means to bottom or right.
   // But positive native delta value means to top or right.
   // Use orienter for computing our delta value with native delta value.
   PRInt32 orienter = mIsVertical ? -1 : 1;
 
-  // NOTE: Don't use aScrollTargetInfo.actualScrollAmount for computing the
-  //       delta value of line/page scroll event.  The value will be recomputed
-  //       in ESM.
-  PRInt32 nativeDelta = mDelta + mRemainingDeltaForScroll;
-  if (IsPage()) {
-    aMouseScrollEvent.delta = nativeDelta * orienter / WHEEL_DELTA;
-    PRInt32 recomputedNativeDelta =
-      aMouseScrollEvent.delta * orienter / WHEEL_DELTA;
-    mRemainingDeltaForScroll = nativeDelta - recomputedNativeDelta;
-  } else {
-    double deltaPerUnit = (double)WHEEL_DELTA / GetScrollAmount();
-    aMouseScrollEvent.delta = 
-      RoundDelta((double)nativeDelta * orienter / deltaPerUnit);
-    PRInt32 recomputedNativeDelta =
-      (PRInt32)(aMouseScrollEvent.delta * orienter * deltaPerUnit);
-    mRemainingDeltaForScroll = nativeDelta - recomputedNativeDelta;
-  }
+  aWheelEvent.deltaMode = mIsPage ? nsIDOMWheelEvent::DOM_DELTA_PAGE :
+                                    nsIDOMWheelEvent::DOM_DELTA_LINE;
+
+  double& delta = mIsVertical ? aWheelEvent.deltaY : aWheelEvent.deltaX;
+  PRInt32& lineOrPageDelta = mIsVertical ? aWheelEvent.lineOrPageDeltaY :
+                                           aWheelEvent.lineOrPageDeltaX;
+
+  double nativeDeltaPerUnit =
+    mIsPage ? static_cast<double>(WHEEL_DELTA) :
+              static_cast<double>(WHEEL_DELTA) / GetScrollAmount();
+
+  delta = static_cast<double>(mDelta) * orienter / nativeDeltaPerUnit;
+  mAccumulatedDelta += mDelta;
+  lineOrPageDelta =
+    mAccumulatedDelta * orienter / RoundDelta(nativeDeltaPerUnit);
+  mAccumulatedDelta -=
+    lineOrPageDelta * orienter * RoundDelta(nativeDeltaPerUnit);
 
   PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
-    ("MouseScroll::LastEventInfo::InitMouseScrollEvent: aWindow=%p, "
-     "aMouseScrollEvent { refPoint: { x: %d, y: %d }, delta: %d, "
-     "scrollFlags: 0x%04X, isShift: %s, isControl: %s, isAlt: %s, "
-     "isMeta: %s }, mRemainingDeltaForScroll: %d",
-     aWindow, aMouseScrollEvent.refPoint.x, aMouseScrollEvent.refPoint.y,
-     aMouseScrollEvent.delta, aMouseScrollEvent.scrollFlags,
-     GetBoolName(aMouseScrollEvent.IsShift()),
-     GetBoolName(aMouseScrollEvent.IsControl()),
-     GetBoolName(aMouseScrollEvent.IsAlt()),
-     GetBoolName(aMouseScrollEvent.IsMeta()), mRemainingDeltaForScroll));
-
-  return (aMouseScrollEvent.delta != 0);
-}
-
-bool
-MouseScrollHandler::LastEventInfo::InitMousePixelScrollEvent(
-                                     nsWindow* aWindow,
-                                     nsMouseScrollEvent& aPixelScrollEvent,
-                                     const ScrollTargetInfo& aScrollTargetInfo,
-                                     const ModifierKeyState& aModKeyState)
-{
-  NS_ABORT_IF_FALSE(aPixelScrollEvent.message == NS_MOUSE_PIXEL_SCROLL,
-    "aPixelScrollEvent must be NS_MOUSE_PIXEL_SCROLL");
-
-  if (!aScrollTargetInfo.dispatchPixelScrollEvent) {
-    PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
-      ("MouseScroll::LastEventInfo::InitMousePixelScrollEvent: aWindow=%p, "
-       "PixelScroll is disabled",
-       aWindow, mRemainingDeltaForPixel));
-
-    mRemainingDeltaForPixel = 0;
-    return false;
-  }
-
-  // XXX Why don't we use lParam value? We should use lParam value because
-  //     our internal message is always posted by original message handler.
-  //     So, GetMessagePos() may return different cursor position.
-  InitEvent(aWindow, aPixelScrollEvent);
-
-  aModKeyState.InitInputEvent(aPixelScrollEvent);
+    ("MouseScroll::LastEventInfo::InitWheelEvent: aWindow=%p, "
+     "aWheelEvent { refPoint: { x: %d, y: %d }, deltaX: %f, deltaY: %f, "
+     "lineOrPageDeltaX: %d, lineOrPageDeltaY: %d, "
+     "isShift: %s, isControl: %s, isAlt: %s, isMeta: %s }, "
+     "mAccumulatedDelta: %d",
+     aWindow, aWheelEvent.refPoint.x, aWheelEvent.refPoint.y,
+     aWheelEvent.deltaX, aWheelEvent.deltaY,
+     aWheelEvent.lineOrPageDeltaX, aWheelEvent.lineOrPageDeltaY,
+     GetBoolName(aWheelEvent.IsShift()),
+     GetBoolName(aWheelEvent.IsControl()),
+     GetBoolName(aWheelEvent.IsAlt()),
+     GetBoolName(aWheelEvent.IsMeta()), mAccumulatedDelta));
 
-  aPixelScrollEvent.scrollFlags = nsMouseScrollEvent::kAllowSmoothScroll;
-  aPixelScrollEvent.scrollFlags |= mIsVertical ?
-    nsMouseScrollEvent::kIsVertical : nsMouseScrollEvent::kIsHorizontal;
-  if (aScrollTargetInfo.actualScrollAction ==
-        nsQueryContentEvent::SCROLL_ACTION_PAGE) {
-    aPixelScrollEvent.scrollFlags |= nsMouseScrollEvent::kIsFullPage;
-  }
-
-  // Our positive delta value means to bottom or right.
-  // But positive native delta value means to top or right.
-  // Use orienter for computing our delta value with native delta value.
-  PRInt32 orienter = mIsVertical ? -1 : 1;
-  // However, pixel scroll event won't be recomputed the scroll amout and
-  // direction by ESM.  Therefore, we need to set the computed amout and
-  // direction here.
-  if (aScrollTargetInfo.reversePixelScrollDirection) {
-    orienter *= -1;
-  }
-
-  PRInt32 nativeDelta = mDelta + mRemainingDeltaForPixel;
-  double deltaPerPixel = (double)WHEEL_DELTA /
-    aScrollTargetInfo.actualScrollAmount / aScrollTargetInfo.pixelsPerUnit;
-  aPixelScrollEvent.delta =
-    RoundDelta((double)nativeDelta * orienter / deltaPerPixel);
-  PRInt32 recomputedNativeDelta =
-    (PRInt32)(aPixelScrollEvent.delta * orienter * deltaPerPixel);
-  mRemainingDeltaForPixel = nativeDelta - recomputedNativeDelta;
-
-  PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
-    ("MouseScroll::LastEventInfo::InitMousePixelScrollEvent: aWindow=%p, "
-     "aPixelScrollEvent { refPoint: { x: %d, y: %d }, delta: %d, "
-     "scrollFlags: 0x%04X, isShift: %s, isControl: %s, isAlt: %s, "
-     "isMeta: %s }, mRemainingDeltaForScroll: %d",
-     aWindow, aPixelScrollEvent.refPoint.x, aPixelScrollEvent.refPoint.y,
-     aPixelScrollEvent.delta, aPixelScrollEvent.scrollFlags,
-     GetBoolName(aPixelScrollEvent.IsShift()),
-     GetBoolName(aPixelScrollEvent.IsControl()),
-     GetBoolName(aPixelScrollEvent.IsAlt()),
-     GetBoolName(aPixelScrollEvent.IsMeta()), mRemainingDeltaForPixel));
-
-  return (aPixelScrollEvent.delta != 0);
+  return (delta != 0);
 }
 
 /******************************************************************************
  *
  * SystemSettings
  *
  ******************************************************************************/
 
@@ -1167,35 +976,32 @@ void
 MouseScrollHandler::UserPrefs::Init()
 {
   if (mInitialized) {
     return;
   }
 
   mInitialized = true;
 
-  mPixelScrollingEnabled =
-    Preferences::GetBool("mousewheel.enable_pixel_scrolling", true);
   mScrollMessageHandledAsWheelMessage =
     Preferences::GetBool("mousewheel.emulate_at_wm_scroll", false);
   mOverriddenVerticalScrollAmount =
     Preferences::GetInt("mousewheel.windows.vertical_amount_override", -1);
   mOverriddenHorizontalScrollAmount =
     Preferences::GetInt("mousewheel.windows.horizontal_amount_override", -1);
   mMouseScrollTransactionTimeout =
     Preferences::GetInt("mousewheel.windows.transaction.timeout",
                         DEFAULT_TIMEOUT_DURATION);
 
   PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
     ("MouseScroll::UserPrefs::Init(): initialized, "
-       "mPixelScrollingEnabled=%s, mScrollMessageHandledAsWheelMessage=%s, "
+       "mScrollMessageHandledAsWheelMessage=%s, "
        "mOverriddenVerticalScrollAmount=%d, "
        "mOverriddenHorizontalScrollAmount=%d, "
        "mMouseScrollTransactionTimeout=%d",
-     GetBoolName(mPixelScrollingEnabled),
      GetBoolName(mScrollMessageHandledAsWheelMessage),
      mOverriddenVerticalScrollAmount, mOverriddenHorizontalScrollAmount,
      mMouseScrollTransactionTimeout));
 }
 
 void
 MouseScrollHandler::UserPrefs::MarkDirty()
 {
--- a/widget/windows/WinMouseScrollHandler.h
+++ b/widget/windows/WinMouseScrollHandler.h
@@ -10,23 +10,23 @@
 #include "nscore.h"
 #include "nsDebug.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/TimeStamp.h"
 #include <windows.h>
 
 class nsWindow;
 class nsGUIEvent;
-class nsMouseScrollEvent;
 struct nsIntPoint;
 
 namespace mozilla {
 namespace widget {
 
 class ModifierKeyState;
+class WheelEvent;
 
 class MouseScrollHandler {
 public:
   static MouseScrollHandler* GetInstance();
 
   static void Initialize();
   static void Shutdown();
 
@@ -175,72 +175,38 @@ private:
    * @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.
-   */
-  struct ScrollTargetInfo {
-    // TRUE if pixel scroll event is needed.  Otherwise, FALSE.
-    bool dispatchPixelScrollEvent;
-    // TRUE if pixel scroll event's delta value should be reversed.
-    // Otherwise, FALSE.
-    bool reversePixelScrollDirection;
-    // Actual scroll amount.  It might be computed with user prefs.
-    PRInt32 actualScrollAmount;
-    // Actual scroll action.  It might be computed with user prefs.
-    // The value is one of nsQueryContentEvent::SCROLL_ACTION_*.
-    PRInt32 actualScrollAction;
-    // Pixels per unit (line or page, depends on the action).
-    PRInt32 pixelsPerUnit;
-  };
-  ScrollTargetInfo GetScrollTargetInfo(
-                     nsWindow* aWindow,
-                     const EventInfo& aEvent,
-                     const ModifierKeyState& aModiferKeyState);
-
   class EventInfo {
   public:
     /**
      * @param aWindow   An nsWindow which is handling the event.
      * @param aMessage  Must be WM_MOUSEWHEEL or WM_MOUSEHWHEEL.
      */
     EventInfo(nsWindow* aWindow, UINT aMessage, WPARAM aWParam, LPARAM aLParam);
 
-    bool CanDispatchMouseScrollEvent() const;
+    bool CanDispatchWheelEvent() const;
 
     PRInt32 GetNativeDelta() const { return mDelta; }
     HWND GetWindowHandle() const { return mWnd; }
     const TimeStamp& GetTimeStamp() const { return mTimeStamp; }
     bool IsVertical() const { return mIsVertical; }
     bool IsPositive() const { return (mDelta > 0); }
     bool IsPage() const { return mIsPage; }
 
     /**
      * @return          Number of lines or pages scrolled per WHEEL_DELTA.
      */
     PRInt32 GetScrollAmount() const;
 
-    /**
-     * @return          One or more values of
-     *                  nsMouseScrollEvent::nsMouseScrollFlags.
-     */
-    PRInt32 GetScrollFlags() const;
-
   protected:
     EventInfo() :
       mIsVertical(false), mIsPage(false), mDelta(0), mWnd(nullptr)
     {
     }
 
     // TRUE if event is for vertical scroll.  Otherwise, FALSE.
     bool mIsVertical;
@@ -252,17 +218,17 @@ private:
     HWND mWnd;
     // Timestamp of the event.
     TimeStamp mTimeStamp;
   };
 
   class LastEventInfo : public EventInfo {
   public:
     LastEventInfo() :
-      EventInfo(), mRemainingDeltaForScroll(0), mRemainingDeltaForPixel(0)
+      EventInfo(), mAccumulatedDelta(0)
     {
     }
 
     /**
      * CanContinueTransaction() checks whether the new event can continue the
      * last transaction or not.  Note that if there is no transaction, this
      * returns true.
      */
@@ -275,60 +241,36 @@ private:
     void ResetTransaction();
 
     /**
      * RecordEvent() saves the information of new event.
      */
     void RecordEvent(const EventInfo& aEvent);
 
     /**
-     * InitMouseScrollEvent() initializes NS_MOUSE_SCROLL event and
+     * InitWheelEvent() initializes NS_WHEEL_WHEEL event and
      * recomputes the remaning detla for the event.
      * This must be called only once during handling a message and after
      * RecordEvent() is called.
      *
      * @param aWindow           A window which will dispatch the event.
-     * @param aMouseScrollEvent An NS_MOUSE_SCROLL event, this will be
+     * @param aWheelEvent       An NS_WHEEL_WHEEL event, this will be
      *                          initialized.
-     * @param aScrollTargetInfo The result of GetScrollTargetInfo().
      * @param aModKeyState      Current modifier key state.
      * @return                  TRUE if the event is ready to dispatch.
      *                          Otherwise, FALSE.
      */
-    bool InitMouseScrollEvent(nsWindow* aWindow,
-                              nsMouseScrollEvent& aMouseScrollEvent,
-                              const ScrollTargetInfo& aScrollTargetInfo,
-                              const ModifierKeyState& aModKeyState);
-
-    /**
-     * InitMousePixelScrollEvent() initializes NS_MOUSE_PIXEL_SCROLL event and
-     * recomputes the remaning detla for the event.
-     * This must be called only once during handling a message and after
-     * RecordEvent() is called.
-     *
-     * @param aWindow           A window which will dispatch the event.
-     * @param aMouseScrollEvent An NS_MOUSE_PIXEL_SCROLL event, this will be
-     *                          initialized.
-     * @param aScrollTargetInfo The result of GetScrollTargetInfo().
-     * @param aModKeyState      Current modifier key state.
-     * @return                  TRUE if the event is ready to dispatch.
-     *                          Otherwise, FALSE.
-     */
-    bool InitMousePixelScrollEvent(nsWindow* aWindow,
-                                   nsMouseScrollEvent& aPixelScrollEvent,
-                                   const ScrollTargetInfo& aScrollTargetInfo,
-                                   const ModifierKeyState& aModKeyState);
+    bool InitWheelEvent(nsWindow* aWindow,
+                        WheelEvent& aWheelEvent,
+                        const ModifierKeyState& aModKeyState);
 
   private:
     static PRInt32 RoundDelta(double aDelta);
 
-    // The remaining native delta value (i.e., not handled by previous
-    // message handler).
-    PRInt32 mRemainingDeltaForScroll;
-    PRInt32 mRemainingDeltaForPixel;
+    PRInt32 mAccumulatedDelta;
   };
 
   LastEventInfo mLastEventInfo;
 
   class SystemSettings {
   public:
     SystemSettings() : mInitialized(false) {}
 
@@ -359,22 +301,16 @@ private:
 
   class UserPrefs {
   public:
     UserPrefs();
     ~UserPrefs();
 
     void MarkDirty();
 
-    bool IsPixelScrollingEnabled()
-    {
-      Init();
-      return mPixelScrollingEnabled;
-    }
-
     bool IsScrollMessageHandledAsWheelMessage()
     {
       Init();
       return mScrollMessageHandledAsWheelMessage;
     }
 
     PRInt32 GetOverriddenVerticalScrollAmout()
     {
@@ -399,17 +335,16 @@ private:
 
     static int OnChange(const char* aPrefName, void* aClosure)
     {
       static_cast<UserPrefs*>(aClosure)->MarkDirty();
       return 0;
     }
 
     bool mInitialized;
-    bool mPixelScrollingEnabled;
     bool mScrollMessageHandledAsWheelMessage;
     PRInt32 mOverriddenVerticalScrollAmount;
     PRInt32 mOverriddenHorizontalScrollAmount;
     PRInt32 mMouseScrollTransactionTimeout;
   };
 
   UserPrefs mUserPrefs;
 
--- a/widget/windows/nsWinGesture.cpp
+++ b/widget/windows/nsWinGesture.cpp
@@ -7,20 +7,22 @@
  * nsWinGesture - Touch input handling for tablet displays.
  */
 
 #include "nscore.h"
 #include "nsWinGesture.h"
 #include "nsUXThemeData.h"
 #include "nsIDOMSimpleGestureEvent.h"
 #include "nsGUIEvent.h"
+#include "nsIDOMWheelEvent.h"
 #include "mozilla/Constants.h"
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
+using namespace mozilla::widget;
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* gWindowsLog;
 #endif
 
 const PRUnichar nsWinGesture::kGestureLibraryName[] =  L"user32.dll";
 HMODULE nsWinGesture::sLibraryHandle = nullptr;
 nsWinGesture::GetGestureInfoPtr nsWinGesture::getGestureInfo = nullptr;
@@ -549,58 +551,34 @@ nsWinGesture::PanFeedbackFinalize(HWND h
     EndPanningFeedback(hWnd);
     return;
   }
 
   UpdatePanningFeedback(hWnd, mPixelScrollOverflow.x, mPixelScrollOverflow.y, mPanInertiaActive);
 }
 
 bool
-nsWinGesture::PanDeltaToPixelScrollX(nsMouseScrollEvent& evt)
+nsWinGesture::PanDeltaToPixelScroll(WheelEvent& aWheelEvent)
 {
-  evt.delta = 0;
-  evt.scrollOverflow = 0;
+  aWheelEvent.deltaX = aWheelEvent.deltaY = aWheelEvent.deltaZ = 0.0;
+  aWheelEvent.lineOrPageDeltaX = aWheelEvent.lineOrPageDeltaY = 0;
+
+  aWheelEvent.refPoint.x = mPanRefPoint.x;
+  aWheelEvent.refPoint.y = mPanRefPoint.y;
+  aWheelEvent.deltaMode = nsIDOMWheelEvent::DOM_DELTA_PIXEL;
+  aWheelEvent.scrollType = WheelEvent::SCROLL_SYNCHRONOUSLY;
+  aWheelEvent.isPixelOnlyDevice = true;
+
+  aWheelEvent.overflowDeltaX = 0.0;
+  aWheelEvent.overflowDeltaY = 0.0;
 
   // Don't scroll the view if we are currently at a bounds, or, if we are
   // panning back from a max feedback position. This keeps the original drag point
   // constant.
-  if (mXAxisFeedback)
-    return false;
-
-  if (mPixelScrollDelta.x != 0)
-  {
-    evt.scrollFlags = nsMouseScrollEvent::kIsHorizontal|
-                      nsMouseScrollEvent::kHasPixels|
-                      nsMouseScrollEvent::kNoLines|
-                      nsMouseScrollEvent::kNoDefer;
-    evt.delta = mPixelScrollDelta.x;
-    evt.refPoint.x = mPanRefPoint.x;
-    evt.refPoint.y = mPanRefPoint.y;
-    return true;
+  if (!mXAxisFeedback) {
+    aWheelEvent.deltaX = mPixelScrollDelta.x;
   }
-  return false;
-}
+  if (!mYAxisFeedback) {
+    aWheelEvent.deltaY = mPixelScrollDelta.y;
+  }
 
-bool
-nsWinGesture::PanDeltaToPixelScrollY(nsMouseScrollEvent& evt)
-{
-  evt.delta = 0;
-  evt.scrollOverflow = 0;
-
-  // Don't scroll the view if we are currently at a bounds, or, if we are
-  // panning back from a max feedback position. This keeps the original drag point
-  // constant.
-  if (mYAxisFeedback)
-    return false;
-
-  if (mPixelScrollDelta.y != 0)
-  {
-    evt.scrollFlags = nsMouseScrollEvent::kIsVertical|
-                      nsMouseScrollEvent::kHasPixels|
-                      nsMouseScrollEvent::kNoLines|
-                      nsMouseScrollEvent::kNoDefer;
-    evt.delta = mPixelScrollDelta.y;
-    evt.refPoint.x = mPanRefPoint.x;
-    evt.refPoint.y = mPanRefPoint.y;
-    return true;
-  }
-  return false;
+  return (aWheelEvent.deltaX != 0 || aWheelEvent.deltaY != 0);
 }
--- a/widget/windows/nsWinGesture.h
+++ b/widget/windows/nsWinGesture.h
@@ -206,18 +206,17 @@ public:
   bool IsAvailable();
   
   // Simple gesture process
   bool ProcessGestureMessage(HWND hWnd, WPARAM wParam, LPARAM lParam, nsSimpleGestureEvent& evt);
 
   // Pan processing
   bool IsPanEvent(LPARAM lParam);
   bool ProcessPanMessage(HWND hWnd, WPARAM wParam, LPARAM lParam);
-  bool PanDeltaToPixelScrollX(nsMouseScrollEvent& evt);
-  bool PanDeltaToPixelScrollY(nsMouseScrollEvent& evt);
+  bool PanDeltaToPixelScroll(mozilla::widget::WheelEvent& aWheelEvent);
   void UpdatePanFeedbackX(HWND hWnd, PRInt32 scrollOverflow, bool& endFeedback);
   void UpdatePanFeedbackY(HWND hWnd, PRInt32 scrollOverflow, bool& endFeedback);
   void PanFeedbackFinalize(HWND hWnd, bool endFeedback);
   
 public:
   // Helpers
   bool GetGestureInfo(HGESTUREINFO hGestureInfo, PGESTUREINFO pGestureInfo);
   bool CloseGestureInfoHandle(HGESTUREINFO hGestureInfo);
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -6268,53 +6268,52 @@ bool nsWindow::OnTouch(WPARAM wParam, LP
     }
   }
 
   delete [] pInputs;
   mGesture.CloseTouchInputHandle((HTOUCHINPUT)lParam);
   return true;
 }
 
+static PRInt32 RoundDown(double aDouble)
+{
+  return aDouble > 0 ? static_cast<PRInt32>(floor(aDouble)) :
+                       static_cast<PRInt32>(ceil(aDouble));
+}
+
 // Gesture event processing. Handles WM_GESTURE events.
 bool nsWindow::OnGesture(WPARAM wParam, LPARAM lParam)
 {
   // Treatment for pan events which translate into scroll events:
   if (mGesture.IsPanEvent(lParam)) {
-    nsMouseScrollEvent event(true, NS_MOUSE_PIXEL_SCROLL, this);
-
     if ( !mGesture.ProcessPanMessage(mWnd, wParam, lParam) )
       return false; // ignore
 
     nsEventStatus status;
 
+    WheelEvent wheelEvent(true, NS_WHEEL_WHEEL, this);
+
     ModifierKeyState modifierKeyState;
-    modifierKeyState.InitInputEvent(event);
-
-    event.button    = 0;
-    event.time      = ::GetMessageTime();
-    event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
+    modifierKeyState.InitInputEvent(wheelEvent);
+
+    wheelEvent.button      = 0;
+    wheelEvent.time        = ::GetMessageTime();
+    wheelEvent.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
 
     bool endFeedback = true;
 
-    PRInt32 scrollOverflowX = 0;
-    PRInt32 scrollOverflowY = 0;
-
-    if (mGesture.PanDeltaToPixelScrollX(event)) {
-      DispatchEvent(&event, status);
-      scrollOverflowX = event.scrollOverflow;
-    }
-
-    if (mGesture.PanDeltaToPixelScrollY(event)) {
-      DispatchEvent(&event, status);
-      scrollOverflowY = event.scrollOverflow;
+    if (mGesture.PanDeltaToPixelScroll(wheelEvent)) {
+      DispatchEvent(&wheelEvent, status);
     }
 
     if (mDisplayPanFeedback) {
-      mGesture.UpdatePanFeedbackX(mWnd, scrollOverflowX, endFeedback);
-      mGesture.UpdatePanFeedbackY(mWnd, scrollOverflowY, endFeedback);
+      mGesture.UpdatePanFeedbackX(mWnd, RoundDown(wheelEvent.overflowDeltaX),
+                                  endFeedback);
+      mGesture.UpdatePanFeedbackY(mWnd, RoundDown(wheelEvent.overflowDeltaY),
+                                  endFeedback);
       mGesture.PanFeedbackFinalize(mWnd, endFeedback);
     }
 
     mGesture.CloseGestureInfoHandle((HGESTUREINFO)lParam);
 
     return true;
   }