diff --git a/browser/components/urlbar/UrlbarPrefs.sys.mjs b/browser/components/urlbar/UrlbarPrefs.sys.mjs index 417e2938b68a..77e0cd845d95 100644 --- a/browser/components/urlbar/UrlbarPrefs.sys.mjs +++ b/browser/components/urlbar/UrlbarPrefs.sys.mjs @@ -67,6 +67,11 @@ const PREF_URLBAR_DEFAULTS = new Map([ // Feature gate pref for clipboard suggestions in the urlbar. ["clipboard.featureGate", false], + // Whether to close other panels when the urlbar panel opens. + // This feature gate exists just as an emergency rollback in case of + // unexpected issues in Release. We normally want this behavior. + ["closeOtherPanelsOnOpen", true], + // Whether to show a link for using the search functionality provided by the // active view if the the view utilizes OpenSearch. ["contextualSearch.enabled", true], diff --git a/browser/components/urlbar/UrlbarView.sys.mjs b/browser/components/urlbar/UrlbarView.sys.mjs index c5ea040f1f18..3b7bd025b534 100644 --- a/browser/components/urlbar/UrlbarView.sys.mjs +++ b/browser/components/urlbar/UrlbarView.sys.mjs @@ -1095,6 +1095,13 @@ export class UrlbarView { this.window.addEventListener("blur", this); this.controller.notify(this.controller.NOTIFICATIONS.VIEW_OPEN); + + if (lazy.UrlbarPrefs.get("closeOtherPanelsOnOpen")) { + this.window.docShell.treeOwner + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIAppWindow) + .rollupAllPopups(); + } } #shouldShowHeuristic(result) { diff --git a/browser/components/urlbar/tests/browser/browser.toml b/browser/components/urlbar/tests/browser/browser.toml index 3935532598c4..b9e31e00e86b 100644 --- a/browser/components/urlbar/tests/browser/browser.toml +++ b/browser/components/urlbar/tests/browser/browser.toml @@ -175,6 +175,8 @@ support-files = [ ["browser_closePanelOnClick.js"] +["browser_close_other_panels.js"] + ["browser_content_opener.js"] ["browser_contextualsearch.js"] diff --git a/browser/components/urlbar/tests/browser/browser_close_other_panels.js b/browser/components/urlbar/tests/browser/browser_close_other_panels.js new file mode 100644 index 000000000000..c6b7f87ec1fc --- /dev/null +++ b/browser/components/urlbar/tests/browser/browser_close_other_panels.js @@ -0,0 +1,42 @@ +/* Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * This tests that other panels close when the urlbar panel opens. + */ + +"use strict"; + +const { CustomizableUITestUtils } = ChromeUtils.importESModule( + "resource://testing-common/CustomizableUITestUtils.sys.mjs" +); +let gCUITestUtils = new CustomizableUITestUtils(window); + +add_task(async function () { + for (let openFn of [ + () => { + EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, {}); + }, + () => { + EventUtils.synthesizeKey("l", { accelKey: true }); + }, + ]) { + await gCUITestUtils.openMainMenu(); + Assert.equal( + PanelUI.panel.state, + "open", + "Check that panel state is 'open'" + ); + let promiseHidden = new Promise(resolve => { + PanelUI.panel.addEventListener("popuphidden", resolve, { once: true }); + }); + await UrlbarTestUtils.promisePopupOpen(window, openFn); + await promiseHidden; + Assert.equal( + PanelUI.panel.state, + "closed", + "Check that panel state is 'closed'" + ); + await UrlbarTestUtils.promisePopupClose(window); + } +}); diff --git a/xpfe/appshell/AppWindow.cpp b/xpfe/appshell/AppWindow.cpp index 65c21e9579f5..8f87bbd1fb8c 100644 --- a/xpfe/appshell/AppWindow.cpp +++ b/xpfe/appshell/AppWindow.cpp @@ -533,6 +533,13 @@ NS_IMETHODIMP AppWindow::ShowModal() { return mModalStatus; } +NS_IMETHODIMP AppWindow::RollupAllPopups() { + if (nsXULPopupManager* pm = nsXULPopupManager::GetInstance()) { + pm->Rollup({}); + } + return NS_OK; +} + //***************************************************************************** // AppWindow::nsIBaseWindow //***************************************************************************** diff --git a/xpfe/appshell/nsIAppWindow.idl b/xpfe/appshell/nsIAppWindow.idl index d373043bac89..0ef6425a2dde 100644 --- a/xpfe/appshell/nsIAppWindow.idl +++ b/xpfe/appshell/nsIAppWindow.idl @@ -152,4 +152,11 @@ interface nsIAppWindow : nsISupports * Since readback of Windows DirectComposition is very slow. */ void needFastSnaphot(); + + /** + * Ask the PopupManager to rollup all popups. + * Can be used by popup-like elements to close other popups when shown. + * Note that tooltips and noautohide popups won't be closed. + */ + void rollupAllPopups(); };