commit dcbcf6b14a80ee09dd7a313bfba1fa43b59007dc
parent 3c38e096408e850731b1647597cd422031ee8bcb
Author: unifolia <jlewis@mozilla.com>
Date: Thu, 18 Dec 2025 19:25:07 +0000
Bug 2000881 - Persist AI-Window session and restore r=Gijs,sessionstore-reviewers,ai-frontend-reviewers,sthompson
Differential Revision: https://phabricator.services.mozilla.com/D275644
Diffstat:
4 files changed, 41 insertions(+), 17 deletions(-)
diff --git a/browser/base/content/utilityOverlay.js b/browser/base/content/utilityOverlay.js
@@ -13,6 +13,8 @@ var { XPCOMUtils } = ChromeUtils.importESModule(
ChromeUtils.defineESModuleGetters(this, {
AboutNewTab: "resource:///modules/AboutNewTab.sys.mjs",
+ AIWindow:
+ "moz-src:///browser/components/aiwindow/ui/modules/AIWindow.sys.mjs",
BrowserUtils: "resource://gre/modules/BrowserUtils.sys.mjs",
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.sys.mjs",
ContextualIdentityService:
@@ -23,8 +25,6 @@ ChromeUtils.defineESModuleGetters(this, {
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
ShellService: "moz-src:///browser/components/shell/ShellService.sys.mjs",
URILoadingHelper: "resource:///modules/URILoadingHelper.sys.mjs",
- AIWindow:
- "moz-src:///browser/components/aiwindow/ui/modules/AIWindow.sys.mjs",
});
ChromeUtils.defineLazyGetter(this, "ReferrerInfo", () =>
diff --git a/browser/components/aiwindow/ui/modules/AIWindow.sys.mjs b/browser/components/aiwindow/ui/modules/AIWindow.sys.mjs
@@ -41,23 +41,24 @@ export const AIWindow = {
* @param {object} options Used in BrowserWindowTracker.openWindow
* @param {object} options.openerWindow Window making the BrowserWindowTracker.openWindow call
* @param {object} options.args Array of arguments to pass to new window
- * @param {boolean} options.aiWindow Should new window be AI Window
- * @param {boolean} options.private Should new window be Private Window
+ * @param {boolean} [options.aiWindow] Should new window be AI Window (true), Classic Window (false), or inherited from opener (undefined, default)
+ * @param {boolean} [options.private] Should new window be Private Window
+ * @param {boolean} [options.restoreSession] Should previous AI Window session be restored
*
* @returns {object} Modified arguments appended to the options object
*/
handleAIWindowOptions({
openerWindow,
args,
- aiWindow,
- private: isPrivate,
+ aiWindow = undefined,
+ private: isPrivate = false,
+ restoreSession = false,
} = {}) {
// Indicates whether the new window should inherit AI Window state from opener window
const canInheritAIWindow =
- this.isAIWindowEnabled() &&
- this.isAIWindowActive(openerWindow) &&
+ this.isAIWindowActiveAndEnabled(openerWindow) &&
!isPrivate &&
- !aiWindow;
+ typeof aiWindow === "undefined";
const willOpenAIWindow =
(aiWindow && this.isAIWindowEnabled()) || canInheritAIWindow;
@@ -72,7 +73,7 @@ export const AIWindow = {
const aiWindowURI = Cc["@mozilla.org/supports-string;1"].createInstance(
Ci.nsISupportsString
);
- aiWindowURI.data = AIWINDOW_URL;
+ aiWindowURI.data = restoreSession ? "" : AIWINDOW_URL;
args.appendElement(aiWindowURI);
const aiOption = Cc["@mozilla.org/hash-property-bag;1"].createInstance(
@@ -91,7 +92,6 @@ export const AIWindow = {
* @param {object} win current Window
* @returns {boolean} whether current Window is an AI Window
*/
-
isAIWindowActive(win) {
return !!win && win.document.documentElement.hasAttribute("ai-window");
},
@@ -101,11 +101,14 @@ export const AIWindow = {
*
* @returns {boolean} whether AI Window is enabled
*/
-
isAIWindowEnabled() {
return this.AIWindowEnabled;
},
+ isAIWindowActiveAndEnabled(win) {
+ return this.isAIWindowActive(win) && this.AIWindowEnabled;
+ },
+
get newTabURL() {
return AIWINDOW_URL;
},
diff --git a/browser/components/sessionstore/SessionStore.sys.mjs b/browser/components/sessionstore/SessionStore.sys.mjs
@@ -173,6 +173,8 @@ XPCOMUtils.defineLazyServiceGetters(lazy, {
});
ChromeUtils.defineESModuleGetters(lazy, {
+ AIWindow:
+ "moz-src:///browser/components/aiwindow/ui/modules/AIWindow.sys.mjs",
AsyncShutdown: "resource://gre/modules/AsyncShutdown.sys.mjs",
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.sys.mjs",
DevToolsShim: "chrome://devtools-startup/content/DevToolsShim.sys.mjs",
@@ -2044,6 +2046,10 @@ var SessionStoreInternal = {
this._windows[aWindow.__SSi].isTaskbarTab = true;
}
+ if (lazy.AIWindow.isAIWindowActiveAndEnabled(aWindow)) {
+ this._windows[aWindow.__SSi].isAIWindow = true;
+ }
+
let tabbrowser = aWindow.gBrowser;
// add tab change listeners to all already existing tabs
@@ -6977,11 +6983,8 @@ var SessionStoreInternal = {
* Object containing session data
*/
_openWindowWithState: function ssi_openWindowWithState(aState) {
- var argString = Cc["@mozilla.org/supports-string;1"].createInstance(
- Ci.nsISupportsString
- );
- argString.data = "";
-
+ // Build arguments string
+ let argString;
// Build feature string
let features;
let winState = aState.windows[0];
@@ -7024,8 +7027,23 @@ var SessionStoreInternal = {
}
});
+ // A window CANNOT be both a Private Window and an AI Window
if (winState.isPrivate) {
features.push("private");
+ } else if (winState.isAIWindow) {
+ argString = lazy.AIWindow.handleAIWindowOptions({
+ openerWindow: null,
+ args: argString,
+ aiWindow: winState.isAIWindow,
+ restoreSession: true,
+ });
+ }
+
+ if (!argString) {
+ argString = Cc["@mozilla.org/supports-string;1"].createInstance(
+ Ci.nsISupportsString
+ );
+ argString.data = "";
}
this._log.debug(
diff --git a/browser/components/sessionstore/session.schema.json b/browser/components/sessionstore/session.schema.json
@@ -174,6 +174,9 @@
"hidden": {
"type": "string"
},
+ "isAIWindow": {
+ "type": "boolean"
+ },
"isPopup": {
"type": "boolean"
},