From 0309bd38d71a1dff835c0b56f8117762549f49d2 Mon Sep 17 00:00:00 2001 From: maxsoch Date: Tue, 7 Jul 2026 05:59:11 +0200 Subject: [PATCH] improve log window: monospace, scrollbar, smarter autoscroll Monospaced font and semantic colors (dark-mode correct), visible vertical scroller (was missing), text inset, centered window with a proper title. Autoscroll now only follows the tail when already at the bottom instead of yanking the scroll position on every log line. Also sets isReleasedWhenClosed = false, fixing a latent crash on close-then-reopen (the settings window already had this guard). Co-Authored-By: Claude Fable 5 --- BrewBar/LogWindowController.swift | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/BrewBar/LogWindowController.swift b/BrewBar/LogWindowController.swift index 062cd35..f46d166 100644 --- a/BrewBar/LogWindowController.swift +++ b/BrewBar/LogWindowController.swift @@ -14,22 +14,41 @@ class LogWindowController: NSWindowController { self.init(window: window) - window.title = "Logs" + window.title = "BrewBar Logs" + // the controller keeps the window alive; without this, closing the + // window would deallocate it and reopening would crash + window.isReleasedWhenClosed = false + window.center() let scrollView = NSScrollView(frame: window.contentView!.bounds) scrollView.autoresizingMask = [.width, .height] + scrollView.hasVerticalScroller = true textView = NSTextView(frame: scrollView.bounds) textView.isEditable = false textView.autoresizingMask = [.width, .height] + textView.font = .monospacedSystemFont(ofSize: 12, weight: .regular) + textView.textColor = .textColor // adapts to light/dark mode + textView.backgroundColor = .textBackgroundColor + textView.textContainerInset = NSSize(width: 8, height: 8) scrollView.documentView = textView window.contentView?.addSubview(scrollView) } func update(text: String) { + // only follow the tail if the user is already at the bottom — don't + // yank the scroll position away while they are reading older output + let wasAtBottom: Bool = if let scrollView = textView.enclosingScrollView { + scrollView.contentView.bounds.maxY >= textView.frame.height - 30 + } else { + true + } + textView.string = text - textView.scrollToEndOfDocument(nil) + if wasAtBottom { + textView.scrollToEndOfDocument(nil) + } } }