-
Notifications
You must be signed in to change notification settings - Fork 936
Add configurable close confirmation settings #2609
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2827,14 +2827,16 @@ class TabManager: ObservableObject { | |
| func closeOtherTabsInFocusedPaneWithConfirmation() { | ||
| guard let plan = closeOtherTabsInFocusedPanePlan() else { return } | ||
|
|
||
| let count = plan.panelIds.count | ||
| let titleLines = plan.titles.map { "• \($0)" }.joined(separator: "\n") | ||
| let message = "This is about to close \(count) tab\(count == 1 ? "" : "s") in this pane:\n\(titleLines)" | ||
| guard confirmClose( | ||
| title: "Close other tabs?", | ||
| message: message, | ||
| acceptCmdD: false | ||
| ) else { return } | ||
| if BatchCloseSettings.isEnabled() { | ||
| let count = plan.panelIds.count | ||
| let titleLines = plan.titles.map { "• \($0)" }.joined(separator: "\n") | ||
| let message = "This is about to close \(count) tab\(count == 1 ? "" : "s") in this pane:\n\(titleLines)" | ||
| guard confirmClose( | ||
| title: "Close other tabs?", | ||
| message: message, | ||
| acceptCmdD: false | ||
| ) else { return } | ||
| } | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| for panelId in plan.panelIds { | ||
| _ = plan.workspace.closePanel(panelId, force: true) | ||
|
|
@@ -2861,7 +2863,7 @@ class TabManager: ObservableObject { | |
|
|
||
| @discardableResult | ||
| func closeWorkspaceWithConfirmation(_ workspace: Workspace) -> Bool { | ||
| if workspace.isPinned { | ||
| if workspace.isPinned && ClosePinnedWorkspaceSettings.isEnabled() { | ||
| guard confirmClose( | ||
| title: String(localized: "dialog.closePinnedWorkspace.title", defaultValue: "Close pinned workspace?"), | ||
| message: String( | ||
|
|
@@ -2899,15 +2901,25 @@ class TabManager: ObservableObject { | |
| } | ||
|
|
||
| let plan = closeWorkspacesPlan(for: workspaces) | ||
| guard confirmClose( | ||
| title: plan.title, | ||
| message: plan.message, | ||
| acceptCmdD: plan.acceptCmdD | ||
| ) else { return } | ||
| let batchConfirmed: Bool | ||
| if BatchCloseSettings.isEnabled() { | ||
| guard confirmClose( | ||
| title: plan.title, | ||
| message: plan.message, | ||
| acceptCmdD: plan.acceptCmdD | ||
| ) else { return } | ||
| batchConfirmed = true | ||
| } else { | ||
| batchConfirmed = false | ||
| } | ||
|
|
||
| for workspace in plan.workspaces { | ||
| guard tabs.contains(where: { $0.id == workspace.id }) else { continue } | ||
| closeWorkspaceIfRunningProcess(workspace, requiresConfirmation: false) | ||
| if batchConfirmed { | ||
| closeWorkspaceIfRunningProcess(workspace, requiresConfirmation: false) | ||
| } else { | ||
| _ = closeWorkspaceWithConfirmation(workspace) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Non-batch multi-close now bypasses running-process confirmation for pinned workspaces by routing through a helper that forces Prompt for AI agents
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3768,6 +3768,70 @@ enum QuitWarningSettings { | |
| } | ||
| } | ||
|
|
||
| enum CloseRunningProcessSettings { | ||
| static let enabledKey = "confirmCloseRunningProcess" | ||
| static let defaultEnabled = true | ||
|
|
||
| static func isEnabled(defaults: UserDefaults = .standard) -> Bool { | ||
| if defaults.object(forKey: enabledKey) == nil { | ||
| return defaultEnabled | ||
| } | ||
| return defaults.bool(forKey: enabledKey) | ||
| } | ||
|
|
||
| static func setEnabled(_ isEnabled: Bool, defaults: UserDefaults = .standard) { | ||
| defaults.set(isEnabled, forKey: enabledKey) | ||
| } | ||
| } | ||
|
|
||
| enum ClosePinnedWorkspaceSettings { | ||
| static let enabledKey = "confirmClosePinnedWorkspace" | ||
| static let defaultEnabled = true | ||
|
|
||
| static func isEnabled(defaults: UserDefaults = .standard) -> Bool { | ||
| if defaults.object(forKey: enabledKey) == nil { | ||
| return defaultEnabled | ||
| } | ||
| return defaults.bool(forKey: enabledKey) | ||
| } | ||
|
|
||
| static func setEnabled(_ isEnabled: Bool, defaults: UserDefaults = .standard) { | ||
| defaults.set(isEnabled, forKey: enabledKey) | ||
| } | ||
| } | ||
|
|
||
| enum CloseWindowSettings { | ||
| static let enabledKey = "confirmCloseWindow" | ||
| static let defaultEnabled = true | ||
|
|
||
| static func isEnabled(defaults: UserDefaults = .standard) -> Bool { | ||
| if defaults.object(forKey: enabledKey) == nil { | ||
| return defaultEnabled | ||
| } | ||
| return defaults.bool(forKey: enabledKey) | ||
| } | ||
|
|
||
| static func setEnabled(_ isEnabled: Bool, defaults: UserDefaults = .standard) { | ||
| defaults.set(isEnabled, forKey: enabledKey) | ||
| } | ||
| } | ||
|
|
||
| enum BatchCloseSettings { | ||
| static let enabledKey = "confirmBatchClose" | ||
| static let defaultEnabled = true | ||
|
|
||
| static func isEnabled(defaults: UserDefaults = .standard) -> Bool { | ||
| if defaults.object(forKey: enabledKey) == nil { | ||
| return defaultEnabled | ||
| } | ||
| return defaults.bool(forKey: enabledKey) | ||
| } | ||
|
|
||
| static func setEnabled(_ isEnabled: Bool, defaults: UserDefaults = .standard) { | ||
| defaults.set(isEnabled, forKey: enabledKey) | ||
| } | ||
| } | ||
|
|
||
| enum CommandPaletteRenameSelectionSettings { | ||
| static let selectAllOnFocusKey = "commandPalette.renameSelectAllOnFocus" | ||
| static let defaultSelectAllOnFocus = true | ||
|
|
@@ -3932,6 +3996,10 @@ struct SettingsView: View { | |
| @AppStorage(NotificationPaneFlashSettings.enabledKey) private var notificationPaneFlashEnabled = NotificationPaneFlashSettings.defaultEnabled | ||
| @AppStorage(MenuBarExtraSettings.showInMenuBarKey) private var showMenuBarExtra = MenuBarExtraSettings.defaultShowInMenuBar | ||
| @AppStorage(QuitWarningSettings.warnBeforeQuitKey) private var warnBeforeQuitShortcut = QuitWarningSettings.defaultWarnBeforeQuit | ||
| @AppStorage(CloseRunningProcessSettings.enabledKey) private var confirmCloseRunningProcess = CloseRunningProcessSettings.defaultEnabled | ||
| @AppStorage(ClosePinnedWorkspaceSettings.enabledKey) private var confirmClosePinnedWorkspace = ClosePinnedWorkspaceSettings.defaultEnabled | ||
| @AppStorage(CloseWindowSettings.enabledKey) private var confirmCloseWindow = CloseWindowSettings.defaultEnabled | ||
| @AppStorage(BatchCloseSettings.enabledKey) private var confirmBatchClose = BatchCloseSettings.defaultEnabled | ||
| @AppStorage(CommandPaletteRenameSelectionSettings.selectAllOnFocusKey) | ||
| private var commandPaletteRenameSelectAllOnFocus = CommandPaletteRenameSelectionSettings.defaultSelectAllOnFocus | ||
| @AppStorage(CommandPaletteSwitcherSearchSettings.searchAllSurfacesKey) | ||
|
|
@@ -4784,6 +4852,58 @@ struct SettingsView: View { | |
|
|
||
| SettingsCardDivider() | ||
|
|
||
| SettingsCardRow( | ||
| String(localized: "settings.app.confirmCloseRunningProcess", defaultValue: "Confirm Close Running Process"), | ||
| subtitle: confirmCloseRunningProcess | ||
| ? String(localized: "settings.app.confirmCloseRunningProcess.subtitleOn", defaultValue: "Show a confirmation before closing a workspace with a running command.") | ||
| : String(localized: "settings.app.confirmCloseRunningProcess.subtitleOff", defaultValue: "Close workspaces without confirmation, even with running commands.") | ||
| ) { | ||
| Toggle("", isOn: $confirmCloseRunningProcess) | ||
| .labelsHidden() | ||
| .controlSize(.small) | ||
| } | ||
|
|
||
| SettingsCardDivider() | ||
|
|
||
| SettingsCardRow( | ||
| String(localized: "settings.app.confirmClosePinnedWorkspace", defaultValue: "Confirm Close Pinned Workspace"), | ||
| subtitle: confirmClosePinnedWorkspace | ||
| ? String(localized: "settings.app.confirmClosePinnedWorkspace.subtitleOn", defaultValue: "Show a confirmation before closing a pinned workspace.") | ||
| : String(localized: "settings.app.confirmClosePinnedWorkspace.subtitleOff", defaultValue: "Close pinned workspaces without extra confirmation.") | ||
| ) { | ||
| Toggle("", isOn: $confirmClosePinnedWorkspace) | ||
| .labelsHidden() | ||
| .controlSize(.small) | ||
| } | ||
|
|
||
| SettingsCardDivider() | ||
|
|
||
| SettingsCardRow( | ||
| String(localized: "settings.app.confirmCloseWindow", defaultValue: "Confirm Close Window"), | ||
| subtitle: confirmCloseWindow | ||
| ? String(localized: "settings.app.confirmCloseWindow.subtitleOn", defaultValue: "Show a confirmation before closing a window with workspaces.") | ||
| : String(localized: "settings.app.confirmCloseWindow.subtitleOff", defaultValue: "Close windows without confirmation.") | ||
| ) { | ||
| Toggle("", isOn: $confirmCloseWindow) | ||
| .labelsHidden() | ||
| .controlSize(.small) | ||
| } | ||
|
|
||
| SettingsCardDivider() | ||
|
|
||
| SettingsCardRow( | ||
| String(localized: "settings.app.confirmBatchClose", defaultValue: "Confirm Batch Close"), | ||
| subtitle: confirmBatchClose | ||
| ? String(localized: "settings.app.confirmBatchClose.subtitleOn", defaultValue: "Show a confirmation before closing multiple tabs or workspaces at once.") | ||
| : String(localized: "settings.app.confirmBatchClose.subtitleOff", defaultValue: "Close multiple tabs or workspaces without confirmation.") | ||
| ) { | ||
| Toggle("", isOn: $confirmBatchClose) | ||
| .labelsHidden() | ||
|
Comment on lines
+4855
to
+4901
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
All 12 new
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| .controlSize(.small) | ||
| } | ||
|
|
||
| SettingsCardDivider() | ||
|
|
||
| SettingsCardRow( | ||
| String(localized: "settings.app.renameSelectsName", defaultValue: "Rename Selects Existing Name"), | ||
| subtitle: commandPaletteRenameSelectAllOnFocus | ||
|
|
@@ -5910,6 +6030,10 @@ struct SettingsView: View { | |
| notificationPaneFlashEnabled = NotificationPaneFlashSettings.defaultEnabled | ||
| showMenuBarExtra = MenuBarExtraSettings.defaultShowInMenuBar | ||
| warnBeforeQuitShortcut = QuitWarningSettings.defaultWarnBeforeQuit | ||
| confirmCloseRunningProcess = CloseRunningProcessSettings.defaultEnabled | ||
| confirmClosePinnedWorkspace = ClosePinnedWorkspaceSettings.defaultEnabled | ||
| confirmCloseWindow = CloseWindowSettings.defaultEnabled | ||
| confirmBatchClose = BatchCloseSettings.defaultEnabled | ||
| commandPaletteRenameSelectAllOnFocus = CommandPaletteRenameSelectionSettings.defaultSelectAllOnFocus | ||
| commandPaletteSearchAllSurfaces = CommandPaletteSwitcherSearchSettings.defaultSearchAllSurfaces | ||
| ShortcutHintDebugSettings.resetVisibilityDefaults() | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.