diff --git a/include/modules/cava/cava_backend.hpp b/include/modules/cava/cava_backend.hpp index 17952c4a..c9d6b92b 100644 --- a/include/modules/cava/cava_backend.hpp +++ b/include/modules/cava/cava_backend.hpp @@ -41,7 +41,8 @@ class CavaBackend final { private: CavaBackend(const Json::Value& config); util::SleeperThread read_thread_; - sigc::connection out_thread_; + util::SleeperThread out_thread_; + // Cava API to read audio source ::cava::ptr input_source_{NULL}; @@ -69,7 +70,6 @@ class CavaBackend final { void doUpdate(bool force = false); void loadConfig(); void freeBackend(); - void doOutReadConnect(); // Signal type_signal_update m_signal_update_; diff --git a/src/modules/cava/cava.cpp b/src/modules/cava/cava.cpp index 906b7021..2ea4e694 100644 --- a/src/modules/cava/cava.cpp +++ b/src/modules/cava/cava.cpp @@ -24,30 +24,35 @@ auto waybar::modules::cava::Cava::doAction(const std::string& name) -> void { // Cava actions void waybar::modules::cava::Cava::pause_resume() { backend_->doPauseResume(); } auto waybar::modules::cava::Cava::onUpdate(const std::string& input) -> void { - if (silence_) { - label_.get_style_context()->remove_class("silent"); - if (!label_.get_style_context()->has_class("updated")) - label_.get_style_context()->add_class("updated"); - } - label_text_.clear(); - for (auto& ch : input) - label_text_.append(getIcon((ch > ascii_range_) ? ascii_range_ : ch, "", ascii_range_ + 1)); + Glib::signal_idle().connect_once([this, input]() { + if (silence_) { + label_.get_style_context()->remove_class("silent"); + if (!label_.get_style_context()->has_class("updated")) + label_.get_style_context()->add_class("updated"); + } + label_text_.clear(); + for (auto& ch : input) + label_text_.append(getIcon((ch > ascii_range_) ? ascii_range_ : ch, "", ascii_range_ + 1)); - label_.set_markup(label_text_); - label_.show(); - ALabel::update(); + label_.set_markup(label_text_); + label_.show(); + ALabel::update(); + }); silence_ = false; } -auto waybar::modules::cava::Cava::onSilence() -> void { - if (!silence_) { - if (label_.get_style_context()->has_class("updated")) - label_.get_style_context()->remove_class("updated"); - if (hide_on_silence_) - label_.hide(); - else if (config_["format_silent"].isString()) - label_.set_markup(format_silent_); - silence_ = true; - label_.get_style_context()->add_class("silent"); - } +auto waybar::modules::cava::Cava::onSilence() -> void { + Glib::signal_idle().connect_once([this]() { + if (!silence_) { + if (label_.get_style_context()->has_class("updated")) + label_.get_style_context()->remove_class("updated"); + + if (hide_on_silence_) + label_.hide(); + else if (config_["format_silent"].isString()) + label_.set_markup(format_silent_); + silence_ = true; + label_.get_style_context()->add_class("silent"); + } + }); } diff --git a/src/modules/cava/cava_backend.cpp b/src/modules/cava/cava_backend.cpp index 1ff7c086..aec945dc 100644 --- a/src/modules/cava/cava_backend.cpp +++ b/src/modules/cava/cava_backend.cpp @@ -14,9 +14,6 @@ waybar::modules::cava::CavaBackend::CavaBackend(const Json::Value& config) : con loadConfig(); // Read audio source trough cava API. Cava orginizes this process via infinity loop read_thread_ = [this] { - // Thread safe reading incoming source and do callbacks - doOutReadConnect(); - try { input_source_(&audio_data_); } catch (const std::runtime_error& e) { @@ -25,9 +22,19 @@ waybar::modules::cava::CavaBackend::CavaBackend(const Json::Value& config) : con read_thread_.sleep_for(fetch_input_delay_); loadConfig(); }; + // Write outcoming data. Emit signals + out_thread_ = [this] { + Update(); + out_thread_.sleep_for(frame_time_milsec_); + }; } -waybar::modules::cava::CavaBackend::~CavaBackend() { freeBackend(); } +waybar::modules::cava::CavaBackend::~CavaBackend() { + out_thread_.stop(); + read_thread_.stop(); + + freeBackend(); +} static bool upThreadDelay(std::chrono::milliseconds& delay, std::chrono::seconds& delta) { if (delta == std::chrono::seconds{0}) { @@ -94,7 +101,7 @@ void waybar::modules::cava::CavaBackend::doPauseResume() { upThreadDelay(frame_time_milsec_, suspend_silence_delay_); } pthread_mutex_unlock(&audio_data_.lock); - doOutReadConnect(); + Update(); } waybar::modules::cava::CavaBackend::type_signal_update @@ -124,19 +131,17 @@ void waybar::modules::cava::CavaBackend::doUpdate(bool force) { } if (!silence_ || prm_.sleep_timer == 0) { - if (downThreadDelay(frame_time_milsec_, suspend_silence_delay_)) doOutReadConnect(); + if (downThreadDelay(frame_time_milsec_, suspend_silence_delay_)) Update(); execute(); if (re_paint_ == 1 || force) m_signal_update_.emit(output_); } else { - if (upThreadDelay(frame_time_milsec_, suspend_silence_delay_)) doOutReadConnect(); + if (upThreadDelay(frame_time_milsec_, suspend_silence_delay_)) Update(); if (silence_ != silence_prev_ || force) m_signal_silence_.emit(); } silence_prev_ = silence_; } void waybar::modules::cava::CavaBackend::freeBackend() { - out_thread_.disconnect(); - if (plan_ != NULL) { cava_destroy(plan_); plan_ = NULL; @@ -238,14 +243,3 @@ void waybar::modules::cava::CavaBackend::loadConfig() { if (!plan_) spdlog::error("cava backend plan is not provided"); audio_raw_.previous_frame[0] = -1; // For first Update() call need to rePaint text message } - -void waybar::modules::cava::CavaBackend::doOutReadConnect() { - out_thread_.disconnect(); - // Thread safe reading incoming source and do callbacks - out_thread_ = Glib::signal_timeout().connect( - [&]() { - Update(); - return true; - }, - frame_time_milsec_.count()); -}