diff --git a/include/modules/cpu.hpp b/include/modules/cpu.hpp index 71d2c51..a371c32 100644 --- a/include/modules/cpu.hpp +++ b/include/modules/cpu.hpp @@ -1,9 +1,11 @@ #pragma once #include +#include #include #include #include +#include #include "util/chrono.hpp" #include "ALabel.hpp" @@ -15,8 +17,11 @@ class Cpu : public ALabel { auto update() -> void; private: static inline const std::string data_dir_ = "/proc/stat"; - std::vector< std::tuple > parseCpuinfo(); - std::vector< std::tuple > prevTimes_; + uint16_t getCpuLoad(); + std::tuple getCpuUsage(); + std::vector> parseCpuinfo(); + + std::vector> prev_times_; waybar::util::SleeperThread thread_; }; diff --git a/resources/config b/resources/config index 8cfbd4d..0f7d2b3 100644 --- a/resources/config +++ b/resources/config @@ -37,7 +37,7 @@ "format-alt": "{:%Y-%m-%d}" }, "cpu": { - "format": "{}% " + "format": "{usage}% " }, "memory": { "format": "{}% " diff --git a/src/client.cpp b/src/client.cpp index 8c38ce3..ab8b1ed 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1,4 +1,5 @@ #include "client.hpp" +#include waybar::Client::Client(int argc, char* argv[]) : gtk_app(Gtk::Application::create(argc, argv, "fr.arouillard.waybar")), @@ -40,7 +41,7 @@ waybar::Client::Client(int argc, char* argv[]) "/etc/xdg/waybar/style.css", "./resources/style.css", }); - + std::cout << "Resources files: " + config_file + ", " + css_file << std::endl; } void waybar::Client::handleGlobal(void *data, struct wl_registry *registry, diff --git a/src/modules/cpu.cpp b/src/modules/cpu.cpp index 1bdd0fe..93ddc7d 100644 --- a/src/modules/cpu.cpp +++ b/src/modules/cpu.cpp @@ -1,7 +1,9 @@ #include "modules/cpu.hpp" +using ctx = fmt::format_context; + waybar::modules::Cpu::Cpu(const Json::Value& config) - : ALabel(config, "{}%") + : ALabel(config, "{usage}%") { label_.set_name("cpu"); uint32_t interval = config_["interval"].isUInt() ? config_["interval"].asUInt() : 10; @@ -13,30 +15,56 @@ waybar::modules::Cpu::Cpu(const Json::Value& config) auto waybar::modules::Cpu::update() -> void { - if (prevTimes_.size() < 1) { - prevTimes_ = parseCpuinfo(); - std::this_thread::sleep_for(chrono::milliseconds(100)); + try { + // TODO: as creating dynamic fmt::arg arrays is buggy we have to do this + auto cpu_load = getCpuLoad(); + auto [cpu_usage, tooltip] = getCpuUsage(); + label_.set_tooltip_text(tooltip); + label_.set_text(fmt::format(format_, + fmt::arg("load", cpu_load), fmt::arg("usage", cpu_usage))); + } catch (const std::exception& e) { + std::cerr << e.what() << std::endl; } - std::vector< std::tuple > currTimes = parseCpuinfo(); - std::string tooltip; - for (size_t i = 0; i < currTimes.size(); ++i) { - auto [currIdle, currTotal] = currTimes[i]; - auto [prevIdle, prevTotal] = prevTimes_[i]; - const float deltaIdle = currIdle - prevIdle; - const float deltaTotal = currTotal - prevTotal; - uint16_t load = 100 * (1 - deltaIdle / deltaTotal); - if (i == 0) { - label_.set_text(fmt::format(format_, load)); - tooltip = fmt::format("Total: {}%", load); - } else { - tooltip = tooltip + fmt::format("\nCore{}: {}%", i - 1, load); - } - } - label_.set_tooltip_text(tooltip); - prevTimes_ = currTimes; } -std::vector< std::tuple > waybar::modules::Cpu::parseCpuinfo() +uint16_t waybar::modules::Cpu::getCpuLoad() +{ + struct sysinfo info = {0}; + if (sysinfo(&info) == 0) { + float f_load = 1.f / (1u << SI_LOAD_SHIFT); + uint16_t load = info.loads[0] * f_load * 100 / get_nprocs(); + return load; + } + throw std::runtime_error("Can't get Cpu load"); +} + +std::tuple waybar::modules::Cpu::getCpuUsage() +{ + if (prev_times_.empty()) { + prev_times_ = parseCpuinfo(); + std::this_thread::sleep_for(chrono::milliseconds(100)); + } + std::vector> curr_times = parseCpuinfo(); + std::string tooltip; + uint16_t usage = 0; + for (size_t i = 0; i < curr_times.size(); ++i) { + auto [curr_idle, curr_total] = curr_times[i]; + auto [prev_idle, prev_total] = prev_times_[i]; + const float delta_idle = curr_idle - prev_idle; + const float delta_total = curr_total - prev_total; + uint16_t tmp = 100 * (1 - delta_idle / delta_total); + if (i == 0) { + usage = tmp; + tooltip = fmt::format("Total: {}%", tmp); + } else { + tooltip = tooltip + fmt::format("\nCore{}: {}%", i - 1, tmp); + } + } + prev_times_ = curr_times; + return {usage, tooltip}; +} + +std::vector> waybar::modules::Cpu::parseCpuinfo() { std::ifstream info(data_dir_); if (!info.is_open()) { @@ -58,7 +86,7 @@ std::vector< std::tuple > waybar::modules::Cpu::parseCpuinfo() idle_time = times[3]; total_time = std::accumulate(times.begin(), times.end(), 0); } - cpuinfo.push_back( {idle_time, total_time} ); + cpuinfo.push_back({idle_time, total_time}); } return cpuinfo; }