From feb6dfb9d66006889018ba250807e1e0dfa69ff8 Mon Sep 17 00:00:00 2001 From: Jeevitha Kannan K S Date: Fri, 21 Mar 2025 16:23:39 +0530 Subject: [PATCH 1/2] feat(power-profiles-daemon): split driver into cpu driver and platform driver --- include/modules/power_profiles_daemon.hpp | 5 +++-- man/waybar-power-profiles-daemon.5.scd | 6 ++--- resources/config.jsonc | 2 +- src/modules/power_profiles_daemon.cpp | 27 ++++++++++++++++++----- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/include/modules/power_profiles_daemon.hpp b/include/modules/power_profiles_daemon.hpp index a2bd3858..c43ccd78 100644 --- a/include/modules/power_profiles_daemon.hpp +++ b/include/modules/power_profiles_daemon.hpp @@ -9,9 +9,10 @@ namespace waybar::modules { struct Profile { std::string name; - std::string driver; + std::string cpuDriver; + std::string platformDriver; - Profile(std::string n, std::string d) : name(std::move(n)), driver(std::move(d)) {} + Profile(std::string n, std::string cd, std::string pd) : name(std::move(n)), cpuDriver(std::move(cd)), platformDriver(std::move(pd)) {} }; class PowerProfilesDaemon : public ALabel { diff --git a/man/waybar-power-profiles-daemon.5.scd b/man/waybar-power-profiles-daemon.5.scd index 6488767b..c1b2f5b8 100644 --- a/man/waybar-power-profiles-daemon.5.scd +++ b/man/waybar-power-profiles-daemon.5.scd @@ -25,7 +25,7 @@ $XDG_CONFIG_HOME/waybar/config :[ Message displayed on the bar. {icon} and {profile} are respectively substituted with the icon representing the active profile and its full name. |[ *tooltip-format* :[ string -:[ "Power profile: {profile}\\nDriver: {driver}" +:[ "Power profile: {profile}\\nCPU driver: {cpu_driver}\\nPlatform driver: {platform_driver}" :[ Messaged displayed in the module tooltip. {icon} and {profile} are respectively substituted with the icon representing the active profile and its full name. |[ *tooltip* :[ bool @@ -51,7 +51,7 @@ Compact display (default config): ``` "power-profiles-daemon": { "format": "{icon}", - "tooltip-format": "Power profile: {profile}\nDriver: {driver}", + "tooltip-format": "Power profile: {profile}\nCPU driver: {cpu_driver}\nPlatform driver: {platform_driver}", "tooltip": true, "format-icons": { "default": "", @@ -67,7 +67,7 @@ Display the full profile name: ``` "power-profiles-daemon": { "format": "{icon} {profile}", - "tooltip-format": "Power profile: {profile}\nDriver: {driver}", + "tooltip-format": "Power profile: {profile}\nCPU driver: {cpu_driver}\nPlatform driver: {platform_driver}", "tooltip": true, "format-icons": { "default": "", diff --git a/resources/config.jsonc b/resources/config.jsonc index 6ac1aa50..3b1ae160 100644 --- a/resources/config.jsonc +++ b/resources/config.jsonc @@ -151,7 +151,7 @@ }, "power-profiles-daemon": { "format": "{icon}", - "tooltip-format": "Power profile: {profile}\nDriver: {driver}", + "tooltip-format": "Power profile: {profile}\nCPU driver: {cpu_driver}\nPlatform driver: {platform_driver}", "tooltip": true, "format-icons": { "default": "", diff --git a/src/modules/power_profiles_daemon.cpp b/src/modules/power_profiles_daemon.cpp index 3ae3ae83..b2876c9e 100644 --- a/src/modules/power_profiles_daemon.cpp +++ b/src/modules/power_profiles_daemon.cpp @@ -12,7 +12,7 @@ PowerProfilesDaemon::PowerProfilesDaemon(const std::string& id, const Json::Valu if (config_["tooltip-format"].isString()) { tooltipFormat_ = config_["tooltip-format"].asString(); } else { - tooltipFormat_ = "Power profile: {profile}\nDriver: {driver}"; + tooltipFormat_ = "Power profile: {profile}\nCpuDriver: {cpu_driver}"; } // Fasten your seatbelt, we're up for quite a ride. The rest of the // init is performed asynchronously. There's 2 callbacks involved. @@ -95,15 +95,29 @@ void PowerProfilesDaemon::populateInitState() { powerProfilesProxy_->get_cached_property(profilesVariant, "Profiles"); for (auto& variantDict : profilesVariant.get()) { Glib::ustring name; - Glib::ustring driver; + Glib::ustring cpuDriver; + Glib::ustring platformDriver; if (auto p = variantDict.find("Profile"); p != variantDict.end()) { name = p->second.get(); } - if (auto d = variantDict.find("Driver"); d != variantDict.end()) { - driver = d->second.get(); + if (auto cd = variantDict.find("CpuDriver"); cd != variantDict.end()) { + cpuDriver = cd->second.get(); } + if (auto pd = variantDict.find("PlatformDriver"); pd != variantDict.end()) { + platformDriver = pd->second.get(); + } + + if (cpuDriver.empty()) { + cpuDriver = "Unavailable"; + spdlog::warn("Cannot find power profiles daemon cpu driver."); + } + if (platformDriver.empty()) { + platformDriver = "Unavailable"; + spdlog::warn("Cannot find power profiles daemon platform driver."); + } + if (!name.empty()) { - availableProfiles_.emplace_back(std::move(name), std::move(driver)); + availableProfiles_.emplace_back(std::move(name), std::move(cpuDriver), std::move(platformDriver)); } else { spdlog::error( "Power profiles daemon: power-profiles-daemon sent us an empty power profile name. " @@ -153,7 +167,8 @@ auto PowerProfilesDaemon::update() -> void { // Set label fmt::dynamic_format_arg_store store; store.push_back(fmt::arg("profile", profile.name)); - store.push_back(fmt::arg("driver", profile.driver)); + store.push_back(fmt::arg("cpu_driver", profile.cpuDriver)); + store.push_back(fmt::arg("platform_driver", profile.platformDriver)); store.push_back(fmt::arg("icon", getIcon(0, profile.name))); label_.set_markup(fmt::vformat(format_, store)); if (tooltipEnabled()) { From fe0e1c139bc4c6044f4592d708063a63d3725ffa Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 3 Jul 2026 22:11:51 +0200 Subject: [PATCH 2/2] power-profiles-daemon: preserve backward compatibility for driver Keep the {driver} placeholder working and support older power-profiles-daemon versions that only expose a single Driver DBus property, while still reading the new CpuDriver/PlatformDriver fields. - Read the legacy Driver property and fall back to it when CpuDriver or PlatformDriver are missing (older daemon). - Derive {driver} from CpuDriver when the daemon no longer exposes Driver (recent daemon), so existing configs using {driver} keep working. - Align the default tooltip-format in the constructor with the documented default. --- include/modules/power_profiles_daemon.hpp | 10 ++++++- man/waybar-power-profiles-daemon.5.scd | 2 +- src/modules/power_profiles_daemon.cpp | 35 +++++++++++++++++++---- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/include/modules/power_profiles_daemon.hpp b/include/modules/power_profiles_daemon.hpp index eb636662..1aa087a4 100644 --- a/include/modules/power_profiles_daemon.hpp +++ b/include/modules/power_profiles_daemon.hpp @@ -9,10 +9,18 @@ namespace waybar::modules { struct Profile { std::string name; + // Legacy driver field, kept for backward compatibility with the + // `{driver}` format placeholder and with older power-profiles-daemon + // versions that only expose a single `Driver` DBus property. + std::string driver; std::string cpuDriver; std::string platformDriver; - Profile(std::string n, std::string cd, std::string pd) : name(std::move(n)), cpuDriver(std::move(cd)), platformDriver(std::move(pd)) {} + Profile(std::string n, std::string d, std::string cd, std::string pd) + : name(std::move(n)), + driver(std::move(d)), + cpuDriver(std::move(cd)), + platformDriver(std::move(pd)) {} }; class PowerProfilesDaemon : public ALabel { diff --git a/man/waybar-power-profiles-daemon.5.scd b/man/waybar-power-profiles-daemon.5.scd index c1b2f5b8..da331795 100644 --- a/man/waybar-power-profiles-daemon.5.scd +++ b/man/waybar-power-profiles-daemon.5.scd @@ -26,7 +26,7 @@ $XDG_CONFIG_HOME/waybar/config |[ *tooltip-format* :[ string :[ "Power profile: {profile}\\nCPU driver: {cpu_driver}\\nPlatform driver: {platform_driver}" -:[ Messaged displayed in the module tooltip. {icon} and {profile} are respectively substituted with the icon representing the active profile and its full name. +:[ Messaged displayed in the module tooltip. {icon} and {profile} are respectively substituted with the icon representing the active profile and its full name. {cpu_driver} and {platform_driver} are substituted with the CPU and platform drivers reported by recent power-profiles-daemon versions. {driver} is kept for backward compatibility: it resolves to the legacy single driver on older daemons and falls back to the CPU driver on recent ones. |[ *tooltip* :[ bool :[ true diff --git a/src/modules/power_profiles_daemon.cpp b/src/modules/power_profiles_daemon.cpp index b272805e..d7eb5bcd 100644 --- a/src/modules/power_profiles_daemon.cpp +++ b/src/modules/power_profiles_daemon.cpp @@ -12,7 +12,8 @@ PowerProfilesDaemon::PowerProfilesDaemon(const std::string& id, const Json::Valu if (config_["tooltip-format"].isString()) { tooltipFormat_ = config_["tooltip-format"].asString(); } else { - tooltipFormat_ = "Power profile: {profile}\nCpuDriver: {cpu_driver}"; + tooltipFormat_ = + "Power profile: {profile}\nCPU driver: {cpu_driver}\nPlatform driver: {platform_driver}"; } // Fasten your seatbelt, we're up for quite a ride. The rest of the // init is performed asynchronously. There's 2 callbacks involved. @@ -95,11 +96,17 @@ void PowerProfilesDaemon::populateInitState() { powerProfilesProxy_->get_cached_property(profilesVariant, "Profiles"); for (auto& variantDict : profilesVariant.get()) { Glib::ustring name; + // Legacy single `Driver` property, still exposed by older + // power-profiles-daemon versions. + Glib::ustring driver; Glib::ustring cpuDriver; Glib::ustring platformDriver; if (auto p = variantDict.find("Profile"); p != variantDict.end()) { name = p->second.get(); } + if (auto d = variantDict.find("Driver"); d != variantDict.end()) { + driver = d->second.get(); + } if (auto cd = variantDict.find("CpuDriver"); cd != variantDict.end()) { cpuDriver = cd->second.get(); } @@ -107,17 +114,33 @@ void PowerProfilesDaemon::populateInitState() { platformDriver = pd->second.get(); } + // Recent power-profiles-daemon versions split the single `Driver` + // property into `CpuDriver` and `PlatformDriver`. When talking to an + // older daemon that only exposes `Driver`, fall back to it so the new + // {cpu_driver}/{platform_driver} placeholders still resolve. if (cpuDriver.empty()) { - cpuDriver = "Unavailable"; - spdlog::warn("Cannot find power profiles daemon cpu driver."); + cpuDriver = driver; } if (platformDriver.empty()) { + platformDriver = driver; + } + // Conversely, keep the legacy {driver} placeholder working against a + // recent daemon that no longer exposes `Driver` by deriving it from + // the CPU driver. + if (driver.empty()) { + driver = cpuDriver; + } + + if (driver.empty()) { + driver = "Unavailable"; + cpuDriver = "Unavailable"; platformDriver = "Unavailable"; - spdlog::warn("Cannot find power profiles daemon platform driver."); + spdlog::warn("Cannot find power profiles daemon driver."); } if (!name.empty()) { - availableProfiles_.emplace_back(std::move(name), std::move(cpuDriver), std::move(platformDriver)); + availableProfiles_.emplace_back(std::move(name), std::move(driver), std::move(cpuDriver), + std::move(platformDriver)); } else { spdlog::error( "Power profiles daemon: power-profiles-daemon sent us an empty power profile name. " @@ -167,6 +190,8 @@ auto PowerProfilesDaemon::update() -> void { // Set label fmt::dynamic_format_arg_store store; store.push_back(fmt::arg("profile", profile.name)); + // Legacy placeholder, kept for backward compatibility with existing configs. + store.push_back(fmt::arg("driver", profile.driver)); store.push_back(fmt::arg("cpu_driver", profile.cpuDriver)); store.push_back(fmt::arg("platform_driver", profile.platformDriver)); store.push_back(fmt::arg("icon", getIcon(0, profile.name)));