Bug 1352069 - Introduce a pref that allows for disabling cosmetic animations draft
authorJim Porter <jporter@mozilla.com>
Tue, 11 Apr 2017 13:47:31 -0500
changeset 564512 fb6c5d987764d2bb0629ac5008d353cff64ce6f1
parent 563687 05c212a94183838f12feebb2c3fd483a6eec18c2
child 624762 0d02a9c0f44305ba9ad3759793b0353c7ff677bc
push id54624
push userbmo:squibblyflabbetydoo@gmail.com
push dateTue, 18 Apr 2017 17:34:42 +0000
bugs1352069
milestone55.0a1
Bug 1352069 - Introduce a pref that allows for disabling cosmetic animations This rolls browser.tabs.animate, browser.fullscreen.animate, and alerts.disableSlidingEffect into a single pref; if any of these are disabled, we'll disable the new pref too (toolkit.cosmeticAnimations.enabled). Most future animations will also be subject to this pref. MozReview-Commit-ID: 77pLMtERDna
browser/app/profile/firefox.js
browser/base/content/browser-fullScreenAndPointerLock.js
browser/base/content/tabbrowser.xml
browser/base/content/test/general/browser_bug577121.js
browser/base/content/test/general/browser_tabkeynavigation.js
browser/components/nsBrowserGlue.js
browser/components/sessionstore/test/browser_crashedTabs.js
browser/components/sessionstore/test/browser_revive_crashed_bg_tabs.js
devtools/client/webconsole/test/browser_bug_871156_ctrlw_close_tab.js
modules/libpref/init/all.js
testing/marionette/client/marionette_driver/geckoinstance.py
testing/marionette/server.js
testing/talos/talos/tests/tabpaint/bootstrap.js
toolkit/components/alerts/resources/content/alert.js
toolkit/components/telemetry/TelemetryEnvironment.jsm
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -249,17 +249,16 @@ pref("browser.casting.enabled", false);
 pref("browser.chrome.site_icons", true);
 pref("browser.chrome.favicons", true);
 // browser.warnOnQuit == false will override all other possible prompts when quitting or restarting
 pref("browser.warnOnQuit", true);
 // browser.showQuitWarning specifically controls the quit warning dialog. We
 // might still show the window closing dialog with showQuitWarning == false.
 pref("browser.showQuitWarning", false);
 pref("browser.fullscreen.autohide", true);
-pref("browser.fullscreen.animate", true);
 pref("browser.overlink-delay", 80);
 
 #ifdef UNIX_BUT_NOT_MAC
 pref("browser.urlbar.clickSelectsAll", false);
 #else
 pref("browser.urlbar.clickSelectsAll", true);
 #endif
 #ifdef UNIX_BUT_NOT_MAC
@@ -439,17 +438,16 @@ pref("browser.tabs.warnOnClose", true);
 pref("browser.tabs.warnOnCloseOtherTabs", true);
 pref("browser.tabs.warnOnOpen", true);
 pref("browser.tabs.maxOpenBeforeWarn", 15);
 pref("browser.tabs.loadInBackground", true);
 pref("browser.tabs.opentabfor.middleclick", true);
 pref("browser.tabs.loadDivertedInBackground", false);
 pref("browser.tabs.loadBookmarksInBackground", false);
 pref("browser.tabs.tabClipWidth", 140);
-pref("browser.tabs.animate", true);
 #ifdef UNIX_BUT_NOT_MAC
 pref("browser.tabs.drawInTitlebar", false);
 #else
 pref("browser.tabs.drawInTitlebar", true);
 #endif
 
 // When tabs opened by links in other tabs via a combination of
 // browser.link.open_newwindow being set to 3 and target="_blank" etc are
--- a/browser/base/content/browser-fullScreenAndPointerLock.js
+++ b/browser/base/content/browser-fullScreenAndPointerLock.js
@@ -588,17 +588,17 @@ var FullScreen = {
   },
 
   hideNavToolbox(aAnimate = false) {
     if (this._isChromeCollapsed || !this._safeToCollapse())
       return;
 
     this._fullScrToggler.hidden = false;
 
-    if (aAnimate && gPrefService.getBoolPref("browser.fullscreen.animate")) {
+    if (aAnimate && gPrefService.getBoolPref("toolkit.cosmeticAnimations.enabled")) {
       gNavToolbox.setAttribute("fullscreenShouldAnimate", true);
       // Hide the fullscreen toggler until the transition ends.
       let listener = () => {
         gNavToolbox.removeEventListener("transitionend", listener, true);
         if (this._isChromeCollapsed)
           this._fullScrToggler.hidden = false;
       };
       gNavToolbox.addEventListener("transitionend", listener, true);
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2237,17 +2237,17 @@
 
             this.tabContainer._unlockTabSizing();
 
             // When overflowing, new tabs are scrolled into view smoothly, which
             // doesn't go well together with the width transition. So we skip the
             // transition in that case.
             let animate = !aSkipAnimation &&
                           this.tabContainer.getAttribute("overflow") != "true" &&
-                          Services.prefs.getBoolPref("browser.tabs.animate");
+                          Services.prefs.getBoolPref("toolkit.cosmeticAnimations.enabled");
             if (!animate) {
               t.setAttribute("fadein", "true");
               setTimeout(function(tabContainer) {
                 tabContainer._handleNewTab(t);
               }, 0, this.tabContainer);
             }
 
             // invalidate cache
@@ -2589,17 +2589,17 @@
 
             if (!animate /* the caller didn't opt in */ ||
                 isLastTab ||
                 aTab.pinned ||
                 aTab.hidden ||
                 this._removingTabs.length > 3 /* don't want lots of concurrent animations */ ||
                 aTab.getAttribute("fadein") != "true" /* fade-in transition hasn't been triggered yet */ ||
                 window.getComputedStyle(aTab).maxWidth == "0.1px" /* fade-in transition hasn't moved yet */ ||
-                !Services.prefs.getBoolPref("browser.tabs.animate")) {
+                !Services.prefs.getBoolPref("toolkit.cosmeticAnimations.enabled")) {
               // We're not animating, so we can cancel the animation stopwatch.
               TelemetryStopwatch.cancel("FX_TAB_CLOSE_TIME_ANIM_MS", aTab);
               this._endRemoveTab(aTab);
               return;
             }
 
             // We're animating, so we can cancel the non-animation stopwatch.
             TelemetryStopwatch.cancel("FX_TAB_CLOSE_TIME_NO_ANIM_MS", aTab);
--- a/browser/base/content/test/general/browser_bug577121.js
+++ b/browser/base/content/test/general/browser_bug577121.js
@@ -1,16 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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 test() {
-  Services.prefs.setBoolPref("browser.tabs.animate", false);
+  Services.prefs.setBoolPref("toolkit.cosmeticAnimations.enabled", false);
   registerCleanupFunction(function() {
-    Services.prefs.clearUserPref("browser.tabs.animate");
+    Services.prefs.clearUserPref("toolkit.cosmeticAnimations.enabled");
   });
 
   // Open 2 other tabs, and pin the second one. Like that, the initial tab
   // should get closed.
   let testTab1 = gBrowser.addTab();
   let testTab2 = gBrowser.addTab();
   gBrowser.pinTab(testTab2);
 
--- a/browser/base/content/test/general/browser_tabkeynavigation.js
+++ b/browser/base/content/test/general/browser_tabkeynavigation.js
@@ -8,17 +8,17 @@ add_task(function* test() {
   let testPage3 = "data:text/html,<html id='tab3'><body><button id='button3'>Tab 3</button></body></html>";
 
   let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, testPage1);
   let browser1 = gBrowser.getBrowserForTab(tab1);
   let tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, testPage2);
   let tab3 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, testPage3);
 
   // Kill the animation for simpler test.
-  Services.prefs.setBoolPref("browser.tabs.animate", false);
+  Services.prefs.setBoolPref("toolkit.cosmeticAnimations.enabled", false);
 
   gBrowser.selectedTab = tab1;
   browser1.focus();
 
   is(gBrowser.selectedTab, tab1,
      "Tab1 should be activated");
   EventUtils.synthesizeKey("VK_TAB", { ctrlKey: true });
   is(gBrowser.selectedTab, tab2,
@@ -147,10 +147,10 @@ add_task(function* test() {
         "The count of tabs should be 3 since renaming key events shouldn't close other tabs");
   }
 
   gBrowser.selectedTab = tab3;
   while (gBrowser.tabs.length > 1) {
     gBrowser.removeCurrentTab();
   }
 
-    Services.prefs.clearUserPref("browser.tabs.animate");
+    Services.prefs.clearUserPref("toolkit.cosmeticAnimations.enabled");
 });
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1563,17 +1563,17 @@ BrowserGlue.prototype = {
       if (topic != "alertclickcallback")
         return;
       this._openPreferences("sync");
     }
     AlertsService.showAlertNotification(null, title, body, true, null, clickCallback);
   },
 
   _migrateUI: function BG__migrateUI() {
-    const UI_VERSION = 43;
+    const UI_VERSION = 44;
     const BROWSER_DOCURL = "chrome://browser/content/browser.xul";
 
     let currentUIVersion;
     if (Services.prefs.prefHasUserValue("browser.migration.version")) {
       currentUIVersion = Services.prefs.getIntPref("browser.migration.version");
     } else {
       // This is a new profile, nothing to migrate.
       Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
@@ -1847,16 +1847,30 @@ BrowserGlue.prototype = {
       let currentTheme = Services.prefs.getCharPref("lightweightThemes.selectedThemeID", "");
       if (currentTheme == "firefox-devedition@mozilla.org") {
         let newTheme = Services.prefs.getCharPref("devtools.theme") == "dark" ?
           "firefox-compact-dark@mozilla.org" : "firefox-compact-light@mozilla.org";
         Services.prefs.setCharPref("lightweightThemes.selectedThemeID", newTheme);
       }
     }
 
+    if (currentUIVersion < 44) {
+      // Merge the various cosmetic animation prefs into one. If any were set to
+      // disable animations, we'll disabled cosmetic animations entirely.
+      let animate = Services.prefs.getBoolPref("browser.tabs.animate", true) &&
+                    Services.prefs.getBoolPref("browser.fullscreen.animate", true) &&
+                    !Services.prefs.getBoolPref("alerts.disableSlidingEffect", false);
+
+      Services.prefs.setBoolPref("toolkit.cosmeticAnimations.enabled", animate);
+
+      Services.prefs.clearUserPref("browser.tabs.animate");
+      Services.prefs.clearUserPref("browser.fullscreen.animate");
+      Services.prefs.clearUserPref("browser.tabs.animate");
+    }
+
     // Update the migration version.
     Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
   },
 
   _hasExistingNotificationPermission: function BG__hasExistingNotificationPermission() {
     let enumerator = Services.perms.enumerator;
     while (enumerator.hasMoreElements()) {
       let permission = enumerator.getNext().QueryInterface(Ci.nsIPermission);
--- a/browser/components/sessionstore/test/browser_crashedTabs.js
+++ b/browser/components/sessionstore/test/browser_crashedTabs.js
@@ -11,17 +11,17 @@ requestLongerTimeout(10);
 const PAGE_1 = "data:text/html,<html><body>A%20regular,%20everyday,%20normal%20page.";
 const PAGE_2 = "data:text/html,<html><body>Another%20regular,%20everyday,%20normal%20page.";
 
 // Turn off tab animations for testing and use a single content process
 // for these tests since we want to test tabs within the crashing process here.
 add_task(function* test_initialize() {
   yield SpecialPowers.pushPrefEnv({
     set: [
-      [ "browser.tabs.animate", false]
+      [ "toolkit.cosmeticAnimations.enabled", false]
   ] });
 });
 
 // Allow tabs to restore on demand so we can test pending states
 Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
 
 function clickButton(browser, id) {
   info("Clicking " + id);
--- a/browser/components/sessionstore/test/browser_revive_crashed_bg_tabs.js
+++ b/browser/components/sessionstore/test/browser_revive_crashed_bg_tabs.js
@@ -9,17 +9,17 @@
 
 "use strict";
 
 const PAGE_1 = "data:text/html,<html><body>A%20regular,%20everyday,%20normal%20page.";
 const PAGE_2 = "data:text/html,<html><body>Another%20regular,%20everyday,%20normal%20page.";
 
 add_task(function* setup() {
   yield pushPrefs(["dom.ipc.processCount", 1],
-                  ["browser.tabs.animate", false],
+                  ["toolkit.cosmeticAnimations.enabled", false],
                   ["browser.sessionstore.restore_on_demand", false]);
 });
 
 add_task(function* test_revive_bg_tabs_on_demand() {
   let newTab1 = gBrowser.addTab(PAGE_1);
   let browser1 = newTab1.linkedBrowser;
   gBrowser.selectedTab = newTab1;
 
--- a/devtools/client/webconsole/test/browser_bug_871156_ctrlw_close_tab.js
+++ b/devtools/client/webconsole/test/browser_bug_871156_ctrlw_close_tab.js
@@ -8,19 +8,19 @@
 
 "use strict";
 
 add_task(function* () {
   const TEST_URI = "data:text/html;charset=utf8,<title>bug871156</title>\n" +
                    "<p>hello world";
   let firstTab = gBrowser.selectedTab;
 
-  Services.prefs.setBoolPref("browser.tabs.animate", false);
+  Services.prefs.setBoolPref("toolkit.cosmeticAnimations.enabled", false);
   registerCleanupFunction(() => {
-    Services.prefs.clearUserPref("browser.tabs.animate");
+    Services.prefs.clearUserPref("toolkit.cosmeticAnimations.enabled");
   });
 
   yield loadTab(TEST_URI);
 
   let hud = yield openConsole();
   ok(hud, "Web Console opened");
 
   let tabClosed = promise.defer();
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -939,16 +939,18 @@ pref("findbar.iteratorTimeout", 100);
 pref("gfx.use_text_smoothing_setting", false);
 
 // Number of characters to consider emphasizing for rich autocomplete results
 pref("toolkit.autocomplete.richBoundaryCutoff", 200);
 
 // Variable controlling logging for osfile.
 pref("toolkit.osfile.log", false);
 
+pref("toolkit.cosmeticAnimations.enabled", true);
+
 pref("toolkit.scrollbox.smoothScroll", true);
 pref("toolkit.scrollbox.scrollIncrement", 20);
 pref("toolkit.scrollbox.verticalScrollDistance", 3);
 pref("toolkit.scrollbox.horizontalScrollDistance", 5);
 pref("toolkit.scrollbox.clickToScroll.scrollDelay", 150);
 
 // Telemetry settings.
 // Server to submit telemetry pings to.
@@ -4817,18 +4819,16 @@ pref("dom.webnotifications.enabled", tru
 pref("dom.webnotifications.serviceworker.enabled", true);
 pref("dom.webnotifications.requireinteraction.count", 3);
 #ifdef NIGHTLY_BUILD
 pref("dom.webnotifications.requireinteraction.enabled", true);
 #else
 pref("dom.webnotifications.requireinteraction.enabled", false);
 #endif
 
-// Alert animation effect, name is disableSlidingEffect for backwards-compat.
-pref("alerts.disableSlidingEffect", false);
 // Show favicons in web notifications.
 pref("alerts.showFavicons", false);
 
 // DOM full-screen API.
 pref("full-screen-api.enabled", false);
 #ifdef RELEASE_OR_BETA
 pref("full-screen-api.unprefix.enabled", false);
 #else
--- a/testing/marionette/client/marionette_driver/geckoinstance.py
+++ b/testing/marionette/client/marionette_driver/geckoinstance.py
@@ -453,18 +453,18 @@ class DesktopInstance(GeckoInstance):
         "browser.tabs.remote.autostart.2": False,
         "browser.tabs.remote.autostart": False,
 
         # Needed for branded builds to prevent opening a second tab on startup
         "browser.startup.homepage_override.mstone": "ignore",
         # Start with a blank page by default
         "browser.startup.page": 0,
 
-        # Disable tab animation
-        "browser.tabs.animate": False,
+        # Disable browser animations
+        "toolkit.cosmeticAnimations.enabled": False,
 
         # Do not warn on exit when multiple tabs are open
         "browser.tabs.warnOnClose": False,
         # Do not warn when closing all other open tabs
         "browser.tabs.warnOnCloseOtherTabs": False,
         # Do not warn when multiple tabs will be opened
         "browser.tabs.warnOnOpen": False,
 
--- a/testing/marionette/server.js
+++ b/testing/marionette/server.js
@@ -121,18 +121,18 @@ const RECOMMENDED_PREFS = new Map([
   ["browser.shell.checkDefaultBrowser", false],
 
   // Start with a blank page (about:blank)
   ["browser.startup.page", 0],
 
   // Do not redirect user when a milstone upgrade of Firefox is detected
   ["browser.startup.homepage_override.mstone", "ignore"],
 
-  // Disable tab animation
-  ["browser.tabs.animate", false],
+  // Disable browser animations
+  ["toolkit.cosmeticAnimations.enabled", false],
 
   // Do not allow background tabs to be zombified, otherwise for tests
   // that open additional tabs, the test harness tab itself might get
   // unloaded
   ["browser.tabs.disableBackgroundZombification", false],
 
   // Do not warn when closing all other open tabs
   ["browser.tabs.warnOnCloseOtherTabs", false],
--- a/testing/talos/talos/tests/tabpaint/bootstrap.js
+++ b/testing/talos/talos/tests/tabpaint/bootstrap.js
@@ -21,17 +21,17 @@
  */
 
 var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
 Cu.import("resource:///modules/RecentWindow.jsm");
 
-const TAB_ANIMATION_PREF = "browser.tabs.animate";
+const ANIMATION_PREF = "toolkit.cosmeticAnimations.enabled";
 
 const PROCESS_COUNT_PREF = "dom.ipc.processCount";
 
 const TARGET_URI = "chrome://tabpaint/content/target.html";
 
 var TabPaint = {
   MESSAGES: [
     "TabPaint:Go",
@@ -65,28 +65,28 @@ var TabPaint = {
     // not be any browser windows around. Since pageloader is loading
     // this add-on, along with the tabpaint.html content, what we'll do
     // is wait for the tabpaint.html content to send us a message to
     // get us moving.
     for (let msgName of this.MESSAGES) {
       Services.mm.addMessageListener(msgName, this);
     }
 
-    this.originalTabsAnimate = Services.prefs.getBoolPref(TAB_ANIMATION_PREF);
-    Services.prefs.setBoolPref(TAB_ANIMATION_PREF, false);
+    this.originalAnimate = Services.prefs.getBoolPref(ANIMATION_PREF);
+    Services.prefs.setBoolPref(ANIMATION_PREF, false);
     this.originalProcessCount = Services.prefs.getIntPref(PROCESS_COUNT_PREF);
     Services.prefs.setIntPref(PROCESS_COUNT_PREF, 1);
   },
 
   uninit() {
     for (let msgName of this.MESSAGES) {
       Services.mm.removeMessageListener(msgName, this);
     }
 
-    Services.prefs.setBoolPref(TAB_ANIMATION_PREF, this.originalTabsAnimate);
+    Services.prefs.setBoolPref(ANIMATION_PREF, this.originalAnimate);
     Services.prefs.setIntPref(PROCESS_COUNT_PREF, this.originalProcessCount);
   },
 
   receiveMessage(msg) {
     let browser = msg.target;
 
     let gBrowser = browser.ownerGlobal.gBrowser;
 
--- a/toolkit/components/alerts/resources/content/alert.js
+++ b/toolkit/components/alerts/resources/content/alert.js
@@ -164,17 +164,17 @@ function onAlertLoad() {
   } else {
     moveWindowToEnd();
   }
 
   window.addEventListener("XULAlertClose", function() { window.close(); });
 
   // If the require interaction flag is set, prevent auto-closing the notification.
   if (!gRequireInteraction) {
-    if (Services.prefs.getBoolPref("alerts.disableSlidingEffect")) {
+    if (!Services.prefs.getBoolPref("toolkit.cosmeticAnimations.enabled")) {
       setTimeout(function() { window.close(); }, ALERT_DURATION_IMMEDIATE);
     } else {
       let alertBox = document.getElementById("alertBox");
       alertBox.addEventListener("animationend", function hideAlert(event) {
         if (event.animationName == "alert-animation" ||
             event.animationName == "alert-clicked-animation" ||
             event.animationName == "alert-closing-animation") {
           alertBox.removeEventListener("animationend", hideAlert);
--- a/toolkit/components/telemetry/TelemetryEnvironment.jsm
+++ b/toolkit/components/telemetry/TelemetryEnvironment.jsm
@@ -173,17 +173,17 @@ const DEFAULT_ENVIRONMENT_PREFS = new Ma
   ["browser.formfill.enable", {what: RECORD_PREF_VALUE}],
   ["browser.newtabpage.enabled", {what: RECORD_PREF_VALUE}],
   ["browser.newtabpage.enhanced", {what: RECORD_PREF_VALUE}],
   ["browser.shell.checkDefaultBrowser", {what: RECORD_PREF_VALUE}],
   ["browser.search.ignoredJAREngines", {what: RECORD_DEFAULTPREF_VALUE}],
   ["browser.search.suggest.enabled", {what: RECORD_PREF_VALUE}],
   ["browser.startup.homepage", {what: RECORD_PREF_STATE}],
   ["browser.startup.page", {what: RECORD_PREF_VALUE}],
-  ["browser.tabs.animate", {what: RECORD_PREF_VALUE}],
+  ["toolkit.cosmeticAnimations.enabled", {what: RECORD_PREF_VALUE}],
   ["browser.urlbar.suggest.searches", {what: RECORD_PREF_VALUE}],
   ["browser.urlbar.userMadeSearchSuggestionsChoice", {what: RECORD_PREF_VALUE}],
   ["devtools.chrome.enabled", {what: RECORD_PREF_VALUE}],
   ["devtools.debugger.enabled", {what: RECORD_PREF_VALUE}],
   ["devtools.debugger.remote-enabled", {what: RECORD_PREF_VALUE}],
   ["dom.ipc.plugins.asyncInit.enabled", {what: RECORD_PREF_VALUE}],
   ["dom.ipc.plugins.enabled", {what: RECORD_PREF_VALUE}],
   ["dom.ipc.processCount", {what: RECORD_PREF_VALUE, requiresRestart: true}],