Bug 930094 - [Australis] Browser windows sometimes have the nav-bar drawn in the titlebar. r=dao, Gijs.
authorMike Conley <mconley@mozilla.com>
Tue, 04 Feb 2014 16:17:00 -0500
changeset 166932 8a56937c985b8525ca5e32c5a08318cf12ad5f6d
parent 166931 a77d5593a3fc7744a82928d0394ab78187b2aa93
child 166933 579cf46bc21ebb2232813c8be9f572d40f018e52
child 166978 f1156ec42c25e1a4b1fd684f7ee5c5d2eeaca39e
push id26154
push usercbook@mozilla.com
push dateWed, 05 Feb 2014 12:28:27 +0000
treeherdermozilla-central@579cf46bc21e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdao, Gijs
bugs930094
milestone30.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 930094 - [Australis] Browser windows sometimes have the nav-bar drawn in the titlebar. r=dao, Gijs. * * * Fix for 930094 * * * Fix because WTF
browser/base/content/browser.css
browser/base/content/browser.js
browser/base/content/test/general/browser.ini
browser/themes/osx/browser.css
toolkit/modules/LightweightThemeConsumer.jsm
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -168,16 +168,17 @@ toolbar[overflowable] > .customization-t
 }
 
 toolbar:not([overflowing]) > .overflow-button,
 toolbar[customizing] > .overflow-button {
   display: none;
 }
 
 %ifdef CAN_DRAW_IN_TITLEBAR
+#main-window:not([chromemargin]) > #titlebar,
 #main-window[inFullscreen] > #titlebar,
 #main-window[inFullscreen] .titlebar-placeholder,
 #main-window:not([tabsintitlebar]) .titlebar-placeholder {
   display: none;
 }
 
 #titlebar {
   -moz-binding: url("chrome://global/content/bindings/general.xml#windowdragbox");
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -4476,54 +4476,45 @@ var TabsInTitlebar = {
       // We set the tabsintitlebar attribute first so that our CSS for
       // tabsintitlebar manifests before we do our measurements.
       document.documentElement.setAttribute("tabsintitlebar", "true");
       updateTitlebarDisplay();
 
       // Try to avoid reflows in this code by calculating dimensions first and
       // then later set the properties affecting layout together in a batch.
 
+      // Get the full height of the tabs toolbar:
+      let tabsToolbar = $("TabsToolbar");
+      let fullTabsHeight = rect(tabsToolbar).height;
       // Buttons first:
       let captionButtonsBoxWidth = rect($("titlebar-buttonbox")).width;
 #ifdef XP_MACOSX
       let fullscreenButtonWidth = rect($("titlebar-fullscreen-button")).width;
       // No need to look up the menubar stuff on OS X:
       let menuHeight = 0;
       let fullMenuHeight = 0;
       // Instead, look up the titlebar padding:
       let titlebarPadding = parseInt(window.getComputedStyle(titlebar).paddingTop, 10);
 #else
       // Otherwise, get the height and margins separately for the menubar
       let menuHeight = rect(menubar).height;
       let menuStyles = window.getComputedStyle(menubar);
       let fullMenuHeight = verticalMargins(menuStyles) + menuHeight;
+      let tabsStyles = window.getComputedStyle(tabsToolbar);
+      fullTabsHeight += verticalMargins(tabsStyles);
 #endif
-      // Get the full height of the tabs toolbar:
-      let tabsToolbar = $("TabsToolbar");
-      let tabsStyles = window.getComputedStyle(tabsToolbar);
-      let fullTabsHeight = rect(tabsToolbar).height + verticalMargins(tabsStyles);
 
       // If the navbar overlaps the tabbar using negative margins, we need to take those into
       // account so we don't overlap it
       let navbarMarginTop = parseFloat(window.getComputedStyle($("nav-bar")).marginTop);
       navbarMarginTop = Math.min(navbarMarginTop, 0);
 
       // And get the height of what's in the titlebar:
       let titlebarContentHeight = rect(titlebarContent).height;
 
-      // Padding surrounds the tab-view-deck when we are in customization mode,
-      // so take that into account:
-      let areCustomizing = document.documentElement.hasAttribute("customizing") ||
-                           document.documentElement.hasAttribute("customize-exiting");
-      let customizePadding = 0;
-      if (areCustomizing) {
-        let deckStyle = window.getComputedStyle($("tab-view-deck"));
-        customizePadding = parseFloat(deckStyle.paddingTop);
-      }
-
       // Begin setting CSS properties which will cause a reflow
 
       // If the menubar is around (menuHeight is non-zero), try to adjust
       // its full height (i.e. including margins) to match the titlebar,
       // by changing the menubar's bottom padding
       if (menuHeight) {
         // Calculate the difference between the titlebar's height and that of the menubar
         let menuTitlebarDelta = titlebarContentHeight - fullMenuHeight;
@@ -4546,37 +4537,27 @@ var TabsInTitlebar = {
           // We've changed the menu height now:
           fullMenuHeight += desiredPadding - existingPadding;
         }
       }
 
       // Next, we calculate how much we need to stretch the titlebar down to
       // go all the way to the bottom of the tab strip, if necessary.
       let tabAndMenuHeight = fullTabsHeight + fullMenuHeight;
-      // Oh, and don't forget customization mode:
-      if (areCustomizing) {
-        tabAndMenuHeight += customizePadding;
-      }
 
       if (tabAndMenuHeight > titlebarContentHeight) {
         // We need to increase the titlebar content's outer height (ie including margins)
         // to match the tab and menu height:
         let extraMargin = tabAndMenuHeight - titlebarContentHeight;
         // We need to reduce the height by the amount of navbar overlap
         // (this value is 0 or negative):
         extraMargin += navbarMarginTop;
         // On non-OSX, we can just use bottom margin:
 #ifndef XP_MACOSX
         titlebarContent.style.marginBottom = extraMargin + "px";
-#else
-        // Otherwise, center the content. This means taking the titlebar's
-        // padding into account:
-        let halfMargin = (extraMargin - titlebarPadding) / 2;
-        titlebarContent.style.marginTop =  halfMargin + "px";
-        titlebarContent.style.marginBottom =  (titlebarPadding + halfMargin) + "px";
 #endif
         titlebarContentHeight += extraMargin;
       }
 
       // Then we bring up the titlebar by the same amount, but we add any negative margin:
       titlebar.style.marginBottom = "-" + titlebarContentHeight + "px";
 
 
@@ -4601,16 +4582,17 @@ var TabsInTitlebar = {
         this._draghandles.navToolbox = new tmp.WindowDraggingElement(gNavToolbox);
         this._draghandles.navToolbox.mouseDownCheck = mouseDownCheck;
       }
     } else {
       document.documentElement.removeAttribute("tabsintitlebar");
       updateTitlebarDisplay();
 
       // Reset the margins and padding that might have been modified:
+      titlebarContent.style.marginTop = "";
       titlebarContent.style.marginBottom = "";
       titlebar.style.marginBottom = "";
       menubar.style.paddingBottom = "";
     }
   },
 
   _sizePlaceholder: function (type, width) {
     Array.forEach(document.querySelectorAll(".titlebar-placeholder[type='"+ type +"']"),
@@ -4625,26 +4607,47 @@ var TabsInTitlebar = {
     this._menuObserver.disconnect();
     CustomizableUI.removeListener(this);
 #endif
   }
 };
 
 #ifdef CAN_DRAW_IN_TITLEBAR
 function updateTitlebarDisplay() {
-  document.getElementById("titlebar").hidden = !TabsInTitlebar.enabled;
+
+#ifdef XP_MACOSX
+  // OS X and the other platforms differ enough to necessitate this kind of
+  // special-casing. Like the other platforms where we CAN_DRAW_IN_TITLEBAR,
+  // we draw in the OS X titlebar when putting the tabs up there. However, OS X
+  // also draws in the titlebar when a lightweight theme is applied, regardless
+  // of whether or not the tabs are drawn in the titlebar.
+  if (TabsInTitlebar.enabled) {
+    document.documentElement.setAttribute("chromemargin-nonlwtheme", "0,-1,-1,-1");
+    document.documentElement.setAttribute("chromemargin", "0,-1,-1,-1");
+    document.documentElement.removeAttribute("drawtitle");
+  } else {
+    // We set chromemargin-nonlwtheme to "" instead of removing it as a way of
+    // making sure that LightweightThemeConsumer doesn't take it upon itself to
+    // detect this value again if and when we do a lwtheme state change.
+    document.documentElement.setAttribute("chromemargin-nonlwtheme", "");
+    let isCustomizing = document.documentElement.hasAttribute("customizing");
+    let hasLWTheme = document.documentElement.hasAttribute("lwtheme");
+    if (!hasLWTheme || isCustomizing) {
+      document.documentElement.removeAttribute("chromemargin");
+    }
+    document.documentElement.setAttribute("drawtitle", "true");
+  }
+
+#else
 
   if (TabsInTitlebar.enabled)
-#ifdef XP_WIN
     document.documentElement.setAttribute("chromemargin", "0,2,2,2");
-#else
-    document.documentElement.setAttribute("chromemargin", "0,-1,-1,-1");
-#endif
   else
     document.documentElement.removeAttribute("chromemargin");
+#endif
 }
 #endif
 
 #ifdef CAN_DRAW_IN_TITLEBAR
 function onTitlebarMaxClick() {
   if (window.windowState == window.STATE_MAXIMIZED)
     window.restore();
   else
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -308,17 +308,18 @@ skip-if = true  # disabled until the tre
 [browser_scope.js]
 [browser_selectTabAtIndex.js]
 [browser_tabDrop.js]
 [browser_tabMatchesInAwesomebar_perwindowpb.js]
 [browser_tab_drag_drop_perwindow.js]
 [browser_tab_dragdrop.js]
 [browser_tab_dragdrop2.js]
 [browser_tabbar_big_widgets.js]
-skip-if = os == "linux" # No tabs in titlebar on linux
+skip-if = os == "linux" || os == "mac" # No tabs in titlebar on linux
+                                       # Disabled on OS X because of bug 967917
 [browser_tabfocus.js]
 [browser_tabopen_reflows.js]
 [browser_tabs_isActive.js]
 [browser_tabs_owner.js]
 [browser_typeAheadFind.js]
 [browser_unloaddialogs.js]
 [browser_urlHighlight.js]
 [browser_urlbarAutoFillTrimURLs.js]
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -54,17 +54,17 @@
 
 @media (-moz-mac-lion-theme) {
   .titlebar-placeholder[type="fullscreen-button"],
   #titlebar-fullscreen-button {
     margin-right: 7px;
   }
 }
 
-#main-window[chromehidden~="toolbar"] > #titlebar {
+#main-window[chromehidden~="toolbar"]:not(:-moz-lwtheme) > #titlebar {
   padding-top: 22px;
 }
 
 #main-window:not(:-moz-lwtheme):not([privatebrowsingmode=temporary]) > #titlebar {
   -moz-appearance: -moz-window-titlebar;
 }
 
 #main-window[chromehidden~="toolbar"][chromehidden~="location"][chromehidden~="directories"] {
@@ -2653,17 +2653,17 @@ toolbarbutton.chevron > .toolbarbutton-m
   border: solid transparent;
   border-width: 0 11px;
 }
 
 .tabbrowser-tab:focus > .tab-stack > .tab-content > .tab-label {
   box-shadow: @focusRingShadow@;
 }
 
-#titlebar {
+#main-window:not(:-moz-lwtheme) > #titlebar {
   padding-top: @spaceAboveTabbar@;
   min-height: @tabHeight@;
 }
 
 #main-window:not(:-moz-any([privatebrowsingmode=temporary],[customizing])) #navigator-toolbox[inFullscreen]:not(:-moz-lwtheme)::before,
 #main-window:not(:-moz-any([privatebrowsingmode=temporary],[customizing],[tabsintitlebar])) #navigator-toolbox:not(:-moz-lwtheme)::before {
   /* We want the titlebar to be unified, but we still want to be able
    * to give #TabsToolbar a background. So we can't set -moz-appearance:
@@ -4088,23 +4088,36 @@ window > chatbox {
   border-bottom-left-radius: @toolbarbuttonCornerRadius@;
   border-bottom-right-radius: @toolbarbuttonCornerRadius@;
 }
 
 /* Customization mode */
 
 %include ../shared/customizableui/customizeMode.inc.css
 
-#main-window[customize-entered] #titlebar {
+#main-window[customize-entered] > #titlebar {
   padding-top: 0;
 }
 
-#main-window[tabsintitlebar][customize-entered] #titlebar-content {
-  margin-bottom: 0px !important;
-  margin-top: 11px !important;
+#main-window[tabsintitlebar]:not([customizing]):not(:-moz-lwtheme) > #titlebar > #titlebar-content,
+#main-window[tabsintitlebar][customize-entering] > #titlebar > #titlebar-content,
+#main-window[tabsintitlebar][customize-exiting] > #titlebar > #titlebar-content {
+  margin-top: 2px;
+  margin-bottom: 11px;
+}
+
+#main-window[tabsintitlebar][customize-entered] > #titlebar > #titlebar-content,
+#main-window:not([tabsintitlebar]):not(:-moz-lwtheme) > #titlebar > #titlebar-content {
+  margin-top: 11px;
+  margin-bottom: 0px;
+}
+
+#main-window[tabsintitlebar]:-moz-lwtheme > #titlebar > #titlebar-content {
+  margin-top: 11px;
+  margin-bottom: 11px;
 }
 
 #main-window[customize-entered] #tab-view-deck {
   background-image: url("chrome://browser/skin/customizableui/customizeMode-gridTexture.png"),
                     url("chrome://browser/skin/customizableui/background-noise-toolbar.png"),
                     linear-gradient(to bottom, rgb(233,233,233), rgb(178,178,178) 21px);
   background-attachment: fixed;
 }
@@ -4119,18 +4132,21 @@ window > chatbox {
   -moz-border-bottom-colors: hsla(0,0%,0%,.05) hsla(0,0%,0%,.1) hsla(0,0%,0%,.2);
   -moz-border-left-colors: hsla(0,0%,0%,.05) hsla(0,0%,0%,.1) hsla(0,0%,0%,.2);
 }
 
 #main-window[customize-entered] #navigator-toolbox > toolbar:not(#TabsToolbar) {
   border-bottom-width: 0;
 }
 
+#main-window[tabsintitlebar][customize-entered] #TabsToolbar {
+  margin-top: 9px;
+}
+
 #main-window[customize-entered] #TabsToolbar {
-  margin-top: 9px;
   background-clip: padding-box;
   border-right: 3px solid transparent;
   border-left: 3px solid transparent;
 }
 
 @media (min-resolution: 2dppx) {
   #customization-titlebar-visibility-button {
     list-style-image: url("chrome://browser/skin/customizableui/customize-titleBar-toggle@2x.png");
--- a/toolkit/modules/LightweightThemeConsumer.jsm
+++ b/toolkit/modules/LightweightThemeConsumer.jsm
@@ -37,19 +37,17 @@ this.LightweightThemeConsumer =
   this._win.addEventListener("resize", this);
 }
 
 LightweightThemeConsumer.prototype = {
   _lastData: null,
   _lastScreenWidth: null,
   _lastScreenHeight: null,
   _enabled: true,
-#ifdef XP_MACOSX
-  _chromemarginDefault: undefined,
-#endif
+  _active: false,
 
   enable: function() {
     this._enabled = true;
     this._update(this._lastData);
   },
 
   disable: function() {
     // Dance to keep the data, but reset the applied styles:
@@ -95,59 +93,68 @@ LightweightThemeConsumer.prototype = {
       this._lastData = aData;
     } else {
       this._lastData = aData;
       aData = LightweightThemeImageOptimizer.optimize(aData, this._win.screen);
     }
     if (!this._enabled)
       return;
 
-    var root = this._doc.documentElement;
-    var active = !!aData.headerURL;
+    let root = this._doc.documentElement;
+    let active = !!aData.headerURL;
+    let stateChanging = (active != this._active);
 
     if (active) {
       root.style.color = aData.textcolor || "black";
       root.style.backgroundColor = aData.accentcolor || "white";
       let [r, g, b] = _parseRGB(this._doc.defaultView.getComputedStyle(root, "").color);
       let luminance = 0.2125 * r + 0.7154 * g + 0.0721 * b;
       root.setAttribute("lwthemetextcolor", luminance <= 110 ? "dark" : "bright");
       root.setAttribute("lwtheme", "true");
     } else {
       root.style.color = "";
       root.style.backgroundColor = "";
       root.removeAttribute("lwthemetextcolor");
       root.removeAttribute("lwtheme");
     }
 
+    this._active = active;
+
     _setImage(root, active, aData.headerURL);
     if (this._footerId) {
       let footer = this._doc.getElementById(this._footerId);
       footer.style.backgroundColor = active ? aData.accentcolor || "white" : "";
       _setImage(footer, active, aData.footerURL);
       if (active && aData.footerURL)
         footer.setAttribute("lwthemefooter", "true");
       else
         footer.removeAttribute("lwthemefooter");
     }
 
 #ifdef XP_MACOSX
-    // Sample whether or not we draw in the titlebar by default the first time we update.
-    // If the root has no chromemargin attribute, getAttribute will return null, and
-    // we'll remove the attribute when the lw-theme is deactivated.
-    if (this._chromemarginDefault === undefined)
-      this._chromemarginDefault = root.getAttribute("chromemargin");
+    // On OS X, we extend the lightweight theme into the titlebar, which means setting
+    // the chromemargin attribute. Some XUL applications already draw in the titlebar,
+    // so we need to save the chromemargin value before we overwrite it with the value
+    // that lets us draw in the titlebar. We stash this value on the root attribute so
+    // that XUL applications have the ability to invalidate the saved value.
+    if (stateChanging) {
+      if (!root.hasAttribute("chromemargin-nonlwtheme")) {
+        root.setAttribute("chromemargin-nonlwtheme", root.getAttribute("chromemargin"));
+      }
 
-    if (active) {
-      root.setAttribute("chromemargin", "0,-1,-1,-1");
-    }
-    else {
-      if (this._chromemarginDefault)
-        root.setAttribute("chromemargin", this._chromemarginDefault);
-      else
-        root.removeAttribute("chromemargin");
+      if (active) {
+        root.setAttribute("chromemargin", "0,-1,-1,-1");
+      } else {
+        let defaultChromemargin = root.getAttribute("chromemargin-nonlwtheme");
+        if (defaultChromemargin) {
+          root.setAttribute("chromemargin", defaultChromemargin);
+        } else {
+          root.removeAttribute("chromemargin");
+        }
+      }
     }
 #endif
   }
 }
 
 function _setImage(aElement, aActive, aURL) {
   aElement.style.backgroundImage =
     (aActive && aURL) ? 'url("' + aURL.replace(/"/g, '\\"') + '")' : "";