Skip to content
Open
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
6 changes: 4 additions & 2 deletions include/modules/battery.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "ALabel.hpp"
#include "bar.hpp"
#include "util/sleeper_thread.hpp"
#include "util/upower_backend.hpp"

namespace waybar::modules {

Expand All @@ -37,7 +38,7 @@ class Battery : public ALabel {
void setBarClass(std::string&);

int global_watch;
std::map<fs::path, int> batteries_;
std::set<fs::path> batteries_;
fs::path adapter_;
int battery_watch_fd_;
int global_watch_fd_;
Expand All @@ -46,7 +47,8 @@ class Battery : public ALabel {
bool warnFirstTime_{true};
const Bar& bar_;

util::SleeperThread thread_;
util::UPowerBackend upower_backend_;

util::SleeperThread thread_battery_update_;
util::SleeperThread thread_timer_;
};
Expand Down
58 changes: 9 additions & 49 deletions include/modules/upower.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
#include <unordered_map>

#include "AIconLabel.hpp"
#include "util/upower_backend.hpp"

using waybar::util::upDevice_output;
using waybar::util::UPowerBackend;

namespace waybar::modules {

Expand All @@ -28,21 +32,6 @@ class UPower final : public AIconLabel {
Gtk::Box contentBox_; // tooltip box
std::string tooltipFormat_;

// UPower device info
struct upDevice_output {
UpDevice *upDevice{NULL};
double percentage{0.0};
double temperature{0.0};
guint64 time_full{0u};
guint64 time_empty{0u};
gchar *icon_name{(char *)'\0'};
bool upDeviceValid{false};
UpDeviceState state;
UpDeviceKind kind;
char *nativePath{(char *)'\0'};
char *model{(char *)'\0'};
};

// Technical variables
std::string nativePath_;
std::string model_;
Expand All @@ -52,43 +41,14 @@ class UPower final : public AIconLabel {
Glib::RefPtr<Gtk::IconTheme> gtkTheme_;
bool sleeping_;

// Technical functions
void addDevice(UpDevice *);
void removeDevice(const gchar *);
void removeDevices();
void resetDevices();
void setDisplayDevice();
const Glib::ustring getText(const upDevice_output &upDevice_, const std::string &format);
bool queryTooltipCb(int, int, bool, const Glib::RefPtr<Gtk::Tooltip> &);

// DBUS variables
guint watcherID_;
Glib::RefPtr<Gio::DBus::Connection> conn_;
guint subscrID_{0u};

// UPower variables
UpClient *upClient_;
UPowerBackend upower_backend_;
upDevice_output upDevice_; // Device to display
typedef std::unordered_map<std::string, upDevice_output> Devices;
Devices devices_;
bool upRunning_{true};

// DBus callbacks
void getConn_cb(Glib::RefPtr<Gio::AsyncResult> &result);
void onAppear(const Glib::RefPtr<Gio::DBus::Connection> &, const Glib::ustring &,
const Glib::ustring &);
void onVanished(const Glib::RefPtr<Gio::DBus::Connection> &, const Glib::ustring &);
void prepareForSleep_cb(const Glib::RefPtr<Gio::DBus::Connection> &connection,
const Glib::ustring &sender_name, const Glib::ustring &object_path,
const Glib::ustring &interface_name, const Glib::ustring &signal_name,
const Glib::VariantContainerBase &parameters);

// UPower callbacks
static void deviceAdded_cb(UpClient *client, UpDevice *device, gpointer data);
static void deviceRemoved_cb(UpClient *client, const gchar *objectPath, gpointer data);
static void deviceNotify_cb(UpDevice *device, GParamSpec *pspec, gpointer user_data);
// UPower secondary functions
void getUpDeviceInfo(upDevice_output &upDevice_);

void setDisplayDevice();
const Glib::ustring getText(const upDevice_output &upDevice_, const std::string &format);
bool queryTooltipCb(int, int, bool, const Glib::RefPtr<Gtk::Tooltip> &);
};

} // namespace waybar::modules
79 changes: 79 additions & 0 deletions include/util/upower_backend.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#pragma once

#include <libupower-glib/upower.h>
#include <spdlog/spdlog.h>

#include <mutex>
#include <string>

#include "util/backend_common.hpp"

namespace waybar::util {

// UPower device info
struct upDevice_output {
UpDevice *upDevice{NULL};
double percentage{0.0};
double temperature{0.0};
guint64 time_full{0u};
guint64 time_empty{0u};
gchar *icon_name{(char *)'\0'};
bool upDeviceValid{false};
UpDeviceState state;
UpDeviceKind kind;
char *nativePath{(char *)'\0'};
char *model{(char *)'\0'};
};

class UPowerBackend {
public:
explicit UPowerBackend(std::function<void(bool)> notify_cb);
~UPowerBackend();

void getUpDeviceInfo(upDevice_output &upDevice_);

std::unordered_map<std::string, upDevice_output> &devices() { return devices_; }
bool running() { return upRunning_; }
UpClient *client() { return upClient_; }

private:
void addDevice(UpDevice *);
void removeDevice(const gchar *);
void notifyDevice(UpDevice *);
void removeDevices();
void resetDevices();
void notify(bool changed) { notify_cb_(changed); }

// DBus callbacks
void getConn_cb(Glib::RefPtr<Gio::AsyncResult> &result);
void onAppear(const Glib::RefPtr<Gio::DBus::Connection> &, const Glib::ustring &,
const Glib::ustring &);
void onVanished(const Glib::RefPtr<Gio::DBus::Connection> &, const Glib::ustring &);
void prepareForSleep_cb(const Glib::RefPtr<Gio::DBus::Connection> &connection,
const Glib::ustring &sender_name, const Glib::ustring &object_path,
const Glib::ustring &interface_name, const Glib::ustring &signal_name,
const Glib::VariantContainerBase &parameters);

// UPower callbacks
static void deviceAdded_cb(UpClient *client, UpDevice *device, gpointer data);
static void deviceRemoved_cb(UpClient *client, const gchar *objectPath, gpointer data);
static void deviceNotify_cb(UpDevice *device, GParamSpec *pspec, gpointer user_data);

std::mutex mutex_;
std::function<void(bool)> notify_cb_;

// DBUS variables
guint watcherID_;
Glib::RefPtr<Gio::DBus::Connection> conn_;
guint subscrID_{0u};

// UPower variables
UpClient *upClient_;
typedef std::unordered_map<std::string, upDevice_output> Devices;
Devices devices_;
bool upRunning_{true};

bool sleeping_;
};

} // namespace waybar::util
3 changes: 2 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ src_files = files(
'src/util/rewrite_string.cpp',
'src/util/gtk_icon.cpp',
'src/util/regex_collection.cpp',
'src/util/css_reload_helper.cpp'
'src/util/css_reload_helper.cpp',
'src/util/upower_backend.cpp'
)

man_files = files(
Expand Down
48 changes: 9 additions & 39 deletions src/modules/battery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,10 @@

#include <iostream>
waybar::modules::Battery::Battery(const std::string& id, const Bar& bar, const Json::Value& config)
: ALabel(config, "battery", id, "{capacity}%", 60), bar_(bar) {
: ALabel(config, "battery", id, "{capacity}%", 60),
bar_(bar),
upower_backend_([this](bool) { dp.emit(); }) {
#if defined(__linux__)
battery_watch_fd_ = inotify_init1(IN_CLOEXEC);
if (battery_watch_fd_ == -1) {
throw std::runtime_error("Unable to listen batteries.");
}

global_watch_fd_ = inotify_init1(IN_CLOEXEC);
if (global_watch_fd_ == -1) {
throw std::runtime_error("Unable to listen batteries.");
Expand All @@ -38,15 +35,7 @@ waybar::modules::Battery::~Battery() {
}
close(global_watch_fd_);

for (auto it = batteries_.cbegin(), next_it = it; it != batteries_.cend(); it = next_it) {
++next_it;
auto watch_id = (*it).second;
if (watch_id >= 0) {
inotify_rm_watch(battery_watch_fd_, watch_id);
}
batteries_.erase(it);
}
close(battery_watch_fd_);
batteries_.clear();
#endif
}

Expand All @@ -64,20 +53,11 @@ void waybar::modules::Battery::worker() {
dp.emit();
thread_timer_.sleep_for(interval_);
};
thread_ = [this] {
struct inotify_event event = {0};
int nbytes = read(battery_watch_fd_, &event, sizeof(event));
if (nbytes != sizeof(event) || event.mask & IN_IGNORED) {
thread_.stop();
return;
}
dp.emit();
};
thread_battery_update_ = [this] {
struct inotify_event event = {0};
int nbytes = read(global_watch_fd_, &event, sizeof(event));
if (nbytes != sizeof(event) || event.mask & IN_IGNORED) {
thread_.stop();
thread_battery_update_.stop();
return;
}
refreshBatteries();
Expand All @@ -92,7 +72,7 @@ void waybar::modules::Battery::refreshBatteries() {
// Mark existing list of batteries as not necessarily found
std::map<fs::path, bool> check_map;
for (auto const& bat : batteries_) {
check_map[bat.first] = false;
check_map[bat] = false;
}

try {
Expand Down Expand Up @@ -124,13 +104,8 @@ void waybar::modules::Battery::refreshBatteries() {
check_map[node.path()] = true;
auto search = batteries_.find(node.path());
if (search == batteries_.end()) {
// We've found a new battery save it and start listening for events
auto event_path = (node.path() / "uevent");
auto wd = inotify_add_watch(battery_watch_fd_, event_path.c_str(), IN_ACCESS);
if (wd < 0) {
throw std::runtime_error("Could not watch events for " + node.path().string());
}
batteries_[node.path()] = wd;
// We've found a new battery save it
batteries_.insert(node.path());
}
}
}
Expand All @@ -156,10 +131,6 @@ void waybar::modules::Battery::refreshBatteries() {
// Remove any batteries that are no longer present and unwatch them
for (auto const& check : check_map) {
if (!check.second) {
auto watch_id = batteries_[check.first];
if (watch_id >= 0) {
inotify_rm_watch(battery_watch_fd_, watch_id);
}
batteries_.erase(check.first);
}
}
Expand Down Expand Up @@ -258,8 +229,7 @@ waybar::modules::Battery::getInfos() {
float mainBatHealthPercent = 0.0F;

std::string status = "Unknown";
for (auto const& item : batteries_) {
auto bat = item.first;
for (auto const& bat : batteries_) {
std::string _status;

/* Check for adapter status if battery is not available */
Expand Down
Loading