diff --git a/packages/app/src/App.ai.test.tsx b/packages/app/src/App.ai.test.tsx index 1cfa6c2a..48d233c3 100644 --- a/packages/app/src/App.ai.test.tsx +++ b/packages/app/src/App.ai.test.tsx @@ -170,6 +170,7 @@ describe("Markra AI workspace", () => { clipboardImageFolder: "assets", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: false, + closeWindowOnLastTabClose: false, contentWidth: "default", contentWidthPx: null, documentLinksOpen: true, @@ -289,6 +290,7 @@ describe("Markra AI workspace", () => { clipboardImageFolder: "assets", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: false, + closeWindowOnLastTabClose: false, contentWidth: "default", contentWidthPx: null, documentLinksOpen: true, diff --git a/packages/app/src/App.test.tsx b/packages/app/src/App.test.tsx index 80c08138..26fd4a1e 100644 --- a/packages/app/src/App.test.tsx +++ b/packages/app/src/App.test.tsx @@ -409,6 +409,7 @@ function createStoredEditorPreferences( clipboardImageFolder: "assets", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: false, + closeWindowOnLastTabClose: overrides.closeWindowOnLastTabClose ?? false, contentWidth: "default", contentWidthPx: null, documentLinksOpen: true, @@ -1613,6 +1614,7 @@ describe("Markra workspace", () => { clipboardImageFolder: "assets", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: false, + closeWindowOnLastTabClose: false, contentWidth: "default", contentWidthPx: null, documentLinksOpen: true, @@ -1686,6 +1688,7 @@ describe("Markra workspace", () => { clipboardImageFolder: "assets", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: false, + closeWindowOnLastTabClose: false, contentWidth: "default", contentWidthPx: null, documentLinksOpen: true, @@ -2962,6 +2965,7 @@ describe("Markra workspace", () => { clipboardImageFolder: "assets", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: false, + closeWindowOnLastTabClose: false, contentWidth: "default", contentWidthPx: null, documentLinksOpen: true, @@ -4215,6 +4219,69 @@ describe("Markra workspace", () => { filePath: null, openFilePaths: [] })); + expect(mockedCloseNativeWindow).not.toHaveBeenCalled(); + }); + + it("closes the window from Cmd+W when the last tab closes and the preference is enabled", async () => { + mockedGetStoredEditorPreferences.mockResolvedValue(createStoredEditorPreferences({ + closeWindowOnLastTabClose: true + })); + mockOpenMarkdownFile({ + content: "# Native file\n\nOpened from disk.", + name: "native.md", + path: mockNativePath + }); + + renderApp(); + + fireEvent.keyDown(window, { key: "o", metaKey: true }); + await expectVisibleMarkdownText("Native file"); + + fireEvent.keyDown(window, { key: "w", metaKey: true }); + + await waitFor(() => expect(mockedCloseNativeWindow).toHaveBeenCalledTimes(1)); + }); + + it("keeps the window open when Cmd+W closes one of multiple tabs", async () => { + mockedGetStoredEditorPreferences.mockResolvedValue(createStoredEditorPreferences({ + closeWindowOnLastTabClose: true + })); + mockOpenMarkdownFile({ + content: "# Native file\n\nOpened from disk.", + name: "native.md", + path: mockNativePath + }); + + renderApp(); + + fireEvent.keyDown(window, { key: "o", metaKey: true }); + await expectVisibleMarkdownText("Native file"); + fireEvent.click(screen.getByRole("button", { name: "New tab" })); + expect(screen.getAllByRole("tab")).toHaveLength(2); + + fireEvent.keyDown(window, { key: "w", metaKey: true }); + + await waitFor(() => expect(screen.getAllByRole("tab")).toHaveLength(1)); + expect(mockedCloseNativeWindow).not.toHaveBeenCalled(); + }); + + it("closes the window when the last tab close button is used", async () => { + mockedGetStoredEditorPreferences.mockResolvedValue(createStoredEditorPreferences({ + closeWindowOnLastTabClose: true + })); + mockOpenMarkdownFile({ + content: "# Native file\n\nOpened from disk.", + name: "native.md", + path: mockNativePath + }); + + renderApp(); + + fireEvent.keyDown(window, { key: "o", metaKey: true }); + await expectVisibleMarkdownText("Native file"); + fireEvent.click(screen.getByRole("button", { name: "Close tab native.md" })); + + await waitFor(() => expect(mockedCloseNativeWindow).toHaveBeenCalledTimes(1)); }); it("previews an image asset from the current folder tree and returns to markdown files", async () => { @@ -5992,6 +6059,7 @@ describe("Markra workspace", () => { clipboardImageFolder: "assets", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: false, + closeWindowOnLastTabClose: false, contentWidth: "default", contentWidthPx: null, documentLinksOpen: true, @@ -6164,6 +6232,7 @@ describe("Markra workspace", () => { clipboardImageFolder: "assets", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: false, + closeWindowOnLastTabClose: false, contentWidth: "default", contentWidthPx: null, documentLinksOpen: true, diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index b2e063a1..874a00e6 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -1207,6 +1207,13 @@ function WorkspaceApp() { path: tab.path })) ], [documentTabs, imageTabs]); + const closeWindowAfterLastTab = useCallback((closedTabId: string) => { + if (!editorPreferences.preferences.closeWindowOnLastTabClose) return; + // Callers run this only after a successful close; this render still holds the pre-close tab list. + if (titlebarTabs.length !== 1 || titlebarTabs[0]?.id !== closedTabId) return; + + closeNativeWindow().catch(() => {}); + }, [editorPreferences.preferences.closeWindowOnLastTabClose, titlebarTabs]); const activeTitlebarTabId = activeImageFile ? imageDocumentTabId(activeImageFile.path) : activeTabId; const { clearSideDocumentGroup, @@ -2867,6 +2874,7 @@ function WorkspaceApp() { clearSideDocumentGroup(); updateActiveAiSelection(null); handleAiCommandClose(); + closeWindowAfterLastTab(focusedSideCloseTabId); return; } @@ -2874,6 +2882,7 @@ function WorkspaceApp() { const closingTabId = imageDocumentTabId(activeImageFile.path); setImageTabs((currentTabs) => currentTabs.filter((tab) => tab.id !== closingTabId)); setActiveImageFile(null); + closeWindowAfterLastTab(closingTabId); return; } @@ -2886,6 +2895,7 @@ function WorkspaceApp() { } updateActiveAiSelection(null); handleAiCommandClose(); + closeWindowAfterLastTab(activeTabId); return; } @@ -2902,6 +2912,7 @@ function WorkspaceApp() { clearSideDocumentGroup, clearOpenDocument, closeMarkdownTab, + closeWindowAfterLastTab, confirmCanDiscardCurrentDocument, documentOperationTarget, handleAiCommandClose, @@ -4378,6 +4389,7 @@ function WorkspaceApp() { if (closingActiveImage) setActiveImageFile(null); updateActiveAiSelection(null); handleAiCommandClose(); + closeWindowAfterLastTab(tabId); return true; } @@ -4389,12 +4401,14 @@ function WorkspaceApp() { } updateActiveAiSelection(null); handleAiCommandClose(); + closeWindowAfterLastTab(tabId); return true; }, [ activeImageFile, captureActiveDocumentViewState, clearSideDocumentGroup, closeMarkdownTab, + closeWindowAfterLastTab, handleAiCommandClose, imageTabs, sideDocumentGroup, diff --git a/packages/app/src/components/settings/GeneralSettings.test.tsx b/packages/app/src/components/settings/GeneralSettings.test.tsx index 5cc2aa5e..7bcd027c 100644 --- a/packages/app/src/components/settings/GeneralSettings.test.tsx +++ b/packages/app/src/components/settings/GeneralSettings.test.tsx @@ -150,6 +150,35 @@ describe("GeneralSettings", () => { }); }); + it("toggles closing the window with the last document tab", () => { + const onUpdatePreferences = vi.fn(); + + render( + + ); + + expect(screen.getByRole("heading", { name: "Window" })).toBeInTheDocument(); + fireEvent.click(screen.getByRole("switch", { name: "Close window with last tab" })); + + expect(onUpdatePreferences).toHaveBeenCalledWith({ + ...defaultEditorPreferences, + closeWindowOnLastTabClose: true + }); + }); + it("keeps diagnostics actions out of general settings", () => { render( ) : null} + + + onUpdatePreferences({ + ...preferences, + closeWindowOnLastTabClose: !preferences.closeWindowOnLastTabClose + }) + } + /> + } + /> + + ({ clipboardImageFolder: "assets", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: false, + closeWindowOnLastTabClose: false, contentWidth: "default", contentWidthPx: null, documentLinksOpen: true, @@ -152,6 +153,7 @@ describe("useEditorPreferences", () => { clipboardImageFolder: "assets", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: false, + closeWindowOnLastTabClose: false, contentWidth: "default", contentWidthPx: null, documentLinksOpen: true, @@ -273,6 +275,7 @@ describe("useEditorPreferences", () => { clipboardImageFolder: "images", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: true, + closeWindowOnLastTabClose: false, contentWidth: "wide", contentWidthPx: 1120, documentLinksOpen: true, diff --git a/packages/app/src/lib/settings/app-settings.test.ts b/packages/app/src/lib/settings/app-settings.test.ts index fea7346b..9d760a5b 100644 --- a/packages/app/src/lib/settings/app-settings.test.ts +++ b/packages/app/src/lib/settings/app-settings.test.ts @@ -379,6 +379,12 @@ describe("app settings", () => { expect(normalizeEditorPreferences({ openDroppedFilesInTabs: "yes" }).openDroppedFilesInTabs).toBe(false); }); + it("normalizes the close window on last tab preference", () => { + expect(defaultEditorPreferences.closeWindowOnLastTabClose).toBe(false); + expect(normalizeEditorPreferences({ closeWindowOnLastTabClose: true }).closeWindowOnLastTabClose).toBe(true); + expect(normalizeEditorPreferences({ closeWindowOnLastTabClose: "yes" }).closeWindowOnLastTabClose).toBe(false); + }); + it("normalizes the document links visibility preference", () => { expect(defaultEditorPreferences.documentLinksVisible).toBe(false); expect(normalizeEditorPreferences({ documentLinksVisible: true }).documentLinksVisible).toBe(true); diff --git a/packages/app/src/lib/settings/app-settings.ts b/packages/app/src/lib/settings/app-settings.ts index 0f639c1f..27ce10d2 100644 --- a/packages/app/src/lib/settings/app-settings.ts +++ b/packages/app/src/lib/settings/app-settings.ts @@ -402,6 +402,7 @@ export type EditorPreferences = { bodyFontSize: number; clipboardImageFolder: string; closeAiCommandOnAgentPanelOpen: boolean; + closeWindowOnLastTabClose: boolean; contentWidth: EditorContentWidth; contentWidthPx: number | null; copyExternalFilesToStorage: boolean; @@ -565,6 +566,7 @@ export const defaultEditorPreferences: EditorPreferences = { bodyFontSize: 16, clipboardImageFolder: "assets", closeAiCommandOnAgentPanelOpen: false, + closeWindowOnLastTabClose: false, contentWidth: "default", contentWidthPx: null, copyExternalFilesToStorage: true, @@ -1762,6 +1764,10 @@ export function normalizeEditorPreferences(value: unknown): EditorPreferences { typeof preferences.closeAiCommandOnAgentPanelOpen === "boolean" ? preferences.closeAiCommandOnAgentPanelOpen : defaultEditorPreferences.closeAiCommandOnAgentPanelOpen, + closeWindowOnLastTabClose: + typeof preferences.closeWindowOnLastTabClose === "boolean" + ? preferences.closeWindowOnLastTabClose + : defaultEditorPreferences.closeWindowOnLastTabClose, contentWidth: editorContentWidthOptions.includes(preferences.contentWidth as EditorContentWidth) ? (preferences.contentWidth as EditorContentWidth) : defaultEditorPreferences.contentWidth, diff --git a/packages/app/src/lib/settings/editor-preferences.test.ts b/packages/app/src/lib/settings/editor-preferences.test.ts index 1e769620..d0d0583c 100644 --- a/packages/app/src/lib/settings/editor-preferences.test.ts +++ b/packages/app/src/lib/settings/editor-preferences.test.ts @@ -35,6 +35,7 @@ describe("editor preferences", () => { clipboardImageFolder: "assets", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: false, + closeWindowOnLastTabClose: false, contentWidth: "default", contentWidthPx: null, documentLinksOpen: true, @@ -132,6 +133,7 @@ describe("editor preferences", () => { clipboardImageFolder: "media/screenshots", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: true, + closeWindowOnLastTabClose: false, contentWidth: "page", imageUpload: { fileNamePattern: "web-{name}-{timestamp}", @@ -183,6 +185,7 @@ describe("editor preferences", () => { clipboardImageFolder: "media/screenshots", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: true, + closeWindowOnLastTabClose: false, contentWidth: "default", contentWidthPx: null, documentLinksOpen: true, @@ -748,6 +751,7 @@ describe("editor preferences", () => { clipboardImageFolder: "assets", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: false, + closeWindowOnLastTabClose: false, contentWidth: "default", contentWidthPx: null, documentLinksOpen: true, @@ -846,6 +850,7 @@ describe("editor preferences", () => { clipboardImageFolder: "images", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: true, + closeWindowOnLastTabClose: false, contentWidth: "wide", contentWidthPx: 1120, documentLinksOpen: true, @@ -952,6 +957,7 @@ describe("editor preferences", () => { clipboardImageFolder: "images", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: true, + closeWindowOnLastTabClose: false, contentWidth: "wide", contentWidthPx: 1120, documentLinksOpen: true, diff --git a/packages/app/src/lib/settings/settings-events.test.ts b/packages/app/src/lib/settings/settings-events.test.ts index ad307d2f..3cc66013 100644 --- a/packages/app/src/lib/settings/settings-events.test.ts +++ b/packages/app/src/lib/settings/settings-events.test.ts @@ -196,6 +196,7 @@ describe("settings events", () => { clipboardImageFolder: "images", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: true, + closeWindowOnLastTabClose: false, contentWidth: "wide" as const, contentWidthPx: 1120, documentLinksOpen: true, @@ -290,6 +291,7 @@ describe("settings events", () => { payload: { preferences: { closeAiCommandOnAgentPanelOpen: false, + closeWindowOnLastTabClose: false, showAiQuickInputOnSelection: "nope", showAiSelectionToolbarOnSelection: true } diff --git a/packages/app/src/test/app-harness.tsx b/packages/app/src/test/app-harness.tsx index 7caee576..8a4054c8 100644 --- a/packages/app/src/test/app-harness.tsx +++ b/packages/app/src/test/app-harness.tsx @@ -295,6 +295,7 @@ vi.mock("../lib/settings/app-settings", () => ({ clipboardImageFolder: "assets", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: false, + closeWindowOnLastTabClose: false, contentWidth: "default", contentWidthPx: null, documentLinksOpen: true, @@ -603,6 +604,7 @@ vi.mock("../lib/settings/app-settings", () => ({ clipboardImageFolder: "assets", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: false, + closeWindowOnLastTabClose: false, contentWidth: "default", contentWidthPx: null, editorFontFamily: { family: null, source: "theme" }, @@ -1449,6 +1451,7 @@ export function installAppTestHarness() { clipboardImageFolder: "assets", copyExternalFilesToStorage: true, closeAiCommandOnAgentPanelOpen: false, + closeWindowOnLastTabClose: false, contentWidth: "default", contentWidthPx: null, documentLinksOpen: true, diff --git a/packages/shared/src/i18n/locales/de.ts b/packages/shared/src/i18n/locales/de.ts index f3abbea9..719ad93e 100644 --- a/packages/shared/src/i18n/locales/de.ts +++ b/packages/shared/src/i18n/locales/de.ts @@ -518,6 +518,7 @@ const messages: LocaleMessages = { "app.clipboardImageS3UploadNotConfigured": "Konfiguriere S3-kompatiblen Speicher, bevor du Bilder einfügst.", "app.clipboardImageSaveFailed": "Das eingefügte Bild konnte nicht gespeichert werden.", "settings.sections.startup": "Start", + "settings.sections.window": "Fenster", "settings.sections.theme": "Design", "settings.sections.editing": "Bearbeitung", "settings.sections.extendedSyntax": "Erweiterte Syntax", @@ -723,6 +724,8 @@ const messages: LocaleMessages = { "settings.editor.titlebarActionsReset": "Schaltflächen oben rechts zurücksetzen", "settings.editor.showDocumentTabs": "Dokument-Tabs anzeigen", "settings.editor.showDocumentTabsDescription": "Zeigt geöffnete Markdown-Dateien in einer kompakten Tab-Leiste über dem Editor.", + "settings.window.closeWindowOnLastTabClose": "Fenster mit letztem Tab schließen", + "settings.window.closeWindowOnLastTabCloseDescription": "Schließt das aktuelle Fenster, wenn sein letzter Dokument- oder Bild-Tab geschlossen wird. Andere Fenster bleiben geöffnet.", "settings.editor.autoRevealActiveFile": "Aktive Datei automatisch anzeigen", "settings.editor.autoRevealActiveFileDescription": "Erweitert beim Wechseln der Tabs den Dateibaum bis zum aktuellen Dokument.", "settings.editor.sidebarLayoutMode": "Seitenleisten-Layout", diff --git a/packages/shared/src/i18n/locales/en.ts b/packages/shared/src/i18n/locales/en.ts index 951611e3..b18cad98 100644 --- a/packages/shared/src/i18n/locales/en.ts +++ b/packages/shared/src/i18n/locales/en.ts @@ -18,6 +18,7 @@ const messages: BaseLocaleMessages = { "settings.categories.templates": "Templates", "settings.categories.export": "Export", "settings.sections.startup": "Startup", + "settings.sections.window": "Window", "settings.sections.language": "Language", "settings.sections.theme": "Theme", "settings.sections.editing": "Editing", @@ -320,6 +321,8 @@ const messages: BaseLocaleMessages = { "settings.editor.titlebarActionsReset": "Reset top-right buttons", "settings.editor.showDocumentTabs": "Show document tabs", "settings.editor.showDocumentTabsDescription": "Keep open Markdown files in a compact tab strip above the editor.", + "settings.window.closeWindowOnLastTabClose": "Close window with last tab", + "settings.window.closeWindowOnLastTabCloseDescription": "Close the current window when its last document or image tab closes. Other windows stay open.", "settings.editor.autoRevealActiveFile": "Reveal active file automatically", "settings.editor.autoRevealActiveFileDescription": "Expand the file tree to the current document when you switch tabs.", "settings.editor.sidebarLayoutMode": "Sidebar layout", diff --git a/packages/shared/src/i18n/locales/es.ts b/packages/shared/src/i18n/locales/es.ts index 426eac9a..153e64f2 100644 --- a/packages/shared/src/i18n/locales/es.ts +++ b/packages/shared/src/i18n/locales/es.ts @@ -518,6 +518,7 @@ const messages: LocaleMessages = { "app.clipboardImageS3UploadNotConfigured": "Configura el almacenamiento compatible con S3 antes de pegar imágenes.", "app.clipboardImageSaveFailed": "No se pudo guardar la imagen pegada.", "settings.sections.startup": "Inicio", + "settings.sections.window": "Ventana", "settings.sections.theme": "Tema", "settings.sections.editing": "Edición", "settings.sections.extendedSyntax": "Sintaxis extendida", @@ -723,6 +724,8 @@ const messages: LocaleMessages = { "settings.editor.titlebarActionsReset": "Restablecer botones superiores derechos", "settings.editor.showDocumentTabs": "Mostrar pestañas de documentos", "settings.editor.showDocumentTabsDescription": "Muestra los archivos Markdown abiertos en una barra de pestañas compacta sobre el editor.", + "settings.window.closeWindowOnLastTabClose": "Cerrar ventana con la última pestaña", + "settings.window.closeWindowOnLastTabCloseDescription": "Cierra la ventana actual al cerrar su última pestaña de documento o imagen. Las demás ventanas permanecen abiertas.", "settings.editor.autoRevealActiveFile": "Mostrar archivo activo automáticamente", "settings.editor.autoRevealActiveFileDescription": "Expande el árbol de archivos hasta el documento actual al cambiar de pestaña.", "settings.editor.sidebarLayoutMode": "Diseño de la barra lateral", diff --git a/packages/shared/src/i18n/locales/fr.ts b/packages/shared/src/i18n/locales/fr.ts index 9981f667..926f33a9 100644 --- a/packages/shared/src/i18n/locales/fr.ts +++ b/packages/shared/src/i18n/locales/fr.ts @@ -518,6 +518,7 @@ const messages: LocaleMessages = { "app.clipboardImageS3UploadNotConfigured": "Configurez le stockage compatible S3 avant de coller des images.", "app.clipboardImageSaveFailed": "Impossible d’enregistrer l’image collée.", "settings.sections.startup": "Démarrage", + "settings.sections.window": "Fenêtre", "settings.sections.theme": "Thème", "settings.sections.editing": "Édition", "settings.sections.extendedSyntax": "Syntaxe étendue", @@ -723,6 +724,8 @@ const messages: LocaleMessages = { "settings.editor.titlebarActionsReset": "Réinitialiser les boutons en haut à droite", "settings.editor.showDocumentTabs": "Afficher les onglets de documents", "settings.editor.showDocumentTabsDescription": "Affiche les fichiers Markdown ouverts dans une barre d’onglets compacte au-dessus de l’éditeur.", + "settings.window.closeWindowOnLastTabClose": "Fermer la fenêtre avec le dernier onglet", + "settings.window.closeWindowOnLastTabCloseDescription": "Ferme la fenêtre actuelle lorsque son dernier onglet de document ou d’image est fermé. Les autres fenêtres restent ouvertes.", "settings.editor.autoRevealActiveFile": "Afficher automatiquement le fichier actif", "settings.editor.autoRevealActiveFileDescription": "Déplie l’arborescence jusqu’au document actuel lorsque vous changez d’onglet.", "settings.editor.sidebarLayoutMode": "Disposition de la barre latérale", diff --git a/packages/shared/src/i18n/locales/it.ts b/packages/shared/src/i18n/locales/it.ts index 707e93ca..4b4df703 100644 --- a/packages/shared/src/i18n/locales/it.ts +++ b/packages/shared/src/i18n/locales/it.ts @@ -518,6 +518,7 @@ const messages: LocaleMessages = { "app.clipboardImageS3UploadNotConfigured": "Configura l’archiviazione compatibile S3 prima di incollare immagini.", "app.clipboardImageSaveFailed": "Impossibile salvare l’immagine incollata.", "settings.sections.startup": "Avvio", + "settings.sections.window": "Finestra", "settings.sections.theme": "Tema", "settings.sections.editing": "Modifica", "settings.sections.extendedSyntax": "Sintassi estesa", @@ -723,6 +724,8 @@ const messages: LocaleMessages = { "settings.editor.titlebarActionsReset": "Ripristina pulsanti in alto a destra", "settings.editor.showDocumentTabs": "Mostra schede documento", "settings.editor.showDocumentTabsDescription": "Mostra i file Markdown aperti in una barra di schede compatta sopra l’editor.", + "settings.window.closeWindowOnLastTabClose": "Chiudi la finestra con l’ultima scheda", + "settings.window.closeWindowOnLastTabCloseDescription": "Chiude la finestra corrente quando viene chiusa l’ultima scheda documento o immagine. Le altre finestre restano aperte.", "settings.editor.autoRevealActiveFile": "Mostra automaticamente il file attivo", "settings.editor.autoRevealActiveFileDescription": "Espande l’albero dei file fino al documento corrente quando cambi scheda.", "settings.editor.sidebarLayoutMode": "Layout barra laterale", diff --git a/packages/shared/src/i18n/locales/ja.ts b/packages/shared/src/i18n/locales/ja.ts index b340591e..c6b04f6f 100644 --- a/packages/shared/src/i18n/locales/ja.ts +++ b/packages/shared/src/i18n/locales/ja.ts @@ -18,6 +18,7 @@ const messages: LocaleMessages = { "settings.categories.templates": "テンプレート", "settings.categories.export": "書き出し", "settings.sections.startup": "起動", + "settings.sections.window": "ウィンドウ", "settings.sections.language": "言語", "settings.sections.theme": "テーマ", "settings.sections.editing": "編集", @@ -723,6 +724,8 @@ const messages: LocaleMessages = { "settings.editor.titlebarActionsReset": "右上ボタンをリセット", "settings.editor.showDocumentTabs": "ドキュメントタブを表示", "settings.editor.showDocumentTabsDescription": "開いている Markdown ファイルをエディター上部のコンパクトなタブに表示します。", + "settings.window.closeWindowOnLastTabClose": "最後のタブでウィンドウを閉じる", + "settings.window.closeWindowOnLastTabCloseDescription": "最後のドキュメントまたは画像タブを閉じたときに、現在のウィンドウを閉じます。他のウィンドウは開いたままです。", "settings.editor.autoRevealActiveFile": "アクティブファイルを自動表示", "settings.editor.autoRevealActiveFileDescription": "タブを切り替えたときに、現在のドキュメントまでファイルツリーを展開します。", "settings.editor.sidebarLayoutMode": "サイドバーレイアウト", diff --git a/packages/shared/src/i18n/locales/ko.ts b/packages/shared/src/i18n/locales/ko.ts index ebb87d45..a779f8d4 100644 --- a/packages/shared/src/i18n/locales/ko.ts +++ b/packages/shared/src/i18n/locales/ko.ts @@ -518,6 +518,7 @@ const messages: LocaleMessages = { "app.clipboardImageS3UploadNotConfigured": "이미지를 붙여넣기 전에 S3 호환 저장을 설정하세요.", "app.clipboardImageSaveFailed": "붙여넣은 이미지를 저장할 수 없습니다.", "settings.sections.startup": "시작", + "settings.sections.window": "창", "settings.sections.theme": "테마", "settings.sections.editing": "편집", "settings.sections.extendedSyntax": "확장 구문", @@ -723,6 +724,8 @@ const messages: LocaleMessages = { "settings.editor.titlebarActionsReset": "오른쪽 상단 버튼 초기화", "settings.editor.showDocumentTabs": "문서 탭 표시", "settings.editor.showDocumentTabsDescription": "열린 Markdown 파일을 편집기 위의 간결한 탭 막대에 표시합니다.", + "settings.window.closeWindowOnLastTabClose": "마지막 탭과 함께 창 닫기", + "settings.window.closeWindowOnLastTabCloseDescription": "마지막 문서 또는 이미지 탭을 닫으면 현재 창을 닫습니다. 다른 창은 열린 상태로 유지됩니다.", "settings.editor.autoRevealActiveFile": "활성 파일 자동 표시", "settings.editor.autoRevealActiveFileDescription": "탭을 전환할 때 현재 문서까지 파일 트리를 펼칩니다.", "settings.editor.sidebarLayoutMode": "사이드바 레이아웃", diff --git a/packages/shared/src/i18n/locales/pt-BR.ts b/packages/shared/src/i18n/locales/pt-BR.ts index 45ec4112..0c46c051 100644 --- a/packages/shared/src/i18n/locales/pt-BR.ts +++ b/packages/shared/src/i18n/locales/pt-BR.ts @@ -518,6 +518,7 @@ const messages: LocaleMessages = { "app.clipboardImageS3UploadNotConfigured": "Configure o armazenamento compatível com S3 antes de colar imagens.", "app.clipboardImageSaveFailed": "Não foi possível salvar a imagem colada.", "settings.sections.startup": "Inicialização", + "settings.sections.window": "Janela", "settings.sections.theme": "Tema", "settings.sections.editing": "Edição", "settings.sections.extendedSyntax": "Sintaxe estendida", @@ -723,6 +724,8 @@ const messages: LocaleMessages = { "settings.editor.titlebarActionsReset": "Redefinir botões do canto superior direito", "settings.editor.showDocumentTabs": "Mostrar abas de documentos", "settings.editor.showDocumentTabsDescription": "Mostra arquivos Markdown abertos em uma barra de abas compacta acima do editor.", + "settings.window.closeWindowOnLastTabClose": "Fechar janela com a última aba", + "settings.window.closeWindowOnLastTabCloseDescription": "Fecha a janela atual ao fechar sua última aba de documento ou imagem. As outras janelas permanecem abertas.", "settings.editor.autoRevealActiveFile": "Mostrar arquivo ativo automaticamente", "settings.editor.autoRevealActiveFileDescription": "Expande a árvore de arquivos até o documento atual ao trocar de aba.", "settings.editor.sidebarLayoutMode": "Layout da barra lateral", diff --git a/packages/shared/src/i18n/locales/ru.ts b/packages/shared/src/i18n/locales/ru.ts index 7695cb6e..4c79d540 100644 --- a/packages/shared/src/i18n/locales/ru.ts +++ b/packages/shared/src/i18n/locales/ru.ts @@ -518,6 +518,7 @@ const messages: LocaleMessages = { "app.clipboardImageS3UploadNotConfigured": "Настройте S3-совместимое хранение перед вставкой изображений.", "app.clipboardImageSaveFailed": "Не удалось сохранить вставленное изображение.", "settings.sections.startup": "Запуск", + "settings.sections.window": "Окно", "settings.sections.theme": "Тема", "settings.sections.editing": "Редактирование", "settings.sections.extendedSyntax": "Расширенный синтаксис", @@ -723,6 +724,8 @@ const messages: LocaleMessages = { "settings.editor.titlebarActionsReset": "Сбросить кнопки в правом верхнем углу", "settings.editor.showDocumentTabs": "Показывать вкладки документов", "settings.editor.showDocumentTabsDescription": "Показывает открытые Markdown-файлы в компактной панели вкладок над редактором.", + "settings.window.closeWindowOnLastTabClose": "Закрывать окно с последней вкладкой", + "settings.window.closeWindowOnLastTabCloseDescription": "Закрывает текущее окно при закрытии последней вкладки документа или изображения. Другие окна остаются открытыми.", "settings.editor.autoRevealActiveFile": "Автоматически показывать активный файл", "settings.editor.autoRevealActiveFileDescription": "Разворачивает дерево файлов до текущего документа при переключении вкладок.", "settings.editor.sidebarLayoutMode": "Макет боковой панели", diff --git a/packages/shared/src/i18n/locales/types.ts b/packages/shared/src/i18n/locales/types.ts index 70bf0f94..0c87d1a4 100644 --- a/packages/shared/src/i18n/locales/types.ts +++ b/packages/shared/src/i18n/locales/types.ts @@ -29,6 +29,7 @@ export type I18nKey = | "settings.categories.templates" | "settings.categories.export" | "settings.sections.startup" + | "settings.sections.window" | "settings.sections.language" | "settings.sections.theme" | "settings.sections.editing" @@ -349,6 +350,8 @@ export type I18nKey = | "settings.editor.titlebarActionsReset" | "settings.editor.showDocumentTabs" | "settings.editor.showDocumentTabsDescription" + | "settings.window.closeWindowOnLastTabClose" + | "settings.window.closeWindowOnLastTabCloseDescription" | "settings.editor.autoRevealActiveFile" | "settings.editor.autoRevealActiveFileDescription" | "settings.editor.sidebarLayoutMode" diff --git a/packages/shared/src/i18n/locales/zh-CN.ts b/packages/shared/src/i18n/locales/zh-CN.ts index b8b50288..71633d9a 100644 --- a/packages/shared/src/i18n/locales/zh-CN.ts +++ b/packages/shared/src/i18n/locales/zh-CN.ts @@ -18,6 +18,7 @@ const messages: LocaleMessages = { "settings.categories.templates": "模板", "settings.categories.export": "导出", "settings.sections.startup": "启动", + "settings.sections.window": "窗口", "settings.sections.language": "语言", "settings.sections.theme": "主题", "settings.sections.editing": "编辑", @@ -320,6 +321,8 @@ const messages: LocaleMessages = { "settings.editor.titlebarActionsReset": "重置右上角按钮", "settings.editor.showDocumentTabs": "显示文档标签页", "settings.editor.showDocumentTabsDescription": "在编辑器上方用紧凑标签栏显示已打开的 Markdown 文件。", + "settings.window.closeWindowOnLastTabClose": "关闭最后一个标签页时关闭窗口", + "settings.window.closeWindowOnLastTabCloseDescription": "关闭当前窗口中的最后一个文档或图片标签页时关闭该窗口,其他窗口保持打开。", "settings.editor.autoRevealActiveFile": "自动定位当前文件", "settings.editor.autoRevealActiveFileDescription": "切换标签页时,自动展开文件树并选中当前文档。", "settings.editor.sidebarLayoutMode": "侧栏布局", diff --git a/packages/shared/src/i18n/locales/zh-TW.ts b/packages/shared/src/i18n/locales/zh-TW.ts index eff5bb72..c52e47c4 100644 --- a/packages/shared/src/i18n/locales/zh-TW.ts +++ b/packages/shared/src/i18n/locales/zh-TW.ts @@ -18,6 +18,7 @@ const messages: LocaleMessages = { "settings.categories.templates": "範本", "settings.categories.export": "匯出", "settings.sections.startup": "啟動", + "settings.sections.window": "視窗", "settings.sections.language": "語言", "settings.sections.theme": "主題", "settings.sections.editing": "編輯", @@ -723,6 +724,8 @@ const messages: LocaleMessages = { "settings.editor.titlebarActionsReset": "重置右上角按鈕", "settings.editor.showDocumentTabs": "顯示文件標籤頁", "settings.editor.showDocumentTabsDescription": "在編輯器上方用精簡標籤列顯示已開啟的 Markdown 檔案。", + "settings.window.closeWindowOnLastTabClose": "關閉最後一個分頁時關閉視窗", + "settings.window.closeWindowOnLastTabCloseDescription": "關閉目前視窗中的最後一個文件或圖片分頁時關閉該視窗,其他視窗保持開啟。", "settings.editor.autoRevealActiveFile": "自動定位目前檔案", "settings.editor.autoRevealActiveFileDescription": "切換標籤頁時,自動展開檔案樹並選中目前文件。", "settings.editor.sidebarLayoutMode": "側欄版面",