feat(pulseaudio): source info
This commit is contained in:
parent
cf7663153d
commit
bb4af295bc
|
@ -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,14 +28,21 @@ 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_;
|
||||||
uint32_t sink_idx_{0};
|
|
||||||
uint16_t volume_;
|
|
||||||
pa_cvolume pa_volume_;
|
|
||||||
bool muted_;
|
|
||||||
std::string port_name_;
|
|
||||||
std::string desc_;
|
|
||||||
std::string monitor_;
|
|
||||||
bool scrolling_;
|
bool scrolling_;
|
||||||
|
// SINK
|
||||||
|
uint32_t sink_idx_{0};
|
||||||
|
uint16_t volume_;
|
||||||
|
pa_cvolume pa_volume_;
|
||||||
|
bool muted_;
|
||||||
|
std::string port_name_;
|
||||||
|
std::string desc_;
|
||||||
|
std::string monitor_;
|
||||||
|
// 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
|
||||||
|
|
|
@ -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": "",
|
||||||
|
|
|
@ -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);
|
||||||
|
@ -76,10 +84,10 @@ bool waybar::modules::Pulseaudio::handleVolume(GdkEventScroll *e) {
|
||||||
if (scrolling_) {
|
if (scrolling_) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool direction_up = false;
|
bool direction_up = false;
|
||||||
double volume_tick = (double)PA_VOLUME_NORM / 100;
|
double volume_tick = (double)PA_VOLUME_NORM / 100;
|
||||||
pa_volume_t change = volume_tick;
|
pa_volume_t change = volume_tick;
|
||||||
pa_cvolume pa_volume = pa_volume_;
|
pa_cvolume pa_volume = pa_volume_;
|
||||||
scrolling_ = true;
|
scrolling_ = true;
|
||||||
if (e->direction == GDK_SCROLL_UP) {
|
if (e->direction == GDK_SCROLL_UP) {
|
||||||
direction_up = true;
|
direction_up = true;
|
||||||
|
@ -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_);
|
||||||
|
|
Loading…
Reference in New Issue