Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Battery event #18

Merged
merged 2 commits into from
Aug 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion include/modules/battery.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <fstream>
#include <iostream>
#include <fmt/format.h>
#include <sys/inotify.h>
#include "util/chrono.hpp"
#include "IModule.hpp"

Expand All @@ -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;
Expand Down
12 changes: 9 additions & 3 deletions include/util/chrono.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ namespace waybar::util {
func();
} while (do_run);
}}
{}
{
defined = true;
}

SleeperThread& operator=(std::function<void()> func)
{
Expand All @@ -48,6 +50,7 @@ namespace waybar::util {
func();
} while (do_run);
});
defined = true;
return *this;
}

Expand All @@ -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;
};

Expand Down
17 changes: 10 additions & 7 deletions src/bar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,24 +167,27 @@ auto waybar::Bar::_setupWidgets() -> void
box1.pack_end(right, true, true);

Factory factory(*this, _config);

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);
}
}
}
45 changes: 27 additions & 18 deletions src/factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
52 changes: 28 additions & 24 deletions src/modules/battery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
6 changes: 2 additions & 4 deletions src/modules/custom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
6 changes: 3 additions & 3 deletions src/modules/network.cpp
Original file line number Diff line number Diff line change
@@ -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] {
Expand Down Expand Up @@ -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);
Expand Down
17 changes: 6 additions & 11 deletions src/modules/workspaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down