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

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

View File

@ -1,14 +1,18 @@
#include "util/audio_backend.hpp"
#include <fmt/core.h>
#include <pulse/def.h>
#include <pulse/error.h>
#include <pulse/introspect.h>
#include <pulse/subscribe.h>
#include <pulse/volume.h>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <stdexcept>
#include <utility>
#include <spdlog/spdlog.h>
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.
*/
@ -139,6 +144,11 @@ void AudioBackend::sinkInfoCb(pa_context * /*context*/, const pa_sink_info *i, i
void *data) {
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);
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->current_sink_running_ = i->state == PA_SINK_RUNNING;
backend->default_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_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) {
auto *backend = static_cast<AudioBackend *>(data);
backend->current_sink_name_ = i->default_sink_name;
backend->default_sink_name = i->default_sink_name;
backend->default_source_name_ = i->default_source_name;
pa_context_get_sink_info_list(context, sinkInfoCb, data);