summaryrefslogtreecommitdiffstats
path: root/widget/tests/window_mouse_scroll_win.html
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--widget/tests/window_mouse_scroll_win.html1516
1 files changed, 1516 insertions, 0 deletions
diff --git a/widget/tests/window_mouse_scroll_win.html b/widget/tests/window_mouse_scroll_win.html
new file mode 100644
index 0000000000..69eca9ebb0
--- /dev/null
+++ b/widget/tests/window_mouse_scroll_win.html
@@ -0,0 +1,1516 @@
+<html lang="en-US"
+ style="font-family: Arial; font-size: 10px; line-height: 16px;">
+<head>
+ <title>Test for mouse scroll handling on Windows</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body onunload="onUnload();">
+<div id="display" style="width: 5000px; height: 5000px;">
+<p id="p1" style="font-size: 16px; width: 100px; height: 100px;">1st &lt;p&gt;.</p>
+<p id="p2" style="font-size: 32px; width: 100px; height: 100px;">2nd &lt;p&gt;.</p>
+</div>
+<script class="testbody" type="application/javascript">
+
+window.arguments[0].SimpleTest.waitForFocus(prepareTests, window);
+
+const nsIDOMWindowUtils = Ci.nsIDOMWindowUtils;
+
+const WHEEL_PAGESCROLL = 4294967295;
+
+const WM_VSCROLL = 0x0115;
+const WM_HSCROLL = 0x0114;
+const WM_MOUSEWHEEL = 0x020A;
+const WM_MOUSEHWHEEL = 0x020E;
+
+const SB_LINEUP = 0;
+const SB_LINELEFT = 0;
+const SB_LINEDOWN = 1;
+const SB_LINERIGHT = 1;
+const SB_PAGEUP = 2;
+const SB_PAGELEFT = 2;
+const SB_PAGEDOWN = 3;
+const SB_PAGERIGHT = 3;
+
+const SHIFT_L = 0x0100;
+const SHIFT_R = 0x0200;
+const CTRL_L = 0x0400;
+const CTRL_R = 0x0800;
+const ALT_L = 0x1000;
+const ALT_R = 0x2000;
+
+const DOM_PAGE_SCROLL_DELTA = 32768;
+
+const kSystemScrollSpeedOverridePref = "mousewheel.system_scroll_override.enabled";
+
+const kAltKeyActionPref = "mousewheel.with_alt.action";
+const kCtrlKeyActionPref = "mousewheel.with_control.action";
+const kShiftKeyActionPref = "mousewheel.with_shift.action";
+const kWinKeyActionPref = "mousewheel.with_win.action";
+
+const kAltKeyDeltaMultiplierXPref = "mousewheel.with_alt.delta_multiplier_x";
+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 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";
+
+const kVAxis = MouseScrollEvent.VERTICAL_AXIS;
+const kHAxis = MouseScrollEvent.HORIZONTAL_AXIS;
+
+var gLineHeight = 0;
+var gCharWidth = 0;
+var gPageHeight = 0;
+var gPageWidth = 0;
+
+var gP1 = document.getElementById("p1");
+var gP2 = document.getElementById("p2");
+
+var gOtherWindow;
+
+function ok(aCondition, aMessage) {
+ window.arguments[0].SimpleTest.ok(aCondition, aMessage);
+}
+
+function is(aLeft, aRight, aMessage) {
+ window.arguments[0].SimpleTest.is(aLeft, aRight, aMessage);
+}
+
+function isnot(aLeft, aRight, aMessage) {
+ window.arguments[0].SimpleTest.isnot(aLeft, aRight, aMessage);
+}
+
+function todo_is(aLeft, aRight, aMessage) {
+ window.arguments[0].SimpleTest.todo_is(aLeft, aRight, aMessage);
+}
+
+function onUnload() {
+ SpecialPowers.clearUserPref(kAltKeyActionPref);
+ SpecialPowers.clearUserPref(kCtrlKeyActionPref);
+ SpecialPowers.clearUserPref(kShiftKeyActionPref);
+ SpecialPowers.clearUserPref(kWinKeyActionPref);
+
+ SpecialPowers.clearUserPref(kAltKeyDeltaMultiplierXPref);
+ SpecialPowers.clearUserPref(kAltKeyDeltaMultiplierYPref);
+ SpecialPowers.clearUserPref(kCtrlKeyDeltaMultiplierXPref);
+ SpecialPowers.clearUserPref(kCtrlKeyDeltaMultiplierYPref);
+ SpecialPowers.clearUserPref(kShiftKeyDeltaMultiplierXPref);
+ SpecialPowers.clearUserPref(kShiftKeyDeltaMultiplierYPref);
+ SpecialPowers.clearUserPref(kWinKeyDeltaMultiplierXPref);
+ SpecialPowers.clearUserPref(kWinKeyDeltaMultiplierYPref);
+
+ SpecialPowers.clearUserPref(kSystemScrollSpeedOverridePref);
+ SpecialPowers.clearUserPref(kEmulateWheelByWMSCROLLPref);
+ SpecialPowers.clearUserPref(kVAmountPref);
+ SpecialPowers.clearUserPref(kHAmountPref);
+ SpecialPowers.clearUserPref(kTimeoutPref);
+ window.arguments[0].SimpleTest.finish();
+}
+
+function getWindowUtils(aWindow) {
+ if (!aWindow) {
+ aWindow = window;
+ }
+ return aWindow.windowUtils;
+}
+
+function getPointInScreen(aElement, aWindow) {
+ if (!aWindow) {
+ aWindow = window;
+ }
+ var bounds = aElement.getBoundingClientRect();
+ return { x: bounds.left + aWindow.mozInnerScreenX,
+ y: bounds.top + aWindow.mozInnerScreenY };
+}
+
+function cut(aNum) {
+ return (aNum >= 0) ? Math.floor(aNum) : Math.ceil(aNum);
+}
+
+/**
+ * Make each steps for the tests in following arrays in global scope. Each item
+ * of the arrays will be executed after previous test is finished.
+ *
+ * description:
+ * Set the description of the test. This will be used for the message of is()
+ * or the others.
+ *
+ * message:
+ * aNativeMessage of nsIDOMWindowUtils.sendNativeMouseScrollEvent().
+ * Must be WM_MOUSEWHEEL, WM_MOUSEHWHEEL, WM_VSCROLL or WM_HSCROLL.
+ *
+ * delta:
+ * The native delta value for WM_MOUSEWHEEL or WM_MOUSEHWHEEL.
+ * Or one of the SB_* const value for WM_VSCROLL or WM_HSCROLL.
+ *
+ * target:
+ * The target element, under the mouse cursor.
+ *
+ * window:
+ * The window which is used for getting nsIDOMWindowUtils.
+ *
+ * modifiers:
+ * Pressed modifier keys, 0 means no modifier key is pressed.
+ * Otherwise, one or more values of SHIFT_L, SHIFT_R, CTRL_L, CTRL_R,
+ * ALT_L or ALT_R.
+ *
+ * additionalFlags:
+ * aAdditionalFlags of nsIDOMWindowUtils.sendNativeMouseScrollEvent().
+ * See the document of nsIDOMWindowUtils for the detail of the values.
+ *
+ * onLineScrollEvent:
+ * Must be a function or null.
+ * If the value is a function, it will be called when DOMMouseScroll event
+ * is received by the synthesized event.
+ * If return true, the common checks are canceled.
+ *
+ * onPixelScrollEvent:
+ * Must be a function or null.
+ * If the value is a function, it will be called when MozMousePixelScroll
+ * event is received by the synthesized event.
+ * If return true, the common checks are canceled.
+ *
+ * expected:
+ * Must not be null and this must have:
+ * axis:
+ * kVAxis if the synthesized event causes vertical scroll. Otherwise,
+ * it causes horizontal scroll, kHAxis.
+ * lines:
+ * Integer value which is expected detail attribute value of
+ * DOMMouseScroll. If the event shouldn't be fired, must be 0.
+ * pixels:
+ * Integer value or a function which returns double value. The value is
+ * expected detail attribute value of MozMousePixelScroll.
+ * If the event shouldn't be fired, must be 0.
+ *
+ * Note that if both lines and pixels are 0, the test framework waits
+ * a few seconds. After that, go to next test.
+ *
+ * init:
+ * Must be a function or null. If this value is a function, it's called
+ * before synthesizing the native event.
+ *
+ * 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",
+ message: WM_MOUSEWHEEL, delta: -120,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ onLineScrollEvent(aEvent) {
+ return true;
+ },
+ onPixelScrollEvent(aEvent) {
+ gLineHeight = aEvent.detail;
+ return true;
+ },
+ expected: {
+ axis: kVAxis, lines: 1, pixels: 1,
+ },
+ init() {
+ SpecialPowers.setIntPref(kVAmountPref, 1);
+ SpecialPowers.setIntPref(kHAmountPref, 1);
+ },
+ },
+ { description: "Preparing gCharWidth",
+ message: WM_MOUSEHWHEEL, delta: 120,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ onLineScrollEvent(aEvent) {
+ return true;
+ },
+ onPixelScrollEvent(aEvent) {
+ gCharWidth = aEvent.detail;
+ return true;
+ },
+ expected: {
+ axis: kVAxis, lines: 1, pixels: 1,
+ },
+ },
+ { description: "Preparing gPageHeight",
+ message: WM_MOUSEWHEEL, delta: -120,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ onLineScrollEvent(aEvent) {
+ return true;
+ },
+ onPixelScrollEvent(aEvent) {
+ gPageHeight = aEvent.detail;
+ return true;
+ },
+ expected: {
+ axis: kHAxis, lines: 1, pixels: 1,
+ },
+ init() {
+ SpecialPowers.setIntPref(kVAmountPref, 0xFFFF);
+ SpecialPowers.setIntPref(kHAmountPref, 0xFFFF);
+ },
+ },
+ { description: "Preparing gPageWidth",
+ message: WM_MOUSEHWHEEL, delta: 120,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ onLineScrollEvent(aEvent) {
+ return true;
+ },
+ onPixelScrollEvent(aEvent) {
+ gPageWidth = aEvent.detail;
+ return true;
+ },
+ expected: {
+ axis: kHAxis, lines: 1, pixels: 1,
+ },
+ finish() {
+ 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);
+
+ ok(gPageHeight > gLineHeight,
+ "gPageHeight must be larger than gLineHeight");
+ ok(gPageWidth > gCharWidth,
+ "gPageWidth must be larger than gCharWidth");
+ runNextTest(gBasicTests, 0);
+ },
+ },
+];
+
+var gBasicTests = [
+ // 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",
+ message: WM_MOUSEWHEEL, delta: -120,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 3, pixels() { return gLineHeight * 3; },
+ },
+ init() {
+ SpecialPowers.setIntPref(kVAmountPref, 3);
+ SpecialPowers.setIntPref(kHAmountPref, 3);
+ },
+ },
+
+ { description: "WM_MOUSEWHEEL, 120, -3 lines",
+ message: WM_MOUSEWHEEL, delta: 120,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: -3, pixels() { return gLineHeight * -3; },
+ },
+ },
+
+ { description: "WM_MOUSEHWHEEL, 120, 3 chars",
+ message: WM_MOUSEHWHEEL, delta: 120,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 3, pixels() { return gCharWidth * 3; },
+ },
+ },
+
+ { description: "WM_MOUSEHWHEEL, -120, -3 chars",
+ message: WM_MOUSEHWHEEL, delta: -120,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: -3, pixels() { return gCharWidth * -3; },
+ },
+ },
+
+ // 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,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 0, pixels() { 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,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 1, pixels() { return gLineHeight / 2; },
+ },
+ },
+ { description: "WM_MOUSEWHEEL, -20, 0.5 lines",
+ message: WM_MOUSEWHEEL, delta: -20,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 0, pixels() { 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,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 0, pixels() { 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,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: -1, pixels() { return -gLineHeight / 2; },
+ },
+ },
+ { description: "WM_MOUSEWHEEL, 20, -0.5 lines",
+ message: WM_MOUSEWHEEL, delta: 20,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 0, pixels() { return gLineHeight / -2; },
+ },
+ },
+
+ { description: "WM_MOUSEHWHEEL, 20, 0.5 chars",
+ message: WM_MOUSEHWHEEL, delta: 20,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 0, pixels() { return gCharWidth / 2; },
+ },
+ },
+ { description: "WM_MOUSEHWHEEL, 20, 0.5 chars (pending: 0.5 chars)",
+ message: WM_MOUSEHWHEEL, delta: 20,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 1, pixels() { return gCharWidth / 2; },
+ },
+ },
+ { description: "WM_MOUSEHWHEEL, 20, 0.5 chars",
+ message: WM_MOUSEHWHEEL, delta: 20,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 0, pixels() { return gCharWidth / 2; },
+ },
+ },
+
+ { description: "WM_MOUSEHWHEEL, -20, -0.5 chars (pending: 0.5 chars)",
+ message: WM_MOUSEHWHEEL, delta: -20,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 0, pixels() { return gCharWidth / -2; },
+ },
+ },
+ { description: "WM_MOUSEHWHEEL, -20, -0.5 chars (pending: -0.5 chars)",
+ message: WM_MOUSEHWHEEL, delta: -20,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: -1, pixels() { return -gCharWidth / 2; },
+ },
+ },
+ { description: "WM_MOUSEHWHEEL, -20, -0.5 chars",
+ message: WM_MOUSEHWHEEL, delta: -20,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 0, pixels() { return gCharWidth / -2; },
+ },
+ },
+
+ // 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,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 3, pixels() { return gLineHeight * 3; },
+ },
+ },
+
+ { 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,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: -3, pixels() { return gLineHeight * -3; },
+ },
+ },
+
+ { description: "WM_MOUSEHWHEEL, 120, 3 chars, on the other div whose font-size is larger",
+ message: WM_MOUSEHWHEEL, delta: 120,
+ target: gP2, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 3, pixels() { return gCharWidth * 3; },
+ },
+ },
+
+ { description: "WM_MOUSEHWHEEL, -120, -3 chars, on the other div whose font-size is larger",
+ message: WM_MOUSEHWHEEL, delta: -120,
+ target: gP2, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: -3, pixels() { return gCharWidth * -3; },
+ },
+ },
+
+ // Modifier key tests
+ { description: "WM_MOUSEWHEEL, -40, 1 line with left Shift",
+ message: WM_MOUSEWHEEL, delta: -40,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: SHIFT_L,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 1, pixels() { return gLineHeight; },
+ },
+ },
+ { description: "WM_MOUSEWHEEL, -40, 1 line with right Shift",
+ message: WM_MOUSEWHEEL, delta: -40,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: SHIFT_R,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 1, pixels() { return gLineHeight; },
+ },
+ },
+ { description: "WM_MOUSEWHEEL, -40, 1 line with left Ctrl",
+ message: WM_MOUSEWHEEL, delta: -40,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: CTRL_L,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 1, pixels() { return gLineHeight; },
+ },
+ },
+ { description: "WM_MOUSEWHEEL, -40, 1 line with right Ctrl",
+ message: WM_MOUSEWHEEL, delta: -40,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: CTRL_R,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 1, pixels() { return gLineHeight; },
+ },
+ },
+ { description: "WM_MOUSEWHEEL, -40, 1 line with left Alt",
+ message: WM_MOUSEWHEEL, delta: -40,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: ALT_L,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 1, pixels() { return gLineHeight; },
+ },
+ },
+ { description: "WM_MOUSEWHEEL, -40, 1 line with right Alt",
+ message: WM_MOUSEWHEEL, delta: -40,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: ALT_R,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 1, pixels() { return gLineHeight; },
+ },
+ },
+
+ { description: "WM_MOUSEHWHEEL, 40, 1 character with left Shift",
+ message: WM_MOUSEHWHEEL, delta: 40,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: SHIFT_L,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 1, pixels() { return gCharWidth; },
+ },
+ },
+ { description: "WM_MOUSEHWHEEL, 40, 1 character with right Shift",
+ message: WM_MOUSEHWHEEL, delta: 40,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: SHIFT_R,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 1, pixels() { return gCharWidth; },
+ },
+ },
+ { description: "WM_MOUSEHWHEEL, 40, 1 character with left Ctrl",
+ message: WM_MOUSEHWHEEL, delta: 40,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: CTRL_L,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 1, pixels() { return gCharWidth; },
+ },
+ },
+ { description: "WM_MOUSEHWHEEL, 40, 1 character with right Ctrl",
+ message: WM_MOUSEHWHEEL, delta: 40,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: CTRL_R,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 1, pixels() { return gCharWidth; },
+ },
+ },
+ { description: "WM_MOUSEHWHEEL, 40, 1 character with left Alt",
+ message: WM_MOUSEHWHEEL, delta: 40,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: ALT_L,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 1, pixels() { return gCharWidth; },
+ },
+ },
+ { description: "WM_MOUSEHWHEEL, 40, 1 character with right Alt",
+ message: WM_MOUSEHWHEEL, delta: 40,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: ALT_R,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 1, pixels() { return gCharWidth; },
+ },
+
+ finish() {
+ runNextTest(gScrollMessageTests, 0);
+ },
+ },
+];
+
+var gPageScrllTests = [
+ // 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,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 0, pixels() { return gPageHeight / 2; },
+ },
+ },
+ { description: "WM_MOUSEWHEEL, -60, 0.5 pages (pending: 0.5 pages)",
+ message: WM_MOUSEWHEEL, delta: -60,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: DOM_PAGE_SCROLL_DELTA,
+ pixels() { return ((gPageHeight / 2) + (gPageHeight % 2)); },
+ },
+ },
+ { description: "WM_MOUSEWHEEL, -60, 0.5 pages",
+ message: WM_MOUSEWHEEL, delta: -60,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 0, pixels() { return gPageHeight / 2; },
+ },
+ },
+
+ { description: "WM_MOUSEWHEEL, 60, -0.5 pages (pending: 0.5 pages)",
+ message: WM_MOUSEWHEEL, delta: 60,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 0, pixels() { return gPageHeight / -2; },
+ },
+ },
+ { description: "WM_MOUSEWHEEL, 60, -0.5 pages (pending: -0.5 pages)",
+ message: WM_MOUSEWHEEL, delta: 60,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: -DOM_PAGE_SCROLL_DELTA,
+ pixels() { return -((gPageHeight / 2) + (gPageHeight % 2)); },
+ },
+ },
+ { description: "WM_MOUSEWHEEL, 60, -0.5 pages",
+ message: WM_MOUSEWHEEL, delta: 60,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 0, pixels() { return gPageHeight / -2; },
+ },
+ },
+
+ { description: "WM_MOUSEHWHEEL, 60, 0.5 pages",
+ message: WM_MOUSEHWHEEL, delta: 60,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 0, pixels() { return gPageWidth / 2; },
+ },
+ },
+ { description: "WM_MOUSEHWHEEL, 60, 0.5 pages (pending: 0.5 pages)",
+ message: WM_MOUSEHWHEEL, delta: 60,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: DOM_PAGE_SCROLL_DELTA,
+ pixels() { return ((gPageWidth / 2) + (gPageWidth % 2)); },
+ },
+ },
+ { description: "WM_MOUSEHWHEEL, 60, 0.5 pages",
+ message: WM_MOUSEHWHEEL, delta: 60,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 0, pixels() { return gPageWidth / 2; },
+ },
+ },
+
+ { description: "WM_MOUSEHWHEEL, -60, -0.5 pages (pending: 0.5 pages)",
+ message: WM_MOUSEHWHEEL, delta: -60,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 0, pixels() { return gCharWidth / -2; },
+ },
+ },
+ { description: "WM_MOUSEHWHEEL, -60, -0.5 pages (pending: -0.5 pages)",
+ message: WM_MOUSEHWHEEL, delta: -60,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: -DOM_PAGE_SCROLL_DELTA,
+ pixels() { return -((gCharWidth / 2) + (gCharWidth % 2)); },
+ },
+ },
+ { description: "WM_MOUSEHWHEEL, -60, -0.5 pages",
+ message: WM_MOUSEHWHEEL, delta: -60,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 0, pixels() { return gCharWidth / -2; },
+ },
+ },
+];
+
+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,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 0, pixels: 0,
+ },
+ init() {
+ SpecialPowers.setIntPref(kVAmountPref, 3);
+ SpecialPowers.setIntPref(kHAmountPref, 3);
+ SpecialPowers.setBoolPref(kEmulateWheelByWMSCROLLPref, false);
+ },
+ },
+
+ { description: "WM_VSCROLL, SB_LINEUP, lParam is NULL, emulation disabled",
+ message: WM_VSCROLL, delta: SB_LINEUP,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 0, pixels: 0,
+ },
+ },
+
+ { description: "WM_HSCROLL, SB_LINERIGHT, lParam is NULL, emulation disabled",
+ message: WM_HSCROLL, delta: SB_LINERIGHT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 0, pixels: 0,
+ },
+ },
+
+ { description: "WM_HSCROLL, SB_LINELEFT, lParam is NULL, emulation disabled",
+ message: WM_HSCROLL, delta: SB_LINELEFT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 0, pixels: 0,
+ },
+ },
+
+ // Widget should emulate mouse wheel behavior for WM_*SCROLL even if the
+ // kEmulateWheelByWMSCROLLPref is disabled but the message's lParam is not
+ // NULL. Then, widget doesn't dispatch a pixel event for WM_*SCROLL messages,
+ // but ESM dispatches it instead.
+ { description: "WM_VSCROLL, SB_LINEUP, lParam is not NULL, emulation disabled",
+ message: WM_VSCROLL, delta: SB_LINEUP,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kVAxis, lines: -1, pixels() { return -gLineHeight; },
+ },
+ init() {
+ SpecialPowers.setBoolPref(kEmulateWheelByWMSCROLLPref, false);
+ },
+ },
+
+ { description: "WM_VSCROLL, SB_LINEDOWN, lParam is not NULL, emulation disabled",
+ message: WM_VSCROLL, delta: SB_LINEDOWN,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kVAxis, lines: 1, pixels() { return gLineHeight; },
+ },
+ },
+
+ { description: "WM_HSCROLL, SB_LINELEFT, lParam is not NULL, emulation disabled",
+ message: WM_HSCROLL, delta: SB_LINELEFT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kHAxis, lines: -1, pixels() { return -gCharWidth; },
+ },
+ },
+
+ { description: "WM_HSCROLL, SB_LINERIGHT, lParam is not NULL, emulation disabled",
+ message: WM_HSCROLL, delta: SB_LINERIGHT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kHAxis, lines: 1, pixels() { return gCharWidth; },
+ },
+ },
+
+ { description: "WM_VSCROLL, SB_PAGEUP, lParam is not NULL, emulation disabled",
+ message: WM_VSCROLL, delta: SB_PAGEUP,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kVAxis, lines: -DOM_PAGE_SCROLL_DELTA,
+ pixels() { return -gPageHeight; },
+ },
+ },
+
+ { description: "WM_VSCROLL, SB_PAGEDOWN, lParam is not NULL, emulation disabled",
+ message: WM_VSCROLL, delta: SB_PAGEDOWN,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kVAxis, lines: DOM_PAGE_SCROLL_DELTA,
+ pixels() { return gPageHeight; },
+ },
+ },
+
+ { description: "WM_HSCROLL, SB_PAGELEFT, lParam is not NULL, emulation disabled",
+ message: WM_HSCROLL, delta: SB_PAGELEFT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kHAxis, lines: -DOM_PAGE_SCROLL_DELTA,
+ pixels() { return -gPageWidth; },
+ },
+ },
+
+ { description: "WM_HSCROLL, SB_PAGERIGHT, lParam is not NULL, emulation disabled",
+ message: WM_HSCROLL, delta: SB_PAGERIGHT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kHAxis, lines: DOM_PAGE_SCROLL_DELTA,
+ pixels() { return gPageWidth; },
+ },
+ },
+
+ // Widget should emulate mouse wheel behavior for WM_*SCROLL when the
+ // kEmulateWheelByWMSCROLLPref is enabled even if the message's lParam is
+ // NULL. Then, widget doesn't dispatch a pixel event for WM_*SCROLL messages,
+ // but ESM dispatches it instead.
+ { description: "WM_VSCROLL, SB_LINEUP, lParam is NULL, emulation enabled",
+ message: WM_VSCROLL, delta: SB_LINEUP,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: -1, pixels() { return -gLineHeight; },
+ },
+ init() {
+ SpecialPowers.setBoolPref(kEmulateWheelByWMSCROLLPref, true);
+ },
+ },
+
+ { description: "WM_VSCROLL, SB_LINEDOWN, lParam is NULL, emulation enabled",
+ message: WM_VSCROLL, delta: SB_LINEDOWN,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 1, pixels() { return gLineHeight; },
+ },
+ },
+
+ { description: "WM_HSCROLL, SB_LINELEFT, lParam is NULL, emulation enabled",
+ message: WM_HSCROLL, delta: SB_LINELEFT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: -1, pixels() { return -gCharWidth; },
+ },
+ },
+
+ { description: "WM_HSCROLL, SB_LINERIGHT, lParam is NULL, emulation enabled",
+ message: WM_HSCROLL, delta: SB_LINERIGHT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 1, pixels() { return gCharWidth; },
+ },
+ },
+
+ { description: "WM_VSCROLL, SB_PAGEUP, lParam is NULL, emulation enabled",
+ message: WM_VSCROLL, delta: SB_PAGEUP,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: -DOM_PAGE_SCROLL_DELTA,
+ pixels() { return -gPageHeight; },
+ },
+ },
+
+ { description: "WM_VSCROLL, SB_PAGEDOWN, lParam is NULL, emulation enabled",
+ message: WM_VSCROLL, delta: SB_PAGEDOWN,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: DOM_PAGE_SCROLL_DELTA,
+ pixels() { return gPageHeight; },
+ },
+ },
+
+ { description: "WM_HSCROLL, SB_PAGELEFT, lParam is NULL, emulation enabled",
+ message: WM_HSCROLL, delta: SB_PAGELEFT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: -DOM_PAGE_SCROLL_DELTA,
+ pixels() { return -gPageWidth; },
+ },
+ },
+
+ { description: "WM_HSCROLL, SB_PAGERIGHT, lParam is NULL, emulation enabled",
+ message: WM_HSCROLL, delta: SB_PAGERIGHT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: DOM_PAGE_SCROLL_DELTA,
+ pixels() { return gPageWidth; },
+ },
+ },
+
+ // Modifier key tests for WM_*SCROLL
+ { description: "WM_VSCROLL, SB_LINEDOWN, lParam is not NULL, emulation disabled, with left Shift",
+ message: WM_VSCROLL, delta: SB_LINEDOWN,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: SHIFT_L,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kVAxis, lines: 1, pixels() { return gLineHeight; },
+ },
+ init() {
+ SpecialPowers.setBoolPref(kEmulateWheelByWMSCROLLPref, false);
+ },
+ },
+ { description: "WM_VSCROLL, SB_LINEDOWN, lParam is not NULL, emulation disabled, with right Shift",
+ message: WM_VSCROLL, delta: SB_LINEDOWN,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: SHIFT_R,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kVAxis, lines: 1, pixels() { return gLineHeight; },
+ },
+ },
+ { description: "WM_VSCROLL, SB_LINEDOWN, lParam is not NULL, emulation disabled, with left Ctrl",
+ message: WM_VSCROLL, delta: SB_LINEDOWN,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: CTRL_L,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kVAxis, lines: 1, pixels() { return gLineHeight; },
+ },
+ },
+ { description: "WM_VSCROLL, SB_LINEDOWN, lParam is not NULL, emulation disabled, with right Ctrl",
+ message: WM_VSCROLL, delta: SB_LINEDOWN,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: CTRL_L,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kVAxis, lines: 1, pixels() { return gLineHeight; },
+ },
+ },
+ { description: "WM_VSCROLL, SB_LINEDOWN, lParam is not NULL, emulation disabled, with left Alt",
+ message: WM_VSCROLL, delta: SB_LINEDOWN,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: ALT_L,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kVAxis, lines: 1, pixels() { return gLineHeight; },
+ },
+ },
+ { description: "WM_VSCROLL, SB_LINEDOWN, lParam is not NULL, emulation disabled, with right Alt",
+ message: WM_VSCROLL, delta: SB_LINEDOWN,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: ALT_R,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kVAxis, lines: 1, pixels() { return gLineHeight; },
+ },
+ },
+
+ { description: "WM_HSCROLL, SB_LINERIGHT, lParam is not NULL, emulation disabled, with left Shift",
+ message: WM_HSCROLL, delta: SB_LINERIGHT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: SHIFT_L,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kHAxis, lines: 1, pixels() { return gCharWidth; },
+ },
+ },
+ { description: "WM_HSCROLL, SB_LINERIGHT, lParam is not NULL, emulation disabled, with right Shift",
+ message: WM_HSCROLL, delta: SB_LINERIGHT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: SHIFT_R,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kHAxis, lines: 1, pixels() { return gCharWidth; },
+ },
+ },
+ { description: "WM_HSCROLL, SB_LINERIGHT, lParam is not NULL, emulation disabled, with left Ctrl",
+ message: WM_HSCROLL, delta: SB_LINERIGHT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: CTRL_L,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kHAxis, lines: 1, pixels() { return gCharWidth; },
+ },
+ },
+ { description: "WM_HSCROLL, SB_LINERIGHT, lParam is not NULL, emulation disabled, with right Ctrl",
+ message: WM_HSCROLL, delta: SB_LINERIGHT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: CTRL_L,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kHAxis, lines: 1, pixels() { return gCharWidth; },
+ },
+ },
+ { description: "WM_HSCROLL, SB_LINERIGHT, lParam is not NULL, emulation disabled, with left Alt",
+ message: WM_HSCROLL, delta: SB_LINERIGHT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: ALT_L,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kHAxis, lines: 1, pixels() { return gCharWidth; },
+ },
+ },
+ { description: "WM_HSCROLL, SB_LINERIGHT, lParam is not NULL, emulation disabled, with right Alt",
+ message: WM_HSCROLL, delta: SB_LINERIGHT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: ALT_R,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kHAxis, lines: 1, pixels() { return gCharWidth; },
+ },
+
+ finish() {
+ runDeactiveWindowTests();
+ },
+ },
+];
+
+var gDeactiveWindowTests = [
+ // Typically, mouse drivers send wheel messages to focused window.
+ // However, we prefer to scroll a scrollable element under the mouse cursor.
+ { description: "WM_MOUSEWHEEL, -120, 3 lines, window is deactive",
+ message: WM_MOUSEWHEEL, delta: -120,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 3, pixels() { return gLineHeight * 3; },
+ },
+ init() {
+ SpecialPowers.setIntPref(kVAmountPref, 3);
+ SpecialPowers.setIntPref(kHAmountPref, 3);
+ },
+ onLineScrollEvent(aEvent) {
+ var fm = Services.focus;
+ is(fm.activeWindow, gOtherWindow, "The other window isn't activated");
+ },
+ },
+
+ { description: "WM_MOUSEWHEEL, 120, -3 lines, window is deactive",
+ message: WM_MOUSEWHEEL, delta: 120,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: -3, pixels() { return gLineHeight * -3; },
+ },
+ },
+
+ { description: "WM_MOUSEHWHEEL, 120, 3 chars, window is deactive",
+ message: WM_MOUSEHWHEEL, delta: 120,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 3, pixels() { return gCharWidth * 3; },
+ },
+ },
+
+ { description: "WM_MOUSEHWHEEL, -120, -3 chars, window is deactive",
+ message: WM_MOUSEHWHEEL, delta: -120,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: -3, pixels() { return gCharWidth * -3; },
+ },
+ },
+
+ // Of course, even if some drivers prefer the cursor position, we don't need
+ // to change anything.
+ { description: "WM_MOUSEWHEEL, -120, 3 lines, window is deactive (receive the message directly)",
+ message: WM_MOUSEWHEEL, delta: -120,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_PREFER_WIDGET_AT_POINT,
+ expected: {
+ axis: kVAxis, lines: 3, pixels() { return gLineHeight * 3; },
+ },
+ },
+
+ { description: "WM_MOUSEWHEEL, 120, -3 lines, window is deactive (receive the message directly)",
+ message: WM_MOUSEWHEEL, delta: 120,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_PREFER_WIDGET_AT_POINT,
+ expected: {
+ axis: kVAxis, lines: -3, pixels() { return gLineHeight * -3; },
+ },
+ },
+
+ { description: "WM_MOUSEHWHEEL, 120, 3 chars, window is deactive (receive the message directly)",
+ message: WM_MOUSEHWHEEL, delta: 120,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_PREFER_WIDGET_AT_POINT,
+ expected: {
+ axis: kHAxis, lines: 3, pixels() { return gCharWidth * 3; },
+ },
+ },
+
+ { description: "WM_MOUSEHWHEEL, -120, -3 chars, window is deactive (receive the message directly)",
+ message: WM_MOUSEHWHEEL, delta: -120,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_PREFER_WIDGET_AT_POINT,
+ expected: {
+ axis: kHAxis, lines: -3, pixels() { return gCharWidth * -3; },
+ },
+ },
+
+ // Same for WM_*SCROLL if lParam is not NULL
+ { description: "WM_VSCROLL, SB_LINEUP, lParam is not NULL, emulation disabled, window is deactive",
+ message: WM_VSCROLL, delta: SB_LINEUP,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kVAxis, lines: -1, pixels() { return -gLineHeight; },
+ },
+ init() {
+ SpecialPowers.setBoolPref(kEmulateWheelByWMSCROLLPref, false);
+ },
+ },
+
+ { description: "WM_VSCROLL, SB_LINEDOWN, lParam is not NULL, emulation disabled, window is deactive",
+ message: WM_VSCROLL, delta: SB_LINEDOWN,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kVAxis, lines: 1, pixels() { return gLineHeight; },
+ },
+ },
+
+ { description: "WM_HSCROLL, SB_LINELEFT, lParam is not NULL, emulation disabled, window is deactive",
+ message: WM_HSCROLL, delta: SB_LINELEFT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kHAxis, lines: -1, pixels() { return -gCharWidth; },
+ },
+ },
+
+ { description: "WM_HSCROLL, SB_LINERIGHT, lParam is not NULL, emulation disabled, window is deactive",
+ message: WM_HSCROLL, delta: SB_LINERIGHT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL,
+ expected: {
+ axis: kHAxis, lines: 1, pixels() { return gCharWidth; },
+ },
+ },
+
+ // Same for WM_*SCROLL if lParam is NULL but emulation is enabled
+ { description: "WM_VSCROLL, SB_LINEUP, lParam is NULL, emulation enabled, window is deactive",
+ message: WM_VSCROLL, delta: SB_LINEUP,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: -1, pixels() { return -gLineHeight; },
+ },
+ init() {
+ SpecialPowers.setBoolPref(kEmulateWheelByWMSCROLLPref, true);
+ },
+ },
+
+ { description: "WM_VSCROLL, SB_LINEDOWN, lParam is NULL, emulation enabled, window is deactive",
+ message: WM_VSCROLL, delta: SB_LINEDOWN,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kVAxis, lines: 1, pixels() { return gLineHeight; },
+ },
+ },
+
+ { description: "WM_HSCROLL, SB_LINELEFT, lParam is NULL, emulation enabled, window is deactive",
+ message: WM_HSCROLL, delta: SB_LINELEFT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: -1, pixels() { return -gCharWidth; },
+ },
+ },
+
+ { description: "WM_HSCROLL, SB_LINERIGHT, lParam is NULL, emulation enabled, window is deactive",
+ message: WM_HSCROLL, delta: SB_LINERIGHT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: 0,
+ expected: {
+ axis: kHAxis, lines: 1, pixels() { return gCharWidth; },
+ },
+ },
+
+ // Same for WM_*SCROLL if lParam is not NULL and message sent to the deactive window directly
+ { description: "WM_VSCROLL, SB_LINEUP, lParam is not NULL, emulation disabled, window is deactive (receive the message directly)",
+ message: WM_VSCROLL, delta: SB_LINEUP,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL |
+ nsIDOMWindowUtils.MOUSESCROLL_PREFER_WIDGET_AT_POINT,
+ expected: {
+ axis: kVAxis, lines: -1, pixels() { return -gLineHeight; },
+ },
+ init() {
+ SpecialPowers.setBoolPref(kEmulateWheelByWMSCROLLPref, false);
+ },
+ },
+
+ { description: "WM_VSCROLL, SB_LINEDOWN, lParam is not NULL, emulation disabled, window is deactive (receive the message directly)",
+ message: WM_VSCROLL, delta: SB_LINEDOWN,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL |
+ nsIDOMWindowUtils.MOUSESCROLL_PREFER_WIDGET_AT_POINT,
+ expected: {
+ axis: kVAxis, lines: 1, pixels() { return gLineHeight; },
+ },
+ },
+
+ { description: "WM_HSCROLL, SB_LINELEFT, lParam is not NULL, emulation disabled, window is deactive (receive the message directly)",
+ message: WM_HSCROLL, delta: SB_LINELEFT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL |
+ nsIDOMWindowUtils.MOUSESCROLL_PREFER_WIDGET_AT_POINT,
+ expected: {
+ axis: kHAxis, lines: -1, pixels() { return -gCharWidth; },
+ },
+ },
+
+ { description: "WM_HSCROLL, SB_LINERIGHT, lParam is not NULL, emulation disabled, window is deactive (receive the message directly)",
+ message: WM_HSCROLL, delta: SB_LINERIGHT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_WIN_SCROLL_LPARAM_NOT_NULL |
+ nsIDOMWindowUtils.MOUSESCROLL_PREFER_WIDGET_AT_POINT,
+ expected: {
+ axis: kHAxis, lines: 1, pixels() { return gCharWidth; },
+ },
+ },
+
+ // Same for WM_*SCROLL if lParam is NULL but emulation is enabled, and message sent to the deactive window directly
+ { description: "WM_VSCROLL, SB_LINEUP, lParam is NULL, emulation enabled, window is deactive (receive the message directly)",
+ message: WM_VSCROLL, delta: SB_LINEUP,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_PREFER_WIDGET_AT_POINT,
+ expected: {
+ axis: kVAxis, lines: -1, pixels() { return -gLineHeight; },
+ },
+ init() {
+ SpecialPowers.setBoolPref(kEmulateWheelByWMSCROLLPref, true);
+ },
+ },
+
+ { description: "WM_VSCROLL, SB_LINEDOWN, lParam is NULL, emulation enabled, window is deactive (receive the message directly)",
+ message: WM_VSCROLL, delta: SB_LINEDOWN,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_PREFER_WIDGET_AT_POINT,
+ expected: {
+ axis: kVAxis, lines: 1, pixels() { return gLineHeight; },
+ },
+ },
+
+ { description: "WM_HSCROLL, SB_LINELEFT, lParam is NULL, emulation enabled, window is deactive (receive the message directly)",
+ message: WM_HSCROLL, delta: SB_LINELEFT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_PREFER_WIDGET_AT_POINT,
+ expected: {
+ axis: kHAxis, lines: -1, pixels() { return -gCharWidth; },
+ },
+ },
+
+ { description: "WM_HSCROLL, SB_LINERIGHT, lParam is NULL, emulation enabled, window is deactive (receive the message directly)",
+ message: WM_HSCROLL, delta: SB_LINERIGHT,
+ target: gP1, x: 10, y: 10, window,
+ modifiers: 0,
+ additionalFlags: nsIDOMWindowUtils.MOUSESCROLL_PREFER_WIDGET_AT_POINT,
+ expected: {
+ axis: kHAxis, lines: 1, pixels() { return gCharWidth; },
+ },
+
+ finish() {
+ gOtherWindow.close();
+ gOtherWindow = null;
+ window.close();
+ },
+ },
+];
+
+function runDeactiveWindowTests() {
+ gOtherWindow = window.open("window_mouse_scroll_win_2.html", "_blank",
+ "chrome,width=100,height=100,top=700,left=700");
+
+ window.arguments[0].SimpleTest.waitForFocus(function() {
+ runNextTest(gDeactiveWindowTests, 0);
+ }, gOtherWindow);
+}
+
+function runNextTest(aTests, aIndex) {
+ if (aIndex > 0 && aTests[aIndex - 1] && aTests[aIndex - 1].finish) {
+ aTests[aIndex - 1].finish();
+ }
+
+ if (aTests.length == aIndex) {
+ return;
+ }
+
+ var test = aTests[aIndex++];
+ if (test.init) {
+ test.init();
+ }
+ test.handled = { lines: false, pixels: false };
+
+ switch (test.message) {
+ case WM_MOUSEWHEEL:
+ case WM_MOUSEHWHEEL:
+ case WM_VSCROLL:
+ case WM_HSCROLL:
+ var expectedLines = test.expected.lines;
+ var expectedPixels =
+ cut((typeof test.expected.pixels == "function") ?
+ test.expected.pixels() : test.expected.pixels);
+ var handler = function(aEvent) {
+ var doCommonTests = true;
+
+ if (!aEvent) {
+ ok(!test.handled.lines,
+ test.description + ", line scroll event has been handled");
+ ok(!test.handled.pixels,
+ test.description + ", pixel scroll event has been handled");
+ doCommonTests = false;
+ } else if (aEvent.type == kMouseLineScrollEvent) {
+ ok(!test.handled.lines,
+ test.description + ":(" + aEvent.type + "), same event has already been handled");
+ test.handled.lines = true;
+ isnot(expectedLines, 0,
+ test.description + ":(" + aEvent.type + "), event shouldn't be fired");
+ if (test.onLineScrollEvent && test.onLineScrollEvent(aEvent)) {
+ doCommonTests = false;
+ }
+ } else if (aEvent.type == kMousePixelScrollEvent) {
+ ok(!test.handled.pixels,
+ test.description + ":(" + aEvent.type + "), same event has already been handled");
+ test.handled.pixels = true;
+ isnot(expectedPixels, 0,
+ test.description + ":(" + aEvent.type + "), event shouldn't be fired");
+ if (test.onPixelScrollEvent && test.onPixelScrollEvent(aEvent)) {
+ doCommonTests = false;
+ }
+ }
+
+ if (doCommonTests) {
+ var expectedDelta =
+ (aEvent.type == kMouseLineScrollEvent) ?
+ expectedLines : expectedPixels;
+ is(aEvent.target.id, test.target.id,
+ test.description + ":(" + aEvent.type + "), ID mismatch");
+ is(aEvent.axis, test.expected.axis,
+ test.description + ":(" + aEvent.type + "), axis mismatch");
+ ok(aEvent.detail != 0,
+ test.description + ":(" + aEvent.type + "), delta must not be 0");
+ is(aEvent.detail, expectedDelta,
+ test.description + ":(" + aEvent.type + "), delta mismatch");
+ is(aEvent.shiftKey, (test.modifiers & (SHIFT_L | SHIFT_R)) != 0,
+ test.description + ":(" + aEvent.type + "), shiftKey mismatch");
+ is(aEvent.ctrlKey, (test.modifiers & (CTRL_L | CTRL_R)) != 0,
+ test.description + ":(" + aEvent.type + "), ctrlKey mismatch");
+ is(aEvent.altKey, (test.modifiers & (ALT_L | ALT_R)) != 0,
+ test.description + ":(" + aEvent.type + "), altKey mismatch");
+ }
+
+ if (!aEvent || (test.handled.lines || expectedLines == 0) &&
+ (test.handled.pixels || expectedPixels == 0)) {
+ // Don't scroll actually.
+ if (aEvent) {
+ aEvent.preventDefault();
+ }
+ test.target.removeEventListener(kMouseLineScrollEvent, handler, true);
+ test.target.removeEventListener(kMousePixelScrollEvent, handler, true);
+ setTimeout(runNextTest, 0, aTests, aIndex);
+ }
+ };
+
+ test.target.addEventListener(kMouseLineScrollEvent, handler, true);
+ test.target.addEventListener(kMousePixelScrollEvent, handler, true);
+
+ if (expectedLines == 0 && expectedPixels == 0) {
+ // The timeout might not be enough if system is slow by other process,
+ // so, the test might be passed unexpectedly. However, it must be able
+ // to be detected by random orange.
+ setTimeout(handler, 500);
+ }
+
+ var utils = getWindowUtils(test.window);
+ var ptInScreen = getPointInScreen(test.target, test.window);
+ var isVertical =
+ ((test.message == WM_MOUSEWHEEL) || (test.message == WM_VSCROLL));
+ var deltaX = !isVertical ? test.delta : 0;
+ var deltaY = isVertical ? test.delta : 0;
+ utils.sendNativeMouseScrollEvent(ptInScreen.x + test.x,
+ ptInScreen.y + test.y,
+ test.message, deltaX, deltaY, 0,
+ test.modifiers,
+ test.additionalFlags,
+ test.target);
+ break;
+ default:
+ ok(false, test.description + ": invalid message");
+ // Let's timeout.
+ }
+}
+
+function prepareTests() {
+ // Disable special action with modifier key
+ SpecialPowers.setIntPref(kAltKeyActionPref, 1);
+ SpecialPowers.setIntPref(kCtrlKeyActionPref, 1);
+ SpecialPowers.setIntPref(kShiftKeyActionPref, 1);
+ SpecialPowers.setIntPref(kWinKeyActionPref, 1);
+
+ SpecialPowers.setIntPref(kAltKeyDeltaMultiplierXPref, 100);
+ SpecialPowers.setIntPref(kAltKeyDeltaMultiplierYPref, 100);
+ 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.setIntPref(kTimeoutPref, -1);
+
+ runNextTest(gPreparingSteps, 0);
+}
+
+</script>
+</body>
+
+</html>