commit
						6b73e2aa58
					
				|  | @ -38,6 +38,9 @@ | |||
| #endif | ||||
| #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" | ||||
| #if defined(HAVE_MEMORY_LINUX) || defined(HAVE_MEMORY_BSD) | ||||
|  |  | |||
|  | @ -21,12 +21,6 @@ class Cpu : public ALabel { | |||
|   auto update() -> void override; | ||||
| 
 | ||||
|  private: | ||||
|   double getCpuLoad(); | ||||
|   std::tuple<std::vector<uint16_t>, std::string> getCpuUsage(); | ||||
|   std::tuple<float, float, float> getCpuFrequency(); | ||||
|   std::vector<std::tuple<size_t, size_t>> parseCpuinfo(); | ||||
|   std::vector<float> parseCpuFrequencies(); | ||||
| 
 | ||||
|   std::vector<std::tuple<size_t, size_t>> prev_times_; | ||||
| 
 | ||||
|   util::SleeperThread thread_; | ||||
|  |  | |||
|  | @ -0,0 +1,32 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <fmt/format.h> | ||||
| 
 | ||||
| #include <cstdint> | ||||
| #include <fstream> | ||||
| #include <numeric> | ||||
| #include <string> | ||||
| #include <utility> | ||||
| #include <vector> | ||||
| 
 | ||||
| #include "ALabel.hpp" | ||||
| #include "util/sleeper_thread.hpp" | ||||
| 
 | ||||
| namespace waybar::modules { | ||||
| 
 | ||||
| class CpuFrequency : public ALabel { | ||||
|  public: | ||||
|   CpuFrequency(const std::string&, const Json::Value&); | ||||
|   virtual ~CpuFrequency() = default; | ||||
|   auto update() -> void override; | ||||
| 
 | ||||
|   // This is a static member because it is also used by the cpu module.
 | ||||
|   static std::tuple<float, float, float> getCpuFrequency(); | ||||
| 
 | ||||
|  private: | ||||
|   static std::vector<float> parseCpuFrequencies(); | ||||
| 
 | ||||
|   util::SleeperThread thread_; | ||||
| }; | ||||
| 
 | ||||
| }  // namespace waybar::modules
 | ||||
|  | @ -0,0 +1,34 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <fmt/format.h> | ||||
| 
 | ||||
| #include <cstdint> | ||||
| #include <fstream> | ||||
| #include <numeric> | ||||
| #include <string> | ||||
| #include <utility> | ||||
| #include <vector> | ||||
| 
 | ||||
| #include "ALabel.hpp" | ||||
| #include "util/sleeper_thread.hpp" | ||||
| 
 | ||||
| namespace waybar::modules { | ||||
| 
 | ||||
| class CpuUsage : public ALabel { | ||||
|  public: | ||||
|   CpuUsage(const std::string&, const Json::Value&); | ||||
|   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::vector<uint16_t>, std::string> getCpuUsage(std::vector<std::tuple<size_t, size_t>>&); | ||||
| 
 | ||||
|  private: | ||||
|   static std::vector<std::tuple<size_t, size_t>> parseCpuinfo(); | ||||
| 
 | ||||
|   std::vector<std::tuple<size_t, size_t>> prev_times_; | ||||
| 
 | ||||
|   util::SleeperThread thread_; | ||||
| }; | ||||
| 
 | ||||
| }  // namespace waybar::modules
 | ||||
|  | @ -0,0 +1,31 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <fmt/format.h> | ||||
| 
 | ||||
| #include <cstdint> | ||||
| #include <fstream> | ||||
| #include <numeric> | ||||
| #include <string> | ||||
| #include <utility> | ||||
| #include <vector> | ||||
| 
 | ||||
| #include "ALabel.hpp" | ||||
| #include "util/sleeper_thread.hpp" | ||||
| 
 | ||||
| namespace waybar::modules { | ||||
| 
 | ||||
| class Load : public ALabel { | ||||
|  public: | ||||
|   Load(const std::string&, const Json::Value&); | ||||
|   virtual ~Load() = default; | ||||
|   auto update() -> void override; | ||||
| 
 | ||||
|   // This is a static member because it is also used by the cpu module.
 | ||||
|   static std::tuple<double, double, double> getLoad(); | ||||
| 
 | ||||
|  private: | ||||
| 
 | ||||
|   util::SleeperThread thread_; | ||||
| }; | ||||
| 
 | ||||
| }  // namespace waybar::modules
 | ||||
							
								
								
									
										15
									
								
								meson.build
								
								
								
								
							
							
						
						
									
										15
									
								
								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/ASlider.cpp', | ||||
|  | @ -189,8 +190,11 @@ 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/linux.cpp', | ||||
|         'src/modules/cpu.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', | ||||
|     ) | ||||
|  | @ -198,8 +202,11 @@ 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.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', | ||||
|         'src/modules/memory/common.cpp', | ||||
|     ) | ||||
|  |  | |||
|  | @ -107,6 +107,17 @@ 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]); | ||||
|     } | ||||
|     if (ref == "load") { | ||||
|       return new waybar::modules::Load(id, config_[name]); | ||||
|     } | ||||
| #endif | ||||
|     if (ref == "clock") { | ||||
|       return new waybar::modules::Clock(id, config_[name]); | ||||
|  |  | |||
|  | @ -0,0 +1,63 @@ | |||
| #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
 | ||||
| // header fmt/args.h
 | ||||
| #if (FMT_VERSION >= 80000) | ||||
| #include <fmt/args.h> | ||||
| #else | ||||
| #include <fmt/core.h> | ||||
| #endif | ||||
| 
 | ||||
| waybar::modules::Cpu::Cpu(const std::string& id, const Json::Value& config) | ||||
|     : ALabel(config, "cpu", id, "{usage}%", 10) { | ||||
|   thread_ = [this] { | ||||
|     dp.emit(); | ||||
|     thread_.sleep_for(interval_); | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| auto waybar::modules::Cpu::update() -> void { | ||||
|   // TODO: as creating dynamic fmt::arg arrays is buggy we have to calc both
 | ||||
|   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()) { | ||||
|     label_.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<std::string>{state}; | ||||
|     fmt::dynamic_format_arg_store<fmt::format_context> store; | ||||
|     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)); | ||||
|     store.push_back(fmt::arg("min_frequency", min_frequency)); | ||||
|     store.push_back(fmt::arg("avg_frequency", avg_frequency)); | ||||
|     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
 | ||||
|   ALabel::update(); | ||||
| } | ||||
|  | @ -0,0 +1,15 @@ | |||
| #include <spdlog/spdlog.h> | ||||
| 
 | ||||
| #include <cmath>  // NAN
 | ||||
| 
 | ||||
| #include "modules/cpu_frequency.hpp" | ||||
| 
 | ||||
| std::vector<float> waybar::modules::CpuFrequency::parseCpuFrequencies() { | ||||
|   static std::vector<float> frequencies; | ||||
|   if (frequencies.empty()) { | ||||
|     spdlog::warn( | ||||
|         "cpu/bsd: parseCpuFrequencies is not implemented, expect garbage in {*_frequency}"); | ||||
|     frequencies.push_back(NAN); | ||||
|   } | ||||
|   return frequencies; | ||||
| } | ||||
|  | @ -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 <fmt/args.h> | ||||
| #else | ||||
| #include <fmt/core.h> | ||||
| #endif | ||||
| 
 | ||||
| waybar::modules::CpuFrequency::CpuFrequency(const std::string& id, const Json::Value& config) | ||||
|     : ALabel(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] = CpuFrequency::getCpuFrequency(); | ||||
|   if (tooltipEnabled()) { | ||||
|     auto tooltip = | ||||
|         fmt::format("Minimum frequency: {}\nAverage frequency: {}\nMaximum frequency: {}\n", | ||||
|                     min_frequency, avg_frequency, max_frequency); | ||||
|     label_.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<std::string>{state}; | ||||
|     fmt::dynamic_format_arg_store<fmt::format_context> 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
 | ||||
|   ALabel::update(); | ||||
| } | ||||
| 
 | ||||
| std::tuple<float, float, float> waybar::modules::CpuFrequency::getCpuFrequency() { | ||||
|   std::vector<float> frequencies = CpuFrequency::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}; | ||||
| } | ||||
|  | @ -1,36 +1,8 @@ | |||
| #include <filesystem> | ||||
| 
 | ||||
| #include "modules/cpu.hpp" | ||||
| #include "modules/cpu_frequency.hpp" | ||||
| 
 | ||||
| std::vector<std::tuple<size_t, size_t>> 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<std::tuple<size_t, size_t>> 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<size_t> 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; | ||||
| } | ||||
| 
 | ||||
| std::vector<float> waybar::modules::Cpu::parseCpuFrequencies() { | ||||
| std::vector<float> waybar::modules::CpuFrequency::parseCpuFrequencies() { | ||||
|   const std::string file_path_ = "/proc/cpuinfo"; | ||||
|   std::ifstream info(file_path_); | ||||
|   if (!info.is_open()) { | ||||
|  | @ -8,7 +8,7 @@ | |||
| #include <cmath>    // NAN
 | ||||
| #include <cstdlib>  // malloc
 | ||||
| 
 | ||||
| #include "modules/cpu.hpp" | ||||
| #include "modules/cpu_usage.hpp" | ||||
| 
 | ||||
| #if defined(__NetBSD__) || defined(__OpenBSD__) | ||||
| #include <sys/sched.h> | ||||
|  | @ -27,7 +27,7 @@ typedef uint64_t pcp_time_t; | |||
| typedef long pcp_time_t; | ||||
| #endif | ||||
| 
 | ||||
| std::vector<std::tuple<size_t, size_t>> waybar::modules::Cpu::parseCpuinfo() { | ||||
| std::vector<std::tuple<size_t, size_t>> 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); | ||||
|  | @ -100,13 +100,3 @@ std::vector<std::tuple<size_t, size_t>> waybar::modules::Cpu::parseCpuinfo() { | |||
|   free(cp_time); | ||||
|   return cpuinfo; | ||||
| } | ||||
| 
 | ||||
| std::vector<float> waybar::modules::Cpu::parseCpuFrequencies() { | ||||
|   static std::vector<float> frequencies; | ||||
|   if (frequencies.empty()) { | ||||
|     spdlog::warn( | ||||
|         "cpu/bsd: parseCpuFrequencies is not implemented, expect garbage in {*_frequency}"); | ||||
|     frequencies.push_back(NAN); | ||||
|   } | ||||
|   return frequencies; | ||||
| } | ||||
|  | @ -1,4 +1,4 @@ | |||
| #include "modules/cpu.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
 | ||||
|  | @ -9,19 +9,17 @@ | |||
| #include <fmt/core.h> | ||||
| #endif | ||||
| 
 | ||||
| waybar::modules::Cpu::Cpu(const std::string& id, const Json::Value& config) | ||||
|     : ALabel(config, "cpu", id, "{usage}%", 10) { | ||||
| waybar::modules::CpuUsage::CpuUsage(const std::string& id, const Json::Value& config) | ||||
|     : ALabel(config, "cpu_usage", id, "{usage}%", 10) { | ||||
|   thread_ = [this] { | ||||
|     dp.emit(); | ||||
|     thread_.sleep_for(interval_); | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| auto waybar::modules::Cpu::update() -> void { | ||||
| auto waybar::modules::CpuUsage::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 [cpu_usage, tooltip] = CpuUsage::getCpuUsage(prev_times_); | ||||
|   if (tooltipEnabled()) { | ||||
|     label_.set_tooltip_text(tooltip); | ||||
|   } | ||||
|  | @ -38,12 +36,8 @@ auto waybar::modules::Cpu::update() -> void { | |||
|     event_box_.show(); | ||||
|     auto icons = std::vector<std::string>{state}; | ||||
|     fmt::dynamic_format_arg_store<fmt::format_context> store; | ||||
|     store.push_back(fmt::arg("load", cpu_load)); | ||||
|     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)); | ||||
|     store.push_back(fmt::arg("min_frequency", min_frequency)); | ||||
|     store.push_back(fmt::arg("avg_frequency", avg_frequency)); | ||||
|     for (size_t i = 1; i < cpu_usage.size(); ++i) { | ||||
|       auto core_i = i - 1; | ||||
|       auto core_format = fmt::format("usage{}", core_i); | ||||
|  | @ -58,25 +52,18 @@ auto waybar::modules::Cpu::update() -> void { | |||
|   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"); | ||||
| } | ||||
| 
 | ||||
| std::tuple<std::vector<uint16_t>, std::string> waybar::modules::Cpu::getCpuUsage() { | ||||
|   if (prev_times_.empty()) { | ||||
|     prev_times_ = parseCpuinfo(); | ||||
| std::tuple<std::vector<uint16_t>, std::string> waybar::modules::CpuUsage::getCpuUsage( | ||||
|     std::vector<std::tuple<size_t, size_t>>& prev_times) { | ||||
|   if (prev_times.empty()) { | ||||
|     prev_times = CpuUsage::parseCpuinfo(); | ||||
|     std::this_thread::sleep_for(std::chrono::milliseconds(100)); | ||||
|   } | ||||
|   std::vector<std::tuple<size_t, size_t>> curr_times = parseCpuinfo(); | ||||
|   std::vector<std::tuple<size_t, size_t>> curr_times = CpuUsage::parseCpuinfo(); | ||||
|   std::string tooltip; | ||||
|   std::vector<uint16_t> 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); | ||||
|  | @ -87,23 +74,6 @@ std::tuple<std::vector<uint16_t>, std::string> waybar::modules::Cpu::getCpuUsage | |||
|     } | ||||
|     usage.push_back(tmp); | ||||
|   } | ||||
|   prev_times_ = curr_times; | ||||
|   prev_times = curr_times; | ||||
|   return {usage, tooltip}; | ||||
| } | ||||
| 
 | ||||
| std::tuple<float, float, float> waybar::modules::Cpu::getCpuFrequency() { | ||||
|   std::vector<float> 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}; | ||||
| } | ||||
|  | @ -0,0 +1,31 @@ | |||
| #include <filesystem> | ||||
| 
 | ||||
| #include "modules/cpu_usage.hpp" | ||||
| 
 | ||||
| std::vector<std::tuple<size_t, size_t>> 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<std::tuple<size_t, size_t>> 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<size_t> 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; | ||||
| } | ||||
|  | @ -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 <fmt/args.h> | ||||
| #else | ||||
| #include <fmt/core.h> | ||||
| #endif | ||||
| 
 | ||||
| waybar::modules::Load::Load(const std::string& id, const Json::Value& config) | ||||
|     : ALabel(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] = Load::getLoad(); | ||||
|   if (tooltipEnabled()) { | ||||
|     auto tooltip = fmt::format("Load 1: {}\nLoad 5: {}\nLoad 15: {}", load1, load5, load15); | ||||
|     label_.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<std::string>{state}; | ||||
|     fmt::dynamic_format_arg_store<fmt::format_context> 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
 | ||||
|   ALabel::update(); | ||||
| } | ||||
| 
 | ||||
| std::tuple<double, double, double> 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 system load"); | ||||
| } | ||||
		Loading…
	
		Reference in New Issue