sndio: Add reconnection support.
This commit is contained in:
parent
aa625f5196
commit
22e46ea6cc
|
@ -18,6 +18,7 @@ class Sndio : public ALabel {
|
||||||
bool handleToggle(GdkEventButton* const&);
|
bool handleToggle(GdkEventButton* const&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
auto connect_to_sndio() -> void;
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
struct sioctl_hdl *hdl_;
|
struct sioctl_hdl *hdl_;
|
||||||
std::vector<struct pollfd> pfds_;
|
std::vector<struct pollfd> pfds_;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
namespace waybar::modules {
|
namespace waybar::modules {
|
||||||
|
|
||||||
|
@ -20,15 +21,7 @@ void onval(void *arg, unsigned int addr, unsigned int val) {
|
||||||
self->put_val(addr, val);
|
self->put_val(addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
Sndio::Sndio(const std::string &id, const Json::Value &config)
|
auto Sndio::connect_to_sndio() -> void {
|
||||||
: ALabel(config, "sndio", id, "{volume}%"),
|
|
||||||
hdl_(nullptr),
|
|
||||||
pfds_(0),
|
|
||||||
addr_(0),
|
|
||||||
volume_(0),
|
|
||||||
old_volume_(0),
|
|
||||||
maxval_(0),
|
|
||||||
muted_(false) {
|
|
||||||
hdl_ = sioctl_open(SIO_DEVANY, SIOCTL_READ | SIOCTL_WRITE, 0);
|
hdl_ = sioctl_open(SIO_DEVANY, SIOCTL_READ | SIOCTL_WRITE, 0);
|
||||||
if (hdl_ == nullptr) {
|
if (hdl_ == nullptr) {
|
||||||
throw std::runtime_error("sioctl_open() failed.");
|
throw std::runtime_error("sioctl_open() failed.");
|
||||||
|
@ -38,9 +31,23 @@ Sndio::Sndio(const std::string &id, const Json::Value &config)
|
||||||
throw std::runtime_error("sioctl_ondesc() failed.");
|
throw std::runtime_error("sioctl_ondesc() failed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
sioctl_onval(hdl_, onval, this);
|
if (sioctl_onval(hdl_, onval, this) == 0) {
|
||||||
|
throw std::runtime_error("sioctl_onval() failed.");
|
||||||
|
}
|
||||||
|
|
||||||
pfds_.reserve(sioctl_nfds(hdl_));
|
pfds_.reserve(sioctl_nfds(hdl_));
|
||||||
|
}
|
||||||
|
|
||||||
|
Sndio::Sndio(const std::string &id, const Json::Value &config)
|
||||||
|
: ALabel(config, "sndio", id, "{volume}%", 1),
|
||||||
|
hdl_(nullptr),
|
||||||
|
pfds_(0),
|
||||||
|
addr_(0),
|
||||||
|
volume_(0),
|
||||||
|
old_volume_(0),
|
||||||
|
maxval_(0),
|
||||||
|
muted_(false) {
|
||||||
|
connect_to_sndio();
|
||||||
|
|
||||||
event_box_.show();
|
event_box_.show();
|
||||||
|
|
||||||
|
@ -65,7 +72,28 @@ Sndio::Sndio(const std::string &id, const Json::Value &config)
|
||||||
|
|
||||||
int revents = sioctl_revents(hdl_, pfds_.data());
|
int revents = sioctl_revents(hdl_, pfds_.data());
|
||||||
if (revents & POLLHUP) {
|
if (revents & POLLHUP) {
|
||||||
throw std::runtime_error("disconnected!");
|
spdlog::warn("sndio disconnected!");
|
||||||
|
sioctl_close(hdl_);
|
||||||
|
hdl_ = nullptr;
|
||||||
|
|
||||||
|
// reconnection loop
|
||||||
|
while (thread_.isRunning()) {
|
||||||
|
try {
|
||||||
|
connect_to_sndio();
|
||||||
|
} catch(std::runtime_error const& e) {
|
||||||
|
// avoid leaking hdl_
|
||||||
|
if (hdl_) {
|
||||||
|
sioctl_close(hdl_);
|
||||||
|
hdl_ = nullptr;
|
||||||
|
}
|
||||||
|
// rate limiting for the retries
|
||||||
|
thread_.sleep_for(interval_);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
spdlog::warn("sndio reconnected!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -116,6 +144,9 @@ bool Sndio::handleScroll(GdkEventScroll *e) {
|
||||||
return AModule::handleScroll(e);
|
return AModule::handleScroll(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// only try to talk to sndio if connected
|
||||||
|
if (hdl_ == nullptr) return true;
|
||||||
|
|
||||||
auto dir = AModule::getScrollDir(e);
|
auto dir = AModule::getScrollDir(e);
|
||||||
if (dir == SCROLL_DIR::NONE) {
|
if (dir == SCROLL_DIR::NONE) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -152,6 +183,9 @@ bool Sndio::handleToggle(GdkEventButton* const& e) {
|
||||||
return AModule::handleToggle(e);
|
return AModule::handleToggle(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// only try to talk to sndio if connected
|
||||||
|
if (hdl_ == nullptr) return true;
|
||||||
|
|
||||||
muted_ = !muted_;
|
muted_ = !muted_;
|
||||||
if (muted_) {
|
if (muted_) {
|
||||||
// store old volume to be able to restore it later
|
// store old volume to be able to restore it later
|
||||||
|
|
Loading…
Reference in New Issue