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.
This commit is contained in:
Mann mit Hut 2022-12-21 17:44:11 +01:00
parent 4d32991bee
commit 729564cc27
No known key found for this signature in database
GPG Key ID: 02D4D60B8250CB8C
5 changed files with 95 additions and 0 deletions

View File

@ -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)

29
include/modules/load.hpp Normal file
View File

@ -0,0 +1,29 @@
#pragma once
#include <fmt/format.h>
#include <cstdint>
#include <fstream>
#include <numeric>
#include <string>
#include <utility>
#include <vector>
#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<double, double, double> getLoad();
util::SleeperThread thread_;
};
} // namespace waybar::modules

View File

@ -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',

View File

@ -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]);

61
src/modules/load.cpp Normal file
View File

@ -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)
: 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<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
AButton::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 Cpu load");
}