Firefox附加组件:如何判断窗口是否在后台

时间:2014-12-12 14:50:38

标签: javascript firefox firefox-addon-sdk

在Firefox Add-on SDK附加组件中,如何判断窗口是否在后台,即。可见但没有集中注意力?

例如,如果我将不同的应用程序带到前台,Firefox窗口将变得没有焦点但仍然可见。

我之所以这样做是因为我在活动窗口中运行了一个CPU密集型内容脚本,我想暂停它以避免在用户没有主动使用窗口时产生不必要的开销 - 意思是它在后台或最小化。

require("sdk/windows").activeWindow会一直返回最后点击的窗口,即使它在后台或最小化。窗口的焦点状态似乎没有任何属性。

我也可以使用以下代码来获取nsIDocShell:

var mostRecentWindow = require("sdk/window/utils").getMostRecentBrowserWindow();
var docShell = require("sdk/window/utils").getWindowDocShell(mostRecentWindow);

现在,当我查询docShell.isActive属性时,即使窗口在后台,它也会返回true。

docShell.isActive的一个优点是,当窗口最小化时它返回false,而activeWindow即使在这种情况下也返回true。但它仍然缺少关于窗口是否在后台的信息。

1 个答案:

答案 0 :(得分:0)

基于@willlma的建议,这段代码似乎可以解决问题:

const windows = require('sdk/windows').browserWindows;
const tabs = require("sdk/tabs");
var anyWindowActive = true;
var refreshTimeoutId;

windows.on('deactivate', function(window) {
    if (window == windows.activeWindow) {
        anyWindowActive = false;
    }
    clearTimeout(refreshTimeoutId);
    refreshTimeoutId = setTimeout(refreshTabStates, 50);
});

windows.on('activate', function(window) {
    anyWindowActive = true;
    clearTimeout(refreshTimeoutId);
    refreshTimeoutId = setTimeout(refreshTabStates, 50);
});

tabs.on('activate', function(tab) {
    clearTimeout(refreshTimeoutId);
    refreshTimeoutId = setTimeout(refreshTabStates, 50);
});

function refreshTabStates() {
    refreshTimeoutId = null;
    for (let win of windows) {
        for (let tab of win.tabs) {
            var shouldBeActive = anyWindowActive
                                 && tab == tabs.activeTab
                                 && win == windows.activeWindow;
            notifyTab(tab, shouldBeActive);
        }
    }
}

其中notifyTab()是一个函数,用于将消息发布到该标签的内容脚本(如果有),以确定它是否应该运行。

setTimeout用于避免快速连续多次调用refreshTabStates。例如,如果您点击的窗口中的非活动标签不是当前标签,则只需点击一次即可生成window.deactivatewindow.activatetab.activate个活动。

此外,初始状态是一个问题。如果用户启动Firefox并在任何脚本设法运行之前将其置于后台,该怎么办?