Repository navigation
Extract About Titlebar Debug subsystem from cmuxApp.swift into CmuxDebugWindowsUI - #6175
azooz2003-bit wants to merge 1 commit into
Conversation
…bugWindowsUI Pull the self-contained About-titlebar debug cluster out of the cmuxApp.swift god file into a new domain UI package, CmuxDebugWindowsUI, as a Coordinator plus value types, store, window controller, and SwiftUI view. What moved (cmuxApp.swift -> Packages/CmuxDebugWindowsUI): - AboutWindowKind, TitlebarVisibilityOption, TitlebarToolbarStyleOption value enums - AboutTitlebarDebugOptions value type - AboutTitlebarDebugStore (was a singleton ObservableObject -> @mainactor @observable) - AboutTitlebarDebugWindowController (NSWindowController) - AboutTitlebarDebugView (SwiftUI) New: DebugWindowsCoordinator (@mainactor @observable) owns the store + lazily owns the window controller; WindowDecorating protocol seam. Seams (constructor-injected, god-type reaches inverted): - AppDelegate.shared?.applyWindowDecorations(to:) -> WindowDecorating protocol. AppDelegate conforms directly (it already has the matching method) and is injected into DebugWindowsCoordinator at the composition root, held WEAKLY by the coordinator/store to avoid a retain cycle (AppDelegate is the singleton owner of the coordinator). - The singleton .shared store/controller are replaced by app-owned instances on AppDelegate (debugWindowsCoordinator / aboutTitlebarDebugStore). Byte-identical behavior: - Window identifiers, titles, style-mask bits, toolbar identifiers, min/max sizes, copy-config payload text, and the didSet-driven reapply are preserved exactly. Call sites (Debug menu, openAllDebugWindows, DebugWindowControlsView, About/Acknowledgments window controllers) are thin forwards to the app-owned coordinator/store, so the runtime sequence is unchanged. - applyToOpenWindows now guards a nil NSApp (no-op only in a headless test process; NSApp is always present in the running app), enabling unit tests. Tests: 7 Testing-framework behavior tests with a fake WindowDecorating (defaults, enabled/disabled overrides, empty-title fallback, toolbar toggle, reset, copy-config payload). Est lines removed from giant: 405 (cmuxApp.swift 4920 -> 4515). Budget reconciled (cmuxApp ratcheted down; AppDelegate +11 for composition-root wiring). Left behind (intentional, not a clean leaf): the #if DEBUG controllers still in cmuxApp.swift (SidebarDebug, MenuBarExtraDebug, BackgroundDebug, StartupAppearance, SplitButtonLayout, TabBarBackdropLab, BrowserProfilePopover/ImportHint, FileExplorerStyle, DebugWindowControls, DebugWindowConfigSnapshot) reach into many app-target settings/catalog/Option types and Workspace/GhosttyApp statics across multiple files, so extracting them requires multi-file seam inversion beyond this PR. The AboutTitlebar cluster is the one fully self-contained, non-DEBUG leaf. NOTE: app build validated by CI (not run locally per refactor policy). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughA new local Swift package ChangesCmuxDebugWindowsUI Package Extraction
Sequence Diagram(s)sequenceDiagram
participant DebugMenu as Debug Menu / DebugWindowControlsView
participant AppDelegate
participant DebugWindowsCoordinator
participant AboutTitlebarDebugWindowController
participant AboutTitlebarDebugStore
participant NSWindow as About NSWindow
DebugMenu->>AppDelegate: shared?.debugWindowsCoordinator.showAboutTitlebarDebugWindow()
AppDelegate->>DebugWindowsCoordinator: showAboutTitlebarDebugWindow()
alt first call
DebugWindowsCoordinator->>AboutTitlebarDebugWindowController: init(store:, decorator: AppDelegate)
AboutTitlebarDebugWindowController->>AppDelegate: applyWindowDecorations(to: panel)
end
DebugWindowsCoordinator->>AboutTitlebarDebugWindowController: show()
AboutTitlebarDebugWindowController->>AboutTitlebarDebugStore: applyToOpenWindows()
AboutTitlebarDebugStore->>NSWindow: apply options (title, styleMask, toolbar, sizing, shadow)
Note over AppDelegate,NSWindow: AboutWindowController.show() path
AppDelegate->>AboutTitlebarDebugStore: applyCurrentOptions(to: window, for: .about)
AboutTitlebarDebugStore->>NSWindow: apply options on newly shown About window
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (2 errors, 1 warning)
✅ Passed checks (18 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryExtracts the About Titlebar Debug cluster from
Confidence Score: 4/5Clean extraction with no functional regressions for the normal running app; a few small rough edges in the view-observation pattern and localization wiring are worth a follow-up but do not block the refactor. The refactor is well-structured: singleton reach is fully inverted, the store is correctly migrated to @observable with working didSet behaviour, and the test suite validates the core store contracts. Three issues are worth attention: AboutWindowController now silently skips applyCurrentOptions if AppDelegate.shared is ever nil, contradicting the byte-identical-behaviour claim; AboutTitlebarDebugView holds the store as private let without @bindable, so SwiftUI observation of most store properties is delegated entirely to child-view render passes rather than anchored at this view boundary; and the two String(localized:) calls inside the package have an implicit main-bundle dependency with no package-local catalog. None of these cause visible bugs in the running app today. Sources/cmuxApp.swift (AboutWindowController call sites), Packages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Views/AboutTitlebarDebugView.swift, Packages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Windows/AboutTitlebarDebugWindowController.swift Important Files Changed
Sequence DiagramsequenceDiagram
participant AM as AppDelegate (composition root)
participant DC as DebugWindowsCoordinator
participant ST as AboutTitlebarDebugStore
participant WC as AboutTitlebarDebugWindowController
participant AW as AboutWindowController
participant WD as WindowDecorating (AppDelegate)
AM->>DC: init(decorator: self)
DC->>ST: init(decorator: decorator)
Note over AM,WD: Debug menu / Open All action
AM->>DC: showAboutTitlebarDebugWindow()
DC->>WC: init(store:, decorator:) [lazy, first call only]
WC->>WD: applyWindowDecorations(to: panel)
DC->>WC: show()
WC->>ST: applyToOpenWindows()
ST->>WD: decorator?.applyWindowDecorations(to: window)
Note over AM,WD: About window opens
AW->>ST: applyCurrentOptions(to: window, for: .about)
ST->>WD: decorator?.applyWindowDecorations(to: window)
Note over AM,WD: User edits options in debug panel
AM->>ST: "aboutOptions = newValue (via Binding)"
ST-->>ST: didSet → applyToOpenWindows(for: .about)
ST->>WD: decorator?.applyWindowDecorations(to: window)
|
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Sources/cmuxApp.swift (1)
2247-2260:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winApply the titlebar-debug store to the Licenses window too.
Only the About controller now applies the app-owned store. If a user changes the Acknowledgments/Licenses titlebar options before opening that window,
AcknowledgmentsWindowControlleris created and shown without applying the moved debug state, so this no longer preserves the previous About/Acknowledgments behavior.Proposed fix
window.identifier = NSUserInterfaceItemIdentifier("cmux.licenses") window.center() window.contentView = NSHostingView(rootView: AcknowledgmentsView()) + AppDelegate.shared?.aboutTitlebarDebugStore.applyCurrentOptions(to: window, for: .acknowledgments) super.init(window: window) window.delegate = self @@ func show() { guard let window else { return } + AppDelegate.shared?.aboutTitlebarDebugStore.applyCurrentOptions(to: window, for: .acknowledgments) window.makeKeyAndOrderFront(nil) }This is based on the stated PR objective that the About/Acknowledgments window controllers should forward to the app-owned store.
Also applies to: 2280-2292
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/cmuxApp.swift` around lines 2247 - 2260, The titlebar-debug store is only applied to the About window controller but not to the AcknowledgmentsWindowController. In the AcknowledgmentsWindowController's initialization and show methods (which correspond to the code at lines 2280-2292), apply the titlebar debug store using the same pattern as the About controller: call AppDelegate.shared?.aboutTitlebarDebugStore.applyCurrentOptions(to: window, for: .about) after creating the window and in the show method to ensure that any titlebar options changed by the user are preserved when the Acknowledgments/Licenses window is opened.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@Packages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Values/AboutTitlebarDebugOptions.swift`:
- Around line 69-87: The windowTitle field in the defaults(for kind:) method
contains a bare English string "About cmux" that should be localized. Replace
the plain string literal with String(localized:defaultValue:) wrapper, using
"About cmux" as both the localization key and the default value, and ensure a
corresponding entry is added to Resources/Localizable.xcstrings to support
internationalization.
In
`@Packages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Values/AboutWindowKind.swift`:
- Around line 36-41: The fallbackTitle property in the AboutWindowKind enum
returns a bare English string "About cmux" without localization. Replace this
string with a localized version using String(localized:defaultValue:) where the
defaultValue parameter contains the current English text, and ensure a matching
entry exists in Resources/Localizable.xcstrings for the key to be used in the
localized call.
- Around line 19-24: The displayTitle property in the about case returns a
hard-coded English string that should be localized. Wrap the string "About
Window" with String(localized:defaultValue:) to enable localization, then add
corresponding translation entries in Resources/Localizable.xcstrings for all
supported locales. This ensures the debug UI string respects the app's
localization settings rather than displaying only in English.
In
`@Packages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Values/TitlebarToolbarStyleOption.swift`:
- Around line 23-36: The displayTitle property in TitlebarToolbarStyleOption
returns bare English strings that are user-facing. Wrap each string return value
("Automatic", "Expanded", "Preference", "Unified", "Unified Compact") with
String(localized:defaultValue:) where the defaultValue parameter contains the
current English text. Then add corresponding localization entries for each key
in Resources/Localizable.xcstrings to enable multi-language support.
In
`@Packages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Values/TitlebarVisibilityOption.swift`:
- Around line 17-24: The displayTitle property in TitlebarVisibilityOption
returns hardcoded English strings that are visible to users in the SwiftUI
Picker and must be localized according to coding guidelines. Replace each
hardcoded string return value ("Hidden" and "Visible") with
String(localized:defaultValue:) calls, providing the English string as the
defaultValue parameter. Additionally, add corresponding entries for these
localization keys in the Resources/Localizable.xcstrings file to ensure
translations can be provided for different languages.
In
`@Packages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Views/AboutTitlebarDebugView.swift`:
- Around line 27-107: The editor(for kind: AboutWindowKind) function and the
Actions GroupBox contain multiple hardcoded English user-facing strings that are
not localized, including "Actions", "Reset All", "Reapply to Open Windows",
"Copy Config", "Enable Debug Overrides", "When disabled, cmux uses normal
default titlebar behavior for this window.", "Window Title", "Title Visibility",
"Toolbar Style", "Show Toolbar", "Transparent Titlebar", "Movable by Window
Background", "Style Mask", "Titled", "Closable", "Miniaturizable", "Resizable",
"Full Size Content View", and "Apply Now". Replace each hardcoded string with
String(localized:) or use the Text(_:) initializer with corresponding
localization keys (for example, "debug.actions", "debug.resetAll", etc.), then
add all these localization keys with their English and translated values to
Resources/Localizable.xcstrings for all supported locales.
---
Outside diff comments:
In `@Sources/cmuxApp.swift`:
- Around line 2247-2260: The titlebar-debug store is only applied to the About
window controller but not to the AcknowledgmentsWindowController. In the
AcknowledgmentsWindowController's initialization and show methods (which
correspond to the code at lines 2280-2292), apply the titlebar debug store using
the same pattern as the About controller: call
AppDelegate.shared?.aboutTitlebarDebugStore.applyCurrentOptions(to: window, for:
.about) after creating the window and in the show method to ensure that any
titlebar options changed by the user are preserved when the
Acknowledgments/Licenses window is opened.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: fc4dc262-fee1-4047-a9d3-52b3c17149a3
⛔ Files ignored due to path filters (1)
.github/swift-file-length-budget.tsvis excluded by!**/*.tsv
📒 Files selected for processing (14)
Packages/CmuxDebugWindowsUI/Package.swiftPackages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Coordinator/DebugWindowsCoordinator.swiftPackages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Seams/WindowDecorating.swiftPackages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Stores/AboutTitlebarDebugStore.swiftPackages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Values/AboutTitlebarDebugOptions.swiftPackages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Values/AboutWindowKind.swiftPackages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Values/TitlebarToolbarStyleOption.swiftPackages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Values/TitlebarVisibilityOption.swiftPackages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Views/AboutTitlebarDebugView.swiftPackages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Windows/AboutTitlebarDebugWindowController.swiftPackages/CmuxDebugWindowsUI/Tests/CmuxDebugWindowsUITests/AboutTitlebarDebugStoreTests.swiftSources/AppDelegate.swiftSources/cmuxApp.swiftcmux.xcodeproj/project.pbxproj
| public static func defaults(for kind: AboutWindowKind) -> AboutTitlebarDebugOptions { | ||
| switch kind { | ||
| case .about: | ||
| return AboutTitlebarDebugOptions( | ||
| overridesEnabled: false, | ||
| windowTitle: "About cmux", | ||
| titleVisibility: .hidden, | ||
| titlebarAppearsTransparent: true, | ||
| movableByWindowBackground: false, | ||
| titled: true, | ||
| closable: true, | ||
| miniaturizable: true, | ||
| resizable: false, | ||
| fullSizeContentView: false, | ||
| showToolbar: false, | ||
| toolbarStyle: .automatic | ||
| ) | ||
| } | ||
| } |
There was a problem hiding this comment.
Localize default window title in defaults factory.
Line 74 contains a bare English string "About cmux" for the windowTitle field. This value is displayed in the debug editor's text field when users open the About Titlebar Debug window. Per coding guidelines, all user-facing strings must use String(localized:defaultValue:) with matching entries in Resources/Localizable.xcstrings.
[full_internationalization]
🌐 Suggested localization fix
case .about:
return AboutTitlebarDebugOptions(
overridesEnabled: false,
- windowTitle: "About cmux",
+ windowTitle: String(
+ localized: "debug.aboutTitlebar.defaults.windowTitle",
+ defaultValue: "About cmux"
+ ),
titleVisibility: .hidden,🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@Packages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Values/AboutTitlebarDebugOptions.swift`
around lines 69 - 87, The windowTitle field in the defaults(for kind:) method
contains a bare English string "About cmux" that should be localized. Replace
the plain string literal with String(localized:defaultValue:) wrapper, using
"About cmux" as both the localization key and the default value, and ensure a
corresponding entry is added to Resources/Localizable.xcstrings to support
internationalization.
Source: Coding guidelines
| public var displayTitle: String { | ||
| switch self { | ||
| case .about: | ||
| return "About Window" | ||
| } | ||
| } |
There was a problem hiding this comment.
Localize user-facing debug UI strings.
The displayTitle property returns a bare English string "About Window" that is shown in the debug editor UI. Per coding guidelines, all user-facing strings must use String(localized:defaultValue:) with matching entries in Resources/Localizable.xcstrings for all supported locales.
[full_internationalization]
🌐 Suggested localization fix
public var displayTitle: String {
switch self {
case .about:
- return "About Window"
+ return String(
+ localized: "debug.aboutTitlebar.kind.about.displayTitle",
+ defaultValue: "About Window"
+ )
}
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@Packages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Values/AboutWindowKind.swift`
around lines 19 - 24, The displayTitle property in the about case returns a
hard-coded English string that should be localized. Wrap the string "About
Window" with String(localized:defaultValue:) to enable localization, then add
corresponding translation entries in Resources/Localizable.xcstrings for all
supported locales. This ensures the debug UI string respects the app's
localization settings rather than displaying only in English.
Source: Coding guidelines
| public var fallbackTitle: String { | ||
| switch self { | ||
| case .about: | ||
| return "About cmux" | ||
| } | ||
| } |
There was a problem hiding this comment.
Localize fallback window title.
The fallbackTitle property returns a bare English string "About cmux" that is applied to NSWindow.title when the debug-overridden title is empty. Per coding guidelines, all user-facing strings must use String(localized:defaultValue:) with matching entries in Resources/Localizable.xcstrings.
[full_internationalization]
🌐 Suggested localization fix
public var fallbackTitle: String {
switch self {
case .about:
- return "About cmux"
+ return String(
+ localized: "debug.aboutTitlebar.kind.about.fallbackTitle",
+ defaultValue: "About cmux"
+ )
}
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@Packages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Values/AboutWindowKind.swift`
around lines 36 - 41, The fallbackTitle property in the AboutWindowKind enum
returns a bare English string "About cmux" without localization. Replace this
string with a localized version using String(localized:defaultValue:) where the
defaultValue parameter contains the current English text, and ensure a matching
entry exists in Resources/Localizable.xcstrings for the key to be used in the
localized call.
Source: Coding guidelines
| public var displayTitle: String { | ||
| switch self { | ||
| case .automatic: | ||
| return "Automatic" | ||
| case .expanded: | ||
| return "Expanded" | ||
| case .preference: | ||
| return "Preference" | ||
| case .unified: | ||
| return "Unified" | ||
| case .unifiedCompact: | ||
| return "Unified Compact" | ||
| } | ||
| } |
There was a problem hiding this comment.
Localize toolbar style picker labels.
The displayTitle property returns bare English strings ("Automatic", "Expanded", "Preference", "Unified", "Unified Compact") that are explicitly documented as "Human-readable label shown in the picker." These labels appear in the debug editor's SwiftUI Picker and are visible to users. Per coding guidelines, all user-facing strings must use String(localized:defaultValue:) with matching entries in Resources/Localizable.xcstrings.
[full_internationalization]
🌐 Suggested localization fix
public var displayTitle: String {
switch self {
case .automatic:
- return "Automatic"
+ return String(
+ localized: "debug.aboutTitlebar.toolbarStyle.automatic",
+ defaultValue: "Automatic"
+ )
case .expanded:
- return "Expanded"
+ return String(
+ localized: "debug.aboutTitlebar.toolbarStyle.expanded",
+ defaultValue: "Expanded"
+ )
case .preference:
- return "Preference"
+ return String(
+ localized: "debug.aboutTitlebar.toolbarStyle.preference",
+ defaultValue: "Preference"
+ )
case .unified:
- return "Unified"
+ return String(
+ localized: "debug.aboutTitlebar.toolbarStyle.unified",
+ defaultValue: "Unified"
+ )
case .unifiedCompact:
- return "Unified Compact"
+ return String(
+ localized: "debug.aboutTitlebar.toolbarStyle.unifiedCompact",
+ defaultValue: "Unified Compact"
+ )
}
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@Packages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Values/TitlebarToolbarStyleOption.swift`
around lines 23 - 36, The displayTitle property in TitlebarToolbarStyleOption
returns bare English strings that are user-facing. Wrap each string return value
("Automatic", "Expanded", "Preference", "Unified", "Unified Compact") with
String(localized:defaultValue:) where the defaultValue parameter contains the
current English text. Then add corresponding localization entries for each key
in Resources/Localizable.xcstrings to enable multi-language support.
Source: Coding guidelines
| public var displayTitle: String { | ||
| switch self { | ||
| case .hidden: | ||
| return "Hidden" | ||
| case .visible: | ||
| return "Visible" | ||
| } | ||
| } |
There was a problem hiding this comment.
Localize picker labels.
The displayTitle property returns bare English strings ("Hidden", "Visible") that are explicitly documented as "Human-readable label shown in the picker." These labels appear in the debug editor's SwiftUI Picker and are visible to users. Per coding guidelines, all user-facing strings must use String(localized:defaultValue:) with matching entries in Resources/Localizable.xcstrings.
[full_internationalization]
🌐 Suggested localization fix
public var displayTitle: String {
switch self {
case .hidden:
- return "Hidden"
+ return String(
+ localized: "debug.aboutTitlebar.titleVisibility.hidden",
+ defaultValue: "Hidden"
+ )
case .visible:
- return "Visible"
+ return String(
+ localized: "debug.aboutTitlebar.titleVisibility.visible",
+ defaultValue: "Visible"
+ )
}
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@Packages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Values/TitlebarVisibilityOption.swift`
around lines 17 - 24, The displayTitle property in TitlebarVisibilityOption
returns hardcoded English strings that are visible to users in the SwiftUI
Picker and must be localized according to coding guidelines. Replace each
hardcoded string return value ("Hidden" and "Visible") with
String(localized:defaultValue:) calls, providing the English string as the
defaultValue parameter. Additionally, add corresponding entries for these
localization keys in the Resources/Localizable.xcstrings file to ensure
translations can be provided for different languages.
Source: Coding guidelines
| GroupBox("Actions") { | ||
| HStack(spacing: 10) { | ||
| Button("Reset All") { | ||
| store.reset(.about) | ||
| } | ||
| Button("Reapply to Open Windows") { | ||
| store.applyToOpenWindows() | ||
| } | ||
| Button("Copy Config") { | ||
| store.copyConfigToPasteboard() | ||
| } | ||
| } | ||
| .frame(maxWidth: .infinity, alignment: .leading) | ||
| .padding(.top, 2) | ||
| } | ||
|
|
||
| Spacer(minLength: 0) | ||
| } | ||
| .padding(16) | ||
| .frame(maxWidth: .infinity, alignment: .topLeading) | ||
| } | ||
| .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) | ||
| } | ||
|
|
||
| private func editor(for kind: AboutWindowKind) -> some View { | ||
| let overridesEnabled = binding(for: kind, keyPath: \.overridesEnabled) | ||
|
|
||
| return GroupBox(kind.displayTitle) { | ||
| VStack(alignment: .leading, spacing: 10) { | ||
| Toggle("Enable Debug Overrides", isOn: overridesEnabled) | ||
|
|
||
| Text("When disabled, cmux uses normal default titlebar behavior for this window.") | ||
| .font(.caption) | ||
| .foregroundColor(.secondary) | ||
|
|
||
| Divider() | ||
|
|
||
| VStack(alignment: .leading, spacing: 10) { | ||
| HStack(spacing: 8) { | ||
| Text("Window Title") | ||
| TextField("", text: binding(for: kind, keyPath: \.windowTitle)) | ||
| } | ||
|
|
||
| HStack(spacing: 10) { | ||
| Picker("Title Visibility", selection: binding(for: kind, keyPath: \.titleVisibility)) { | ||
| ForEach(TitlebarVisibilityOption.allCases) { option in | ||
| Text(option.displayTitle).tag(option) | ||
| } | ||
| } | ||
| Picker("Toolbar Style", selection: binding(for: kind, keyPath: \.toolbarStyle)) { | ||
| ForEach(TitlebarToolbarStyleOption.allCases) { option in | ||
| Text(option.displayTitle).tag(option) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Toggle("Show Toolbar", isOn: binding(for: kind, keyPath: \.showToolbar)) | ||
| Toggle("Transparent Titlebar", isOn: binding(for: kind, keyPath: \.titlebarAppearsTransparent)) | ||
| Toggle("Movable by Window Background", isOn: binding(for: kind, keyPath: \.movableByWindowBackground)) | ||
|
|
||
| Divider() | ||
|
|
||
| Text("Style Mask") | ||
| .font(.caption) | ||
| .foregroundColor(.secondary) | ||
|
|
||
| Toggle("Titled", isOn: binding(for: kind, keyPath: \.titled)) | ||
| Toggle("Closable", isOn: binding(for: kind, keyPath: \.closable)) | ||
| Toggle("Miniaturizable", isOn: binding(for: kind, keyPath: \.miniaturizable)) | ||
| Toggle("Resizable", isOn: binding(for: kind, keyPath: \.resizable)) | ||
| Toggle("Full Size Content View", isOn: binding(for: kind, keyPath: \.fullSizeContentView)) | ||
|
|
||
| HStack(spacing: 10) { | ||
| Button(String(localized: "debug.aboutTitlebarDebug.resetAbout", defaultValue: "Reset About")) { | ||
| store.reset(kind) | ||
| } | ||
| Button("Apply Now") { | ||
| store.applyToOpenWindows(for: kind) | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Localize all newly added UI labels in this editor.
This segment introduces many bare English user-facing strings, so non-English locales will get mixed-language UI. Route these labels/help text through localization keys and add matching translations in Resources/Localizable.xcstrings for all supported locales.
🌐 Example direction
- GroupBox("Actions") {
+ GroupBox(String(localized: "debug.aboutTitlebarDebug.actions", defaultValue: "Actions")) {
- Button("Reset All") {
+ Button(String(localized: "debug.aboutTitlebarDebug.resetAll", defaultValue: "Reset All")) {
- Text("When disabled, cmux uses normal default titlebar behavior for this window.")
+ Text(String(
+ localized: "debug.aboutTitlebarDebug.overridesDisabledHint",
+ defaultValue: "When disabled, cmux uses normal default titlebar behavior for this window."
+ ))As per coding guidelines, “All user-facing strings must be localized” and Swift production text must have matching Resources/Localizable.xcstrings translations for every supported locale.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@Packages/CmuxDebugWindowsUI/Sources/CmuxDebugWindowsUI/Views/AboutTitlebarDebugView.swift`
around lines 27 - 107, The editor(for kind: AboutWindowKind) function and the
Actions GroupBox contain multiple hardcoded English user-facing strings that are
not localized, including "Actions", "Reset All", "Reapply to Open Windows",
"Copy Config", "Enable Debug Overrides", "When disabled, cmux uses normal
default titlebar behavior for this window.", "Window Title", "Title Visibility",
"Toolbar Style", "Show Toolbar", "Transparent Titlebar", "Movable by Window
Background", "Style Mask", "Titled", "Closable", "Miniaturizable", "Resizable",
"Full Size Content View", and "Apply Now". Replace each hardcoded string with
String(localized:) or use the Text(_:) initializer with corresponding
localization keys (for example, "debug.actions", "debug.resetAll", etc.), then
add all these localization keys with their English and translated values to
Resources/Localizable.xcstrings for all supported locales.
Source: Coding guidelines
| @@ -2662,7 +2257,7 @@ private final class AboutWindowController: NSWindowController, NSWindowDelegate | |||
|
|
|||
There was a problem hiding this comment.
Behavior change under nil
AppDelegate.shared
The old code called AboutTitlebarDebugStore.shared.applyCurrentOptions(to: window, for: .about) unconditionally — applying debug options (and falling back to defaults when overrides were disabled) before applyWindowDecorations. The replacement AppDelegate.shared?.aboutTitlebarDebugStore.applyCurrentOptions(to: window, for: .about) silently skips applyCurrentOptions entirely when AppDelegate.shared is nil. That means neither the debug options nor the default titlebar treatment is applied on that call. In a normally-launched app this never fires, but it contradicts the PR's "byte-identical behaviour" claim and leaves a silent no-op gap if AppDelegate.shared is ever nil at window-open time (e.g. during teardown or in a future refactor that changes initialization order).
|
Superseded by #6224 — consolidated into the existing CmuxFeedback/CmuxAppKitSupportUI package (no new micro-package) per over-engineering review. The extraction is preserved there. |
Pulls the self-contained About-titlebar debug cluster out of the
cmuxApp.swiftgod file into a new domain UI package,CmuxDebugWindowsUI, as a Coordinator plus value types, an@Observablestore, anNSWindowController, and a SwiftUI view.What moved (
Sources/cmuxApp.swift->Packages/CmuxDebugWindowsUI)AboutWindowKind,TitlebarVisibilityOption,TitlebarToolbarStyleOptionvalue enumsAboutTitlebarDebugOptionsvalue typeAboutTitlebarDebugStore(was a singletonObservableObject->@MainActor @Observable, single writer of the options)AboutTitlebarDebugWindowController(NSWindowController)AboutTitlebarDebugView(SwiftUI editor)New:
DebugWindowsCoordinator(@MainActor @Observable) owns the store and lazily owns the window controller;WindowDecoratingprotocol seam. One major public type per file, DocC///on every public symbol,swiftLanguageMode(.v6)+ExistentialAny/InternalImportsByDefault.Seams (constructor-injected; every god-type reach inverted)
AppDelegate.shared?.applyWindowDecorations(to:)->WindowDecoratingprotocol.AppDelegateconforms directly (it already exposes the matching method) and is injected intoDebugWindowsCoordinatorat the composition root. The coordinator and store hold the decorator weakly to avoid a retain cycle, sinceAppDelegateis the singleton that owns the coordinator..sharedsingleton store/controller are gone; the app owns one coordinator onAppDelegate(debugWindowsCoordinator/aboutTitlebarDebugStore). The concrete conformer stays in the app target.Byte-identical behavior
didSet-driven reapply are preserved exactly. Every call site (Debug menu,openAllDebugWindows,DebugWindowControlsView, theAbout/Acknowledgmentswindow controllers) is a thin forward to the app-owned coordinator/store, so the runtime sequence is unchanged.applyToOpenWindowsnow guards a nilNSApp(no-op only in a headless unit-test process;NSAppis always present in the running app), which is what lets the store be unit-tested.Tests
7 Swift-Testing behavior tests with a fake
WindowDecorating: defaults are non-overriding, disabled overrides fall back to kind defaults, enabled overrides apply title/style-mask/visibility, empty title falls back, toolbar toggles, reset restores defaults, copy-config payload contains current values.swift build+swift testgreen in the package.Stats
cmuxApp.swift4920 -> 4515).AppDelegate.swift+11 for composition-root wiring;.github/swift-file-length-budget.tsvreconciled (cmuxApp ratcheted down, AppDelegate bumped).scripts/lint-ios-package-conventions.sh-> OK, zero newlint:allow.Left behind (intentional, not a clean leaf)
The
#if DEBUGcontrollers still incmuxApp.swift(SidebarDebug, MenuBarExtraDebug, BackgroundDebug, StartupAppearance, SplitButtonLayout, TabBarBackdropLab, BrowserProfilePopover/ImportHint, FileExplorerStyle, DebugWindowControls,DebugWindowConfigSnapshot) reach into many app-target settings/catalog/*Optiontypes andWorkspace/GhosttyAppstatics across multiple files, so extracting them needs multi-file seam inversion beyond this PR. The About-titlebar cluster is the one fully self-contained, non-DEBUG leaf.NOTE: the full app build is validated by CI; per refactor policy it was not run locally.
🤖 Generated with Claude Code
Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.Summary by cubic
Extracted the About titlebar debug subsystem from
Sources/cmuxApp.swiftinto a new package,CmuxDebugWindowsUI, to decouple it from the app and make it testable. Behavior is unchanged; existing debug menu actions and About/Acknowledgments windows work as before.CmuxDebugWindowsUIwithDebugWindowsCoordinator,AboutTitlebarDebugStore(@MainActor @Observable),AboutTitlebarDebugWindowController,AboutTitlebarDebugView, and value types.WindowDecoratingprotocol;AppDelegateconforms and is injected into the coordinator; references held weakly to avoid cycles.AppDelegate(debugWindowsCoordinator,aboutTitlebarDebugStore); updated call sites to forward to them.applyToOpenWindowsnow no-ops ifNSAppis nil to enable unit tests.swiftLanguageMode(.v6)) and enablesExistentialAny/InternalImportsByDefault.Written for commit c98f409. Summary will update on new commits.
Summary by CodeRabbit
Release Notes
New Features
Tests