Bug 1875831: Don't use arrow positioning for the tab preview panel. r=tabbrowser-reviewers,dao

Something about the arrow positioning logic causes background windows to raise.
The tab preview was only made an arrow panel because other panels consume wheel
events[1] meaning we couldn't detect them to close the panel but it turns out there
is a dedicated `rolluponmousewheel` attribute that allows us to automatically
close the panel anyway so this removes the dedicated wheel handling and adds
the correct attribute.

The original test added for closing on wheel events wasn't actually working as
it wasn't actually dispatching any wheel events, the panel was closing for other
reasons. This switches to sending native mouse wheel events.

[1] https://searchfox.org/mozilla-central/rev/098f910d0593b12a42089dd8f40dcd19d1121430/layout/xul/nsXULPopupManager.cpp#546-557

Differential Revision: https://phabricator.services.mozilla.com/D202709
This commit is contained in:
Dave Townsend 2024-02-27 13:38:50 +00:00
parent 50818a234e
commit 29ba507d7e
2 changed files with 68 additions and 25 deletions

View file

@ -46,7 +46,7 @@ add_setup(async function () {
* 2. Tab preview card shows the correct preview for the tab being hovered
* 3. Tab preview card is dismissed when the mouse leaves the tab bar
*/
add_task(async () => {
add_task(async function hoverTests() {
const tabUrl1 =
"data:text/html,<html><head><title>First New Tab</title></head><body>Hello</body></html>";
const tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, tabUrl1);
@ -85,6 +85,11 @@ add_task(async () => {
BrowserTestUtils.removeTab(tab1);
BrowserTestUtils.removeTab(tab2);
// Move the mouse outside of the tab strip.
EventUtils.synthesizeMouseAtCenter(document.documentElement, {
type: "mouseover",
});
});
/**
@ -92,7 +97,7 @@ add_task(async () => {
* when browser.tabs.cardPreview.showThumbnails is set to true,
* while the currently selected tab never displays a thumbnail in its preview.
*/
add_task(async () => {
add_task(async function thumbnailTests() {
await SpecialPowers.pushPrefEnv({
set: [["browser.tabs.cardPreview.showThumbnails", true]],
});
@ -120,15 +125,28 @@ add_task(async () => {
"Tab2 (selected) does not contain thumbnail"
);
const previewHidden = BrowserTestUtils.waitForEvent(
document.getElementById("tabbrowser-tab-preview"),
"previewhidden"
);
BrowserTestUtils.removeTab(tab1);
BrowserTestUtils.removeTab(tab2);
await SpecialPowers.popPrefEnv();
// Removing the tab should close the preview.
await previewHidden;
// Move the mouse outside of the tab strip.
EventUtils.synthesizeMouseAtCenter(document.documentElement, {
type: "mouseover",
});
});
/**
* Wheel events at the document-level of the window should hide the preview.
*/
add_task(async () => {
add_task(async function wheelTests() {
const tabUrl1 = "about:blank";
const tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, tabUrl1);
const tabUrl2 = "about:blank";
@ -141,14 +159,49 @@ add_task(async () => {
document.getElementById("tabbrowser-tab-preview"),
"previewhidden"
);
EventUtils.synthesizeMouse(tabs, 0, tabs.outerHeight + 1, {
wheel: true,
deltaY: -1,
deltaMode: WheelEvent.DOM_DELTA_LINE,
});
// Copied from apz_test_native_event_utils.js
let message = 0;
switch (AppConstants.platform) {
case "win":
message = 0x020a;
break;
case "linux":
message = 4;
break;
case "macosx":
message = 1;
break;
}
let rect = tabs.getBoundingClientRect();
let screenRect = window.windowUtils.toScreenRect(
rect.x,
rect.y,
rect.width,
rect.height
);
window.windowUtils.sendNativeMouseScrollEvent(
screenRect.left,
screenRect.bottom,
message,
0,
3,
0,
0,
Ci.nsIDOMWindowUtils.MOUSESCROLL_SCROLL_LINES,
tabs,
null
);
await previewHidden;
BrowserTestUtils.removeTab(tab1);
BrowserTestUtils.removeTab(tab2);
await SpecialPowers.popPrefEnv();
// Move the mouse outside of the tab strip.
EventUtils.synthesizeMouseAtCenter(document.documentElement, {
type: "mouseover",
});
});

View file

@ -60,8 +60,8 @@ export default class TabPreview extends MozLitElement {
this.panel.setAttribute("noautofocus", true);
this.panel.setAttribute("norolluponanchor", true);
this.panel.setAttribute("consumeoutsideclicks", "never");
this.panel.setAttribute("rolluponmousewheel", "true");
this.panel.setAttribute("level", "parent");
this.panel.setAttribute("type", "arrow");
this.shadowRoot.append(this.panel);
return this.panel;
}
@ -94,10 +94,6 @@ export default class TabPreview extends MozLitElement {
this.requestUpdate();
break;
}
case "wheel": {
this.hidePreview();
break;
}
case "popuphidden": {
this.previewHidden();
break;
@ -111,29 +107,23 @@ export default class TabPreview extends MozLitElement {
y: -2,
isContextMenu: false,
});
window.addEventListener("wheel", this, {
capture: true,
passive: true,
});
window.addEventListener("TabSelect", this);
this.panel.addEventListener("popuphidden", this);
}
hidePreview() {
this.panel.hidePopup();
this.updateComplete.then(() => {
/**
* @event TabPreview#previewhidden
* @type {CustomEvent}
*/
this.dispatchEvent(new CustomEvent("previewhidden"));
});
}
previewHidden() {
window.removeEventListener("wheel", this, { capture: true, passive: true });
window.removeEventListener("TabSelect", this);
this.panel.removeEventListener("popuphidden", this);
/**
* @event TabPreview#previewhidden
* @type {CustomEvent}
*/
this.dispatchEvent(new CustomEvent("previewhidden"));
}
// compute values derived from tab element