···9999// Throws on query failure so callers can distinguish "no Firefox windows"
100100// from "we don't know" — a silent empty result here under load caused
101101// duplicate window restoration.
102102+//
103103+// A workspace holding more than one Firefox window is ambiguous and is left
104104+// out of the map. This happens after every Firefox restart: session restore
105105+// reopens all windows on the focused workspace, and mapping any one of them to
106106+// that workspace would overwrite its file with another workspace's tabs.
102107async function getFirefoxWindowMappings() {
103108 const resp = await sendNative("map_windows");
104109 if (resp.error) throw new Error(resp.error);
105110 if (!resp.windows) throw new Error("map_windows: no windows field");
111111+112112+ const perWorkspace = new Map();
113113+ for (const mapping of resp.windows) {
114114+ perWorkspace.set(
115115+ mapping.workspace,
116116+ (perWorkspace.get(mapping.workspace) || 0) + 1,
117117+ );
118118+ }
106119107120 const allWindows = await browser.windows.getAll({ populate: true });
108121 const result = new Map();
109122 const matched = new Set();
110123111124 for (const mapping of resp.windows) {
125125+ if (perWorkspace.get(mapping.workspace) > 1) {
126126+ console.warn(
127127+ `Workspace ${mapping.workspace} has several Firefox windows — not mapping it`,
128128+ );
129129+ continue;
130130+ }
112131 const swayTitle = mapping.windowTitle || "";
113132 for (const win of allWindows) {
114133 if (matched.has(win.id) || win.id === anchorWindowId) continue;