From cb968c93692537b3c4291209092881e70feb1206 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 4 Jul 2026 12:49:47 +0200 Subject: [PATCH] fix(mpd): bound the connect timeout so an unreachable server can't freeze the bar The MPD state machine drives all connection attempts from Glib::signal_timeout callbacks, which run on the GTK main loop. tryConnect() called mpd_connection_new() with the user-facing timeout_ (up to 30s by default), so an unreachable server blocked the whole bar for the full connect timeout. Bound the connect attempt to a short fixed timeout (2000 ms) so a dead server fails fast, then restore the configured timeout_ for subsequent command reads so slow-but-alive servers are unaffected. Fixes #1186. --- src/modules/mpd/mpd.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/modules/mpd/mpd.cpp b/src/modules/mpd/mpd.cpp index 106c54eb..8598628d 100644 --- a/src/modules/mpd/mpd.cpp +++ b/src/modules/mpd/mpd.cpp @@ -294,8 +294,19 @@ void waybar::modules::MPD::tryConnect() { return; } - connection_ = - detail::unique_connection(mpd_connection_new(server_, port_, timeout_), &mpd_connection_free); + // tryConnect() runs on the GTK main thread (via Glib::signal_timeout), so a + // blocking connect freezes the whole bar. Bound the connect attempt to a + // short timeout so an unreachable MPD server fails fast instead of hanging + // the loop for the full user-facing `timeout_` (up to 30s by default, #1186). + // The third argument to mpd_connection_new() is also the default command + // read timeout, so restore `timeout_` once connected to avoid shortening + // reads for slow-but-alive servers. + static constexpr unsigned kConnectTimeoutMs = 2'000; + unsigned connect_timeout = + (timeout_ != 0 && timeout_ < kConnectTimeoutMs) ? timeout_ : kConnectTimeoutMs; + + connection_ = detail::unique_connection(mpd_connection_new(server_, port_, connect_timeout), + &mpd_connection_free); if (connection_ == nullptr) { spdlog::error("{}: Failed to connect to MPD", module_name_); @@ -303,6 +314,11 @@ void waybar::modules::MPD::tryConnect() { return; } + // Restore the user-configured timeout for subsequent command reads. + if (timeout_ != 0) { + mpd_connection_set_timeout(connection_.get(), timeout_); + } + try { checkErrors(connection_.get()); spdlog::debug("{}: Connected to MPD", module_name_);