Merge branch 'main' into config-trailing-newline

This commit is contained in:
Jakob P. Liljenberg 2024-02-11 16:45:56 +01:00 committed by GitHub
commit c7fdd8adfe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 198 additions and 54 deletions

View file

@ -65,6 +65,8 @@ if(APPLE)
target_sources(btop PRIVATE src/osx/btop_collect.cpp src/osx/sensors.cpp src/osx/smc.cpp) target_sources(btop PRIVATE src/osx/btop_collect.cpp src/osx/sensors.cpp src/osx/smc.cpp)
elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
target_sources(btop PRIVATE src/freebsd/btop_collect.cpp) target_sources(btop PRIVATE src/freebsd/btop_collect.cpp)
elseif(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
target_sources(btop PRIVATE src/openbsd/btop_collect.cpp src/openbsd/sysctlbyname.cpp)
elseif(LINUX) elseif(LINUX)
target_sources(btop PRIVATE src/linux/btop_collect.cpp) target_sources(btop PRIVATE src/linux/btop_collect.cpp)
else() else()
@ -110,6 +112,7 @@ if(HAS_FCF_PROTECTION)
endif() endif()
target_compile_definitions(btop PRIVATE target_compile_definitions(btop PRIVATE
FMT_HEADER_ONLY
_FILE_OFFSET_BITS=64 _FILE_OFFSET_BITS=64
$<$<CONFIG:Debug>:_GLIBCXX_ASSERTIONS _LIBCPP_ENABLE_ASSERTIONS=1> $<$<CONFIG:Debug>:_GLIBCXX_ASSERTIONS _LIBCPP_ENABLE_ASSERTIONS=1>
# Only has an effect with optimizations enabled # Only has an effect with optimizations enabled
@ -185,6 +188,12 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
find_package(kvm REQUIRED) find_package(kvm REQUIRED)
target_link_libraries(btop elf::elf kvm::kvm) target_link_libraries(btop elf::elf kvm::kvm)
endif() endif()
elseif(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_compile_options(btop PRIVATE -static-libstdc++)
endif()
find_package(kvm REQUIRED)
target_link_libraries(btop kvm::kvm)
endif() endif()
install(TARGETS btop RUNTIME) install(TARGETS btop RUNTIME)

View file

@ -143,7 +143,7 @@ else ifeq ($(PLATFORM_LC),macos)
else ifeq ($(PLATFORM_LC),openbsd) else ifeq ($(PLATFORM_LC),openbsd)
PLATFORM_DIR := openbsd PLATFORM_DIR := openbsd
THREADS := $(shell sysctl -n hw.ncpu || echo 1) THREADS := $(shell sysctl -n hw.ncpu || echo 1)
override ADDFLAGS += -lkvm override ADDFLAGS += -lkvm -static-libstdc++
export MAKE = gmake export MAKE = gmake
SU_GROUP := wheel SU_GROUP := wheel
else else
@ -179,7 +179,7 @@ override GOODFLAGS := $(foreach flag,$(TESTFLAGS),$(strip $(shell echo "int main
override REQFLAGS := -std=c++20 override REQFLAGS := -std=c++20
WARNFLAGS := -Wall -Wextra -pedantic WARNFLAGS := -Wall -Wextra -pedantic
OPTFLAGS := -O2 -ftree-vectorize -flto=$(LTO) OPTFLAGS := -O2 -ftree-vectorize -flto=$(LTO)
LDCXXFLAGS := -pthread -D_GLIBCXX_ASSERTIONS -D_FILE_OFFSET_BITS=64 $(GOODFLAGS) $(ADDFLAGS) LDCXXFLAGS := -pthread -DFMT_HEADER_ONLY -D_GLIBCXX_ASSERTIONS -D_FILE_OFFSET_BITS=64 $(GOODFLAGS) $(ADDFLAGS)
override CXXFLAGS += $(REQFLAGS) $(LDCXXFLAGS) $(OPTFLAGS) $(WARNFLAGS) override CXXFLAGS += $(REQFLAGS) $(LDCXXFLAGS) $(OPTFLAGS) $(WARNFLAGS)
override LDFLAGS += $(LDCXXFLAGS) $(OPTFLAGS) $(WARNFLAGS) override LDFLAGS += $(LDCXXFLAGS) $(OPTFLAGS) $(WARNFLAGS)
INC := $(foreach incdir,$(INCDIRS),-isystem $(incdir)) -I$(SRCDIR) INC := $(foreach incdir,$(INCDIRS),-isystem $(incdir)) -I$(SRCDIR)

View file

@ -995,6 +995,74 @@ If you have an AMD GPU `rocm_smi_lib` is required, which may or may not be packa
gmake help gmake help
``` ```
</details>
<details>
<summary>
### With CMake (Community maintained)
</summary>
1. **Install build dependencies**
Requires GCC, CMake, Ninja and Git
_**Note:** LLVM's libc++ shipped with OpenBSD 7.4 is too old and cannot compile btop._
```bash
pkg_add cmake g++%11 git ninja
```
2. **Clone the repository**
```bash
git clone https://github.com/aristocratos/btop.git && cd btop
```
3. **Compile**
```bash
# Configure
CXX=eg++ cmake -B build -G Ninja
# Build
cmake --build build
```
This will automatically build a release version of btop.
Some useful options to pass to the configure step:
| Configure flag | Description |
|---------------------------------|-------------------------------------------------------------------------|
| `-DBTOP_LTO=<ON\|OFF>` | Enables link time optimization (ON by default) |
| `-DBTOP_USE_MOLD=<ON\|OFF>` | Use mold to link btop (OFF by default) |
| `-DBTOP_PEDANTIC=<ON\|OFF>` | Compile with additional warnings (OFF by default) |
| `-DBTOP_WERROR=<ON\|OFF>` | Compile with warnings as errors (OFF by default) |
| `-DBTOP_FORTIFY=<ON\|OFF>` | Detect buffer overflows with `_FORTIFY_SOURCE=3` (ON by default) |
| `-DCMAKE_INSTALL_PREFIX=<path>` | The installation prefix ('/usr/local' by default) |
To force any other compiler, run `CXX=<compiler> cmake -B build -G Ninja`
4. **Install**
```bash
cmake --install build
```
May require root privileges
5. **Uninstall**
CMake doesn't generate an uninstall target by default. To remove installed files, run
```
cat build/install_manifest.txt | xargs rm -irv
```
6. **Cleanup build directory**
```bash
cmake --build build -t clean
```
</details> </details>
## Installing the snap ## Installing the snap

View file

@ -3,7 +3,7 @@
# Find libkvm, the Kernel Data Access Library # Find libkvm, the Kernel Data Access Library
# #
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") if(BSD)
find_path(kvm_INCLUDE_DIR NAMES kvm.h) find_path(kvm_INCLUDE_DIR NAMES kvm.h)
find_library(kvm_LIBRARY NAMES kvm) find_library(kvm_LIBRARY NAMES kvm)

View file

@ -53,6 +53,7 @@ tab-size = 4
#include "btop_draw.hpp" #include "btop_draw.hpp"
#include "btop_menu.hpp" #include "btop_menu.hpp"
#include "fmt/core.h" #include "fmt/core.h"
#include "fmt/ostream.h"
using std::atomic; using std::atomic;
using std::cout; using std::cout;

View file

@ -199,6 +199,8 @@ namespace Config {
{"selected_battery", "#* Which battery to use if multiple are present. \"Auto\" for auto detection."}, {"selected_battery", "#* Which battery to use if multiple are present. \"Auto\" for auto detection."},
{"show_battery_watts", "#* Show power stats of battery next to charge indicator."},
{"log_level", "#* Set loglevel for \"~/.config/btop/btop.log\" levels are: \"ERROR\" \"WARNING\" \"INFO\" \"DEBUG\".\n" {"log_level", "#* Set loglevel for \"~/.config/btop/btop.log\" levels are: \"ERROR\" \"WARNING\" \"INFO\" \"DEBUG\".\n"
"#* The level set includes all lower levels, i.e. \"DEBUG\" will show all logging info."}, "#* The level set includes all lower levels, i.e. \"DEBUG\" will show all logging info."},
#ifdef GPU_SUPPORT #ifdef GPU_SUPPORT
@ -293,6 +295,7 @@ namespace Config {
{"net_auto", true}, {"net_auto", true},
{"net_sync", true}, {"net_sync", true},
{"show_battery", true}, {"show_battery", true},
{"show_battery_watts", true},
{"vim_keys", false}, {"vim_keys", false},
{"tty_mode", false}, {"tty_mode", false},
{"disk_free_priv", false}, {"disk_free_priv", false},

View file

@ -706,6 +706,7 @@ namespace Cpu {
if (Config::getB("show_battery") and has_battery) { if (Config::getB("show_battery") and has_battery) {
static int old_percent{}; // defaults to = 0 static int old_percent{}; // defaults to = 0
static long old_seconds{}; // defaults to = 0 static long old_seconds{}; // defaults to = 0
static float old_watts{}; // defaults to = 0
static string old_status; static string old_status;
static Draw::Meter bat_meter {10, "cpu", true}; static Draw::Meter bat_meter {10, "cpu", true};
static const std::unordered_map<string, string> bat_symbols = { static const std::unordered_map<string, string> bat_symbols = {
@ -715,16 +716,18 @@ namespace Cpu {
{"unknown", ""} {"unknown", ""}
}; };
const auto& [percent, seconds, status] = current_bat; const auto& [percent, watts, seconds, status] = current_bat;
if (redraw or percent != old_percent or seconds != old_seconds or status != old_status) { if (redraw or percent != old_percent or (watts != old_watts and Config::getB("show_battery_watts")) or seconds != old_seconds or status != old_status) {
old_percent = percent; old_percent = percent;
old_watts = watts;
old_seconds = seconds; old_seconds = seconds;
old_status = status; old_status = status;
const string str_time = (seconds > 0 ? sec_to_dhms(seconds, true, true) : ""); const string str_time = (seconds > 0 ? sec_to_dhms(seconds, true, true) : "");
const string str_percent = to_string(percent) + '%'; const string str_percent = to_string(percent) + '%';
const string str_watts = (watts != -1 and Config::getB("show_battery_watts") ? fmt::format("{:.2f}", watts) + 'W' : "");
const auto& bat_symbol = bat_symbols.at((bat_symbols.contains(status) ? status : "unknown")); const auto& bat_symbol = bat_symbols.at((bat_symbols.contains(status) ? status : "unknown"));
const int current_len = (Term::width >= 100 ? 11 : 0) + str_time.size() + str_percent.size() + to_string(Config::getI("update_ms")).size(); const int current_len = (Term::width >= 100 ? 11 : 0) + str_time.size() + str_percent.size() + str_watts.size() + to_string(Config::getI("update_ms")).size();
const int current_pos = Term::width - current_len - 17; const int current_pos = Term::width - current_len - 17;
if ((bat_pos != current_pos or bat_len != current_len) and bat_pos > 0 and not redraw) if ((bat_pos != current_pos or bat_len != current_len) and bat_pos > 0 and not redraw)
@ -734,7 +737,7 @@ namespace Cpu {
out += Mv::to(y, bat_pos) + title_left + Theme::c("title") + Fx::b + "BAT" + bat_symbol + ' ' + str_percent out += Mv::to(y, bat_pos) + title_left + Theme::c("title") + Fx::b + "BAT" + bat_symbol + ' ' + str_percent
+ (Term::width >= 100 ? Fx::ub + ' ' + bat_meter(percent) + Fx::b : "") + (Term::width >= 100 ? Fx::ub + ' ' + bat_meter(percent) + Fx::b : "")
+ (not str_time.empty() ? ' ' + Theme::c("title") + str_time : " ") + Fx::ub + title_right; + (not str_time.empty() ? ' ' + Theme::c("title") + str_time : "") + (not str_watts.empty() ? " " + Theme::c("title") + Fx::b + str_watts : "") + Fx::ub + title_right;
} }
} }
else if (bat_pos > 0) { else if (bat_pos > 0) {
@ -1361,6 +1364,7 @@ namespace Net {
int x = 1, y, width = 20, height; int x = 1, y, width = 20, height;
int b_x, b_y, b_width, b_height, d_graph_height, u_graph_height; int b_x, b_y, b_width, b_height, d_graph_height, u_graph_height;
bool shown = true, redraw = true; bool shown = true, redraw = true;
const int MAX_IFNAMSIZ = 15;
string old_ip; string old_ip;
std::unordered_map<string, Draw::Graph> graphs; std::unordered_map<string, Draw::Graph> graphs;
string box; string box;
@ -1381,7 +1385,7 @@ namespace Net {
out.reserve(width * height); out.reserve(width * height);
const string title_left = Theme::c("net_box") + Fx::ub + Symbols::title_left; const string title_left = Theme::c("net_box") + Fx::ub + Symbols::title_left;
const string title_right = Theme::c("net_box") + Fx::ub + Symbols::title_right; const string title_right = Theme::c("net_box") + Fx::ub + Symbols::title_right;
const int i_size = min((int)selected_iface.size(), 10); const int i_size = min((int)selected_iface.size(), MAX_IFNAMSIZ);
const long long down_max = (net_auto ? safeVal(graph_max, "download"s) : ((long long)(Config::getI("net_download")) << 20) / 8); const long long down_max = (net_auto ? safeVal(graph_max, "download"s) : ((long long)(Config::getI("net_download")) << 20) / 8);
const long long up_max = (net_auto ? safeVal(graph_max, "upload"s) : ((long long)(Config::getI("net_upload")) << 20) / 8); const long long up_max = (net_auto ? safeVal(graph_max, "upload"s) : ((long long)(Config::getI("net_upload")) << 20) / 8);
@ -1403,7 +1407,7 @@ namespace Net {
//? Interface selector and buttons //? Interface selector and buttons
out += Mv::to(y, x+width - i_size - 9) + title_left + Fx::b + Theme::c("hi_fg") + "<b " + Theme::c("title") out += Mv::to(y, x+width - i_size - 9) + title_left + Fx::b + Theme::c("hi_fg") + "<b " + Theme::c("title")
+ uresize(selected_iface, 10) + Theme::c("hi_fg") + " n>" + title_right + uresize(selected_iface, MAX_IFNAMSIZ) + Theme::c("hi_fg") + " n>" + title_right
+ Mv::to(y, x+width - i_size - 15) + title_left + Theme::c("hi_fg") + (safeVal(net.stat, "download"s).offset + safeVal(net.stat, "upload"s).offset > 0 ? Fx::b : "") + 'z' + Mv::to(y, x+width - i_size - 15) + title_left + Theme::c("hi_fg") + (safeVal(net.stat, "download"s).offset + safeVal(net.stat, "upload"s).offset > 0 ? Fx::b : "") + 'z'
+ Theme::c("title") + "ero" + title_right; + Theme::c("title") + "ero" + title_right;
Input::mouse_mappings["b"] = {y, x+width - i_size - 8, 1, 3}; Input::mouse_mappings["b"] = {y, x+width - i_size - 8, 1, 3};
@ -2238,3 +2242,4 @@ namespace Draw {
} }
} }
} }

View file

@ -353,6 +353,11 @@ namespace Menu {
"Can be both batteries and UPS.", "Can be both batteries and UPS.",
"", "",
"\"Auto\" for auto detection."}, "\"Auto\" for auto detection."},
{"show_battery_watts",
"Show battery power.",
"",
"Show discharge power when discharging.",
"Show charging power when charging."},
{"log_level", {"log_level",
"Set loglevel for error.log", "Set loglevel for error.log",
"", "",

View file

@ -178,7 +178,7 @@ namespace Cpu {
extern string cpuName, cpuHz; extern string cpuName, cpuHz;
extern vector<string> available_fields; extern vector<string> available_fields;
extern vector<string> available_sensors; extern vector<string> available_sensors;
extern tuple<int, long, string> current_bat; extern tuple<int, float, long, string> current_bat;
struct cpu_info { struct cpu_info {
std::unordered_map<string, deque<long long>> cpu_percent = { std::unordered_map<string, deque<long long>> cpu_percent = {
@ -213,7 +213,7 @@ namespace Cpu {
auto get_cpuHz() -> string; auto get_cpuHz() -> string;
//* Get battery info from /sys //* Get battery info from /sys
auto get_battery() -> tuple<int, long, string>; auto get_battery() -> tuple<int, float, long, string>;
} }
namespace Mem { namespace Mem {

View file

@ -18,6 +18,10 @@ tab-size = 4
#pragma once #pragma once
#if !defined(NDEBUG)
# define BTOP_DEBUG
#endif
#include <algorithm> // for std::ranges::count_if #include <algorithm> // for std::ranges::count_if
#include <array> #include <array>
#include <atomic> #include <atomic>
@ -42,11 +46,9 @@ tab-size = 4
#define HOST_NAME_MAX 64 #define HOST_NAME_MAX 64
#endif #endif
#endif #endif
#define FMT_HEADER_ONLY
#include "fmt/core.h" #include "fmt/core.h"
#include "fmt/format.h" #include "fmt/format.h"
#include "fmt/ostream.h"
#include "fmt/ranges.h"
using std::array; using std::array;
using std::atomic; using std::atomic;

View file

@ -207,7 +207,7 @@ namespace Cpu {
string cpuName; string cpuName;
string cpuHz; string cpuHz;
bool has_battery = true; bool has_battery = true;
tuple<int, long, string> current_bat; tuple<int, float, long, string> current_bat;
const array<string, 10> time_names = {"user", "nice", "system", "idle"}; const array<string, 10> time_names = {"user", "nice", "system", "idle"};
@ -373,10 +373,11 @@ namespace Cpu {
return core_map; return core_map;
} }
auto get_battery() -> tuple<int, long, string> { auto get_battery() -> tuple<int, float, long, string> {
if (not has_battery) return {0, 0, ""}; if (not has_battery) return {0, 0, 0, ""};
long seconds = -1; long seconds = -1;
float watts = -1;
uint32_t percent = -1; uint32_t percent = -1;
size_t size = sizeof(percent); size_t size = sizeof(percent);
string status = "discharging"; string status = "discharging";
@ -388,6 +389,10 @@ namespace Cpu {
if (sysctlbyname("hw.acpi.battery.time", &seconds, &size, nullptr, 0) < 0) { if (sysctlbyname("hw.acpi.battery.time", &seconds, &size, nullptr, 0) < 0) {
seconds = 0; seconds = 0;
} }
size = sizeof(watts);
if (sysctlbyname("hw.acpi.battery.rate", &watts, &size, nullptr, 0) < 0) {
watts = -1;
}
int state; int state;
size = sizeof(state); size = sizeof(state);
if (sysctlbyname("hw.acpi.battery.state", &state, &size, nullptr, 0) < 0) { if (sysctlbyname("hw.acpi.battery.state", &state, &size, nullptr, 0) < 0) {
@ -402,7 +407,7 @@ namespace Cpu {
} }
} }
return {percent, seconds, status}; return {percent, watts, seconds, status};
} }
auto collect(bool no_update) -> cpu_info & { auto collect(bool no_update) -> cpu_info & {

View file

@ -301,7 +301,7 @@ namespace Cpu {
string cpuName; string cpuName;
string cpuHz; string cpuHz;
bool has_battery = true; bool has_battery = true;
tuple<int, long, string> current_bat; tuple<int, float, long, string> current_bat;
const array time_names { const array time_names {
"user"s, "nice"s, "system"s, "idle"s, "iowait"s, "user"s, "nice"s, "system"s, "idle"s, "iowait"s,
@ -590,7 +590,7 @@ namespace Cpu {
cpuhz += " GHz"; cpuhz += " GHz";
} }
else if (hz > 0) else if (hz > 0)
cpuhz = to_string((int)round(hz)) + " MHz"; cpuhz = to_string((int)hz) + " MHz";
} }
catch (const std::exception& e) { catch (const std::exception& e) {
@ -671,13 +671,14 @@ namespace Cpu {
} }
struct battery { struct battery {
fs::path base_dir, energy_now, energy_full, power_now, status, online; fs::path base_dir, energy_now, charge_now, energy_full, charge_full, power_now, current_now, voltage_now, status, online;
string device_type; string device_type;
bool use_energy = true; bool use_energy_or_charge = true;
bool use_power = true;
}; };
auto get_battery() -> tuple<int, long, string> { auto get_battery() -> tuple<int, float, long, string> {
if (not has_battery) return {0, 0, ""}; if (not has_battery) return {0, 0, 0, ""};
static string auto_sel; static string auto_sel;
static std::unordered_map<string, battery> batteries; static std::unordered_map<string, battery> batteries;
@ -709,19 +710,27 @@ namespace Cpu {
} }
if (fs::exists(bat_dir / "energy_now")) new_bat.energy_now = bat_dir / "energy_now"; if (fs::exists(bat_dir / "energy_now")) new_bat.energy_now = bat_dir / "energy_now";
else if (fs::exists(bat_dir / "charge_now")) new_bat.energy_now = bat_dir / "charge_now"; else if (fs::exists(bat_dir / "charge_now")) new_bat.charge_now = bat_dir / "charge_now";
else new_bat.use_energy = false; else new_bat.use_energy_or_charge = false;
if (fs::exists(bat_dir / "energy_full")) new_bat.energy_full = bat_dir / "energy_full"; if (fs::exists(bat_dir / "energy_full")) new_bat.energy_full = bat_dir / "energy_full";
else if (fs::exists(bat_dir / "charge_full")) new_bat.energy_full = bat_dir / "charge_full"; else if (fs::exists(bat_dir / "charge_full")) new_bat.charge_full = bat_dir / "charge_full";
else new_bat.use_energy = false; else new_bat.use_energy_or_charge = false;
if (not new_bat.use_energy and not fs::exists(bat_dir / "capacity")) { if (not new_bat.use_energy_or_charge and not fs::exists(bat_dir / "capacity")) {
continue; continue;
} }
if (fs::exists(bat_dir / "power_now")) new_bat.power_now = bat_dir / "power_now"; if (fs::exists(bat_dir / "power_now")) {
else if (fs::exists(bat_dir / "current_now")) new_bat.power_now = bat_dir / "current_now"; new_bat.power_now = bat_dir / "power_now";
}
else if ((fs::exists(bat_dir / "current_now")) and (fs::exists(bat_dir / "current_now"))) {
new_bat.current_now = bat_dir / "current_now";
new_bat.voltage_now = bat_dir / "voltage_now";
}
else {
new_bat.use_power = false;
}
if (fs::exists(bat_dir / "AC0/online")) new_bat.online = bat_dir / "AC0/online"; if (fs::exists(bat_dir / "AC0/online")) new_bat.online = bat_dir / "AC0/online";
else if (fs::exists(bat_dir / "AC/online")) new_bat.online = bat_dir / "AC/online"; else if (fs::exists(bat_dir / "AC/online")) new_bat.online = bat_dir / "AC/online";
@ -736,7 +745,7 @@ namespace Cpu {
} }
if (batteries.empty()) { if (batteries.empty()) {
has_battery = false; has_battery = false;
return {0, 0, ""}; return {0, 0, 0, ""};
} }
} }
@ -756,15 +765,9 @@ namespace Cpu {
int percent = -1; int percent = -1;
long seconds = -1; long seconds = -1;
float watts = -1;
//? Try to get battery percentage //? Try to get battery percentage
if (b.use_energy) {
try {
percent = round(100.0 * stoll(readfile(b.energy_now, "-1")) / stoll(readfile(b.energy_full, "1")));
}
catch (const std::invalid_argument&) { }
catch (const std::out_of_range&) { }
}
if (percent < 0) { if (percent < 0) {
try { try {
percent = stoll(readfile(b.base_dir / "capacity", "-1")); percent = stoll(readfile(b.base_dir / "capacity", "-1"));
@ -772,9 +775,23 @@ namespace Cpu {
catch (const std::invalid_argument&) { } catch (const std::invalid_argument&) { }
catch (const std::out_of_range&) { } catch (const std::out_of_range&) { }
} }
if (b.use_energy_or_charge and percent < 0) {
try {
percent = round(100.0 * stoll(readfile(b.energy_now, "-1")) / stoll(readfile(b.energy_full, "1")));
}
catch (const std::invalid_argument&) { }
catch (const std::out_of_range&) { }
}
if (b.use_energy_or_charge and percent < 0) {
try {
percent = round(100.0 * stoll(readfile(b.charge_now, "-1")) / stoll(readfile(b.charge_full, "1")));
}
catch (const std::invalid_argument&) { }
catch (const std::out_of_range&) { }
}
if (percent < 0) { if (percent < 0) {
has_battery = false; has_battery = false;
return {0, 0, ""}; return {0, 0, 0, ""};
} }
//? Get charging/discharging status //? Get charging/discharging status
@ -788,13 +805,23 @@ namespace Cpu {
//? Get seconds to empty //? Get seconds to empty
if (not is_in(status, "charging", "full")) { if (not is_in(status, "charging", "full")) {
if (b.use_energy and not b.power_now.empty()) { if (b.use_energy_or_charge ) {
try { if (not b.power_now.empty()) {
seconds = round((double)stoll(readfile(b.energy_now, "0")) / stoll(readfile(b.power_now, "1")) * 3600); try {
seconds = round((double)stoll(readfile(b.energy_now, "0")) / stoll(readfile(b.power_now, "1")) * 3600);
}
catch (const std::invalid_argument&) { }
catch (const std::out_of_range&) { }
}
else if (not b.current_now.empty()) {
try {
seconds = round((double)stoll(readfile(b.charge_now, "0")) / (double)stoll(readfile(b.current_now, "1")) * 3600);
}
catch (const std::invalid_argument&) { }
catch (const std::out_of_range&) { }
} }
catch (const std::invalid_argument&) { }
catch (const std::out_of_range&) { }
} }
if (seconds < 0 and fs::exists(b.base_dir / "time_to_empty")) { if (seconds < 0 and fs::exists(b.base_dir / "time_to_empty")) {
try { try {
seconds = stoll(readfile(b.base_dir / "time_to_empty", "0")) * 60; seconds = stoll(readfile(b.base_dir / "time_to_empty", "0")) * 60;
@ -804,7 +831,26 @@ namespace Cpu {
} }
} }
return {percent, seconds, status}; //? Get power draw
if (b.use_power) {
if (not b.power_now.empty()) {
try {
watts = (float)stoll(readfile(b.energy_now, "-1")) / 1000000.0;
}
catch (const std::invalid_argument&) { }
catch (const std::out_of_range&) { }
}
else if (not b.voltage_now.empty() and not b.current_now.empty()) {
try {
watts = (float)stoll(readfile(b.current_now, "-1")) / 1000000.0 * stoll(readfile(b.voltage_now, "1")) / 1000000.0;
}
catch (const std::invalid_argument&) { }
catch (const std::out_of_range&) { }
}
}
return {percent, watts, seconds, status};
} }
auto collect(bool no_update) -> cpu_info& { auto collect(bool no_update) -> cpu_info& {

View file

@ -202,7 +202,7 @@ namespace Cpu {
string cpuName; string cpuName;
string cpuHz; string cpuHz;
bool has_battery = true; bool has_battery = true;
tuple<int, long, string> current_bat; tuple<int, float, long, string> current_bat;
const array<string, 10> time_names = {"user", "nice", "system", "idle"}; const array<string, 10> time_names = {"user", "nice", "system", "idle"};
@ -385,8 +385,8 @@ namespace Cpu {
return core_map; return core_map;
} }
auto get_battery() -> tuple<int, long, string> { auto get_battery() -> tuple<int, float, long, string> {
if (not has_battery) return {0, 0, ""}; if (not has_battery) return {0, 0, 0, ""};
long seconds = -1; long seconds = -1;
uint32_t percent = -1; uint32_t percent = -1;
@ -417,7 +417,7 @@ namespace Cpu {
} }
} }
return {percent, seconds, status}; return {percent, -1, seconds, status};
} }
auto collect(bool no_update) -> cpu_info & { auto collect(bool no_update) -> cpu_info & {

View file

@ -191,7 +191,7 @@ namespace Cpu {
string cpuHz; string cpuHz;
bool has_battery = true; bool has_battery = true;
bool macM1 = false; bool macM1 = false;
tuple<int, long, string> current_bat; tuple<int, float, long, string> current_bat;
const array<string, 10> time_names = {"user", "nice", "system", "idle"}; const array<string, 10> time_names = {"user", "nice", "system", "idle"};
@ -407,8 +407,8 @@ namespace Cpu {
~IOPSList_Wrap() { CFRelease(data); } ~IOPSList_Wrap() { CFRelease(data); }
}; };
auto get_battery() -> tuple<int, long, string> { auto get_battery() -> tuple<int, float, long, string> {
if (not has_battery) return {0, 0, ""}; if (not has_battery) return {0, 0, 0, ""};
uint32_t percent = -1; uint32_t percent = -1;
long seconds = -1; long seconds = -1;
@ -447,7 +447,7 @@ namespace Cpu {
has_battery = false; has_battery = false;
} }
} }
return {percent, seconds, status}; return {percent, -1, seconds, status};
} }
auto collect(bool no_update) -> cpu_info & { auto collect(bool no_update) -> cpu_info & {