diff --git a/include/modules/cpu.hpp b/include/modules/cpu.hpp index 7a703364..6a9b5864 100644 --- a/include/modules/cpu.hpp +++ b/include/modules/cpu.hpp @@ -22,7 +22,9 @@ class Cpu : public ALabel { private: uint16_t getCpuLoad(); std::tuple getCpuUsage(); + std::tuple getCpuFrequency(); std::vector> parseCpuinfo(); + std::vector parseCpuFrequencies(); std::vector> prev_times_; diff --git a/man/waybar-cpu.5.scd b/man/waybar-cpu.5.scd index c8b12e26..fbf6206f 100644 --- a/man/waybar-cpu.5.scd +++ b/man/waybar-cpu.5.scd @@ -79,6 +79,12 @@ The *cpu* module displays the current cpu utilization. *{usage}*: Current cpu usage. +*{avg_frequency}*: Current cpu average frequency (based on all cores) in GHz. + +*{max_frequency}*: Current cpu max frequency (based on the core with the highest frequency) in GHz. + +*{min_frequency}*: Current cpu min frequency (based on the core with the lowest frequency) in GHz. + # EXAMPLE ``` diff --git a/src/modules/cpu/bsd.cpp b/src/modules/cpu/bsd.cpp index 73ab1e8a..10f18385 100644 --- a/src/modules/cpu/bsd.cpp +++ b/src/modules/cpu/bsd.cpp @@ -95,3 +95,7 @@ std::vector> waybar::modules::Cpu::parseCpuinfo() { free(cp_time); return cpuinfo; } + +std::vector waybar::modules::Cpu::parseCpuFrequencies() { + throw std::runtime_error("Cpu frequency is not implemented on BSD."); +} diff --git a/src/modules/cpu/common.cpp b/src/modules/cpu/common.cpp index e86d10a0..74f1e404 100644 --- a/src/modules/cpu/common.cpp +++ b/src/modules/cpu/common.cpp @@ -12,6 +12,7 @@ auto waybar::modules::Cpu::update() -> void { // TODO: as creating dynamic fmt::arg arrays is buggy we have to calc both auto cpu_load = getCpuLoad(); auto [cpu_usage, tooltip] = getCpuUsage(); + auto [max_frequency, min_frequency, avg_frequency] = getCpuFrequency(); if (tooltipEnabled()) { label_.set_tooltip_text(tooltip); } @@ -25,7 +26,12 @@ auto waybar::modules::Cpu::update() -> void { event_box_.hide(); } else { event_box_.show(); - label_.set_markup(fmt::format(format, fmt::arg("load", cpu_load), fmt::arg("usage", cpu_usage))); + label_.set_markup(fmt::format(format, + fmt::arg("load", cpu_load), + fmt::arg("usage", cpu_usage), + fmt::arg("max_frequency", max_frequency), + fmt::arg("min_frequency", min_frequency), + fmt::arg("avg_frequency", avg_frequency))); } // Call parent update @@ -64,3 +70,16 @@ std::tuple waybar::modules::Cpu::getCpuUsage() { prev_times_ = curr_times; return {usage, tooltip}; } + +std::tuple waybar::modules::Cpu::getCpuFrequency() { + std::vector frequencies = parseCpuFrequencies(); + auto [min, max] = std::minmax_element(std::begin(frequencies), std::end(frequencies)); + float avg_frequency = std::accumulate(std::begin(frequencies), std::end(frequencies), 0.0) / frequencies.size(); + + // Round frequencies with double decimal precision to get GHz + float max_frequency = std::ceil(*max / 10.0) / 100.0; + float min_frequency = std::ceil(*min / 10.0) / 100.0; + avg_frequency = std::ceil(avg_frequency / 10.0) / 100.0; + + return { max_frequency, min_frequency, avg_frequency }; +} diff --git a/src/modules/cpu/linux.cpp b/src/modules/cpu/linux.cpp index 9f1734fb..b69f71a7 100644 --- a/src/modules/cpu/linux.cpp +++ b/src/modules/cpu/linux.cpp @@ -27,3 +27,24 @@ std::vector> waybar::modules::Cpu::parseCpuinfo() { } return cpuinfo; } + +std::vector waybar::modules::Cpu::parseCpuFrequencies() { + const std::string file_path_ = "/proc/cpuinfo"; + std::ifstream info(file_path_); + if (!info.is_open()) { + throw std::runtime_error("Can't open " + file_path_); + } + std::vector frequencies; + std::string line; + while (getline(info, line)) { + if (line.substr(0, 7).compare("cpu MHz") != 0) { + continue; + } + + std::string frequency_str = line.substr(line.find(":") + 2); + float frequency = std::strtol(frequency_str.c_str(), nullptr, 10); + frequencies.push_back(frequency); + } + info.close(); + return frequencies; +}