From a48a7f2413fc0f7b714aca0f5474730d873915a6 Mon Sep 17 00:00:00 2001 From: Stefano Bertagno Date: Sat, 9 May 2026 23:39:52 +0200 Subject: [PATCH] Make the Window-menu Supacode entry shortcut configurable (#289) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wires the entry to the new .showMainWindow AppShortcut (default ⌘0) so it honors user overrides, and deminiaturizes the window when needed. Drops the empty .windowList replacement; replacing only .singleWindowList preserves the macOS 26 Tahoe arrangement items while still injecting the ⌘0 entry. Rewrites appKeyboardShortcut to never branch on the optional — the ViewBuilder if/else flipped view identity when the shortcut hydrated from disk, which re-evaluated the Window-menu CommandGroup and stripped the Tahoe arrangement items mid-launch. Also drops the shortcut display from the menu-bar .help strings so the help text is stable during hydration. Also drops the Deeplink Reference entry (and its now-unused DeeplinkReferenceMenuButton view) from the Help menu. --- SupacodeSettingsShared/App/AppShortcuts.swift | 20 +++++++++++-------- supacode/App/DeeplinkReferenceView.swift | 11 ---------- supacode/App/supacodeApp.swift | 20 +++++++------------ 3 files changed, 19 insertions(+), 32 deletions(-) diff --git a/SupacodeSettingsShared/App/AppShortcuts.swift b/SupacodeSettingsShared/App/AppShortcuts.swift index 6a5adc3bf..238ba036f 100644 --- a/SupacodeSettingsShared/App/AppShortcuts.swift +++ b/SupacodeSettingsShared/App/AppShortcuts.swift @@ -5,7 +5,7 @@ import SwiftUI // Compile-time checkable shortcut identifier. public nonisolated enum AppShortcutID: Codable, Hashable, Sendable, CodingKeyRepresentable { - case commandPalette, openSettings, checkForUpdates + case commandPalette, openSettings, checkForUpdates, showMainWindow case toggleLeftSidebar, revealInSidebar case newWorktree, refreshWorktrees, archivedWorktrees, archiveWorktree case deleteWorktree, confirmWorktreeAction @@ -38,6 +38,7 @@ public nonisolated enum AppShortcutID: Codable, Hashable, Sendable, CodingKeyRep case .commandPalette: "commandPalette" case .openSettings: "openSettings" case .checkForUpdates: "checkForUpdates" + case .showMainWindow: "showMainWindow" case .toggleLeftSidebar: "toggleLeftSidebar" case .revealInSidebar: "revealInSidebar" case .newWorktree: "newWorktree" @@ -66,6 +67,7 @@ public nonisolated enum AppShortcutID: Codable, Hashable, Sendable, CodingKeyRep "commandPalette": .commandPalette, "openSettings": .openSettings, "checkForUpdates": .checkForUpdates, + "showMainWindow": .showMainWindow, "toggleLeftSidebar": .toggleLeftSidebar, "revealInSidebar": .revealInSidebar, "newWorktree": .newWorktree, @@ -106,6 +108,7 @@ public nonisolated enum AppShortcutID: Codable, Hashable, Sendable, CodingKeyRep case .commandPalette: "Command Palette" case .openSettings: "Open Settings" case .checkForUpdates: "Check For Updates" + case .showMainWindow: "Show Main Window" case .toggleLeftSidebar: "Toggle Left Sidebar" case .revealInSidebar: "Reveal in Sidebar" case .newWorktree: "New Worktree" @@ -286,6 +289,7 @@ public enum AppShortcuts { public static let commandPalette = AppShortcut(id: .commandPalette, key: "p", modifiers: .command) public static let openSettings = AppShortcut(id: .openSettings, key: ",", modifiers: .command) public static let checkForUpdates = AppShortcut(id: .checkForUpdates, key: "u", modifiers: .command) + public static let showMainWindow = AppShortcut(id: .showMainWindow, key: "0", modifiers: .command) public static let toggleLeftSidebar = AppShortcut(id: .toggleLeftSidebar, key: "[", modifiers: .command) public static let revealInSidebar = AppShortcut(id: .revealInSidebar, key: "e", modifiers: [.command, .shift]) @@ -352,7 +356,10 @@ public enum AppShortcuts { // MARK: - Groups. public static let groups: [AppShortcutGroup] = [ - AppShortcutGroup(category: .general, shortcuts: [commandPalette, openSettings, checkForUpdates]), + AppShortcutGroup( + category: .general, + shortcuts: [commandPalette, openSettings, checkForUpdates, showMainWindow] + ), AppShortcutGroup(category: .sidebar, shortcuts: [toggleLeftSidebar, revealInSidebar]), AppShortcutGroup( category: .worktrees, @@ -434,12 +441,9 @@ public enum AppShortcuts { // MARK: - View modifier. extension View { - @ViewBuilder + // Always returns the same view type so menu-bar CommandGroups don't lose identity + // when the shortcut hydrates from disk; that flip strips Tahoe arrangement items. public func appKeyboardShortcut(_ shortcut: AppShortcut?) -> some View { - if let shortcut { - self.keyboardShortcut(shortcut.keyEquivalent, modifiers: shortcut.modifiers) - } else { - self - } + keyboardShortcut(shortcut.map { KeyboardShortcut($0.keyEquivalent, modifiers: $0.modifiers) }) } } diff --git a/supacode/App/DeeplinkReferenceView.swift b/supacode/App/DeeplinkReferenceView.swift index f3b24ce69..5eb21b702 100644 --- a/supacode/App/DeeplinkReferenceView.swift +++ b/supacode/App/DeeplinkReferenceView.swift @@ -150,17 +150,6 @@ private struct DeeplinkSection: View { } } -struct DeeplinkReferenceMenuButton: View { - @Environment(\.openWindow) private var openWindow - - var body: some View { - Button("Deeplink Reference") { - openWindow(id: WindowID.deeplinkReference) - } - .help("Open the deeplink reference.") - } -} - // MARK: - Deeplink → window bridge. /// Opens the deeplink reference window when the reducer sets `isDeeplinkReferenceRequested`. diff --git a/supacode/App/supacodeApp.swift b/supacode/App/supacodeApp.swift index c7a4c9729..a4391448f 100644 --- a/supacode/App/supacodeApp.swift +++ b/supacode/App/supacodeApp.swift @@ -388,23 +388,19 @@ struct SupacodeApp: App { TerminalCommands(ghosttyShortcuts: ghosttyShortcuts) WindowCommands(ghosttyShortcuts: ghosttyShortcuts) CommandGroup(after: .textEditing) { - let cmdPalette = AppShortcuts.commandPalette.effective(from: store.settings.shortcutOverrides) Button("Command Palette") { store.send(.commandPalette(.togglePresented)) } - .appKeyboardShortcut(cmdPalette) - .help("Command Palette (\(cmdPalette?.display ?? "none"))") + .appKeyboardShortcut(AppShortcuts.commandPalette.effective(from: store.settings.shortcutOverrides)) + .help("Command Palette") } UpdateCommands(store: store.scope(state: \.updates, action: \.updates)) - Group { - CommandGroup(replacing: .windowList) {} - CommandGroup(replacing: .singleWindowList) { - Button("Supacode") { - NSApplication.shared.surfaceMainWindow() - } - .keyboardShortcut("0") - .help("Show main window (⌘0)") + CommandGroup(replacing: .singleWindowList) { + Button("Supacode") { + NSApplication.shared.surfaceMainWindow() } + .appKeyboardShortcut(AppShortcuts.showMainWindow.effective(from: store.settings.shortcutOverrides)) + .help("Show Main Window") } CommandGroup(replacing: .appSettings) { SettingsMenuButton(shortcutOverrides: store.settings.shortcutOverrides) { @@ -412,8 +408,6 @@ struct SupacodeApp: App { } } CommandGroup(replacing: .help) { - DeeplinkReferenceMenuButton() - Divider() Button("Submit GitHub Issue") { guard let url = URL(string: "https://github.com/supabitapp/supacode/issues/new") else { return } NSWorkspace.shared.open(url)