summaryrefslogtreecommitdiffstats
path: root/widget/tests/native_mouse_mac_window.xul
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /widget/tests/native_mouse_mac_window.xul
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'widget/tests/native_mouse_mac_window.xul')
-rw-r--r--widget/tests/native_mouse_mac_window.xul773
1 files changed, 773 insertions, 0 deletions
diff --git a/widget/tests/native_mouse_mac_window.xul b/widget/tests/native_mouse_mac_window.xul
new file mode 100644
index 000000000..8680c3b1a
--- /dev/null
+++ b/widget/tests/native_mouse_mac_window.xul
@@ -0,0 +1,773 @@
+<?xml version="1.0"?>
+
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+
+<window id="NativeMenuWindow"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ width="600"
+ height="600"
+ title="Native Mouse Event Test"
+ orient="vertical">
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+
+ <box height="200" id="box"/>
+ <menupopup id="popup" width="250" height="50"/>
+ <panel id="panel" width="250" height="50" noautohide="true"/>
+
+ <script type="application/javascript"><![CDATA[
+
+ function ok(condition, message) {
+ window.opener.wrappedJSObject.SimpleTest.ok(condition, message);
+ }
+
+ function is(a, b, message) {
+ window.opener.wrappedJSObject.SimpleTest.is(a, b, message);
+ }
+
+ function todo(condition, message) {
+ window.opener.wrappedJSObject.SimpleTest.todo(condition, message);
+ }
+
+ function todo_is(a, b, message) {
+ window.opener.wrappedJSObject.SimpleTest.todo_is(a, b, message);
+ }
+
+ function onTestsFinished() {
+ clearTimeout(gAfterLoopExecution);
+ observe(window, eventMonitor, false);
+ observe(gRightWindow, eventMonitor, false);
+ observe(gPopup, eventMonitor, false);
+ gRightWindow.close();
+ var openerSimpleTest = window.opener.wrappedJSObject.SimpleTest;
+ window.close();
+ openerSimpleTest.finish();
+ }
+
+ const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+ const xulWin = 'data:application/vnd.mozilla.xul+xml,<?xml version="1.0"?><?xml-stylesheet href="chrome://global/skin" type="text/css"?><window xmlns="' + XUL_NS + '"/>';
+
+ const NSLeftMouseDown = 1,
+ NSLeftMouseUp = 2,
+ NSRightMouseDown = 3,
+ NSRightMouseUp = 4,
+ NSMouseMoved = 5,
+ NSLeftMouseDragged = 6,
+ NSRightMouseDragged = 7,
+ NSMouseEntered = 8,
+ NSMouseExited = 9,
+ NSKeyDown = 10,
+ NSKeyUp = 11,
+ NSFlagsChanged = 12,
+ NSAppKitDefined = 13,
+ NSSystemDefined = 14,
+ NSApplicationDefined = 15,
+ NSPeriodic = 16,
+ NSCursorUpdate = 17,
+ NSScrollWheel = 22,
+ NSTabletPoint = 23,
+ NSTabletProximity = 24,
+ NSOtherMouseDown = 25,
+ NSOtherMouseUp = 26,
+ NSOtherMouseDragged = 27,
+ NSEventTypeGesture = 29,
+ NSEventTypeMagnify = 30,
+ NSEventTypeSwipe = 31,
+ NSEventTypeRotate = 18,
+ NSEventTypeBeginGesture = 19,
+ NSEventTypeEndGesture = 20;
+
+ const NSAlphaShiftKeyMask = 1 << 16,
+ NSShiftKeyMask = 1 << 17,
+ NSControlKeyMask = 1 << 18,
+ NSAlternateKeyMask = 1 << 19,
+ NSCommandKeyMask = 1 << 20,
+ NSNumericPadKeyMask = 1 << 21,
+ NSHelpKeyMask = 1 << 22,
+ NSFunctionKeyMask = 1 << 23;
+
+ const gDebug = false;
+
+ function printDebug(msg) { if (gDebug) dump(msg); }
+
+ var gExpectedEvents = [];
+ var gRightWindow = null, gPopup = null;
+ var gCurrentMouseX = 0, gCurrentMouseY = 0;
+ var gAfterLoopExecution = 0;
+
+ function testMouse(x, y, msg, elem, win, exp, flags, callback) {
+ clearExpectedEvents();
+ var syntheticEvent = null;
+ exp.forEach(function (expEv) {
+ expEv.screenX = x;
+ expEv.screenY = y;
+ if (expEv.synthetic) {
+ is(syntheticEvent, null,
+ "Can't handle two synthetic events in a single testMouse call");
+ syntheticEvent = expEv;
+ }
+ gExpectedEvents.push(expEv);
+ });
+ printDebug("sending event: " + x + ", " + y + " (" + msg + ")\n");
+ gCurrentMouseX = x;
+ gCurrentMouseY = y;
+ var utils = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
+ getInterface(Components.interfaces.nsIDOMWindowUtils);
+ var callbackFunc = function() {
+ clearExpectedEvents();
+ callback();
+ }
+ if (syntheticEvent) {
+ // Set up this listener before we sendNativeMouseEvent, just
+ // in case that synchronously calls us.
+ eventListenOnce(syntheticEvent.target, syntheticEvent.type,
+ // Trigger callbackFunc async, so we're not assuming
+ // anything about how our listener gets ordered with
+ // others.
+ function () { SimpleTest.executeSoon(callbackFunc) });
+ }
+ utils.sendNativeMouseEvent(x, y, msg, flags || 0, elem);
+ if (!syntheticEvent) {
+ gAfterLoopExecution = setTimeout(callbackFunc, 0);
+ }
+ }
+
+ function eventListenOnce(elem, name, callback) {
+ elem.addEventListener(name, function(e) {
+ elem.removeEventListener(name, arguments.callee, false);
+ callback(e);
+ }, false);
+ }
+
+ function focusAndThen(win, callback) {
+ eventListenOnce(win, "focus", callback);
+ printDebug("focusing a window\n");
+ win.focus();
+ }
+
+ function eventToString(e) {
+ return JSON.stringify({
+ type: e.type, target: e.target.nodeName, screenX: e.screenX, screenY: e.screenY
+ });
+ }
+
+ function clearExpectedEvents() {
+ while (gExpectedEvents.length > 0) {
+ var expectedEvent = gExpectedEvents.shift();
+ var errFun = expectedEvent.shouldFireButDoesnt ? todo : ok;
+ errFun(false, "Didn't receive expected event: " + eventToString(expectedEvent));
+ }
+ }
+
+ var gEventNum = 0;
+
+ function eventMonitor(e) {
+ printDebug("got event: " + eventToString(e) + "\n");
+ processEvent(e);
+ }
+
+ function processEvent(e) {
+ if (e.screenX != gCurrentMouseX || e.screenY != gCurrentMouseY) {
+ todo(false, "Oh no! Received a stray event from a confused tracking area. Aborting test.");
+ onTestsFinished();
+ return;
+ }
+ var expectedEvent = gExpectedEvents.shift();
+ if (!expectedEvent) {
+ ok(false, "received event I didn't expect: " + eventToString(e));
+ return;
+ }
+ if (e.type != expectedEvent.type) {
+ // Didn't get expectedEvent.
+ var errFun = expectedEvent.shouldFireButDoesnt ? todo : ok;
+ errFun(false, "Didn't receive expected event: " + eventToString(expectedEvent));
+ return processEvent(e);
+ }
+ gEventNum++;
+ is(e.screenX, expectedEvent.screenX, gEventNum + " | wrong X coord for event " + eventToString(e));
+ is(e.screenY, expectedEvent.screenY, gEventNum + " | wrong Y coord for event " + eventToString(e));
+ is(e.target, expectedEvent.target, gEventNum + " | wrong target for event " + eventToString(e));
+ if (expectedEvent.firesButShouldnt) {
+ todo(false, gEventNum + " | Got an event that should not have fired: " + eventToString(e));
+ }
+ }
+
+ function observe(elem, fun, add) {
+ var addOrRemove = add ? "addEventListener" : "removeEventListener";
+ elem[addOrRemove]("mousemove", fun, false);
+ elem[addOrRemove]("mouseover", fun, false);
+ elem[addOrRemove]("mouseout", fun, false);
+ elem[addOrRemove]("mousedown", fun, false);
+ elem[addOrRemove]("mouseup", fun, false);
+ elem[addOrRemove]("click", fun, false);
+ }
+
+ function start() {
+ window.resizeTo(200, 200);
+ window.moveTo(50, 50);
+ gRightWindow = open(xulWin, '', 'chrome,screenX=300,screenY=50,width=200,height=200');
+ eventListenOnce(gRightWindow, "focus", function () {
+ focusAndThen(window, runTests);
+ });
+ gPopup = document.getElementById("popup");
+ }
+
+ function runTests() {
+ observe(window, eventMonitor, true);
+ observe(gRightWindow, eventMonitor, true);
+ var left = window, right = gRightWindow;
+ var leftElem = document.getElementById("box");
+ var rightElem = gRightWindow.document.documentElement;
+ var panel = document.getElementById("panel");
+ var tooltip = (function createTooltipInRightWindow() {
+ var _tooltip = right.document.createElementNS(XUL_NS, "tooltip");
+ _tooltip.setAttribute("id", "tip");
+ _tooltip.setAttribute("width", "80");
+ _tooltip.setAttribute("height", "20");
+ right.document.documentElement.appendChild(_tooltip);
+ return _tooltip;
+ })();
+ var tests = [
+
+ // Part 1: Disallow click-through
+
+ function blockClickThrough(callback) {
+ document.documentElement.setAttribute("clickthrough", "never");
+ gRightWindow.document.documentElement.setAttribute("clickthrough", "never");
+ callback();
+ },
+ // Enter the left window, which is focused.
+ [150, 150, NSMouseMoved, null, left, [
+ { type: "mouseover", target: leftElem },
+ { type: "mousemove", target: leftElem }
+ ]],
+ // Test that moving inside the window fires mousemove events.
+ [170, 150, NSMouseMoved, null, left, [
+ { type: "mousemove", target: leftElem },
+ ]],
+ // Leaving the window should fire a mouseout event...
+ [170, 20, NSMouseMoved, null, left, [
+ { type: "mouseout", target: leftElem },
+ ]],
+ // ... and entering a mouseover event.
+ [170, 120, NSMouseMoved, null, left, [
+ { type: "mouseover", target: leftElem },
+ { type: "mousemove", target: leftElem },
+ ]],
+ // Move over the right window, which is inactive.
+ // Inactive windows shouldn't respond to mousemove events when clickthrough="never",
+ // so we should only get a mouseout event, no mouseover event.
+ [400, 150, NSMouseMoved, null, right, [
+ { type: "mouseout", target: leftElem },
+ ]],
+ // Left-clicking while holding Cmd and middle clicking should work even
+ // on inactive windows, but without making them active.
+ [400, 150, NSLeftMouseDown, null, right, [
+ { type: "mousedown", target: rightElem },
+ ], NSCommandKeyMask],
+ [400, 150, NSLeftMouseUp, null, right, [
+ { type: "mouseup", target: rightElem },
+ { type: "click", target: rightElem },
+ ], NSCommandKeyMask],
+ [400, 150, NSOtherMouseDown, null, right, [
+ { type: "mousedown", target: rightElem },
+ ]],
+ [400, 150, NSOtherMouseUp, null, right, [
+ { type: "mouseup", target: rightElem },
+ { type: "click", target: rightElem },
+ ]],
+ // Clicking an inactive window should make it active and fire a mouseover
+ // event.
+ [400, 150, NSLeftMouseDown, null, right, [
+ { type: "mouseover", target: rightElem, synthetic: true },
+ ]],
+ [400, 150, NSLeftMouseUp, null, right, [
+ ]],
+ // Now it's focused, so we should get a mousedown event when clicking.
+ [400, 150, NSLeftMouseDown, null, right, [
+ { type: "mousedown", target: rightElem },
+ ]],
+ // Let's drag to the right without letting the button go.
+ [410, 150, NSLeftMouseDragged, null, right, [
+ { type: "mousemove", target: rightElem },
+ ]],
+ // Let go of the mouse.
+ [410, 150, NSLeftMouseUp, null, right, [
+ { type: "mouseup", target: rightElem },
+ { type: "click", target: rightElem },
+ ]],
+ // Move the mouse back over the left window, which is inactive.
+ [150, 170, NSMouseMoved, null, left, [
+ { type: "mouseout", target: rightElem },
+ ]],
+ // Now we're being sneaky. The left window is inactive, but *right*-clicks to it
+ // should still get through. Test that.
+ // Ideally we'd be bracketing that event with over and out events, too, but it
+ // probably doesn't matter too much.
+ [150, 170, NSRightMouseDown, null, left, [
+ { type: "mouseover", target: leftElem, shouldFireButDoesnt: true },
+ { type: "mousedown", target: leftElem },
+ { type: "mouseout", target: leftElem, shouldFireButDoesnt: true },
+ ]],
+ // Let go of the mouse.
+ [150, 170, NSRightMouseUp, null, left, [
+ { type: "mouseover", target: leftElem, shouldFireButDoesnt: true },
+ { type: "mouseup", target: leftElem },
+ { type: "click", target: leftElem },
+ { type: "mouseout", target: leftElem, shouldFireButDoesnt: true },
+ ]],
+ // Right clicking hasn't focused it, so the window is still inactive.
+ // Let's focus it; this time without the mouse, for variaton's sake.
+ // Still, mouseout and mouseover events should fire.
+ function raiseLeftWindow(callback) {
+ clearExpectedEvents();
+ gExpectedEvents.push({ screenX: 150, screenY: 170, type: "mouseover", target: leftElem });
+ // We have to be a bit careful here. The synthetic mouse event may
+ // not fire for a bit after we focus the left window.
+ eventListenOnce(leftElem, "mouseover", function() {
+ // Trigger callback async, so we're not assuming
+ // anything about how our listener gets ordered with others.
+ SimpleTest.executeSoon(callback);
+ });
+ printDebug("focusing left window");
+ left.focus();
+ },
+ // It's active, so it should respond to mousemove events now.
+ [150, 170, NSMouseMoved, null, left, [
+ { type: "mousemove", target: leftElem },
+ ]],
+ // This was boring... let's introduce a popup. It will overlap both the left
+ // and the right window.
+ function openPopupInLeftWindow(callback) {
+ eventListenOnce(gPopup, "popupshown", callback);
+ gPopup.openPopupAtScreen(150, 50, true);
+ },
+ // Move the mouse over the popup.
+ [200, 80, NSMouseMoved, gPopup, left, [
+ { type: "mouseout", target: leftElem },
+ { type: "mouseover", target: gPopup },
+ { type: "mousemove", target: gPopup },
+ ]],
+ // Move the mouse back over the left window outside the popup.
+ [160, 170, NSMouseMoved, null, left, [
+ { type: "mouseout", target: gPopup },
+ { type: "mouseover", target: leftElem },
+ { type: "mousemove", target: leftElem },
+ ]],
+ // Back over the popup...
+ [190, 80, NSMouseMoved, gPopup, left, [
+ { type: "mouseout", target: leftElem },
+ { type: "mouseover", target: gPopup },
+ { type: "mousemove", target: gPopup },
+ ]],
+ // ...and over into the right window.
+ // It's inactive, so it shouldn't get mouseover events yet.
+ [400, 170, NSMouseMoved, null, right, [
+ { type: "mouseout", target: gPopup },
+ ]],
+ // Again, no mouse events please, even though a popup is open. (bug 425556)
+ [400, 180, NSMouseMoved, null, right, [
+ ]],
+ // Activate the right window with a click.
+ // This will close the popup and make the mouse enter the right window.
+ [400, 180, NSLeftMouseDown, null, right, [
+ { type: "mouseover", target: rightElem, synthetic: true },
+ ]],
+ [400, 180, NSLeftMouseUp, null, right, [
+ ]],
+ function verifyPopupClosed2(callback) {
+ is(gPopup.popupBoxObject.popupState, "closed", "popup should have closed when clicking");
+ callback();
+ },
+ // Now the right window is active; click it again, just for fun.
+ [400, 180, NSLeftMouseDown, null, right, [
+ { type: "mousedown", target: rightElem },
+ ]],
+ [400, 180, NSLeftMouseUp, null, right, [
+ { type: "mouseup", target: rightElem },
+ { type: "click", target: rightElem },
+ ]],
+
+ // Time for our next trick: a tooltip!
+ // Install the tooltip, but don't show it yet.
+ function setTooltip(callback) {
+ rightElem.setAttribute("tooltip", "tip");
+ gExpectedEvents.push({ screenX: 410, screenY: 180, type: "mousemove", target: rightElem });
+ eventListenOnce(rightElem, "popupshown", callback);
+ gCurrentMouseX = 410;
+ gCurrentMouseY = 180;
+ var utils = right.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
+ getInterface(Components.interfaces.nsIDOMWindowUtils);
+ utils.sendNativeMouseEvent(410, 180, NSMouseMoved, 0, null);
+ },
+ // Now the tooltip is visible.
+ // Move the mouse a little to the right.
+ [411, 180, NSMouseMoved, null, right, [
+ { type: "mousemove", target: rightElem },
+ ]],
+ // Move another pixel.
+ [412, 180, NSMouseMoved, null, right, [
+ { type: "mousemove", target: rightElem },
+ ]],
+ // Move up and click to make the tooltip go away.
+ [412, 80, NSMouseMoved, null, right, [
+ { type: "mousemove", target: rightElem },
+ ]],
+ [412, 80, NSLeftMouseDown, null, right, [
+ { type: "mousedown", target: rightElem },
+ ]],
+ [412, 80, NSLeftMouseUp, null, right, [
+ { type: "mouseup", target: rightElem },
+ { type: "click", target: rightElem },
+ ]],
+ // OK, next round. Open a panel in the left window, which is inactive.
+ function openPanel(callback) {
+ eventListenOnce(panel, "popupshown", callback);
+ panel.openPopupAtScreen(150, 150, false);
+ },
+ // The panel is parented, so it will be z-ordered over its parent but
+ // under the active window.
+ // Now we move the mouse over the part where the panel rect intersects the
+ // right window's rect. Since the panel is under the window, all the events
+ // should target the right window.
+ [390, 170, NSMouseMoved, null, right, [
+ { type: "mousemove", target: rightElem },
+ ]],
+ [390, 171, NSMouseMoved, null, right, [
+ { type: "mousemove", target: rightElem },
+ ]],
+ [391, 171, NSMouseMoved, null, right, [
+ { type: "mousemove", target: rightElem },
+ ]],
+ // Now move off the right window, so that the mouse is directly over the
+ // panel.
+ [260, 170, NSMouseMoved, panel, left, [
+ { type: "mouseout", target: rightElem },
+ ]],
+ [260, 171, NSMouseMoved, panel, left, [
+ ]],
+ [261, 171, NSMouseMoved, panel, left, [
+ ]],
+ // Let's be evil and click it.
+ [261, 171, NSLeftMouseDown, panel, left, [
+ ]],
+ [261, 171, NSLeftMouseUp, panel, left, [
+ ]],
+ // This didn't focus the window, unfortunately, so let's do it ourselves.
+ function raiseLeftWindowTakeTwo(callback) {
+ focusAndThen(left, callback);
+ },
+ // Now mouse events should get through to the panel (which is now over the
+ // right window).
+ [387, 170, NSMouseMoved, panel, left, [
+ { type: "mouseover", target: panel },
+ { type: "mousemove", target: panel },
+ ]],
+ [387, 171, NSMouseMoved, panel, left, [
+ { type: "mousemove", target: panel },
+ ]],
+ [388, 171, NSMouseMoved, panel, left, [
+ { type: "mousemove", target: panel },
+ ]],
+ // Click the panel.
+ [388, 171, NSLeftMouseDown, panel, left, [
+ { type: "mousedown", target: panel }
+ ]],
+ [388, 171, NSLeftMouseUp, panel, left, [
+ { type: "mouseup", target: panel },
+ { type: "click", target: panel },
+ ]],
+
+ // Last test for this part: Hit testing in the Canyon of Nowhere -
+ // the pixel row directly south of the panel, over the left window.
+ // Before bug 515003 we wrongly thought the mouse wasn't over any window.
+ [173, 200, NSMouseMoved, null, left, [
+ { type: "mouseout", target: panel },
+ { type: "mouseover", target: leftElem },
+ { type: "mousemove", target: leftElem },
+ ]],
+ [173, 201, NSMouseMoved, null, left, [
+ { type: "mousemove", target: leftElem },
+ ]],
+
+ // Part 2: Allow click-through
+
+ function hideThatPanel(callback) {
+ eventListenOnce(panel, "popuphidden", callback);
+ panel.hidePopup();
+ },
+ function unblockClickThrough(callback) {
+ document.documentElement.removeAttribute("clickthrough");
+ gRightWindow.document.documentElement.removeAttribute("clickthrough");
+ callback();
+ },
+ // Enter the left window, which is focused.
+ [150, 150, NSMouseMoved, null, left, [
+ { type: "mousemove", target: leftElem }
+ ]],
+ // Test that moving inside the window fires mousemove events.
+ [170, 150, NSMouseMoved, null, left, [
+ { type: "mousemove", target: leftElem },
+ ]],
+ // Leaving the window should fire a mouseout event...
+ [170, 20, NSMouseMoved, null, left, [
+ { type: "mouseout", target: leftElem },
+ ]],
+ // ... and entering a mouseover event.
+ [170, 120, NSMouseMoved, null, left, [
+ { type: "mouseover", target: leftElem },
+ { type: "mousemove", target: leftElem },
+ ]],
+ // Move over the right window, which is inactive but still accepts
+ // mouse events.
+ [400, 150, NSMouseMoved, null, right, [
+ { type: "mouseout", target: leftElem },
+ { type: "mouseover", target: rightElem },
+ { type: "mousemove", target: rightElem },
+ ]],
+ // Left-clicking while holding Cmd and middle clicking should work
+ // on inactive windows, but without making them active.
+ [400, 150, NSLeftMouseDown, null, right, [
+ { type: "mousedown", target: rightElem },
+ ], NSCommandKeyMask],
+ [400, 150, NSLeftMouseUp, null, right, [
+ { type: "mouseup", target: rightElem },
+ { type: "click", target: rightElem },
+ ], NSCommandKeyMask],
+ [400, 150, NSOtherMouseDown, null, right, [
+ { type: "mousedown", target: rightElem },
+ ]],
+ [400, 150, NSOtherMouseUp, null, right, [
+ { type: "mouseup", target: rightElem },
+ { type: "click", target: rightElem },
+ ]],
+ // Clicking an inactive window should make it active
+ [400, 150, NSLeftMouseDown, null, right, [
+ { type: "mousedown", target: rightElem },
+ ]],
+ [400, 150, NSLeftMouseUp, null, right, [
+ { type: "mouseup", target: rightElem },
+ { type: "click", target: rightElem },
+ ]],
+ // Now it's focused.
+ [401, 150, NSLeftMouseDown, null, right, [
+ { type: "mousedown", target: rightElem },
+ ]],
+ // Let's drag to the right without letting the button go.
+ [410, 150, NSLeftMouseDragged, null, right, [
+ { type: "mousemove", target: rightElem },
+ ]],
+ // Let go of the mouse.
+ [410, 150, NSLeftMouseUp, null, right, [
+ { type: "mouseup", target: rightElem },
+ { type: "click", target: rightElem },
+ ]],
+ // Move the mouse back over the left window, which is inactive.
+ [150, 170, NSMouseMoved, null, left, [
+ { type: "mouseout", target: rightElem },
+ { type: "mouseover", target: leftElem },
+ { type: "mousemove", target: leftElem },
+ ]],
+ // Right-click it.
+ [150, 170, NSRightMouseDown, null, left, [
+ { type: "mousedown", target: leftElem },
+ ]],
+ // Let go of the mouse.
+ [150, 170, NSRightMouseUp, null, left, [
+ { type: "mouseup", target: leftElem },
+ { type: "click", target: leftElem },
+ ]],
+ // Right clicking hasn't focused it, so the window is still inactive.
+ // Let's focus it; this time without the mouse, for variaton's sake.
+ function raiseLeftWindow(callback) {
+ clearExpectedEvents();
+ focusAndThen(left, function () { SimpleTest.executeSoon(callback); });
+ },
+ // It's active and should still respond to mousemove events.
+ [150, 170, NSMouseMoved, null, left, [
+ { type: "mousemove", target: leftElem },
+ ]],
+
+ // This was boring... let's introduce a popup. It will overlap both the left
+ // and the right window.
+ function openPopupInLeftWindow(callback) {
+ eventListenOnce(gPopup, "popupshown", callback);
+ gPopup.openPopupAtScreen(150, 50, true);
+ },
+ // Move the mouse over the popup.
+ [200, 80, NSMouseMoved, gPopup, left, [
+ { type: "mouseout", target: leftElem },
+ { type: "mouseover", target: gPopup },
+ { type: "mousemove", target: gPopup },
+ ]],
+ // Move the mouse back over the left window outside the popup.
+ [160, 170, NSMouseMoved, null, left, [
+ { type: "mouseout", target: gPopup },
+ { type: "mouseover", target: leftElem },
+ { type: "mousemove", target: leftElem },
+ ]],
+ // Back over the popup...
+ [190, 80, NSMouseMoved, gPopup, left, [
+ { type: "mouseout", target: leftElem },
+ { type: "mouseover", target: gPopup },
+ { type: "mousemove", target: gPopup },
+ ]],
+ // ...and over into the right window.
+ [400, 170, NSMouseMoved, null, right, [
+ { type: "mouseout", target: gPopup },
+ { type: "mouseover", target: rightElem },
+ { type: "mousemove", target: rightElem },
+ ]],
+ [400, 180, NSMouseMoved, null, right, [
+ { type: "mousemove", target: rightElem },
+ ]],
+ // Activate the right window with a click.
+ [400, 180, NSLeftMouseDown, null, right, [
+ { type: "mousedown", target: rightElem },
+ ]],
+ [400, 180, NSLeftMouseUp, null, right, [
+ { type: "mouseup", target: rightElem },
+ { type: "click", target: rightElem },
+ ]],
+ function verifyPopupClosed2(callback) {
+ is(gPopup.popupBoxObject.popupState, "closed", "popup should have closed when clicking");
+ callback();
+ },
+ // Now the right window is active; click it again, just for fun.
+ [400, 180, NSLeftMouseDown, null, right, [
+ { type: "mousedown", target: rightElem },
+ ]],
+ [400, 180, NSLeftMouseUp, null, right, [
+ { type: "mouseup", target: rightElem },
+ { type: "click", target: rightElem },
+ ]],
+
+ // Time for our next trick: a tooltip!
+ // Install the tooltip, but don't show it yet.
+ function setTooltip2(callback) {
+ rightElem.setAttribute("tooltip", "tip");
+ gExpectedEvents.push({ screenX: 410, screenY: 180, type: "mousemove", target: rightElem });
+ eventListenOnce(rightElem, "popupshown", callback);
+ gCurrentMouseX = 410;
+ gCurrentMouseY = 180;
+ var utils = right.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
+ getInterface(Components.interfaces.nsIDOMWindowUtils);
+ utils.sendNativeMouseEvent(410, 180, NSMouseMoved, 0, null);
+ },
+ // Now the tooltip is visible.
+ // Move the mouse a little to the right.
+ [411, 180, NSMouseMoved, null, right, [
+ { type: "mousemove", target: rightElem },
+ ]],
+ // Move another pixel.
+ [412, 180, NSMouseMoved, null, right, [
+ { type: "mousemove", target: rightElem },
+ ]],
+ // Move up and click to make the tooltip go away.
+ [412, 80, NSMouseMoved, null, right, [
+ { type: "mousemove", target: rightElem },
+ ]],
+ [412, 80, NSLeftMouseDown, null, right, [
+ { type: "mousedown", target: rightElem },
+ ]],
+ [412, 80, NSLeftMouseUp, null, right, [
+ { type: "mouseup", target: rightElem },
+ { type: "click", target: rightElem },
+ ]],
+ // OK, next round. Open a panel in the left window, which is inactive.
+ function openPanel2(callback) {
+ eventListenOnce(panel, "popupshown", callback);
+ panel.openPopupAtScreen(150, 150, false);
+ },
+ // The panel is parented, so it will be z-ordered over its parent but
+ // under the active window.
+ // Now we move the mouse over the part where the panel rect intersects the
+ // right window's rect. Since the panel is under the window, all the events
+ // should target the right window.
+ [390, 170, NSMouseMoved, null, right, [
+ { type: "mousemove", target: rightElem },
+ ]],
+ [390, 171, NSMouseMoved, null, right, [
+ { type: "mousemove", target: rightElem },
+ ]],
+ [391, 171, NSMouseMoved, null, right, [
+ { type: "mousemove", target: rightElem },
+ ]],
+ // Now move off the right window, so that the mouse is directly over the
+ // panel.
+ [260, 170, NSMouseMoved, panel, left, [
+ { type: "mouseout", target: rightElem },
+ { type: "mouseover", target: panel },
+ { type: "mousemove", target: panel },
+ ]],
+ [260, 171, NSMouseMoved, panel, left, [
+ { type: "mousemove", target: panel },
+ ]],
+ [261, 171, NSMouseMoved, panel, left, [
+ { type: "mousemove", target: panel },
+ ]],
+ // Let's be evil and click it.
+ [261, 171, NSLeftMouseDown, panel, left, [
+ { type: "mousedown", target: panel },
+ ]],
+ [261, 171, NSLeftMouseUp, panel, left, [
+ { type: "mouseup", target: panel },
+ { type: "click", target: panel },
+ ]],
+ // This didn't focus the window, unfortunately, so let's do it ourselves.
+ function raiseLeftWindowTakeTwo(callback) {
+ focusAndThen(left, callback);
+ },
+ [387, 170, NSMouseMoved, panel, left, [
+ { type: "mousemove", target: panel },
+ ]],
+ [387, 171, NSMouseMoved, panel, left, [
+ { type: "mousemove", target: panel },
+ ]],
+ [388, 171, NSMouseMoved, panel, left, [
+ { type: "mousemove", target: panel },
+ ]],
+ // Click the panel.
+ [388, 171, NSLeftMouseDown, panel, left, [
+ { type: "mousedown", target: panel }
+ ]],
+ [388, 171, NSLeftMouseUp, panel, left, [
+ { type: "mouseup", target: panel },
+ { type: "click", target: panel },
+ ]],
+
+ // Last test for today: Hit testing in the Canyon of Nowhere -
+ // the pixel row directly south of the panel, over the left window.
+ // Before bug 515003 we wrongly thought the mouse wasn't over any window.
+ [173, 200, NSMouseMoved, null, left, [
+ { type: "mouseout", target: panel },
+ { type: "mouseover", target: leftElem },
+ { type: "mousemove", target: leftElem },
+ ]],
+ [173, 201, NSMouseMoved, null, left, [
+ { type: "mousemove", target: leftElem },
+ ]],
+ ];
+ function runNextTest() {
+ if (!tests.length)
+ return onTestsFinished();
+
+ var test = tests.shift();
+ if (typeof test == "function")
+ return test(runNextTest);
+
+ var [x, y, msg, elem, win, exp, flags] = test;
+ testMouse(x, y, msg, elem, win, exp, flags, runNextTest);
+ }
+ runNextTest();
+ }
+
+ SimpleTest.waitForFocus(start);
+
+ ]]></script>
+</window>