fix(window): normalize closedAt of OpenNoteContexts for abnormally closed windows

This commit is contained in:
SiriusXT 2026-01-05 11:21:40 +08:00
parent 3a9e686533
commit c612bdbfc1
3 changed files with 52 additions and 13 deletions

View File

@ -149,18 +149,31 @@ export default class TabManager extends Component {
currentWin.contexts = filteredNoteContexts;
} else {
if (savedWindows?.length >= MAX_SAVED_WINDOWS) {
// Filter out a window to remove
// Filter out the oldest entry
// 1) Never remove the "main" window
// 2) Remove the window with the oldest creation time
let windowToRemove: WindowState | null = null;
for (const win of savedWindows) {
if (win.windowId === "main") continue; // never remove main
if (!windowToRemove || win.createdAt < windowToRemove.createdAt) {
windowToRemove = win;
// 2) Prefer removing the oldest closed window (closedAt !== 0)
// 3) If no closed window exists, remove the window with the oldest created window
let oldestClosedIndex = -1;
let oldestClosedTime = Infinity;
let oldestCreatedIndex = -1;
let oldestCreatedTime = Infinity;
savedWindows.forEach((w: WindowState, i: number) => {
if (w.windowId === "main") return;
if (w.closedAt !== 0) {
if (w.closedAt < oldestClosedTime) {
oldestClosedTime = w.closedAt;
oldestClosedIndex = i;
}
} else {
if (w.createdAt < oldestCreatedTime) {
oldestCreatedTime = w.createdAt;
oldestCreatedIndex = i;
}
}
}
if (windowToRemove) {
savedWindows.splice(savedWindows.indexOf(windowToRemove), 1);
});
const indexToRemove = oldestClosedIndex !== -1 ? oldestClosedIndex : oldestCreatedIndex;
if (indexToRemove !== -1) {
savedWindows.splice(indexToRemove, 1);
}
}

View File

@ -127,7 +127,8 @@ async function onReady() {
}
});
}
await normalizeOpenNoteContexts();
tray.createTray();
} else {
await windowService.createSetupWindow();
@ -136,6 +137,30 @@ async function onReady() {
await windowService.registerGlobalShortcuts();
}
/**
* Some windows may have closed abnormally, leaving closedAt as 0 in openNoteContexts.
* This function normalizes those timestamps to the current time for correct sorting/filtering.
*/
async function normalizeOpenNoteContexts() {
const savedWindows = options.getOptionJson("openNoteContexts") || [];
const now = Date.now();
let changed = false;
for (const win of savedWindows) {
if (win.windowId !== "main" && win.closedAt === 0) {
win.closedAt = now;
changed = true;
}
}
if (changed) {
const { default: cls } = (await import("@triliumnext/server/src/services/cls.js"));
cls.wrap(() => {
options.setOption("openNoteContexts", JSON.stringify(savedWindows));
})();
}
}
function getElectronLocale() {
const uiLocale = options.getOptionOrNull("locale");
const formattingLocale = options.getOptionOrNull("formattingLocale");

View File

@ -201,10 +201,11 @@ function updateTrayMenu() {
const openedWindowIds = windowService.getAllWindowIds();
const closedWindows = savedWindows
.filter(win => !openedWindowIds.includes(win.windowId))
.sort((a, b) => { return b.closedAt - a.closedAt; }); // sort by time in descending order
.sort((a, b) => { return a.closedAt - b.closedAt; }); // sort by time in ascending order
const menuItems: Electron.MenuItemConstructorOptions[] = [];
for (const win of closedWindows) {
for (let i = closedWindows.length - 1; i >= 0; i--) {
const win = closedWindows[i];
const activeCtx = win.contexts.find(c => c.active === true);
const activateNotePath = (activeCtx ?? win.contexts[0])?.notePath;
const activateNoteId = activateNotePath?.split("/").pop() ?? null;