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

Firefox add-on: how to tell if a window is in the background

本文关键字:判断 窗口 是否 后台 组件 何判断 火狐      更新时间:2023-09-26

在 Firefox 附加组件 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。但它仍然缺少有关窗口是否在后台的信息。

根据@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用于避免快速连续多次调用刷新 TabState。例如,如果您单击不是当前窗口的非活动选项卡,则单击该一次会导致window.deactivatewindow.activatetab.activate事件。

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