Added terminal size limit warnings and fixed net auto sizing

This commit is contained in:
aristocratos 2021-08-22 21:39:25 +02:00
parent 3f27fb24b5
commit b2e0707c32
4 changed files with 58 additions and 32 deletions

View file

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

View file

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

View file

@ -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<bool> resized (false);
atomic<int> resizing (0);
atomic<bool> 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;

View file

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