From c9d3cb3dc9bcd2ca678104804d5d7edf5308570f Mon Sep 17 00:00:00 2001
From: "mr. m" <91018726+mr-cheffy@users.noreply.github.com>
Date: Tue, 8 Sep 2026 20:14:23 +0200
Subject: [PATCH] gh-15297: Fixed synced tabs losing their icon when they are
unloaded (gh-15298)
---
.../base/content/zen-commands.inc.xhtml | 1 +
src/zen/common/zen-sets.js | 3 ++
src/zen/share/ZenShareManager.mjs | 48 +++++++------------
src/zen/split-view/ZenViewSplitter.mjs | 16 +++++++
src/zen/sync/ZenSpacesSyncApplier.sys.mjs | 2 +-
src/zen/tabs/ZenPinnedTabManager.mjs | 2 +-
6 files changed, 38 insertions(+), 34 deletions(-)
diff --git a/src/browser/base/content/zen-commands.inc.xhtml b/src/browser/base/content/zen-commands.inc.xhtml
index 4205420cc..d3e11d053 100644
--- a/src/browser/base/content/zen-commands.inc.xhtml
+++ b/src/browser/base/content/zen-commands.inc.xhtml
@@ -16,6 +16,7 @@
+
diff --git a/src/zen/common/zen-sets.js b/src/zen/common/zen-sets.js
index 34a57d79d..f62575840 100644
--- a/src/zen/common/zen-sets.js
+++ b/src/zen/common/zen-sets.js
@@ -41,6 +41,9 @@ document.addEventListener(
case "cmd_zenSplitViewContextMenu":
gZenViewSplitter.contextSplitTabs();
break;
+ case "cmd_zenCtxShareSplitView":
+ gZenViewSplitter.contextShareSplitView();
+ break;
case "cmd_zenCopyCurrentURLMarkdown":
gZenCommonActions.copyCurrentURLAsMarkdownToClipboard();
break;
diff --git a/src/zen/share/ZenShareManager.mjs b/src/zen/share/ZenShareManager.mjs
index 2a50d4972..ee5f6b78e 100644
--- a/src/zen/share/ZenShareManager.mjs
+++ b/src/zen/share/ZenShareManager.mjs
@@ -24,7 +24,15 @@ const FOLDER_ICON_RE = /^chrome:\/\//;
*/
class nsZenShareManager extends nsZenDOMOperatedFeature {
init() {
- this.#insertSplitViewMenuItem();
+ if (!this.enabled) {
+ for (const id of [
+ "context_zenShareWorkspace",
+ "context_zenShareFolder",
+ ]) {
+ document.getElementById(id)?.setAttribute("hidden", "true");
+ }
+ return;
+ }
delayedStartupPromise.then(() => {
gBrowser.addTabsProgressListener({
onLocationChange: (browser, webProgress, request, aLocation) => {
@@ -34,6 +42,10 @@ class nsZenShareManager extends nsZenDOMOperatedFeature {
});
}
+ get enabled() {
+ return !gZenWorkspaces.privateWindowOrDisabled;
+ }
+
// Mark: sharing
async shareSpace(workspaceId) {
@@ -93,6 +105,9 @@ class nsZenShareManager extends nsZenDOMOperatedFeature {
}
async #createAndCopyLink(item) {
+ if (!this.enabled) {
+ return;
+ }
if (!(await this.#confirmShare())) {
return;
}
@@ -801,37 +816,6 @@ class nsZenShareManager extends nsZenDOMOperatedFeature {
}
return tab;
}
-
- // Mark: split view context menu
-
- #insertSplitViewMenuItem() {
- const fragment = window.MozXULElement.parseXULToFragment(`
-
- `);
- document.getElementById("context_moveTabToSplitView").before(fragment);
- const menuItem = document.getElementById("context_zenShareSplitView");
- menuItem.addEventListener("command", () => {
- const group = TabContextMenu.contextTab?.group;
- if (group?.hasAttribute("split-view-group")) {
- this.shareSplitView(group);
- }
- });
- document
- .getElementById("tabContextMenu")
- .addEventListener("popupshowing", () => {
- const contextTab = TabContextMenu.contextTab;
- const selectedTabs = contextTab?.multiselected
- ? gBrowser.selectedTabs
- : [contextTab];
- menuItem.hidden =
- !contextTab ||
- !selectedTabs.every(tab =>
- tab?.group?.hasAttribute("split-view-group")
- );
- });
- }
}
window.gZenShareManager = new nsZenShareManager();
diff --git a/src/zen/split-view/ZenViewSplitter.mjs b/src/zen/split-view/ZenViewSplitter.mjs
index e464e16cd..3eb1b1a35 100644
--- a/src/zen/split-view/ZenViewSplitter.mjs
+++ b/src/zen/split-view/ZenViewSplitter.mjs
@@ -1184,6 +1184,8 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
document.l10n.setAttributes(splitTabCommand, "tab-zen-split-tabs", {
tabCount: isExistingSplitView ? -1 : selectedTabs.length,
});
+ document.getElementById("context_zenShareSplitView").hidden =
+ !gZenShareManager.enabled || !isExistingSplitView;
if (isExistingSplitView) {
splitTabCommand.removeAttribute("hidden");
return;
@@ -1204,6 +1206,10 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
data-lazy-l10n-id="tab-zen-split-tabs"
data-l10n-args='{"tabCount": 1}'
command="cmd_zenSplitViewContextMenu"/>
+
`);
document.getElementById("context_moveTabToSplitView").before(element);
}
@@ -1252,6 +1258,16 @@ class nsZenViewSplitter extends nsZenDOMOperatedFeature {
this.splitTabs([currentTab, newTab], undefined, 1);
}
+ /**
+ * Shares the split view of the context tab.
+ */
+ contextShareSplitView() {
+ const group = TabContextMenu.contextTab?.group;
+ if (group?.hasAttribute("split-view-group")) {
+ gZenShareManager.shareSplitView(group);
+ }
+ }
+
/**
* Splits the selected tabs.
*
diff --git a/src/zen/sync/ZenSpacesSyncApplier.sys.mjs b/src/zen/sync/ZenSpacesSyncApplier.sys.mjs
index b6226f7eb..aeba7b2e6 100644
--- a/src/zen/sync/ZenSpacesSyncApplier.sys.mjs
+++ b/src/zen/sync/ZenSpacesSyncApplier.sys.mjs
@@ -654,7 +654,7 @@ class nsZenSpacesSyncApplier {
);
win.gBrowser.setIcon(tab, icon);
lazy.TabStateCache.update(tab.linkedBrowser.permanentKey, {
- image: null,
+ image: icon || null,
});
} catch (e) {
console.error("ZenSpacesSync: failed to set tab icon", e);
diff --git a/src/zen/tabs/ZenPinnedTabManager.mjs b/src/zen/tabs/ZenPinnedTabManager.mjs
index 2313edd61..a60f52c4c 100644
--- a/src/zen/tabs/ZenPinnedTabManager.mjs
+++ b/src/zen/tabs/ZenPinnedTabManager.mjs
@@ -680,7 +680,7 @@ class nsZenPinnedTabManager extends nsZenDOMOperatedFeature {
}
gBrowser.setIcon(tab, icon);
lazy.TabStateCache.update(tab.permanentKey, {
- image: null,
+ image: icon || null,
});
},
});