Repository navigation
v0.7.0 — hardening
A hardening release: many fixes to playback state and navigation, protection against hostile text and images, a cleaner shutdown, and faster visualizers.
New
- Filter playlists and podcasts with
/. Typing filters the list as you go and keeps loading pages until it has searched everything. --versionfalls back to the module version or git revision forgo installand source builds.
Fixed
- Closing the terminal now restores it and stops librespot. Before, closing the window could leave the terminal in the alternate screen and librespot running as an orphaned Connect device. On Linux, librespot is also stopped if tuify is killed outright.
- Hidden rows no longer respond to the mouse. Clicks and scrolling are ignored while help, the visualizer, mini mode or the device picker is open. Before, a double-click could play a track you couldn't see.
- Lists no longer mix up pages. Backing out of a playlist and opening another could append the first one's tracks to the second.
- Now playing no longer flips back to the previous track when a slow status update arrives after a quick one.
- Status messages stay up for their full time instead of being cleared early by an older message's timer.
- Rate limiting: several requests throttled at once now pause for 30 s instead of 2 minutes.
- Error messages are readable, e.g. "Session expired", "Premium required", "Rate limited until 14:03", instead of raw API responses. Login failures are no longer reported as network errors.
- Login: a stray request to the local callback port (a reloaded old tab, a web page) no longer aborts sign-in. The token refresh and revocation handling were also hardened.
- Config and token files are written atomically, so a crash mid-write can no longer corrupt them. A damaged
token.jsonjust triggers a fresh login. config.jsonwith extra content after the JSON object is now rejected instead of being silently ignored.- First run without a terminal (piped stdin) explains how to create
config.jsoninstead of saying the client ID is required. Config errors name the file. - Unknown command-line arguments exit with an error instead of starting the app. An external Ctrl+C exits with status 130.
- Followed playlists still show when fetching the user ID failed at startup.
- The search hint box uses your theme colours.
- librespot's last output before a crash now reaches
debug.log, and two quick reconnects no longer both transfer playback (the second could resume playback you had just paused). - Background requests stop promptly at shutdown, and list and search requests time out after 30 s instead of hanging.
Security
- Terminal escape sequences are stripped from Spotify names (tracks, playlists, owners, shows, devices) and Genius lyrics. A crafted name or lyric could otherwise write your clipboard, retitle the window or clear the screen.
- Oversized album art is rejected before decoding (limit 4096 px per side). A small crafted image could otherwise allocate gigabytes.
debug.logis now private (0600). The previous run's log is kept asdebug.log.1, so a crash log survives one relaunch.
Performance
- The audio analyzer uses a built-in FFT that doesn't allocate: about 7× faster per frame (98 µs → 13 µs). The
go-dspdependency is gone. - Visualizer frames no longer scan for clickable regions they don't have. A large Spectrogram frame went from 2.4 ms to 0.8 ms.
- Milkdrop presets are 7–11% faster with identical output. Colour output, gradients and buffers allocate far less per frame.
- The spinner and scrolling-label timers only run when something on screen needs them, so an idle screen no longer redraws about 17 times a second.
Full Changelog: v0.6.0...v0.7.0