From 62b0d70189be9453cf5bd875fae22ab5600719bf Mon Sep 17 00:00:00 2001 From: h3p Date: Sun, 8 Mar 2026 13:20:14 +0100 Subject: [PATCH] Fix Cmd+W close flow to confirm unsaved editor tabs --- Neon Vision Editor.xcodeproj/project.pbxproj | 4 ++-- Neon Vision Editor/App/AppMenus.swift | 8 +++----- Neon Vision Editor/App/NeonVisionEditorApp.swift | 1 + Neon Vision Editor/UI/ContentView.swift | 5 +++++ Neon Vision Editor/UI/PanelsAndHelpers.swift | 1 + 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Neon Vision Editor.xcodeproj/project.pbxproj b/Neon Vision Editor.xcodeproj/project.pbxproj index 308f1de..7150e11 100644 --- a/Neon Vision Editor.xcodeproj/project.pbxproj +++ b/Neon Vision Editor.xcodeproj/project.pbxproj @@ -361,7 +361,7 @@ CODE_SIGNING_ALLOWED = YES; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 429; + CURRENT_PROJECT_VERSION = 430; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = CS727NF72U; ENABLE_APP_SANDBOX = YES; @@ -444,7 +444,7 @@ CODE_SIGNING_ALLOWED = YES; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 429; + CURRENT_PROJECT_VERSION = 430; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = CS727NF72U; ENABLE_APP_SANDBOX = YES; diff --git a/Neon Vision Editor/App/AppMenus.swift b/Neon Vision Editor/App/AppMenus.swift index 69b4f78..5387e80 100644 --- a/Neon Vision Editor/App/AppMenus.swift +++ b/Neon Vision Editor/App/AppMenus.swift @@ -6,6 +6,7 @@ import FoundationModels struct NeonVisionMacAppCommands: Commands { let activeEditorViewModel: () -> EditorViewModel + let hasActiveEditorWindow: () -> Bool let openNewWindow: () -> Void let openAIDiagnosticsWindow: () -> Void let postWindowCommand: (_ name: Notification.Name, _ object: Any?) -> Void @@ -121,13 +122,10 @@ struct NeonVisionMacAppCommands: Commands { Divider() Button("Close Tab") { - let current = activeEditorViewModel() - if let tab = current.selectedTab { - current.closeTab(tabID: tab.id) - } + post(.closeSelectedTabRequested) } .keyboardShortcut("w", modifiers: .command) - .disabled(!hasSelectedTab) + .disabled(!hasActiveEditorWindow() || !hasSelectedTab) } } diff --git a/Neon Vision Editor/App/NeonVisionEditorApp.swift b/Neon Vision Editor/App/NeonVisionEditorApp.swift index 73a7e40..9720de6 100644 --- a/Neon Vision Editor/App/NeonVisionEditorApp.swift +++ b/Neon Vision Editor/App/NeonVisionEditorApp.swift @@ -368,6 +368,7 @@ struct NeonVisionEditorApp: App { .commands { NeonVisionMacAppCommands( activeEditorViewModel: { activeEditorViewModel }, + hasActiveEditorWindow: { WindowViewModelRegistry.shared.activeViewModel() != nil }, openNewWindow: { openWindow(id: "blank-window") }, openAIDiagnosticsWindow: { openWindow(id: "ai-logs") }, postWindowCommand: { name, object in diff --git a/Neon Vision Editor/UI/ContentView.swift b/Neon Vision Editor/UI/ContentView.swift index 0a12e02..fda6111 100644 --- a/Neon Vision Editor/UI/ContentView.swift +++ b/Neon Vision Editor/UI/ContentView.swift @@ -1612,6 +1612,11 @@ struct ContentView: View { openSettings() } } + .onReceive(NotificationCenter.default.publisher(for: .closeSelectedTabRequested)) { notif in + guard matchesCurrentWindow(notif) else { return } + guard let tab = viewModel.selectedTab else { return } + requestCloseTab(tab) + } .onReceive(NotificationCenter.default.publisher(for: .showUpdaterRequested)) { notif in guard matchesCurrentWindow(notif) else { return } let shouldCheckNow = (notif.object as? Bool) ?? true diff --git a/Neon Vision Editor/UI/PanelsAndHelpers.swift b/Neon Vision Editor/UI/PanelsAndHelpers.swift index a02ab6d..5eb7133 100644 --- a/Neon Vision Editor/UI/PanelsAndHelpers.swift +++ b/Neon Vision Editor/UI/PanelsAndHelpers.swift @@ -777,6 +777,7 @@ extension Notification.Name { static let keyboardAccessoryBarVisibilityChanged = Notification.Name("keyboardAccessoryBarVisibilityChanged") static let showUpdaterRequested = Notification.Name("showUpdaterRequested") static let showSettingsRequested = Notification.Name("showSettingsRequested") + static let closeSelectedTabRequested = Notification.Name("closeSelectedTabRequested") } extension NSRange {