Merge pull request #3421 from Ape/pr/pulseaudio_mapping

pulseaudio: Add 'sink-mapping' config option
This commit is contained in:
Alexis Rouillard
2026-07-03 23:58:57 +02:00
committed by GitHub
5 changed files with 27 additions and 1 deletions
+2
View File
@@ -57,6 +57,7 @@ class AudioBackend {
std::string default_source_name_; std::string default_source_name_;
std::vector<std::string> ignored_sinks_; std::vector<std::string> ignored_sinks_;
std::map<std::string, std::string> sink_mapping_;
std::function<void()> on_updated_cb_ = NOOP; std::function<void()> on_updated_cb_ = NOOP;
@@ -80,6 +81,7 @@ class AudioBackend {
PulseaudioTarget target = PulseaudioTarget::Sink); PulseaudioTarget target = PulseaudioTarget::Sink);
void setIgnoredSinks(const Json::Value& config); void setIgnoredSinks(const Json::Value& config);
void setSinkMapping(const Json::Value& config);
std::string getSinkPortName() const { return port_name_; } std::string getSinkPortName() const { return port_name_; }
std::string getFormFactor() const { return form_factor_; } std::string getFormFactor() const { return form_factor_; }
+4
View File
@@ -117,6 +117,10 @@ Additionally, you can control the volume by scrolling *up* or *down* while the c
typeof: array ++ typeof: array ++
Sinks in this list will not be shown as active sink by Waybar. Entries should be the sink's description field. Sinks in this list will not be shown as active sink by Waybar. Entries should be the sink's description field.
*sink-mapping*: ++
typeof: object ++
Sinks named by the values of this mapping will be considered to be the current sink instead of the sinks named by the respective keys.
*menu*: ++ *menu*: ++
typeof: string ++ typeof: string ++
Action that popups the menu. Action that popups the menu.
+1
View File
@@ -7,6 +7,7 @@ waybar::modules::Pulseaudio::Pulseaudio(const std::string& id, const Json::Value
backend = util::AudioBackend::getInstance([this] { this->dp.emit(); }); backend = util::AudioBackend::getInstance([this] { this->dp.emit(); });
backend->setIgnoredSinks(config_["ignored-sinks"]); backend->setIgnoredSinks(config_["ignored-sinks"]);
backend->setSinkMapping(config_["sink-mapping"]);
if (config_["target"].isString() && config_["target"].asString() == "source") { if (config_["target"].isString() && config_["target"].asString() == "source") {
target = util::PulseaudioTarget::Source; target = util::PulseaudioTarget::Source;
+1
View File
@@ -6,6 +6,7 @@ PulseaudioSlider::PulseaudioSlider(const std::string& id, const Json::Value& con
: ASlider(config, "pulseaudio-slider", id) { : ASlider(config, "pulseaudio-slider", id) {
backend = util::AudioBackend::getInstance([this] { this->dp.emit(); }); backend = util::AudioBackend::getInstance([this] { this->dp.emit(); });
backend->setIgnoredSinks(config_["ignored-sinks"]); backend->setIgnoredSinks(config_["ignored-sinks"]);
backend->setSinkMapping(config_["sink-mapping"]);
if (config_["target"].isString()) { if (config_["target"].isString()) {
std::string target = config_["target"].asString(); std::string target = config_["target"].asString();
+19 -1
View File
@@ -198,10 +198,18 @@ void AudioBackend::sinkInfoCb(pa_context* /*context*/, const pa_sink_info* i, in
} }
} }
if (const auto mapping = backend->sink_mapping_.find(backend->current_sink_name_);
mapping != backend->sink_mapping_.end()) {
if (i->name == mapping->second) {
backend->current_sink_name_ = i->name;
}
}
backend->default_sink_running_ = backend->default_sink_name == i->name && backend->default_sink_running_ = backend->default_sink_name == i->name &&
(i->state == PA_SINK_RUNNING || i->state == PA_SINK_IDLE); (i->state == PA_SINK_RUNNING || i->state == PA_SINK_IDLE);
if (i->name != backend->default_sink_name && !backend->default_sink_running_) { if (i->name != backend->default_sink_name && i->name != backend->current_sink_name_ &&
!backend->default_sink_running_) {
return; return;
} }
@@ -493,4 +501,14 @@ void AudioBackend::setIgnoredSinks(const Json::Value& config) {
} }
} }
void AudioBackend::setSinkMapping(const Json::Value& config) {
if (config.isObject()) {
for (auto it = config.begin(); it != config.end(); ++it) {
if (it.key().isString() && it->isString()) {
sink_mapping_.emplace(it.key().asString(), it->asString());
}
}
}
}
} // namespace waybar::util } // namespace waybar::util