mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 15:25:52 +00:00
Bug 1712306 - add telemetry for the close multiple tabs modal, r=jaws
Differential Revision: https://phabricator.services.mozilla.com/D115840
This commit is contained in:
parent
c329fa104b
commit
1d7f4797cd
@ -33,11 +33,11 @@
|
||||
<command id="cmd_file_importFromAnotherBrowser" oncommand="MigrationUtils.showMigrationWizard(window, [MigrationUtils.MIGRATION_ENTRYPOINT_FILE_MENU]);"/>
|
||||
<command id="cmd_help_importFromAnotherBrowser" oncommand="MigrationUtils.showMigrationWizard(window, [MigrationUtils.MIGRATION_ENTRYPOINT_HELP_MENU]);"/>
|
||||
<command id="cmd_close" oncommand="BrowserCloseTabOrWindow(event);"/>
|
||||
<command id="cmd_closeWindow" oncommand="BrowserTryToCloseWindow()"/>
|
||||
<command id="cmd_closeWindow" oncommand="BrowserTryToCloseWindow(event)"/>
|
||||
<command id="cmd_toggleMute" oncommand="gBrowser.toggleMuteAudioOnMultiSelectedTabs(gBrowser.selectedTab)"/>
|
||||
<command id="cmd_CustomizeToolbars" oncommand="gCustomizeMode.enter()"/>
|
||||
<command id="cmd_toggleOfflineStatus" oncommand="BrowserOffline.toggleOfflineStatus();"/>
|
||||
<command id="cmd_quitApplication" oncommand="goQuitApplication()"/>
|
||||
<command id="cmd_quitApplication" oncommand="goQuitApplication(event)"/>
|
||||
|
||||
<command id="View:PageSource" oncommand="BrowserViewSource(window.gBrowser.selectedBrowser);"/>
|
||||
<command id="View:PageInfo" oncommand="BrowserPageInfo();"/>
|
||||
|
@ -3043,8 +3043,8 @@ function BrowserCloseTabOrWindow(event) {
|
||||
gBrowser.removeCurrentTab({ animate: true });
|
||||
}
|
||||
|
||||
function BrowserTryToCloseWindow() {
|
||||
if (WindowIsClosing()) {
|
||||
function BrowserTryToCloseWindow(event) {
|
||||
if (WindowIsClosing(event)) {
|
||||
window.close();
|
||||
} // WindowIsClosing does all the necessary checks
|
||||
}
|
||||
@ -7860,8 +7860,20 @@ function CanCloseWindow() {
|
||||
return true;
|
||||
}
|
||||
|
||||
function WindowIsClosing() {
|
||||
if (!closeWindow(false, warnAboutClosingWindow)) {
|
||||
function WindowIsClosing(event) {
|
||||
let source;
|
||||
if (event) {
|
||||
let target = event.sourceEvent?.target;
|
||||
if (target?.id?.startsWith("menu_")) {
|
||||
source = "menuitem";
|
||||
} else if (target?.nodeName == "toolbarbutton") {
|
||||
source = "close-button";
|
||||
} else {
|
||||
let key = AppConstants.platform == "macosx" ? "metaKey" : "ctrlKey";
|
||||
source = event[key] ? "shortcut" : "OS";
|
||||
}
|
||||
}
|
||||
if (!closeWindow(false, warnAboutClosingWindow, source)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -7883,9 +7895,11 @@ function WindowIsClosing() {
|
||||
/**
|
||||
* Checks if this is the last full *browser* window around. If it is, this will
|
||||
* be communicated like quitting. Otherwise, we warn about closing multiple tabs.
|
||||
*
|
||||
* @param source where the request to close came from (used for telemetry)
|
||||
* @returns true if closing can proceed, false if it got cancelled.
|
||||
*/
|
||||
function warnAboutClosingWindow() {
|
||||
function warnAboutClosingWindow(source) {
|
||||
// Popups aren't considered full browser windows; we also ignore private windows.
|
||||
let isPBWindow =
|
||||
PrivateBrowsingUtils.isWindowPrivate(window) &&
|
||||
@ -7896,7 +7910,8 @@ function warnAboutClosingWindow() {
|
||||
if (!isPBWindow && !toolbar.visible) {
|
||||
return gBrowser.warnAboutClosingTabs(
|
||||
closingTabs,
|
||||
gBrowser.closingTabsEnum.ALL
|
||||
gBrowser.closingTabsEnum.ALL,
|
||||
source
|
||||
);
|
||||
}
|
||||
|
||||
@ -7934,7 +7949,11 @@ function warnAboutClosingWindow() {
|
||||
if (otherWindowExists) {
|
||||
return (
|
||||
isPBWindow ||
|
||||
gBrowser.warnAboutClosingTabs(closingTabs, gBrowser.closingTabsEnum.ALL)
|
||||
gBrowser.warnAboutClosingTabs(
|
||||
closingTabs,
|
||||
gBrowser.closingTabsEnum.ALL,
|
||||
source
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ -7956,7 +7975,11 @@ function warnAboutClosingWindow() {
|
||||
return (
|
||||
AppConstants.platform != "macosx" ||
|
||||
isPBWindow ||
|
||||
gBrowser.warnAboutClosingTabs(closingTabs, gBrowser.closingTabsEnum.ALL)
|
||||
gBrowser.warnAboutClosingTabs(
|
||||
closingTabs,
|
||||
gBrowser.closingTabsEnum.ALL,
|
||||
source
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -2124,7 +2124,7 @@
|
||||
|
||||
<toolbarbutton id="close-button"
|
||||
data-l10n-id="browser-window-close-button"
|
||||
oncommand="BrowserTryToCloseWindow();"/>
|
||||
oncommand="BrowserTryToCloseWindow(event);"/>
|
||||
</hbox>
|
||||
</toolbar>
|
||||
|
||||
|
@ -3108,7 +3108,7 @@
|
||||
}
|
||||
},
|
||||
|
||||
warnAboutClosingTabs(tabsToClose, aCloseTabs) {
|
||||
warnAboutClosingTabs(tabsToClose, aCloseTabs, aSource) {
|
||||
if (tabsToClose <= 1) {
|
||||
return true;
|
||||
}
|
||||
@ -3171,6 +3171,40 @@
|
||||
checkboxLabel,
|
||||
warnOnClose
|
||||
);
|
||||
|
||||
Services.telemetry.setEventRecordingEnabled("close_tab_warning", true);
|
||||
let closeTabEnumKey =
|
||||
Object.entries(this.closingTabsEnum)
|
||||
.find(([k, v]) => v == aCloseTabs)?.[0]
|
||||
?.toLowerCase() || "some";
|
||||
|
||||
let warnCheckbox = warnOnClose.value ? "checked" : "unchecked";
|
||||
if (!checkboxLabel) {
|
||||
warnCheckbox = "not-present";
|
||||
}
|
||||
let sessionWillBeRestored =
|
||||
Services.prefs.getIntPref("browser.startup.page") == 3 ||
|
||||
Services.prefs.getBoolPref("browser.sessionstore.resume_session_once");
|
||||
let closesWindow = aCloseTabs == this.closingTabsEnum.ALL;
|
||||
Services.telemetry.recordEvent(
|
||||
"close_tab_warning",
|
||||
"shown",
|
||||
closesWindow ? "window" : "tabs",
|
||||
null,
|
||||
{
|
||||
source: aSource || `close-${closeTabEnumKey}-tabs`,
|
||||
button: buttonPressed == 0 ? "close" : "cancel",
|
||||
warn_checkbox: warnCheckbox,
|
||||
closing_tabs: "" + tabsToClose,
|
||||
closing_wins: "" + +closesWindow, // ("1" or "0", depending on the value)
|
||||
// This value doesn't really apply to whether this warning
|
||||
// gets shown, but having pings be consistent (and perhaps
|
||||
// being able to see trends for users with/without sessionrestore)
|
||||
// seems useful:
|
||||
will_restore: sessionWillBeRestored ? "yes" : "no",
|
||||
}
|
||||
);
|
||||
|
||||
var reallyClose = buttonPressed == 0;
|
||||
|
||||
// don't set the pref unless they press OK and it's false
|
||||
@ -3399,7 +3433,8 @@
|
||||
) {
|
||||
window.closeWindow(
|
||||
true,
|
||||
suppressWarnAboutClosingWindow ? null : window.warnAboutClosingWindow
|
||||
suppressWarnAboutClosingWindow ? null : window.warnAboutClosingWindow,
|
||||
"close-last-tab"
|
||||
);
|
||||
return;
|
||||
}
|
||||
@ -3725,7 +3760,8 @@
|
||||
// cancels the operation. We are finished here in both cases.
|
||||
this._windowIsClosing = window.closeWindow(
|
||||
true,
|
||||
window.warnAboutClosingWindow
|
||||
window.warnAboutClosingWindow,
|
||||
"close-last-tab"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@ -3991,7 +4027,8 @@
|
||||
if (aCloseWindow) {
|
||||
this._windowIsClosing = closeWindow(
|
||||
true,
|
||||
window.warnAboutClosingWindow
|
||||
window.warnAboutClosingWindow,
|
||||
"close-last-tab"
|
||||
);
|
||||
}
|
||||
},
|
||||
|
@ -2694,6 +2694,11 @@ BrowserGlue.prototype = {
|
||||
);
|
||||
},
|
||||
|
||||
_quitSource: "unknown",
|
||||
_registerQuitSource(source) {
|
||||
this._quitSource = source;
|
||||
},
|
||||
|
||||
_onQuitRequest: function BG__onQuitRequest(aCancelQuit, aQuitType) {
|
||||
// If user has already dismissed quit request, then do nothing
|
||||
if (aCancelQuit instanceof Ci.nsISupportsPRBool && aCancelQuit.data) {
|
||||
@ -2722,6 +2727,7 @@ BrowserGlue.prototype = {
|
||||
|
||||
var windowcount = 0;
|
||||
var pagecount = 0;
|
||||
let pinnedcount = 0;
|
||||
for (let win of BrowserWindowTracker.orderedWindows) {
|
||||
if (win.closed) {
|
||||
continue;
|
||||
@ -2729,6 +2735,7 @@ BrowserGlue.prototype = {
|
||||
windowcount++;
|
||||
let tabbrowser = win.gBrowser;
|
||||
if (tabbrowser) {
|
||||
pinnedcount += tabbrowser._numPinnedTabs;
|
||||
pagecount +=
|
||||
tabbrowser.browsers.length -
|
||||
tabbrowser._numPinnedTabs -
|
||||
@ -2826,6 +2833,28 @@ BrowserGlue.prototype = {
|
||||
checkboxLabel,
|
||||
warnOnClose
|
||||
);
|
||||
Services.telemetry.setEventRecordingEnabled("close_tab_warning", true);
|
||||
let warnCheckbox = warnOnClose.value ? "checked" : "unchecked";
|
||||
if (!checkboxLabel) {
|
||||
warnCheckbox = "not-present";
|
||||
}
|
||||
Services.telemetry.recordEvent(
|
||||
"close_tab_warning",
|
||||
"shown",
|
||||
"application",
|
||||
null,
|
||||
{
|
||||
source: this._quitSource,
|
||||
button: buttonPressed == 0 ? "close" : "cancel",
|
||||
warn_checkbox: warnCheckbox,
|
||||
closing_wins: "" + windowcount,
|
||||
closing_tabs: "" + (pagecount + pinnedcount),
|
||||
will_restore: sessionWillBeRestored ? "yes" : "no",
|
||||
}
|
||||
);
|
||||
|
||||
this._quitSource = "unknown";
|
||||
|
||||
// If the user has unticked the box, and has confirmed closing, stop showing
|
||||
// the warning.
|
||||
if (!sessionWillBeRestored && buttonPressed == 0 && !warnOnClose.value) {
|
||||
|
@ -2896,3 +2896,25 @@ contextservices.quicksuggest:
|
||||
notification_emails:
|
||||
- fx-search@mozilla.com
|
||||
expiry_version: never
|
||||
|
||||
close_tab_warning:
|
||||
shown:
|
||||
description: >
|
||||
Recorded whenever we show the 'Close Tabs' dialog, with details about
|
||||
the reason it is shown and what choices the user makes (close or not).
|
||||
objects: ["window", "application", "tabs"]
|
||||
release_channel_collection: opt-out
|
||||
expiry_version: "94"
|
||||
record_in_processes: ["main"]
|
||||
products: ["firefox"]
|
||||
bug_numbers: [1712306]
|
||||
notification_emails:
|
||||
- gkruitbosch@mozilla.com
|
||||
- rtestard@mozilla.com
|
||||
extra_keys:
|
||||
source: The way in which the tabs were closed (shortcut, close button, menuitem, appmenu, etc.)
|
||||
button: Which button the user clicked (Close tabs or Cancel)
|
||||
warn_checkbox: Whether the checkbox to display the warning again was checked or not.
|
||||
closing_wins: The number of windows being closed.
|
||||
closing_tabs: The number of tabs being closed.
|
||||
will_restore: Whether the session will be restored if closed now.
|
||||
|
@ -2,7 +2,7 @@
|
||||
* 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/. */
|
||||
|
||||
function closeWindow(aClose, aPromptFunction) {
|
||||
function closeWindow(aClose, aPromptFunction, aSource) {
|
||||
let { AppConstants } = ChromeUtils.import(
|
||||
"resource://gre/modules/AppConstants.jsm"
|
||||
);
|
||||
@ -20,17 +20,20 @@ function closeWindow(aClose, aPromptFunction) {
|
||||
}
|
||||
|
||||
// If we're down to the last window and someone tries to shut down, check to make sure we can!
|
||||
if (windowCount == 1 && !canQuitApplication("lastwindow")) {
|
||||
if (windowCount == 1 && !canQuitApplication("lastwindow", aSource)) {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
windowCount != 1 &&
|
||||
typeof aPromptFunction == "function" &&
|
||||
!aPromptFunction()
|
||||
!aPromptFunction(aSource)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
} else if (typeof aPromptFunction == "function" && !aPromptFunction()) {
|
||||
} else if (
|
||||
typeof aPromptFunction == "function" &&
|
||||
!aPromptFunction(aSource)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -42,7 +45,12 @@ function closeWindow(aClose, aPromptFunction) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function canQuitApplication(aData) {
|
||||
function canQuitApplication(aData, aSource) {
|
||||
const kCID = "@mozilla.org/browser/browserglue;1";
|
||||
if (kCID in Cc && !(aData || "").includes("restart")) {
|
||||
let BrowserGlue = Cc[kCID].getService(Ci.nsISupports).wrappedJSObject;
|
||||
BrowserGlue._registerQuitSource(aSource);
|
||||
}
|
||||
try {
|
||||
var cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(
|
||||
Ci.nsISupportsPRBool
|
||||
@ -61,8 +69,22 @@ function canQuitApplication(aData) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function goQuitApplication() {
|
||||
if (!canQuitApplication()) {
|
||||
function goQuitApplication(event) {
|
||||
// We can't know for sure if the user used a shortcut to trigger quit.
|
||||
// Proxy by means of checking for the shortcut modifier.
|
||||
let isMac = navigator.platform.startsWith("Mac");
|
||||
let key = isMac ? "metaKey" : "ctrlKey";
|
||||
let source = "OS";
|
||||
if (event[key]) {
|
||||
source = "shortcut";
|
||||
// Note that macOS likes pretending something came from this menu even if
|
||||
// activated by keyboard shortcut, hence checking that first.
|
||||
} else if (event.sourceEvent?.target?.id?.startsWith("menu_")) {
|
||||
source = "menuitem";
|
||||
} else if (event.sourceEvent?.target?.id?.startsWith("appMenu")) {
|
||||
source = "appmenu";
|
||||
}
|
||||
if (!canQuitApplication(undefined, source)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user