feat(pulseaudio): source info

pull/331/head
Alex 2019-05-21 14:53:31 +02:00
parent cf7663153d
commit bb4af295bc
3 changed files with 64 additions and 16 deletions

View File

@ -18,6 +18,7 @@ class Pulseaudio : public ALabel {
static void subscribeCb(pa_context*, pa_subscription_event_type_t, uint32_t, void*); static void subscribeCb(pa_context*, pa_subscription_event_type_t, uint32_t, void*);
static void contextStateCb(pa_context*, void*); static void contextStateCb(pa_context*, void*);
static void sinkInfoCb(pa_context*, const pa_sink_info*, int, void*); static void sinkInfoCb(pa_context*, const pa_sink_info*, int, void*);
static void sourceInfoCb(pa_context*, const pa_source_info* i, int, void* data);
static void serverInfoCb(pa_context*, const pa_server_info*, void*); static void serverInfoCb(pa_context*, const pa_server_info*, void*);
static void volumeModifyCb(pa_context*, int, void*); static void volumeModifyCb(pa_context*, int, void*);
bool handleVolume(GdkEventScroll* e); bool handleVolume(GdkEventScroll* e);
@ -27,6 +28,8 @@ class Pulseaudio : public ALabel {
pa_threaded_mainloop* mainloop_; pa_threaded_mainloop* mainloop_;
pa_mainloop_api* mainloop_api_; pa_mainloop_api* mainloop_api_;
pa_context* context_; pa_context* context_;
bool scrolling_;
// SINK
uint32_t sink_idx_{0}; uint32_t sink_idx_{0};
uint16_t volume_; uint16_t volume_;
pa_cvolume pa_volume_; pa_cvolume pa_volume_;
@ -34,7 +37,12 @@ class Pulseaudio : public ALabel {
std::string port_name_; std::string port_name_;
std::string desc_; std::string desc_;
std::string monitor_; std::string monitor_;
bool scrolling_; // SOURCE
uint32_t source_idx_{0};
uint16_t source_volume_;
bool source_muted_;
std::string source_port_name_;
std::string source_desc_;
}; };
} // namespace waybar::modules } // namespace waybar::modules

View File

@ -112,9 +112,11 @@
}, },
"pulseaudio": { "pulseaudio": {
// "scroll-step": 1, // %, can be a float // "scroll-step": 1, // %, can be a float
"format": "{volume}% {icon}", "format": "{volume}% {icon} {format_source}",
"format-bluetooth": "{volume}% {icon}", "format-bluetooth": "{volume}% {icon}",
"format-muted": "", "format-muted": "",
"format-source": "{volume}% ",
"format-source-muted": "",
"format-icons": { "format-icons": {
"headphones": "", "headphones": "",
"handsfree": "", "handsfree": "",

View File

@ -1,15 +1,18 @@
#include "modules/pulseaudio.hpp" #include "modules/pulseaudio.hpp"
#include <array> #include <iostream>
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, "{volume}%"), : ALabel(config, "{volume}%"),
mainloop_(nullptr), mainloop_(nullptr),
mainloop_api_(nullptr), mainloop_api_(nullptr),
context_(nullptr), context_(nullptr),
scrolling_(false),
sink_idx_(0), sink_idx_(0),
volume_(0), volume_(0),
muted_(false), muted_(false),
scrolling_(false) { source_idx_(0),
source_volume_(0),
source_muted_(false) {
label_.set_name("pulseaudio"); label_.set_name("pulseaudio");
if (!id.empty()) { if (!id.empty()) {
label_.get_style_context()->add_class(id); label_.get_style_context()->add_class(id);
@ -58,7 +61,12 @@ void waybar::modules::Pulseaudio::contextStateCb(pa_context *c, void *data) {
case PA_CONTEXT_READY: case PA_CONTEXT_READY:
pa_context_get_server_info(c, serverInfoCb, data); pa_context_get_server_info(c, serverInfoCb, data);
pa_context_set_subscribe_callback(c, subscribeCb, data); pa_context_set_subscribe_callback(c, subscribeCb, data);
pa_context_subscribe(c, PA_SUBSCRIPTION_MASK_SINK, nullptr, nullptr); pa_context_subscribe(
c,
static_cast<enum pa_subscription_mask>(static_cast<int>(PA_SUBSCRIPTION_MASK_SINK) |
static_cast<int>(PA_SUBSCRIPTION_MASK_SOURCE)),
nullptr,
nullptr);
break; break;
case PA_CONTEXT_FAILED: case PA_CONTEXT_FAILED:
pa->mainloop_api_->quit(pa->mainloop_api_, 1); pa->mainloop_api_->quit(pa->mainloop_api_, 1);
@ -127,6 +135,8 @@ void waybar::modules::Pulseaudio::subscribeCb(pa_context * conte
unsigned facility = type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK; unsigned facility = type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK;
if (facility == PA_SUBSCRIPTION_EVENT_SINK) { if (facility == PA_SUBSCRIPTION_EVENT_SINK) {
pa_context_get_sink_info_by_index(context, idx, sinkInfoCb, data); pa_context_get_sink_info_by_index(context, idx, sinkInfoCb, data);
} else if (facility == PA_SUBSCRIPTION_EVENT_SOURCE) {
pa_context_get_source_info_by_index(context, idx, sourceInfoCb, data);
} }
} }
@ -140,6 +150,23 @@ void waybar::modules::Pulseaudio::volumeModifyCb(pa_context *c, int success, voi
} }
} }
/*
* Called when the requested source information is ready.
*/
void waybar::modules::Pulseaudio::sourceInfoCb(pa_context * /*context*/, const pa_source_info *i,
int /*eol*/, void *data) {
if (i != nullptr) {
auto self = static_cast<waybar::modules::Pulseaudio *>(data);
auto source_volume = static_cast<float>(pa_cvolume_avg(&(i->volume))) / float{PA_VOLUME_NORM};
self->source_volume_ = std::round(source_volume * 100.0F);
self->source_idx_ = i->index;
self->source_muted_ = i->mute != 0;
self->source_desc_ = i->description;
self->source_port_name_ = i->active_port != nullptr ? i->active_port->name : "Unknown";
self->dp.emit();
}
}
/* /*
* Called when the requested sink information is ready. * Called when the requested sink information is ready.
*/ */
@ -166,6 +193,7 @@ void waybar::modules::Pulseaudio::sinkInfoCb(pa_context * /*context*/, const pa_
void waybar::modules::Pulseaudio::serverInfoCb(pa_context *context, const pa_server_info *i, void waybar::modules::Pulseaudio::serverInfoCb(pa_context *context, const pa_server_info *i,
void *data) { void *data) {
pa_context_get_sink_info_by_name(context, i->default_sink_name, sinkInfoCb, data); pa_context_get_sink_info_by_name(context, i->default_sink_name, sinkInfoCb, data);
pa_context_get_source_info_by_name(context, i->default_source_name, sourceInfoCb, data);
} }
static const std::array<std::string, 9> ports = { static const std::array<std::string, 9> ports = {
@ -206,8 +234,18 @@ auto waybar::modules::Pulseaudio::update() -> void {
label_.get_style_context()->remove_class("bluetooth"); label_.get_style_context()->remove_class("bluetooth");
} }
} }
label_.set_markup(fmt::format( // TODO: find a better way to split source/sink
format, fmt::arg("volume", volume_), fmt::arg("icon", getIcon(volume_, getPortIcon())))); std::string format_source = "{source_volume}%";
if (source_muted_ && config_["format-source-muted"].isString()) {
format_source = config_["format-source-muted"].asString();
} else if (!source_muted_ && config_["format-source"].isString()) {
format_source = config_["format-source"].asString();
}
format_source = fmt::format(format_source, fmt::arg("volume", source_volume_));
label_.set_markup(fmt::format(format,
fmt::arg("volume", volume_),
fmt::arg("format_source", format_source),
fmt::arg("icon", getIcon(volume_, getPortIcon()))));
getState(volume_); getState(volume_);
if (tooltipEnabled()) { if (tooltipEnabled()) {
label_.set_tooltip_text(desc_); label_.set_tooltip_text(desc_);