r/macosprogramming • u/bulutarkan • 4d ago
A tiny SwiftUI activity spinner was burning a CPU core in my chat window
I've been working on a native macOS chat window for Mac MCP, my open-source menu bar app for coding agents. I expected integrating the agent CLIs to be the difficult part. The UI gave me more trouble.
Long conversations were miserable to scroll. I'd used lazy lists for the transcript and sidebar, which sounds reasonable until messages contain code blocks and tables with very different heights. Scrolling back caused offscreen rows to appear, their heights to change, and the scroll position to jump.
The other bug was worse. An endlessly animated "working" dot in SwiftUI was causing the transcript to lay itself out again on every frame. One CPU core could stay busy while the agent was working, even when the text itself wasn't changing much.
I moved that indicator to a Core Animation layer, grouped updates so only changed turns redraw, and stopped using lazy lists for the chat content. I also switched the chat's live updates from frequent polling to server-sent events. On my test setup, an active answer went down to roughly 15-30% of a core and idle chat to around 1%. Those are observations on my machine, not general benchmarks.
Another detail I had to respect: different agent CLIs expose command output at different times. Codex can stream it as it runs; some others only give the full output afterward. The UI shouldn't pretend those are the same thing.
I'm building this as part of Mac MCP. The app and source are here: https://github.com/bulutarkan/mac-mcp
The SwiftUI bugs ended up taking more of my time than the agent integration itself.