From bd8b215416cdca6ed0c929c18cede7dfb907edf0 Mon Sep 17 00:00:00 2001 From: Bartel Sielski Date: Mon, 18 Mar 2024 11:47:43 +0100 Subject: [PATCH 1/2] upower: Add 'low' and 'critical' CSS classes Add secondary CSS class based on the 'warning_level' field reported by UPower over D-Bus. This makes it possible to add custom styling when the battery is near empty. --- include/modules/upower/upower.hpp | 1 + src/modules/upower/upower.cpp | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/include/modules/upower/upower.hpp b/include/modules/upower/upower.hpp index d763259b..8cea8c42 100644 --- a/include/modules/upower/upower.hpp +++ b/include/modules/upower/upower.hpp @@ -71,6 +71,7 @@ class UPower : public AModule { GDBusConnection *login1_connection; std::unique_ptr upower_tooltip; std::string lastStatus; + const char *lastWarningLevel; bool showAltText; bool showIcon = true; bool upowerRunning; diff --git a/src/modules/upower/upower.cpp b/src/modules/upower/upower.cpp index 3554d43b..c31f9ea7 100644 --- a/src/modules/upower/upower.cpp +++ b/src/modules/upower/upower.cpp @@ -8,6 +8,17 @@ #include "gtkmm/tooltip.h" #include "util/gtk_icon.hpp" +static const char* getDeviceWarningLevel(UpDeviceLevel level) { + switch (level) { + case UP_DEVICE_LEVEL_CRITICAL: + return "critical"; + case UP_DEVICE_LEVEL_LOW: + return "low"; + default: + return nullptr; + } +} + namespace waybar::modules::upower { UPower::UPower(const std::string& id, const Json::Value& config) : AModule(config, "upower", id), @@ -306,6 +317,7 @@ auto UPower::update() -> void { UpDeviceKind kind; UpDeviceState state; + UpDeviceLevel level = UP_DEVICE_LEVEL_UNKNOWN; double percentage; gint64 time_empty; gint64 time_full; @@ -318,7 +330,7 @@ auto UPower::update() -> void { if (displayDevice) { g_object_get(displayDevice, "kind", &kind, "state", &state, "percentage", &percentage, "icon-name", &icon_name, "time-to-empty", &time_empty, "time-to-full", &time_full, - NULL); + "warning-level", &level, NULL); /* Every Device which is handled by Upower and which is not * UP_DEVICE_KIND_UNKNOWN (0) or UP_DEVICE_KIND_LINE_POWER (1) is a Battery */ @@ -338,6 +350,15 @@ auto UPower::update() -> void { } lastStatus = status; + const char* warning_level = getDeviceWarningLevel(level); + if (lastWarningLevel && box_.get_style_context()->has_class(lastWarningLevel)) { + box_.get_style_context()->remove_class(lastWarningLevel); + } + if (warning_level && !box_.get_style_context()->has_class(warning_level)) { + box_.get_style_context()->add_class(warning_level); + } + lastWarningLevel = warning_level; + if (devices.size() == 0 && !displayDeviceValid && hideIfEmpty) { event_box_.set_visible(false); // Call parent update From bbb69bd977745fc9b4a5b7da345426da208423f3 Mon Sep 17 00:00:00 2001 From: Bartel Sielski Date: Mon, 18 Mar 2024 12:47:36 +0100 Subject: [PATCH 2/2] upower: Initialize variables There are code paths in which some of these variables were used but not initialized, causing undefined behavior. --- src/modules/upower/upower.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/modules/upower/upower.cpp b/src/modules/upower/upower.cpp index c31f9ea7..ad4c4732 100644 --- a/src/modules/upower/upower.cpp +++ b/src/modules/upower/upower.cpp @@ -315,12 +315,12 @@ auto UPower::update() -> void { return; } - UpDeviceKind kind; - UpDeviceState state; + UpDeviceKind kind = UP_DEVICE_KIND_UNKNOWN; + UpDeviceState state = UP_DEVICE_STATE_UNKNOWN; UpDeviceLevel level = UP_DEVICE_LEVEL_UNKNOWN; - double percentage; - gint64 time_empty; - gint64 time_full; + double percentage = 0.0; + gint64 time_empty = 0; + gint64 time_full = 0; gchar* icon_name{(char*)'\0'}; std::string percentString{""}; std::string time_format{""};