[Basilisk] port PM's ghostbuster

This commit is contained in:
roytam1 2024-09-22 21:17:32 +08:00
commit d1fde5c4ea
4 changed files with 49 additions and 2 deletions

View file

@ -444,6 +444,9 @@ pref("javascript.options.showInConsole", true);
pref("general.warnOnAboutConfig", false); pref("general.warnOnAboutConfig", false);
#endif #endif
// Enable unlinking of ghost windows so they can be garbage collected.
pref("browser.ghostbuster.enabled", true);
// This is the pref to control the location bar, change this to true to // This is the pref to control the location bar, change this to true to
// force this - this makes the origin of popup windows more obvious to avoid // force this - this makes the origin of popup windows more obvious to avoid
// spoofing. We would rather not do it by default because it affects UE for web // spoofing. We would rather not do it by default because it affects UE for web

View file

@ -2645,12 +2645,24 @@
} }
// We're going to remove the tab and the browser now. // We're going to remove the tab and the browser now.
// Using the "STOP_ALL" flag should halt all animations, fetches, network
// activity, etc. to come to a clean state for removal and unlinking (if enabled).
var browser = this.getBrowserForTab(aTab);
browser.webNavigation.stop(nsIWebNavigation.STOP_ALL);
this._tabFilters.delete(aTab); this._tabFilters.delete(aTab);
this._tabListeners.delete(aTab); this._tabListeners.delete(aTab);
var browser = this.getBrowserForTab(aTab);
this._outerWindowIDBrowserMap.delete(browser.outerWindowID); this._outerWindowIDBrowserMap.delete(browser.outerWindowID);
if (Services.prefs.getBoolPref("browser.ghostbuster.enabled", true)) {
Cu.unlinkGhostWindows();
#ifdef DEBUG
dump("Unlinking ghost windows has run on tab close.\n");
#endif
}
// Because of the way XBL works (fields just set JS // Because of the way XBL works (fields just set JS
// properties on the element) and the code we have in place // properties on the element) and the code we have in place
// to preserve the JS objects for any elements that have // to preserve the JS objects for any elements that have

View file

@ -128,7 +128,7 @@ browser.jar:
content/browser/contentSearchUI.js (content/contentSearchUI.js) content/browser/contentSearchUI.js (content/contentSearchUI.js)
content/browser/contentSearchUI.css (content/contentSearchUI.css) content/browser/contentSearchUI.css (content/contentSearchUI.css)
content/browser/tabbrowser.css (content/tabbrowser.css) content/browser/tabbrowser.css (content/tabbrowser.css)
content/browser/tabbrowser.xml (content/tabbrowser.xml) * content/browser/tabbrowser.xml (content/tabbrowser.xml)
* content/browser/urlbarBindings.xml (content/urlbarBindings.xml) * content/browser/urlbarBindings.xml (content/urlbarBindings.xml)
content/browser/utilityOverlay.js (content/utilityOverlay.js) content/browser/utilityOverlay.js (content/utilityOverlay.js)
content/browser/usercontext.svg (content/usercontext.svg) content/browser/usercontext.svg (content/usercontext.svg)

View file

@ -81,6 +81,10 @@ const BOOKMARKS_BACKUP_MIN_INTERVAL_DAYS = 1;
// days we will try to create a new one more aggressively. // days we will try to create a new one more aggressively.
const BOOKMARKS_BACKUP_MAX_INTERVAL_DAYS = 3; const BOOKMARKS_BACKUP_MAX_INTERVAL_DAYS = 3;
// Use users' idle time to unlink ghost windows and clean up memory.
// Trigger this by default every 5 minutes.
const GHOSTBUSTER_INTERVAL = 5 * 60;
// Factory object // Factory object
const BrowserGlueServiceFactory = { const BrowserGlueServiceFactory = {
_instance: null, _instance: null,
@ -99,6 +103,10 @@ function BrowserGlue() {
"@mozilla.org/widget/idleservice;1", "@mozilla.org/widget/idleservice;1",
"nsIIdleService"); "nsIIdleService");
XPCOMUtils.defineLazyServiceGetter(this, "_ghostBusterService",
"@mozilla.org/widget/idleservice;1",
"nsIIdleService");
XPCOMUtils.defineLazyGetter(this, "_distributionCustomizer", function() { XPCOMUtils.defineLazyGetter(this, "_distributionCustomizer", function() {
Cu.import("resource:///modules/distribution.js"); Cu.import("resource:///modules/distribution.js");
return new DistributionCustomizer(); return new DistributionCustomizer();
@ -127,6 +135,7 @@ BrowserGlue.prototype = {
_isPlacesShutdownObserver: false, _isPlacesShutdownObserver: false,
_isPlacesDatabaseLocked: false, _isPlacesDatabaseLocked: false,
_migrationImportsDefaultBookmarks: false, _migrationImportsDefaultBookmarks: false,
_isGhostBusterObserver: false,
_setPrefToSaveSession: function(aForce) { _setPrefToSaveSession: function(aForce) {
if (!this._saveSession && !aForce) if (!this._saveSession && !aForce)
@ -241,6 +250,15 @@ BrowserGlue.prototype = {
break; break;
case "idle": case "idle":
this._backupBookmarks(); this._backupBookmarks();
if (this._ghostBusterService.idleTime > GHOSTBUSTER_INTERVAL * 1000) {
if (Services.prefs.getBoolPref("browser.ghostbuster.enabled", true)) {
Cu.unlinkGhostWindows();
Cu.forceGC();
#ifdef DEBUG
dump("Unlinking ghost windows + GC has run on idle.\n");
#endif
}
}
break; break;
case "distribution-customization-complete": case "distribution-customization-complete":
Services.obs.removeObserver(this, "distribution-customization-complete"); Services.obs.removeObserver(this, "distribution-customization-complete");
@ -843,6 +861,13 @@ BrowserGlue.prototype = {
this._trackSlowStartup(); this._trackSlowStartup();
// Initialize ghost window idle observer.
if (!this._isGhostBusterObserver) {
this._ghostBusterService.addIdleObserver(this, GHOSTBUSTER_INTERVAL);
// Prevent re-entry.
this._isGhostBusterObserver = true;
}
// Offer to reset a user's profile if it hasn't been used for 60 days. // Offer to reset a user's profile if it hasn't been used for 60 days.
const OFFER_PROFILE_RESET_INTERVAL_MS = 60 * 24 * 60 * 60 * 1000; const OFFER_PROFILE_RESET_INTERVAL_MS = 60 * 24 * 60 * 60 * 1000;
let lastUse = Services.appinfo.replacedLockTime; let lastUse = Services.appinfo.replacedLockTime;
@ -914,6 +939,13 @@ BrowserGlue.prototype = {
if (AppConstants.NIGHTLY_BUILD) { if (AppConstants.NIGHTLY_BUILD) {
AddonWatcher.uninit(); AddonWatcher.uninit();
} }
// Shut down ghost window idle observer.
if (this._isGhostBusterObserver) {
this._ghostBusterService.removeIdleObserver(this, GHOSTBUSTER_INTERVAL);
this._isGhostBusterObserver = false;
}
// Do one final unlink to combat shutdown issues.
Cu.unlinkGhostWindows();
}, },
// All initial windows have opened. // All initial windows have opened.