Bug 1375940 - Part 1: Add a test for destroying a window during a click event while double-clicking, r=smaug

MozReview-Commit-ID: BdyWjvG9q8m
This commit is contained in:
Michael Layzell 2017-06-23 14:39:03 -04:00
Родитель 9e991dd02b
Коммит 068e7442ed
3 изменённых файлов: 104 добавлений и 1 удалений

Просмотреть файл

@ -177,3 +177,5 @@ skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
[test_bug1332699.html]
[test_bug1339758.html]
[test_dnd_with_modifiers.html]
[test_dblclick_kill_window.html]
skip-if = toolkit != "gtk3" # Dispatches GTK native widget events

Просмотреть файл

@ -0,0 +1,98 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1375940
-->
<head>
<title>Test for Bug 1375940</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<pre id="test">
<iframe src="about:blank"></iframe>
<script type="application/javascript">
// Convert (aX, aY), in CSS pixels relative to aElement's bounding rect,
// to device pixels relative to the screen.
function coordinatesRelativeToScreen(aX, aY, aElement) {
var targetWindow = aElement.ownerDocument.defaultView;
var scale = targetWindow.devicePixelRatio;
var rect = aElement.getBoundingClientRect();
return {
x: (targetWindow.mozInnerScreenX + rect.left + aX) * scale,
y: (targetWindow.mozInnerScreenY + rect.top + aY) * scale
};
}
// GDK event constants for emitting a double click event to content.
const GDK_BUTTON_PRESS = 4;
const GDK_BUTTON_RELEASE = 7;
const GDK_2BUTTON_PRESS = 5;
const frame = document.querySelector("iframe");
add_task(async function() {
frame.contentDocument.body.innerHTML = "<button>clicky</button>";
const button = frame.contentDocument.querySelector("button");
const utils = SpecialPowers.getDOMWindowUtils(frame.contentWindow);
const {x, y} = coordinatesRelativeToScreen(5, 5, button);
let doubleClick = false;
let gotClicks = new Promise(resolve => {
let sawFirst = false;
let sawSecond = false;
button.addEventListener("click", () => {
ok(true, "Got a click");
if (sawFirst) {
sawSecond = true;
// Let's synchronously destroy the universe!
frame.style.display = "none";
frame.contentDocument.body.clientWidth;
// Re-create our presshell.
frame.style.display = "";
frame.contentDocument.body.clientWidth;
resolve();
}
sawFirst = true;
});
button.addEventListener("dblclick", () => {
ok(sawSecond, "Should have already seen 2 clicks");
doubleClick = true;
});
});
// Emulate a double-click (GDK only)
// Source: https://developer.gnome.org/gdk3/stable/gdk3-Event-Structures.html#GdkEventButton
const msgs = [
GDK_BUTTON_PRESS,
GDK_BUTTON_RELEASE,
GDK_BUTTON_PRESS, // NOTE: Gecko currently discards this event
GDK_2BUTTON_PRESS,
GDK_BUTTON_RELEASE
];
for (let msg of msgs) {
await new Promise(resolve => {
ok(true, "Sent event " + msg);
utils.sendNativeMouseEvent(x, y, msg, 0, button, resolve);
});
}
ok(true, "Waiting for clicks");
await gotClicks;
// NOTE: I would think we should see the doubleclick event here, however, it
// seems as though setting the display to none, and then clearing it doesn't
// re-create the PresShell eagerly enough to perform the dblclick event
// dispatch.
todo(doubleClick, "We should have triggered a dblclick event");
});
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -6625,7 +6625,10 @@ nsWindow::SynthesizeNativeMouseEvent(LayoutDeviceIntPoint aPoint,
// explicitly *before* requesting a button-press/release. You will also need to wait
// for the motion event to be dispatched before requesting a button-press/release
// event to maintain the desired event order.
if (aNativeMessage == GDK_BUTTON_PRESS || aNativeMessage == GDK_BUTTON_RELEASE) {
if (aNativeMessage == GDK_BUTTON_PRESS ||
aNativeMessage == GDK_BUTTON_RELEASE ||
aNativeMessage == GDK_2BUTTON_PRESS ||
aNativeMessage == GDK_3BUTTON_PRESS) {
GdkEvent event;
memset(&event, 0, sizeof(GdkEvent));
event.type = (GdkEventType)aNativeMessage;