From b2e0707c3265d47d4abcc5e83dcdfef1a0505529 Mon Sep 17 00:00:00 2001 From: aristocratos Date: Sun, 22 Aug 2021 21:39:25 +0200 Subject: [PATCH] Added terminal size limit warnings and fixed net auto sizing --- Makefile | 4 ++-- README.md | 15 ++++++++------- src/btop.cpp | 49 +++++++++++++++++++++++++++++++++++------------ src/btop_draw.cpp | 22 ++++++++++----------- 4 files changed, 58 insertions(+), 32 deletions(-) diff --git a/Makefile b/Makefile index 79eff29..bb5f385 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ BANNER = \n \033[38;5;196m██████\033[38;5;240m╗ \033[38;5;196m████████\033[38;5;240m╗ \033[38;5;196m██████\033[38;5;240m╗ \033[38;5;196m██████\033[38;5;240m╗\n \033[38;5;160m██\033[38;5;239m╔══\033[38;5;160m██\033[38;5;239m╗╚══\033[38;5;160m██\033[38;5;239m╔══╝\033[38;5;160m██\033[38;5;239m╔═══\033[38;5;160m██\033[38;5;239m╗\033[38;5;160m██\033[38;5;239m╔══\033[38;5;160m██\033[38;5;239m╗ \033[38;5;160m██\033[38;5;239m╗ \033[38;5;160m██\033[38;5;239m╗\n \033[38;5;124m██████\033[38;5;238m╔╝ \033[38;5;124m██\033[38;5;238m║ \033[38;5;124m██\033[38;5;238m║ \033[38;5;124m██\033[38;5;238m║\033[38;5;124m██████\033[38;5;238m╔╝ \033[38;5;124m██████\033[38;5;238m╗\033[38;5;124m██████\033[38;5;238m╗\n \033[38;5;88m██\033[38;5;237m╔══\033[38;5;88m██\033[38;5;237m╗ \033[38;5;88m██\033[38;5;237m║ \033[38;5;88m██\033[38;5;237m║ \033[38;5;88m██\033[38;5;237m║\033[38;5;88m██\033[38;5;237m╔═══╝ ╚═\033[38;5;88m██\033[38;5;237m╔═╝╚═\033[38;5;88m██\033[38;5;237m╔═╝\n \033[38;5;52m██████\033[38;5;236m╔╝ \033[38;5;52m██\033[38;5;236m║ ╚\033[38;5;52m██████\033[38;5;236m╔╝\033[38;5;52m██\033[38;5;236m║ ╚═╝ ╚═╝\n \033[38;5;235m╚═════╝ ╚═╝ ╚═════╝ ╚═╝ BTOP_VERSION = $(shell head -n100 src/btop.cpp 2>/dev/null | grep "Version =" | cut -f2 -d"\"" || echo " unknown") -TIMESTAMP = $(shell date +%s) +TIMESTAMP = $(shell date +%s 2>/dev/null || echo "0") PREFIX ?= /usr/local @@ -130,7 +130,7 @@ btop: $(OBJECTS) @printf "\n\033[1;92mLinking and optimizing binary\033[0m\n" @$(CXX) -o $(TARGETDIR)/btop $^ $(LDFLAGS) @printf "\033[1;97m./$(TARGETDIR)/btop ($$(du -ah $(TARGETDIR)/btop | cut -f1)iB)\033[0m\n" - @printf "\n\033[1;92mBuild complete in (\033[1;97m$$(date -d @$$(expr $$(date +%s) - $(TIMESTAMP)) -u +%Mm:%Ss)\033[1;92m)\033[0m\n" + @printf "\n\033[1;92mBuild complete in (\033[1;97m$$(date -d @$$(expr $$(date +%s 2>/dev/null || echo "0") - $(TIMESTAMP)) -u +%Mm:%Ss)\033[1;92m)\033[0m\n" #? Compile $(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SRCEXT) diff --git a/README.md b/README.md index 7d73ae8..0ffe6ce 100644 --- a/README.md +++ b/README.md @@ -127,13 +127,14 @@ Options menu. #### Manual compilation and installation -Needs GCC 10 or higher, (GCC 11 preferably). +Needs GCC 10 or higher, (GCC 11 or above strongly recommended for better CPU efficiency in compiled binary). +The makefile also needs GNU coreutils and sed installed. ->Install dependencies (Ubuntu 21.04 Hirsute) +>Install dependencies (example for Ubuntu 21.04 Hirsute) ``` bash -sudo apt install git build-essential gcc-11 g++-11 -#gcc-10 g++-10 if on older +sudo apt install coreutils sed git build-essential gcc-11 g++-11 +#use gcc-10 g++-10 if gcc-11 isn't available ``` >Clone and compile @@ -141,24 +142,24 @@ sudo apt install git build-essential gcc-11 g++-11 ``` bash git clone https://github.com/aristocratos/btop.git cd btop +# use "make -j X" where X is threads, to manually set number of threads, the makefile will use all available cores by default make -# use "make -jX" where X is your number of cores for multithreaded compilation ``` >to install ``` bash -sudo make install # use "make install PREFIX=/target/dir" to set target, default: /usr/local # only use "sudo" when installing to a NON user owned directory +sudo make install ``` >to make btop always run as root (or other user), (no need for `sudo` to enable signal sending to any process and to prevent /proc read permissions problems on some systems) ``` bash # run after make install and use same PREFIX if any was used at install -sudo make setuid # set SU_USER and SU_GROUP to select user and group, default is root:root +sudo make setuid ``` diff --git a/src/btop.cpp b/src/btop.cpp index bb13365..08019ae 100644 --- a/src/btop.cpp +++ b/src/btop.cpp @@ -78,6 +78,12 @@ namespace Global { string overlay; string clock; + string bg_black = "\x1b[0;40m"; + string fg_white = "\x1b[1;97m"; + string fg_green = "\x1b[1;92m"; + string fg_red = "\x1b[0;91m"; + + fs::path self_path; string exit_error_msg; @@ -90,7 +96,6 @@ namespace Global { uint64_t start_time; atomic resized (false); - atomic resizing (0); atomic quitting (false); bool arg_tty = false; @@ -150,20 +155,28 @@ void term_resize(bool force) { } else return; - auto rez_state = ++Global::resizing; - if (rez_state > 1) return; Global::resized = true; Runner::stop(); auto min_size = Term::get_min_size(Config::getS("shown_boxes")); while (not force) { sleep_ms(100); - if (rez_state != Global::resizing) rez_state = --Global::resizing; - else if (not Term::refresh() and Term::width >= min_size[0] and Term::height >= min_size[1]) break; + if (Term::width < min_size.at(0) or Term::height < min_size.at(1)) { + min_size = Term::get_min_size(Config::getS("shown_boxes")); + cout << Term::clear << Global::bg_black << Global::fg_white << Mv::to((Term::height / 2) - 2, (Term::width / 2) - 11) + << "Terminal size too small:" << Mv::to((Term::height / 2) - 1, (Term::width / 2) - 10) + << " Width = " << (Term::width < min_size.at(1) ? Global::fg_red : Global::fg_green) << Term::width + << Global::fg_white << " Height = " << (Term::height < min_size.at(0) ? Global::fg_red : Global::fg_green) << Term::height + << Mv::to((Term::height / 2) + 1, (Term::width / 2) - 12) << Global::fg_white + << "Needed for current config:" << Mv::to((Term::height / 2) + 2, (Term::width / 2) - 10) + << "Width = " << min_size.at(0) << " Height = " << min_size.at(1) << flush; + while (not Term::refresh() and not Input::poll()) sleep_ms(10); + if (Input::poll() and Input::get() == "q") exit(0); + } + else if (not Term::refresh()) break; } Input::interrupt = true; - Global::resizing = 0; } //* Exit handler; stops threads, restores terminal and saves config changes @@ -174,14 +187,8 @@ void clean_quit(int sig) { if (pthread_join(Runner::runner_id, NULL) != 0) Logger::error("Failed to join _runner thread!"); - if (not Global::exit_error_msg.empty()) { - sig = 1; - Logger::error(Global::exit_error_msg); - std::cerr << "ERROR: " << Global::exit_error_msg << endl; - } Config::write(); Input::clear(); - Logger::info("Quitting! Runtime: " + sec_to_dhms(time_s() - Global::start_time)); //? Wait for any remaining Tools::atomic_lock destructors to finish for max 1000ms for (int i = 0; Tools::active_locks > 0 and i < 100; i++) { @@ -192,6 +199,13 @@ void clean_quit(int sig) { Term::restore(); } + if (not Global::exit_error_msg.empty()) { + sig = 1; + Logger::error(Global::exit_error_msg); + std::cerr << Global::fg_red << "ERROR: " << Global::fg_white << Global::exit_error_msg << Fx::reset << endl; + } + Logger::info("Quitting! Runtime: " + sec_to_dhms(time_s() - Global::start_time)); + //? Assume error if still not cleaned up and call quick_exit to avoid a segfault from Tools::atomic_lock destructor if (Tools::active_locks > 0) { quick_exit((sig != -1 ? sig : 0)); @@ -824,6 +838,17 @@ int main(int argc, char **argv) { //? Calculate sizes of all boxes Draw::calcSizes(); + { + const auto [x, y] = Term::get_min_size(Config::getS("shown_boxes")); + if (Term::height < y or Term::width < x) { + Global::exit_error_msg = "Terminal size to small for current config.\n(WxH) Current: " + to_string(Term::width) + + 'x' + to_string(Term::height) + " | Needed: " + to_string(x) + 'x' + to_string(y) + + "\nResize terminal or disable some boxes in config file to fix this."; + exit(1); + } + + } + //? Print out box outlines cout << Term::sync_start << Cpu::box << Mem::box << Net::box << Proc::box << Term::sync_end << flush; diff --git a/src/btop_draw.cpp b/src/btop_draw.cpp index 6b668a8..450d136 100644 --- a/src/btop_draw.cpp +++ b/src/btop_draw.cpp @@ -515,7 +515,7 @@ namespace Cpu { } namespace Mem { - int width_p = 45, height_p = 38; + int width_p = 45, height_p = 36; int min_width = 36, min_height = 10; int x = 1, y, width = 20, height; int mem_width, disks_width, divider, item_height, mem_size, mem_meter, graph_height, disk_meter; @@ -668,7 +668,7 @@ namespace Mem { const auto& disks = mem.disks; cx = x + mem_width - 1; cy = 0; const bool big_disk = disks_width >= 25; - divider = Mv::l(1) + Theme::c("div_line") + Symbols::div_left + Symbols::h_line * disks_width + Theme::c("mem_box") + Fx::ub + Symbols::div_right + Mv::l(disks_width - 1); + divider = Mv::l(1) + Theme::c("div_line") + Symbols::div_left + Symbols::h_line * disks_width + Theme::c("mem_box") + Fx::ub + Symbols::div_right + Mv::l(disks_width); if (io_mode) { for (const auto& mount : mem.disks_order) { if (not disks.contains(mount)) continue; @@ -676,7 +676,7 @@ namespace Mem { const auto& disk = disks.at(mount); if (disk.io_read.empty()) continue; const string total = floating_humanizer(disk.total, not big_disk); - out += Mv::to(y+1+cy, x+1+cx) + divider + Theme::c("title") + Fx::b + uresize(disk.name, disks_width - 2) + Mv::to(y+1+cy, x+cx + disks_width - total.size() - 1) + out += Mv::to(y+1+cy, x+1+cx) + divider + Theme::c("title") + Fx::b + uresize(disk.name, disks_width - 2) + Mv::to(y+1+cy, x+cx + disks_width - total.size()) + trans(total) + Fx::ub; if (big_disk) { const string used_percent = to_string(disk.used_percent); @@ -715,7 +715,7 @@ namespace Mem { const string human_used = floating_humanizer(disk.used, not big_disk); const string human_free = floating_humanizer(disk.free, not big_disk); - out += Mv::to(y+1+cy, x+1+cx) + divider + Theme::c("title") + Fx::b + uresize(disk.name, disks_width - 2) + Mv::to(y+1+cy, x+cx + disks_width - human_total.size() - 1) + out += Mv::to(y+1+cy, x+1+cx) + divider + Theme::c("title") + Fx::b + uresize(disk.name, disks_width - 2) + Mv::to(y+1+cy, x+cx + disks_width - human_total.size()) + trans(human_total) + Fx::ub + Theme::c("main_fg"); if (big_disk and not human_io.empty()) out += Mv::to(y+1+cy, x+1+cx + round((double)disks_width / 2) - round((double)human_io.size() / 2)) + Theme::c("main_fg") + human_io; @@ -751,7 +751,7 @@ namespace Mem { } namespace Net { - int width_p = 45, height_p = 30; + int width_p = 45, height_p = 32; int min_width = 36, min_height = 6; int x = 1, y, width = 20, height; int b_x, b_y, b_width, b_height, d_graph_height, u_graph_height; @@ -825,14 +825,14 @@ namespace Net { const string total = floating_humanizer(net.stat.at(dir).total); const string symbol = (dir == "upload" ? "▲" : "▼"); out += Mv::to(b_y+1+cy, b_x+1) + Fx::ub + Theme::c("main_fg") + symbol + ' ' + ljust(speed, 10) + (b_width >= 20 ? rjust('(' + speed_bits + ')', 13) : ""); - cy += (b_height == 3 ? 2 : 1); - if (b_height >= 6) { + cy += (b_height == 5 ? 2 : 1); + if (b_height >= 8) { out += Mv::to(b_y+1+cy, b_x+1) + symbol + ' ' + "Top: " + rjust('(' + top, (b_width >= 20 ? 17 : 9)) + ')'; cy++; } - if (b_height >= 4) { + if (b_height >= 6) { out += Mv::to(b_y+1+cy, b_x+1) + symbol + ' ' + "Total: " + rjust(total, (b_width >= 20 ? 16 : 8)); - cy += (b_height > 2 and b_height % 2 ? 2 : 1); + cy += (b_height > 6 and b_height % 2 ? 2 : 1); } } @@ -1332,7 +1332,7 @@ namespace Draw { using namespace Cpu; const bool show_temp = (Config::getB("check_temp") and got_sensors); width = round((double)Term::width * width_p / 100); - height = max(8, (int)round((double)Term::height * (trim(boxes) == "cpu" ? 100 : height_p) / 100)); + height = max(8, (int)ceil((double)Term::height * (trim(boxes) == "cpu" ? 100 : height_p) / 100)); x = 1; y = cpu_bottom ? Term::height - height + 1 : 1; @@ -1374,7 +1374,7 @@ namespace Draw { auto& mem_graphs = Config::getB("mem_graphs"); width = round((double)Term::width * (Proc::shown ? width_p : 100) / 100); - height = round((double)Term::height * (100 - Cpu::height_p * Cpu::shown - Net::height_p * Net::shown) / 100) + 1; + height = ceil((double)Term::height * (100 - Cpu::height_p * Cpu::shown - Net::height_p * Net::shown) / 100) + 1; if (height + Cpu::height > Term::height) height = Term::height - Cpu::height; x = (proc_left and Proc::shown) ? Term::width - width + 1: 1; if (mem_below_net and Net::shown)