Bumping gaia.json for 2 gaia revision(s) a=gaia-bump
[gecko.git] / widget / tests / native_mouse_mac_window.xul
blob8680c3b1a40c91d6dba47172fad236e1a8cc74d5
1 <?xml version="1.0"?>
3 <!-- This Source Code Form is subject to the terms of the Mozilla Public
4 - License, v. 2.0. If a copy of the MPL was not distributed with this
5 - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
7 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
9 <window id="NativeMenuWindow"
10 xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
11 xmlns:html="http://www.w3.org/1999/xhtml"
12 width="600"
13 height="600"
14 title="Native Mouse Event Test"
15 orient="vertical">
16 <script type="application/javascript"
17 src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
19 <box height="200" id="box"/>
20 <menupopup id="popup" width="250" height="50"/>
21 <panel id="panel" width="250" height="50" noautohide="true"/>
23 <script type="application/javascript"><![CDATA[
25 function ok(condition, message) {
26 window.opener.wrappedJSObject.SimpleTest.ok(condition, message);
29 function is(a, b, message) {
30 window.opener.wrappedJSObject.SimpleTest.is(a, b, message);
33 function todo(condition, message) {
34 window.opener.wrappedJSObject.SimpleTest.todo(condition, message);
37 function todo_is(a, b, message) {
38 window.opener.wrappedJSObject.SimpleTest.todo_is(a, b, message);
41 function onTestsFinished() {
42 clearTimeout(gAfterLoopExecution);
43 observe(window, eventMonitor, false);
44 observe(gRightWindow, eventMonitor, false);
45 observe(gPopup, eventMonitor, false);
46 gRightWindow.close();
47 var openerSimpleTest = window.opener.wrappedJSObject.SimpleTest;
48 window.close();
49 openerSimpleTest.finish();
52 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
53 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 + '"/>';
55 const NSLeftMouseDown = 1,
56 NSLeftMouseUp = 2,
57 NSRightMouseDown = 3,
58 NSRightMouseUp = 4,
59 NSMouseMoved = 5,
60 NSLeftMouseDragged = 6,
61 NSRightMouseDragged = 7,
62 NSMouseEntered = 8,
63 NSMouseExited = 9,
64 NSKeyDown = 10,
65 NSKeyUp = 11,
66 NSFlagsChanged = 12,
67 NSAppKitDefined = 13,
68 NSSystemDefined = 14,
69 NSApplicationDefined = 15,
70 NSPeriodic = 16,
71 NSCursorUpdate = 17,
72 NSScrollWheel = 22,
73 NSTabletPoint = 23,
74 NSTabletProximity = 24,
75 NSOtherMouseDown = 25,
76 NSOtherMouseUp = 26,
77 NSOtherMouseDragged = 27,
78 NSEventTypeGesture = 29,
79 NSEventTypeMagnify = 30,
80 NSEventTypeSwipe = 31,
81 NSEventTypeRotate = 18,
82 NSEventTypeBeginGesture = 19,
83 NSEventTypeEndGesture = 20;
85 const NSAlphaShiftKeyMask = 1 << 16,
86 NSShiftKeyMask = 1 << 17,
87 NSControlKeyMask = 1 << 18,
88 NSAlternateKeyMask = 1 << 19,
89 NSCommandKeyMask = 1 << 20,
90 NSNumericPadKeyMask = 1 << 21,
91 NSHelpKeyMask = 1 << 22,
92 NSFunctionKeyMask = 1 << 23;
94 const gDebug = false;
96 function printDebug(msg) { if (gDebug) dump(msg); }
98 var gExpectedEvents = [];
99 var gRightWindow = null, gPopup = null;
100 var gCurrentMouseX = 0, gCurrentMouseY = 0;
101 var gAfterLoopExecution = 0;
103 function testMouse(x, y, msg, elem, win, exp, flags, callback) {
104 clearExpectedEvents();
105 var syntheticEvent = null;
106 exp.forEach(function (expEv) {
107 expEv.screenX = x;
108 expEv.screenY = y;
109 if (expEv.synthetic) {
110 is(syntheticEvent, null,
111 "Can't handle two synthetic events in a single testMouse call");
112 syntheticEvent = expEv;
114 gExpectedEvents.push(expEv);
116 printDebug("sending event: " + x + ", " + y + " (" + msg + ")\n");
117 gCurrentMouseX = x;
118 gCurrentMouseY = y;
119 var utils = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
120 getInterface(Components.interfaces.nsIDOMWindowUtils);
121 var callbackFunc = function() {
122 clearExpectedEvents();
123 callback();
125 if (syntheticEvent) {
126 // Set up this listener before we sendNativeMouseEvent, just
127 // in case that synchronously calls us.
128 eventListenOnce(syntheticEvent.target, syntheticEvent.type,
129 // Trigger callbackFunc async, so we're not assuming
130 // anything about how our listener gets ordered with
131 // others.
132 function () { SimpleTest.executeSoon(callbackFunc) });
134 utils.sendNativeMouseEvent(x, y, msg, flags || 0, elem);
135 if (!syntheticEvent) {
136 gAfterLoopExecution = setTimeout(callbackFunc, 0);
140 function eventListenOnce(elem, name, callback) {
141 elem.addEventListener(name, function(e) {
142 elem.removeEventListener(name, arguments.callee, false);
143 callback(e);
144 }, false);
147 function focusAndThen(win, callback) {
148 eventListenOnce(win, "focus", callback);
149 printDebug("focusing a window\n");
150 win.focus();
153 function eventToString(e) {
154 return JSON.stringify({
155 type: e.type, target: e.target.nodeName, screenX: e.screenX, screenY: e.screenY
159 function clearExpectedEvents() {
160 while (gExpectedEvents.length > 0) {
161 var expectedEvent = gExpectedEvents.shift();
162 var errFun = expectedEvent.shouldFireButDoesnt ? todo : ok;
163 errFun(false, "Didn't receive expected event: " + eventToString(expectedEvent));
167 var gEventNum = 0;
169 function eventMonitor(e) {
170 printDebug("got event: " + eventToString(e) + "\n");
171 processEvent(e);
174 function processEvent(e) {
175 if (e.screenX != gCurrentMouseX || e.screenY != gCurrentMouseY) {
176 todo(false, "Oh no! Received a stray event from a confused tracking area. Aborting test.");
177 onTestsFinished();
178 return;
180 var expectedEvent = gExpectedEvents.shift();
181 if (!expectedEvent) {
182 ok(false, "received event I didn't expect: " + eventToString(e));
183 return;
185 if (e.type != expectedEvent.type) {
186 // Didn't get expectedEvent.
187 var errFun = expectedEvent.shouldFireButDoesnt ? todo : ok;
188 errFun(false, "Didn't receive expected event: " + eventToString(expectedEvent));
189 return processEvent(e);
191 gEventNum++;
192 is(e.screenX, expectedEvent.screenX, gEventNum + " | wrong X coord for event " + eventToString(e));
193 is(e.screenY, expectedEvent.screenY, gEventNum + " | wrong Y coord for event " + eventToString(e));
194 is(e.target, expectedEvent.target, gEventNum + " | wrong target for event " + eventToString(e));
195 if (expectedEvent.firesButShouldnt) {
196 todo(false, gEventNum + " | Got an event that should not have fired: " + eventToString(e));
200 function observe(elem, fun, add) {
201 var addOrRemove = add ? "addEventListener" : "removeEventListener";
202 elem[addOrRemove]("mousemove", fun, false);
203 elem[addOrRemove]("mouseover", fun, false);
204 elem[addOrRemove]("mouseout", fun, false);
205 elem[addOrRemove]("mousedown", fun, false);
206 elem[addOrRemove]("mouseup", fun, false);
207 elem[addOrRemove]("click", fun, false);
210 function start() {
211 window.resizeTo(200, 200);
212 window.moveTo(50, 50);
213 gRightWindow = open(xulWin, '', 'chrome,screenX=300,screenY=50,width=200,height=200');
214 eventListenOnce(gRightWindow, "focus", function () {
215 focusAndThen(window, runTests);
217 gPopup = document.getElementById("popup");
220 function runTests() {
221 observe(window, eventMonitor, true);
222 observe(gRightWindow, eventMonitor, true);
223 var left = window, right = gRightWindow;
224 var leftElem = document.getElementById("box");
225 var rightElem = gRightWindow.document.documentElement;
226 var panel = document.getElementById("panel");
227 var tooltip = (function createTooltipInRightWindow() {
228 var _tooltip = right.document.createElementNS(XUL_NS, "tooltip");
229 _tooltip.setAttribute("id", "tip");
230 _tooltip.setAttribute("width", "80");
231 _tooltip.setAttribute("height", "20");
232 right.document.documentElement.appendChild(_tooltip);
233 return _tooltip;
234 })();
235 var tests = [
237 // Part 1: Disallow click-through
239 function blockClickThrough(callback) {
240 document.documentElement.setAttribute("clickthrough", "never");
241 gRightWindow.document.documentElement.setAttribute("clickthrough", "never");
242 callback();
244 // Enter the left window, which is focused.
245 [150, 150, NSMouseMoved, null, left, [
246 { type: "mouseover", target: leftElem },
247 { type: "mousemove", target: leftElem }
249 // Test that moving inside the window fires mousemove events.
250 [170, 150, NSMouseMoved, null, left, [
251 { type: "mousemove", target: leftElem },
253 // Leaving the window should fire a mouseout event...
254 [170, 20, NSMouseMoved, null, left, [
255 { type: "mouseout", target: leftElem },
257 // ... and entering a mouseover event.
258 [170, 120, NSMouseMoved, null, left, [
259 { type: "mouseover", target: leftElem },
260 { type: "mousemove", target: leftElem },
262 // Move over the right window, which is inactive.
263 // Inactive windows shouldn't respond to mousemove events when clickthrough="never",
264 // so we should only get a mouseout event, no mouseover event.
265 [400, 150, NSMouseMoved, null, right, [
266 { type: "mouseout", target: leftElem },
268 // Left-clicking while holding Cmd and middle clicking should work even
269 // on inactive windows, but without making them active.
270 [400, 150, NSLeftMouseDown, null, right, [
271 { type: "mousedown", target: rightElem },
272 ], NSCommandKeyMask],
273 [400, 150, NSLeftMouseUp, null, right, [
274 { type: "mouseup", target: rightElem },
275 { type: "click", target: rightElem },
276 ], NSCommandKeyMask],
277 [400, 150, NSOtherMouseDown, null, right, [
278 { type: "mousedown", target: rightElem },
280 [400, 150, NSOtherMouseUp, null, right, [
281 { type: "mouseup", target: rightElem },
282 { type: "click", target: rightElem },
284 // Clicking an inactive window should make it active and fire a mouseover
285 // event.
286 [400, 150, NSLeftMouseDown, null, right, [
287 { type: "mouseover", target: rightElem, synthetic: true },
289 [400, 150, NSLeftMouseUp, null, right, [
291 // Now it's focused, so we should get a mousedown event when clicking.
292 [400, 150, NSLeftMouseDown, null, right, [
293 { type: "mousedown", target: rightElem },
295 // Let's drag to the right without letting the button go.
296 [410, 150, NSLeftMouseDragged, null, right, [
297 { type: "mousemove", target: rightElem },
299 // Let go of the mouse.
300 [410, 150, NSLeftMouseUp, null, right, [
301 { type: "mouseup", target: rightElem },
302 { type: "click", target: rightElem },
304 // Move the mouse back over the left window, which is inactive.
305 [150, 170, NSMouseMoved, null, left, [
306 { type: "mouseout", target: rightElem },
308 // Now we're being sneaky. The left window is inactive, but *right*-clicks to it
309 // should still get through. Test that.
310 // Ideally we'd be bracketing that event with over and out events, too, but it
311 // probably doesn't matter too much.
312 [150, 170, NSRightMouseDown, null, left, [
313 { type: "mouseover", target: leftElem, shouldFireButDoesnt: true },
314 { type: "mousedown", target: leftElem },
315 { type: "mouseout", target: leftElem, shouldFireButDoesnt: true },
317 // Let go of the mouse.
318 [150, 170, NSRightMouseUp, null, left, [
319 { type: "mouseover", target: leftElem, shouldFireButDoesnt: true },
320 { type: "mouseup", target: leftElem },
321 { type: "click", target: leftElem },
322 { type: "mouseout", target: leftElem, shouldFireButDoesnt: true },
324 // Right clicking hasn't focused it, so the window is still inactive.
325 // Let's focus it; this time without the mouse, for variaton's sake.
326 // Still, mouseout and mouseover events should fire.
327 function raiseLeftWindow(callback) {
328 clearExpectedEvents();
329 gExpectedEvents.push({ screenX: 150, screenY: 170, type: "mouseover", target: leftElem });
330 // We have to be a bit careful here. The synthetic mouse event may
331 // not fire for a bit after we focus the left window.
332 eventListenOnce(leftElem, "mouseover", function() {
333 // Trigger callback async, so we're not assuming
334 // anything about how our listener gets ordered with others.
335 SimpleTest.executeSoon(callback);
337 printDebug("focusing left window");
338 left.focus();
340 // It's active, so it should respond to mousemove events now.
341 [150, 170, NSMouseMoved, null, left, [
342 { type: "mousemove", target: leftElem },
344 // This was boring... let's introduce a popup. It will overlap both the left
345 // and the right window.
346 function openPopupInLeftWindow(callback) {
347 eventListenOnce(gPopup, "popupshown", callback);
348 gPopup.openPopupAtScreen(150, 50, true);
350 // Move the mouse over the popup.
351 [200, 80, NSMouseMoved, gPopup, left, [
352 { type: "mouseout", target: leftElem },
353 { type: "mouseover", target: gPopup },
354 { type: "mousemove", target: gPopup },
356 // Move the mouse back over the left window outside the popup.
357 [160, 170, NSMouseMoved, null, left, [
358 { type: "mouseout", target: gPopup },
359 { type: "mouseover", target: leftElem },
360 { type: "mousemove", target: leftElem },
362 // Back over the popup...
363 [190, 80, NSMouseMoved, gPopup, left, [
364 { type: "mouseout", target: leftElem },
365 { type: "mouseover", target: gPopup },
366 { type: "mousemove", target: gPopup },
368 // ...and over into the right window.
369 // It's inactive, so it shouldn't get mouseover events yet.
370 [400, 170, NSMouseMoved, null, right, [
371 { type: "mouseout", target: gPopup },
373 // Again, no mouse events please, even though a popup is open. (bug 425556)
374 [400, 180, NSMouseMoved, null, right, [
376 // Activate the right window with a click.
377 // This will close the popup and make the mouse enter the right window.
378 [400, 180, NSLeftMouseDown, null, right, [
379 { type: "mouseover", target: rightElem, synthetic: true },
381 [400, 180, NSLeftMouseUp, null, right, [
383 function verifyPopupClosed2(callback) {
384 is(gPopup.popupBoxObject.popupState, "closed", "popup should have closed when clicking");
385 callback();
387 // Now the right window is active; click it again, just for fun.
388 [400, 180, NSLeftMouseDown, null, right, [
389 { type: "mousedown", target: rightElem },
391 [400, 180, NSLeftMouseUp, null, right, [
392 { type: "mouseup", target: rightElem },
393 { type: "click", target: rightElem },
396 // Time for our next trick: a tooltip!
397 // Install the tooltip, but don't show it yet.
398 function setTooltip(callback) {
399 rightElem.setAttribute("tooltip", "tip");
400 gExpectedEvents.push({ screenX: 410, screenY: 180, type: "mousemove", target: rightElem });
401 eventListenOnce(rightElem, "popupshown", callback);
402 gCurrentMouseX = 410;
403 gCurrentMouseY = 180;
404 var utils = right.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
405 getInterface(Components.interfaces.nsIDOMWindowUtils);
406 utils.sendNativeMouseEvent(410, 180, NSMouseMoved, 0, null);
408 // Now the tooltip is visible.
409 // Move the mouse a little to the right.
410 [411, 180, NSMouseMoved, null, right, [
411 { type: "mousemove", target: rightElem },
413 // Move another pixel.
414 [412, 180, NSMouseMoved, null, right, [
415 { type: "mousemove", target: rightElem },
417 // Move up and click to make the tooltip go away.
418 [412, 80, NSMouseMoved, null, right, [
419 { type: "mousemove", target: rightElem },
421 [412, 80, NSLeftMouseDown, null, right, [
422 { type: "mousedown", target: rightElem },
424 [412, 80, NSLeftMouseUp, null, right, [
425 { type: "mouseup", target: rightElem },
426 { type: "click", target: rightElem },
428 // OK, next round. Open a panel in the left window, which is inactive.
429 function openPanel(callback) {
430 eventListenOnce(panel, "popupshown", callback);
431 panel.openPopupAtScreen(150, 150, false);
433 // The panel is parented, so it will be z-ordered over its parent but
434 // under the active window.
435 // Now we move the mouse over the part where the panel rect intersects the
436 // right window's rect. Since the panel is under the window, all the events
437 // should target the right window.
438 [390, 170, NSMouseMoved, null, right, [
439 { type: "mousemove", target: rightElem },
441 [390, 171, NSMouseMoved, null, right, [
442 { type: "mousemove", target: rightElem },
444 [391, 171, NSMouseMoved, null, right, [
445 { type: "mousemove", target: rightElem },
447 // Now move off the right window, so that the mouse is directly over the
448 // panel.
449 [260, 170, NSMouseMoved, panel, left, [
450 { type: "mouseout", target: rightElem },
452 [260, 171, NSMouseMoved, panel, left, [
454 [261, 171, NSMouseMoved, panel, left, [
456 // Let's be evil and click it.
457 [261, 171, NSLeftMouseDown, panel, left, [
459 [261, 171, NSLeftMouseUp, panel, left, [
461 // This didn't focus the window, unfortunately, so let's do it ourselves.
462 function raiseLeftWindowTakeTwo(callback) {
463 focusAndThen(left, callback);
465 // Now mouse events should get through to the panel (which is now over the
466 // right window).
467 [387, 170, NSMouseMoved, panel, left, [
468 { type: "mouseover", target: panel },
469 { type: "mousemove", target: panel },
471 [387, 171, NSMouseMoved, panel, left, [
472 { type: "mousemove", target: panel },
474 [388, 171, NSMouseMoved, panel, left, [
475 { type: "mousemove", target: panel },
477 // Click the panel.
478 [388, 171, NSLeftMouseDown, panel, left, [
479 { type: "mousedown", target: panel }
481 [388, 171, NSLeftMouseUp, panel, left, [
482 { type: "mouseup", target: panel },
483 { type: "click", target: panel },
486 // Last test for this part: Hit testing in the Canyon of Nowhere -
487 // the pixel row directly south of the panel, over the left window.
488 // Before bug 515003 we wrongly thought the mouse wasn't over any window.
489 [173, 200, NSMouseMoved, null, left, [
490 { type: "mouseout", target: panel },
491 { type: "mouseover", target: leftElem },
492 { type: "mousemove", target: leftElem },
494 [173, 201, NSMouseMoved, null, left, [
495 { type: "mousemove", target: leftElem },
498 // Part 2: Allow click-through
500 function hideThatPanel(callback) {
501 eventListenOnce(panel, "popuphidden", callback);
502 panel.hidePopup();
504 function unblockClickThrough(callback) {
505 document.documentElement.removeAttribute("clickthrough");
506 gRightWindow.document.documentElement.removeAttribute("clickthrough");
507 callback();
509 // Enter the left window, which is focused.
510 [150, 150, NSMouseMoved, null, left, [
511 { type: "mousemove", target: leftElem }
513 // Test that moving inside the window fires mousemove events.
514 [170, 150, NSMouseMoved, null, left, [
515 { type: "mousemove", target: leftElem },
517 // Leaving the window should fire a mouseout event...
518 [170, 20, NSMouseMoved, null, left, [
519 { type: "mouseout", target: leftElem },
521 // ... and entering a mouseover event.
522 [170, 120, NSMouseMoved, null, left, [
523 { type: "mouseover", target: leftElem },
524 { type: "mousemove", target: leftElem },
526 // Move over the right window, which is inactive but still accepts
527 // mouse events.
528 [400, 150, NSMouseMoved, null, right, [
529 { type: "mouseout", target: leftElem },
530 { type: "mouseover", target: rightElem },
531 { type: "mousemove", target: rightElem },
533 // Left-clicking while holding Cmd and middle clicking should work
534 // on inactive windows, but without making them active.
535 [400, 150, NSLeftMouseDown, null, right, [
536 { type: "mousedown", target: rightElem },
537 ], NSCommandKeyMask],
538 [400, 150, NSLeftMouseUp, null, right, [
539 { type: "mouseup", target: rightElem },
540 { type: "click", target: rightElem },
541 ], NSCommandKeyMask],
542 [400, 150, NSOtherMouseDown, null, right, [
543 { type: "mousedown", target: rightElem },
545 [400, 150, NSOtherMouseUp, null, right, [
546 { type: "mouseup", target: rightElem },
547 { type: "click", target: rightElem },
549 // Clicking an inactive window should make it active
550 [400, 150, NSLeftMouseDown, null, right, [
551 { type: "mousedown", target: rightElem },
553 [400, 150, NSLeftMouseUp, null, right, [
554 { type: "mouseup", target: rightElem },
555 { type: "click", target: rightElem },
557 // Now it's focused.
558 [401, 150, NSLeftMouseDown, null, right, [
559 { type: "mousedown", target: rightElem },
561 // Let's drag to the right without letting the button go.
562 [410, 150, NSLeftMouseDragged, null, right, [
563 { type: "mousemove", target: rightElem },
565 // Let go of the mouse.
566 [410, 150, NSLeftMouseUp, null, right, [
567 { type: "mouseup", target: rightElem },
568 { type: "click", target: rightElem },
570 // Move the mouse back over the left window, which is inactive.
571 [150, 170, NSMouseMoved, null, left, [
572 { type: "mouseout", target: rightElem },
573 { type: "mouseover", target: leftElem },
574 { type: "mousemove", target: leftElem },
576 // Right-click it.
577 [150, 170, NSRightMouseDown, null, left, [
578 { type: "mousedown", target: leftElem },
580 // Let go of the mouse.
581 [150, 170, NSRightMouseUp, null, left, [
582 { type: "mouseup", target: leftElem },
583 { type: "click", target: leftElem },
585 // Right clicking hasn't focused it, so the window is still inactive.
586 // Let's focus it; this time without the mouse, for variaton's sake.
587 function raiseLeftWindow(callback) {
588 clearExpectedEvents();
589 focusAndThen(left, function () { SimpleTest.executeSoon(callback); });
591 // It's active and should still respond to mousemove events.
592 [150, 170, NSMouseMoved, null, left, [
593 { type: "mousemove", target: leftElem },
596 // This was boring... let's introduce a popup. It will overlap both the left
597 // and the right window.
598 function openPopupInLeftWindow(callback) {
599 eventListenOnce(gPopup, "popupshown", callback);
600 gPopup.openPopupAtScreen(150, 50, true);
602 // Move the mouse over the popup.
603 [200, 80, NSMouseMoved, gPopup, left, [
604 { type: "mouseout", target: leftElem },
605 { type: "mouseover", target: gPopup },
606 { type: "mousemove", target: gPopup },
608 // Move the mouse back over the left window outside the popup.
609 [160, 170, NSMouseMoved, null, left, [
610 { type: "mouseout", target: gPopup },
611 { type: "mouseover", target: leftElem },
612 { type: "mousemove", target: leftElem },
614 // Back over the popup...
615 [190, 80, NSMouseMoved, gPopup, left, [
616 { type: "mouseout", target: leftElem },
617 { type: "mouseover", target: gPopup },
618 { type: "mousemove", target: gPopup },
620 // ...and over into the right window.
621 [400, 170, NSMouseMoved, null, right, [
622 { type: "mouseout", target: gPopup },
623 { type: "mouseover", target: rightElem },
624 { type: "mousemove", target: rightElem },
626 [400, 180, NSMouseMoved, null, right, [
627 { type: "mousemove", target: rightElem },
629 // Activate the right window with a click.
630 [400, 180, NSLeftMouseDown, null, right, [
631 { type: "mousedown", target: rightElem },
633 [400, 180, NSLeftMouseUp, null, right, [
634 { type: "mouseup", target: rightElem },
635 { type: "click", target: rightElem },
637 function verifyPopupClosed2(callback) {
638 is(gPopup.popupBoxObject.popupState, "closed", "popup should have closed when clicking");
639 callback();
641 // Now the right window is active; click it again, just for fun.
642 [400, 180, NSLeftMouseDown, null, right, [
643 { type: "mousedown", target: rightElem },
645 [400, 180, NSLeftMouseUp, null, right, [
646 { type: "mouseup", target: rightElem },
647 { type: "click", target: rightElem },
650 // Time for our next trick: a tooltip!
651 // Install the tooltip, but don't show it yet.
652 function setTooltip2(callback) {
653 rightElem.setAttribute("tooltip", "tip");
654 gExpectedEvents.push({ screenX: 410, screenY: 180, type: "mousemove", target: rightElem });
655 eventListenOnce(rightElem, "popupshown", callback);
656 gCurrentMouseX = 410;
657 gCurrentMouseY = 180;
658 var utils = right.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
659 getInterface(Components.interfaces.nsIDOMWindowUtils);
660 utils.sendNativeMouseEvent(410, 180, NSMouseMoved, 0, null);
662 // Now the tooltip is visible.
663 // Move the mouse a little to the right.
664 [411, 180, NSMouseMoved, null, right, [
665 { type: "mousemove", target: rightElem },
667 // Move another pixel.
668 [412, 180, NSMouseMoved, null, right, [
669 { type: "mousemove", target: rightElem },
671 // Move up and click to make the tooltip go away.
672 [412, 80, NSMouseMoved, null, right, [
673 { type: "mousemove", target: rightElem },
675 [412, 80, NSLeftMouseDown, null, right, [
676 { type: "mousedown", target: rightElem },
678 [412, 80, NSLeftMouseUp, null, right, [
679 { type: "mouseup", target: rightElem },
680 { type: "click", target: rightElem },
682 // OK, next round. Open a panel in the left window, which is inactive.
683 function openPanel2(callback) {
684 eventListenOnce(panel, "popupshown", callback);
685 panel.openPopupAtScreen(150, 150, false);
687 // The panel is parented, so it will be z-ordered over its parent but
688 // under the active window.
689 // Now we move the mouse over the part where the panel rect intersects the
690 // right window's rect. Since the panel is under the window, all the events
691 // should target the right window.
692 [390, 170, NSMouseMoved, null, right, [
693 { type: "mousemove", target: rightElem },
695 [390, 171, NSMouseMoved, null, right, [
696 { type: "mousemove", target: rightElem },
698 [391, 171, NSMouseMoved, null, right, [
699 { type: "mousemove", target: rightElem },
701 // Now move off the right window, so that the mouse is directly over the
702 // panel.
703 [260, 170, NSMouseMoved, panel, left, [
704 { type: "mouseout", target: rightElem },
705 { type: "mouseover", target: panel },
706 { type: "mousemove", target: panel },
708 [260, 171, NSMouseMoved, panel, left, [
709 { type: "mousemove", target: panel },
711 [261, 171, NSMouseMoved, panel, left, [
712 { type: "mousemove", target: panel },
714 // Let's be evil and click it.
715 [261, 171, NSLeftMouseDown, panel, left, [
716 { type: "mousedown", target: panel },
718 [261, 171, NSLeftMouseUp, panel, left, [
719 { type: "mouseup", target: panel },
720 { type: "click", target: panel },
722 // This didn't focus the window, unfortunately, so let's do it ourselves.
723 function raiseLeftWindowTakeTwo(callback) {
724 focusAndThen(left, callback);
726 [387, 170, NSMouseMoved, panel, left, [
727 { type: "mousemove", target: panel },
729 [387, 171, NSMouseMoved, panel, left, [
730 { type: "mousemove", target: panel },
732 [388, 171, NSMouseMoved, panel, left, [
733 { type: "mousemove", target: panel },
735 // Click the panel.
736 [388, 171, NSLeftMouseDown, panel, left, [
737 { type: "mousedown", target: panel }
739 [388, 171, NSLeftMouseUp, panel, left, [
740 { type: "mouseup", target: panel },
741 { type: "click", target: panel },
744 // Last test for today: Hit testing in the Canyon of Nowhere -
745 // the pixel row directly south of the panel, over the left window.
746 // Before bug 515003 we wrongly thought the mouse wasn't over any window.
747 [173, 200, NSMouseMoved, null, left, [
748 { type: "mouseout", target: panel },
749 { type: "mouseover", target: leftElem },
750 { type: "mousemove", target: leftElem },
752 [173, 201, NSMouseMoved, null, left, [
753 { type: "mousemove", target: leftElem },
756 function runNextTest() {
757 if (!tests.length)
758 return onTestsFinished();
760 var test = tests.shift();
761 if (typeof test == "function")
762 return test(runNextTest);
764 var [x, y, msg, elem, win, exp, flags] = test;
765 testMouse(x, y, msg, elem, win, exp, flags, runNextTest);
767 runNextTest();
770 SimpleTest.waitForFocus(start);
772 ]]></script>
773 </window>