From 729564cc27a753aacb1bc553c89ca6857fbc4c5c Mon Sep 17 00:00:00 2001 From: Mann mit Hut Date: Wed, 21 Dec 2022 17:44:11 +0100 Subject: [PATCH 01/12] Introduced separate load module The module provides the three system load averages. This is an improvement compared what you can do with the cpu module: cpu only provides the one minute sample and the state of the cpu module is derived from the cpu usage which messes up the formating of the load average. Also, at least on modern Linux systems, the load of a system takes much more than the cpu utilization into account and it should therefore live in a separate module. --- include/factory.hpp | 1 + include/modules/load.hpp | 29 +++++++++++++++++++ meson.build | 1 + src/factory.cpp | 3 ++ src/modules/load.cpp | 61 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 95 insertions(+) create mode 100644 include/modules/load.hpp create mode 100644 src/modules/load.cpp diff --git a/include/factory.hpp b/include/factory.hpp index 90d0ac1d..217f4122 100644 --- a/include/factory.hpp +++ b/include/factory.hpp @@ -38,6 +38,7 @@ #endif #if defined(HAVE_CPU_LINUX) || defined(HAVE_CPU_BSD) #include "modules/cpu.hpp" +#include "modules/load.hpp" #endif #include "modules/idle_inhibitor.hpp" #if defined(HAVE_MEMORY_LINUX) || defined(HAVE_MEMORY_BSD) diff --git a/include/modules/load.hpp b/include/modules/load.hpp new file mode 100644 index 00000000..39df4131 --- /dev/null +++ b/include/modules/load.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include + +#include +#include +#include +#include +#include +#include + +#include "AButton.hpp" +#include "util/sleeper_thread.hpp" + +namespace waybar::modules { + +class Load : public AButton { + public: + Load(const std::string&, const Json::Value&); + ~Load() = default; + auto update() -> void; + + private: + std::tuple getLoad(); + + util::SleeperThread thread_; +}; + +} // namespace waybar::modules diff --git a/meson.build b/meson.build index 9ccd83d8..fc6aa738 100644 --- a/meson.build +++ b/meson.build @@ -164,6 +164,7 @@ src_files = files( 'src/modules/disk.cpp', 'src/modules/idle_inhibitor.cpp', 'src/modules/image.cpp', + 'src/modules/load.cpp', 'src/modules/temperature.cpp', 'src/modules/user.cpp', 'src/main.cpp', diff --git a/src/factory.cpp b/src/factory.cpp index 1d7a00b5..965c57d5 100644 --- a/src/factory.cpp +++ b/src/factory.cpp @@ -99,6 +99,9 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name) const { if (ref == "cpu") { return new waybar::modules::Cpu(id, config_[name]); } + if (ref == "load") { + return new waybar::modules::Load(id, config_[name]); + } #endif if (ref == "clock") { return new waybar::modules::Clock(id, config_[name]); diff --git a/src/modules/load.cpp b/src/modules/load.cpp new file mode 100644 index 00000000..98bc1302 --- /dev/null +++ b/src/modules/load.cpp @@ -0,0 +1,61 @@ +#include "modules/load.hpp" + +// In the 80000 version of fmt library authors decided to optimize imports +// and moved declarations required for fmt::dynamic_format_arg_store in new +// header fmt/args.h +#if (FMT_VERSION >= 80000) +#include +#else +#include +#endif + +waybar::modules::Load::Load(const std::string& id, const Json::Value& config) + : AButton(config, "load", id, "{load1}", 10) { + thread_ = [this] { + dp.emit(); + thread_.sleep_for(interval_); + }; +} + +auto waybar::modules::Load::update() -> void { + // TODO: as creating dynamic fmt::arg arrays is buggy we have to calc both + auto [load1, load5, load15] = getLoad(); + if (tooltipEnabled()) { + auto tooltip = fmt::format("Load 1: {}\nLoad 5: {}\nLoad 15: {}", load1, load5, load15); + button_.set_tooltip_text(tooltip); + } + auto format = format_; + auto state = getState(load1); + if (!state.empty() && config_["format-" + state].isString()) { + format = config_["format-" + state].asString(); + } + + if (format.empty()) { + event_box_.hide(); + } else { + event_box_.show(); + auto icons = std::vector{state}; + fmt::dynamic_format_arg_store store; + store.push_back(fmt::arg("load1", load1)); + store.push_back(fmt::arg("load5", load5)); + store.push_back(fmt::arg("load15", load15)); + store.push_back(fmt::arg("icon1", getIcon(load1, icons))); + store.push_back(fmt::arg("icon5", getIcon(load5, icons))); + store.push_back(fmt::arg("icon15", getIcon(load15, icons))); + label_->set_markup(fmt::vformat(format, store)); + } + + // Call parent update + AButton::update(); +} + +std::tuple waybar::modules::Load::getLoad() { + double load[3]; + if (getloadavg(load, 3) != -1) { + double load1 = std::ceil(load[0] * 100.0) / 100.0; + double load5 = std::ceil(load[1] * 100.0) / 100.0; + double load15 = std::ceil(load[2] * 100.0) / 100.0; + return {load1, load5, load15}; + } + throw std::runtime_error("Can't get Cpu load"); +} From c36fe3a0041ad51fea33f92148e5a62cf2571923 Mon Sep 17 00:00:00 2001 From: Mann mit Hut Date: Wed, 21 Dec 2022 17:45:53 +0100 Subject: [PATCH 02/12] Introduce cpu_frequency module --- include/factory.hpp | 1 + include/modules/cpu_frequency.hpp | 30 +++++++++++++ meson.build | 2 + src/factory.cpp | 3 ++ src/modules/cpu_frequency/common.cpp | 67 ++++++++++++++++++++++++++++ src/modules/cpu_frequency/linux.cpp | 47 +++++++++++++++++++ 6 files changed, 150 insertions(+) create mode 100644 include/modules/cpu_frequency.hpp create mode 100644 src/modules/cpu_frequency/common.cpp create mode 100644 src/modules/cpu_frequency/linux.cpp diff --git a/include/factory.hpp b/include/factory.hpp index 217f4122..ff72749e 100644 --- a/include/factory.hpp +++ b/include/factory.hpp @@ -38,6 +38,7 @@ #endif #if defined(HAVE_CPU_LINUX) || defined(HAVE_CPU_BSD) #include "modules/cpu.hpp" +#include "modules/cpu_frequency.hpp" #include "modules/load.hpp" #endif #include "modules/idle_inhibitor.hpp" diff --git a/include/modules/cpu_frequency.hpp b/include/modules/cpu_frequency.hpp new file mode 100644 index 00000000..84475722 --- /dev/null +++ b/include/modules/cpu_frequency.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include + +#include +#include +#include +#include +#include +#include + +#include "AButton.hpp" +#include "util/sleeper_thread.hpp" + +namespace waybar::modules { + +class CpuFrequency : public AButton { + public: + CpuFrequency(const std::string&, const Json::Value&); + ~CpuFrequency() = default; + auto update() -> void; + + private: + std::tuple getCpuFrequency(); + std::vector parseCpuFrequencies(); + + util::SleeperThread thread_; +}; + +} // namespace waybar::modules diff --git a/meson.build b/meson.build index fc6aa738..a20748d1 100644 --- a/meson.build +++ b/meson.build @@ -190,6 +190,8 @@ if is_linux 'src/modules/battery.cpp', 'src/modules/cpu/common.cpp', 'src/modules/cpu/linux.cpp', + 'src/modules/cpu_frequency/common.cpp', + 'src/modules/cpu_frequency/linux.cpp', 'src/modules/memory/common.cpp', 'src/modules/memory/linux.cpp', ) diff --git a/src/factory.cpp b/src/factory.cpp index 965c57d5..b0b9af47 100644 --- a/src/factory.cpp +++ b/src/factory.cpp @@ -99,6 +99,9 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name) const { if (ref == "cpu") { return new waybar::modules::Cpu(id, config_[name]); } + if (ref == "cpu_frequency") { + return new waybar::modules::CpuFrequency(id, config_[name]); + } if (ref == "load") { return new waybar::modules::Load(id, config_[name]); } diff --git a/src/modules/cpu_frequency/common.cpp b/src/modules/cpu_frequency/common.cpp new file mode 100644 index 00000000..13aa4d27 --- /dev/null +++ b/src/modules/cpu_frequency/common.cpp @@ -0,0 +1,67 @@ +#include "modules/cpu_frequency.hpp" + +// In the 80000 version of fmt library authors decided to optimize imports +// and moved declarations required for fmt::dynamic_format_arg_store in new +// header fmt/args.h +#if (FMT_VERSION >= 80000) +#include +#else +#include +#endif + +waybar::modules::CpuFrequency::CpuFrequency(const std::string& id, const Json::Value& config) + : AButton(config, "cpu_frequency", id, "{avg_frequency}", 10) { + thread_ = [this] { + dp.emit(); + thread_.sleep_for(interval_); + }; +} + +auto waybar::modules::CpuFrequency::update() -> void { + // TODO: as creating dynamic fmt::arg arrays is buggy we have to calc both + auto [max_frequency, min_frequency, avg_frequency] = getCpuFrequency(); + if (tooltipEnabled()) { + auto tooltip = + fmt::format("Minimum frequency: {}\nAverage frequency: {}\nMaximum frequency: {}\n", + min_frequency, avg_frequency, max_frequency); + button_.set_tooltip_text(tooltip); + } + auto format = format_; + auto state = getState(avg_frequency); + if (!state.empty() && config_["format-" + state].isString()) { + format = config_["format-" + state].asString(); + } + + if (format.empty()) { + event_box_.hide(); + } else { + event_box_.show(); + auto icons = std::vector{state}; + fmt::dynamic_format_arg_store store; + store.push_back(fmt::arg("icon", getIcon(avg_frequency, icons))); + store.push_back(fmt::arg("max_frequency", max_frequency)); + store.push_back(fmt::arg("min_frequency", min_frequency)); + store.push_back(fmt::arg("avg_frequency", avg_frequency)); + label_->set_markup(fmt::vformat(format, store)); + } + + // Call parent update + AButton::update(); +} + +std::tuple waybar::modules::CpuFrequency::getCpuFrequency() { + std::vector frequencies = parseCpuFrequencies(); + if (frequencies.empty()) { + return {0.f, 0.f, 0.f}; + } + 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_frequency/linux.cpp b/src/modules/cpu_frequency/linux.cpp new file mode 100644 index 00000000..1f368789 --- /dev/null +++ b/src/modules/cpu_frequency/linux.cpp @@ -0,0 +1,47 @@ +#include + +#include "modules/cpu_frequency.hpp" + +std::vector waybar::modules::CpuFrequency::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(); + + if (frequencies.size() <= 0) { + std::string cpufreq_dir = "/sys/devices/system/cpu/cpufreq"; + if (std::filesystem::exists(cpufreq_dir)) { + std::vector frequency_files = {"/cpuinfo_min_freq", "/cpuinfo_max_freq"}; + for (auto& p : std::filesystem::directory_iterator(cpufreq_dir)) { + for (auto freq_file : frequency_files) { + std::string freq_file_path = p.path().string() + freq_file; + if (std::filesystem::exists(freq_file_path)) { + std::string freq_value; + std::ifstream freq(freq_file_path); + if (freq.is_open()) { + getline(freq, freq_value); + float frequency = std::strtol(freq_value.c_str(), nullptr, 10); + frequencies.push_back(frequency / 1000); + freq.close(); + } + } + } + } + } + } + + return frequencies; +} From 888adb57ec8c87b4a32a5f335e6116e1aba2c18e Mon Sep 17 00:00:00 2001 From: Mann mit Hut Date: Wed, 21 Dec 2022 17:47:06 +0100 Subject: [PATCH 03/12] Introduce cpu_usage module --- include/factory.hpp | 1 + include/modules/cpu_usage.hpp | 32 ++++++++++ meson.build | 4 ++ src/factory.cpp | 3 + src/modules/cpu_usage/bsd.cpp | 102 +++++++++++++++++++++++++++++++ src/modules/cpu_usage/common.cpp | 78 +++++++++++++++++++++++ src/modules/cpu_usage/linux.cpp | 31 ++++++++++ 7 files changed, 251 insertions(+) create mode 100644 include/modules/cpu_usage.hpp create mode 100644 src/modules/cpu_usage/bsd.cpp create mode 100644 src/modules/cpu_usage/common.cpp create mode 100644 src/modules/cpu_usage/linux.cpp diff --git a/include/factory.hpp b/include/factory.hpp index ff72749e..cb25078d 100644 --- a/include/factory.hpp +++ b/include/factory.hpp @@ -39,6 +39,7 @@ #if defined(HAVE_CPU_LINUX) || defined(HAVE_CPU_BSD) #include "modules/cpu.hpp" #include "modules/cpu_frequency.hpp" +#include "modules/cpu_usage.hpp" #include "modules/load.hpp" #endif #include "modules/idle_inhibitor.hpp" diff --git a/include/modules/cpu_usage.hpp b/include/modules/cpu_usage.hpp new file mode 100644 index 00000000..0e57124a --- /dev/null +++ b/include/modules/cpu_usage.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include + +#include +#include +#include +#include +#include +#include + +#include "AButton.hpp" +#include "util/sleeper_thread.hpp" + +namespace waybar::modules { + +class CpuUsage : public AButton { + public: + CpuUsage(const std::string&, const Json::Value&); + ~CpuUsage() = default; + auto update() -> void; + + private: + std::tuple, std::string> getCpuUsage(); + std::vector> parseCpuinfo(); + + std::vector> prev_times_; + + util::SleeperThread thread_; +}; + +} // namespace waybar::modules diff --git a/meson.build b/meson.build index a20748d1..2a0922cb 100644 --- a/meson.build +++ b/meson.build @@ -192,6 +192,8 @@ if is_linux 'src/modules/cpu/linux.cpp', 'src/modules/cpu_frequency/common.cpp', 'src/modules/cpu_frequency/linux.cpp', + 'src/modules/cpu_usage/common.cpp', + 'src/modules/cpu_usage/linux.cpp', 'src/modules/memory/common.cpp', 'src/modules/memory/linux.cpp', ) @@ -201,6 +203,8 @@ elif is_dragonfly or is_freebsd or is_netbsd or is_openbsd src_files += files( 'src/modules/cpu/bsd.cpp', 'src/modules/cpu/common.cpp', + 'src/modules/cpu_usage/bsd.cpp', + 'src/modules/cpu_usage/common.cpp', 'src/modules/memory/bsd.cpp', 'src/modules/memory/common.cpp', ) diff --git a/src/factory.cpp b/src/factory.cpp index b0b9af47..18b14427 100644 --- a/src/factory.cpp +++ b/src/factory.cpp @@ -102,6 +102,9 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name) const { if (ref == "cpu_frequency") { return new waybar::modules::CpuFrequency(id, config_[name]); } + if (ref == "cpu_usage") { + return new waybar::modules::CpuUsage(id, config_[name]); + } if (ref == "load") { return new waybar::modules::Load(id, config_[name]); } diff --git a/src/modules/cpu_usage/bsd.cpp b/src/modules/cpu_usage/bsd.cpp new file mode 100644 index 00000000..c987a770 --- /dev/null +++ b/src/modules/cpu_usage/bsd.cpp @@ -0,0 +1,102 @@ +#include +// clang-format off +#include +#include +// clang-format on +#include // sysconf + +#include // NAN +#include // malloc + +#include "modules/cpu_usage.hpp" + +#if defined(__NetBSD__) || defined(__OpenBSD__) +#include +#else +#include +#endif + +#if defined(__NetBSD__) +typedef uint64_t cp_time_t; +#else +typedef long cp_time_t; +#endif +#if defined(__NetBSD__) || defined(__OpenBSD__) +typedef uint64_t pcp_time_t; +#else +typedef long pcp_time_t; +#endif + +std::vector> waybar::modules::CpuUsage::parseCpuinfo() { + cp_time_t sum_cp_time[CPUSTATES]; + size_t sum_sz = sizeof(sum_cp_time); + int ncpu = sysconf(_SC_NPROCESSORS_CONF); + size_t sz = CPUSTATES * (ncpu + 1) * sizeof(pcp_time_t); + pcp_time_t *cp_time = static_cast(malloc(sz)), *pcp_time = cp_time; +#if defined(__NetBSD__) + int mib[] = { + CTL_KERN, + KERN_CP_TIME, + }; + if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), sum_cp_time, &sum_sz, NULL, 0)) { + throw std::runtime_error("sysctl kern.cp_time failed"); + } + for (int state = 0; state < CPUSTATES; state++) { + cp_time[state] = sum_cp_time[state]; + } + pcp_time += CPUSTATES; + if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), pcp_time, &sz, NULL, 0)) { + throw std::runtime_error("sysctl kern.cp_time failed"); + } +#elif defined(__OpenBSD__) + { + int mib[] = { + CTL_KERN, + KERN_CPTIME, + }; + if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), sum_cp_time, &sum_sz, NULL, 0)) { + throw std::runtime_error("sysctl kern.cp_time failed"); + } + } + for (int state = 0; state < CPUSTATES; state++) { + cp_time[state] = sum_cp_time[state]; + } + pcp_time = cp_time; + sz /= ncpu + 1; + { + int mib[] = { + CTL_KERN, + KERN_CPTIME2, + 0, + }; + for (int cpu = 0; cpu < ncpu; cpu++) { + mib[2] = cpu; + pcp_time += CPUSTATES; + if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), pcp_time, &sz, NULL, 0)) { + throw std::runtime_error("sysctl kern.cp_time2 failed"); + } + } + } +#else + if (sysctlbyname("kern.cp_time", sum_cp_time, &sum_sz, NULL, 0)) { + throw std::runtime_error("sysctl kern.cp_time failed"); + } + for (int state = 0; state < CPUSTATES; state++) { + cp_time[state] = sum_cp_time[state]; + } + pcp_time += CPUSTATES; + if (sysctlbyname("kern.cp_times", pcp_time, &sz, NULL, 0)) { + throw std::runtime_error("sysctl kern.cp_times failed"); + } +#endif + std::vector> cpuinfo; + for (int cpu = 0; cpu < ncpu + 1; cpu++) { + pcp_time_t total = 0, *single_cp_time = &cp_time[cpu * CPUSTATES]; + for (int state = 0; state < CPUSTATES; state++) { + total += single_cp_time[state]; + } + cpuinfo.emplace_back(single_cp_time[CP_IDLE], total); + } + free(cp_time); + return cpuinfo; +} diff --git a/src/modules/cpu_usage/common.cpp b/src/modules/cpu_usage/common.cpp new file mode 100644 index 00000000..140373a0 --- /dev/null +++ b/src/modules/cpu_usage/common.cpp @@ -0,0 +1,78 @@ +#include "modules/cpu_usage.hpp" + +// In the 80000 version of fmt library authors decided to optimize imports +// and moved declarations required for fmt::dynamic_format_arg_store in new +// header fmt/args.h +#if (FMT_VERSION >= 80000) +#include +#else +#include +#endif + +waybar::modules::CpuUsage::CpuUsage(const std::string& id, const Json::Value& config) + : AButton(config, "cpu_usage", id, "{usage}%", 10) { + thread_ = [this] { + dp.emit(); + thread_.sleep_for(interval_); + }; +} + +auto waybar::modules::CpuUsage::update() -> void { + // TODO: as creating dynamic fmt::arg arrays is buggy we have to calc both + auto [cpu_usage, tooltip] = getCpuUsage(); + if (tooltipEnabled()) { + button_.set_tooltip_text(tooltip); + } + auto format = format_; + auto total_usage = cpu_usage.empty() ? 0 : cpu_usage[0]; + auto state = getState(total_usage); + if (!state.empty() && config_["format-" + state].isString()) { + format = config_["format-" + state].asString(); + } + + if (format.empty()) { + event_box_.hide(); + } else { + event_box_.show(); + auto icons = std::vector{state}; + fmt::dynamic_format_arg_store store; + store.push_back(fmt::arg("usage", total_usage)); + store.push_back(fmt::arg("icon", getIcon(total_usage, icons))); + for (size_t i = 1; i < cpu_usage.size(); ++i) { + auto core_i = i - 1; + auto core_format = fmt::format("usage{}", core_i); + store.push_back(fmt::arg(core_format.c_str(), cpu_usage[i])); + auto icon_format = fmt::format("icon{}", core_i); + store.push_back(fmt::arg(icon_format.c_str(), getIcon(cpu_usage[i], icons))); + } + label_->set_markup(fmt::vformat(format, store)); + } + + // Call parent update + AButton::update(); +} + +std::tuple, std::string> waybar::modules::CpuUsage::getCpuUsage() { + if (prev_times_.empty()) { + prev_times_ = parseCpuinfo(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + std::vector> curr_times = parseCpuinfo(); + std::string tooltip; + std::vector usage; + 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) { + tooltip = fmt::format("Total: {}%", tmp); + } else { + tooltip = tooltip + fmt::format("\nCore{}: {}%", i - 1, tmp); + } + usage.push_back(tmp); + } + prev_times_ = curr_times; + return {usage, tooltip}; +} diff --git a/src/modules/cpu_usage/linux.cpp b/src/modules/cpu_usage/linux.cpp new file mode 100644 index 00000000..28930c1c --- /dev/null +++ b/src/modules/cpu_usage/linux.cpp @@ -0,0 +1,31 @@ +#include + +#include "modules/cpu_usage.hpp" + +std::vector> waybar::modules::CpuUsage::parseCpuinfo() { + const std::string data_dir_ = "/proc/stat"; + std::ifstream info(data_dir_); + if (!info.is_open()) { + throw std::runtime_error("Can't open " + data_dir_); + } + std::vector> cpuinfo; + std::string line; + while (getline(info, line)) { + if (line.substr(0, 3).compare("cpu") != 0) { + break; + } + std::stringstream sline(line.substr(5)); + std::vector times; + for (size_t time = 0; sline >> time; times.push_back(time)) + ; + + size_t idle_time = 0; + size_t total_time = 0; + if (times.size() >= 4) { + idle_time = times[3]; + total_time = std::accumulate(times.begin(), times.end(), 0); + } + cpuinfo.emplace_back(idle_time, total_time); + } + return cpuinfo; +} From 982ffde0027d3808858248929bc6317c766f5f44 Mon Sep 17 00:00:00 2001 From: Mann mit Hut Date: Fri, 14 Apr 2023 01:25:13 +0200 Subject: [PATCH 04/12] Use labels instead of buttons --- include/modules/cpu_frequency.hpp | 4 ++-- include/modules/cpu_usage.hpp | 4 ++-- include/modules/load.hpp | 4 ++-- src/modules/cpu_frequency/common.cpp | 8 ++++---- src/modules/cpu_usage/common.cpp | 8 ++++---- src/modules/load.cpp | 10 +++++----- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/include/modules/cpu_frequency.hpp b/include/modules/cpu_frequency.hpp index 84475722..0b5bba0c 100644 --- a/include/modules/cpu_frequency.hpp +++ b/include/modules/cpu_frequency.hpp @@ -9,12 +9,12 @@ #include #include -#include "AButton.hpp" +#include "ALabel.hpp" #include "util/sleeper_thread.hpp" namespace waybar::modules { -class CpuFrequency : public AButton { +class CpuFrequency : public ALabel { public: CpuFrequency(const std::string&, const Json::Value&); ~CpuFrequency() = default; diff --git a/include/modules/cpu_usage.hpp b/include/modules/cpu_usage.hpp index 0e57124a..3088c5a6 100644 --- a/include/modules/cpu_usage.hpp +++ b/include/modules/cpu_usage.hpp @@ -9,12 +9,12 @@ #include #include -#include "AButton.hpp" +#include "ALabel.hpp" #include "util/sleeper_thread.hpp" namespace waybar::modules { -class CpuUsage : public AButton { +class CpuUsage : public ALabel { public: CpuUsage(const std::string&, const Json::Value&); ~CpuUsage() = default; diff --git a/include/modules/load.hpp b/include/modules/load.hpp index 39df4131..1d11370d 100644 --- a/include/modules/load.hpp +++ b/include/modules/load.hpp @@ -9,12 +9,12 @@ #include #include -#include "AButton.hpp" +#include "ALabel.hpp" #include "util/sleeper_thread.hpp" namespace waybar::modules { -class Load : public AButton { +class Load : public ALabel { public: Load(const std::string&, const Json::Value&); ~Load() = default; diff --git a/src/modules/cpu_frequency/common.cpp b/src/modules/cpu_frequency/common.cpp index 13aa4d27..abed2aba 100644 --- a/src/modules/cpu_frequency/common.cpp +++ b/src/modules/cpu_frequency/common.cpp @@ -10,7 +10,7 @@ #endif waybar::modules::CpuFrequency::CpuFrequency(const std::string& id, const Json::Value& config) - : AButton(config, "cpu_frequency", id, "{avg_frequency}", 10) { + : ALabel(config, "cpu_frequency", id, "{avg_frequency}", 10) { thread_ = [this] { dp.emit(); thread_.sleep_for(interval_); @@ -24,7 +24,7 @@ auto waybar::modules::CpuFrequency::update() -> void { auto tooltip = fmt::format("Minimum frequency: {}\nAverage frequency: {}\nMaximum frequency: {}\n", min_frequency, avg_frequency, max_frequency); - button_.set_tooltip_text(tooltip); + label_.set_tooltip_text(tooltip); } auto format = format_; auto state = getState(avg_frequency); @@ -42,11 +42,11 @@ auto waybar::modules::CpuFrequency::update() -> void { store.push_back(fmt::arg("max_frequency", max_frequency)); store.push_back(fmt::arg("min_frequency", min_frequency)); store.push_back(fmt::arg("avg_frequency", avg_frequency)); - label_->set_markup(fmt::vformat(format, store)); + label_.set_markup(fmt::vformat(format, store)); } // Call parent update - AButton::update(); + ALabel::update(); } std::tuple waybar::modules::CpuFrequency::getCpuFrequency() { diff --git a/src/modules/cpu_usage/common.cpp b/src/modules/cpu_usage/common.cpp index 140373a0..bd56cf1a 100644 --- a/src/modules/cpu_usage/common.cpp +++ b/src/modules/cpu_usage/common.cpp @@ -10,7 +10,7 @@ #endif waybar::modules::CpuUsage::CpuUsage(const std::string& id, const Json::Value& config) - : AButton(config, "cpu_usage", id, "{usage}%", 10) { + : ALabel(config, "cpu_usage", id, "{usage}%", 10) { thread_ = [this] { dp.emit(); thread_.sleep_for(interval_); @@ -21,7 +21,7 @@ auto waybar::modules::CpuUsage::update() -> void { // TODO: as creating dynamic fmt::arg arrays is buggy we have to calc both auto [cpu_usage, tooltip] = getCpuUsage(); if (tooltipEnabled()) { - button_.set_tooltip_text(tooltip); + label_.set_tooltip_text(tooltip); } auto format = format_; auto total_usage = cpu_usage.empty() ? 0 : cpu_usage[0]; @@ -45,11 +45,11 @@ auto waybar::modules::CpuUsage::update() -> void { auto icon_format = fmt::format("icon{}", core_i); store.push_back(fmt::arg(icon_format.c_str(), getIcon(cpu_usage[i], icons))); } - label_->set_markup(fmt::vformat(format, store)); + label_.set_markup(fmt::vformat(format, store)); } // Call parent update - AButton::update(); + ALabel::update(); } std::tuple, std::string> waybar::modules::CpuUsage::getCpuUsage() { diff --git a/src/modules/load.cpp b/src/modules/load.cpp index 98bc1302..2ea646f3 100644 --- a/src/modules/load.cpp +++ b/src/modules/load.cpp @@ -10,7 +10,7 @@ #endif waybar::modules::Load::Load(const std::string& id, const Json::Value& config) - : AButton(config, "load", id, "{load1}", 10) { + : ALabel(config, "load", id, "{load1}", 10) { thread_ = [this] { dp.emit(); thread_.sleep_for(interval_); @@ -22,7 +22,7 @@ auto waybar::modules::Load::update() -> void { auto [load1, load5, load15] = getLoad(); if (tooltipEnabled()) { auto tooltip = fmt::format("Load 1: {}\nLoad 5: {}\nLoad 15: {}", load1, load5, load15); - button_.set_tooltip_text(tooltip); + label_.set_tooltip_text(tooltip); } auto format = format_; auto state = getState(load1); @@ -42,11 +42,11 @@ auto waybar::modules::Load::update() -> void { store.push_back(fmt::arg("icon1", getIcon(load1, icons))); store.push_back(fmt::arg("icon5", getIcon(load5, icons))); store.push_back(fmt::arg("icon15", getIcon(load15, icons))); - label_->set_markup(fmt::vformat(format, store)); + label_.set_markup(fmt::vformat(format, store)); } // Call parent update - AButton::update(); + ALabel::update(); } std::tuple waybar::modules::Load::getLoad() { @@ -57,5 +57,5 @@ std::tuple waybar::modules::Load::getLoad() { double load15 = std::ceil(load[2] * 100.0) / 100.0; return {load1, load5, load15}; } - throw std::runtime_error("Can't get Cpu load"); + throw std::runtime_error("Can't get Load"); } From dce6a98f38f4bcc0c62d8f34b28f8e55b50bb0f5 Mon Sep 17 00:00:00 2001 From: Mann mit Hut Date: Sat, 29 Jul 2023 14:52:59 +0200 Subject: [PATCH 05/12] Added changes made to the cpu module --- include/modules/cpu_frequency.hpp | 4 ++-- include/modules/cpu_usage.hpp | 4 ++-- include/modules/load.hpp | 4 ++-- src/modules/load.cpp | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/modules/cpu_frequency.hpp b/include/modules/cpu_frequency.hpp index 0b5bba0c..3331bd9c 100644 --- a/include/modules/cpu_frequency.hpp +++ b/include/modules/cpu_frequency.hpp @@ -17,8 +17,8 @@ namespace waybar::modules { class CpuFrequency : public ALabel { public: CpuFrequency(const std::string&, const Json::Value&); - ~CpuFrequency() = default; - auto update() -> void; + virtual ~CpuFrequency() = default; + auto update() -> void override; private: std::tuple getCpuFrequency(); diff --git a/include/modules/cpu_usage.hpp b/include/modules/cpu_usage.hpp index 3088c5a6..48f9194c 100644 --- a/include/modules/cpu_usage.hpp +++ b/include/modules/cpu_usage.hpp @@ -17,8 +17,8 @@ namespace waybar::modules { class CpuUsage : public ALabel { public: CpuUsage(const std::string&, const Json::Value&); - ~CpuUsage() = default; - auto update() -> void; + virtual ~CpuUsage() = default; + auto update() -> void override; private: std::tuple, std::string> getCpuUsage(); diff --git a/include/modules/load.hpp b/include/modules/load.hpp index 1d11370d..e4e91213 100644 --- a/include/modules/load.hpp +++ b/include/modules/load.hpp @@ -17,8 +17,8 @@ namespace waybar::modules { class Load : public ALabel { public: Load(const std::string&, const Json::Value&); - ~Load() = default; - auto update() -> void; + virtual ~Load() = default; + auto update() -> void override; private: std::tuple getLoad(); diff --git a/src/modules/load.cpp b/src/modules/load.cpp index 2ea646f3..9ee4b764 100644 --- a/src/modules/load.cpp +++ b/src/modules/load.cpp @@ -57,5 +57,5 @@ std::tuple waybar::modules::Load::getLoad() { double load15 = std::ceil(load[2] * 100.0) / 100.0; return {load1, load5, load15}; } - throw std::runtime_error("Can't get Load"); + throw std::runtime_error("Can't get system load"); } From c45f6681b37257cc6fdb63b0d610b809914f9194 Mon Sep 17 00:00:00 2001 From: Mann mit Hut Date: Sat, 29 Jul 2023 15:28:26 +0200 Subject: [PATCH 06/12] cpu module: Reuse getCpuFrequency of cpu_frequency module --- include/modules/cpu.hpp | 2 -- include/modules/cpu_frequency.hpp | 6 ++-- src/modules/cpu/bsd.cpp | 10 ------- src/modules/cpu/common.cpp | 20 ++----------- src/modules/cpu/linux.cpp | 44 ---------------------------- src/modules/cpu_frequency/common.cpp | 4 +-- 6 files changed, 8 insertions(+), 78 deletions(-) diff --git a/include/modules/cpu.hpp b/include/modules/cpu.hpp index a5235486..57331163 100644 --- a/include/modules/cpu.hpp +++ b/include/modules/cpu.hpp @@ -23,9 +23,7 @@ class Cpu : public ALabel { private: double getCpuLoad(); std::tuple, std::string> getCpuUsage(); - std::tuple getCpuFrequency(); std::vector> parseCpuinfo(); - std::vector parseCpuFrequencies(); std::vector> prev_times_; diff --git a/include/modules/cpu_frequency.hpp b/include/modules/cpu_frequency.hpp index 3331bd9c..49ca1b86 100644 --- a/include/modules/cpu_frequency.hpp +++ b/include/modules/cpu_frequency.hpp @@ -20,9 +20,11 @@ class CpuFrequency : public ALabel { virtual ~CpuFrequency() = default; auto update() -> void override; + // This is a static member because it is also used by the cpu module. + static std::tuple getCpuFrequency(); + private: - std::tuple getCpuFrequency(); - std::vector parseCpuFrequencies(); + static std::vector parseCpuFrequencies(); util::SleeperThread thread_; }; diff --git a/src/modules/cpu/bsd.cpp b/src/modules/cpu/bsd.cpp index 5eb767d9..96f2e51c 100644 --- a/src/modules/cpu/bsd.cpp +++ b/src/modules/cpu/bsd.cpp @@ -100,13 +100,3 @@ std::vector> waybar::modules::Cpu::parseCpuinfo() { free(cp_time); return cpuinfo; } - -std::vector waybar::modules::Cpu::parseCpuFrequencies() { - static std::vector frequencies; - if (frequencies.empty()) { - spdlog::warn( - "cpu/bsd: parseCpuFrequencies is not implemented, expect garbage in {*_frequency}"); - frequencies.push_back(NAN); - } - return frequencies; -} diff --git a/src/modules/cpu/common.cpp b/src/modules/cpu/common.cpp index 8fedf842..a27b7f52 100644 --- a/src/modules/cpu/common.cpp +++ b/src/modules/cpu/common.cpp @@ -1,4 +1,5 @@ #include "modules/cpu.hpp" +#include "modules/cpu_frequency.hpp" // In the 80000 version of fmt library authors decided to optimize imports // and moved declarations required for fmt::dynamic_format_arg_store in new @@ -21,7 +22,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(); + auto [max_frequency, min_frequency, avg_frequency] = CpuFrequency::getCpuFrequency(); if (tooltipEnabled()) { label_.set_tooltip_text(tooltip); } @@ -90,20 +91,3 @@ std::tuple, std::string> waybar::modules::Cpu::getCpuUsage prev_times_ = curr_times; return {usage, tooltip}; } - -std::tuple waybar::modules::Cpu::getCpuFrequency() { - std::vector frequencies = parseCpuFrequencies(); - if (frequencies.empty()) { - return {0.f, 0.f, 0.f}; - } - 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 e9b18d70..88d71ee7 100644 --- a/src/modules/cpu/linux.cpp +++ b/src/modules/cpu/linux.cpp @@ -29,47 +29,3 @@ 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(); - - if (frequencies.size() <= 0) { - std::string cpufreq_dir = "/sys/devices/system/cpu/cpufreq"; - if (std::filesystem::exists(cpufreq_dir)) { - std::vector frequency_files = {"/cpuinfo_min_freq", "/cpuinfo_max_freq"}; - for (auto& p : std::filesystem::directory_iterator(cpufreq_dir)) { - for (auto freq_file : frequency_files) { - std::string freq_file_path = p.path().string() + freq_file; - if (std::filesystem::exists(freq_file_path)) { - std::string freq_value; - std::ifstream freq(freq_file_path); - if (freq.is_open()) { - getline(freq, freq_value); - float frequency = std::strtol(freq_value.c_str(), nullptr, 10); - frequencies.push_back(frequency / 1000); - freq.close(); - } - } - } - } - } - } - - return frequencies; -} diff --git a/src/modules/cpu_frequency/common.cpp b/src/modules/cpu_frequency/common.cpp index abed2aba..e47364ba 100644 --- a/src/modules/cpu_frequency/common.cpp +++ b/src/modules/cpu_frequency/common.cpp @@ -19,7 +19,7 @@ waybar::modules::CpuFrequency::CpuFrequency(const std::string& id, const Json::V auto waybar::modules::CpuFrequency::update() -> void { // TODO: as creating dynamic fmt::arg arrays is buggy we have to calc both - auto [max_frequency, min_frequency, avg_frequency] = getCpuFrequency(); + auto [max_frequency, min_frequency, avg_frequency] = CpuFrequency::getCpuFrequency(); if (tooltipEnabled()) { auto tooltip = fmt::format("Minimum frequency: {}\nAverage frequency: {}\nMaximum frequency: {}\n", @@ -50,7 +50,7 @@ auto waybar::modules::CpuFrequency::update() -> void { } std::tuple waybar::modules::CpuFrequency::getCpuFrequency() { - std::vector frequencies = parseCpuFrequencies(); + std::vector frequencies = CpuFrequency::parseCpuFrequencies(); if (frequencies.empty()) { return {0.f, 0.f, 0.f}; } From d1602e383c88d1f546b36704037133648b0e5ac4 Mon Sep 17 00:00:00 2001 From: Mann mit Hut Date: Sat, 29 Jul 2023 15:56:51 +0200 Subject: [PATCH 07/12] cpu module: Reuse getCpuUsage of cpu_usage module --- include/modules/cpu.hpp | 2 - include/modules/cpu_usage.hpp | 6 +- meson.build | 2 - src/modules/cpu/bsd.cpp | 102 ------------------------------- src/modules/cpu/common.cpp | 28 +-------- src/modules/cpu/linux.cpp | 31 ---------- src/modules/cpu_usage/common.cpp | 14 ++--- 7 files changed, 13 insertions(+), 172 deletions(-) delete mode 100644 src/modules/cpu/bsd.cpp delete mode 100644 src/modules/cpu/linux.cpp diff --git a/include/modules/cpu.hpp b/include/modules/cpu.hpp index 57331163..aff4c508 100644 --- a/include/modules/cpu.hpp +++ b/include/modules/cpu.hpp @@ -22,8 +22,6 @@ class Cpu : public ALabel { private: double getCpuLoad(); - std::tuple, std::string> getCpuUsage(); - std::vector> parseCpuinfo(); std::vector> prev_times_; diff --git a/include/modules/cpu_usage.hpp b/include/modules/cpu_usage.hpp index 48f9194c..4349f705 100644 --- a/include/modules/cpu_usage.hpp +++ b/include/modules/cpu_usage.hpp @@ -20,9 +20,11 @@ class CpuUsage : public ALabel { virtual ~CpuUsage() = default; auto update() -> void override; + // This is a static member because it is also used by the cpu module. + static std::tuple, std::string> getCpuUsage(std::vector>&); + private: - std::tuple, std::string> getCpuUsage(); - std::vector> parseCpuinfo(); + static std::vector> parseCpuinfo(); std::vector> prev_times_; diff --git a/meson.build b/meson.build index 2a0922cb..3bb79d43 100644 --- a/meson.build +++ b/meson.build @@ -189,7 +189,6 @@ if is_linux src_files += files( 'src/modules/battery.cpp', 'src/modules/cpu/common.cpp', - 'src/modules/cpu/linux.cpp', 'src/modules/cpu_frequency/common.cpp', 'src/modules/cpu_frequency/linux.cpp', 'src/modules/cpu_usage/common.cpp', @@ -201,7 +200,6 @@ elif is_dragonfly or is_freebsd or is_netbsd or is_openbsd add_project_arguments('-DHAVE_CPU_BSD', language: 'cpp') add_project_arguments('-DHAVE_MEMORY_BSD', language: 'cpp') src_files += files( - 'src/modules/cpu/bsd.cpp', 'src/modules/cpu/common.cpp', 'src/modules/cpu_usage/bsd.cpp', 'src/modules/cpu_usage/common.cpp', diff --git a/src/modules/cpu/bsd.cpp b/src/modules/cpu/bsd.cpp deleted file mode 100644 index 96f2e51c..00000000 --- a/src/modules/cpu/bsd.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include -// clang-format off -#include -#include -// clang-format on -#include // sysconf - -#include // NAN -#include // malloc - -#include "modules/cpu.hpp" - -#if defined(__NetBSD__) || defined(__OpenBSD__) -#include -#else -#include -#endif - -#if defined(__NetBSD__) -typedef uint64_t cp_time_t; -#else -typedef long cp_time_t; -#endif -#if defined(__NetBSD__) || defined(__OpenBSD__) -typedef uint64_t pcp_time_t; -#else -typedef long pcp_time_t; -#endif - -std::vector> waybar::modules::Cpu::parseCpuinfo() { - cp_time_t sum_cp_time[CPUSTATES]; - size_t sum_sz = sizeof(sum_cp_time); - int ncpu = sysconf(_SC_NPROCESSORS_CONF); - size_t sz = CPUSTATES * (ncpu + 1) * sizeof(pcp_time_t); - pcp_time_t *cp_time = static_cast(malloc(sz)), *pcp_time = cp_time; -#if defined(__NetBSD__) - int mib[] = { - CTL_KERN, - KERN_CP_TIME, - }; - if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), sum_cp_time, &sum_sz, NULL, 0)) { - throw std::runtime_error("sysctl kern.cp_time failed"); - } - for (int state = 0; state < CPUSTATES; state++) { - cp_time[state] = sum_cp_time[state]; - } - pcp_time += CPUSTATES; - if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), pcp_time, &sz, NULL, 0)) { - throw std::runtime_error("sysctl kern.cp_time failed"); - } -#elif defined(__OpenBSD__) - { - int mib[] = { - CTL_KERN, - KERN_CPTIME, - }; - if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), sum_cp_time, &sum_sz, NULL, 0)) { - throw std::runtime_error("sysctl kern.cp_time failed"); - } - } - for (int state = 0; state < CPUSTATES; state++) { - cp_time[state] = sum_cp_time[state]; - } - pcp_time = cp_time; - sz /= ncpu + 1; - { - int mib[] = { - CTL_KERN, - KERN_CPTIME2, - 0, - }; - for (int cpu = 0; cpu < ncpu; cpu++) { - mib[2] = cpu; - pcp_time += CPUSTATES; - if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), pcp_time, &sz, NULL, 0)) { - throw std::runtime_error("sysctl kern.cp_time2 failed"); - } - } - } -#else - if (sysctlbyname("kern.cp_time", sum_cp_time, &sum_sz, NULL, 0)) { - throw std::runtime_error("sysctl kern.cp_time failed"); - } - for (int state = 0; state < CPUSTATES; state++) { - cp_time[state] = sum_cp_time[state]; - } - pcp_time += CPUSTATES; - if (sysctlbyname("kern.cp_times", pcp_time, &sz, NULL, 0)) { - throw std::runtime_error("sysctl kern.cp_times failed"); - } -#endif - std::vector> cpuinfo; - for (int cpu = 0; cpu < ncpu + 1; cpu++) { - pcp_time_t total = 0, *single_cp_time = &cp_time[cpu * CPUSTATES]; - for (int state = 0; state < CPUSTATES; state++) { - total += single_cp_time[state]; - } - cpuinfo.emplace_back(single_cp_time[CP_IDLE], total); - } - free(cp_time); - return cpuinfo; -} diff --git a/src/modules/cpu/common.cpp b/src/modules/cpu/common.cpp index a27b7f52..5259dcb9 100644 --- a/src/modules/cpu/common.cpp +++ b/src/modules/cpu/common.cpp @@ -1,5 +1,6 @@ #include "modules/cpu.hpp" #include "modules/cpu_frequency.hpp" +#include "modules/cpu_usage.hpp" // In the 80000 version of fmt library authors decided to optimize imports // and moved declarations required for fmt::dynamic_format_arg_store in new @@ -21,7 +22,7 @@ waybar::modules::Cpu::Cpu(const std::string& id, const Json::Value& config) 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 [cpu_usage, tooltip] = CpuUsage::getCpuUsage(prev_times_); auto [max_frequency, min_frequency, avg_frequency] = CpuFrequency::getCpuFrequency(); if (tooltipEnabled()) { label_.set_tooltip_text(tooltip); @@ -66,28 +67,3 @@ double waybar::modules::Cpu::getCpuLoad() { } throw std::runtime_error("Can't get Cpu load"); } - -std::tuple, std::string> waybar::modules::Cpu::getCpuUsage() { - if (prev_times_.empty()) { - prev_times_ = parseCpuinfo(); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - std::vector> curr_times = parseCpuinfo(); - std::string tooltip; - std::vector usage; - 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) { - tooltip = fmt::format("Total: {}%", tmp); - } else { - tooltip = tooltip + fmt::format("\nCore{}: {}%", i - 1, tmp); - } - usage.push_back(tmp); - } - prev_times_ = curr_times; - return {usage, tooltip}; -} diff --git a/src/modules/cpu/linux.cpp b/src/modules/cpu/linux.cpp deleted file mode 100644 index 88d71ee7..00000000 --- a/src/modules/cpu/linux.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include - -#include "modules/cpu.hpp" - -std::vector> waybar::modules::Cpu::parseCpuinfo() { - const std::string data_dir_ = "/proc/stat"; - std::ifstream info(data_dir_); - if (!info.is_open()) { - throw std::runtime_error("Can't open " + data_dir_); - } - std::vector> cpuinfo; - std::string line; - while (getline(info, line)) { - if (line.substr(0, 3).compare("cpu") != 0) { - break; - } - std::stringstream sline(line.substr(5)); - std::vector times; - for (size_t time = 0; sline >> time; times.push_back(time)) - ; - - size_t idle_time = 0; - size_t total_time = 0; - if (times.size() >= 4) { - idle_time = times[3]; - total_time = std::accumulate(times.begin(), times.end(), 0); - } - cpuinfo.emplace_back(idle_time, total_time); - } - return cpuinfo; -} diff --git a/src/modules/cpu_usage/common.cpp b/src/modules/cpu_usage/common.cpp index bd56cf1a..ffa54ae0 100644 --- a/src/modules/cpu_usage/common.cpp +++ b/src/modules/cpu_usage/common.cpp @@ -19,7 +19,7 @@ waybar::modules::CpuUsage::CpuUsage(const std::string& id, const Json::Value& co auto waybar::modules::CpuUsage::update() -> void { // TODO: as creating dynamic fmt::arg arrays is buggy we have to calc both - auto [cpu_usage, tooltip] = getCpuUsage(); + auto [cpu_usage, tooltip] = CpuUsage::getCpuUsage(prev_times_); if (tooltipEnabled()) { label_.set_tooltip_text(tooltip); } @@ -52,17 +52,17 @@ auto waybar::modules::CpuUsage::update() -> void { ALabel::update(); } -std::tuple, std::string> waybar::modules::CpuUsage::getCpuUsage() { - if (prev_times_.empty()) { - prev_times_ = parseCpuinfo(); +std::tuple, std::string> waybar::modules::CpuUsage::getCpuUsage(std::vector>& prev_times) { + if (prev_times.empty()) { + prev_times = CpuUsage::parseCpuinfo(); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } - std::vector> curr_times = parseCpuinfo(); + std::vector> curr_times = CpuUsage::parseCpuinfo(); std::string tooltip; std::vector usage; 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]; + 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); @@ -73,6 +73,6 @@ std::tuple, std::string> waybar::modules::CpuUsage::getCpu } usage.push_back(tmp); } - prev_times_ = curr_times; + prev_times = curr_times; return {usage, tooltip}; } From 8d7341da6e9a5186dcba8f993123c2d4d151bd99 Mon Sep 17 00:00:00 2001 From: Mann mit Hut Date: Sat, 29 Jul 2023 16:02:36 +0200 Subject: [PATCH 08/12] cpu module: Reuse getLoad of load module --- include/modules/cpu.hpp | 2 -- include/modules/load.hpp | 4 +++- src/modules/cpu/common.cpp | 13 +++---------- src/modules/load.cpp | 2 +- 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/include/modules/cpu.hpp b/include/modules/cpu.hpp index aff4c508..7f78c165 100644 --- a/include/modules/cpu.hpp +++ b/include/modules/cpu.hpp @@ -21,8 +21,6 @@ class Cpu : public ALabel { auto update() -> void override; private: - double getCpuLoad(); - std::vector> prev_times_; util::SleeperThread thread_; diff --git a/include/modules/load.hpp b/include/modules/load.hpp index e4e91213..2c4ce610 100644 --- a/include/modules/load.hpp +++ b/include/modules/load.hpp @@ -20,8 +20,10 @@ class Load : public ALabel { virtual ~Load() = default; auto update() -> void override; + // This is a static member because it is also used by the cpu module. + static std::tuple getLoad(); + private: - std::tuple getLoad(); util::SleeperThread thread_; }; diff --git a/src/modules/cpu/common.cpp b/src/modules/cpu/common.cpp index 5259dcb9..8373d79e 100644 --- a/src/modules/cpu/common.cpp +++ b/src/modules/cpu/common.cpp @@ -1,6 +1,7 @@ #include "modules/cpu.hpp" #include "modules/cpu_frequency.hpp" #include "modules/cpu_usage.hpp" +#include "modules/load.hpp" // In the 80000 version of fmt library authors decided to optimize imports // and moved declarations required for fmt::dynamic_format_arg_store in new @@ -21,7 +22,7 @@ waybar::modules::Cpu::Cpu(const std::string& id, const Json::Value& config) 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 [load1, load5, load15] = Load::getLoad(); auto [cpu_usage, tooltip] = CpuUsage::getCpuUsage(prev_times_); auto [max_frequency, min_frequency, avg_frequency] = CpuFrequency::getCpuFrequency(); if (tooltipEnabled()) { @@ -40,7 +41,7 @@ auto waybar::modules::Cpu::update() -> void { event_box_.show(); auto icons = std::vector{state}; fmt::dynamic_format_arg_store store; - store.push_back(fmt::arg("load", cpu_load)); + store.push_back(fmt::arg("load", load1)); store.push_back(fmt::arg("usage", total_usage)); store.push_back(fmt::arg("icon", getIcon(total_usage, icons))); store.push_back(fmt::arg("max_frequency", max_frequency)); @@ -59,11 +60,3 @@ auto waybar::modules::Cpu::update() -> void { // Call parent update ALabel::update(); } - -double waybar::modules::Cpu::getCpuLoad() { - double load[1]; - if (getloadavg(load, 1) != -1) { - return std::ceil(load[0] * 100.0) / 100.0; - } - throw std::runtime_error("Can't get Cpu load"); -} diff --git a/src/modules/load.cpp b/src/modules/load.cpp index 9ee4b764..69a37b4e 100644 --- a/src/modules/load.cpp +++ b/src/modules/load.cpp @@ -19,7 +19,7 @@ waybar::modules::Load::Load(const std::string& id, const Json::Value& config) auto waybar::modules::Load::update() -> void { // TODO: as creating dynamic fmt::arg arrays is buggy we have to calc both - auto [load1, load5, load15] = getLoad(); + auto [load1, load5, load15] = Load::getLoad(); if (tooltipEnabled()) { auto tooltip = fmt::format("Load 1: {}\nLoad 5: {}\nLoad 15: {}", load1, load5, load15); label_.set_tooltip_text(tooltip); From 93d66a92589dd3c6f52fd7c81e38db65a233945f Mon Sep 17 00:00:00 2001 From: Mann mit Hut Date: Sat, 29 Jul 2023 16:27:46 +0200 Subject: [PATCH 09/12] Moved cpu/common.cpp to cpu.cpp --- meson.build | 4 ++-- src/modules/{cpu/common.cpp => cpu.cpp} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename src/modules/{cpu/common.cpp => cpu.cpp} (100%) diff --git a/meson.build b/meson.build index 3bb79d43..f4af7c67 100644 --- a/meson.build +++ b/meson.build @@ -188,7 +188,7 @@ if is_linux add_project_arguments('-DHAVE_MEMORY_LINUX', language: 'cpp') src_files += files( 'src/modules/battery.cpp', - 'src/modules/cpu/common.cpp', + 'src/modules/cpu.cpp', 'src/modules/cpu_frequency/common.cpp', 'src/modules/cpu_frequency/linux.cpp', 'src/modules/cpu_usage/common.cpp', @@ -200,7 +200,7 @@ elif is_dragonfly or is_freebsd or is_netbsd or is_openbsd add_project_arguments('-DHAVE_CPU_BSD', language: 'cpp') add_project_arguments('-DHAVE_MEMORY_BSD', language: 'cpp') src_files += files( - 'src/modules/cpu/common.cpp', + 'src/modules/cpu.cpp', 'src/modules/cpu_usage/bsd.cpp', 'src/modules/cpu_usage/common.cpp', 'src/modules/memory/bsd.cpp', diff --git a/src/modules/cpu/common.cpp b/src/modules/cpu.cpp similarity index 100% rename from src/modules/cpu/common.cpp rename to src/modules/cpu.cpp From 91b66291039a6dbdbb79e6fc4b5fde0e8e141fbd Mon Sep 17 00:00:00 2001 From: Mann mit Hut Date: Wed, 13 Sep 2023 21:59:42 +0200 Subject: [PATCH 10/12] Fixed format errors --- src/modules/cpu.cpp | 1 + src/modules/cpu_usage/common.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modules/cpu.cpp b/src/modules/cpu.cpp index 8373d79e..0703eaf7 100644 --- a/src/modules/cpu.cpp +++ b/src/modules/cpu.cpp @@ -1,4 +1,5 @@ #include "modules/cpu.hpp" + #include "modules/cpu_frequency.hpp" #include "modules/cpu_usage.hpp" #include "modules/load.hpp" diff --git a/src/modules/cpu_usage/common.cpp b/src/modules/cpu_usage/common.cpp index ffa54ae0..4e36f48e 100644 --- a/src/modules/cpu_usage/common.cpp +++ b/src/modules/cpu_usage/common.cpp @@ -52,7 +52,8 @@ auto waybar::modules::CpuUsage::update() -> void { ALabel::update(); } -std::tuple, std::string> waybar::modules::CpuUsage::getCpuUsage(std::vector>& prev_times) { +std::tuple, std::string> waybar::modules::CpuUsage::getCpuUsage( + std::vector>& prev_times) { if (prev_times.empty()) { prev_times = CpuUsage::parseCpuinfo(); std::this_thread::sleep_for(std::chrono::milliseconds(100)); From d5203e5b379077da262834f11fa30bfd6436c293 Mon Sep 17 00:00:00 2001 From: Mann mit Hut Date: Wed, 13 Sep 2023 23:12:35 +0200 Subject: [PATCH 11/12] Fixed cpu module: Provide stub implementation for parseCpuFrequencies --- meson.build | 2 ++ src/factory.cpp | 2 ++ src/modules/cpu_frequency/bsd.cpp | 15 +++++++++++++++ 3 files changed, 19 insertions(+) create mode 100644 src/modules/cpu_frequency/bsd.cpp diff --git a/meson.build b/meson.build index f4af7c67..0dab053e 100644 --- a/meson.build +++ b/meson.build @@ -201,6 +201,8 @@ elif is_dragonfly or is_freebsd or is_netbsd or is_openbsd add_project_arguments('-DHAVE_MEMORY_BSD', language: 'cpp') src_files += files( 'src/modules/cpu.cpp', + 'src/modules/cpu_frequency/bsd.cpp', + 'src/modules/cpu_frequency/common.cpp', 'src/modules/cpu_usage/bsd.cpp', 'src/modules/cpu_usage/common.cpp', 'src/modules/memory/bsd.cpp', diff --git a/src/factory.cpp b/src/factory.cpp index 18b14427..d9d09ed1 100644 --- a/src/factory.cpp +++ b/src/factory.cpp @@ -99,9 +99,11 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name) const { if (ref == "cpu") { return new waybar::modules::Cpu(id, config_[name]); } +#if defined(HAVE_CPU_LINUX) if (ref == "cpu_frequency") { return new waybar::modules::CpuFrequency(id, config_[name]); } +#endif if (ref == "cpu_usage") { return new waybar::modules::CpuUsage(id, config_[name]); } diff --git a/src/modules/cpu_frequency/bsd.cpp b/src/modules/cpu_frequency/bsd.cpp new file mode 100644 index 00000000..8cbe4f85 --- /dev/null +++ b/src/modules/cpu_frequency/bsd.cpp @@ -0,0 +1,15 @@ +#include + +#include // NAN + +#include "modules/cpu_frequency.hpp" + +std::vector waybar::modules::CpuFrequency::parseCpuFrequencies() { + static std::vector frequencies; + if (frequencies.empty()) { + spdlog::warn( + "cpu/bsd: parseCpuFrequencies is not implemented, expect garbage in {*_frequency}"); + frequencies.push_back(NAN); + } + return frequencies; +} From 80a34eec81254c63d2dd9ebe3f4fa18e0a763fb9 Mon Sep 17 00:00:00 2001 From: Mann mit Hut Date: Wed, 13 Sep 2023 23:25:39 +0200 Subject: [PATCH 12/12] Fixed formatting again --- src/modules/cpu_frequency/bsd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/cpu_frequency/bsd.cpp b/src/modules/cpu_frequency/bsd.cpp index 8cbe4f85..c837c1fd 100644 --- a/src/modules/cpu_frequency/bsd.cpp +++ b/src/modules/cpu_frequency/bsd.cpp @@ -1,6 +1,6 @@ #include -#include // NAN +#include // NAN #include "modules/cpu_frequency.hpp"