Cut idle CPU from ~15% to ~0%#1
Merged
Merged
Conversation
… re-renders - Start the CoreAudio system tap only while music is actually playing (2s delayed teardown on pause); previously the tap + realtime IO thread ran six biquads over every sample 24/7 from launch. - Skip the 60Hz bars publish when levels haven't visibly moved, so silence no longer drives SwiftUI re-renders of the whole notch. - Replace the 16Hz hover poll with mouse-moved event monitors plus a 0.5s safety tick. - Slow the CGWindowListCopyWindowInfo overlay poll from 0.15s to 0.4s; the occlusion watcher remains the fast open-detection path. - Cap the fallback dancing-bars wiggle at 30fps instead of display refresh. Idle CPU drops from ~11% sustained to ~0.1-0.2%. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V66hekkNTU1kraQvcYMZjN
…poll MediaRemote is locked down on recent macOS, so every 3s poll ran a synchronous AppleScript round-trip to Spotify on the main thread — ~3% steady CPU even after the audio-tap gating. Listen for Spotify's PlaybackStateChanged distributed notification instead and keep only a 15s recovery poll. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V66hekkNTU1kraQvcYMZjN
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The problem
The notch was burning 11–19% CPU sitting completely idle, with a matching hit to battery life. Sampling the running process found five always-on loops doing work nobody could see:
audioMeter.start()was called unconditionally, so a realtime IO thread filtered every audio sample through six biquads forever — even with nothing playing and the notch collapsed. It also kept the audio stack from power-idling, which is the real battery cost.@Published barsunconditionally, so silence still invalidated and re-rendered the whole notch 60 times a second.The fix
PlaybackStateChangedinstead of polling; a 15s poll stays as a recovery net.Results
Measured on the running app with
ps/sample:A 10-second sample of the final build catches essentially nothing on-CPU — no
AudioMeter.process, noSpotifyBridge, no renderer frames. Behavior is unchanged: play/pause and track changes still update instantly, and the bars spin up on play.🤖 Generated with Claude Code
https://claude.ai/code/session_01V66hekkNTU1kraQvcYMZjN