Battery event (#18)
parent
01894f18cd
commit
a423f7032d
|
@ -15,7 +15,7 @@ namespace waybar {
|
|||
class Factory {
|
||||
public:
|
||||
Factory(Bar &bar, Json::Value config);
|
||||
IModule &makeModule(std::string name);
|
||||
IModule *makeModule(std::string name);
|
||||
private:
|
||||
Bar &_bar;
|
||||
Json::Value _config;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <fmt/format.h>
|
||||
#include <sys/inotify.h>
|
||||
#include "util/chrono.hpp"
|
||||
#include "IModule.hpp"
|
||||
|
||||
|
@ -18,7 +19,7 @@ namespace waybar::modules {
|
|||
auto update() -> void;
|
||||
operator Gtk::Widget&();
|
||||
private:
|
||||
std::string _getIcon(uint32_t percentage);
|
||||
std::string _getIcon(uint16_t percentage);
|
||||
static inline const fs::path _data_dir = "/sys/class/power_supply/";
|
||||
std::vector<fs::path> _batteries;
|
||||
util::SleeperThread _thread;
|
||||
|
|
|
@ -39,7 +39,9 @@ namespace waybar::util {
|
|||
func();
|
||||
} while (do_run);
|
||||
}}
|
||||
{}
|
||||
{
|
||||
defined = true;
|
||||
}
|
||||
|
||||
SleeperThread& operator=(std::function<void()> func)
|
||||
{
|
||||
|
@ -48,6 +50,7 @@ namespace waybar::util {
|
|||
func();
|
||||
} while (do_run);
|
||||
});
|
||||
defined = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -72,14 +75,17 @@ namespace waybar::util {
|
|||
~SleeperThread()
|
||||
{
|
||||
do_run = false;
|
||||
condvar.notify_all();
|
||||
thread.join();
|
||||
if (defined) {
|
||||
condvar.notify_all();
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::thread thread;
|
||||
std::condition_variable condvar;
|
||||
std::mutex mutex;
|
||||
bool defined = false;
|
||||
bool do_run = true;
|
||||
};
|
||||
|
||||
|
|
15
src/bar.cpp
15
src/bar.cpp
|
@ -170,21 +170,24 @@ auto waybar::Bar::_setupWidgets() -> void
|
|||
|
||||
if (_config["modules-left"]) {
|
||||
for (auto name : _config["modules-left"]) {
|
||||
auto &module = factory.makeModule(name.asString());
|
||||
left.pack_start(module, false, true, 0);
|
||||
auto module = factory.makeModule(name.asString());
|
||||
if (module)
|
||||
left.pack_start(*module, false, true, 0);
|
||||
}
|
||||
}
|
||||
if (_config["modules-center"]) {
|
||||
for (auto name : _config["modules-center"]) {
|
||||
auto &module = factory.makeModule(name.asString());
|
||||
center.pack_start(module, true, false, 10);
|
||||
auto module = factory.makeModule(name.asString());
|
||||
if (module)
|
||||
center.pack_start(*module, true, false, 10);
|
||||
}
|
||||
}
|
||||
if (_config["modules-right"]) {
|
||||
std::reverse(_config["modules-right"].begin(), _config["modules-right"].end());
|
||||
for (auto name : _config["modules-right"]) {
|
||||
auto &module = factory.makeModule(name.asString());
|
||||
right.pack_end(module, false, false, 0);
|
||||
auto module = factory.makeModule(name.asString());
|
||||
if (module)
|
||||
right.pack_end(*module, false, false, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,23 +4,32 @@ waybar::Factory::Factory(Bar &bar, Json::Value config)
|
|||
: _bar(bar), _config(config)
|
||||
{}
|
||||
|
||||
waybar::IModule &waybar::Factory::makeModule(std::string name)
|
||||
waybar::IModule *waybar::Factory::makeModule(std::string name)
|
||||
{
|
||||
if (name == "battery")
|
||||
return *new waybar::modules::Battery(_config[name]);
|
||||
if (name == "workspaces")
|
||||
return *new waybar::modules::Workspaces(_bar);
|
||||
if (name == "memory")
|
||||
return *new waybar::modules::Memory(_config[name]);
|
||||
if (name == "cpu")
|
||||
return *new waybar::modules::Cpu(_config[name]);
|
||||
if (name == "clock")
|
||||
return *new waybar::modules::Clock(_config[name]);
|
||||
if (name == "network")
|
||||
return *new waybar::modules::Network(_config[name]);
|
||||
if (name == "pulseaudio")
|
||||
return *new waybar::modules::Pulseaudio(_config[name]);
|
||||
if (!name.compare(0, 7, "custom/") && name.size() > 7)
|
||||
return *new waybar::modules::Custom(name.substr(7), _config[name]);
|
||||
throw std::runtime_error("Unknown module: " + name);
|
||||
try {
|
||||
if (name == "battery")
|
||||
return new waybar::modules::Battery(_config[name]);
|
||||
if (name == "workspaces")
|
||||
return new waybar::modules::Workspaces(_bar);
|
||||
if (name == "memory")
|
||||
return new waybar::modules::Memory(_config[name]);
|
||||
if (name == "cpu")
|
||||
return new waybar::modules::Cpu(_config[name]);
|
||||
if (name == "clock")
|
||||
return new waybar::modules::Clock(_config[name]);
|
||||
if (name == "network")
|
||||
return new waybar::modules::Network(_config[name]);
|
||||
if (name == "pulseaudio")
|
||||
return new waybar::modules::Pulseaudio(_config[name]);
|
||||
if (!name.compare(0, 7, "custom/") && name.size() > 7)
|
||||
return new waybar::modules::Custom(name.substr(7), _config[name]);
|
||||
std::cerr << "Unknown module: " + name << std::endl;
|
||||
} catch (const std::exception& e) {
|
||||
auto err = fmt::format("Disabling module \"{}\", {}", name, e.what());
|
||||
std::cerr << err << std::endl;
|
||||
} catch (...) {
|
||||
auto err = fmt::format("Disabling module \"{}\", Unknown reason", name);
|
||||
std::cerr << err << std::endl;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -5,62 +5,66 @@ waybar::modules::Battery::Battery(Json::Value config)
|
|||
{
|
||||
try {
|
||||
for (auto &node : fs::directory_iterator(_data_dir)) {
|
||||
if (fs::is_directory(node) && fs::exists(node / "capacity")
|
||||
&& fs::exists(node / "status")) {
|
||||
if (fs::is_directory(node) && fs::exists(node / "capacity"))
|
||||
_batteries.push_back(node);
|
||||
}
|
||||
}
|
||||
} catch (fs::filesystem_error &e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
throw std::runtime_error(e.what());
|
||||
}
|
||||
|
||||
if (!_batteries.size()) {
|
||||
std::cerr << "No batteries." << std::endl;
|
||||
return;
|
||||
}
|
||||
if (!_batteries.size())
|
||||
throw std::runtime_error("No batteries.");
|
||||
|
||||
auto fd = inotify_init();
|
||||
if (fd == -1)
|
||||
throw std::runtime_error("Unable to listen batteries.");
|
||||
for (auto &bat : _batteries)
|
||||
inotify_add_watch(fd, (bat / "uevent").c_str(), IN_ACCESS);
|
||||
// Trigger first value
|
||||
update();
|
||||
_label.get_style_context()->add_class("battery");
|
||||
int interval = _config["interval"] ? _config["inveral"].asInt() : 1;
|
||||
_thread = [this, interval] {
|
||||
_thread = [this, fd] {
|
||||
struct inotify_event event;
|
||||
int nbytes = read(fd, &event, sizeof(event));
|
||||
if (nbytes != sizeof(event))
|
||||
return;
|
||||
Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Battery::update));
|
||||
_thread.sleep_for(chrono::seconds(interval));
|
||||
};
|
||||
}
|
||||
|
||||
auto waybar::modules::Battery::update() -> void
|
||||
{
|
||||
try {
|
||||
int total = 0;
|
||||
uint16_t total = 0;
|
||||
bool charging = false;
|
||||
std::string status;
|
||||
for (auto &bat : _batteries) {
|
||||
int capacity;
|
||||
std::string status;
|
||||
uint16_t capacity;
|
||||
std::ifstream(bat / "capacity") >> capacity;
|
||||
total += capacity;
|
||||
std::ifstream(bat / "status") >> status;
|
||||
if (status == "Charging") {
|
||||
if (status == "Charging")
|
||||
charging = true;
|
||||
}
|
||||
total += capacity;
|
||||
}
|
||||
uint16_t capacity = total / _batteries.size();
|
||||
auto format = _config["format"] ? _config["format"].asString() : "{}%";
|
||||
auto value = total / _batteries.size();
|
||||
_label.set_text(fmt::format(format, fmt::arg("value", value),
|
||||
fmt::arg("icon", _getIcon(value))));
|
||||
_label.set_tooltip_text(charging ? "Charging" : "Discharging");
|
||||
_label.set_text(fmt::format(format, fmt::arg("value", capacity),
|
||||
fmt::arg("icon", _getIcon(capacity))));
|
||||
_label.set_tooltip_text(status);
|
||||
if (charging)
|
||||
_label.get_style_context()->add_class("charging");
|
||||
else
|
||||
_label.get_style_context()->remove_class("charging");
|
||||
if (value < 16 && !charging)
|
||||
if (capacity < 16 && !charging)
|
||||
_label.get_style_context()->add_class("warning");
|
||||
else
|
||||
_label.get_style_context()->remove_class("warning");
|
||||
} catch (std::exception &e) {
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::string waybar::modules::Battery::_getIcon(uint32_t percentage)
|
||||
std::string waybar::modules::Battery::_getIcon(uint16_t percentage)
|
||||
{
|
||||
if (!_config["format-icons"] || !_config["format-icons"].isArray()) return "";
|
||||
auto step = 100 / _config["format-icons"].size();
|
||||
|
|
|
@ -4,10 +4,8 @@
|
|||
waybar::modules::Custom::Custom(std::string name, Json::Value config)
|
||||
: _name(name), _config(config)
|
||||
{
|
||||
if (!_config["exec"]) {
|
||||
std::cerr << name + " has no exec path." << std::endl;
|
||||
return;
|
||||
}
|
||||
if (!_config["exec"])
|
||||
throw std::runtime_error(name + " has no exec path.");
|
||||
int interval = _config["interval"] ? _config["inveral"].asInt() : 30;
|
||||
_thread = [this, interval] {
|
||||
Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Custom::update));
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
#include "modules/network.hpp"
|
||||
|
||||
waybar::modules::Network::Network(Json::Value config)
|
||||
: _config(config), _ifid(if_nametoindex(config["interface"].asString().c_str()))
|
||||
: _config(config), _ifid(if_nametoindex(config["interface"].asCString()))
|
||||
{
|
||||
if (_ifid == 0)
|
||||
throw std::runtime_error("Can't found network interface");
|
||||
_label.get_style_context()->add_class("network");
|
||||
int interval = _config["interval"] ? _config["inveral"].asInt() : 30;
|
||||
_thread = [this, interval] {
|
||||
|
@ -103,8 +105,6 @@ bool waybar::modules::Network::_associatedOrJoined(struct nlattr** bss)
|
|||
|
||||
auto waybar::modules::Network::_getInfo() -> void
|
||||
{
|
||||
if (_ifid == 0)
|
||||
return;
|
||||
struct nl_sock *sk = nl_socket_alloc();
|
||||
if (genl_connect(sk) != 0) {
|
||||
nl_socket_free(sk);
|
||||
|
|
|
@ -5,17 +5,12 @@ waybar::modules::Workspaces::Workspaces(Bar &bar)
|
|||
: _bar(bar)
|
||||
{
|
||||
_box.get_style_context()->add_class("workspaces");
|
||||
try {
|
||||
std::string socketPath = get_socketpath();
|
||||
_ipcSocketfd = ipc_open_socket(socketPath);
|
||||
_ipcEventSocketfd = ipc_open_socket(socketPath);
|
||||
const char *subscribe = "[ \"workspace\", \"mode\" ]";
|
||||
uint32_t len = strlen(subscribe);
|
||||
ipc_single_command(_ipcEventSocketfd, IPC_SUBSCRIBE, subscribe, &len);
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
return;
|
||||
}
|
||||
std::string socketPath = get_socketpath();
|
||||
_ipcSocketfd = ipc_open_socket(socketPath);
|
||||
_ipcEventSocketfd = ipc_open_socket(socketPath);
|
||||
const char *subscribe = "[ \"workspace\", \"mode\" ]";
|
||||
uint32_t len = strlen(subscribe);
|
||||
ipc_single_command(_ipcEventSocketfd, IPC_SUBSCRIBE, subscribe, &len);
|
||||
_thread = [this] {
|
||||
Glib::signal_idle().connect_once(sigc::mem_fun(*this, &Workspaces::update));
|
||||
_thread.sleep_for(chrono::milliseconds(250));
|
||||
|
|
Loading…
Reference in New Issue