TaskBar: Show CPU load in task bar!

This commit is contained in:
2026-05-20 19:14:21 +03:00
parent f6679eb4b5
commit d5ee98708b

View File

@@ -4,9 +4,10 @@
#include <dirent.h> #include <dirent.h>
#include <fcntl.h> #include <fcntl.h>
#include <time.h> #include <inttypes.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <time.h>
static BAN::ErrorOr<long long> read_integer_from_file(const char* file) static BAN::ErrorOr<long long> read_integer_from_file(const char* file)
{ {
@@ -63,6 +64,77 @@ static BAN::String get_battery_percentage()
return result; return result;
} }
static BAN::String get_cpu_load(bool show_long)
{
struct LoadStats
{
uint64_t idle_ns;
uint64_t total_ns;
};
static BAN::Vector<LoadStats> cpu_stats;
BAN::Vector<LoadStats> delta_stats;
(void)delta_stats.reserve(show_long ? cpu_stats.size() : 1);
for (size_t i = 0;; i++)
{
char buffer[PATH_MAX];
sprintf(buffer, "/proc/cpu/%zu", i);
FILE* fp = fopen(buffer, "r");
if (fp == nullptr)
break;
LoadStats stats;
if (fscanf(fp, "%" SCNu64 " %" SCNu64, &stats.idle_ns, &stats.total_ns) == 2)
{
if (i >= cpu_stats.size())
MUST(cpu_stats.resize(i + 1, {}));
const LoadStats delta {
.idle_ns = stats.idle_ns - cpu_stats[i].idle_ns,
.total_ns = stats.total_ns - cpu_stats[i].total_ns,
};
cpu_stats[i] = stats;
if (show_long)
(void)delta_stats.push_back(delta);
else
{
if (delta_stats.empty())
(void)delta_stats.push_back(delta);
else
{
delta_stats[0].idle_ns += delta.idle_ns;
delta_stats[0].total_ns += delta.total_ns;
}
}
}
fclose(fp);
}
BAN::String result;
(void)result.append("CPU");
for (size_t i = 0; i < delta_stats.size(); i++)
{
const uint64_t idle_10000 = 10'000 * delta_stats[i].idle_ns / delta_stats[i].total_ns;
const uint64_t load_10000 = 10'000 - idle_10000;
auto string = BAN::String::formatted(" {}.{2}%", load_10000 / 100, load_10000 % 100);
if (string.is_error())
continue;
(void)result.append(string.release_value());
}
(void)result.append(" | "_sv);
return result;
}
static int open_audio_server_fd() static int open_audio_server_fd()
{ {
int fd = socket(AF_UNIX, SOCK_STREAM, 0); int fd = socket(AF_UNIX, SOCK_STREAM, 0);
@@ -106,10 +178,12 @@ static BAN::String get_audio_volume()
return MUST(BAN::String::formatted("vol {}% | ", response / 10)); return MUST(BAN::String::formatted("vol {}% | ", response / 10));
} }
static BAN::ErrorOr<BAN::String> get_task_bar_string() static BAN::ErrorOr<BAN::String> get_task_bar_string(bool show_long)
{ {
BAN::String result; BAN::String result;
TRY(result.append(get_cpu_load(show_long)));
TRY(result.append(get_battery_percentage())); TRY(result.append(get_battery_percentage()));
TRY(result.append(get_audio_volume())); TRY(result.append(get_audio_volume()));
@@ -144,6 +218,12 @@ int main()
window->set_position(0, 0); window->set_position(0, 0);
bool show_long = false;
window->set_mouse_button_event_callback([&](auto event) {
if (event.pressed)
show_long = !show_long;
});
window->texture().fill(bg_color); window->texture().fill(bg_color);
window->invalidate(); window->invalidate();
@@ -153,7 +233,7 @@ int main()
const auto update_string = const auto update_string =
[&]() [&]()
{ {
auto text_or_error = get_task_bar_string(); auto text_or_error = get_task_bar_string(show_long);
if (text_or_error.is_error()) if (text_or_error.is_error())
return; return;
const auto text = text_or_error.release_value(); const auto text = text_or_error.release_value();
@@ -176,6 +256,8 @@ int main()
while (is_running) while (is_running)
{ {
window->poll_events();
update_string(); update_string();
constexpr uint64_t ns_per_s = 1'000'000'000; constexpr uint64_t ns_per_s = 1'000'000'000;
@@ -193,10 +275,10 @@ int main()
uint64_t sleep_ns = target_ns - current_ns; uint64_t sleep_ns = target_ns - current_ns;
timespec sleep_ts; timespec timeout_ts;
sleep_ts.tv_sec = sleep_ns / ns_per_s; timeout_ts.tv_sec = sleep_ns / ns_per_s;
sleep_ts.tv_nsec = sleep_ns % ns_per_s; timeout_ts.tv_nsec = sleep_ns % ns_per_s;
nanosleep(&sleep_ts, nullptr); window->wait_events(&timeout_ts);
} }
} }