diff --git a/src/btop.cpp b/src/btop.cpp index 6d4753a3a..02501f889 100644 --- a/src/btop.cpp +++ b/src/btop.cpp @@ -289,7 +289,7 @@ void term_resize(bool force) { else if (key.size() == 1 and isint(key)) { auto intKey = stoi(key); #ifdef GPU_SUPPORT - if ((intKey == 0 and Gpu::gpu_names.size() >= 5) or (intKey >= 5 and std::cmp_greater_equal(Gpu::gpu_names.size(), intKey - 4))) { + if ((intKey == 0 and Gpu::count >= 5) or (intKey >= 5 and intKey - 4 <= Gpu::count)) { #else if (intKey > 0 and intKey < 5) { #endif @@ -1075,8 +1075,8 @@ int main(int argc, char **argv) { clean_quit(1); } - if (not Config::check_boxes(Config::getS("shown_boxes"))) { - Config::check_boxes("cpu mem net proc"); + if (not Config::set_boxes(Config::getS("shown_boxes"))) { + Config::set_boxes("cpu mem net proc"); Config::set("shown_boxes", "cpu mem net proc"s); } diff --git a/src/btop_config.cpp b/src/btop_config.cpp index ef3bfeb6b..b1ccfd11d 100644 --- a/src/btop_config.cpp +++ b/src/btop_config.cpp @@ -439,7 +439,7 @@ namespace Config { } //* Apply selected preset - void apply_preset(const string& preset) { + bool apply_preset(const string& preset) { string boxes; for (const auto& box : ssplit(preset, ',')) { @@ -450,7 +450,7 @@ namespace Config { auto min_size = Term::get_min_size(boxes); if (Term::width < min_size.at(0) or Term::height < min_size.at(1)) { - return; + return false; } for (const auto& box : ssplit(preset, ',')) { @@ -461,7 +461,11 @@ namespace Config { set("graph_symbol_" + vals.at(0), vals.at(2)); } - if (check_boxes(boxes)) set("shown_boxes", boxes); + if (set_boxes(boxes)) { + set("shown_boxes", boxes); + return true; + } + return false; } void lock() { @@ -501,6 +505,11 @@ namespace Config { return false; } + bool validBoxSizes(const string& boxes) { + auto min_size = Term::get_min_size(boxes); + return (Term::width >= min_size.at(0) and Term::height >= min_size.at(1)); + } + bool stringValid(const std::string_view name, const string& value) { if (name == "log_level" and not v_contains(Logger::log_levels, value)) validError = "Invalid log_level: " + value; @@ -511,8 +520,16 @@ namespace Config { else if (name.starts_with("graph_symbol_") and (value != "default" and not v_contains(valid_graph_symbols, value))) validError = fmt::format("Invalid graph symbol identifier for {}: {}", name, value); - else if (name == "shown_boxes" and not Global::init_conf and not value.empty() and not check_boxes(value)) - validError = "Invalid box name(s) in shown_boxes!"; + else if (name == "shown_boxes" and not Global::init_conf) { + if (value.empty()) + validError = "No boxes selected!"; + else if (not validBoxSizes(value)) + validError = "Terminal too small to display entered boxes!"; + else if (not set_boxes(value)) + validError = "Invalid box name(s) in shown_boxes!"; + else + return true; + } #ifdef GPU_SUPPORT else if (name == "show_gpu_info" and not v_contains(show_gpu_values, value)) @@ -617,14 +634,14 @@ namespace Config { locked = false; } - bool check_boxes(const string& boxes) { + bool set_boxes(const string& boxes) { auto new_boxes = ssplit(boxes); for (auto& box : new_boxes) { if (not v_contains(valid_boxes, box)) return false; #ifdef GPU_SUPPORT if (box.starts_with("gpu")) { - size_t gpu_num = stoi(box.substr(3)) + 1; - if (std::cmp_greater(gpu_num, Gpu::gpu_names.size())) return false; + int gpu_num = stoi(box.substr(3)) + 1; + if (gpu_num > Gpu::count) return false; } #endif } @@ -632,7 +649,7 @@ namespace Config { return true; } - void toggle_box(const string& box) { + bool toggle_box(const string& box) { auto old_boxes = current_boxes; auto box_pos = rng::find(current_boxes, box); if (box_pos == current_boxes.end()) @@ -650,10 +667,11 @@ namespace Config { if (Term::width < min_size.at(0) or Term::height < min_size.at(1)) { current_boxes = old_boxes; - return; + return false; } Config::set("shown_boxes", new_boxes); + return true; } void load(const fs::path& conf_file, vector& load_warnings) { diff --git a/src/btop_config.hpp b/src/btop_config.hpp index 3651566a8..2a71e0f52 100644 --- a/src/btop_config.hpp +++ b/src/btop_config.hpp @@ -62,17 +62,19 @@ namespace Config { [[nodiscard]] std::optional get_config_dir() noexcept; - //* Check if string only contains space separated valid names for boxes - bool check_boxes(const string& boxes); + //* Check if string only contains space separated valid names for boxes and set current_boxes + bool set_boxes(const string& boxes); + + bool validBoxSizes(const string& boxes); //* Toggle box and update config string shown_boxes - void toggle_box(const string& box); + bool toggle_box(const string& box); //* Parse and setup config value presets bool presetsValid(const string& presets); //* Apply selected preset - void apply_preset(const string& preset); + bool apply_preset(const string& preset); bool _locked(const std::string_view name); diff --git a/src/btop_input.cpp b/src/btop_input.cpp index 6bfe9d8f9..da77313bb 100644 --- a/src/btop_input.cpp +++ b/src/btop_input.cpp @@ -232,7 +232,7 @@ namespace Input { auto intKey = stoi(key); #ifdef GPU_SUPPORT static const array boxes = {"gpu5", "cpu", "mem", "net", "proc", "gpu0", "gpu1", "gpu2", "gpu3", "gpu4"}; - if ((intKey == 0 and Gpu::gpu_names.size() < 5) or (intKey >= 5 and std::cmp_less(Gpu::gpu_names.size(), intKey - 4))) + if ((intKey == 0 and Gpu::count < 5) or (intKey >= 5 and intKey - 4 > Gpu::count)) return; #else static const array boxes = {"", "cpu", "mem", "net", "proc"}; @@ -240,14 +240,18 @@ namespace Input { return; #endif atomic_wait(Runner::active); - Config::current_preset = -1; - Config::toggle_box(boxes.at(intKey)); + if (not Config::toggle_box(boxes.at(intKey))) { + Menu::show(Menu::Menus::SizeError); + return; + } + Config::current_preset = -1; Draw::calcSizes(); Runner::run("all", false, true); return; } else if (is_in(key, "p", "P") and Config::preset_list.size() > 1) { + const auto old_preset = Config::current_preset; if (key == "p") { if (++Config::current_preset >= (int)Config::preset_list.size()) Config::current_preset = 0; } @@ -255,7 +259,11 @@ namespace Input { if (--Config::current_preset < 0) Config::current_preset = Config::preset_list.size() - 1; } atomic_wait(Runner::active); - Config::apply_preset(Config::preset_list.at(Config::current_preset)); + if (not Config::apply_preset(Config::preset_list.at(Config::current_preset))) { + Menu::show(Menu::Menus::SizeError); + Config::current_preset = old_preset; + return; + } Draw::calcSizes(); Runner::run("all", false, true); return; diff --git a/src/btop_shared.hpp b/src/btop_shared.hpp index 0cf08eb44..7e24078a2 100644 --- a/src/btop_shared.hpp +++ b/src/btop_shared.hpp @@ -119,7 +119,7 @@ namespace Gpu { extern std::unordered_map> shared_gpu_percent; // averages, power/vram total - const array mem_names { "used"s, "free"s }; + const array mem_names { "used"s, "free"s }; //* Container for process information // TODO /*struct proc_info { diff --git a/src/btop_tools.cpp b/src/btop_tools.cpp index d1351e401..263009d75 100644 --- a/src/btop_tools.cpp +++ b/src/btop_tools.cpp @@ -123,9 +123,9 @@ namespace Term { bool proc = boxes.find("proc") != string::npos; #ifdef GPU_SUPPORT int gpu = 0; - if (not Gpu::gpu_names.empty()) - for (char i = '0'; i <= '5'; ++i) - gpu += (boxes.find(std::string("gpu") + i) != string::npos); + if (Gpu::count > 0) + for (char i = '0'; i <= '5'; i++) + gpu += (Tools::s_contains(boxes, "gpu"s + i) ? 1 : 0); #endif int width = 0; if (mem) width = Mem::min_width; diff --git a/src/linux/btop_collect.cpp b/src/linux/btop_collect.cpp index c3592d5bb..c8736ca61 100644 --- a/src/linux/btop_collect.cpp +++ b/src/linux/btop_collect.cpp @@ -1226,6 +1226,8 @@ namespace Gpu { if constexpr(is_init) gpus_slice[i].supported_functions.pwr_usage = false; } else { gpus_slice[i].pwr_usage = (long long)power; + if (gpus_slice[i].pwr_usage > gpus_slice[i].pwr_max_usage) + gpus_slice[i].pwr_max_usage = gpus_slice[i].pwr_usage; gpus_slice[i].gpu_percent.at("gpu-pwr-totals").push_back(clamp((long long)round((double)gpus_slice[i].pwr_usage * 100.0 / (double)gpus_slice[i].pwr_max_usage), 0ll, 100ll)); } } @@ -1534,6 +1536,8 @@ namespace Gpu { if constexpr(is_init) gpus_slice[i].supported_functions.pwr_usage = false; } else { gpus_slice[i].pwr_usage = (long long)power / 1000; + if (gpus_slice[i].pwr_usage > gpus_slice[i].pwr_max_usage) + gpus_slice[i].pwr_max_usage = gpus_slice[i].pwr_usage; gpus_slice[i].gpu_percent.at("gpu-pwr-totals").push_back(clamp((long long)round((double)gpus_slice[i].pwr_usage * 100.0 / (double)gpus_slice[i].pwr_max_usage), 0ll, 100ll)); } @@ -1675,6 +1679,8 @@ namespace Gpu { .mem_used = false, .pcie_txrx = false }; + + gpus_slice->pwr_max_usage = 20'000; //? 20W } pmu_sample(engines); @@ -1692,11 +1698,10 @@ namespace Gpu { double pwr = pmu_calc(&engines->r_gpu.val, 1, t, engines->r_gpu.scale); // in Watts gpus_slice->pwr_usage = (long long)round(pwr * 1000); - if (gpus_slice->pwr_usage > 0) { - gpus_slice->gpu_percent.at("gpu-pwr-totals").push_back(100); - } else { - gpus_slice->gpu_percent.at("gpu-pwr-totals").push_back(0); - } + if (gpus_slice->pwr_usage > gpus_slice->pwr_max_usage) + gpus_slice->pwr_max_usage = gpus_slice->pwr_usage; + + gpus_slice->gpu_percent.at("gpu-pwr-totals").push_back(clamp((long long)round((double)gpus_slice->pwr_usage * 100.0 / (double)gpus_slice->pwr_max_usage), 0ll, 100ll)); double freq = pmu_calc(&engines->freq_act.val, 1, t, 1); // in MHz gpus_slice->gpu_clock_speed = (unsigned int)round(freq);