Bug 966098 - Handle inactive/no windows case for "sync started" notification r=markh a=sylvestre
--- a/browser/base/content/browser-fxaccounts.js
+++ b/browser/base/content/browser-fxaccounts.js
@@ -2,16 +2,17 @@
# 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/.
XPCOMUtils.defineLazyGetter(this, "FxAccountsCommon", function () {
return Cu.import("resource://gre/modules/FxAccountsCommon.js", {});
});
const PREF_SYNC_START_DOORHANGER = "services.sync.ui.showSyncStartDoorhanger";
+const DOORHANGER_ACTIVATE_DELAY_MS = 5000;
let gFxAccounts = {
_initialized: false,
_inCustomizationMode: false,
get weave() {
delete this.weave;
@@ -28,26 +29,16 @@ let gFxAccounts = {
"weave:service:sync:start",
"weave:service:login:error",
"weave:service:setup-complete",
FxAccountsCommon.ONVERIFIED_NOTIFICATION,
FxAccountsCommon.ONLOGOUT_NOTIFICATION
];
},
- // The set of topics that only the active window should handle.
- get activeWindowTopics() {
- // Do all this dance to lazy-load FxAccountsCommon.
- delete this.activeWindowTopics;
- return this.activeWindowTopics = new Set([
- "weave:service:sync:start",
- FxAccountsCommon.ONVERIFIED_NOTIFICATION
- ]);
- },
-
get button() {
delete this.button;
return this.button = document.getElementById("PanelUI-fxa-status");
},
get loginFailed() {
// Referencing Weave.Service will implicitly initialize sync, and we don't
// want to force that - so first check if it is ready.
@@ -59,31 +50,31 @@ let gFxAccounts = {
}
// LOGIN_FAILED_LOGIN_REJECTED explicitly means "you must log back in".
// All other login failures are assumed to be transient and should go
// away by themselves, so aren't reflected here.
return Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED;
},
get isActiveWindow() {
- let mostRecentNonPopupWindow =
- RecentWindow.getMostRecentBrowserWindow({allowPopups: false});
- return window == mostRecentNonPopupWindow;
+ let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
+ return fm.activeWindow == window;
},
init: function () {
// Bail out if we're already initialized and for pop-up windows.
if (this._initialized || !window.toolbar.visible) {
return;
}
for (let topic of this.topics) {
Services.obs.addObserver(this, topic, false);
}
+ addEventListener("activate", this);
gNavToolbox.addEventListener("customizationstarting", this);
gNavToolbox.addEventListener("customizationending", this);
this._initialized = true;
this.updateUI();
},
@@ -95,50 +86,58 @@ let gFxAccounts = {
for (let topic of this.topics) {
Services.obs.removeObserver(this, topic);
}
this._initialized = false;
},
observe: function (subject, topic) {
- // Ignore certain topics if we're not the active window.
- if (this.activeWindowTopics.has(topic) && !this.isActiveWindow) {
- return;
- }
-
switch (topic) {
case FxAccountsCommon.ONVERIFIED_NOTIFICATION:
Services.prefs.setBoolPref(PREF_SYNC_START_DOORHANGER, true);
break;
case "weave:service:sync:start":
this.onSyncStart();
break;
default:
this.updateUI();
break;
}
},
onSyncStart: function () {
+ if (!this.isActiveWindow) {
+ return;
+ }
+
let showDoorhanger = false;
try {
showDoorhanger = Services.prefs.getBoolPref(PREF_SYNC_START_DOORHANGER);
} catch (e) { /* The pref might not exist. */ }
if (showDoorhanger) {
Services.prefs.clearUserPref(PREF_SYNC_START_DOORHANGER);
this.showSyncStartedDoorhanger();
}
},
handleEvent: function (event) {
- this._inCustomizationMode = event.type == "customizationstarting";
- this.updateUI();
+ if (event.type == "activate") {
+ // Our window might have been in the background while we received the
+ // sync:start notification. If still needed, show the doorhanger after
+ // a short delay. Without this delay the doorhanger would not show up
+ // or with a too small delay show up while we're still animating the
+ // window.
+ setTimeout(() => this.onSyncStart(), DOORHANGER_ACTIVATE_DELAY_MS);
+ } else {
+ this._inCustomizationMode = event.type == "customizationstarting";
+ this.updateUI();
+ }
},
showDoorhanger: function (id) {
let panel = document.getElementById(id);
let anchor = document.getElementById("PanelUI-menu-button");
let iconAnchor =
document.getAnonymousElementByAttribute(anchor, "class",