From 2ca4dcac490c0d787db510bd2c70b6bafe05be52 Mon Sep 17 00:00:00 2001 From: Erik Reider Date: Fri, 25 Mar 2022 14:52:12 +0100 Subject: [PATCH 1/9] Set box widget name to "upower" --- src/modules/upower/upower.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/upower/upower.cpp b/src/modules/upower/upower.cpp index f628514..c9c2168 100644 --- a/src/modules/upower/upower.cpp +++ b/src/modules/upower/upower.cpp @@ -22,6 +22,7 @@ UPower::UPower(const std::string& id, const Json::Value& config) showAltText(false) { box_.pack_start(icon_); box_.pack_start(label_); + box_.set_name(name_); event_box_.add(box_); // Icon Size From 9dc09d2702c0e075a2acd2cf56e2882d213042c2 Mon Sep 17 00:00:00 2001 From: Erik Reider Date: Fri, 25 Mar 2022 14:53:46 +0100 Subject: [PATCH 2/9] Added upower man page into man_files meson variable --- meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/meson.build b/meson.build index e9daeca..73e74a5 100644 --- a/meson.build +++ b/meson.build @@ -359,6 +359,7 @@ if scdoc.found() 'waybar-wlr-workspaces.5.scd', 'waybar-bluetooth.5.scd', 'waybar-sndio.5.scd', + 'waybar-upower.5.scd', ] if (giounix.found() and not get_option('logind').disabled()) From d1d73b50032dd18b7e3f2b2fad30530a9dc2204b Mon Sep 17 00:00:00 2001 From: Erik Reider Date: Fri, 25 Mar 2022 14:57:04 +0100 Subject: [PATCH 3/9] Added missing "fulL" and "empty" CSS classes --- man/waybar-upower.5.scd | 2 ++ src/modules/upower/upower.cpp | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/man/waybar-upower.5.scd b/man/waybar-upower.5.scd index e6f6307..99c015a 100644 --- a/man/waybar-upower.5.scd +++ b/man/waybar-upower.5.scd @@ -71,4 +71,6 @@ depending on the charging state. - *#upower* - *#upower.charging* - *#upower.discharging* +- *#upower.full* +- *#upower.empty* - *#upower.unknown-status* diff --git a/src/modules/upower/upower.cpp b/src/modules/upower/upower.cpp index c9c2168..00b69aa 100644 --- a/src/modules/upower/upower.cpp +++ b/src/modules/upower/upower.cpp @@ -227,11 +227,13 @@ const std::string UPower::getDeviceStatus(UpDeviceState& state) { case UP_DEVICE_STATE_CHARGING: case UP_DEVICE_STATE_PENDING_CHARGE: return "charging"; - case UP_DEVICE_STATE_EMPTY: - case UP_DEVICE_STATE_FULLY_CHARGED: case UP_DEVICE_STATE_DISCHARGING: case UP_DEVICE_STATE_PENDING_DISCHARGE: return "discharging"; + case UP_DEVICE_STATE_FULLY_CHARGED: + return "full"; + case UP_DEVICE_STATE_EMPTY: + return "empty"; default: return "unknown-status"; } From 0140606226e4ed24bbd61f28a46735ae27176ad6 Mon Sep 17 00:00:00 2001 From: Erik Reider <35975961+ErikReider@users.noreply.github.com> Date: Fri, 25 Mar 2022 16:57:25 +0100 Subject: [PATCH 4/9] Fixed segfault on upower service restart --- src/modules/upower/upower.cpp | 2 +- src/modules/upower/upower_tooltip.cpp | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/modules/upower/upower.cpp b/src/modules/upower/upower.cpp index 00b69aa..3032679 100644 --- a/src/modules/upower/upower.cpp +++ b/src/modules/upower/upower.cpp @@ -347,7 +347,7 @@ auto UPower::update() -> void { label_.set_markup(onlySpaces ? "" : label_format); // Set icon - if (!Gtk::IconTheme::get_default()->has_icon(icon_name)) { + if (icon_name == NULL || !Gtk::IconTheme::get_default()->has_icon(icon_name)) { icon_name = (char*)"battery-missing-symbolic"; } icon_.set_from_icon_name(icon_name, Gtk::ICON_SIZE_INVALID); diff --git a/src/modules/upower/upower_tooltip.cpp b/src/modules/upower/upower_tooltip.cpp index 644b8e0..8aaba92 100644 --- a/src/modules/upower/upower_tooltip.cpp +++ b/src/modules/upower/upower_tooltip.cpp @@ -62,7 +62,9 @@ uint UPowerTooltip::updateTooltip(Devices& devices) { NULL); // Skip Line_Power and BAT0 devices - if (kind == UP_DEVICE_KIND_LINE_POWER || strcmp(native_path, "BAT0") == 0) continue; + if (kind == UP_DEVICE_KIND_LINE_POWER || native_path == NULL || strlen(native_path) == 0 || + strcmp(native_path, "BAT0") == 0) + continue; Gtk::Box* modelBox = new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL); box->add(*modelBox); @@ -77,6 +79,7 @@ uint UPowerTooltip::updateTooltip(Devices& devices) { modelBox->add(*deviceIcon); // Set model + if (model == NULL) model = (gchar*)""; Gtk::Label* modelLabel = new Gtk::Label(model); modelBox->add(*modelLabel); @@ -86,7 +89,7 @@ uint UPowerTooltip::updateTooltip(Devices& devices) { // Set icon Gtk::Image* icon = new Gtk::Image(); icon->set_pixel_size(iconSize); - if (!Gtk::IconTheme::get_default()->has_icon(icon_name)) { + if (icon_name == NULL || !Gtk::IconTheme::get_default()->has_icon(icon_name)) { icon_name = (char*)"battery-missing-symbolic"; } icon->set_from_icon_name(icon_name, Gtk::ICON_SIZE_INVALID); From e0f0931e2db38f01375895614dc385cba099c0cd Mon Sep 17 00:00:00 2001 From: Erik Reider <35975961+ErikReider@users.noreply.github.com> Date: Fri, 25 Mar 2022 17:27:36 +0100 Subject: [PATCH 5/9] Hide module if UPower service isn't running --- include/modules/upower/upower.hpp | 6 ++++++ src/modules/upower/upower.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/include/modules/upower/upower.hpp b/include/modules/upower/upower.hpp index 5b4d2f5..ee70fbe 100644 --- a/include/modules/upower/upower.hpp +++ b/include/modules/upower/upower.hpp @@ -34,6 +34,10 @@ class UPower : public AModule { const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data); + static void upowerAppear(GDBusConnection *conn, const gchar *name, const gchar *name_owner, + gpointer data); + static void upowerDisappear(GDBusConnection *connection, const gchar *name, gpointer user_data); + void removeDevice(const gchar *objectPath); void addDevice(UpDevice *device); void setDisplayDevice(); @@ -67,6 +71,8 @@ class UPower : public AModule { UPowerTooltip *upower_tooltip; std::string lastStatus; bool showAltText; + bool upowerRunning; + guint upowerWatcher_id; }; } // namespace waybar::modules::upower diff --git a/src/modules/upower/upower.cpp b/src/modules/upower/upower.cpp index 3032679..8750c86 100644 --- a/src/modules/upower/upower.cpp +++ b/src/modules/upower/upower.cpp @@ -68,6 +68,14 @@ UPower::UPower(const std::string& id, const Json::Value& config) box_.signal_query_tooltip().connect(sigc::mem_fun(*this, &UPower::show_tooltip_callback)); } + upowerWatcher_id = g_bus_watch_name(G_BUS_TYPE_SYSTEM, + "org.freedesktop.UPower", + G_BUS_NAME_WATCHER_FLAGS_AUTO_START, + upowerAppear, + upowerDisappear, + this, + NULL); + GError* error = NULL; client = up_client_new_full(NULL, &error); if (client == NULL) { @@ -106,6 +114,7 @@ UPower::~UPower() { g_dbus_connection_signal_unsubscribe(login1_connection, login1_id); login1_id = 0; } + g_bus_unwatch_name(upowerWatcher_id); removeDevices(); } @@ -142,6 +151,17 @@ void UPower::prepareForSleep_cb(GDBusConnection* system_bus, const gchar* sender } } } +void UPower::upowerAppear(GDBusConnection* conn, const gchar* name, const gchar* name_owner, + gpointer data) { + UPower* up = static_cast(data); + up->upowerRunning = true; + up->dp.emit(); +} +void UPower::upowerDisappear(GDBusConnection* conn, const gchar* name, gpointer data) { + UPower* up = static_cast(data); + up->upowerRunning = false; + up->dp.emit(); +} void UPower::removeDevice(const gchar* objectPath) { std::lock_guard guard(m_Mutex); @@ -261,6 +281,14 @@ std::string UPower::timeToString(gint64 time) { auto UPower::update() -> void { std::lock_guard guard(m_Mutex); + // Hide everything if the UPower service is not running + if (!upowerRunning) { + event_box_.set_visible(false); + // Call parent update + AModule::update(); + return; + } + UpDeviceKind kind; UpDeviceState state; double percentage; From a7ed1ed570dd14383a59b88f44d7e129c94f66de Mon Sep 17 00:00:00 2001 From: Erik Reider <35975961+ErikReider@users.noreply.github.com> Date: Fri, 25 Mar 2022 17:35:37 +0100 Subject: [PATCH 6/9] Don't call dp.emit() when UPower service active status changes --- src/modules/upower/upower.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/modules/upower/upower.cpp b/src/modules/upower/upower.cpp index 8750c86..83d3df2 100644 --- a/src/modules/upower/upower.cpp +++ b/src/modules/upower/upower.cpp @@ -155,12 +155,12 @@ void UPower::upowerAppear(GDBusConnection* conn, const gchar* name, const gchar* gpointer data) { UPower* up = static_cast(data); up->upowerRunning = true; - up->dp.emit(); + up->event_box_.set_visible(true); } void UPower::upowerDisappear(GDBusConnection* conn, const gchar* name, gpointer data) { UPower* up = static_cast(data); up->upowerRunning = false; - up->dp.emit(); + up->event_box_.set_visible(false); } void UPower::removeDevice(const gchar* objectPath) { @@ -281,13 +281,8 @@ std::string UPower::timeToString(gint64 time) { auto UPower::update() -> void { std::lock_guard guard(m_Mutex); - // Hide everything if the UPower service is not running - if (!upowerRunning) { - event_box_.set_visible(false); - // Call parent update - AModule::update(); - return; - } + // Don't update widget if the UPower service isn't running + if (!upowerRunning) return; UpDeviceKind kind; UpDeviceState state; From 3a95f8f5996d8020c2f3cf7795476877e0b0e898 Mon Sep 17 00:00:00 2001 From: 0cc4m Date: Sat, 26 Mar 2022 19:42:06 +0100 Subject: [PATCH 7/9] Add battery module fallback for batteries without capacity or with _avg instead of _cur files --- src/modules/battery.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp index c2dc389..59874f7 100644 --- a/src/modules/battery.cpp +++ b/src/modules/battery.cpp @@ -88,8 +88,9 @@ void waybar::modules::Battery::refreshBatteries() { auto dir_name = node.path().filename(); auto bat_defined = config_["bat"].isString(); if (((bat_defined && dir_name == config_["bat"].asString()) || !bat_defined) && - fs::exists(node.path() / "capacity") && fs::exists(node.path() / "uevent") && - fs::exists(node.path() / "status") && fs::exists(node.path() / "type")) { + (fs::exists(node.path() / "capacity") || fs::exists(node.path() / "charge_now")) && + fs::exists(node.path() / "uevent") && fs::exists(node.path() / "status") && + fs::exists(node.path() / "type")) { std::string type; std::ifstream(node.path() / "type") >> type; @@ -168,14 +169,21 @@ const std::tuple waybar::modules::Battery::g // Some battery will report current and charge in μA/μAh. // Scale these by the voltage to get μW/μWh. - if (fs::exists(bat / "current_now")) { + if (fs::exists(bat / "current_now") || fs::exists(bat / "current_avg")) { uint32_t voltage_now; uint32_t current_now; uint32_t charge_now; uint32_t charge_full; uint32_t charge_full_design; - std::ifstream(bat / "voltage_now") >> voltage_now; - std::ifstream(bat / "current_now") >> current_now; + // Some batteries have only *_avg, not *_now + if (fs::exists(bat / "voltage_now")) + std::ifstream(bat / "voltage_now") >> voltage_now; + else + std::ifstream(bat / "voltage_avg") >> voltage_now; + if (fs::exists(bat / "current_now")) + std::ifstream(bat / "current_now") >> current_now; + else + std::ifstream(bat / "current_avg") >> current_now; std::ifstream(bat / "charge_full") >> charge_full; std::ifstream(bat / "charge_full_design") >> charge_full_design; if (fs::exists(bat / "charge_now")) From b086e2f9959a055b2a1d5655d17aed927b16b34a Mon Sep 17 00:00:00 2001 From: Viktar Lukashonak Date: Tue, 29 Mar 2022 12:26:05 +0300 Subject: [PATCH 8/9] Waybar. Issue#1068. Double/Triple events --- include/AModule.hpp | 19 +++++++++++++++++++ src/AModule.cpp | 35 +++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/include/AModule.hpp b/include/AModule.hpp index c9f1ae2..ea73028 100644 --- a/include/AModule.hpp +++ b/include/AModule.hpp @@ -7,6 +7,8 @@ #include "IModule.hpp" +#include + namespace waybar { class AModule : public IModule { @@ -36,6 +38,23 @@ class AModule : public IModule { std::vector pid_; gdouble distance_scrolled_y_; gdouble distance_scrolled_x_; + static const inline std::map, std::string> eventMap_{ + {std::make_pair(1, GdkEventType::GDK_BUTTON_PRESS), "on-click"}, + {std::make_pair(1, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click"}, + {std::make_pair(1, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click"}, + {std::make_pair(2, GdkEventType::GDK_BUTTON_PRESS), "on-click-middle"}, + {std::make_pair(2, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click-middle"}, + {std::make_pair(2, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click-middle"}, + {std::make_pair(3, GdkEventType::GDK_BUTTON_PRESS), "on-click-right"}, + {std::make_pair(3, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click-right"}, + {std::make_pair(3, GdkEventType::GDK_3BUTTON_PRESS), "on-triple-click-right"}, + {std::make_pair(8, GdkEventType::GDK_BUTTON_PRESS), "on-click-backward"}, + {std::make_pair(8, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click-backward"}, + {std::make_pair(8, GdkEventType::GDK_2BUTTON_PRESS), "on-triple-click-backward"}, + {std::make_pair(9, GdkEventType::GDK_BUTTON_PRESS), "on-click-forward"}, + {std::make_pair(9, GdkEventType::GDK_2BUTTON_PRESS), "on-double-click-forward"}, + {std::make_pair(9, GdkEventType::GDK_2BUTTON_PRESS), "on-triple-click-forward"} + }; }; } // namespace waybar diff --git a/src/AModule.cpp b/src/AModule.cpp index 0e0f00e..e65067e 100644 --- a/src/AModule.cpp +++ b/src/AModule.cpp @@ -10,16 +10,24 @@ AModule::AModule(const Json::Value& config, const std::string& name, const std:: , distance_scrolled_y_(0.0) , distance_scrolled_x_(0.0) { // configure events' user commands - if (config_["on-click"].isString() || config_["on-click-middle"].isString() || - config_["on-click-backward"].isString() || config_["on-click-forward"].isString() || - config_["on-click-right"].isString() || enable_click) { + if (enable_click) { event_box_.add_events(Gdk::BUTTON_PRESS_MASK); event_box_.signal_button_press_event().connect(sigc::mem_fun(*this, &AModule::handleToggle)); + } else { + std::map, std::string>::const_iterator it{eventMap_.cbegin()}; + while(it != eventMap_.cend()) { + if (config_[it->second].isString()) { + event_box_.add_events(Gdk::BUTTON_PRESS_MASK); + event_box_.signal_button_press_event().connect(sigc::mem_fun(*this, &AModule::handleToggle)); + break; + } + ++it; + } } if (config_["on-scroll-up"].isString() || config_["on-scroll-down"].isString() || enable_scroll) { event_box_.add_events(Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); event_box_.signal_scroll_event().connect(sigc::mem_fun(*this, &AModule::handleScroll)); - } + } } AModule::~AModule() { @@ -30,7 +38,6 @@ AModule::~AModule() { } } - auto AModule::update() -> void { // Run user-provided update handler if configured if (config_["on-update"].isString()) { @@ -39,18 +46,14 @@ auto AModule::update() -> void { } bool AModule::handleToggle(GdkEventButton* const& e) { - std::string format; - if (config_["on-click"].isString() && e->button == 1) { - format = config_["on-click"].asString(); - } else if (config_["on-click-middle"].isString() && e->button == 2) { - format = config_["on-click-middle"].asString(); - } else if (config_["on-click-right"].isString() && e->button == 3) { - format = config_["on-click-right"].asString(); - } else if (config_["on-click-backward"].isString() && e->button == 8) { - format = config_["on-click-backward"].asString(); - } else if (config_["on-click-forward"].isString() && e->button == 9) { - format = config_["on-click-forward"].asString(); + const std::map, std::string>::const_iterator& rec{eventMap_.find(std::pair(e->button, e->type))}; + std::string format{ (rec != eventMap_.cend()) ? rec->second : std::string{""}}; + + if (!format.empty()) { + if (config_[format].isString()) format = config_[format].asString(); + else format.clear(); } + if (!format.empty()) { pid_.push_back(util::command::forkExec(format)); } From f4cc088d2fa5574632baf47687fa3cad7c9a670f Mon Sep 17 00:00:00 2001 From: Viktar Lukashonak Date: Tue, 29 Mar 2022 12:35:50 +0300 Subject: [PATCH 9/9] Waybar. Issue#1068. Double/Triple events. Removed unnecessary including --- include/AModule.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/AModule.hpp b/include/AModule.hpp index ea73028..91606f5 100644 --- a/include/AModule.hpp +++ b/include/AModule.hpp @@ -7,8 +7,6 @@ #include "IModule.hpp" -#include - namespace waybar { class AModule : public IModule {