← back to Exo
fix(app): tighten Share Bug Report prompt layout (#2008)
fb12b403ea77ad219a7d81b78d1246171454378a · 2026-04-30 15:10:26 +0100 · Alex Cheema
## Summary
Follow-ups to #2003 based on feedback that the Share Bug Report window
felt visually weighty: too much padding above and below, and a
description editor that invited an essay rather than a one-liner.
## Changes (one file)
`app/EXO/EXO/Views/BugReportWindowController.swift`:
- **Auto-size the window to its content.** Switched from `NSHostingView`
+ fixed `contentRect: 480x380` + SwiftUI `frame(minHeight: 320)` to
`NSHostingController` with `sizingOptions = [.preferredContentSize,
.minSize]`. The fixed-min combo was centering the form in dead vertical
space.
- **Smaller, lower-pressure editor.** Field is now labeled `Description
(optional)` with a placeholder hint (`What were you doing when it
broke?`) inside the editor. Editor height fixed at 72pt (was 120pt min).
Replaced the long lead-in paragraph and headline with a single one-line
caption between field and buttons: `Diagnostic logs will be uploaded
with your report.`
- **Tighter spacing.** Outer padding 20 -> 16, root spacing 16 -> 12,
prompting-section spacing 12 -> 8.
- **Remove em dash from copy.**
`BugReportService` and the menu wiring are unchanged.
## Test plan
- [ ] Click `Share Bug Report...` from the menu bar.
- [ ] The window opens centered and sized to its content (no big empty
bands top/bottom).
- [ ] Description editor is visibly compact, with the placeholder hint
showing when empty.
- [ ] The optional-ness is conveyed by the field label (no separate help
paragraph).
- [ ] Caption `Diagnostic logs will be uploaded with your report.`
appears in `.caption` style under the editor, above the buttons.
- [ ] Resize the window: persists across re-opens (frame autosave still
works).
- [ ] Send/Cancel/Try Again/Done flows behave the same as before.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Files touched
M app/EXO/EXO/Views/BugReportWindowController.swift
Diff
commit fb12b403ea77ad219a7d81b78d1246171454378a
Author: Alex Cheema <41707476+AlexCheema@users.noreply.github.com>
Date: Thu Apr 30 15:10:26 2026 +0100
fix(app): tighten Share Bug Report prompt layout (#2008)
## Summary
Follow-ups to #2003 based on feedback that the Share Bug Report window
felt visually weighty: too much padding above and below, and a
description editor that invited an essay rather than a one-liner.
## Changes (one file)
`app/EXO/EXO/Views/BugReportWindowController.swift`:
- **Auto-size the window to its content.** Switched from `NSHostingView`
+ fixed `contentRect: 480x380` + SwiftUI `frame(minHeight: 320)` to
`NSHostingController` with `sizingOptions = [.preferredContentSize,
.minSize]`. The fixed-min combo was centering the form in dead vertical
space.
- **Smaller, lower-pressure editor.** Field is now labeled `Description
(optional)` with a placeholder hint (`What were you doing when it
broke?`) inside the editor. Editor height fixed at 72pt (was 120pt min).
Replaced the long lead-in paragraph and headline with a single one-line
caption between field and buttons: `Diagnostic logs will be uploaded
with your report.`
- **Tighter spacing.** Outer padding 20 -> 16, root spacing 16 -> 12,
prompting-section spacing 12 -> 8.
- **Remove em dash from copy.**
`BugReportService` and the menu wiring are unchanged.
## Test plan
- [ ] Click `Share Bug Report...` from the menu bar.
- [ ] The window opens centered and sized to its content (no big empty
bands top/bottom).
- [ ] Description editor is visibly compact, with the placeholder hint
showing when empty.
- [ ] The optional-ness is conveyed by the field label (no separate help
paragraph).
- [ ] Caption `Diagnostic logs will be uploaded with your report.`
appears in `.caption` style under the editor, above the buttons.
- [ ] Resize the window: persists across re-opens (frame autosave still
works).
- [ ] Send/Cancel/Try Again/Done flows behave the same as before.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
app/EXO/EXO/Views/BugReportWindowController.swift | 72 ++++++++++++-----------
1 file changed, 37 insertions(+), 35 deletions(-)
diff --git a/app/EXO/EXO/Views/BugReportWindowController.swift b/app/EXO/EXO/Views/BugReportWindowController.swift
index 853976c0..1e1c9604 100644
--- a/app/EXO/EXO/Views/BugReportWindowController.swift
+++ b/app/EXO/EXO/Views/BugReportWindowController.swift
@@ -18,17 +18,12 @@ final class BugReportWindowController: ObservableObject {
self?.window?.close()
})
- let hostingView = NSHostingView(rootView: view)
-
- let newWindow = NSWindow(
- contentRect: NSRect(x: 0, y: 0, width: 480, height: 380),
- styleMask: [.titled, .closable, .resizable],
- backing: .buffered,
- defer: false
- )
+ let hostingController = NSHostingController(rootView: view)
+ hostingController.sizingOptions = [.preferredContentSize, .minSize]
+
+ let newWindow = NSWindow(contentViewController: hostingController)
+ newWindow.styleMask = [.titled, .closable, .resizable]
newWindow.title = "Send a Bug Report"
- newWindow.contentView = hostingView
- newWindow.contentMinSize = NSSize(width: 420, height: 320)
newWindow.center()
newWindow.setFrameAutosaveName("ExoBugReportWindow")
newWindow.isReleasedWhenClosed = false
@@ -54,7 +49,7 @@ private struct BugReportView: View {
@FocusState private var descriptionFocused: Bool
var body: some View {
- VStack(alignment: .leading, spacing: 16) {
+ VStack(alignment: .leading, spacing: 12) {
switch phase {
case .prompting:
promptingView
@@ -66,39 +61,45 @@ private struct BugReportView: View {
failureView(message: message)
}
}
- .padding(20)
- .frame(minWidth: 420, minHeight: 320)
+ .padding(16)
+ .frame(minWidth: 380)
.animation(.easeInOut(duration: 0.2), value: phase)
.onAppear { descriptionFocused = true }
}
private var promptingView: some View {
- VStack(alignment: .leading, spacing: 12) {
- VStack(alignment: .leading, spacing: 4) {
- Text("Tell us what went wrong")
- .font(.headline)
- Text(
- "A short description of what you were doing and what happened helps us track down the bug. This is optional — diagnostic logs will be sent either way."
- )
+ VStack(alignment: .leading, spacing: 8) {
+ Text("Description (optional)")
.font(.subheadline)
.foregroundColor(.secondary)
- .fixedSize(horizontal: false, vertical: true)
+ ZStack(alignment: .topLeading) {
+ if userDescription.isEmpty {
+ Text("What were you doing when it broke?")
+ .font(.body)
+ .foregroundColor(Color(nsColor: .placeholderTextColor))
+ .padding(.horizontal, 10)
+ .padding(.vertical, 8)
+ .allowsHitTesting(false)
+ }
+ TextEditor(text: $userDescription)
+ .font(.body)
+ .scrollContentBackground(.hidden)
+ .padding(4)
+ .frame(height: 72)
+ .focused($descriptionFocused)
}
+ .background(
+ RoundedRectangle(cornerRadius: 6)
+ .fill(Color(nsColor: .textBackgroundColor))
+ )
+ .overlay(
+ RoundedRectangle(cornerRadius: 6)
+ .strokeBorder(Color(nsColor: .separatorColor), lineWidth: 1)
+ )
- TextEditor(text: $userDescription)
- .font(.body)
- .scrollContentBackground(.hidden)
- .padding(6)
- .frame(minHeight: 120)
- .background(
- RoundedRectangle(cornerRadius: 6)
- .fill(Color(nsColor: .textBackgroundColor))
- )
- .overlay(
- RoundedRectangle(cornerRadius: 6)
- .strokeBorder(Color(nsColor: .separatorColor), lineWidth: 1)
- )
- .focused($descriptionFocused)
+ Text("Diagnostic logs will be uploaded with your report.")
+ .font(.caption)
+ .foregroundColor(.secondary)
HStack {
Spacer()
@@ -109,6 +110,7 @@ private struct BugReportView: View {
}
.keyboardShortcut(.defaultAction)
}
+ .padding(.top, 4)
}
}
← 1606e638 feat(app): open Share Bug Report in a dedicated window (#200
·
back to Exo
·
A few targeted tweaks to address HF rate limits (#2009) 8dae3ecb →