pulseaudio: show correct sink volume on default output changes

on sinkInfo callbacks, the default sink now has highest priority.
That fixes an issue that the volume indicator is not updated when
the changes the default output to another devices.

added PA_SINK_IDLE as valid state. PA_SINK_RUNNING is only true
if any sound output is happening on sink switch. Indicator should
also update when no sound is being played.
This commit is contained in:
Philipp Hentschel
2024-07-22 12:17:21 +02:00
parent 21af48fdc9
commit dedee8cd14
3 changed files with 34 additions and 3 deletions

View File

@ -38,6 +38,8 @@ class AudioBackend {
std::string desc_; std::string desc_;
std::string monitor_; std::string monitor_;
std::string current_sink_name_; std::string current_sink_name_;
std::string default_sink_name;
bool default_sink_running_;
bool current_sink_running_; bool current_sink_running_;
// SOURCE // SOURCE
uint32_t source_idx_{0}; uint32_t source_idx_{0};

View File

@ -1,4 +1,6 @@
#include "modules/pulseaudio.hpp" #include "modules/pulseaudio.hpp"
#include <spdlog/spdlog.h>
#include <numeric>
waybar::modules::Pulseaudio::Pulseaudio(const std::string &id, const Json::Value &config) waybar::modules::Pulseaudio::Pulseaudio(const std::string &id, const Json::Value &config)
: ALabel(config, "pulseaudio", id, "{volume}%") { : ALabel(config, "pulseaudio", id, "{volume}%") {
@ -52,6 +54,7 @@ const std::vector<std::string> waybar::modules::Pulseaudio::getPulseIcon() const
std::string nameLC = backend->getSinkPortName() + backend->getFormFactor(); std::string nameLC = backend->getSinkPortName() + backend->getFormFactor();
std::transform(nameLC.begin(), nameLC.end(), nameLC.begin(), ::tolower); std::transform(nameLC.begin(), nameLC.end(), nameLC.begin(), ::tolower);
for (auto const &port : ports) { for (auto const &port : ports) {
spdlog::trace("Port: {}", nameLC);
if (nameLC.find(port) != std::string::npos) { if (nameLC.find(port) != std::string::npos) {
if (sink_muted) { if (sink_muted) {
res.emplace_back(port + "-muted"); res.emplace_back(port + "-muted");
@ -63,6 +66,10 @@ const std::vector<std::string> waybar::modules::Pulseaudio::getPulseIcon() const
if (sink_muted) { if (sink_muted) {
res.emplace_back("default-muted"); res.emplace_back("default-muted");
} }
spdlog::trace("Ports:");
for (auto const &item : res) {
spdlog::trace(" {}", item);
}
return res; return res;
} }

View File

@ -1,14 +1,18 @@
#include "util/audio_backend.hpp" #include "util/audio_backend.hpp"
#include <fmt/core.h> #include <fmt/core.h>
#include <pulse/def.h>
#include <pulse/error.h> #include <pulse/error.h>
#include <pulse/introspect.h>
#include <pulse/subscribe.h> #include <pulse/subscribe.h>
#include <pulse/volume.h> #include <pulse/volume.h>
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <cstring>
#include <stdexcept> #include <stdexcept>
#include <utility> #include <utility>
#include <spdlog/spdlog.h>
namespace waybar::util { namespace waybar::util {
@ -132,6 +136,7 @@ void AudioBackend::volumeModifyCb(pa_context *c, int success, void *data) {
} }
} }
/* /*
* Called when the requested sink information is ready. * Called when the requested sink information is ready.
*/ */
@ -139,6 +144,11 @@ void AudioBackend::sinkInfoCb(pa_context * /*context*/, const pa_sink_info *i, i
void *data) { void *data) {
if (i == nullptr) return; if (i == nullptr) return;
spdlog::trace("Callback start");
auto running = i->state == PA_SINK_RUNNING;
auto idle = i->state == PA_SINK_IDLE;
spdlog::trace("Sink name {} Running:[{}] Idle:[{}]", i->name, running,idle );
auto *backend = static_cast<AudioBackend *>(data); auto *backend = static_cast<AudioBackend *>(data);
if (!backend->ignored_sinks_.empty()) { if (!backend->ignored_sinks_.empty()) {
@ -155,11 +165,22 @@ void AudioBackend::sinkInfoCb(pa_context * /*context*/, const pa_sink_info *i, i
} }
} }
if (backend->current_sink_name_ == i->name) { backend->default_sink_running_ =
backend->current_sink_running_ = i->state == PA_SINK_RUNNING; backend->default_sink_name == i->name;
if ( i->name != backend->default_sink_name) {
return;
} }
if (!backend->current_sink_running_ && i->state == PA_SINK_RUNNING) { if (backend->current_sink_name_ == i->name) {
backend->current_sink_running_ =
(i->state == PA_SINK_RUNNING ||
i->state == PA_SINK_IDLE);
}
if (!backend->current_sink_running_ && (
i->state == PA_SINK_RUNNING ||
i->state == PA_SINK_IDLE)) {
backend->current_sink_name_ = i->name; backend->current_sink_name_ = i->name;
backend->current_sink_running_ = true; backend->current_sink_running_ = true;
} }
@ -207,6 +228,7 @@ void AudioBackend::sourceInfoCb(pa_context * /*context*/, const pa_source_info *
void AudioBackend::serverInfoCb(pa_context *context, const pa_server_info *i, void *data) { void AudioBackend::serverInfoCb(pa_context *context, const pa_server_info *i, void *data) {
auto *backend = static_cast<AudioBackend *>(data); auto *backend = static_cast<AudioBackend *>(data);
backend->current_sink_name_ = i->default_sink_name; backend->current_sink_name_ = i->default_sink_name;
backend->default_sink_name = i->default_sink_name;
backend->default_source_name_ = i->default_source_name; backend->default_source_name_ = i->default_source_name;
pa_context_get_sink_info_list(context, sinkInfoCb, data); pa_context_get_sink_info_list(context, sinkInfoCb, data);