Bug 773267 - The Downloads Panel flickers at the top left of the screen before anchoring to the Downloads button. r=mak77, f=paolo.
authorMike Conley <mconley@mozilla.com>
Tue, 09 Oct 2012 13:45:51 -0400
changeset 109764 48c1645f720f6d837e2e5f00612b6920767fc735
parent 109763 ab420f694c83275081575f88ebc1fb1d657ef3cd
child 109765 cb9aa35ad1caa4c666dc19053fd40330b995ee08
push id23652
push userryanvm@gmail.com
push dateWed, 10 Oct 2012 01:10:20 +0000
treeherdermozilla-central@5cca0408a73f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmak77
bugs773267
milestone19.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 773267 - The Downloads Panel flickers at the top left of the screen before anchoring to the Downloads button. r=mak77, f=paolo.
browser/components/downloads/content/downloads.js
--- a/browser/components/downloads/content/downloads.js
+++ b/browser/components/downloads/content/downloads.js
@@ -61,19 +61,22 @@ const DownloadsPanel = {
    */
   _state: 0,
 
   /** The panel is not linked to downloads data yet. */
   get kStateUninitialized() 0,
   /** This object is linked to data, but the panel is invisible. */
   get kStateHidden() 1,
   /** The panel will be shown as soon as possible. */
-  get kStateShowing() 2,
+  get kStateWaitingData() 2,
+  /** The panel is almost shown - we're just waiting to get a handle on the
+      anchor. */
+  get kStateWaitingAnchor() 3,
   /** The panel is open. */
-  get kStateShown() 3,
+  get kStateShown() 4,
 
   /**
    * Location of the panel overlay.
    */
   get kDownloadsOverlay()
       "chrome://browser/content/downloads/downloadsOverlay.xul",
 
   /**
@@ -159,17 +162,17 @@ const DownloadsPanel = {
     this.initialize(function DP_SP_callback() {
       // Delay displaying the panel because this function will sometimes be
       // called while another window is closing (like the window for selecting
       // whether to save or open the file), and that would cause the panel to
       // close immediately.
       setTimeout(function () DownloadsPanel._openPopupIfDataReady(), 0);
     }.bind(this));
 
-    this._state = this.kStateShowing;
+    this._state = this.kStateWaitingData;
   },
 
   /**
    * Hides the downloads panel, if visible, but keeps the internal state so that
    * the panel can be reopened quickly if required.
    */
   hidePanel: function DP_hidePanel()
   {
@@ -185,17 +188,18 @@ const DownloadsPanel = {
     this._state = this.kStateHidden;
   },
 
   /**
    * Indicates whether the panel is shown or will be shown.
    */
   get isPanelShowing()
   {
-    return this._state == this.kStateShowing ||
+    return this._state == this.kStateWaitingData ||
+           this._state == this.kStateWaitingAnchor ||
            this._state == this.kStateShown;
   },
 
   //////////////////////////////////////////////////////////////////////////////
   //// Callback functions from DownloadsView
 
   /**
    * Called after data loading finished.
@@ -292,23 +296,30 @@ const DownloadsPanel = {
 
   /**
    * Opens the downloads panel when data is ready to be displayed.
    */
   _openPopupIfDataReady: function DP_openPopupIfDataReady()
   {
     // We don't want to open the popup if we already displayed it, or if we are
     // still loading data.
-    if (this._state != this.kStateShowing || DownloadsView.loading) {
+    if (this._state != this.kStateWaitingData || DownloadsView.loading) {
       return;
     }
 
+    this._state = this.kStateWaitingAnchor;
+
     // Ensure the anchor is visible.  If that is not possible, show the panel
     // anchored to the top area of the window, near the default anchor position.
     DownloadsButton.getAnchor(function DP_OPIDR_callback(aAnchor) {
+      // If somehow we've switched states already (by getting a panel hiding
+      // event before an overlay is loaded, for example), bail out.
+      if (this._state != this.kStateWaitingAnchor)
+        return;
+
       // At this point, if the window is minimized, opening the panel could fail
       // without any notification, and there would be no way to either open or
       // close the panel anymore.  To prevent this, check if the window is
       // minimized and in that case force the panel to the closed state.
       if (window.windowState == Ci.nsIDOMChromeWindow.STATE_MINIMIZED) {
         DownloadsButton.releaseAnchor();
         this._state = this.kStateHidden;
         return;