Bug 1504766 - Let explicit Dark and Light themes ignore the Windows 10 setting for accent color in title bars. r=ntim,Gijs a=lizzard
authorDão Gottwald <dao@mozilla.com>
Wed, 20 Feb 2019 07:20:52 +0000
changeset 516104 b9fe883c6c1e
parent 516103 fa6574ad741f
child 516105 3c75057cd305
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersntim, Gijs, lizzard
bugs1504766
milestone66.0
Bug 1504766 - Let explicit Dark and Light themes ignore the Windows 10 setting for accent color in title bars. r=ntim,Gijs a=lizzard Differential Revision: https://phabricator.services.mozilla.com/D19764
browser/themes/windows/browser-aero.css
browser/themes/windows/compacttheme.css
toolkit/modules/LightweightThemeConsumer.jsm
toolkit/mozapps/extensions/LightweightThemeManager.jsm
--- a/browser/themes/windows/browser-aero.css
+++ b/browser/themes/windows/browser-aero.css
@@ -65,20 +65,25 @@
             color: hsl(240,9%,98%);
           }
         }
 
         @media (-moz-windows-accent-color-in-titlebar) {
           :root[sizemode=normal][tabsintitlebar] {
             border-top: 1px solid -moz-win-accentcolor;
           }
-          :root[tabsintitlebar]:not(:-moz-window-inactive):not(:-moz-lwtheme) {
+          :root[tabsintitlebar]:not(:-moz-window-inactive):not(:-moz-lwtheme),
+          :root[tabsintitlebar]:not(:-moz-window-inactive)[lwt-default-theme-in-dark-mode] {
             background-color: -moz-win-accentcolor;
             color: -moz-win-accentcolortext;
           }
+          :root[tabsintitlebar][lwt-default-theme-in-dark-mode] #titlebar {
+            --lwt-toolbarbutton-icon-fill: currentColor;
+            --toolbarbutton-icon-fill-opacity: .7;
+          }
         }
 
         :root[sizemode=normal][tabsintitlebar]:-moz-window-inactive {
           border-top-color: rgba(0,0,0,.3);
         }
 
         :root[tabsintitlebar] .tab-label:-moz-window-inactive {
           /* Calculated to match the opacity change of Windows Explorer
--- a/browser/themes/windows/compacttheme.css
+++ b/browser/themes/windows/compacttheme.css
@@ -1,25 +1,14 @@
 % 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/.
 
 %include ../shared/compacttheme.inc.css
 
-@media (-moz-windows-default-theme) and (-moz-windows-accent-color-in-titlebar) {
-  :root[tabsintitlebar]:not(:-moz-window-inactive) {
-    background-color: -moz-win-accentcolor;
-    color: -moz-win-accentcolortext;
-  }
-  :root[tabsintitlebar] #titlebar {
-    --lwt-toolbarbutton-icon-fill: currentColor;
-    --toolbarbutton-icon-fill-opacity: .7;
-  }
-}
-
 /* The window background is white due to no accentcolor in the lightweight
    theme. It can't be changed to transparent when there is no compositor
    (Win 7 in classic / basic theme), or else dragging and focus become
    broken. So instead just show the normal titlebar in that case, and override
    the window color as transparent when the compositor is available. */
 @media (-moz-windows-compositor: 0) {
   :root[tabsintitlebar]:not([inDOMFullscreen]) > #navigator-toolbox > #titlebar:-moz-lwtheme {
     visibility: visible;
--- a/toolkit/modules/LightweightThemeConsumer.jsm
+++ b/toolkit/modules/LightweightThemeConsumer.jsm
@@ -109,26 +109,26 @@ ChromeUtils.defineModuleGetter(this, "Li
 
 function LightweightThemeConsumer(aDocument) {
   this._doc = aDocument;
   this._win = aDocument.defaultView;
   this._winId = this._win.windowUtils.outerWindowID;
 
   Services.obs.addObserver(this, "lightweight-theme-styling-update");
 
-  var temp = {};
-  ChromeUtils.import("resource://gre/modules/LightweightThemeManager.jsm", temp);
-  this._update(temp.LightweightThemeManager.currentThemeWithPersistedData);
+  ChromeUtils.import("resource://gre/modules/LightweightThemeManager.jsm", this);
+
+  this._darkThemeMediaQuery = this._win.matchMedia("(-moz-system-dark-theme)");
+  this._darkThemeMediaQuery.addListener(this.LightweightThemeManager);
+  this.LightweightThemeManager.systemThemeChanged(this._darkThemeMediaQuery);
+
+  this._update(this.LightweightThemeManager.currentThemeWithPersistedData);
 
   this._win.addEventListener("resolutionchange", this);
   this._win.addEventListener("unload", this, { once: true });
-
-  let darkThemeMediaQuery = this._win.matchMedia("(-moz-system-dark-theme)");
-  darkThemeMediaQuery.addListener(temp.LightweightThemeManager);
-  temp.LightweightThemeManager.systemThemeChanged(darkThemeMediaQuery);
 }
 
 LightweightThemeConsumer.prototype = {
   _lastData: null,
   // Whether a lightweight theme is enabled.
   _active: false,
 
   observe(aSubject, aTopic, aData) {
@@ -153,32 +153,42 @@ LightweightThemeConsumer.prototype = {
         if (this._active) {
           this._update(this._lastData);
         }
         break;
       case "unload":
         Services.obs.removeObserver(this, "lightweight-theme-styling-update");
         Services.ppmm.sharedData.delete(`theme/${this._winId}`);
         this._win.removeEventListener("resolutionchange", this);
-        this._win = this._doc = null;
+        this._darkThemeMediaQuery.removeListener(this.LightweightThemeManager);
+        this._win = this._doc = this._darkThemeMediaQuery = null;
         break;
     }
   },
 
   _update(theme, experiment) {
     this._lastData = theme;
     if (theme) {
       theme = LightweightThemeImageOptimizer.optimize(theme, this._win.screen);
     }
+    if (!theme) {
+      theme = { id: DEFAULT_THEME_ID };
+    }
 
-    let active = this._active = theme && theme.id !== DEFAULT_THEME_ID;
+    let active = this._active = (theme.id != DEFAULT_THEME_ID);
 
-    if (!theme) {
-      theme = {};
-    }
+    // The theme we're switching to can be different from the user-selected
+    // theme. E.g. if the default theme is selected and the OS is in dark mode,
+    // we'd silently activate the dark theme if available. We set an attribute
+    // in that case so stylesheets can differentiate this from the dark theme
+    // being selected explicitly by the user.
+    let isDefaultThemeInDarkMode =
+      theme.id == this.LightweightThemeManager.defaultDarkThemeID &&
+      this.LightweightThemeManager.selectedThemeID == DEFAULT_THEME_ID &&
+      this._darkThemeMediaQuery.matches;
 
     let root = this._doc.documentElement;
 
     if (active && theme.headerURL) {
       root.setAttribute("lwtheme-image", "true");
     } else {
       root.removeAttribute("lwtheme-image");
     }
@@ -201,16 +211,21 @@ LightweightThemeConsumer.prototype = {
     _setProperties(root, active, theme);
 
     if (active) {
       root.setAttribute("lwtheme", "true");
     } else {
       root.removeAttribute("lwtheme");
       root.removeAttribute("lwthemetextcolor");
     }
+    if (isDefaultThemeInDarkMode) {
+      root.setAttribute("lwt-default-theme-in-dark-mode", "true");
+    } else {
+      root.removeAttribute("lwt-default-theme-in-dark-mode");
+    }
 
     let contentThemeData = _getContentProperties(this._doc, active, theme);
     Services.ppmm.sharedData.set(`theme/${this._winId}`, contentThemeData);
   },
 
   _setExperiment(active, experiment, properties) {
     const root = this._doc.documentElement;
     if (this._lastExperimentData) {
--- a/toolkit/mozapps/extensions/LightweightThemeManager.jsm
+++ b/toolkit/mozapps/extensions/LightweightThemeManager.jsm
@@ -97,16 +97,24 @@ var LightweightThemeManager = {
   // Themes that can be added for an application.  They can't be removed, and
   // will always show up at the top of the list.
   _builtInThemes: new Map(),
 
   isBuiltIn(theme) {
     return this._builtInThemes.has(theme.id);
   },
 
+  get selectedThemeID() {
+    return _prefs.getStringPref("selectedThemeID") || DEFAULT_THEME_ID;
+  },
+
+  get defaultDarkThemeID() {
+    return _defaultDarkThemeID;
+  },
+
   get usedThemes() {
     let themes = [];
     try {
       themes = JSON.parse(_prefs.getStringPref("usedThemes"));
     } catch (e) { }
 
     themes.push(...this._builtInThemes.values());
     return themes;